├── Src
├── BuildNugetPackage.cmd
├── packages
│ ├── NUnit.2.6.3
│ │ ├── license.txt
│ │ └── lib
│ │ │ └── nunit.framework.dll
│ ├── Moq.4.2.1402.2112
│ │ └── lib
│ │ │ ├── net35
│ │ │ └── Moq.dll
│ │ │ ├── net40
│ │ │ └── Moq.dll
│ │ │ └── sl4
│ │ │ └── Moq.Silverlight.dll
│ └── repositories.config
├── DBHelpers.Tests
│ ├── packages.config
│ ├── InternalDBHelper.cs
│ ├── DataReaderConverterTests.cs
│ ├── TypeExtensions.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── MockProviderFactory.cs
│ ├── DBHelpers.Tests.csproj
│ ├── BaseOverloadTests.cs
│ ├── DBConvertOverloadTests.cs
│ ├── DBHelperTests.cs
│ ├── DBConvertTests.cs
│ └── DbHelperOverloadTests.cs
├── DBHelpers
│ ├── DBHelpers.nuspec
│ ├── RawValue.cs
│ ├── DataReaderExtensions.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── DataReaderConverter.cs
│ ├── DBHelpers.csproj
│ ├── DBConvert.cs
│ ├── DBHelper.StringOverloads.cs
│ └── DBHelper.Core.cs
└── DBHelpers.sln
├── .gitignore
└── README.md
/Src/BuildNugetPackage.cmd:
--------------------------------------------------------------------------------
1 | @echo off
2 | nuget pack DBHelpers\DBHelpers.csproj -Prop Configuration=Release
3 | pause
--------------------------------------------------------------------------------
/Src/packages/NUnit.2.6.3/license.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nvivo/dbhelpers/HEAD/Src/packages/NUnit.2.6.3/license.txt
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.user
2 | *.suo
3 | *.bak
4 | *.~*
5 | *.lnk
6 | *.design
7 | *.log
8 | *.licenseheader
9 | bin
10 | obj
11 | Build
12 | *.nupkg
--------------------------------------------------------------------------------
/Src/packages/Moq.4.2.1402.2112/lib/net35/Moq.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nvivo/dbhelpers/HEAD/Src/packages/Moq.4.2.1402.2112/lib/net35/Moq.dll
--------------------------------------------------------------------------------
/Src/packages/Moq.4.2.1402.2112/lib/net40/Moq.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nvivo/dbhelpers/HEAD/Src/packages/Moq.4.2.1402.2112/lib/net40/Moq.dll
--------------------------------------------------------------------------------
/Src/packages/NUnit.2.6.3/lib/nunit.framework.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nvivo/dbhelpers/HEAD/Src/packages/NUnit.2.6.3/lib/nunit.framework.dll
--------------------------------------------------------------------------------
/Src/packages/Moq.4.2.1402.2112/lib/sl4/Moq.Silverlight.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nvivo/dbhelpers/HEAD/Src/packages/Moq.4.2.1402.2112/lib/sl4/Moq.Silverlight.dll
--------------------------------------------------------------------------------
/Src/packages/repositories.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Src/DBHelpers.Tests/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Src/DBHelpers/DBHelpers.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | DBHelpers
5 | $version$
6 | DBHelpers
7 | Natan Vivo
8 | Natan Vivo
9 | http://www.apache.org/licenses/LICENSE-2.0
10 | https://github.com/nvivo/dbhelpers
11 | false
12 | DBHelpers is a simple but powerful helper library for working with plain ADO.NET.
13 |
14 | Copyright 2010-2014
15 | dbhelpers dbhelper ado.net database helper
16 |
17 |
--------------------------------------------------------------------------------
/Src/DBHelpers.Tests/InternalDBHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Data.Common;
3 |
4 | namespace DBHelpers.Tests
5 | {
6 | public class InternalDBHelper : DBHelper
7 | {
8 | public InternalDBHelper()
9 | : base(new MockProviderFactory(), "fake connection string")
10 | { }
11 |
12 | public string CreateParameterName_(int index)
13 | {
14 | return base.CreateParameterName(index);
15 | }
16 |
17 | public void FillFromReader_(DbDataReader reader, int startRecord, int maxRecords, Action action)
18 | {
19 | FillFromReader(reader, startRecord, maxRecords, action);
20 | }
21 |
22 | protected override void OnExecuteCommand(DbCommand command)
23 | {
24 | OnExecuteCommand_(command);
25 | }
26 |
27 | public void OnExecuteCommand_(DbCommand command)
28 | {
29 | base.OnExecuteCommand(command);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Src/DBHelpers/RawValue.cs:
--------------------------------------------------------------------------------
1 | #region License
2 | // Copyright 2010-2015 Natan Vivo - http://github.com/nvivo/dbhelpers
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | #endregion
16 |
17 | namespace DBHelpers
18 | {
19 | public class RawValue
20 | {
21 | public RawValue(string value)
22 | {
23 | this.Value = value;
24 | }
25 |
26 | public string Value { get; private set; }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Src/DBHelpers.Tests/DataReaderConverterTests.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 | using System.Data.Common;
3 |
4 | namespace DBHelpers.Tests
5 | {
6 | [TestFixture]
7 | public class DataReaderConverterTests
8 | {
9 | [Test]
10 | public void ConvertByName()
11 | {
12 | var reader = CreateReader();
13 | reader.Read();
14 |
15 | var converter = new DataReaderConverter();
16 |
17 | var model = converter.Convert(reader);
18 |
19 | Assert.IsNotNull(model);
20 | Assert.AreEqual(reader["IntCol"], model.IntCol);
21 | Assert.AreEqual(reader["StringCol"], model.StringCol);
22 | Assert.AreEqual(reader["DateCol"], model.DateCol);
23 | Assert.IsNull(model.UnmappedCol);
24 | }
25 |
26 | private DbDataReader CreateReader()
27 | {
28 | var factory = new MockProviderFactory();
29 | var reader = factory.CreateReader();
30 | return reader;
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Src/DBHelpers.Tests/TypeExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Reflection;
4 |
5 | namespace DBHelpers.Tests
6 | {
7 | public static class TypeExtensions
8 | {
9 | public static string[] GetSignatures(this Type type, string methodName, BindingFlags flags)
10 | {
11 | var methods = type.GetMethods(flags).Where(m => m.Name == methodName);
12 |
13 | var signatures = methods.Select(m =>
14 | {
15 | var returnType = GetTypeName(m.ReturnType);
16 | var argumentTypes = m.GetParameters().Select(p => GetTypeName(p.ParameterType));
17 |
18 | return String.Format("{0} {1}({2})", returnType, methodName, String.Join(", ", argumentTypes));
19 | });
20 |
21 | return signatures.ToArray();
22 | }
23 |
24 | public static string GetTypeName(Type type)
25 | {
26 | if (type.IsGenericType)
27 | {
28 | var name = type.Name.Split('`')[0];
29 | var genericArguments = type.GetGenericArguments().Select(t => GetTypeName(t));
30 |
31 | return String.Format("{0}<{1}>", name, String.Join(", ", genericArguments));
32 | }
33 |
34 | return type.Name;
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Src/DBHelpers.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2012
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DBHelpers", "DBHelpers\DBHelpers.csproj", "{DECB23E4-A87D-433F-9066-0428C2C6466E}"
5 | EndProject
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DBHelpers.Tests", "DBHelpers.Tests\DBHelpers.Tests.csproj", "{C3A369D0-68CD-4DDF-8607-8AAAB62EB39D}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {DECB23E4-A87D-433F-9066-0428C2C6466E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {DECB23E4-A87D-433F-9066-0428C2C6466E}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {DECB23E4-A87D-433F-9066-0428C2C6466E}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {DECB23E4-A87D-433F-9066-0428C2C6466E}.Release|Any CPU.Build.0 = Release|Any CPU
18 | {C3A369D0-68CD-4DDF-8607-8AAAB62EB39D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {C3A369D0-68CD-4DDF-8607-8AAAB62EB39D}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {C3A369D0-68CD-4DDF-8607-8AAAB62EB39D}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {C3A369D0-68CD-4DDF-8607-8AAAB62EB39D}.Release|Any CPU.Build.0 = Release|Any CPU
22 | EndGlobalSection
23 | GlobalSection(SolutionProperties) = preSolution
24 | HideSolutionNode = FALSE
25 | EndGlobalSection
26 | EndGlobal
27 |
--------------------------------------------------------------------------------
/Src/DBHelpers.Tests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("DBHelper.Tests")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("DBHelper.Tests")]
13 | [assembly: AssemblyCopyright("Copyright © 2013")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("9939d625-e194-459b-beef-ddd0d6e76350")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Src/DBHelpers/DataReaderExtensions.cs:
--------------------------------------------------------------------------------
1 | #region License
2 | // Copyright 2010-2015 Natan Vivo - http://github.com/nvivo/dbhelpers
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | #endregion
16 |
17 | using System;
18 | using System.Data.Common;
19 | using System.Globalization;
20 |
21 | namespace DBHelpers
22 | {
23 | public static class DataReaderExtensions
24 | {
25 | public static T Get(this DbDataReader reader, int ordinal, IFormatProvider provider)
26 | {
27 | return DBConvert.To(reader[ordinal], provider);
28 | }
29 |
30 | public static T Get(this DbDataReader reader, int ordinal)
31 | {
32 | return DBConvert.To(reader[ordinal], CultureInfo.CurrentCulture);
33 | }
34 |
35 | public static T Get(this DbDataReader reader, string name, IFormatProvider provider)
36 | {
37 | return DBConvert.To(reader[name], provider);
38 | }
39 |
40 | public static T Get(this DbDataReader reader, string name)
41 | {
42 | return DBConvert.To(reader[name], CultureInfo.CurrentCulture);
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Src/DBHelpers/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | #region License
2 | // Copyright 2010-2015 Natan Vivo - http://github.com/nvivo/dbhelpers
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | #endregion
16 |
17 | using System.Reflection;
18 | using System.Runtime.CompilerServices;
19 | using System.Runtime.InteropServices;
20 |
21 | // General Information about an assembly is controlled through the following
22 | // set of attributes. Change these attribute values to modify the information
23 | // associated with an assembly.
24 | [assembly: AssemblyTitle("DBHelpers")]
25 | [assembly: AssemblyDescription("DBHelpers")]
26 | [assembly: AssemblyProduct("DBHelpers")]
27 | [assembly: AssemblyCopyright("Copyright © Natan Vivo 2010-2015")]
28 |
29 | // Setting ComVisible to false makes the types in this assembly not visible
30 | // to COM components. If you need to access a type in this assembly from
31 | // COM, set the ComVisible attribute to true on that type.
32 | [assembly: ComVisible(false)]
33 |
34 | // The following GUID is for the ID of the typelib if this project is exposed to COM
35 | [assembly: Guid("8874ddf4-cd68-49fe-83c1-753d7f3f99c6")]
36 |
37 | // Version information for an assembly consists of the following four values:
38 | //
39 | // Major Version
40 | // Minor Version
41 | // Build Number
42 | // Revision
43 | //
44 | // You can specify all the values or you can default the Build and Revision Numbers
45 | // by using the '*' as shown below:
46 | // [assembly: AssemblyVersion("1.0.*")]
47 | [assembly: AssemblyVersion("1.1.0")]
48 | [assembly: AssemblyFileVersion("1.1.0")]
49 |
--------------------------------------------------------------------------------
/Src/DBHelpers.Tests/MockProviderFactory.cs:
--------------------------------------------------------------------------------
1 | using Moq;
2 | using Moq.Protected;
3 | using System;
4 | using System.Data;
5 | using System.Data.Common;
6 |
7 | namespace DBHelpers.Tests
8 | {
9 | public class MockProviderFactory : DbProviderFactory
10 | {
11 | public class DataReaderModel
12 | {
13 | public DateTime DateCol { get; set; }
14 | public int IntCol { get; set; }
15 | public string StringCol { get; set; }
16 | public string UnmappedCol { get; set; }
17 | }
18 |
19 | public Func NewConnection = () => new Mock().Object;
20 | public Func NewParameter = () => new Mock().Object;
21 | public Func NewDataAdapter = () => new Mock().Object;
22 |
23 | public override DbCommand CreateCommand()
24 | {
25 | var command = new Mock();
26 |
27 | command
28 | .Protected()
29 | .Setup("ExecuteDbDataReader", ItExpr.IsAny())
30 | .Returns(() => CreateReader());
31 |
32 | return command.Object;
33 | }
34 |
35 | public override DbCommandBuilder CreateCommandBuilder()
36 | {
37 | var mock = new Mock();
38 |
39 | mock.Protected()
40 | .Setup("GetParameterPlaceholder", ItExpr.IsAny())
41 | .Returns((int i) => "$p" + i);
42 |
43 | return mock.Object;
44 | }
45 |
46 | public override DbConnection CreateConnection()
47 | {
48 | return NewConnection();
49 | }
50 |
51 | public override DbDataAdapter CreateDataAdapter()
52 | {
53 | return NewDataAdapter();
54 | }
55 |
56 | public override DbParameter CreateParameter()
57 | {
58 | return NewParameter();
59 | }
60 |
61 | public DbDataReader CreateReader()
62 | {
63 | var dt = new DataTable();
64 | dt.Columns.Add("IntCol", typeof(int));
65 | dt.Columns.Add("StringCol", typeof(string));
66 | dt.Columns.Add("DateCol", typeof(DateTime));
67 |
68 | for (int i = 0; i < 50; i++)
69 | dt.Rows.Add(i, "row " + i, DateTime.Today.AddDays(i));
70 |
71 | return dt.CreateDataReader();
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/Src/DBHelpers/DataReaderConverter.cs:
--------------------------------------------------------------------------------
1 | #region License
2 | // Copyright 2010-2015 Natan Vivo - http://github.com/nvivo/dbhelpers
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | #endregion
16 |
17 | using System.Collections.Generic;
18 | using System.Data.Common;
19 | using System.Reflection;
20 |
21 | namespace DBHelpers
22 | {
23 | public class DataReaderConverter where T : new()
24 | {
25 | private class Mapping
26 | {
27 | public int Index;
28 | public PropertyInfo Property;
29 | }
30 |
31 | private Mapping[] _mappings;
32 | private DbDataReader _lastReader;
33 |
34 | public T Convert(DbDataReader reader)
35 | {
36 | if (_mappings == null || reader != _lastReader)
37 | _mappings = MapProperties(reader);
38 |
39 | var o = new T();
40 |
41 | foreach (var mapping in _mappings)
42 | {
43 | var prop = mapping.Property;
44 | var rawValue = reader.GetValue(mapping.Index);
45 | var value = DBConvert.To(prop.PropertyType, rawValue);
46 | prop.SetValue(o, value, null);
47 | }
48 |
49 | _lastReader = reader;
50 |
51 | return o;
52 | }
53 |
54 | private Mapping[] MapProperties(DbDataReader reader)
55 | {
56 | var fieldCount = reader.FieldCount;
57 |
58 | var fields = new Dictionary(fieldCount);
59 |
60 | for (var i = 0; i < fieldCount; i++)
61 | fields.Add(reader.GetName(i).ToLowerInvariant(), i);
62 |
63 | var type = typeof(T);
64 |
65 | var mapping = new List(fieldCount);
66 |
67 | foreach (var prop in type.GetProperties())
68 | {
69 | var name = prop.Name.ToLowerInvariant();
70 |
71 | int index;
72 |
73 | if (fields.TryGetValue(name, out index))
74 | mapping.Add(new Mapping() { Index = index, Property = prop });
75 | }
76 |
77 | return mapping.ToArray();
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/Src/DBHelpers/DBHelpers.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {DECB23E4-A87D-433F-9066-0428C2C6466E}
8 | Library
9 | Properties
10 | DBHelpers
11 | DBHelpers
12 | v4.5
13 | 512
14 |
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 | false
25 |
26 |
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 | false
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
60 |
--------------------------------------------------------------------------------
/Src/DBHelpers.Tests/DBHelpers.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {C3A369D0-68CD-4DDF-8607-8AAAB62EB39D}
8 | Library
9 | Properties
10 | DBHelpers.Tests
11 | DBHelpers.Tests
12 | v4.5
13 | 512
14 |
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 | false
25 |
26 |
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 | false
34 |
35 |
36 |
37 | False
38 | ..\packages\Moq.4.2.1402.2112\lib\net40\Moq.dll
39 |
40 |
41 | ..\packages\NUnit.2.6.3\lib\nunit.framework.dll
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | {decb23e4-a87d-433f-9066-0428c2c6466e}
69 | DBHelpers
70 |
71 |
72 |
73 |
74 |
75 |
76 |
83 |
--------------------------------------------------------------------------------
/Src/DBHelpers.Tests/BaseOverloadTests.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 |
7 | namespace DBHelpers.Tests
8 | {
9 | public abstract class BaseOverloadTests
10 | {
11 | protected virtual IEnumerable GetRequiredInstanceSignatures()
12 | {
13 | return null;
14 | }
15 |
16 | protected virtual IEnumerable GetRequiredStaticSignatures()
17 | {
18 | return null;
19 | }
20 |
21 | protected virtual IEnumerable GetExistingInstanceSignatures()
22 | {
23 | return null;
24 | }
25 |
26 | protected virtual IEnumerable GetExistingStaticSignatures()
27 | {
28 | return null;
29 | }
30 |
31 | [TestCaseSource("RequiredInstanceSignaturesTestSource")]
32 | public void RequiredInstanceSignaturesExist(bool pass)
33 | {
34 | Assert.That(pass, "The signature does not exists when it should.");
35 | }
36 |
37 | [TestCaseSource("RequiredStaticSignaturesTestSource")]
38 | public void RequiredStaticSignaturesExist(bool pass)
39 | {
40 | Assert.That(pass, "The signature does not exists when it should.");
41 | }
42 |
43 | [TestCaseSource("TestedInstanceSignaturesTestSource")]
44 | public void TestedInstanceSignatures(bool pass)
45 | {
46 | Assert.That(pass, "Public instance signature exists but is not required.");
47 | }
48 |
49 | [TestCaseSource("TestedStaticSignaturesTestSource")]
50 | public void TestedStaticSignatures(bool pass)
51 | {
52 | Assert.That(pass, "Public static signature exists but is not required.");
53 | }
54 |
55 | public IEnumerable RequiredInstanceSignaturesTestSource()
56 | {
57 | var existing = GetExistingInstanceSignatures() ?? new string[0];
58 | var required = GetRequiredInstanceSignatures() ?? new string[0];
59 |
60 | if (required.Count() == 0)
61 | yield return new TestCaseData(true).SetName("No required signatures to test.");
62 |
63 | foreach (var sig in required)
64 | {
65 | bool pass = existing.Contains(sig);
66 | yield return new TestCaseData(pass).SetName(sig);
67 | }
68 | }
69 |
70 | protected IEnumerable TestedInstanceSignaturesTestSource()
71 | {
72 | var existing = GetExistingInstanceSignatures() ?? new string[0];
73 | var required = GetRequiredInstanceSignatures() ?? new string[0];
74 |
75 | if (required.Count() == 0)
76 | yield return new TestCaseData(true).SetName("No required signatures to test.");
77 |
78 | foreach (var sig in existing)
79 | {
80 | bool pass = required.Contains(sig);
81 | yield return new TestCaseData(pass).SetName(sig);
82 | }
83 | }
84 |
85 | protected IEnumerable RequiredStaticSignaturesTestSource()
86 | {
87 | var existing = GetExistingStaticSignatures() ?? new string[0];
88 | var required = GetRequiredStaticSignatures() ?? new string[0];
89 |
90 | if (required.Count() == 0)
91 | yield return new TestCaseData(true).SetName("No required signatures to test.");
92 |
93 | foreach (var sig in required)
94 | {
95 | bool pass = existing.Contains(sig);
96 | yield return new TestCaseData(pass).SetName(sig);
97 | }
98 | }
99 |
100 | protected IEnumerable TestedStaticSignaturesTestSource()
101 | {
102 | var existing = GetExistingStaticSignatures() ?? new string[0];
103 | var required = GetRequiredStaticSignatures() ?? new string[0];
104 |
105 | if (required.Count() == 0)
106 | yield return new TestCaseData(true).SetName("No required signatures to test.");
107 |
108 | foreach (var sig in existing)
109 | {
110 | bool pass = required.Contains(sig);
111 | yield return new TestCaseData(pass).SetName(sig);
112 | }
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/Src/DBHelpers.Tests/DBConvertOverloadTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using System.Text;
6 |
7 | namespace DBHelpers.Tests
8 | {
9 | public class DBConvertOverloadTests : BaseOverloadTests
10 | {
11 | protected override IEnumerable GetRequiredStaticSignatures()
12 | {
13 | return new string[] {
14 | "Boolean ToBoolean(Object)",
15 | "Boolean ToBoolean(Object, IFormatProvider)",
16 |
17 | "SByte ToSByte(Object)",
18 | "SByte ToSByte(Object, IFormatProvider)",
19 |
20 | "Int16 ToInt16(Object)",
21 | "Int16 ToInt16(Object, IFormatProvider)",
22 |
23 | "Int32 ToInt32(Object)",
24 | "Int32 ToInt32(Object, IFormatProvider)",
25 |
26 | "Int64 ToInt64(Object)",
27 | "Int64 ToInt64(Object, IFormatProvider)",
28 |
29 | "Byte ToByte(Object)",
30 | "Byte ToByte(Object, IFormatProvider)",
31 |
32 | "UInt16 ToUInt16(Object)",
33 | "UInt16 ToUInt16(Object, IFormatProvider)",
34 |
35 | "UInt32 ToUInt32(Object)",
36 | "UInt32 ToUInt32(Object, IFormatProvider)",
37 |
38 | "UInt64 ToUInt64(Object)",
39 | "UInt64 ToUInt64(Object, IFormatProvider)",
40 |
41 | "Decimal ToDecimal(Object)",
42 | "Decimal ToDecimal(Object, IFormatProvider)",
43 |
44 | "Single ToSingle(Object)",
45 | "Single ToSingle(Object, IFormatProvider)",
46 |
47 | "Double ToDouble(Object)",
48 | "Double ToDouble(Object, IFormatProvider)",
49 |
50 | "Char ToChar(Object)",
51 | "Char ToChar(Object, IFormatProvider)",
52 |
53 | "DateTime ToDateTime(Object)",
54 | "DateTime ToDateTime(Object, IFormatProvider)",
55 |
56 | "Guid ToGuid(Object)",
57 |
58 | "Nullable ToNullableBoolean(Object)",
59 | "Nullable ToNullableBoolean(Object, IFormatProvider)",
60 |
61 | "Nullable ToNullableSByte(Object)",
62 | "Nullable ToNullableSByte(Object, IFormatProvider)",
63 |
64 | "Nullable ToNullableInt16(Object)",
65 | "Nullable ToNullableInt16(Object, IFormatProvider)",
66 |
67 | "Nullable ToNullableInt32(Object)",
68 | "Nullable ToNullableInt32(Object, IFormatProvider)",
69 |
70 | "Nullable ToNullableInt64(Object)",
71 | "Nullable ToNullableInt64(Object, IFormatProvider)",
72 |
73 | "Nullable ToNullableByte(Object)",
74 | "Nullable ToNullableByte(Object, IFormatProvider)",
75 |
76 | "Nullable ToNullableUInt16(Object)",
77 | "Nullable ToNullableUInt16(Object, IFormatProvider)",
78 |
79 | "Nullable ToNullableUInt32(Object)",
80 | "Nullable ToNullableUInt32(Object, IFormatProvider)",
81 |
82 | "Nullable ToNullableUInt64(Object)",
83 | "Nullable ToNullableUInt64(Object, IFormatProvider)",
84 |
85 | "Nullable ToNullableDecimal(Object)",
86 | "Nullable ToNullableDecimal(Object, IFormatProvider)",
87 |
88 | "Nullable ToNullableSingle(Object)",
89 | "Nullable ToNullableSingle(Object, IFormatProvider)",
90 |
91 | "Nullable ToNullableDouble(Object)",
92 | "Nullable ToNullableDouble(Object, IFormatProvider)",
93 |
94 | "Nullable ToNullableChar(Object)",
95 | "Nullable ToNullableChar(Object, IFormatProvider)",
96 |
97 | "Nullable ToNullableDateTime(Object)",
98 | "Nullable ToNullableDateTime(Object, IFormatProvider)",
99 |
100 | "Nullable ToNullableGuid(Object)",
101 |
102 | "String ToString(Object)",
103 | "String ToString(Object, IFormatProvider)",
104 |
105 | "Object To(Type, Object)",
106 | "Object To(Type, Object, IFormatProvider)",
107 |
108 | "T To(Object)",
109 | "T To(Object, IFormatProvider)",
110 |
111 | "Object ToDBValue(Object)"
112 | };
113 | }
114 |
115 | protected override IEnumerable GetExistingStaticSignatures()
116 | {
117 | string[] methods = {
118 | "ToBoolean",
119 | "ToSByte",
120 | "ToInt16",
121 | "ToInt32",
122 | "ToInt64",
123 | "ToByte",
124 | "ToUInt16",
125 | "ToUInt32",
126 | "ToUInt64",
127 | "ToDecimal",
128 | "ToSingle",
129 | "ToDouble",
130 | "ToChar",
131 | "ToDateTime",
132 | "ToGuid",
133 | "ToNullableBoolean",
134 | "ToNullableSByte",
135 | "ToNullableInt16",
136 | "ToNullableInt32",
137 | "ToNullableInt64",
138 | "ToNullableByte",
139 | "ToNullableUInt16",
140 | "ToNullableUInt32",
141 | "ToNullableUInt64",
142 | "ToNullableDecimal",
143 | "ToNullableSingle",
144 | "ToNullableDouble",
145 | "ToNullableChar",
146 | "ToNullableDateTime",
147 | "ToNullableGuid",
148 | "ToString",
149 | "To",
150 | "ToDBValue",
151 | };
152 |
153 | var type = typeof(DBConvert);
154 |
155 | foreach (var method in methods)
156 | foreach (var signature in type.GetSignatures(method, BindingFlags.Public | BindingFlags.Static))
157 | yield return signature;
158 | }
159 |
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/Src/DBHelpers.Tests/DBHelperTests.cs:
--------------------------------------------------------------------------------
1 | using Moq;
2 | using Moq.Protected;
3 | using NUnit.Framework;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Data;
7 | using System.Data.Common;
8 | using System.Data.SqlClient;
9 |
10 | namespace DBHelpers.Tests
11 | {
12 | [TestFixture]
13 | public class DBHelperTests
14 | {
15 | private InternalDBHelper DB = new InternalDBHelper();
16 |
17 | [Test]
18 | public void CreateCommand_NoParameters()
19 | {
20 | var db = NewSqlHelper();
21 |
22 | var commandText = "select * from table";
23 | var command = db.CreateCommand(commandText);
24 |
25 | Assert.AreEqual(commandText, command.CommandText);
26 | Assert.AreEqual(CommandType.Text, command.CommandType);
27 | Assert.AreEqual(0, command.Parameters.Count);
28 | }
29 |
30 | [Test]
31 | public void CreateCommand_WithParameters()
32 | {
33 | var db = NewSqlHelper();
34 |
35 | var commandText = "text {0}, {1}, {2}, {3}";
36 | var p0 = 1;
37 | var p1 = "foo";
38 | var p2 = DateTime.Now;
39 | var p3 = new RawValue("(raw text)");
40 | var command = db.CreateCommand(commandText, p0, p1, p2, p3);
41 |
42 | Assert.AreEqual("text @p0, @p1, @p2, (raw text)", command.CommandText);
43 | Assert.AreEqual(CommandType.Text, command.CommandType);
44 | Assert.AreEqual(3, command.Parameters.Count);
45 | Assert.AreEqual(p0, command.Parameters[0].Value);
46 | Assert.AreEqual(p1, command.Parameters[1].Value);
47 | Assert.AreEqual(p2, command.Parameters[2].Value);
48 | }
49 |
50 | [Test]
51 | public void CreateCommand_NullValuesSentAsDBNull()
52 | {
53 | var db = NewSqlHelper();
54 |
55 | var command = db.CreateCommand("text {0}", new string[] { null });
56 |
57 | Assert.AreEqual(DBNull.Value, command.Parameters[0].Value);
58 | }
59 |
60 | [Test]
61 | public void CreateParameterName()
62 | {
63 | var param = DB.CreateParameterName_(123);
64 | Assert.AreEqual("$p123", param);
65 | }
66 |
67 | [Test]
68 | public void ExecuteArray()
69 | {
70 | var command = DB.Factory.CreateCommand();
71 | var arr = DB.ExecuteArray(command);
72 |
73 | Assert.AreEqual(50, arr.Length);
74 | }
75 |
76 | [Test]
77 | public void ExecuteDataSet()
78 | {
79 | var adapter = new Mock();
80 | var factory = new MockProviderFactory() { NewDataAdapter = () => adapter.Object };
81 |
82 | adapter.Setup(a => a.Fill(It.IsAny()));
83 | var db = new DBHelper(factory, "cn");
84 |
85 | var command = db.Factory.CreateCommand();
86 | db.ExecuteDataSet(command);
87 |
88 | adapter.VerifyAll();
89 | }
90 |
91 | [Test]
92 | public void ExecuteDataTable()
93 | {
94 | Assert.Inconclusive("No simple way to check for DbDataAdapter.Fill(DataTable).");
95 | }
96 |
97 | [Test]
98 | public void ExecuteDictionary()
99 | {
100 | var command = DB.Factory.CreateCommand();
101 | var dict = DB.ExecuteDictionary(command);
102 |
103 | Assert.AreEqual(50, dict.Count);
104 | }
105 |
106 | [Test]
107 | public void ExecuteList()
108 | {
109 | var command = DB.Factory.CreateCommand();
110 | var list = DB.ExecuteList(command);
111 |
112 | Assert.IsNotNull(list);
113 | Assert.AreEqual(50, list.Count);
114 | }
115 |
116 | [Test]
117 | public void ExecuteNonQuery()
118 | {
119 | var mockCommand = new Mock();
120 |
121 | mockCommand.SetupSet(c => c.Connection = It.IsAny());
122 | mockCommand.Setup(c => c.ExecuteNonQuery());
123 |
124 | DB.ExecuteNonQuery(mockCommand.Object);
125 |
126 | mockCommand.VerifyAll();
127 | }
128 |
129 | [Test]
130 | public void ExecuteObject()
131 | {
132 | var command = DB.Factory.CreateCommand();
133 | var obj = DB.ExecuteObject(command);
134 |
135 | Assert.IsNotNull(obj);
136 | Assert.AreEqual(0, obj.IntCol);
137 | Assert.AreEqual("row 0", obj.StringCol);
138 | Assert.AreEqual(DateTime.Today, obj.DateCol);
139 | }
140 |
141 | [Test]
142 | public void ExecuteReader_WithoutConnectionParameter_ShouldCloseConnection()
143 | {
144 | var mockCommand = new Mock();
145 |
146 | mockCommand.SetupSet(c => c.Connection = It.IsAny());
147 | mockCommand.Protected().Setup("ExecuteDbDataReader", CommandBehavior.CloseConnection);
148 |
149 | var reader = DB.ExecuteReader(mockCommand.Object);
150 |
151 | mockCommand.VerifyAll();
152 | }
153 |
154 | [Test]
155 | public void ExecuteReader_WithConnectionParameter_ShouldNotCloseConnection()
156 | {
157 | var mockCommand = new Mock();
158 | var mockConnection = new Mock();
159 |
160 | mockCommand.Protected().Setup("ExecuteDbDataReader", ItExpr.Is(v => v != CommandBehavior.CloseConnection));
161 | DB.ExecuteReader(mockCommand.Object, mockConnection.Object);
162 |
163 | mockCommand.VerifyAll();
164 | }
165 |
166 | [Test]
167 | public void ExecuteScalar()
168 | {
169 | var mockCommand = new Mock();
170 | var expectedValue = 10;
171 |
172 | mockCommand.SetupSet(c => c.Connection = It.IsAny());
173 | mockCommand.Setup(c => c.ExecuteScalar()).Returns(expectedValue);
174 |
175 | var value = DB.ExecuteScalar(mockCommand.Object);
176 |
177 | mockCommand.VerifyAll();
178 | Assert.AreEqual(expectedValue, value);
179 | }
180 |
181 | [TestCaseSource("FillFromReaderSource")]
182 | public void FillFromReader(int startRecord, int maxRecords, int expectedCount, int firstValue)
183 | {
184 | var factory = (MockProviderFactory)DB.Factory;
185 | var reader = factory.CreateReader();
186 |
187 | var list = new List();
188 |
189 | DB.FillFromReader_(reader, startRecord, maxRecords, r => list.Add(r.GetInt32(0)));
190 |
191 | Assert.AreEqual(expectedCount, list.Count, "Invalid row count.");
192 |
193 | if (list.Count > 0)
194 | Assert.AreEqual(firstValue, list[0], "Invalid first value.");
195 | }
196 |
197 | [ExpectedException(typeof(ArgumentOutOfRangeException))]
198 | public void FillFromReader(int startRecord, int maxRecords)
199 | {
200 | var factory = (MockProviderFactory)DB.Factory;
201 | var reader = factory.CreateReader();
202 |
203 | DB.FillFromReader_(reader, startRecord, maxRecords, r => { });
204 | }
205 |
206 | public IEnumerable FillFromReaderSource()
207 | {
208 | var dataSets = new[]
209 | {
210 | // startRecord, maxRecords, expectedCount, firstValue
211 | new [] {0, 0, 50, 0},
212 | new [] {0, -1, 50, 0},
213 | new [] {51, 10, 0, 0},
214 | new [] {0, 100, 50, 0},
215 | new [] {10, 20, 20, 10},
216 | new [] {45, 10, 5, 45}
217 | };
218 |
219 | foreach (var arr in dataSets)
220 | {
221 | string name = String.Format("Start {0}, maxRecords {1} should return {2}", arr[0], arr[1], arr[2]);
222 |
223 | int expectedCount = arr[2];
224 |
225 | if (expectedCount > 0)
226 | name += " with first index " + arr[3];
227 |
228 | yield return new TestCaseData(arr[0], arr[1], arr[2], arr[3]).SetName(name);
229 | }
230 | }
231 |
232 | private InternalDBHelper NewMockHelper()
233 | {
234 | return new InternalDBHelper();
235 | }
236 |
237 | private DBHelper NewSqlHelper()
238 | {
239 | return new DBHelper(SqlClientFactory.Instance, "cn");
240 | }
241 | }
242 | }
243 |
--------------------------------------------------------------------------------
/Src/DBHelpers.Tests/DBConvertTests.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Reflection;
6 | using System.Text;
7 |
8 | namespace DBHelpers.Tests
9 | {
10 | [TestFixture]
11 | public class DBConvertTests
12 | {
13 | [TestCaseSource("NumericConversionCases")]
14 | public void ConvertTo_NumericsFromNumericsInRange_ReturnsCastValue(Type targetType, object sourceValue)
15 | {
16 | var value = DBConvert.To(targetType, sourceValue);
17 | Assert.IsInstanceOf(targetType, value);
18 | }
19 |
20 | [TestCaseSource("NumericTypes")]
21 | [TestCaseSource("NonNumericTypes")]
22 | public void ConvertTo_FromNull_ReturnsDefaultValue(Type targetType)
23 | {
24 | object reference = targetType.IsValueType ? Activator.CreateInstance(targetType) : null;
25 | object value = DBConvert.To(targetType, (object)null);
26 | Assert.AreEqual(reference, value);
27 | }
28 |
29 | [TestCaseSource("NumericTypes")]
30 | [TestCaseSource("NonNumericTypes")]
31 | public void ConvertTo_FromDBNull_ReturnsDefaultValue(Type targetType)
32 | {
33 | object reference = targetType.IsValueType ? Activator.CreateInstance(targetType) : null;
34 | object value = DBConvert.To(targetType, DBNull.Value);
35 | Assert.AreEqual(reference, value);
36 | }
37 |
38 | [TestCaseSource("NumericValues")]
39 | [TestCaseSource("NonNumericValues")]
40 | public void ConvertTo_String_ReturnsNonEmptyValue(object value)
41 | {
42 | string s = DBConvert.To(value);
43 | Assert.IsNotEmpty(s);
44 | }
45 |
46 | [TestCase('A')]
47 | [TestCase("A")]
48 | [TestCase("ABC")]
49 | public void ConvertTo_Char_ReturnsCharOrFirstChar(object value)
50 | {
51 | var c = DBConvert.To(value);
52 | Assert.AreEqual('A', c);
53 | }
54 |
55 | [TestCase("2000-12-31T23:59:59")]
56 | [TestCase("2000-12-31 23:59:59")]
57 | public void ConvertTo_DateTime_ReturnsDateTime(object value)
58 | {
59 | var reference = new DateTime(2000, 12, 31, 23, 59, 59);
60 | var dt = DBConvert.To(value);
61 | Assert.AreEqual(reference, dt);
62 | }
63 |
64 | [TestCase("2000-12-31T23:59:59+03:00")]
65 | [TestCase("2000-12-31 23:59:59+03:00")]
66 | public void ConvertTo_DateTimeOffset_ReturnsDateTimeOffset(object value)
67 | {
68 | var reference = new DateTimeOffset(2000, 12, 31, 23, 59, 59, TimeSpan.FromHours(3));
69 | var dt = DBConvert.To(value);
70 | Assert.AreEqual(reference, dt);
71 | }
72 |
73 | [TestCase("2000-12-31")]
74 | public void ConvertTo_DateTime_ReturnsDate(object value)
75 | {
76 | var reference = new DateTime(2000, 12, 31);
77 | var dt = DBConvert.To(value);
78 | Assert.AreEqual(reference, dt);
79 | }
80 |
81 | [TestCase("5033b416-9f63-4370-a435-1c0c7c102e67")]
82 | [TestCase("5033b4169f634370a4351c0c7c102e67")]
83 | public void ConvertTo_Guid_ReturnsGuid(object value)
84 | {
85 | var reference = Guid.Parse("5033b416-9f63-4370-a435-1c0c7c102e67");
86 | var guid = DBConvert.To(value);
87 |
88 | Assert.AreEqual(reference, guid);
89 | }
90 |
91 | [TestCase(new byte[] { 0, 1, 2 })]
92 | public void ConvertTo_ByteArray_ReturnsByteArray(object value)
93 | {
94 | var arr = DBConvert.To(value);
95 |
96 | Assert.NotNull(arr);
97 | Assert.AreEqual(arr.Length, 3);
98 | }
99 |
100 | [Test]
101 | public void Convert_DBNullToNullable_ReturnsNull()
102 | {
103 | var value = DBNull.Value;
104 |
105 | Assert.IsNull(DBConvert.ToNullableSByte(value), "ToNullableSByte");
106 | Assert.IsNull(DBConvert.ToNullableInt16(value), "ToNullableInt16");
107 | Assert.IsNull(DBConvert.ToNullableInt32(value), "ToNullableInt32");
108 | Assert.IsNull(DBConvert.ToNullableInt64(value), "ToNullableInt64");
109 |
110 | Assert.IsNull(DBConvert.ToNullableByte(value), "ToNullableByte");
111 | Assert.IsNull(DBConvert.ToNullableUInt16(value), "ToNullableUInt16");
112 | Assert.IsNull(DBConvert.ToNullableUInt32(value), "ToNullableUInt32");
113 | Assert.IsNull(DBConvert.ToNullableUInt64(value), "ToNullableUInt64");
114 |
115 | Assert.IsNull(DBConvert.ToNullableSingle(value), "ToNullableSingle");
116 | Assert.IsNull(DBConvert.ToNullableDouble(value), "ToNullableDouble");
117 | Assert.IsNull(DBConvert.ToNullableDecimal(value), "ToNullableDecimal");
118 | Assert.IsNull(DBConvert.ToNullableGuid(value), "ToNullableGuid");
119 |
120 | Assert.IsNull(DBConvert.ToNullableBoolean(value), "ToNullableBoolean");
121 | Assert.IsNull(DBConvert.ToNullableChar(value), "ToNullableChar");
122 | }
123 |
124 | [Test]
125 | public void Convert_NullToNullable_ReturnsNull()
126 | {
127 | var value = (object) null;
128 |
129 | Assert.IsNull(DBConvert.ToNullableSByte(value), "ToNullableSByte");
130 | Assert.IsNull(DBConvert.ToNullableInt16(value), "ToNullableInt16");
131 | Assert.IsNull(DBConvert.ToNullableInt32(value), "ToNullableInt32");
132 | Assert.IsNull(DBConvert.ToNullableInt64(value), "ToNullableInt64");
133 |
134 | Assert.IsNull(DBConvert.ToNullableByte(value), "ToNullableByte");
135 | Assert.IsNull(DBConvert.ToNullableUInt16(value), "ToNullableUInt16");
136 | Assert.IsNull(DBConvert.ToNullableUInt32(value), "ToNullableUInt32");
137 | Assert.IsNull(DBConvert.ToNullableUInt64(value), "ToNullableUInt64");
138 |
139 | Assert.IsNull(DBConvert.ToNullableSingle(value), "ToNullableSingle");
140 | Assert.IsNull(DBConvert.ToNullableDouble(value), "ToNullableDouble");
141 | Assert.IsNull(DBConvert.ToNullableDecimal(value), "ToNullableDecimal");
142 | Assert.IsNull(DBConvert.ToNullableGuid(value), "ToNullableGuid");
143 |
144 | Assert.IsNull(DBConvert.ToNullableBoolean(value), "ToNullableBoolean");
145 | Assert.IsNull(DBConvert.ToNullableChar(value), "ToNullableChar");
146 | }
147 |
148 | [TestCase(true)]
149 | [TestCase("true")]
150 | [TestCase("TRUE")]
151 | [TestCase(1)]
152 | [TestCase('1')]
153 | [TestCase("1")]
154 | public void ConvertTo_Bool_ReturnsTrue(object value)
155 | {
156 | var b = DBConvert.To(value);
157 | Assert.AreEqual(true, b);
158 | }
159 |
160 | [TestCase(false)]
161 | [TestCase("false")]
162 | [TestCase("FALSE")]
163 | [TestCase(0)]
164 | [TestCase('0')]
165 | [TestCase("0")]
166 | public void ConvertTo_Bool_ReturnsFalse(object value)
167 | {
168 | var b = DBConvert.To(value);
169 | Assert.AreEqual(false, b);
170 | }
171 |
172 | private Type[] NumericTypes = {
173 | typeof(SByte),
174 | typeof(Int16),
175 | typeof(Int32),
176 | typeof(Int64),
177 | typeof(Byte),
178 | typeof(UInt16),
179 | typeof(UInt32),
180 | typeof(UInt64),
181 | typeof(Decimal),
182 | typeof(Single),
183 | typeof(Double)
184 | };
185 |
186 | private Type[] NonNumericTypes = {
187 | typeof(char),
188 | typeof(string),
189 | typeof(DateTime),
190 | typeof(Guid),
191 | typeof(bool)
192 | };
193 |
194 | // numeric types used by data providers
195 | private object[] NumericValues = {
196 | (SByte) 127,
197 | (Int16) 127,
198 | (Int32) 127,
199 | (Int64) 127,
200 | (Byte) 127,
201 | (UInt16) 127,
202 | (UInt32) 127,
203 | (UInt64) 127,
204 | (Decimal) 127,
205 | (Single) 127,
206 | (Double) 127
207 | };
208 |
209 | // core non-numeric types used by data providers
210 | private object[] NonNumericValues = {
211 | "string",
212 | 'c',
213 | DateTime.Today,
214 | Guid.Parse("5033b416-9f63-4370-a435-1c0c7c102e67"),
215 | true
216 | };
217 |
218 | private IEnumerable NumericConversionCases()
219 | {
220 | foreach (var type in NumericTypes)
221 | {
222 | foreach (var value in NumericValues)
223 | {
224 | var name = String.Format("{0} to {1}", value.GetType().Name, type.Name);
225 | yield return new TestCaseData(type, value).SetName(name);
226 | }
227 | }
228 | }
229 | }
230 | }
231 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DBHelpers
2 |
3 | DBHelpers is a simple but powerful library for working with plain ADO.NET.
4 |
5 | There are countless frameworks for data access, but most of them get in the way when you need to run direct SQL.
6 | If you want to optimize complex operations, or just want to run some sql without mapping classes, this library is for you.
7 |
8 | This library is not intended to replace any big framework, but is a nice and lightweight addition to any project of any size and it will make you rethink how much you can do using plain ADO.NET.
9 |
10 | ## System Requirements
11 |
12 | DBHelpers is coded for .NET 4.5 and should work with any .NET Data Provider.
13 |
14 | ## Installation
15 |
16 |
17 | You can install DBHelpers from [Nuget](https://www.nuget.org/packages/DBHelpers/):
18 |
19 | ```
20 | Install-Package DBHelpers
21 | ```
22 |
23 | ## Quick Start
24 |
25 | This is not actually required, but makes it easier to work with DBHelper. If possible, add the "providerName" to your connection string:
26 |
27 | ```xml
28 |
29 |
30 |
31 | ```
32 | Then, instantiate the DBHelper:
33 |
34 | ```cs
35 | using DBHelpers;
36 | ...
37 | // if you have provided a providerName in the connectionString, you can just use the connection string name
38 | var db = new DBHelper("MyCN");
39 |
40 | // or instantiate it manually
41 | var db = new DBHelper(System.Data.SqlClient.SqlClientFactory.Instance, "Server=localhost; ...");
42 | ```
43 | And start calling the ExecuteXyz methods:
44 | ```cs
45 | // returning a Scalar value
46 | var count = db.ExecuteScalar("select count(*) from table");
47 |
48 | // returning a DataTable
49 | var dt = db.ExecuteDataTable("select * from table");
50 |
51 | // returning an object (properties are mapped if names match the columns)
52 | var client = db.ExecuteObject("select * from client");
53 | ```
54 |
55 | ## More Details
56 |
57 | ADO.NET is not hard to use, but as any low level component it requires a lot of plumbing. It requires you to explicitly open connections and remember to close them. It requires you to convert values and handle DBNulls. As you work with it, it becomes clear that many things could be automated. This library is basically a lot of overloads that do most of this plumbing and let you concentrate on what you need to do.
58 |
59 | DBHelpers is composed of 2 main helper classes:
60 |
61 | * **DBHelper**: handles query execution
62 | * **DBConvert**: handles common cases of type conversion when using by ADO.NET (similar to System.Convert)
63 |
64 | Once instantiated, DBHelper supports executing queries directly to the database and returning useful types in a single command. For example:
65 |
66 | ```cs
67 | var lastDate = db.ExecuteScalar("select max(change_date) from table");
68 | var arr = db.ExecuteArray("select id from table");
69 | var dict = db.ExecuteDictionary("select id, name from users");
70 | var dt = db.ExecuteDataTable("select * from table");
71 | ```
72 |
73 | The connection is automatically opened, closed and returned to the pool as quickly as possible.
74 |
75 | You can execute any type of query and return any type of object. It support the regular old methods:
76 |
77 | * `ExecuteNonQuery`
78 | * `ExecuteReader`
79 | * `ExecuteScalar`
80 |
81 | The exception is ExecuteScalar which is typed and automatically converts values to the appropriate type.
82 | Additionally we have some more useful methods:
83 |
84 | * `ExecuteDataTable`
85 | * `ExecuteDataSet`
86 | * `ExecuteArray`
87 | * `ExecuteDictionary`
88 | * `ExecuteObject`
89 | * `ExecuteList`
90 |
91 | All methods are optimized for speed and will do as little as possible and return the data in the desired format.
92 |
93 | ### Automatic Type Conversion
94 | ---
95 | When loading data from the database, values can be null/DBNull or can be of a slightly different type. DBHelpers adds some extension methods to DbDataReader, so you can safely expect certain types.
96 |
97 | This is how you can read data from a table to a list of anonymous objects for quick use:
98 |
99 | ```cs
100 | var list = DB.ExecuteList("select id, name, age from people", r => new {
101 | ID = r.Get("id"),
102 | Name = r.Get("name"),
103 | Age = r.Get("age")
104 | });
105 | ```
106 |
107 | DBHelper uses **DBConvert** under the hood for type conversion when it needs to. This class was based on System.Convert, and can be used directly in your code. It provides methods to convert all the basc types and some others between .NET and data providers. It is supposed to be used to get values out of DbDataReader and DataRows, and here is how you would use it:
108 |
109 | ```cs
110 | string value = DBConvert.ToString(reader["someField"]);
111 | int value = DBConvert.ToInt32(reader["someField"]);
112 | int? value = DBConvert.ToNullableDateTime(reader["someField"]);
113 | long? value = DBConvert.To(reader["someField"]);
114 | Guid value = (Guid) DBConvert.To(typeof(Guid), reader["someField"]);
115 |
116 | ```
117 | The core functionality of DBConvert for all "ToXyz" overloads is quite simple:
118 |
119 | * If the value is a DBNull or null, return the default value for the type
120 | * If the value is of the desired type or can be safely cast to that type, cast it and return
121 | * If the value is something else, delegate to System.Convert (if possible)
122 |
123 | This provides a quite safe experience for most cases and allow you to not care about DBNulls or conversions.
124 |
125 | Here is what is expected:
126 | ```cs
127 | var value = db.ExecuteScalar("select cast(null as int)");
128 | // int is a struct, so value = default(int) = 0
129 |
130 | var value = db.ExecuteScalar("select cast(null as varchar)");
131 | // string is a reference type, so value = default(string) = null
132 |
133 | var value = db.ExecuteScalar("select cast(null as int)");
134 | // int? is a nullable, so value = default(int?) = null
135 |
136 | var value = db.ExecuteScalar("select count(*) from t");
137 | // value comes as int or long depending on the provider, but is converted to byte using System.Convert
138 | ```
139 |
140 | Note that the idea is not to hide errors, but to avoid having to write obvious conversions. If you retrieve a byte[] and try to cast to a DateTime, you will get an exception. You are expected to know what you are doing. :-) Check [how System.Convert works](https://msdn.microsoft.com/en-us/library/system.convert(v=vs.110).aspx) for what you need, most of the actual conversion is done there when needed.
141 |
142 | There is also a simple `DBConvert.ToDBValue(object)` that does one simple thing:
143 |
144 | * If the value is null return DBNull.Value, else return the original value
145 |
146 | This is used to when creating commands and passing values to DbParameters.
147 |
148 | ### Some other useful features
149 | ---
150 |
151 | #### Async
152 | All methods have `Async` versions, so you can use tasks. Async support is provided by the .NET data provider directly whenever possible.
153 |
154 | ```cs
155 | await db.ExecuteNonQueryAsync("create table... ");
156 | var ids = await db.ExecuteScalarAsync("select id from table");
157 | using (var reader = await db.ExecuteReaderAsync(query)) { ... }
158 | ```
159 |
160 | #### Batch execution
161 |
162 | All methods have overloads to support using a specific connections, so you can can also run multiple operations in batch:
163 |
164 | ```cs
165 | using (var connection = db.CreateConnection()) {
166 | connection.Open();
167 | db.ExecuteNonQuery(..., connection);
168 | db.ExecuteNonQuery(..., connection);
169 | db.ExecuteNonQuery(..., connection);
170 | return db.ExecuteScalar(..., connection);
171 | }
172 | ```
173 |
174 | #### Custom converters
175 |
176 | All methods that return values accept either `Converter