From 9e40c4e20bb42bbf341542e21f66efccba6084c7 Mon Sep 17 00:00:00 2001 From: "grzegorz.russek" Date: Mon, 18 Jan 2016 07:47:29 +0000 Subject: [PATCH] --- AmalgamationTool/DynamORM.Amalgamation.cs | 75 +++++- DynamORM.Tests/Select/ParserTests.cs | 15 +- .../Implementation/DynamicQueryBuilder.cs | 48 +++- DynamORM/DynamicProcedureInvoker.cs | 27 ++- Tester/Program.cs | 214 ++++++++++++++++-- Tester/Tester.csproj | 6 +- 6 files changed, 352 insertions(+), 33 deletions(-) diff --git a/AmalgamationTool/DynamORM.Amalgamation.cs b/AmalgamationTool/DynamORM.Amalgamation.cs index 8045f48..062b17f 100644 --- a/AmalgamationTool/DynamORM.Amalgamation.cs +++ b/AmalgamationTool/DynamORM.Amalgamation.cs @@ -4433,12 +4433,32 @@ namespace DynamORM public class DynamicProcedureInvoker : DynamicObject, IDisposable { private DynamicDatabase _db; + private List _prefixes; - internal DynamicProcedureInvoker(DynamicDatabase db) + internal DynamicProcedureInvoker(DynamicDatabase db, List prefixes = null) { + _prefixes = prefixes; _db = db; } + /// This is where the magic begins. + /// Binder to create owner. + /// Binder invoke result. + /// Returns true if invoke was performed. + public override bool TryGetMember(GetMemberBinder binder, out object result) + { + List pref = new List(); + + if (_prefixes != null) + pref.AddRange(_prefixes); + + pref.Add(binder.Name); + + result = new DynamicProcedureInvoker(_db, pref); + + return true; + } + /// This is where the magic begins. /// Binder to invoke. /// Binder arguments. @@ -4457,7 +4477,10 @@ namespace DynamORM using (IDbConnection con = _db.Open()) using (IDbCommand cmd = con.CreateCommand()) { - cmd.SetCommand(CommandType.StoredProcedure, binder.Name); + if (_prefixes == null || _prefixes.Count == 0) + cmd.SetCommand(CommandType.StoredProcedure, binder.Name); + else + cmd.SetCommand(CommandType.StoredProcedure, string.Format("{0}.{1}", string.Join(".", _prefixes), binder.Name)); #region Prepare arguments @@ -6979,7 +7002,9 @@ namespace DynamORM { IsDisposed = true; - Schema.Clear(); + if (Schema != null) + Schema.Clear(); + Owner = Name = Alias = null; Schema = null; } @@ -7483,6 +7508,47 @@ namespace DynamORM return string.Format("{0} IN({1})", parent, sbin.ToString()); } + case "NOTIN": + { + if (node.Arguments == null || node.Arguments.Length == 0) + throw new ArgumentException("IN method expects at least one argument: " + node.Arguments.Sketch()); + + bool firstParam = true; + StringBuilder sbin = new StringBuilder(); + foreach (object arg in node.Arguments) + { + if (!firstParam) + sbin.Append(", "); + + if ((arg is IEnumerable || arg is Array) && !(arg is byte[])) + { + IEnumerable vals = arg as IEnumerable; + + if (vals == null && arg is Array) + vals = ((Array)arg).Cast() as IEnumerable; + + if (vals != null) + foreach (object val in vals) + { + if (!firstParam) + sbin.Append(", "); + else + firstParam = false; + + sbin.Append(Parse(val, ref columnSchema, pars: pars)); + } + else + sbin.Append(Parse(arg, ref columnSchema, pars: pars)); + } + else + sbin.Append(Parse(arg, ref columnSchema, pars: pars)); + + firstParam = false; + } + + return string.Format("{0} NOT IN({1})", parent, sbin.ToString()); + } + case "LIKE": if (node.Arguments == null || node.Arguments.Length != 1) throw new ArgumentException("LIKE method expects one argument: " + node.Arguments.Sketch()); @@ -7733,7 +7799,8 @@ namespace DynamORM if (Tables != null) { foreach (ITableInfo t in Tables) - t.Dispose(); + if (t != null) + t.Dispose(); Tables.Clear(); Tables = null; diff --git a/DynamORM.Tests/Select/ParserTests.cs b/DynamORM.Tests/Select/ParserTests.cs index 567615b..36950d6 100644 --- a/DynamORM.Tests/Select/ParserTests.cs +++ b/DynamORM.Tests/Select/ParserTests.cs @@ -26,10 +26,10 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -using System.Linq; using DynamORM.Builders; using DynamORM.Builders.Implementation; using NUnit.Framework; +using System.Linq; namespace DynamORM.Tests.Select { @@ -159,6 +159,19 @@ namespace DynamORM.Tests.Select Assert.AreEqual("SELECT * FROM \"dbo\".\"Users\" AS u", cmd.CommandText()); } + /// + /// Tests from method using invoke with as. + /// + [Test] + public void TestFromTextAs3() + { + IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database); + + cmd.From(u => u("\"dbo\".\"Users\"").As(u.u)); + + Assert.AreEqual("SELECT * FROM \"dbo\".\"Users\" AS u", cmd.CommandText()); + } + /// /// Tests from method using invoke with sub query. /// diff --git a/DynamORM/Builders/Implementation/DynamicQueryBuilder.cs b/DynamORM/Builders/Implementation/DynamicQueryBuilder.cs index 4e3c569..b753e49 100644 --- a/DynamORM/Builders/Implementation/DynamicQueryBuilder.cs +++ b/DynamORM/Builders/Implementation/DynamicQueryBuilder.cs @@ -129,7 +129,9 @@ namespace DynamORM.Builders.Implementation { IsDisposed = true; - Schema.Clear(); + if (Schema != null) + Schema.Clear(); + Owner = Name = Alias = null; Schema = null; } @@ -632,6 +634,47 @@ namespace DynamORM.Builders.Implementation return string.Format("{0} IN({1})", parent, sbin.ToString()); } + + case "NOTIN": + { + if (node.Arguments == null || node.Arguments.Length == 0) + throw new ArgumentException("IN method expects at least one argument: " + node.Arguments.Sketch()); + + bool firstParam = true; + StringBuilder sbin = new StringBuilder(); + foreach (object arg in node.Arguments) + { + if (!firstParam) + sbin.Append(", "); + + if ((arg is IEnumerable || arg is Array) && !(arg is byte[])) + { + IEnumerable vals = arg as IEnumerable; + + if (vals == null && arg is Array) + vals = ((Array)arg).Cast() as IEnumerable; + + if (vals != null) + foreach (object val in vals) + { + if (!firstParam) + sbin.Append(", "); + else + firstParam = false; + + sbin.Append(Parse(val, ref columnSchema, pars: pars)); + } + else + sbin.Append(Parse(arg, ref columnSchema, pars: pars)); + } + else + sbin.Append(Parse(arg, ref columnSchema, pars: pars)); + + firstParam = false; + } + + return string.Format("{0} NOT IN({1})", parent, sbin.ToString()); + } case "LIKE": if (node.Arguments == null || node.Arguments.Length != 1) @@ -883,7 +926,8 @@ namespace DynamORM.Builders.Implementation if (Tables != null) { foreach (ITableInfo t in Tables) - t.Dispose(); + if (t != null) + t.Dispose(); Tables.Clear(); Tables = null; diff --git a/DynamORM/DynamicProcedureInvoker.cs b/DynamORM/DynamicProcedureInvoker.cs index d1bfca8..bbd33af 100644 --- a/DynamORM/DynamicProcedureInvoker.cs +++ b/DynamORM/DynamicProcedureInvoker.cs @@ -53,12 +53,32 @@ namespace DynamORM public class DynamicProcedureInvoker : DynamicObject, IDisposable { private DynamicDatabase _db; + private List _prefixes; - internal DynamicProcedureInvoker(DynamicDatabase db) + internal DynamicProcedureInvoker(DynamicDatabase db, List prefixes = null) { + _prefixes = prefixes; _db = db; } + /// This is where the magic begins. + /// Binder to create owner. + /// Binder invoke result. + /// Returns true if invoke was performed. + public override bool TryGetMember(GetMemberBinder binder, out object result) + { + List pref = new List(); + + if (_prefixes != null) + pref.AddRange(_prefixes); + + pref.Add(binder.Name); + + result = new DynamicProcedureInvoker(_db, pref); + + return true; + } + /// This is where the magic begins. /// Binder to invoke. /// Binder arguments. @@ -77,7 +97,10 @@ namespace DynamORM using (IDbConnection con = _db.Open()) using (IDbCommand cmd = con.CreateCommand()) { - cmd.SetCommand(CommandType.StoredProcedure, binder.Name); + if (_prefixes == null || _prefixes.Count == 0) + cmd.SetCommand(CommandType.StoredProcedure, binder.Name); + else + cmd.SetCommand(CommandType.StoredProcedure, string.Format("{0}.{1}", string.Join(".", _prefixes), binder.Name)); #region Prepare arguments diff --git a/Tester/Program.cs b/Tester/Program.cs index 365f165..e56e518 100644 --- a/Tester/Program.cs +++ b/Tester/Program.cs @@ -1,5 +1,9 @@ using System; -using DynamORM.Mapper; +using System.Collections.Generic; +using System.Data; +using System.Data.SqlClient; +using System.IO; +using System.Text; namespace Tester { @@ -8,7 +12,8 @@ namespace Tester private static DynamORM.DynamicDatabase GetORM() { return new DynamORM.DynamicDatabase(System.Data.SqlClient.SqlClientFactory.Instance, - "packet size=4096;User Id=sa;Password=Sa123;data source=192.168.1.9,1434;initial catalog=MAH_Melle-GAGARIN;", + //"packet size=4096;User Id=sa;Password=Sa123;data source=192.168.1.9,1434;initial catalog=MAH_Melle-GAGARIN;", + "packet size=4096;User Id=sa;Password=sa123;data source=192.168.1.9,1433;initial catalog=MOM_NEXT_Florentyna_WMS_PROD;", DynamORM.DynamicDatabaseOptions.SingleConnection | DynamORM.DynamicDatabaseOptions.SingleTransaction | DynamORM.DynamicDatabaseOptions.SupportStoredProcedures | DynamORM.DynamicDatabaseOptions.SupportSchema | DynamORM.DynamicDatabaseOptions.SupportTop); @@ -18,28 +23,195 @@ namespace Tester // DynamORM.DynamicDatabaseOptions.SupportSchema | DynamORM.DynamicDatabaseOptions.SupportLimitOffset); } - public class ProcResult - { - [Column("sp_Test_Scalar_In_Out")] - public Guid Result { get; set; } - - [Column("outp")] - public Guid Output { get; set; } - } - private static void Main(string[] args) { - using (var db = GetORM()) - { - Guid res1 = db.Procedures.sp_Test_Scalar(); - object res2 = db.Procedures.sp_Test_NonScalar(); - object res3 = db.Procedures.sp_Test_Scalar_In_Out(inp: Guid.NewGuid(), out_outp: Guid.Empty); - ProcResult res4 = db.Procedures.sp_Test_Scalar_In_Out(inp: Guid.NewGuid(), out_outp: Guid.Empty); + //StringBuilder code = new StringBuilder(); + //using (var db = GetORM()) + //{ + // List procs = db.From(x => x.INFORMATION_SCHEMA.ROUTINES).OrderBy(x => x.SPECIFIC_NAME).Where(x => x.ROUTINE_TYPE == "PROCEDURE").Execute().ToList(); - Console.Out.WriteLine(res1); - Console.Out.WriteLine(res2); - Console.Out.WriteLine(res3); - Console.Out.WriteLine(res4.Output); + // foreach (dynamic d in procs) + // PrintWhatYouKnow(d.SPECIFIC_NAME, code); + //} + + //Console.ReadLine(); + //Console.WriteLine(code.ToString()); + //File.WriteAllText("code.cs", code.ToString()); + //Console.ReadLine(); + + Dictionary times = new Dictionary() + { + /*{ new DateTime(2015,03,07,13,00,00), new DateTime(2015,03,07,23,30,00) }, + { new DateTime(2015,03,08,14,00,00), new DateTime(2015,03,08,19,00,00) }, + { new DateTime(2015,03,14,13,00,00), new DateTime(2015,03,15,01,30,00) }, + { new DateTime(2015,03,15,14,00,00), new DateTime(2015,03,16,00,00,00) }, + { new DateTime(2015,03,28,13,00,00), new DateTime(2015,03,28,22,30,00) }, + { new DateTime(2015,03,29,14,00,00), new DateTime(2015,03,29,21,00,00) }, + { new DateTime(2015,04,02,20,30,00), new DateTime(2015,04,03,00,30,00) }, + { new DateTime(2015,04,04,12,00,00), new DateTime(2015,04,04,23,30,00) }, + { new DateTime(2015,04,05,15,00,00), new DateTime(2015,04,05,21,00,00) }, + { new DateTime(2015,04,06,18,00,00), new DateTime(2015,04,06,23,30,00) }, + { new DateTime(2015,04,07,20,00,00), new DateTime(2015,04,08,00,00,00) }, + { new DateTime(2015,04,08,20,00,00), new DateTime(2015,04,08,23,30,00) }, + { new DateTime(2015,04,09,22,30,00), new DateTime(2015,04,10,00,00,00) }, + { new DateTime(2015,04,10,21,00,00), new DateTime(2015,04,11,00,00,00) }, + { new DateTime(2015,04,11,13,00,00), new DateTime(2015,04,11,18,00,00) }, + { new DateTime(2015,04,11,20,30,00), new DateTime(2015,04,11,23,30,00) }, + { new DateTime(2015,04,12,10,00,00), new DateTime(2015,04,12,13,00,00) }, + { new DateTime(2015,04,12,16,00,00), new DateTime(2015,04,13,00,00,00) }, + { new DateTime(2015,04,13,21,30,00), new DateTime(2015,04,14,00,00,00) }, + { new DateTime(2015,04,14,21,00,00), new DateTime(2015,04,15,00,30,00) }, + { new DateTime(2015,04,17,20,30,00), new DateTime(2015,04,17,23,30,00) }, + { new DateTime(2015,04,18,14,00,00), new DateTime(2015,04,18,18,30,00) }, + { new DateTime(2015,04,18,20,30,00), new DateTime(2015,04,19,02,00,00) }, + { new DateTime(2015,04,19,13,30,00), new DateTime(2015,04,19,17,00,00) }, + { new DateTime(2015,04,19,19,00,00), new DateTime(2015,04,20,00,00,00) }, + { new DateTime(2015,04,20,21,00,00), new DateTime(2015,04,21,00,00,00) }, + { new DateTime(2015,04,21,21,30,00), new DateTime(2015,04,22,00,00,00) }, + { new DateTime(2015,04,22,21,00,00), new DateTime(2015,04,22,23,30,00) }, + { new DateTime(2015,04,23,20,30,00), new DateTime(2015,04,24,00,00,00) }, + { new DateTime(2015,04,25,09,30,00), new DateTime(2015,04,25,15,00,00) }, + { new DateTime(2015,04,25,15,30,00), new DateTime(2015,04,25,19,30,00) }, + { new DateTime(2015,04,25,21,00,00), new DateTime(2015,04,26,02,00,00) }, + { new DateTime(2015,04,26,10,00,00), new DateTime(2015,04,26,12,00,00) }, + { new DateTime(2015,04,26,18,00,00), new DateTime(2015,04,26,19,30,00) }, + { new DateTime(2015,04,26,20,00,00), new DateTime(2015,04,27,00,00,00) }, + { new DateTime(2015,04,27,20,30,00), new DateTime(2015,04,28,01,00,00) }, + { new DateTime(2015,04,28,20,00,00), new DateTime(2015,04,29,01,00,00) }, + { new DateTime(2015,04,29,20,30,00), new DateTime(2015,04,30,01,00,00) }, + { new DateTime(2015,04,30,21,00,00), new DateTime(2015,05,01,02,30,00) }, + { new DateTime(2015,05,01,10,00,00), new DateTime(2015,05,01,14,30,00) }, + { new DateTime(2015,05,02,11,00,00), new DateTime(2015,05,02,17,30,00) }, + { new DateTime(2015,05,03,10,00,00), new DateTime(2015,05,03,22,00,00) }, + { new DateTime(2015,05,04,20,30,00), new DateTime(2015,05,05,01,00,00) }, + { new DateTime(2015,05,05,17,30,00), new DateTime(2015,05,05,19,00,00) }, + { new DateTime(2015,05,05,20,30,00), new DateTime(2015,05,06,01,00,00) }, + { new DateTime(2015,05,06,17,30,00), new DateTime(2015,05,06,19,00,00) }, + { new DateTime(2015,05,06,20,00,00), new DateTime(2015,05,07,01,00,00) }, + { new DateTime(2015,05,07,20,30,00), new DateTime(2015,05,08,01,00,00) }, + { new DateTime(2015,05,08,17,30,00), new DateTime(2015,05,08,19,00,00) }, + { new DateTime(2015,05,08,20,30,00), new DateTime(2015,05,09,02,00,00) }, + { new DateTime(2015,05,09,11,00,00), new DateTime(2015,05,09,16,30,00) }, + { new DateTime(2015,05,10,10,00,00), new DateTime(2015,05,10,15,30,00) }, + { new DateTime(2015,05,10,16,30,00), new DateTime(2015,05,10,23,30,00) }, + { new DateTime(2015,05,11,21,00,00), new DateTime(2015,05,12,01,00,00) }, + { new DateTime(2015,05,12,21,30,00), new DateTime(2015,05,13,01,30,00) }, + { new DateTime(2015,05,13,20,30,00), new DateTime(2015,05,14,00,30,00) }, + { new DateTime(2015,05,14,21,00,00), new DateTime(2015,05,15,02,00,00) }, + { new DateTime(2015,05,15,22,00,00), new DateTime(2015,05,16,02,00,00) }, + { new DateTime(2015,05,16,16,00,00), new DateTime(2015,05,17,01,00,00) }, + { new DateTime(2015,05,17,19,00,00), new DateTime(2015,05,18,00,30,00) }, + { new DateTime(2015,05,18,20,30,00), new DateTime(2015,05,19,01,00,00) }, + { new DateTime(2015,05,19,13,00,00), new DateTime(2015,05,19,15,00,00) }, + { new DateTime(2015,05,19,20,00,00), new DateTime(2015,05,20,00,30,00) }, + { new DateTime(2015,05,20,20,30,00), new DateTime(2015,05,21,00,00,00) }, + { new DateTime(2015,05,21,21,00,00), new DateTime(2015,05,21,23,00,00) }, + { new DateTime(2015,05,22,20,30,00), new DateTime(2015,05,23,02,30,00) }, + { new DateTime(2015,05,23,09,30,00), new DateTime(2015,05,23,17,30,00) }, + { new DateTime(2015,05,23,18,30,00), new DateTime(2015,05,23,22,30,00) }, + { new DateTime(2015,05,24,13,00,00), new DateTime(2015,05,25,00,00,00) }, + { new DateTime(2015,06,02,20,00,00), new DateTime(2015,06,02,23,00,00) }, + { new DateTime(2015,06,05,17,30,00), new DateTime(2015,06,05,19,30,00) },*/ + { new DateTime(2015,05,26,21,00,00), new DateTime(2015,05,26,23,30,00) }, + { new DateTime(2015,05,27,21,00,00), new DateTime(2015,05,28,01,00,00) }, + { new DateTime(2015,05,28,20,00,00), new DateTime(2015,05,29,00,00,00) }, + { new DateTime(2015,05,30,10,30,00), new DateTime(2015,05,30,14,30,00) }, + { new DateTime(2015,05,30,16,00,00), new DateTime(2015,05,30,21,00,00) }, + { new DateTime(2015,05,30,22,00,00), new DateTime(2015,05,31,02,30,00) }, + { new DateTime(2015,05,31,13,30,00), new DateTime(2015,05,31,15,30,00) }, + { new DateTime(2015,05,31,16,30,00), new DateTime(2015,05,31,23,30,00) }, + { new DateTime(2015,06,01,21,00,00), new DateTime(2015,06,01,22,00,00) }, + { new DateTime(2015,06,04,18,00,00), new DateTime(2015,06,04,22,00,00) }, + }; + + StringBuilder inserts = new StringBuilder(); + + int counter = 0; + + foreach (var item in times) + AddInserts(inserts, item.Key, item.Value, ref counter); + + File.WriteAllText("times.sql", inserts.ToString()); + } + + private static void AddInserts(StringBuilder sb, DateTime from, DateTime to, ref int counter) + { + string format = @" +INSERT INTO ticket_change(ticket, ""time"", author, field, oldvalue, newvalue) VALUES (26114, {0}, 'grzegorz.russek', 'comment', '{1}', 'Google calendar import.'); +INSERT INTO ticket_change(ticket, ""time"", author, field, oldvalue, newvalue) VALUES (26114, {0}, 'grzegorz.russek', 'hours', '0', '{2:0.000000}');"; + + if (from.Date != to.Date) + { + if (to.Hour == 0 && to.Minute == 0) + sb.AppendFormat(format, GetTracEpoch(to.AddSeconds(-1)), ++counter, (to - from).TotalHours); + else + { + sb.AppendFormat(format, GetTracEpoch(to.Date.AddSeconds(-1)), ++counter, (to.Date - from).TotalHours); + sb.AppendFormat(format, GetTracEpoch(to), ++counter, (to - to.Date).TotalHours); + } + } + else + sb.AppendFormat(format, GetTracEpoch(to), ++counter, (to - from).TotalHours); + } + + private static long GetTracEpoch(DateTime date) + { + return Convert.ToInt64((date.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds) * 1000000; + } + + private static void PrintWhatYouKnow(string name, StringBuilder code) + { + string yourConnStr = "packet size=4096;User Id=sa;Password=sa123;data source=192.168.1.9,1433;initial catalog=MOM_NEXT_Florentyna_WMS_PROD;"; + using (SqlConnection sqlConn = new SqlConnection(yourConnStr)) + using (SqlCommand sqlCmd = new SqlCommand(name, sqlConn)) + { + StringBuilder body = new StringBuilder(); + + sqlConn.Open(); + sqlCmd.CommandType = CommandType.StoredProcedure; + try + { + SqlCommandBuilder.DeriveParameters(sqlCmd); + Console.WriteLine("PROCEDURE: {0}", name); + Console.WriteLine(sqlCmd.Parameters.Count.ToString()); + + code.AppendFormat("public static void {0}(this DynamicDatabase db", name); + body.AppendFormat(" db.Procedures.{0}(x$x$", name); + + foreach (SqlParameter p in sqlCmd.Parameters) + { + Console.WriteLine(p.ParameterName.ToString() + "\t" + + p.Direction.ToString() + "\t" + p.DbType.ToString()); + + if (p.Direction != ParameterDirection.ReturnValue) + { + code.Append(", "); body.Append(", "); + + switch (p.Direction) + { + case ParameterDirection.InputOutput: + code.Append("ref "); body.Append("both_"); + break; + + case ParameterDirection.Output: + code.Append("out "); body.Append("out_"); + break; + + default: + break; + } + + code.AppendFormat("{0} {1}", p.DbType, p.ParameterName.Trim('@')); + body.AppendFormat("{0}: {0}", p.ParameterName.Trim('@')); + } + } + + code.AppendFormat("){0}{{{0}{1});{0}}}{0}", Environment.NewLine, body.ToString().Replace("(x$x$, ", "(")); + } + catch (Exception ex) + { + Console.WriteLine("PROCEDURE: {0}, has errors: {1}", name, ex.Message); + } } } } diff --git a/Tester/Tester.csproj b/Tester/Tester.csproj index 1577f28..8145bf4 100644 --- a/Tester/Tester.csproj +++ b/Tester/Tester.csproj @@ -51,15 +51,15 @@ + + + {63963ED7-9C78-4672-A4D4-339B6E825503} DynamORM - - -