This commit is contained in:
grzegorz.russek
2013-05-24 20:44:39 +00:00
parent d9d4ef65c3
commit 4e0652dd89
15 changed files with 171 additions and 103 deletions

View File

@@ -26,6 +26,7 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using DynamORM.Tests.Helpers;
using NUnit.Framework;
@@ -64,13 +65,13 @@ namespace DynamORM.Tests.Modify
[Test]
public void TestInsertByArguments()
{
Assert.AreEqual(1, GetTestTable().Insert(code: 201, first: "Juri", last: "Gagarin", email: "juri.gagarin@megacorp.com", quote: "bla, bla, bla"));
Assert.AreEqual(1, GetTestTable().Insert(code: 201, first: null, last: "Gagarin", email: "juri.gagarin@megacorp.com", quote: "bla, bla, bla"));
// Verify
var o = GetTestTable().Single(code: 201);
Assert.Less(200, o.id);
Assert.AreEqual("201", o.code);
Assert.AreEqual("Juri", o.first);
Assert.AreEqual(null, o.first);
Assert.AreEqual("Gagarin", o.last);
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
Assert.AreEqual("bla, bla, bla", o.quote);
@@ -81,13 +82,13 @@ namespace DynamORM.Tests.Modify
[Test]
public void TestInsertByDynamicObjects()
{
Assert.AreEqual(1, GetTestTable().Insert(values: new { code = 202, first = "Juri", last = "Gagarin", email = "juri.gagarin@megacorp.com", quote = "bla, bla, bla" }));
Assert.AreEqual(1, GetTestTable().Insert(values: new { code = 202, first = DBNull.Value, last = "Gagarin", email = "juri.gagarin@megacorp.com", quote = "bla, bla, bla" }));
// Verify
var o = GetTestTable().Single(code: 202);
Assert.Less(200, o.id);
Assert.AreEqual("202", o.code);
Assert.AreEqual("Juri", o.first);
Assert.AreEqual(null, o.first);
Assert.AreEqual("Gagarin", o.last);
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
Assert.AreEqual("bla, bla, bla", o.quote);
@@ -104,7 +105,7 @@ namespace DynamORM.Tests.Modify
{
Id = u.Max(columns: "id") + 1,
Code = "203",
First = "Juri",
First = null,
Last = "Gagarin",
Email = "juri.gagarin@megacorp.com",
Quote = "bla, bla, bla"
@@ -114,7 +115,7 @@ namespace DynamORM.Tests.Modify
var o = u.Single(code: 203);
Assert.Less(200, o.id);
Assert.AreEqual("203", o.code);
Assert.AreEqual("Juri", o.first);
Assert.AreEqual(null, o.first);
Assert.AreEqual("Gagarin", o.last);
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
Assert.AreEqual("bla, bla, bla", o.quote);
@@ -131,7 +132,7 @@ namespace DynamORM.Tests.Modify
{
id = u.Max(columns: "id") + 1,
code = "204",
first = "Juri",
first = null,
last = "Gagarin",
email = "juri.gagarin@megacorp.com",
quote = "bla, bla, bla"
@@ -141,7 +142,7 @@ namespace DynamORM.Tests.Modify
var o = u.Single(code: 204);
Assert.Less(200, o.id);
Assert.AreEqual("204", o.code);
Assert.AreEqual("Juri", o.first);
Assert.AreEqual(null, o.first);
Assert.AreEqual("Gagarin", o.last);
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
Assert.AreEqual("bla, bla, bla", o.quote);
@@ -156,13 +157,13 @@ namespace DynamORM.Tests.Modify
[Test]
public void TestUpdateByArguments()
{
Assert.AreEqual(1, GetTestTable().Update(id: 1, code: 201, first: "Juri", last: "Gagarin", email: "juri.gagarin@megacorp.com", quote: "bla, bla, bla"));
Assert.AreEqual(1, GetTestTable().Update(id: 1, code: 201, first: null, last: "Gagarin", email: "juri.gagarin@megacorp.com", quote: "bla, bla, bla"));
// Verify
var o = GetTestTable().Single(code: 201);
Assert.AreEqual(1, o.id);
Assert.AreEqual("201", o.code);
Assert.AreEqual("Juri", o.first);
Assert.AreEqual(null, o.first);
Assert.AreEqual("Gagarin", o.last);
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
Assert.AreEqual("bla, bla, bla", o.quote);
@@ -173,13 +174,13 @@ namespace DynamORM.Tests.Modify
[Test]
public void TestUpdateByDynamicObject()
{
Assert.AreEqual(1, GetTestTable().Update(update: new { id = 2, code = 202, first = "Juri", last = "Gagarin", email = "juri.gagarin@megacorp.com", quote = "bla, bla, bla" }));
Assert.AreEqual(1, GetTestTable().Update(update: new { id = 2, code = 202, first = DBNull.Value, last = "Gagarin", email = "juri.gagarin@megacorp.com", quote = "bla, bla, bla" }));
// Verify
var o = GetTestTable().Single(code: 202);
Assert.AreEqual(2, o.id);
Assert.AreEqual("202", o.code);
Assert.AreEqual("Juri", o.first);
Assert.AreEqual(null, o.first);
Assert.AreEqual("Gagarin", o.last);
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
Assert.AreEqual("bla, bla, bla", o.quote);
@@ -196,7 +197,7 @@ namespace DynamORM.Tests.Modify
{
Id = 3,
Code = "203",
First = "Juri",
First = null,
Last = "Gagarin",
Email = "juri.gagarin@megacorp.com",
Quote = "bla, bla, bla"
@@ -206,7 +207,7 @@ namespace DynamORM.Tests.Modify
var o = u.Single(code: 203);
Assert.AreEqual(3, o.id);
Assert.AreEqual("203", o.code);
Assert.AreEqual("Juri", o.first);
Assert.AreEqual(null, o.first);
Assert.AreEqual("Gagarin", o.last);
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
Assert.AreEqual("bla, bla, bla", o.quote);
@@ -223,7 +224,7 @@ namespace DynamORM.Tests.Modify
{
id = 4,
code = "204",
first = "Juri",
first = null,
last = "Gagarin",
email = "juri.gagarin@megacorp.com",
quote = "bla, bla, bla"
@@ -233,7 +234,7 @@ namespace DynamORM.Tests.Modify
var o = u.Single(code: 204);
Assert.AreEqual(4, o.id);
Assert.AreEqual("204", o.code);
Assert.AreEqual("Juri", o.first);
Assert.AreEqual(null, o.first);
Assert.AreEqual("Gagarin", o.last);
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
Assert.AreEqual("bla, bla, bla", o.quote);
@@ -244,13 +245,13 @@ namespace DynamORM.Tests.Modify
[Test]
public void TestUpdateByDynamicObjects()
{
Assert.AreEqual(1, GetTestTable().Update(values: new { code = 205, first = "Juri", last = "Gagarin", email = "juri.gagarin@megacorp.com", quote = "bla, bla, bla" }, where: new { id = 5 }));
Assert.AreEqual(1, GetTestTable().Update(values: new { code = 205, first = DBNull.Value, last = "Gagarin", email = "juri.gagarin@megacorp.com", quote = "bla, bla, bla" }, where: new { id = 5 }));
// Verify
var o = GetTestTable().Single(code: 205);
Assert.AreEqual(5, o.id);
Assert.AreEqual("205", o.code);
Assert.AreEqual("Juri", o.first);
Assert.AreEqual(null, o.first);
Assert.AreEqual("Gagarin", o.last);
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
Assert.AreEqual("bla, bla, bla", o.quote);
@@ -267,7 +268,7 @@ namespace DynamORM.Tests.Modify
{
Id = 6,
Code = "206",
First = "Juri",
First = null,
Last = "Gagarin",
Email = "juri.gagarin@megacorp.com",
Quote = "bla, bla, bla"
@@ -277,7 +278,7 @@ namespace DynamORM.Tests.Modify
var o = u.Single(code: 206);
Assert.AreEqual(6, o.id);
Assert.AreEqual("206", o.code);
Assert.AreEqual("Juri", o.first);
Assert.AreEqual(null, o.first);
Assert.AreEqual("Gagarin", o.last);
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
Assert.AreEqual("bla, bla, bla", o.quote);
@@ -294,7 +295,7 @@ namespace DynamORM.Tests.Modify
{
id = 7,
code = "207",
first = "Juri",
first = null,
last = "Gagarin",
email = "juri.gagarin@megacorp.com",
quote = "bla, bla, bla"
@@ -304,7 +305,7 @@ namespace DynamORM.Tests.Modify
var o = u.Single(code: 207);
Assert.AreEqual(7, o.id);
Assert.AreEqual("207", o.code);
Assert.AreEqual("Juri", o.first);
Assert.AreEqual(null, o.first);
Assert.AreEqual("Gagarin", o.last);
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
Assert.AreEqual("bla, bla, bla", o.quote);

View File

@@ -37,7 +37,7 @@ namespace DynamORM.Builders
/// <summary>Insert query builder.</summary>
public class DynamicInsertQueryBuilder : DynamicQueryBuilder<DynamicInsertQueryBuilder>
{
/// <summary>Gets list of columns that will be seected.</summary>
/// <summary>Gets list of columns that will be selected.</summary>
public IDictionary<string, DynamicColumn> ValueColumns { get; private set; }
/// <summary>Initializes a new instance of the <see cref="DynamicInsertQueryBuilder"/> class.</summary>

View File

@@ -37,7 +37,7 @@ namespace DynamORM.Builders
/// <summary>Select query builder.</summary>
public class DynamicSelectQueryBuilder : DynamicQueryBuilder<DynamicSelectQueryBuilder>
{
/// <summary>Gets dictionary of columns that will be seected.</summary>
/// <summary>Gets dictionary of columns that will be selected.</summary>
public List<DynamicColumn> Columns { get; private set; }
/// <summary>Gets dictionary of columns that will be used to group query.</summary>

View File

@@ -37,7 +37,7 @@ namespace DynamORM.Builders
/// <summary>Update query builder.</summary>
public class DynamicUpdateQueryBuilder : DynamicQueryBuilder<DynamicUpdateQueryBuilder>
{
/// <summary>Gets list of columns that will be seected.</summary>
/// <summary>Gets list of columns that will be selected.</summary>
public IDictionary<string, DynamicColumn> ValueColumns { get; private set; }
/// <summary>Initializes a new instance of the <see cref="DynamicUpdateQueryBuilder" /> class.</summary>

View File

@@ -71,10 +71,10 @@ namespace DynamORM
/// <summary>Less or equal operator.</summary>
Lte,
/// <summary>Greather than operator.</summary>
/// <summary>Greater than operator.</summary>
Gt,
/// <summary>Greather or equal operator.</summary>
/// <summary>Greater or equal operator.</summary>
Gte,
/// <summary>Between two values.</summary>
@@ -89,7 +89,7 @@ namespace DynamORM
public DynamicColumn() { }
/// <summary>Initializes a new instance of the <see cref="DynamicColumn" /> class.</summary>
/// <remarks>Constructor provided for easier object creation in qeries.</remarks>
/// <remarks>Constructor provided for easier object creation in queries.</remarks>
/// <param name="columnName">Name of column to set.</param>
public DynamicColumn(string columnName)
: this()
@@ -98,7 +98,7 @@ namespace DynamORM
}
/// <summary>Initializes a new instance of the <see cref="DynamicColumn" /> class.</summary>
/// <remarks>Constructor provided for easier object creation in qeries.</remarks>
/// <remarks>Constructor provided for easier object creation in queries.</remarks>
/// <param name="columnName">Name of column to set.</param>
/// <param name="oper">Compare column to value(s) operator.</param>
/// <param name="value">Parameter value(s).</param>
@@ -136,18 +136,18 @@ namespace DynamORM
/// <summary>Gets or sets a value indicating whether this condition will be treated as or condition.</summary>
public bool Or { get; set; }
/// <summary>Gets or sets a value indicating whether start new block in where steatement.</summary>
/// <summary>Gets or sets a value indicating whether start new block in where statement.</summary>
public bool BeginBlock { get; set; }
/// <summary>Gets or sets a value indicating whether end existing block in where steatement.</summary>
/// <summary>Gets or sets a value indicating whether end existing block in where statement.</summary>
public bool EndBlock { get; set; }
/// <summary>Gets or sets a value indicating whether set parameters for null values.</summary>
public bool VirtualColumn { get; set; }
/// <summary>Gets or sets schema representation of a column.</summary>
/// <remarks>Woraround to providers issues which sometimes pass wrong
/// data o schema. For example decimal has precission of 255 in sql
/// <remarks>Workaround to providers issues which sometimes pass wrong
/// data o schema. For example decimal has precision of 255 in SQL
/// server.</remarks>
public DynamicSchemaColumn? Schema { get; set; }
@@ -366,7 +366,7 @@ namespace DynamORM
}
/// <summary>Sets the virtual column.</summary>
/// <param name="virt">If set to <c>true</c> [virt].</param>
/// <param name="virt">Set virtual column value.</param>
/// <returns>Returns self.</returns>
public DynamicColumn SetVirtualColumn(bool virt)
{

View File

@@ -42,7 +42,7 @@ namespace DynamORM
/// <summary>Initializes a new instance of the <see cref="DynamicCommand"/> class.</summary>
/// <param name="con">The connection.</param>
/// <param name="db">The databas manager.</param>
/// <param name="db">The database manager.</param>
internal DynamicCommand(DynamicConnection con, DynamicDatabase db)
{
_con = con;
@@ -61,8 +61,8 @@ namespace DynamORM
}
/// <summary>Initializes a new instance of the <see cref="DynamicCommand"/> class.</summary>
/// <param name="db">The databas manager.</param>
/// <remarks>Used intenaly to create command without context.</remarks>
/// <param name="db">The database manager.</param>
/// <remarks>Used internally to create command without context.</remarks>
internal DynamicCommand(DynamicDatabase db)
{
_db = db;
@@ -177,9 +177,9 @@ namespace DynamORM
}
/// <summary>Executes the query, and returns the first column of the
/// first row in the resultset returned by the query. Extra columns or
/// first row in the result set returned by the query. Extra columns or
/// rows are ignored.</summary>
/// <returns>The first column of the first row in the resultset.</returns>
/// <returns>The first column of the first row in the result set.</returns>
public object ExecuteScalar()
{
return PrepareForExecution().ExecuteScalar();

View File

@@ -32,14 +32,14 @@ using System.Data;
namespace DynamORM
{
/// <summary>Connection wrapper.</summary>
/// <remarks>This class is only connection holder conection is managed by
/// <remarks>This class is only connection holder, connection is managed by
/// <see cref="DynamicDatabase"/> instance.</remarks>
public class DynamicConnection : IDbConnection, IDisposable
{
private DynamicDatabase _db;
private bool _singleTransaction;
/// <summary>Gets underlaying connection.</summary>
/// <summary>Gets underlying connection.</summary>
internal IDbConnection Connection { get; private set; }
/// <summary>Initializes a new instance of the <see cref="DynamicConnection" /> class.</summary>
@@ -89,7 +89,7 @@ namespace DynamORM
/// <summary>Changes the current database for an open Connection object.</summary>
/// <param name="databaseName">The name of the database to use in place of the current database.</param>
/// <remarks>This operation is not supported in DynamORM. and will throw <see cref="NotSupportedException"/>.</remarks>
/// <remarks>This operation is not supported in <c>DynamORM</c>. and will throw <see cref="NotSupportedException"/>.</remarks>
/// <exception cref="NotSupportedException">Thrown always.</exception>
public void ChangeDatabase(string databaseName)
{
@@ -107,12 +107,12 @@ namespace DynamORM
/// <remarks>Does nothing. <see cref="DynamicDatabase"/> handles
/// closing connections. Only way to close it is to dispose connection.
/// It will close if this is multi connection configuration, otherwise
/// it will stay open untill <see cref="DynamicDatabase"/> is not
/// it will stay open until <see cref="DynamicDatabase"/> is not
/// disposed.</remarks>
public void Close() { }
/// <summary>Gets or sets the string used to open a database.</summary>
/// <remarks>Changing connection string operation is not supported in DynamORM.
/// <remarks>Changing connection string operation is not supported in <c>DynamORM</c>.
/// and will throw <see cref="NotSupportedException"/>.</remarks>
/// <exception cref="NotSupportedException">Thrown always when set is attempted.</exception>
public string ConnectionString

View File

@@ -108,7 +108,7 @@ namespace DynamORM
public bool DumpCommands { get; set; }
/// <summary>Initializes a new instance of the <see cref="DynamicDatabase" /> class.</summary>
/// <param name="provider">Database proider by name.</param>
/// <param name="provider">Database provider by name.</param>
/// <param name="connectionString">Connection string to provided database.</param>
/// <param name="options">Connection options.</param>
public DynamicDatabase(string provider, string connectionString, DynamicDatabaseOptions options)
@@ -117,7 +117,7 @@ namespace DynamORM
}
/// <summary>Initializes a new instance of the <see cref="DynamicDatabase" /> class.</summary>
/// <param name="provider">Database proider.</param>
/// <param name="provider">Database provider.</param>
/// <param name="connectionString">Connection string to provided database.</param>
/// <param name="options">Connection options.</param>
public DynamicDatabase(DbProviderFactory provider, string connectionString, DynamicDatabaseOptions options)
@@ -146,6 +146,7 @@ namespace DynamORM
_singleConnection = (options & DynamicDatabaseOptions.SingleConnection) == DynamicDatabaseOptions.SingleConnection;
_singleTransaction = (options & DynamicDatabaseOptions.SingleTransaction) == DynamicDatabaseOptions.SingleTransaction;
DumpCommands = (options & DynamicDatabaseOptions.DumpCommands) == DynamicDatabaseOptions.DumpCommands;
TransactionPool = new Dictionary<IDbConnection, Stack<IDbTransaction>>();
CommandsPool = new Dictionary<IDbConnection, List<IDbCommand>>();
@@ -158,7 +159,7 @@ namespace DynamORM
#region Table
/// <summary>Gets dynamic table which is a simple ORM using dynamic objects.</summary>
/// <param name="action">The action with nstance of <see cref="DynamicTable"/> as parameter.</param>
/// <param name="action">The action with instance of <see cref="DynamicTable"/> as parameter.</param>
/// <param name="table">Table name.</param>
/// <param name="keys">Override keys in schema.</param>
public void Table(Action<dynamic> action, string table = "", string[] keys = null)
@@ -169,7 +170,7 @@ namespace DynamORM
/// <summary>Gets dynamic table which is a simple ORM using dynamic objects.</summary>
/// <typeparam name="T">Type used to determine table name.</typeparam>
/// <param name="action">The action with nstance of <see cref="DynamicTable"/> as parameter.</param>
/// <param name="action">The action with instance of <see cref="DynamicTable"/> as parameter.</param>
/// <param name="keys">Override keys in schema.</param>
public void Table<T>(Action<dynamic> action, string[] keys = null)
{
@@ -228,9 +229,9 @@ namespace DynamORM
#region Schema
/// <summary>Builds table cache if nessesary and returns it.</summary>
/// <summary>Builds table cache if necessary and returns it.</summary>
/// <param name="table">Name of table for which build schema.</param>
/// <returns>Table chema.</returns>
/// <returns>Table schema.</returns>
public Dictionary<string, DynamicSchemaColumn> GetSchema(string table)
{
Dictionary<string, DynamicSchemaColumn> schema = null;
@@ -242,7 +243,7 @@ namespace DynamORM
return schema;
}
/// <summary>Builds table cache if nessesary and returns it.</summary>
/// <summary>Builds table cache if necessary and returns it.</summary>
/// <typeparam name="T">Type of table for which build schema.</typeparam>
/// <returns>Table schema or null if type was anonymous.</returns>
public Dictionary<string, DynamicSchemaColumn> GetSchema<T>()
@@ -259,7 +260,7 @@ namespace DynamORM
return schema;
}
/// <summary>Builds table cache if nessesary and returns it.</summary>
/// <summary>Builds table cache if necessary and returns it.</summary>
/// <param name="table">Type of table for which build schema.</param>
/// <returns>Table schema or null if type was anonymous.</returns>
public Dictionary<string, DynamicSchemaColumn> GetSchema(Type table)
@@ -558,7 +559,7 @@ namespace DynamORM
/// <summary>Begins a global database transaction.</summary>
/// <remarks>Using this method connection is set to single open
/// connection untill all transactions are finished.</remarks>
/// connection until all transactions are finished.</remarks>
/// <returns>Returns <see cref="DynamicTransaction"/> representation.</returns>
public IDbTransaction BeginTransaction()
{

View File

@@ -32,27 +32,31 @@ namespace DynamORM
{
/// <summary>Represents database connection options.</summary>
[Flags]
[System.Reflection.ObfuscationAttribute(Feature = "renaming", ApplyToMembers = true)]
public enum DynamicDatabaseOptions
{
/// <summary>No specific options.</summary>
None,
None = 0x00000000,
/// <summary>Only single presistent database connection.</summary>
SingleConnection,
/// <summary>Only single persistent database connection.</summary>
SingleConnection = 0x00000001,
/// <summary>Only one transaction.</summary>
SingleTransaction,
SingleTransaction = 0x00000002,
/// <summary>Database supports top syntax (SELECT TOP x ... FROM ...).</summary>
SupportTop,
SupportTop = 0x00000080,
/// <summary>Database supports limit offset syntax (SELECT ... FROM ... LIMIT x OFFSET y).</summary>
SupportLimitOffset,
SupportLimitOffset = 0x00000040,
/// <summary>Database support standard schema.</summary>
SupportSchema,
SupportSchema = 0x00000010,
/// <summary>Database support stored procedures (EXEC proc ...).</summary>
SupportStoredProcedures
/// <summary>Database support stored procedures (EXEC procedure ...).</summary>
SupportStoredProcedures = 0x00000020,
/// <summary>Debug option allowing to enable command dumps by default.</summary>
DumpCommands = 0x01000000,
}
}

View File

@@ -46,7 +46,7 @@ namespace DynamORM
{
#region Type column map
/// <summary>MapEnumerable of .NET types to DbType's.</summary>
/// <summary>MapEnumerable of .NET types to <see cref="DbType"/>.</summary>
public static readonly Dictionary<Type, DbType> TypeMap = new Dictionary<Type, DbType>()
{
{ typeof(byte), DbType.Byte },
@@ -115,7 +115,7 @@ namespace DynamORM
/// <summary>Set <see cref="System.Data.IDbCommand"/> properties on the fly.</summary>
/// <param name="command"><see cref="System.Data.IDbCommand"/> in which changes will be made.</param>
/// <param name="commandType">Indicates or specifies how the System.Data.IDbCommand.CommandText property is interpreted.</param>
/// <param name="commandType">Indicates or specifies how the <see cref="System.Data.IDbCommand.CommandText"/> property is interpreted.</param>
/// <param name="commandTimeout">The wait time before terminating the attempt to execute a command and generating an error.</param>
/// <param name="commandText">The text command to run against the data source.</param>
/// <param name="args">Arguments used to format command.</param>
@@ -153,7 +153,7 @@ namespace DynamORM
/// <summary>Set <see cref="System.Data.IDbCommand"/> properties on the fly.</summary>
/// <param name="command"><see cref="System.Data.IDbCommand"/> in which changes will be made.</param>
/// <param name="commandType">Indicates or specifies how the System.Data.IDbCommand.CommandText property is interpreted.</param>
/// <param name="commandType">Indicates or specifies how the <see cref="System.Data.IDbCommand.CommandText"/> property is interpreted.</param>
/// <param name="commandText">The text command to run against the data source.</param>
/// <param name="args">Arguments used to format command.</param>
/// <returns>Returns edited <see cref="System.Data.IDbCommand"/> instance.</returns>
@@ -248,7 +248,7 @@ namespace DynamORM
var p = cmd.CreateParameter();
p.ParameterName = name;
if (item == null)
if (item == null || item == DBNull.Value)
p.Value = DBNull.Value;
else
{
@@ -298,7 +298,7 @@ namespace DynamORM
p.Scale = 4;
}
p.Value = item.Value;
p.Value = item.Value == null ? DBNull.Value : item.Value;
}
else if (item.Value == null || item.Value == DBNull.Value)
p.Value = DBNull.Value;
@@ -308,6 +308,8 @@ namespace DynamORM
if (p.DbType == DbType.String)
p.Size = item.Value.ToString().Length > 4000 ? -1 : 4000;
p.Value = item.Value;
}
cmd.Parameters.Add(p);
@@ -703,7 +705,7 @@ namespace DynamORM
param.Scale,
param.Precision,
param.Scale,
param.Value ?? "NULL",
param.Value is byte[] ? ConvertByteArrayToHexString((byte[])param.Value) : param.Value ?? "NULL",
param.Value != null ? param.Value.GetType().Name : "DBNull");
}
@@ -713,6 +715,32 @@ namespace DynamORM
return command;
}
/// <summary>Convert byte array to hex formatted string without separators.</summary>
/// <param name="data">Byte Array Data.</param>
/// <returns>Hex string representation of byte array.</returns>
private static string ConvertByteArrayToHexString(byte[] data)
{
return ConvertByteArrayToHexString(data, 0);
}
/// <summary>Convert byte array to hex formatted string.</summary>
/// <param name="data">Byte Array Data.</param>
/// <param name="separatorEach">Put '-' each <c>separatorEach</c> characters.</param>
/// <returns>Hex string representation of byte array.</returns>
private static string ConvertByteArrayToHexString(byte[] data, int separatorEach)
{
int len = data.Length * 2;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
for (int i = 0; i < len; i++)
{
sb.AppendFormat("{0:X}", data[(i / 2)] >> (((i % 2) == 0) ? 4 : 0) & 0x0F);
if ((separatorEach > 0) && ((i + 1) % separatorEach == 0))
sb.AppendFormat("-");
}
return sb.ToString();
}
#endregion Command extensions
#region Dynamic extensions
@@ -751,10 +779,16 @@ namespace DynamORM
{
var result = new ExpandoObject();
var dict = result as IDictionary<string, object>;
var ot = o.GetType();
if (o.GetType() == typeof(ExpandoObject))
if (ot == typeof(ExpandoObject))
return o;
if (o.GetType() == typeof(NameValueCollection) || o.GetType().IsSubclassOf(typeof(NameValueCollection)))
if (o is IDictionary<string, object>)
((IDictionary<string, object>)o)
.ToList()
.ForEach(kvp => dict.Add(kvp.Key, kvp.Value));
else if (ot == typeof(NameValueCollection) || ot.IsSubclassOf(typeof(NameValueCollection)))
{
var nameValue = (NameValueCollection)o;
nameValue.Cast<string>()
@@ -764,7 +798,7 @@ namespace DynamORM
}
else
{
var mapper = DynamicMapperCache.GetMapper(o.GetType());
var mapper = DynamicMapperCache.GetMapper(ot);
if (mapper != null)
{
@@ -774,7 +808,7 @@ namespace DynamORM
}
else
{
var props = o.GetType().GetProperties();
var props = ot.GetProperties();
foreach (var item in props)
if (item.CanRead)
@@ -804,7 +838,7 @@ namespace DynamORM
/// <summary>Convert data row row into dynamic object (upper case key).</summary>
/// <param name="r">DataRow from which read.</param>
/// <returns>Generated dynamic object.</returns>
internal static dynamic RowToDynamicUpper(this DataRow r)
public static dynamic RowToDynamicUpper(this DataRow r)
{
dynamic e = new ExpandoObject();
var d = e as IDictionary<string, object>;
@@ -845,7 +879,9 @@ namespace DynamORM
/// <returns>Resulting dictionary.</returns>
public static IDictionary<string, object> ToDictionary(this object o)
{
return (IDictionary<string, object>)o.ToDynamic();
return o is IDictionary<string, object> ?
(IDictionary<string, object>)o :
(IDictionary<string, object>)o.ToDynamic();
}
#endregion Dynamic extensions
@@ -987,7 +1023,7 @@ namespace DynamORM
return (T)mapper.Create(item);
}
/// <summary>Fill object of speciied type with data from source object.</summary>
/// <summary>Fill object of specified type with data from source object.</summary>
/// <typeparam name="T">Type to which columnMap results.</typeparam>
/// <param name="item">Item to which columnMap data.</param>
/// <param name="source">Item from which extract data.</param>

View File

@@ -41,7 +41,7 @@ namespace DynamORM
/// <example>
/// <para>Assume that we have a table representing Users class.</para>
/// <para>
/// <para>Let's take a look at <c>Query</c> posibilities. Assume we want
/// <para>Let's take a look at <c>Query</c> possibilities. Assume we want
/// to get enumerator for all records in database, mapped to our class
/// instead of dynamic type we can use following syntax.</para>
/// <para>Approach first. Use dynamic <c>Query</c> method and just set type
@@ -54,13 +54,13 @@ namespace DynamORM
/// <c>IEnumerable&lt;object&gt;</c> (to which we must cast to) to map
/// object.</para>
/// <code>(db.Table&lt;User&gt;().Query(columns: "*") as IEnumerable&lt;object&gt;).MapEnumerable&lt;User&gt;();</code>
/// You can also use generic approach. But be careful this method is currently avaliable thanks to framework hack.
/// You can also use generic approach. But be careful this method is currently available thanks to framework hack.
/// <code>(db.Table&lt;User&gt;().Query&lt;User&gt;() as IEnumerable&lt;object&gt;).Cast&lt;User&gt;()</code>
/// <para>Another approach uses existing methods, but still requires a
/// cast, because <c>Query</c> also returns dynamic object enumerator.</para>
/// <code>(db.Table&lt;User&gt;().Query().Execute() as IEnumerable&lt;object&gt;).MapEnumerable&lt;User&gt;();</code>
/// </para>
/// <para>Below you can find various invocations of dynamic and non dynemic
/// <para>Below you can find various invocations of dynamic and non dynamic
/// methods of this class. <c>x</c> variable is a class instance.
/// First various selects:</para>
/// <code>x.Count(columns: "id");</code>
@@ -215,7 +215,9 @@ namespace DynamORM
/// <remarks>If database doesn't support schema, only key columns are listed here.</remarks>
public virtual Dictionary<string, DynamicSchemaColumn> Schema { get; private set; }
private DynamicTable() { }
private DynamicTable()
{
}
/// <summary>Initializes a new instance of the <see cref="DynamicTable" /> class.</summary>
/// <param name="database">Database and connection management.</param>
@@ -311,8 +313,8 @@ namespace DynamORM
#region Basic Queries
/// <summary>Enumerate the reader and yield the result.</summary>
/// <param name="sql">Sql query containing numered parameters in format provided by
/// <see cref="DynamicDatabase.GetParameterName(object)"/> methods. Also names should be formated with
/// <param name="sql">SQL query containing numbered parameters in format provided by
/// <see cref="DynamicDatabase.GetParameterName(object)"/> methods. Also names should be formatted with
/// <see cref="DynamicDatabase.DecorateName(string)"/> method.</param>
/// <param name="args">Arguments (parameters).</param>
/// <returns>Enumerator of objects expanded from query.</returns>
@@ -354,8 +356,8 @@ namespace DynamORM
}
/// <summary>Returns a single result.</summary>
/// <param name="sql">Sql query containing numered parameters in format provided by
/// <see cref="DynamicDatabase.GetParameterName(object)"/> methods. Also names should be formated with
/// <param name="sql">SQL query containing numbered parameters in format provided by
/// <see cref="DynamicDatabase.GetParameterName(object)"/> methods. Also names should be formatted with
/// <see cref="DynamicDatabase.DecorateName(string)"/> method.</param>
/// <param name="args">Arguments (parameters).</param>
/// <returns>Result of a query.</returns>
@@ -403,8 +405,8 @@ namespace DynamORM
}
/// <summary>Execute non query.</summary>
/// <param name="sql">Sql query containing numered parameters in format provided by
/// <see cref="DynamicDatabase.GetParameterName(object)"/> methods. Also names should be formated with
/// <param name="sql">SQL query containing numbered parameters in format provided by
/// <see cref="DynamicDatabase.GetParameterName(object)"/> methods. Also names should be formatted with
/// <see cref="DynamicDatabase.DecorateName(string)"/> method.</param>
/// <param name="args">Arguments (parameters).</param>
/// <returns>Number of affected rows.</returns>
@@ -472,9 +474,9 @@ namespace DynamORM
return new DynamicInsertQueryBuilder(this);
}
/// <summary>Adds a record to the database. You can pass in an Anonymous object, an ExpandoObject,
/// A regular old POCO, or a NameValueColletion from a Request.Form or Request.QueryString.</summary>
/// <param name="o">Anonymous object, an ExpandoObject, a regular old POCO, or a NameValueCollection
/// <summary>Adds a record to the database. You can pass in an Anonymous object, an <see cref="ExpandoObject"/>,
/// A regular old POCO, or a NameValueCollection from a Request.Form or Request.QueryString.</summary>
/// <param name="o">Anonymous object, an <see cref="ExpandoObject"/>, a regular old POCO, or a NameValueCollection
/// from a Request.Form or Request.QueryString, containing fields to update.</param>
/// <returns>Number of updated rows.</returns>
public virtual int Insert(object o)
@@ -499,7 +501,7 @@ namespace DynamORM
/// a regular old POCO, or a NameValueCollection from a Request.Form or Request.QueryString.</summary>
/// <param name="o">Anonymous object, an ExpandoObject, a regular old POCO, or a NameValueCollection
/// from a Request.Form or Request.QueryString, containing fields to update.</param>
/// <param name="key">Anonymous object, an ExpandoObject, a regular old POCO, or a NameValueCollection
/// <param name="key">Anonymous object, an <see cref="ExpandoObject"/>, a regular old POCO, or a NameValueCollection
/// from a Request.Form or Request.QueryString, containing fields with conditions.</param>
/// <returns>Number of updated rows.</returns>
public virtual int Update(object o, object key)
@@ -512,7 +514,7 @@ namespace DynamORM
/// <summary>Updates a record in the database using schema. You can pass in an Anonymous object, an ExpandoObject,
/// a regular old POCO, or a NameValueCollection from a Request.Form or Request.QueryString.</summary>
/// <param name="o">Anonymous object, an ExpandoObject, a regular old POCO, or a NameValueCollection
/// <param name="o">Anonymous object, an <see cref="ExpandoObject"/>, a regular old POCO, or a NameValueCollection
/// from a Request.Form or Request.QueryString, containing fields to update and conditions.</param>
/// <returns>Number of updated rows.</returns>
public virtual int Update(object o)
@@ -533,9 +535,9 @@ namespace DynamORM
return new DynamicDeleteQueryBuilder(this);
}
/// <summary>Removes a record from the database. You can pass in an Anonymous object, an ExpandoObject,
/// A regular old POCO, or a NameValueColletion from a Request.Form or Request.QueryString.</summary>
/// <param name="o">Anonymous object, an ExpandoObject, a regular old POCO, or a NameValueCollection
/// <summary>Removes a record from the database. You can pass in an Anonymous object, an <see cref="ExpandoObject"/>,
/// A regular old POCO, or a NameValueCollection from a Request.Form or Request.QueryString.</summary>
/// <param name="o">Anonymous object, an <see cref="ExpandoObject"/>, a regular old POCO, or a NameValueCollection
/// from a Request.Form or Request.QueryString, containing fields with where conditions.</param>
/// <param name="schema">If <c>true</c> use schema to determine key columns and ignore those which
/// aren't keys.</param>
@@ -579,12 +581,15 @@ namespace DynamORM
case "Insert":
result = DynamicInsert(args, info, types);
break;
case "Update":
result = DynamicUpdate(args, info, types);
break;
case "Delete":
result = DynamicDelete(args, info, types);
break;
default:
result = DynamicQuery(args, info, op, types);
break;
@@ -614,14 +619,17 @@ namespace DynamORM
builder.Table(args[i].ToString());
else goto default;
break;
case "values":
builder.Insert(args[i]);
break;
case "type":
if (types == null || types.Count == 0)
HandleTypeArgument<DynamicInsertQueryBuilder>(args, info, ref types, builder, i);
else goto default;
break;
default:
builder.Insert(name, args[i]);
break;
@@ -654,20 +662,25 @@ namespace DynamORM
builder.Table(args[i].ToString());
else goto default;
break;
case "update":
builder.Update(args[i]);
break;
case "values":
builder.Values(args[i]);
break;
case "where":
builder.Where(args[i]);
break;
case "type":
if (types == null || types.Count == 0)
HandleTypeArgument(args, info, ref types, builder, i);
else goto default;
break;
default:
builder.Update(name, args[i]);
break;
@@ -700,17 +713,21 @@ namespace DynamORM
builder.Table(args[i].ToString());
else goto default;
break;
case "where":
builder.Where(args[i], false);
break;
case "delete":
builder.Where(args[i], true);
break;
case "type":
if (types == null || types.Count == 0)
HandleTypeArgument<DynamicDeleteQueryBuilder>(args, info, ref types, builder, i);
else goto default;
break;
default:
builder.Where(name, args[i]);
break;
@@ -751,6 +768,7 @@ namespace DynamORM
builder.OrderBy((DynamicColumn)args[i]);
else goto default;
break;
case "group":
if (args[i] is string)
builder.GroupBy(((string)args[i]).Split(','));
@@ -762,6 +780,7 @@ namespace DynamORM
builder.GroupBy((DynamicColumn)args[i]);
else goto default;
break;
case "columns":
if (args[i] is string)
builder.Select(((string)args[i]).Split(','));
@@ -773,19 +792,23 @@ namespace DynamORM
builder.Select((DynamicColumn)args[i]);
else goto default;
break;
case "where":
builder.Where(args[i]);
break;
case "table":
if (args[i] is string)
builder.Table(args[i].ToString());
else goto default;
break;
case "type":
if (types == null || types.Count == 0)
HandleTypeArgument<DynamicSelectQueryBuilder>(args, info, ref types, builder, i);
else goto default;
break;
default:
builder.Where(name, args[i]);
break;
@@ -820,6 +843,8 @@ namespace DynamORM
if (op == "Count" && result is long)
result = (int)(long)result;
else if (result == DBNull.Value)
result = null;
}
else
{
@@ -851,7 +876,7 @@ namespace DynamORM
if (op == "Scalar")
{
if (builder.Columns.Count != 1)
throw new InvalidOperationException("You must select one column in scalar steatement.");
throw new InvalidOperationException("You must select one column in scalar statement.");
result = Scalar(builder);
}
@@ -905,11 +930,12 @@ namespace DynamORM
/// freeing, releasing, or resetting unmanaged resources.</summary>
public void Dispose()
{
Database.RemoveFromCache(this);
// Lose reference but don't kill it.
if (Database != null)
{
Database.RemoveFromCache(this);
Database = null;
}
}
#endregion IDisposable Members

View File

@@ -39,7 +39,7 @@ namespace DynamORM.Helpers
{
#region Mono or .NET Framework detection
/// <summary>This is preaty simple trick.</summary>
/// <summary>This is pretty simple trick.</summary>
private static bool _isMono = Type.GetType("Mono.Runtime") != null;
/// <summary>Gets a value indicating whether application is running under mono runtime.</summary>
@@ -98,7 +98,7 @@ namespace DynamORM.Helpers
return null;
}
/// <summary>Extension method allowing to easyly extract generic type
/// <summary>Extension method allowing to easily extract generic type
/// arguments from <see cref="InvokeMemberBinder"/> assuming that it
/// inherits from
/// <c>Microsoft.CSharp.RuntimeBinder.ICSharpInvokeOrInvokeMemberBinder</c>

View File

@@ -31,7 +31,7 @@ using System.Collections.Generic;
namespace DynamORM.Mapper
{
/// <summary>Class with maper cache.</summary>
/// <summary>Class with mapper cache.</summary>
public static class DynamicMapperCache
{
private static readonly object SyncLock = new object();

View File

@@ -106,7 +106,7 @@ namespace DynamORM.Mapper
}
/// <summary>Create object of <see cref="DynamicTypeMap.Type"/> type and fill values from <c>source</c>.</summary>
/// <param name="source">Object containing values that will be mapped to newy created object.</param>
/// <param name="source">Object containing values that will be mapped to newly created object.</param>
/// <returns>New object of <see cref="DynamicTypeMap.Type"/> type with matching values from <c>source</c>.</returns>
public object Create(object source)
{
@@ -114,7 +114,7 @@ namespace DynamORM.Mapper
}
/// <summary>Fill values from <c>source</c> to <see cref="DynamicTypeMap.Type"/> object in <c>destination</c>.</summary>
/// <param name="source">Object containing values that will be mapped to newy created object.</param>
/// <param name="source">Object containing values that will be mapped to newly created object.</param>
/// <param name="destination">Object of <see cref="DynamicTypeMap.Type"/> type to which copy values from <c>source</c>.</param>
/// <returns>Object of <see cref="DynamicTypeMap.Type"/> type with matching values from <c>source</c>.</returns>
public object Map(object source, object destination)

View File

@@ -37,9 +37,9 @@ namespace DynamORM.Mapper
/// <summary>Gets or sets name.</summary>
public string Name { get; set; }
/// <summary>Gets or sets a value indicating whether overide database
/// <summary>Gets or sets a value indicating whether override database
/// schema values.</summary>
/// <remarks>If database doeesn't support schema, you still have to
/// <remarks>If database doesn't support schema, you still have to
/// set this to true to get schema from type.</remarks>
public bool Override { get; set; }
}