From bfa078841f4410021b6aa6f2c90975249c647f63 Mon Sep 17 00:00:00 2001 From: "grzegorz.russek" Date: Sun, 12 Aug 2012 21:49:48 +0000 Subject: [PATCH] * Fixes of errors detected while integrating DynamORM to existing project * New features (VirtualColumn, VirtualMode, BeginBlock, EndBlock) --- DynamORM.Tests/DynamORM.Tests.csproj | 2 +- DynamORM.Tests/Helpers/AttachToDebugger.cs | 16 ++++++++ DynamORM/Builders/DynamicQueryBuilder.cs | 44 ++++++++++++++++------ DynamORM/DynamicColumn.cs | 15 +++++++- DynamORM/DynamicDatabase.cs | 23 ++++++++++- DynamORM/DynamicDatabaseOptions.cs | 6 +-- DynamORM/DynamicExtensions.cs | 25 ++++++++++++ 7 files changed, 114 insertions(+), 17 deletions(-) diff --git a/DynamORM.Tests/DynamORM.Tests.csproj b/DynamORM.Tests/DynamORM.Tests.csproj index a31eb30..cb4aeca 100644 --- a/DynamORM.Tests/DynamORM.Tests.csproj +++ b/DynamORM.Tests/DynamORM.Tests.csproj @@ -37,7 +37,7 @@ - lib\System.Data.SQLite.dll + Libraries\System.Data.SQLite.dll diff --git a/DynamORM.Tests/Helpers/AttachToDebugger.cs b/DynamORM.Tests/Helpers/AttachToDebugger.cs index 3d0b140..18ede23 100644 --- a/DynamORM.Tests/Helpers/AttachToDebugger.cs +++ b/DynamORM.Tests/Helpers/AttachToDebugger.cs @@ -26,6 +26,7 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ +using System.Collections.Generic; using System.Diagnostics; using NUnit.Framework; @@ -53,5 +54,20 @@ namespace DynamORM.Tests.Helpers Assert.AreEqual(a.GetType(), b.GetType()); } + + /// Test anonymous type value. + [Test] + public void TestAnonTypeValue() + { + var a = new { x = 1, y = "bla bla" }; + var b = new { x = 1, y = "bla bla" }; + + Assert.AreEqual(a, b); + Assert.IsTrue(a.Equals(b)); + + Dictionary dict = new Dictionary() { { a, 999 } }; + + Assert.IsTrue(dict.ContainsKey(b)); + } } } \ No newline at end of file diff --git a/DynamORM/Builders/DynamicQueryBuilder.cs b/DynamORM/Builders/DynamicQueryBuilder.cs index 7caaba6..b701ddf 100644 --- a/DynamORM/Builders/DynamicQueryBuilder.cs +++ b/DynamORM/Builders/DynamicQueryBuilder.cs @@ -51,6 +51,9 @@ namespace DynamORM.Builders /// Gets a value indicating whether database supports standard schema. public bool SupportSchema { get; private set; } + /// Gets or sets a value indicating whether set parameters for null values. + public bool VirtualMode { get; set; } + /// Gets table name. public string TableName { get; private set; } @@ -60,6 +63,7 @@ namespace DynamORM.Builders { DynamicTable = table; TableName = table.TableName; + VirtualMode = false; WhereConditions = new List(); @@ -245,7 +249,7 @@ namespace DynamORM.Builders foreach (var v in WhereConditions) { - var col = Schema.TryGetNullable(v.ColumnName); + var col = Schema.TryGetNullable(v.ColumnName.ToLower()); string column = col.HasValue ? col.Value.Name : v.ColumnName; @@ -253,14 +257,17 @@ namespace DynamORM.Builders (column.IndexOf('(') == -1 || column.IndexOf(')') == -1)) column = db.DecorateName(column); - if (v.Value == null) + if ((v.Value == null || v.Value == DBNull.Value) && !VirtualMode && !v.VirtualColumn) { #region Null operators if (v.Operator == DynamicColumn.CompareOperator.Not || v.Operator == DynamicColumn.CompareOperator.Eq) - sb.AppendFormat(" {0} {1} IS{2} NULL", - first ? "WHERE" : "AND", column, - v.Operator == DynamicColumn.CompareOperator.Not ? " NOT" : string.Empty); + sb.AppendFormat(" {0} {1}{2} IS{3} NULL{4}", + first ? "WHERE" : v.Or ? "OR" : "AND", + v.BeginBlock ? "(" : string.Empty, + column, + v.Operator == DynamicColumn.CompareOperator.Not ? " NOT" : string.Empty, + v.EndBlock ? ")" : string.Empty); else throw new InvalidOperationException("NULL can only be compared by IS or IS NOT operator."); @@ -273,12 +280,17 @@ namespace DynamORM.Builders int pos = command.Parameters.Count; - sb.AppendFormat(" {0} {1} {2} ", - first ? "WHERE" : "AND", column, + sb.AppendFormat(" {0} {1}{2} {3} ", + first ? "WHERE" : v.Or ? "OR" : "AND", + v.BeginBlock ? "(" : string.Empty, + column, ToOperator(v.Operator)); db.GetParameterName(sb, pos); + if (v.EndBlock) + sb.Append(")"); + command.AddParameter(this, v); #endregion @@ -298,8 +310,10 @@ namespace DynamORM.Builders if (vals.Count == 2) { - sb.AppendFormat(" {0} {1} BETWEEN ", - first ? "WHERE" : "AND", column); + sb.AppendFormat(" {0} {1}{2} BETWEEN ", + first ? "WHERE" : v.Or ? "OR" : "AND", + v.BeginBlock ? "(" : string.Empty, + column); // From parameter db.GetParameterName(sb, command.Parameters.Count); @@ -313,6 +327,9 @@ namespace DynamORM.Builders v.Value = vals[1]; command.AddParameter(this, v); + if (v.EndBlock) + sb.Append(")"); + // Reset value v.Value = vals; } @@ -325,8 +342,10 @@ namespace DynamORM.Builders { #region In operator - sb.AppendFormat(" {0} {1} IN(", - first ? "WHERE" : "AND", column); + sb.AppendFormat(" {0} {1}{2} IN(", + first ? "WHERE" : v.Or ? "OR" : "AND", + v.BeginBlock ? "(" : string.Empty, + column); bool firstParam = true; @@ -354,6 +373,9 @@ namespace DynamORM.Builders sb.Append(")"); + if (v.EndBlock) + sb.Append(")"); + #endregion } else diff --git a/DynamORM/DynamicColumn.cs b/DynamORM/DynamicColumn.cs index 19a2702..9783c35 100644 --- a/DynamORM/DynamicColumn.cs +++ b/DynamORM/DynamicColumn.cs @@ -92,6 +92,7 @@ namespace DynamORM /// Constructor provided for easier object creation in qeries. /// Name of column to set. public DynamicColumn(string columnName) + : this() { ColumnName = columnName; } @@ -132,6 +133,18 @@ namespace DynamORM /// Gets or sets condition operator. public CompareOperator Operator { get; set; } + /// Gets or sets a value indicating whether this condition will be treated as or condition. + public bool Or { get; set; } + + /// Gets or sets a value indicating whether start new block in where steatement. + public bool BeginBlock { get; set; } + + /// Gets or sets a value indicating whether end existing block in where steatement. + public bool EndBlock { get; set; } + + /// Gets or sets a value indicating whether set parameters for null values. + public bool VirtualColumn { get; set; } + #endregion Properties #region Query creation helpers @@ -382,7 +395,7 @@ namespace DynamORM string column = ColumnName == "*" ? "*" : ColumnName; if (column != "*" && - (column.IndexOf(db.LeftDecorator) == -1 || column.IndexOf(db.LeftDecorator) == -1) && + (column.IndexOf(db.LeftDecorator) == -1 || column.IndexOf(db.RightDecorator) == -1) && (column.IndexOf('(') == -1 || column.IndexOf(')') == -1)) column = db.DecorateName(column); diff --git a/DynamORM/DynamicDatabase.cs b/DynamORM/DynamicDatabase.cs index f513baa..782a74e 100644 --- a/DynamORM/DynamicDatabase.cs +++ b/DynamORM/DynamicDatabase.cs @@ -196,7 +196,7 @@ namespace DynamORM Dictionary schema = null; lock (SyncLock) - schema = Schema.TryGetValue(table.GetType().FullName) ?? + schema = Schema.TryGetValue(table.ToLower()) ?? BuildAndCacheSchema(table, null); return schema; @@ -417,6 +417,7 @@ namespace DynamORM { IDbConnection conn = null; DynamicConnection ret = null; + bool opened = false; lock (SyncLock) { @@ -427,6 +428,7 @@ namespace DynamORM conn = _provider.CreateConnection(); conn.ConnectionString = _connectionString; conn.Open(); + opened = true; TransactionPool.Add(conn, new Stack()); CommandsPool.Add(conn, new List()); @@ -436,7 +438,10 @@ namespace DynamORM conn = TransactionPool.Keys.First(); if (conn.State != ConnectionState.Open) + { conn.Open(); + opened = true; + } } ret = new DynamicConnection(this, conn, _singleTransaction); @@ -445,6 +450,9 @@ namespace DynamORM ret = _tempConn; } + if (opened) + ExecuteInitCommands(ret); + return ret; } @@ -491,6 +499,19 @@ namespace DynamORM } } + /// Gets or sets contains commands executed when connection is opened. + public List InitCommands { get; set; } + + private void ExecuteInitCommands(IDbConnection conn) + { + if (InitCommands != null) + using (IDbCommand command = conn.CreateCommand()) + foreach (string commandText in InitCommands) + command + .SetCommand(commandText) + .ExecuteNonQuery(); + } + #endregion Connection #region Transaction diff --git a/DynamORM/DynamicDatabaseOptions.cs b/DynamORM/DynamicDatabaseOptions.cs index 5369e5d..83d986e 100644 --- a/DynamORM/DynamicDatabaseOptions.cs +++ b/DynamORM/DynamicDatabaseOptions.cs @@ -43,16 +43,16 @@ namespace DynamORM /// Only one transaction. SingleTransaction, - /// Database supports top syntax. + /// Database supports top syntax (SELECT TOP x ... FROM ...). SupportTop, - /// Database supports limit offset syntax. + /// Database supports limit offset syntax (SELECT ... FROM ... LIMIT x OFFSET y). SupportLimitOffset, /// Database support standard schema. SupportSchema, - /// Database support stored procedures. + /// Database support stored procedures (EXEC proc ...). SupportStoredProcedures } } \ No newline at end of file diff --git a/DynamORM/DynamicExtensions.cs b/DynamORM/DynamicExtensions.cs index 694e778..612f29c 100644 --- a/DynamORM/DynamicExtensions.cs +++ b/DynamORM/DynamicExtensions.cs @@ -35,6 +35,7 @@ using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; +using System.Text; using DynamORM.Builders; using DynamORM.Mapper; @@ -645,6 +646,16 @@ namespace DynamORM #endregion Generic Execution + /// Dump command into text writer. + /// Command to dump. + /// Builder to which write output. + /// Returns dumped instance. + public static IDbCommand Dump(this IDbCommand command, StringBuilder buider) + { + using (StringWriter sw = new StringWriter(buider)) + return command.Dump(sw); + } + /// Dump command into text writer. /// Command to dump. /// Writer to which write output. @@ -688,6 +699,20 @@ namespace DynamORM return result; } + /// Turns the dictionary into an ExpandoObject. + /// Dictionary to convert. + /// Converted dictionary. + public static dynamic ToDynamic(this IDictionary d) + { + var result = new ExpandoObject(); + var dict = result as IDictionary; + + foreach (var prop in d) + dict.Add(prop.Key, prop.Value); + + return result; + } + /// Turns the object into an ExpandoObject. /// Object to convert. /// Converted object.