Select improvements and alias parsing.

Insert evolved.
This commit is contained in:
grzegorz.russek
2013-06-04 22:16:40 +00:00
parent 02cd81aab5
commit de58df8c60
7 changed files with 167 additions and 18 deletions

View File

@@ -68,5 +68,58 @@ namespace DynamORM.Tests.Modify
Assert.AreEqual(string.Format(@"INSERT INTO ""Users"" (""Code"", ""Name"", ""IsAdmin"") VALUES ({0})", Assert.AreEqual(string.Format(@"INSERT INTO ""Users"" (""Code"", ""Name"", ""IsAdmin"") VALUES ({0})",
string.Join(", ", cmd.Parameters.Keys.Select(p => string.Format("[${0}]", p)))), cmd.CommandText()); string.Join(", ", cmd.Parameters.Keys.Select(p => string.Format("[${0}]", p)))), cmd.CommandText());
} }
/// <summary>
/// Tests the insert with sub query.
/// </summary>
[Test]
public void TestInsertSubQuery()
{
var 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))
.Select(a => a.IsAdmin)
.Where(a => a.User_Id == "001")));
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());
}
/// <summary>
/// Tests the basic insert using object.
/// </summary>
[Test]
public void TestBasicInsertObject()
{
var cmd = new DynamicInsertQueryBuilder(Database, "Users");
cmd.Insert(x => new { Code = "001", Name = "Admin", IsAdmin = 1 });
Assert.AreEqual(string.Format(@"INSERT INTO ""Users"" (""Code"", ""Name"", ""IsAdmin"") VALUES ({0})",
string.Join(", ", cmd.Parameters.Keys.Select(p => string.Format("[${0}]", p)))), cmd.CommandText());
}
/// <summary>
/// Tests the insert using object with sub query.
/// </summary>
[Test]
public void TestInsertSubQueryObject()
{
var cmd = new DynamicInsertQueryBuilder(Database, "Users");
cmd.Insert(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 == "001"))
});
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());
}
} }
} }

View File

@@ -436,6 +436,29 @@ namespace DynamORM.Tests.Select
Assert.AreEqual(exp.last, o.last); Assert.AreEqual(exp.last, o.last);
} }
/// <summary>Test dynamic duplicate column name ocurrance.</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 => 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 #endregion Select
#region Where #region Where

View File

@@ -482,6 +482,20 @@ namespace DynamORM.Tests.Select
Assert.AreEqual("SELECT \"dbo\".\"Users\".\"UserName\" AS \"Name\" FROM \"dbo\".\"Users\"", cmd.CommandText()); Assert.AreEqual("SELECT \"dbo\".\"Users\".\"UserName\" AS \"Name\" FROM \"dbo\".\"Users\"", cmd.CommandText());
} }
/// <summary>
/// Tests select field with alias.
/// </summary>
[Test]
public void TestSelectFieldAlias3()
{
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
cmd.From(u => u.dbo.Users.As(u.u))
.Select(u => u.UserName.As(u.Name));
Assert.AreEqual("SELECT u.\"UserName\" AS \"Name\" FROM \"dbo\".\"Users\" AS u", cmd.CommandText());
}
/// <summary> /// <summary>
/// Tests select aggregate field with alias (Sum). /// Tests select aggregate field with alias (Sum).
/// </summary> /// </summary>

View File

@@ -38,7 +38,7 @@ namespace DynamORM.Tests.Select
/// <summary>Test typed ORM.</summary> /// <summary>Test typed ORM.</summary>
/// <typeparam name="T">Type to test.</typeparam> /// <typeparam name="T">Type to test.</typeparam>
[TestFixture(typeof(users))] [TestFixture(typeof(users))]
public class TypedAccessTests<T> : TestsBase public class TypedAccessTests<T> : TestsBase where T : class
{ {
/// <summary>Setup test parameters.</summary> /// <summary>Setup test parameters.</summary>
[TestFixtureSetUp] [TestFixtureSetUp]
@@ -97,6 +97,18 @@ namespace DynamORM.Tests.Select
Assert.AreEqual(200, list.Count); Assert.AreEqual(200, list.Count);
} }
/// <summary>Test load all rows into mapped list alternate way.</summary>
[Test]
public virtual void TestTypedGetAll3()
{
var list = GetTestBuilder()
.From(x => x(typeof(T)).As(x.t))
.Execute<T>()
.ToList();
Assert.AreEqual(200, list.Count);
}
/// <summary>Test unknown op.</summary> /// <summary>Test unknown op.</summary>
[Test] [Test]
public virtual void TestTypedUnknownOperation() public virtual void TestTypedUnknownOperation()

View File

@@ -5,12 +5,17 @@ namespace DynamORM.Builders
{ {
/// <summary>Dynamic select query builder interface.</summary> /// <summary>Dynamic select query builder interface.</summary>
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks> /// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
public interface IDynamicSelectQueryBuilder : IDynamicQueryBuilder, IEnumerable<object> public interface IDynamicSelectQueryBuilder : IDynamicQueryBuilder ////, IEnumerable<object>
{ {
/// <summary>Execute this builder.</summary> /// <summary>Execute this builder.</summary>
/// <returns>Enumerator of objects expanded from query.</returns> /// <returns>Enumerator of objects expanded from query.</returns>
IEnumerable<dynamic> Execute(); IEnumerable<dynamic> Execute();
/// <summary>Execute this builder and map to given type.</summary>
/// <typeparam name="T">Type of object to map on.</typeparam>
/// <returns>Enumerator of objects expanded from query.</returns>
IEnumerable<T> Execute<T>() where T : class;
/// <summary>Returns a single result.</summary> /// <summary>Returns a single result.</summary>
/// <returns>Result of a query.</returns> /// <returns>Result of a query.</returns>
object Scalar(); object Scalar();

View File

@@ -913,7 +913,15 @@ namespace DynamORM
int c = r.FieldCount; int c = r.FieldCount;
for (int i = 0; i < c; i++) for (int i = 0; i < c; i++)
d.Add(r.GetName(i), r.IsDBNull(i) ? null : r[i]); try
{
d.Add(r.GetName(i), r.IsDBNull(i) ? null : r[i]);
}
catch (ArgumentException argex)
{
throw new ArgumentException(
string.Format("Field '{0}' is defined more than once in a query.", r.GetName(i)), "Column name or alias", argex);
}
return e; return e;
} }

View File

@@ -31,6 +31,7 @@ using System.Collections.Generic;
using System.Data; using System.Data;
using System.Dynamic; using System.Dynamic;
using System.Linq; using System.Linq;
using System.Text;
using DynamORM.Builders; using DynamORM.Builders;
using DynamORM.Builders.Extensions; using DynamORM.Builders.Extensions;
using DynamORM.Builders.Implementation; using DynamORM.Builders.Implementation;
@@ -340,14 +341,30 @@ namespace DynamORM
{ {
using (var con = Database.Open()) using (var con = Database.Open())
using (var cmd = con.CreateCommand()) using (var cmd = con.CreateCommand())
{ using (var rdr = cmd
using (var rdr = cmd .SetCommand(sql, args)
.SetCommand(sql) .ExecuteReader())
.AddParameters(Database, args) while (rdr.Read())
.ExecuteReader()) {
while (rdr.Read()) dynamic val = null;
yield return rdr.RowToDynamic();
} // Work around to avoid yield being in try...catch block:
// http://stackoverflow.com/questions/346365/why-cant-yield-return-appear-inside-a-try-block-with-a-catch
try
{
val = rdr.RowToDynamic();
}
catch (ArgumentException argex)
{
var sb = new StringBuilder();
cmd.Dump(sb);
throw new ArgumentException(string.Format("{0}{1}{2}", argex.Message, Environment.NewLine, sb),
argex.InnerException.NullOr(a => a, argex));
}
yield return val;
}
} }
/// <summary>Enumerate the reader and yield the result.</summary> /// <summary>Enumerate the reader and yield the result.</summary>
@@ -357,13 +374,30 @@ namespace DynamORM
{ {
using (var con = Database.Open()) using (var con = Database.Open())
using (var cmd = con.CreateCommand()) using (var cmd = con.CreateCommand())
{ using (var rdr = cmd
using (var rdr = cmd .SetCommand(builder)
.SetCommand(builder) .ExecuteReader())
.ExecuteReader()) while (rdr.Read())
while (rdr.Read()) {
yield return rdr.RowToDynamic(); dynamic val = null;
}
// Work around to avoid yield being in try...catch block:
// http://stackoverflow.com/questions/346365/why-cant-yield-return-appear-inside-a-try-block-with-a-catch
try
{
val = rdr.RowToDynamic();
}
catch (ArgumentException argex)
{
var sb = new StringBuilder();
cmd.Dump(sb);
throw new ArgumentException(string.Format("{0}{1}{2}", argex.Message, Environment.NewLine, sb),
argex.InnerException.NullOr(a => a, argex));
}
yield return val;
}
} }
/// <summary>Create new <see cref="DynamicSelectQueryBuilder"/>.</summary> /// <summary>Create new <see cref="DynamicSelectQueryBuilder"/>.</summary>