diff --git a/README.md b/README.md index 6e4bb44..19b6c2e 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,10 @@ Or, to connect just one context to another database: var context = new DataContext("AnotherDatabaseConnection"); +If you need to connect to a dynamic connection string, pass a ConnectionStringSettings object to the DataContext class: + + var context = new DataContext(new ConnectionStringSettings("myDb", "myConnectionString")); + Parameters binding of the Thunderstruck commands prevents string concatenation, errors, conversions and SQL injection: var insertParams = new { Name = "Esprit Turbo", ModelYear = 1981 }; diff --git a/Thunderstruck-3.5.sln b/Thunderstruck-3.5.sln new file mode 100644 index 0000000..9bc7478 --- /dev/null +++ b/Thunderstruck-3.5.sln @@ -0,0 +1,50 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30523.141 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Thunderstruck-3.5", "Thunderstruck\Thunderstruck-3.5.csproj", "{277E5AD1-EC26-4273-B6F5-18CEB36CDC0F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{F35E2E1A-DCD9-4807-9EE6-0BF0FCAA050B}" + ProjectSection(SolutionItems) = preProject + .nuget\NuGet.Config = .nuget\NuGet.Config + .nuget\NuGet.exe = .nuget\NuGet.exe + .nuget\NuGet.targets = .nuget\NuGet.targets + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E9FAB6F7-94F5-482B-8419-A38EFFEC9A53}" + ProjectSection(SolutionItems) = preProject + .gitattributes = .gitattributes + .gitignore = .gitignore + LICENSE.txt = LICENSE.txt + README.md = README.md + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {277E5AD1-EC26-4273-B6F5-18CEB36CDC0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {277E5AD1-EC26-4273-B6F5-18CEB36CDC0F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {277E5AD1-EC26-4273-B6F5-18CEB36CDC0F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {277E5AD1-EC26-4273-B6F5-18CEB36CDC0F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {277E5AD1-EC26-4273-B6F5-18CEB36CDC0F}.Debug|x86.ActiveCfg = Debug|Any CPU + {277E5AD1-EC26-4273-B6F5-18CEB36CDC0F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {277E5AD1-EC26-4273-B6F5-18CEB36CDC0F}.Release|Any CPU.Build.0 = Release|Any CPU + {277E5AD1-EC26-4273-B6F5-18CEB36CDC0F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {277E5AD1-EC26-4273-B6F5-18CEB36CDC0F}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {277E5AD1-EC26-4273-B6F5-18CEB36CDC0F}.Release|x86.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {9A46D863-5935-4A2B-98FA-966BF9C9F981} + EndGlobalSection +EndGlobal diff --git a/Thunderstruck.Test/Unit/DataContextTest.cs b/Thunderstruck.Test/Unit/DataContextTest.cs index 4f2cea9..80b9a16 100644 --- a/Thunderstruck.Test/Unit/DataContextTest.cs +++ b/Thunderstruck.Test/Unit/DataContextTest.cs @@ -5,6 +5,7 @@ using Thunderstruck.Runtime; using System.Data; using FluentAssertions; +using System.Configuration; namespace Thunderstruck.Test.Unit { @@ -132,9 +133,18 @@ public void DataContext_Should_Be_Possible_To_Use_Another_Connection_String() var context = new DataContext("AnotherDatabase", Transaction.Begin); context.ConnectionSettings.ConnectionString.Should().Be("whatever"); - } + } - [TestMethod] + [TestMethod] + public void DataContext_Should_Be_Possible_To_Use_Connection_String_Settings() + { + var css = new ConnectionStringSettings("SettingsDatabase", "connectionStringSettings"); + var context = new DataContext(css, Transaction.Begin); + + context.ConnectionSettings.ConnectionString.Should().Be("connectionStringSettings"); + } + + [TestMethod] public void DataContext_Should_Not_Create_Connection_If_Not_Use_Commands() { var context = new DataContext(); diff --git a/Thunderstruck.sln b/Thunderstruck.sln index 41255c1..5c973c6 100644 --- a/Thunderstruck.sln +++ b/Thunderstruck.sln @@ -1,6 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30523.141 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Thunderstruck", "Thunderstruck\Thunderstruck.csproj", "{0DC5AB48-1DA5-4185-A18E-46C111A82454}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Thunderstruck.Test", "Thunderstruck.Test\Thunderstruck.Test.csproj", "{1516ECE1-30A2-443A-BB17-1FEE1997ADD3}" @@ -54,4 +56,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {9A46D863-5935-4A2B-98FA-966BF9C9F981} + EndGlobalSection EndGlobal diff --git a/Thunderstruck/DataContext.cs b/Thunderstruck/DataContext.cs index 8421380..21a59e1 100644 --- a/Thunderstruck/DataContext.cs +++ b/Thunderstruck/DataContext.cs @@ -20,29 +20,41 @@ static DataContext() /// /// Creates a new transactional data context to connection string named "Default". /// - public DataContext() : this(null, Transaction.Begin) { } + public DataContext() : this((string)null, Transaction.Begin) { } /// /// Creates a new data context to connection string named "Default". /// /// Defines if data context is transactional. - public DataContext(Transaction transactionMode) : this(null, transactionMode) { } + public DataContext(Transaction transactionMode) : this((string)null, transactionMode) { } /// /// Creates a new data context. /// /// Connection string name of target database. /// Defines if data context is transactional. - public DataContext(string connectionStringName, Transaction transaction) - { - TransactionMode = transaction; - - var connectionName = connectionStringName ?? DefaultConnectionStringName; - ConnectionSettings = ConnectionStringBuffer.Instance.Get(connectionName); - - var providerFactory = new ProviderFactory(); - Provider = providerFactory.Create(ConnectionSettings, transaction); - } + public DataContext(string connectionStringName, Transaction transaction) : this(ConnectionStringBuffer.Instance.Get(connectionStringName ?? DefaultConnectionStringName), transaction) { } + + /// + /// Creates a new data context. + /// + /// Connection string settings of target database. + public DataContext(ConnectionStringSettings connectionStringSettings) : this(connectionStringSettings, Transaction.Begin) { } + + /// + /// Creates a new data context. + /// + /// Connection string settings of target database. + /// Defines if data context is transactional. + public DataContext(ConnectionStringSettings connectionStringSettings, Transaction transaction) + { + TransactionMode = transaction; + + ConnectionSettings = connectionStringSettings; + + var providerFactory = new ProviderFactory(); + Provider = providerFactory.Create(ConnectionSettings, transaction); + } /// /// Thunderstruck data provider. diff --git a/Thunderstruck/Provider/ProviderFactory.cs b/Thunderstruck/Provider/ProviderFactory.cs index c48b592..6173d3f 100644 --- a/Thunderstruck/Provider/ProviderFactory.cs +++ b/Thunderstruck/Provider/ProviderFactory.cs @@ -63,10 +63,15 @@ private IDbConnection CreateConnection(string providerName, ConnectionStringSett public static void AddProvider(string providerName, Type providerType) { +#if !NET35 if (String.IsNullOrWhiteSpace(providerName)) +#else + if (String.IsNullOrEmpty(providerName)) +#endif { throw new ArgumentException("Parameter 'providerName' can not be null and must contain data.", "providerName"); } + if (providerType == null) { throw new ArgumentNullException("providerType"); diff --git a/Thunderstruck/Runtime/DataObjectCommand.cs b/Thunderstruck/Runtime/DataObjectCommand.cs index 7198674..5eb2ac2 100644 --- a/Thunderstruck/Runtime/DataObjectCommand.cs +++ b/Thunderstruck/Runtime/DataObjectCommand.cs @@ -81,7 +81,7 @@ private string GetCommaFields(DataContext context) { var fields = _runtimeObject.GetFields(removePrimaryKey: _primaryKey.Name); var formatedFields = fields.Select(f => String.Format(context.Provider.FieldFormat, f)); - return String.Join(", ", formatedFields); + return String.Join(", ", formatedFields.ToArray()); } } } diff --git a/Thunderstruck/Runtime/DataObjectQuery.cs b/Thunderstruck/Runtime/DataObjectQuery.cs index ff71c2a..1470e21 100644 --- a/Thunderstruck/Runtime/DataObjectQuery.cs +++ b/Thunderstruck/Runtime/DataObjectQuery.cs @@ -106,7 +106,7 @@ private string GetCommaFields(DataContext context) { var fields = _runtimeObject.GetFields(removePrimaryKey: null); var formatedFields = fields.Select(f => String.Format(context.Provider.FieldFormat, f)); - return String.Join(", ", formatedFields); + return String.Join(", ", formatedFields.ToArray()); } } } diff --git a/Thunderstruck/Runtime/DataReader.cs b/Thunderstruck/Runtime/DataReader.cs index 991f752..67773e8 100644 --- a/Thunderstruck/Runtime/DataReader.cs +++ b/Thunderstruck/Runtime/DataReader.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; using System.Data; +#if !NET35 using System.Dynamic; +#endif using System.Linq; using System.Reflection; @@ -24,8 +26,12 @@ public DataReader(IDataReader dataReader) var properties = typeof(T).GetProperties(); var readerFields = GetFields(); +#if !NET35 bool isDynamic = (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(typeof(T))); IDictionary dynamicValues = null; +#else + bool isDynamic = false; +#endif while (_dataReader.Read()) { @@ -35,11 +41,7 @@ public DataReader(IDataReader dataReader) { if (isDynamic) { - if (dynamicValues == null) - { - dynamicValues = (IDictionary)item; - } - + IDictionary dynamicValues = (IDictionary)item; dynamicValues[field] = GetSafeValue(_dataReader[field].GetType(), field); continue; diff --git a/Thunderstruck/Runtime/DataRuntimeObject.cs b/Thunderstruck/Runtime/DataRuntimeObject.cs index 787d23b..138a6fc 100644 --- a/Thunderstruck/Runtime/DataRuntimeObject.cs +++ b/Thunderstruck/Runtime/DataRuntimeObject.cs @@ -98,7 +98,7 @@ private string CreateFieldAndParameter(string field, string paramIdentifier) private string Comma(IEnumerable list) { - return String.Join(", ", list); + return String.Join(", ", list.ToArray()); } } } \ No newline at end of file diff --git a/Thunderstruck/Thunderstruck-3.5.csproj b/Thunderstruck/Thunderstruck-3.5.csproj new file mode 100644 index 0000000..39b95dd --- /dev/null +++ b/Thunderstruck/Thunderstruck-3.5.csproj @@ -0,0 +1,84 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {277E5AD1-EC26-4273-B6F5-18CEB36CDC0F} + Library + Properties + Thunderstruck + Thunderstruck + v3.5 + 512 + + + + + true + full + false + bin\Debug\Net35\ + TRACE;DEBUG;NET35 + prompt + 4 + bin\Debug\Net35\Thunderstruck.xml + 1591 + false + false + false + MinimumRecommendedRules.ruleset + false + + + pdbonly + false + bin\Release\Net35\ + TRACE;NET35 + prompt + 4 + bin\Release\Net35\Thunderstruck.xml + 1591 + true + MinimumRecommendedRules.ruleset + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file