Select improvements and alias parsing.
Insert and updates evolved. Written more tests that intended to break parser. Added basic exception handling, telling user what went wrong. TODO: * INSERT INTO ... SELECT ... * Extend and normalize documentation.
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
*/
|
||||
|
||||
using System.Linq;
|
||||
using DynamORM.Builders;
|
||||
using DynamORM.Builders.Implementation;
|
||||
using NUnit.Framework;
|
||||
|
||||
@@ -55,13 +56,15 @@ namespace DynamORM.Tests.Modify
|
||||
DestroyTestDatabase();
|
||||
}
|
||||
|
||||
#region Insert
|
||||
|
||||
/// <summary>
|
||||
/// Tests the basic insert.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestBasicInsert()
|
||||
public void TestInsertBasic()
|
||||
{
|
||||
var cmd = new DynamicInsertQueryBuilder(Database, "Users");
|
||||
IDynamicInsertQueryBuilder cmd = new DynamicInsertQueryBuilder(Database, "Users");
|
||||
|
||||
cmd.Insert(x => x.Users.Code = "001", x => x.Users.Name = "Admin", x => x.Users.IsAdmin = 1);
|
||||
|
||||
@@ -75,7 +78,7 @@ namespace DynamORM.Tests.Modify
|
||||
[Test]
|
||||
public void TestInsertSubQuery()
|
||||
{
|
||||
var cmd = new DynamicInsertQueryBuilder(Database, "Users");
|
||||
IDynamicInsertQueryBuilder cmd = new DynamicInsertQueryBuilder(Database, "Users");
|
||||
|
||||
cmd.Insert(x => x.Code = "001", x => x.Name = "Admin", x => x.IsAdmin = x(cmd
|
||||
.SubQuery(a => a.AccessRights.As(a.a))
|
||||
@@ -90,9 +93,9 @@ namespace DynamORM.Tests.Modify
|
||||
/// Tests the basic insert using object.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestBasicInsertObject()
|
||||
public void TestInsertBasicObject()
|
||||
{
|
||||
var cmd = new DynamicInsertQueryBuilder(Database, "Users");
|
||||
IDynamicInsertQueryBuilder cmd = new DynamicInsertQueryBuilder(Database, "Users");
|
||||
|
||||
cmd.Insert(x => new { Code = "001", Name = "Admin", IsAdmin = 1 });
|
||||
|
||||
@@ -106,7 +109,7 @@ namespace DynamORM.Tests.Modify
|
||||
[Test]
|
||||
public void TestInsertSubQueryObject()
|
||||
{
|
||||
var cmd = new DynamicInsertQueryBuilder(Database, "Users");
|
||||
IDynamicInsertQueryBuilder cmd = new DynamicInsertQueryBuilder(Database, "Users");
|
||||
|
||||
cmd.Insert(x => new
|
||||
{
|
||||
@@ -121,5 +124,81 @@ namespace DynamORM.Tests.Modify
|
||||
Assert.AreEqual(string.Format(@"INSERT INTO ""Users"" (""Code"", ""Name"", ""IsAdmin"") VALUES ({0}, (SELECT a.""IsAdmin"" FROM ""AccessRights"" AS a WHERE (a.""User_Id"" = [${1}])))",
|
||||
string.Join(", ", cmd.Parameters.Keys.Take(2).Select(p => string.Format("[${0}]", p))), cmd.Parameters.Keys.Last()), cmd.CommandText());
|
||||
}
|
||||
|
||||
#endregion Insert
|
||||
|
||||
#region Update
|
||||
|
||||
/// <summary>
|
||||
/// Tests the basic update.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestUpdateBasic()
|
||||
{
|
||||
IDynamicUpdateQueryBuilder cmd = new DynamicUpdateQueryBuilder(Database, "Users");
|
||||
|
||||
cmd.Values(x => x.Users.Code = "001", x => x.Users.Name = "Admin", x => x.Users.IsAdmin = 1)
|
||||
.Where(x => x.Users.Id_User == 1);
|
||||
|
||||
Assert.AreEqual(string.Format(@"UPDATE ""Users"" SET ""Code"" = [${0}], ""Name"" = [${1}], ""IsAdmin"" = [${2}] WHERE (""Users"".""Id_User"" = [${3}])",
|
||||
cmd.Parameters.Keys.ToArray()[0], cmd.Parameters.Keys.ToArray()[1], cmd.Parameters.Keys.ToArray()[2], cmd.Parameters.Keys.ToArray()[3]), cmd.CommandText());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests the insert with sub query.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestUpdateSubQuery()
|
||||
{
|
||||
IDynamicUpdateQueryBuilder cmd = new DynamicUpdateQueryBuilder(Database, "Users");
|
||||
|
||||
cmd.Values(x => x.Users.Code = "001", x => x.Users.Name = "Admin", x => x.Users.IsAdmin = x(cmd
|
||||
.SubQuery(a => a.AccessRights.As(a.a))
|
||||
.Select(a => a.IsAdmin)
|
||||
.Where(a => a.User_Id == a.Users.Id_User)))
|
||||
.Where(x => x.Users.Id_User == 1);
|
||||
|
||||
Assert.AreEqual(string.Format(@"UPDATE ""Users"" SET ""Code"" = [${0}], ""Name"" = [${1}], ""IsAdmin"" = (SELECT a.""IsAdmin"" FROM ""AccessRights"" AS a WHERE (a.""User_Id"" = ""Users"".""Id_User"")) WHERE (""Users"".""Id_User"" = [${2}])",
|
||||
cmd.Parameters.Keys.ToArray()[0], cmd.Parameters.Keys.ToArray()[1], cmd.Parameters.Keys.ToArray()[2]), cmd.CommandText());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests the basic insert using object.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestUpdateBasicObject()
|
||||
{
|
||||
IDynamicUpdateQueryBuilder cmd = new DynamicUpdateQueryBuilder(Database, "Users");
|
||||
|
||||
cmd.Values(x => new { Code = "001", Name = "Admin", IsAdmin = 1 })
|
||||
.Where(x => new { Id_User = 1 });
|
||||
|
||||
Assert.AreEqual(string.Format(@"UPDATE ""Users"" SET ""Code"" = [${0}], ""Name"" = [${1}], ""IsAdmin"" = [${2}] WHERE (""Id_User"" = [${3}])",
|
||||
cmd.Parameters.Keys.ToArray()[0], cmd.Parameters.Keys.ToArray()[1], cmd.Parameters.Keys.ToArray()[2], cmd.Parameters.Keys.ToArray()[3]), cmd.CommandText());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests the basic insert using object.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestUpdateSubQueryObject()
|
||||
{
|
||||
IDynamicUpdateQueryBuilder cmd = new DynamicUpdateQueryBuilder(Database, "Users");
|
||||
|
||||
cmd.Values(x => new
|
||||
{
|
||||
Code = "001",
|
||||
Name = "Admin",
|
||||
IsAdmin = x(cmd
|
||||
.SubQuery(a => a.AccessRights.As(a.a))
|
||||
.Select(a => a.IsAdmin)
|
||||
.Where(a => a.User_Id == a.Users.Id_User))
|
||||
}).Where(x => new { Id_User = 1 });
|
||||
|
||||
Assert.AreEqual(string.Format(@"UPDATE ""Users"" SET ""Code"" = [${0}], ""Name"" = [${1}], ""IsAdmin"" = (SELECT a.""IsAdmin"" FROM ""AccessRights"" AS a WHERE (a.""User_Id"" = ""Users"".""Id_User"")) WHERE (""Id_User"" = [${2}])",
|
||||
cmd.Parameters.Keys.ToArray()[0], cmd.Parameters.Keys.ToArray()[1], cmd.Parameters.Keys.ToArray()[2]), cmd.CommandText());
|
||||
}
|
||||
|
||||
#endregion Update
|
||||
}
|
||||
}
|
||||
@@ -436,29 +436,23 @@ namespace DynamORM.Tests.Select
|
||||
Assert.AreEqual(exp.last, o.last);
|
||||
}
|
||||
|
||||
/// <summary>Test dynamic duplicate column name ocurrance.</summary>
|
||||
/// <summary>Test dynamic duplicate column name occurrence.</summary>
|
||||
[Test]
|
||||
public void TestDuplicateColumnNameException()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => GetTestBuilder()
|
||||
.Where(x => x.id == 19)
|
||||
.Select(x => new { id = x.id, first = x.first, last = x.last })
|
||||
.Select(x => new
|
||||
{
|
||||
id = x.id,
|
||||
first = x.first,
|
||||
last = x.last,
|
||||
})
|
||||
.Select(x => x.last.As(x.first)) // Make last be first
|
||||
.Execute()
|
||||
.First());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEmptyColumnName()
|
||||
{
|
||||
var v = GetTestBuilder()
|
||||
.Select(x => x.first, x => x.Count(x.first))
|
||||
.GroupBy(x => x.first)
|
||||
.OrderBy(x => x.Desc(2))
|
||||
.Execute()
|
||||
.ToList();
|
||||
}
|
||||
|
||||
#endregion Select
|
||||
|
||||
#region Where
|
||||
|
||||
@@ -326,6 +326,21 @@ namespace DynamORM.Tests.Select
|
||||
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS usr INNER JOIN \"dbo\".\"UserClients\" AS uc ON (usr.\"Id_User\" = uc.\"User_Id\")"), cmd.CommandText());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests inner join method with aliases mix.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestInnerJoin2()
|
||||
{
|
||||
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||
|
||||
cmd.From(u => u.dbo.Users.As(u.usr))
|
||||
.Join(usr => usr.Inner().dbo.UserClients.AS(usr.uc).On(usr.Id_User == usr.uc.User_Id && usr.uc.Users != null))
|
||||
.Select(usr => usr.All(), uc => uc.Users);
|
||||
|
||||
Assert.AreEqual(string.Format("SELECT usr.*, uc.\"Users\" FROM \"dbo\".\"Users\" AS usr INNER JOIN \"dbo\".\"UserClients\" AS uc ON ((usr.\"Id_User\" = uc.\"User_Id\") AND (uc.\"Users\" IS NOT NULL))"), cmd.CommandText());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests left outer join method.
|
||||
/// </summary>
|
||||
@@ -496,6 +511,20 @@ namespace DynamORM.Tests.Select
|
||||
Assert.AreEqual("SELECT u.\"UserName\" AS \"Name\" FROM \"dbo\".\"Users\" AS u", cmd.CommandText());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests select field with alias.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSelectFieldAlias4()
|
||||
{
|
||||
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||
|
||||
cmd.From(u => u.dbo.Users.As(u.u))
|
||||
.Select(u => u.UserName.As(u.u.Name));
|
||||
|
||||
Assert.AreEqual("SELECT u.\"UserName\" AS \"Name\" FROM \"dbo\".\"Users\" AS u", cmd.CommandText());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests select aggregate field with alias (Sum).
|
||||
/// </summary>
|
||||
|
||||
@@ -1,4 +1,32 @@
|
||||
using System;
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DynamORM.Builders
|
||||
|
||||
@@ -1,8 +1,30 @@
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="ITableInfo.cs" company="Microsoft">
|
||||
// TODO: Update copyright text.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
<Compile Include="DynamicDatabase.cs" />
|
||||
<Compile Include="DynamicDatabaseOptions.cs" />
|
||||
<Compile Include="DynamicExtensions.cs" />
|
||||
<Compile Include="DynamicQueryException.cs" />
|
||||
<Compile Include="DynamicSchemaColumn.cs" />
|
||||
<Compile Include="DynamicTable.cs" />
|
||||
<Compile Include="DynamicTransaction.cs" />
|
||||
|
||||
@@ -28,11 +28,12 @@
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using DynamORM.Helpers;
|
||||
|
||||
namespace DynamORM
|
||||
{
|
||||
/// <summary>Helper class to easy manage command.</summary>
|
||||
public class DynamicCommand : IDbCommand
|
||||
public class DynamicCommand : IDbCommand, IExtendedDisposable
|
||||
{
|
||||
private IDbCommand _command;
|
||||
private int? _commandTimeout = null;
|
||||
@@ -45,6 +46,7 @@ namespace DynamORM
|
||||
/// <param name="db">The database manager.</param>
|
||||
internal DynamicCommand(DynamicConnection con, DynamicDatabase db)
|
||||
{
|
||||
IsDisposed = false;
|
||||
_con = con;
|
||||
_db = db;
|
||||
|
||||
@@ -65,6 +67,7 @@ namespace DynamORM
|
||||
/// <remarks>Used internally to create command without context.</remarks>
|
||||
internal DynamicCommand(DynamicDatabase db)
|
||||
{
|
||||
IsDisposed = false;
|
||||
_db = db;
|
||||
_command = db.Provider.CreateCommand();
|
||||
}
|
||||
@@ -151,9 +154,16 @@ namespace DynamORM
|
||||
/// data provider, and returns the number of rows affected.</summary>
|
||||
/// <returns>The number of rows affected.</returns>
|
||||
public int ExecuteNonQuery()
|
||||
{
|
||||
try
|
||||
{
|
||||
return PrepareForExecution().ExecuteNonQuery();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new DynamicQueryException(ex, this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Executes the <see cref="P:System.Data.IDbCommand.CommandText"/>
|
||||
/// against the <see cref="P:System.Data.IDbCommand.Connection"/>,
|
||||
@@ -163,27 +173,48 @@ namespace DynamORM
|
||||
/// <see cref="T:System.Data.CommandBehavior"/> values.</param>
|
||||
/// <returns>An <see cref="T:System.Data.IDataReader"/> object.</returns>
|
||||
public IDataReader ExecuteReader(CommandBehavior behavior)
|
||||
{
|
||||
try
|
||||
{
|
||||
return PrepareForExecution().ExecuteReader(behavior);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new DynamicQueryException(ex, this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Executes the <see cref="P:System.Data.IDbCommand.CommandText"/>
|
||||
/// against the <see cref="P:System.Data.IDbCommand.Connection"/> and
|
||||
/// builds an <see cref="T:System.Data.IDataReader"/>.</summary>
|
||||
/// <returns>An <see cref="T:System.Data.IDataReader"/> object.</returns>
|
||||
public IDataReader ExecuteReader()
|
||||
{
|
||||
try
|
||||
{
|
||||
return PrepareForExecution().ExecuteReader();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new DynamicQueryException(ex, this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Executes the query, and returns the first column of the
|
||||
/// 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 result set.</returns>
|
||||
public object ExecuteScalar()
|
||||
{
|
||||
try
|
||||
{
|
||||
return PrepareForExecution().ExecuteScalar();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new DynamicQueryException(ex, this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets the <see cref="T:System.Data.IDataParameterCollection"/>.</summary>
|
||||
public IDataParameterCollection Parameters
|
||||
@@ -193,9 +224,16 @@ namespace DynamORM
|
||||
|
||||
/// <summary>Creates a prepared (or compiled) version of the command on the data source.</summary>
|
||||
public void Prepare()
|
||||
{
|
||||
try
|
||||
{
|
||||
_command.Prepare();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new DynamicQueryException("Error preparing command.", ex, this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets or sets the transaction within which the Command
|
||||
/// object of a data provider executes.</summary>
|
||||
@@ -214,7 +252,7 @@ namespace DynamORM
|
||||
|
||||
#endregion IDbCommand Members
|
||||
|
||||
#region IDisposable Members
|
||||
#region IExtendedDisposable Members
|
||||
|
||||
/// <summary>Performs application-defined tasks associated with
|
||||
/// freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
@@ -231,9 +269,14 @@ namespace DynamORM
|
||||
}
|
||||
|
||||
_command.Dispose();
|
||||
|
||||
IsDisposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion IDisposable Members
|
||||
/// <summary>Gets a value indicating whether this instance is disposed.</summary>
|
||||
public bool IsDisposed { get; private set; }
|
||||
|
||||
#endregion IExtendedDisposable Members
|
||||
}
|
||||
}
|
||||
@@ -28,13 +28,14 @@
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using DynamORM.Helpers;
|
||||
|
||||
namespace DynamORM
|
||||
{
|
||||
/// <summary>Connection wrapper.</summary>
|
||||
/// <remarks>This class is only connection holder, connection is managed by
|
||||
/// <see cref="DynamicDatabase"/> instance.</remarks>
|
||||
public class DynamicConnection : IDbConnection, IDisposable
|
||||
public class DynamicConnection : IDbConnection, IExtendedDisposable
|
||||
{
|
||||
private DynamicDatabase _db;
|
||||
private bool _singleTransaction;
|
||||
@@ -48,6 +49,7 @@ namespace DynamORM
|
||||
/// <param name="singleTransaction">Are we using single transaction mode? I so... act correctly.</param>
|
||||
internal DynamicConnection(DynamicDatabase db, IDbConnection con, bool singleTransaction)
|
||||
{
|
||||
IsDisposed = false;
|
||||
_db = db;
|
||||
Connection = con;
|
||||
_singleTransaction = singleTransaction;
|
||||
@@ -147,11 +149,19 @@ namespace DynamORM
|
||||
|
||||
#endregion IDbConnection Members
|
||||
|
||||
#region IExtendedDisposable Members
|
||||
|
||||
/// <summary>Performs application-defined tasks associated with freeing,
|
||||
/// releasing, or resetting unmanaged resources.</summary>
|
||||
public void Dispose()
|
||||
{
|
||||
_db.Close(Connection);
|
||||
}
|
||||
IsDisposed = true;
|
||||
}
|
||||
|
||||
/// <summary>Gets a value indicating whether this instance is disposed.</summary>
|
||||
public bool IsDisposed { get; private set; }
|
||||
|
||||
#endregion IExtendedDisposable Members
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,7 @@ using DynamORM.Mapper;
|
||||
namespace DynamORM
|
||||
{
|
||||
/// <summary>Dynamic database is a class responsible for managing database.</summary>
|
||||
public class DynamicDatabase : IDisposable
|
||||
public class DynamicDatabase : IExtendedDisposable
|
||||
{
|
||||
#region Internal fields and properties
|
||||
|
||||
@@ -127,6 +127,7 @@ namespace DynamORM
|
||||
/// <param name="options">Connection options.</param>
|
||||
public DynamicDatabase(DbProviderFactory provider, string connectionString, DynamicDatabaseOptions options)
|
||||
{
|
||||
IsDisposed = false;
|
||||
_provider = provider;
|
||||
|
||||
InitCommon(connectionString, options);
|
||||
@@ -137,6 +138,7 @@ namespace DynamORM
|
||||
/// <param name="options">Connection options. <see cref="DynamicDatabaseOptions.SingleConnection"/> required.</param>
|
||||
public DynamicDatabase(IDbConnection connection, DynamicDatabaseOptions options)
|
||||
{
|
||||
IsDisposed = false;
|
||||
InitCommon(connection.ConnectionString, options);
|
||||
TransactionPool.Add(connection, new Stack<IDbTransaction>());
|
||||
|
||||
@@ -643,7 +645,7 @@ namespace DynamORM
|
||||
|
||||
#endregion Transaction
|
||||
|
||||
#region IDisposable Members
|
||||
#region IExtendedDisposable Members
|
||||
|
||||
/// <summary>Performs application-defined tasks associated with freeing,
|
||||
/// releasing, or resetting unmanaged resources.</summary>
|
||||
@@ -684,9 +686,13 @@ namespace DynamORM
|
||||
// Clear pools
|
||||
TransactionPool.Clear();
|
||||
CommandsPool.Clear();
|
||||
IsDisposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion IDisposable Members
|
||||
/// <summary>Gets a value indicating whether this instance is disposed.</summary>
|
||||
public bool IsDisposed { get; private set; }
|
||||
|
||||
#endregion IExtendedDisposable Members
|
||||
}
|
||||
}
|
||||
@@ -798,9 +798,9 @@ namespace DynamORM
|
||||
#region Dynamic extensions
|
||||
|
||||
/// <summary>Turns an <see cref="IDataReader"/> to a Dynamic list of things.</summary>
|
||||
/// <param name="r">Reader from which read data..</param>
|
||||
/// <param name="r">Reader from which read data.</param>
|
||||
/// <returns>List of things.</returns>
|
||||
public static List<dynamic> ToDynamicList(this IDataReader r)
|
||||
public static List<dynamic> ToList(this IDataReader r)
|
||||
{
|
||||
var result = new List<dynamic>();
|
||||
|
||||
@@ -810,6 +810,23 @@ namespace DynamORM
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Turns an <see cref="IDynamicSelectQueryBuilder"/> to a Dynamic list of things.</summary>
|
||||
/// <param name="b">Ready to execute builder.</param>
|
||||
/// <returns>List of things.</returns>
|
||||
public static List<dynamic> ToList(this IDynamicSelectQueryBuilder b)
|
||||
{
|
||||
return b.Execute().ToList();
|
||||
}
|
||||
|
||||
/// <summary>Turns an <see cref="IDynamicSelectQueryBuilder"/> to a Dynamic list of things with specified type.</summary>
|
||||
/// <typeparam name="T">Type of object to map on.</typeparam>
|
||||
/// <param name="b">Ready to execute builder.</param>
|
||||
/// <returns>List of things.</returns>
|
||||
public static List<T> ToList<T>(this IDynamicSelectQueryBuilder b) where T : class
|
||||
{
|
||||
return b.Execute<T>().ToList();
|
||||
}
|
||||
|
||||
/// <summary>Turns the dictionary into an ExpandoObject.</summary>
|
||||
/// <param name="d">Dictionary to convert.</param>
|
||||
/// <returns>Converted dictionary.</returns>
|
||||
|
||||
128
DynamORM/DynamicQueryException.cs
Normal file
128
DynamORM/DynamicQueryException.cs
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
|
||||
namespace DynamORM
|
||||
{
|
||||
/// <summary>Dynamic query exception.</summary>
|
||||
public class DynamicQueryException : Exception, ISerializable
|
||||
{
|
||||
/// <summary>Gets the dumped command which failed.</summary>
|
||||
public string Command { get; private set; }
|
||||
|
||||
/// <summary>Initializes a new instance of the
|
||||
/// <see cref="DynamicQueryException"/> class.</summary>
|
||||
/// <param name="command">The command which failed.</param>
|
||||
public DynamicQueryException(IDbCommand command = null)
|
||||
: base("Error executing command.")
|
||||
{
|
||||
if (command != null)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
command.Dump(sb);
|
||||
Command = sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Initializes a new instance of the
|
||||
/// <see cref="DynamicQueryException"/> class.</summary>
|
||||
/// <param name="message">The message.</param>
|
||||
/// <param name="command">The command which failed.</param>
|
||||
public DynamicQueryException(string message, IDbCommand command = null)
|
||||
: base(message)
|
||||
{
|
||||
SetCommand(command);
|
||||
}
|
||||
|
||||
/// <summary>Initializes a new instance of the
|
||||
/// <see cref="DynamicQueryException"/> class.</summary>
|
||||
/// <param name="innerException">The inner exception.</param>
|
||||
/// <param name="command">The command which failed.</param>
|
||||
public DynamicQueryException(Exception innerException, IDbCommand command = null)
|
||||
: base("Error executing command.", innerException)
|
||||
{
|
||||
SetCommand(command);
|
||||
}
|
||||
|
||||
/// <summary>Initializes a new instance of the
|
||||
/// <see cref="DynamicQueryException"/> class.</summary>
|
||||
/// <param name="message">The message.</param>
|
||||
/// <param name="innerException">The inner exception.</param>
|
||||
/// <param name="command">The command which failed.</param>
|
||||
public DynamicQueryException(string message, Exception innerException, IDbCommand command = null)
|
||||
: base(message, innerException)
|
||||
{
|
||||
SetCommand(command);
|
||||
}
|
||||
|
||||
/// <summary>Initializes a new instance of the
|
||||
/// <see cref="DynamicQueryException"/> class.</summary>
|
||||
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo" />
|
||||
/// that holds the serialized object data about the exception being thrown.</param>
|
||||
/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext" />
|
||||
/// that contains contextual information about the source or destination.</param>
|
||||
public DynamicQueryException(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
Command = info.GetString("Command");
|
||||
}
|
||||
|
||||
/// <summary>When overridden in a derived class, sets the
|
||||
/// <see cref="T:System.Runtime.Serialization.SerializationInfo" />
|
||||
/// with information about the exception.</summary>
|
||||
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo" />
|
||||
/// that holds the serialized object data about the exception being thrown.</param>
|
||||
/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext" />
|
||||
/// that contains contextual information about the source or destination.</param>
|
||||
/// <PermissionSet>
|
||||
/// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Read="*AllFiles*" PathDiscovery="*AllFiles*" />
|
||||
/// <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="SerializationFormatter" />
|
||||
/// </PermissionSet>
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
base.GetObjectData(info, context);
|
||||
|
||||
if (!string.IsNullOrEmpty(Command))
|
||||
info.AddValue("Command", Command);
|
||||
}
|
||||
|
||||
private void SetCommand(IDbCommand command)
|
||||
{
|
||||
if (command != null && (!(command is DynamicCommand) || ((command is DynamicCommand) && !(command as DynamicCommand).IsDisposed)))
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
command.Dump(sb);
|
||||
Command = sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -194,7 +194,7 @@ namespace DynamORM
|
||||
/// });</code>
|
||||
/// <code>x.Delete(where: new { id = 14, code = 14 });</code>
|
||||
/// </example>
|
||||
public class DynamicTable : DynamicObject, IDisposable, ICloneable
|
||||
public class DynamicTable : DynamicObject, IExtendedDisposable, ICloneable
|
||||
{
|
||||
private static HashSet<string> _allowedCommands = new HashSet<string>
|
||||
{
|
||||
@@ -243,6 +243,7 @@ namespace DynamORM
|
||||
/// <param name="keys">Override keys in schema.</param>
|
||||
public DynamicTable(DynamicDatabase database, string table = "", string owner = "", string[] keys = null)
|
||||
{
|
||||
IsDisposed = false;
|
||||
Database = database;
|
||||
TableName = Database.StripName(table);
|
||||
OwnerName = Database.StripName(owner);
|
||||
@@ -260,15 +261,20 @@ namespace DynamORM
|
||||
if (type == null)
|
||||
throw new ArgumentNullException("type", "Type can't be null.");
|
||||
|
||||
Database = database;
|
||||
IsDisposed = false;
|
||||
|
||||
Database = database;
|
||||
TableType = type;
|
||||
|
||||
var mapper = DynamicMapperCache.GetMapper(type);
|
||||
|
||||
if (mapper != null)
|
||||
{
|
||||
TableName = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Name) ?
|
||||
type.Name : mapper.Table.Name;
|
||||
OwnerName = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Name) ?
|
||||
type.Name : mapper.Table.Name;
|
||||
}
|
||||
|
||||
BuildAndCacheSchema(keys);
|
||||
}
|
||||
@@ -995,7 +1001,7 @@ namespace DynamORM
|
||||
|
||||
#endregion Universal Dynamic Invoker
|
||||
|
||||
#region IDisposable Members
|
||||
#region IExtendedDisposable Members
|
||||
|
||||
/// <summary>Performs application-defined tasks associated with
|
||||
/// freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
@@ -1007,9 +1013,14 @@ namespace DynamORM
|
||||
Database.RemoveFromCache(this);
|
||||
Database = null;
|
||||
}
|
||||
|
||||
IsDisposed = true;
|
||||
}
|
||||
|
||||
#endregion IDisposable Members
|
||||
/// <summary>Gets a value indicating whether this instance is disposed.</summary>
|
||||
public bool IsDisposed { get; private set; }
|
||||
|
||||
#endregion IExtendedDisposable Members
|
||||
|
||||
#region ICloneable Members
|
||||
|
||||
|
||||
@@ -28,11 +28,12 @@
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using DynamORM.Helpers;
|
||||
|
||||
namespace DynamORM
|
||||
{
|
||||
/// <summary>Helper class to easy manage transaction.</summary>
|
||||
public class DynamicTransaction : IDbTransaction, IDisposable
|
||||
public class DynamicTransaction : IDbTransaction, IExtendedDisposable
|
||||
{
|
||||
private DynamicDatabase _db;
|
||||
private DynamicConnection _con;
|
||||
@@ -48,6 +49,7 @@ namespace DynamORM
|
||||
/// <param name="disposed">This action is invoked when transaction is disposed.</param>
|
||||
internal DynamicTransaction(DynamicDatabase db, DynamicConnection con, bool singleTransaction, IsolationLevel? il, Action disposed)
|
||||
{
|
||||
IsDisposed = false;
|
||||
_db = db;
|
||||
_con = con;
|
||||
_singleTransaction = singleTransaction;
|
||||
@@ -125,6 +127,8 @@ namespace DynamORM
|
||||
/// <summary>Gets <see cref="System.Data.IsolationLevel"/> for this transaction.</summary>
|
||||
public IsolationLevel IsolationLevel { get; private set; }
|
||||
|
||||
#region IExtendedDisposable Members
|
||||
|
||||
/// <summary>Performs application-defined tasks associated with
|
||||
/// freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
public void Dispose()
|
||||
@@ -133,6 +137,13 @@ namespace DynamORM
|
||||
|
||||
if (_disposed != null)
|
||||
_disposed();
|
||||
}
|
||||
|
||||
IsDisposed = true;
|
||||
}
|
||||
|
||||
/// <summary>Gets a value indicating whether this instance is disposed.</summary>
|
||||
public bool IsDisposed { get; private set; }
|
||||
|
||||
#endregion IExtendedDisposable Members
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user