From 1de570be42ebc5a88254ef8ff2fd2ec22b0e85f1 Mon Sep 17 00:00:00 2001 From: "grzegorz.russek" Date: Sun, 6 Apr 2014 12:10:17 +0000 Subject: [PATCH] --- DynamORM.Tests/DynamORM.Tests.csproj | 38 +++++++++---- .../DynamicTypeSchemaModificationTests.cs | 21 +++++++ DynamORM.Tests/Select/LegacyParserTests.cs | 1 + DynamORM.Tests/Select/ParserTests.cs | 1 + .../Select/RenamedTypedAccessTests.cs | 1 + DynamORM.sln | 13 +---- .../Builders/IDynamicSelectQueryBuilder.cs | 16 ------ .../Implementation/DynamicQueryBuilder.cs | 2 +- .../DynamicSelectQueryBuilder.cs | 28 ---------- DynamORM/DynamORM.csproj | 15 ++++- DynamORM/DynamicDatabase.cs | 55 +++++++++++++++++++ DynamORM/DynamicExtensions.cs | 38 +++++++++---- DynamORM/Mapper/DynamicTypeMap.cs | 8 ++- 13 files changed, 155 insertions(+), 82 deletions(-) diff --git a/DynamORM.Tests/DynamORM.Tests.csproj b/DynamORM.Tests/DynamORM.Tests.csproj index b4a1186..b34fc80 100644 --- a/DynamORM.Tests/DynamORM.Tests.csproj +++ b/DynamORM.Tests/DynamORM.Tests.csproj @@ -13,32 +13,40 @@ v4.0 512 - False False False - False + false obj\$(Configuration)\ + False + False + OnBuildSuccess - true Full False bin\Debug\ DEBUG;TRACE prompt 4 + true + 4194304 + False + Auto + False + AnyCPU - pdbonly + PdbOnly true bin\Release\ TRACE prompt 4 - - - False - obj\ + 4194304 + False + Auto + False + AnyCPU 4194304 @@ -47,13 +55,21 @@ Auto False + + False + + + False + - + + C:\Program Files %28x86%29\NUnit 2.6.3\bin\framework\nunit.framework.dll + - Libraries\System.Data.SQLite.dll + ..\..\..\Libs\SQLite\Any\System.Data.SQLite.dll @@ -81,10 +97,10 @@ Resources.resx - + diff --git a/DynamORM.Tests/Modify/DynamicTypeSchemaModificationTests.cs b/DynamORM.Tests/Modify/DynamicTypeSchemaModificationTests.cs index 1794586..6e1ef5f 100644 --- a/DynamORM.Tests/Modify/DynamicTypeSchemaModificationTests.cs +++ b/DynamORM.Tests/Modify/DynamicTypeSchemaModificationTests.cs @@ -26,6 +26,7 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ +using System.Collections.Generic; using DynamORM.Tests.Helpers; using NUnit.Framework; @@ -41,5 +42,25 @@ namespace DynamORM.Tests.Modify { return Database.Table(); } + + [Test] + public void TestBulkInsert() + { + Assert.AreEqual(2, Database.Insert(new List + { + new users + { + id = 1001, + login = "a", + }, + new users + { + id = 1002, + login = "b", + } + })); + + Assert.AreEqual(2, Database.Delete().Where(u => u.users.id.In(1001, 1002)).Execute()); + } } } \ No newline at end of file diff --git a/DynamORM.Tests/Select/LegacyParserTests.cs b/DynamORM.Tests/Select/LegacyParserTests.cs index 17bdcdb..a2f2961 100644 --- a/DynamORM.Tests/Select/LegacyParserTests.cs +++ b/DynamORM.Tests/Select/LegacyParserTests.cs @@ -34,6 +34,7 @@ using NUnit.Framework; namespace DynamORM.Tests.Select { /// Tests of legacy parser methods. + [TestFixture] public class LegacyParserTests : TestsBase { /// Setup test parameters. diff --git a/DynamORM.Tests/Select/ParserTests.cs b/DynamORM.Tests/Select/ParserTests.cs index 95e8899..051b526 100644 --- a/DynamORM.Tests/Select/ParserTests.cs +++ b/DynamORM.Tests/Select/ParserTests.cs @@ -36,6 +36,7 @@ namespace DynamORM.Tests.Select /// /// New parser tests. /// + [TestFixture] public class ParserTests : TestsBase { /// Setup test parameters. diff --git a/DynamORM.Tests/Select/RenamedTypedAccessTests.cs b/DynamORM.Tests/Select/RenamedTypedAccessTests.cs index 78eedb4..9191154 100644 --- a/DynamORM.Tests/Select/RenamedTypedAccessTests.cs +++ b/DynamORM.Tests/Select/RenamedTypedAccessTests.cs @@ -34,6 +34,7 @@ using NUnit.Framework; namespace DynamORM.Tests.Select { /// Test typed ORM. + [TestFixture] public class RenamedTypedAccessTests : TypedAccessTests { /// Test something fancy... like: select "first", count("first") aggregatefield from "users" group by "first" order by 2 desc;. diff --git a/DynamORM.sln b/DynamORM.sln index 02ecc04..a35f372 100644 --- a/DynamORM.sln +++ b/DynamORM.sln @@ -1,12 +1,11 @@  Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 +# SharpDevelop 4.2.2.8818 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynamORM", "DynamORM\DynamORM.csproj", "{63963ED7-9C78-4672-A4D4-339B6E825503}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynamORM.Tests", "DynamORM.Tests\DynamORM.Tests.csproj", "{D5013B4E-8A1B-4DBB-8FB5-E09935F4F764}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Workbench", "Workbench\Workbench.csproj", "{01429808-B1A9-4272-852E-B2F7649BD788}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -37,16 +36,6 @@ Global {D5013B4E-8A1B-4DBB-8FB5-E09935F4F764}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {D5013B4E-8A1B-4DBB-8FB5-E09935F4F764}.Release|Mixed Platforms.Build.0 = Release|Any CPU {D5013B4E-8A1B-4DBB-8FB5-E09935F4F764}.Release|x86.ActiveCfg = Release|Any CPU - {01429808-B1A9-4272-852E-B2F7649BD788}.Debug|Any CPU.ActiveCfg = Debug|x86 - {01429808-B1A9-4272-852E-B2F7649BD788}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {01429808-B1A9-4272-852E-B2F7649BD788}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {01429808-B1A9-4272-852E-B2F7649BD788}.Debug|x86.ActiveCfg = Debug|x86 - {01429808-B1A9-4272-852E-B2F7649BD788}.Debug|x86.Build.0 = Debug|x86 - {01429808-B1A9-4272-852E-B2F7649BD788}.Release|Any CPU.ActiveCfg = Release|x86 - {01429808-B1A9-4272-852E-B2F7649BD788}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {01429808-B1A9-4272-852E-B2F7649BD788}.Release|Mixed Platforms.Build.0 = Release|x86 - {01429808-B1A9-4272-852E-B2F7649BD788}.Release|x86.ActiveCfg = Release|x86 - {01429808-B1A9-4272-852E-B2F7649BD788}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/DynamORM/Builders/IDynamicSelectQueryBuilder.cs b/DynamORM/Builders/IDynamicSelectQueryBuilder.cs index 169588e..eb5ac98 100644 --- a/DynamORM/Builders/IDynamicSelectQueryBuilder.cs +++ b/DynamORM/Builders/IDynamicSelectQueryBuilder.cs @@ -53,22 +53,6 @@ namespace DynamORM.Builders /// Result of a query. object Scalar(); - #region SubQuery - - /// Adds to the 'From' clause of sub query the contents obtained by - /// parsing the dynamic lambda expressions given. The supported formats are: - /// - Resolve to a string: 'x => "Table AS Alias', where the alias part is optional. - /// - Resolve to an expression: 'x => x.Table.As( x.Alias )', where the alias part is optional. - /// - Generic expression: 'x => x( expression ).As( x.Alias )', where the alias part is mandatory. In this - /// case the alias is not annotated. - /// - /// First argument is parent query, second one is a subquery. - /// The specification for subquery. - /// This instance to permit chaining. - IDynamicSelectQueryBuilder SubQuery(Action subquery, params Func[] func); - - #endregion SubQuery - #region From/Join /// diff --git a/DynamORM/Builders/Implementation/DynamicQueryBuilder.cs b/DynamORM/Builders/Implementation/DynamicQueryBuilder.cs index e8830ca..4c03321 100644 --- a/DynamORM/Builders/Implementation/DynamicQueryBuilder.cs +++ b/DynamORM/Builders/Implementation/DynamicQueryBuilder.cs @@ -360,7 +360,7 @@ namespace DynamORM.Builders.Implementation return ParseConstant(node, pars, columnSchema); } - protected virtual string ParseCommand(DynamicQueryBuilder node, IDictionary pars = null) + internal virtual string ParseCommand(DynamicQueryBuilder node, IDictionary pars = null) { // Getting the command's text... string str = node.CommandText(); // Avoiding spurious "OUTPUT XXX" statements diff --git a/DynamORM/Builders/Implementation/DynamicSelectQueryBuilder.cs b/DynamORM/Builders/Implementation/DynamicSelectQueryBuilder.cs index 42ff4a4..3c90525 100644 --- a/DynamORM/Builders/Implementation/DynamicSelectQueryBuilder.cs +++ b/DynamORM/Builders/Implementation/DynamicSelectQueryBuilder.cs @@ -241,34 +241,6 @@ namespace DynamORM.Builders.Implementation #endregion Execution - #region Subquery - - /// - /// Adds to the 'From' clause of sub query the contents obtained by - /// parsing the dynamic lambda expressions given. The supported formats are: - /// - Resolve to a string: 'x => "Table AS Alias', where the alias part is optional. - /// - Resolve to an expression: 'x => x.Table.As( x.Alias )', where the alias part is optional. - /// - Generic expression: 'x => x( expression ).As( x.Alias )', where the alias part is mandatory. In this - /// case the alias is not annotated. - /// - /// First argument is parent query, second one is a subquery. - /// The specification for subquery. - /// - /// This instance to permit chaining. - /// - public virtual IDynamicSelectQueryBuilder SubQuery(Action subquery, params Func[] func) - { - var sub = func == null || func.Length == 0 ? base.SubQuery() : base.SubQuery(func); - - subquery(this, sub); - - ParseCommand(sub as DynamicQueryBuilder, Parameters); - - return this; - } - - #endregion Subquery - #region From/Join /// diff --git a/DynamORM/DynamORM.csproj b/DynamORM/DynamORM.csproj index 1879792..120421d 100644 --- a/DynamORM/DynamORM.csproj +++ b/DynamORM/DynamORM.csproj @@ -13,6 +13,11 @@ v4.0 512 + False + False + OnBuildSuccess + False + False true @@ -26,17 +31,23 @@ true - pdbonly + PdbOnly true bin\Release\ TRACE prompt 4 true - true + false true bin\Release\DynamORM.xml + + False + Auto + 4194304 + AnyCPU + diff --git a/DynamORM/DynamicDatabase.cs b/DynamORM/DynamicDatabase.cs index 03ab83f..c26ed97 100644 --- a/DynamORM/DynamicDatabase.cs +++ b/DynamORM/DynamicDatabase.cs @@ -286,6 +286,61 @@ namespace DynamORM { return new DynamicInsertQueryBuilder(this).Table(typeof(T)); } + + public virtual int Insert(IEnumerable e) where T : class + { + int affected = 0; + var mapper = DynamicMapperCache.GetMapper(typeof(T)); + + if (mapper != null) + using (var con = Open()) + using (var tra = con.BeginTransaction()) + using (var cmd = con.CreateCommand()) + { + try + { + DynamicPropertyInvoker currentprop = null; + var temp = new Dictionary(); + var parameters = new Dictionary(); + + var ib = Insert() + .SetVirtualMode(true) + .CreateTemporaryParameterAction(p => temp[p.Name] = currentprop) + .CreateParameterAction((p, cp) => parameters[cp] = temp[p.Name]); + + foreach (var prop in mapper.PropertyMap) + if (!mapper.Ignored.Contains(prop.Key)) + { + var col = mapper.PropertyMap.TryGetValue(prop.Key) ?? prop.Key; + currentprop = mapper.ColumnsMap.TryGetValue(col.ToLower()); + + if (currentprop.Get != null) + ib.Insert(col, null); + } + + ib.FillCommand(cmd); + + foreach (var o in e) + { + foreach (var m in parameters) + m.Key.Value = m.Value.Get(o); + + affected += cmd.ExecuteNonQuery(); + } + + tra.Commit(); + } + catch + { + if (tra != null) + tra.Rollback(); + + throw; + } + } + + return affected; + } /// /// Adds to the UPDATE clause the contents obtained by parsing the dynamic lambda expressions given. The supported diff --git a/DynamORM/DynamicExtensions.cs b/DynamORM/DynamicExtensions.cs index a4b0c49..740e6f5 100644 --- a/DynamORM/DynamicExtensions.cs +++ b/DynamORM/DynamicExtensions.cs @@ -816,17 +816,6 @@ namespace DynamORM return b; } - /// Sets the virtual mode on builder. - /// Class implementing interface. - /// The builder on which set delegate. - /// Virtual mode. - /// Returns instance of builder on which virtual mode is set. - public static T SetVirtualMode(this T b, bool virtualMode) where T : IDynamicQueryBuilder - { - b.VirtualMode = virtualMode; - return b; - } - /// Sets the on create real parameter action. /// Class implementing interface. /// The builder on which set delegate. @@ -838,6 +827,33 @@ namespace DynamORM return b; } + /// Sets the virtual mode on builder. + /// Class implementing interface. + /// The builder on which set virtual mode. + /// Virtual mode. + /// Returns instance of builder on which virtual mode is set. + public static T SetVirtualMode(this T b, bool virtualMode) where T : IDynamicQueryBuilder + { + b.VirtualMode = virtualMode; + return b; + } + + /// Creates sub query that can be used inside of from/join/expresions. + /// The builder that will be parent of new sub query. + /// First argument is parent query, second one is a subquery. + /// The specification for subquery. + /// This instance to permit chaining. + public static T SubQuery(this T b, Action subquery, params Func[] func) where T : IDynamicQueryBuilder + { + var sub = func == null || func.Length == 0 ? b.SubQuery() : b.SubQuery(func); + + subquery(b, sub); + + (b as DynamicQueryBuilder).ParseCommand(sub as DynamicQueryBuilder, b.Parameters); + + return b; + } + #endregion Dynamic builders extensions #region Dynamic extensions diff --git a/DynamORM/Mapper/DynamicTypeMap.cs b/DynamORM/Mapper/DynamicTypeMap.cs index 07e7a59..b3b2eb9 100644 --- a/DynamORM/Mapper/DynamicTypeMap.cs +++ b/DynamORM/Mapper/DynamicTypeMap.cs @@ -46,9 +46,11 @@ namespace DynamORM.Mapper public Func Creator { get; private set; } /// Gets map of columns to properties. + /// Key: Column name (lower), Value: . public Dictionary ColumnsMap { get; private set; } /// Gets map of properties to column. + /// Key: Property name, Value: Column name. public Dictionary PropertyMap { get; private set; } /// Gets list of ignored properties. @@ -73,6 +75,7 @@ namespace DynamORM.Mapper { var columnMap = new Dictionary(); var propertyMap = new Dictionary(); + var ignored = new List(); foreach (var pi in Type.GetProperties()) { @@ -89,12 +92,15 @@ namespace DynamORM.Mapper columnMap.Add(col.ToLower(), val); propertyMap.Add(pi.Name, col); + + if (val.Ignore) + ignored.Add(pi.Name); } ColumnsMap = columnMap; PropertyMap = propertyMap; - Ignored = columnMap.Where(i => i.Value.Ignore).Select(i => i.Value.Name).ToList(); + Ignored = ignored; ////columnMap.Where(i => i.Value.Ignore).Select(i => i.Value.Name).ToList(); } private Func CreateCreator()