New version alpha
This commit is contained in:
@@ -13,11 +13,16 @@
|
|||||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<TargetFrameworkProfile />
|
<TargetFrameworkProfile />
|
||||||
|
<NoWin32Manifest>False</NoWin32Manifest>
|
||||||
|
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
|
||||||
|
<NoStdLib>False</NoStdLib>
|
||||||
|
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
|
||||||
|
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>Full</DebugType>
|
||||||
<Optimize>false</Optimize>
|
<Optimize>False</Optimize>
|
||||||
<OutputPath>bin\Debug\</OutputPath>
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
@@ -31,6 +36,17 @@
|
|||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||||
|
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
|
||||||
|
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
|
||||||
|
<BaseAddress>4194304</BaseAddress>
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<RegisterForComInterop>False</RegisterForComInterop>
|
||||||
|
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
|
||||||
|
<Prefer32Bit>False</Prefer32Bit>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="nunit.framework, Version=2.5.10.11092, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />
|
<Reference Include="nunit.framework, Version=2.5.10.11092, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />
|
||||||
@@ -45,10 +61,12 @@
|
|||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Helpers\Dynamic\DynamicParserTests.cs" />
|
||||||
<Compile Include="Helpers\PoolingTests.cs" />
|
<Compile Include="Helpers\PoolingTests.cs" />
|
||||||
<Compile Include="Modify\DynamicModificationTests.cs" />
|
<Compile Include="Modify\DynamicModificationTests.cs" />
|
||||||
<Compile Include="Modify\DynamicNoSchemaModificationTests.cs" />
|
<Compile Include="Modify\DynamicNoSchemaModificationTests.cs" />
|
||||||
<Compile Include="Modify\DynamicTypeSchemaModificationTests.cs" />
|
<Compile Include="Modify\DynamicTypeSchemaModificationTests.cs" />
|
||||||
|
<Compile Include="Modify\ParserTests.cs" />
|
||||||
<Compile Include="Select\DynamicNoSchemaAccessTests.cs" />
|
<Compile Include="Select\DynamicNoSchemaAccessTests.cs" />
|
||||||
<Compile Include="Select\DynamicTypeSchemaAccessTests.cs" />
|
<Compile Include="Select\DynamicTypeSchemaAccessTests.cs" />
|
||||||
<Compile Include="Helpers\AttachToDebugger.cs" />
|
<Compile Include="Helpers\AttachToDebugger.cs" />
|
||||||
@@ -61,7 +79,9 @@
|
|||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
<DependentUpon>Resources.resx</DependentUpon>
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Select\LegacyParserTests.cs" />
|
||||||
<Compile Include="Select\RenamedTypedAccessTests.cs" />
|
<Compile Include="Select\RenamedTypedAccessTests.cs" />
|
||||||
|
<Compile Include="Select\ParserTests.cs" />
|
||||||
<Compile Include="TestsBase.cs" />
|
<Compile Include="TestsBase.cs" />
|
||||||
<Compile Include="Select\TypedAccessTests.cs" />
|
<Compile Include="Select\TypedAccessTests.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ namespace DynamORM.Tests.Helpers
|
|||||||
Debugger.Launch();
|
Debugger.Launch();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Test anonymous type compatybility.</summary>
|
/// <summary>Test anonymous type compatibility.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestAnonType()
|
public void TestAnonType()
|
||||||
{
|
{
|
||||||
@@ -59,14 +59,14 @@ namespace DynamORM.Tests.Helpers
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestAnonTypeValue()
|
public void TestAnonTypeValue()
|
||||||
{
|
{
|
||||||
var a = new { x = 1, y = "bla bla" };
|
var a = new { x = 1, y = "bla bla" };
|
||||||
var b = new { x = 1, y = "bla bla" };
|
var b = new { x = 1, y = "bla bla" };
|
||||||
|
|
||||||
Assert.AreEqual(a, b);
|
Assert.AreEqual(a, b);
|
||||||
Assert.IsTrue(a.Equals(b));
|
Assert.IsTrue(a.Equals(b));
|
||||||
|
|
||||||
Dictionary<object, int> dict = new Dictionary<object, int>() { { a, 999 } };
|
Dictionary<object, int> dict = new Dictionary<object, int>() { { a, 999 } };
|
||||||
|
|
||||||
Assert.IsTrue(dict.ContainsKey(b));
|
Assert.IsTrue(dict.ContainsKey(b));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
121
DynamORM.Tests/Helpers/Dynamic/DynamicParserTests.cs
Normal file
121
DynamORM.Tests/Helpers/Dynamic/DynamicParserTests.cs
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* 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 DynamORM.Helpers.Dynamics;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace DynamORM.Tests.Helpers.Dynamic
|
||||||
|
{
|
||||||
|
/// <summary><see cref="DynamicParser"/> tests.</summary>
|
||||||
|
[TestFixture]
|
||||||
|
public class DynamicParserTests
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the get member.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestGetMember()
|
||||||
|
{
|
||||||
|
Func<dynamic, object> f = x => x.SomePropery;
|
||||||
|
|
||||||
|
var val = DynamicParser.Parse(f).Result as DynamicParser.Node.GetMember;
|
||||||
|
|
||||||
|
Assert.NotNull(val);
|
||||||
|
Assert.AreEqual("SomePropery", val.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the set member.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSetMember()
|
||||||
|
{
|
||||||
|
Func<dynamic, object> f = x => x.SomePropery = "value";
|
||||||
|
|
||||||
|
var val = DynamicParser.Parse(f).Result as DynamicParser.Node.SetMember;
|
||||||
|
|
||||||
|
Assert.NotNull(val);
|
||||||
|
Assert.AreEqual("SomePropery", val.Name);
|
||||||
|
Assert.AreEqual("value", val.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the index of the get.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestGetIndex()
|
||||||
|
{
|
||||||
|
Func<dynamic, object> f = x => x.SomePropery[0];
|
||||||
|
|
||||||
|
var val = DynamicParser.Parse(f).Result as DynamicParser.Node.GetIndex;
|
||||||
|
|
||||||
|
Assert.NotNull(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the index of the set.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSetIndex()
|
||||||
|
{
|
||||||
|
Func<dynamic, object> f = x => x.SomePropery[0] = "value";
|
||||||
|
|
||||||
|
var val = DynamicParser.Parse(f).Result as DynamicParser.Node.SetIndex;
|
||||||
|
|
||||||
|
Assert.NotNull(val);
|
||||||
|
Assert.AreEqual("value", val.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests something.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSomething()
|
||||||
|
{
|
||||||
|
Func<dynamic, object> f = x => x.SomePropery == "value" || x.OtherProperty == -1;
|
||||||
|
|
||||||
|
var p = DynamicParser.Parse(f);
|
||||||
|
var val = p.Result as DynamicParser.Node.Binary;
|
||||||
|
|
||||||
|
Assert.NotNull(val);
|
||||||
|
|
||||||
|
var left = val.Host as DynamicParser.Node.Binary;
|
||||||
|
var right = val.Right as DynamicParser.Node.Binary;
|
||||||
|
|
||||||
|
Assert.NotNull(left);
|
||||||
|
Assert.NotNull(right);
|
||||||
|
|
||||||
|
Assert.IsInstanceOf<DynamicParser.Node.GetMember>(left.Host);
|
||||||
|
Assert.IsInstanceOf<DynamicParser.Node.GetMember>(right.Host);
|
||||||
|
|
||||||
|
Assert.AreEqual("value", left.Right);
|
||||||
|
Assert.AreEqual(-1, right.Right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,7 +46,7 @@ namespace DynamORM.Tests.Helpers
|
|||||||
[Column("login")]
|
[Column("login")]
|
||||||
public string Login { get; set; }
|
public string Login { get; set; }
|
||||||
|
|
||||||
/// <summary>Gets or sets first columnvalue.</summary>
|
/// <summary>Gets or sets first column value.</summary>
|
||||||
[Column("first")]
|
[Column("first")]
|
||||||
public string First { get; set; }
|
public string First { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ namespace DynamORM.Tests.Helpers
|
|||||||
/// <summary>Gets or sets login column value.</summary>
|
/// <summary>Gets or sets login column value.</summary>
|
||||||
public string login { get; set; }
|
public string login { get; set; }
|
||||||
|
|
||||||
/// <summary>Gets or sets first columnvalue.</summary>
|
/// <summary>Gets or sets first column value.</summary>
|
||||||
public string first { get; set; }
|
public string first { get; set; }
|
||||||
|
|
||||||
/// <summary>Gets or sets last column value.</summary>
|
/// <summary>Gets or sets last column value.</summary>
|
||||||
|
|||||||
@@ -65,12 +65,12 @@ namespace DynamORM.Tests.Modify
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestInsertByArguments()
|
public void TestInsertByArguments()
|
||||||
{
|
{
|
||||||
Assert.AreEqual(1, GetTestTable().Insert(code: 201, first: null, 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
|
// Verify
|
||||||
var o = GetTestTable().Single(code: 201);
|
var o = GetTestTable().Single(code: "201");
|
||||||
Assert.Less(200, o.id);
|
Assert.Less(200, o.id);
|
||||||
Assert.AreEqual("201", o.code);
|
Assert.AreEqual("201", o.code.ToString());
|
||||||
Assert.AreEqual(null, o.first);
|
Assert.AreEqual(null, o.first);
|
||||||
Assert.AreEqual("Gagarin", o.last);
|
Assert.AreEqual("Gagarin", o.last);
|
||||||
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
||||||
@@ -82,12 +82,12 @@ namespace DynamORM.Tests.Modify
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestInsertByDynamicObjects()
|
public void TestInsertByDynamicObjects()
|
||||||
{
|
{
|
||||||
Assert.AreEqual(1, GetTestTable().Insert(values: new { code = 202, first = DBNull.Value, 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
|
// Verify
|
||||||
var o = GetTestTable().Single(code: 202);
|
var o = GetTestTable().Single(code: "202");
|
||||||
Assert.Less(200, o.id);
|
Assert.Less(200, o.id);
|
||||||
Assert.AreEqual("202", o.code);
|
Assert.AreEqual("202", o.code.ToString());
|
||||||
Assert.AreEqual(null, o.first);
|
Assert.AreEqual(null, o.first);
|
||||||
Assert.AreEqual("Gagarin", o.last);
|
Assert.AreEqual("Gagarin", o.last);
|
||||||
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
||||||
@@ -112,9 +112,9 @@ namespace DynamORM.Tests.Modify
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
var o = u.Single(code: 203);
|
var o = u.Single(code: "203");
|
||||||
Assert.Less(200, o.id);
|
Assert.Less(200, o.id);
|
||||||
Assert.AreEqual("203", o.code);
|
Assert.AreEqual("203", o.code.ToString());
|
||||||
Assert.AreEqual(null, o.first);
|
Assert.AreEqual(null, o.first);
|
||||||
Assert.AreEqual("Gagarin", o.last);
|
Assert.AreEqual("Gagarin", o.last);
|
||||||
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
||||||
@@ -139,9 +139,9 @@ namespace DynamORM.Tests.Modify
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
var o = u.Single(code: 204);
|
var o = u.Single(code: "204");
|
||||||
Assert.Less(200, o.id);
|
Assert.Less(200, o.id);
|
||||||
Assert.AreEqual("204", o.code);
|
Assert.AreEqual("204", o.code.ToString());
|
||||||
Assert.AreEqual(null, o.first);
|
Assert.AreEqual(null, o.first);
|
||||||
Assert.AreEqual("Gagarin", o.last);
|
Assert.AreEqual("Gagarin", o.last);
|
||||||
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
||||||
@@ -157,12 +157,12 @@ namespace DynamORM.Tests.Modify
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestUpdateByArguments()
|
public void TestUpdateByArguments()
|
||||||
{
|
{
|
||||||
Assert.AreEqual(1, GetTestTable().Update(id: 1, code: 201, first: null, 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
|
// Verify
|
||||||
var o = GetTestTable().Single(code: 201);
|
var o = GetTestTable().Single(code: "201");
|
||||||
Assert.AreEqual(1, o.id);
|
Assert.AreEqual(1, o.id);
|
||||||
Assert.AreEqual("201", o.code);
|
Assert.AreEqual("201", o.code.ToString());
|
||||||
Assert.AreEqual(null, o.first);
|
Assert.AreEqual(null, o.first);
|
||||||
Assert.AreEqual("Gagarin", o.last);
|
Assert.AreEqual("Gagarin", o.last);
|
||||||
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
||||||
@@ -174,12 +174,12 @@ namespace DynamORM.Tests.Modify
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestUpdateByDynamicObject()
|
public void TestUpdateByDynamicObject()
|
||||||
{
|
{
|
||||||
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" }));
|
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
|
// Verify
|
||||||
var o = GetTestTable().Single(code: 202);
|
var o = GetTestTable().Single(code: "202");
|
||||||
Assert.AreEqual(2, o.id);
|
Assert.AreEqual(2, o.id);
|
||||||
Assert.AreEqual("202", o.code);
|
Assert.AreEqual("202", o.code.ToString());
|
||||||
Assert.AreEqual(null, o.first);
|
Assert.AreEqual(null, o.first);
|
||||||
Assert.AreEqual("Gagarin", o.last);
|
Assert.AreEqual("Gagarin", o.last);
|
||||||
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
||||||
@@ -204,9 +204,9 @@ namespace DynamORM.Tests.Modify
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
var o = u.Single(code: 203);
|
var o = u.Single(code: "203");
|
||||||
Assert.AreEqual(3, o.id);
|
Assert.AreEqual(3, o.id);
|
||||||
Assert.AreEqual("203", o.code);
|
Assert.AreEqual("203", o.code.ToString());
|
||||||
Assert.AreEqual(null, o.first);
|
Assert.AreEqual(null, o.first);
|
||||||
Assert.AreEqual("Gagarin", o.last);
|
Assert.AreEqual("Gagarin", o.last);
|
||||||
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
||||||
@@ -231,9 +231,9 @@ namespace DynamORM.Tests.Modify
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
var o = u.Single(code: 204);
|
var o = u.Single(code: "204");
|
||||||
Assert.AreEqual(4, o.id);
|
Assert.AreEqual(4, o.id);
|
||||||
Assert.AreEqual("204", o.code);
|
Assert.AreEqual("204", o.code.ToString());
|
||||||
Assert.AreEqual(null, o.first);
|
Assert.AreEqual(null, o.first);
|
||||||
Assert.AreEqual("Gagarin", o.last);
|
Assert.AreEqual("Gagarin", o.last);
|
||||||
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
||||||
@@ -245,12 +245,12 @@ namespace DynamORM.Tests.Modify
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestUpdateByDynamicObjects()
|
public void TestUpdateByDynamicObjects()
|
||||||
{
|
{
|
||||||
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 }));
|
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
|
// Verify
|
||||||
var o = GetTestTable().Single(code: 205);
|
var o = GetTestTable().Single(code: "205");
|
||||||
Assert.AreEqual(5, o.id);
|
Assert.AreEqual(5, o.id);
|
||||||
Assert.AreEqual("205", o.code);
|
Assert.AreEqual("205", o.code.ToString());
|
||||||
Assert.AreEqual(null, o.first);
|
Assert.AreEqual(null, o.first);
|
||||||
Assert.AreEqual("Gagarin", o.last);
|
Assert.AreEqual("Gagarin", o.last);
|
||||||
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
||||||
@@ -275,9 +275,9 @@ namespace DynamORM.Tests.Modify
|
|||||||
}, id: 6));
|
}, id: 6));
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
var o = u.Single(code: 206);
|
var o = u.Single(code: "206");
|
||||||
Assert.AreEqual(6, o.id);
|
Assert.AreEqual(6, o.id);
|
||||||
Assert.AreEqual("206", o.code);
|
Assert.AreEqual("206", o.code.ToString());
|
||||||
Assert.AreEqual(null, o.first);
|
Assert.AreEqual(null, o.first);
|
||||||
Assert.AreEqual("Gagarin", o.last);
|
Assert.AreEqual("Gagarin", o.last);
|
||||||
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
||||||
@@ -302,9 +302,9 @@ namespace DynamORM.Tests.Modify
|
|||||||
}, id: 7));
|
}, id: 7));
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
var o = u.Single(code: 207);
|
var o = u.Single(code: "207");
|
||||||
Assert.AreEqual(7, o.id);
|
Assert.AreEqual(7, o.id);
|
||||||
Assert.AreEqual("207", o.code);
|
Assert.AreEqual("207", o.code.ToString());
|
||||||
Assert.AreEqual(null, o.first);
|
Assert.AreEqual(null, o.first);
|
||||||
Assert.AreEqual("Gagarin", o.last);
|
Assert.AreEqual("Gagarin", o.last);
|
||||||
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
Assert.AreEqual("juri.gagarin@megacorp.com", o.email);
|
||||||
@@ -320,10 +320,10 @@ namespace DynamORM.Tests.Modify
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestDeleteByArguments()
|
public void TestDeleteByArguments()
|
||||||
{
|
{
|
||||||
Assert.AreEqual(1, GetTestTable().Delete(code: 10));
|
Assert.AreEqual(1, GetTestTable().Delete(code: "10"));
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
Assert.AreEqual(0, GetTestTable().Count(code: 10));
|
Assert.AreEqual(0, GetTestTable().Count(code: "10"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Test row deleting by dynamic objects (all except ID should be ignored).</summary>
|
/// <summary>Test row deleting by dynamic objects (all except ID should be ignored).</summary>
|
||||||
@@ -380,7 +380,7 @@ namespace DynamORM.Tests.Modify
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestDeleteyDynamicObjectWhere()
|
public void TestDeleteyDynamicObjectWhere()
|
||||||
{
|
{
|
||||||
Assert.AreEqual(1, GetTestTable().Delete(where: new { id = 14, code = 14 }));
|
Assert.AreEqual(1, GetTestTable().Delete(where: new { id = 14, code = "14" }));
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
Assert.AreEqual(0, GetTestTable().Count(id: 14));
|
Assert.AreEqual(0, GetTestTable().Count(id: 14));
|
||||||
|
|||||||
72
DynamORM.Tests/Modify/ParserTests.cs
Normal file
72
DynamORM.Tests/Modify/ParserTests.cs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* 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.Linq;
|
||||||
|
using DynamORM.Builders.Implementation;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace DynamORM.Tests.Modify
|
||||||
|
{
|
||||||
|
/// <summary>New parser tests.</summary>
|
||||||
|
[TestFixture]
|
||||||
|
public class ParserTests : TestsBase
|
||||||
|
{
|
||||||
|
/// <summary>Setup test parameters.</summary>
|
||||||
|
[TestFixtureSetUp]
|
||||||
|
public virtual void SetUp()
|
||||||
|
{
|
||||||
|
CreateTestDatabase();
|
||||||
|
CreateDynamicDatabase(
|
||||||
|
DynamicDatabaseOptions.SingleConnection |
|
||||||
|
DynamicDatabaseOptions.SingleTransaction |
|
||||||
|
DynamicDatabaseOptions.SupportLimitOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Tear down test objects.</summary>
|
||||||
|
[TestFixtureTearDown]
|
||||||
|
public virtual void TearDown()
|
||||||
|
{
|
||||||
|
DestroyDynamicDatabase();
|
||||||
|
DestroyTestDatabase();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the basic insert.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestBasicInsert()
|
||||||
|
{
|
||||||
|
var cmd = new DynamicInsertQueryBuilder(Database, "Users");
|
||||||
|
|
||||||
|
cmd.Insert(x => x.Users.Code = "001", x => x.Users.Name = "Admin", x => x.Users.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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using DynamORM.Builders;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace DynamORM.Tests.Select
|
namespace DynamORM.Tests.Select
|
||||||
@@ -60,6 +61,13 @@ namespace DynamORM.Tests.Select
|
|||||||
return Database.Table("users");
|
return Database.Table("users");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Create table using specified method.</summary>
|
||||||
|
/// <returns>Dynamic table.</returns>
|
||||||
|
public virtual IDynamicSelectQueryBuilder GetTestBuilder()
|
||||||
|
{
|
||||||
|
return Database.Table("users").Query() as IDynamicSelectQueryBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
#region Select
|
#region Select
|
||||||
|
|
||||||
/// <summary>Test unknown op.</summary>
|
/// <summary>Test unknown op.</summary>
|
||||||
@@ -76,7 +84,14 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(200, GetTestTable().Count(columns: "id"));
|
Assert.AreEqual(200, GetTestTable().Count(columns: "id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Test count with in steatement.</summary>
|
/// <summary>Test dynamic <c>Count</c> method.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestCount2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(200, GetTestBuilder().Select(x => x.Count(x.id)).Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Test count with in statement.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestSelectInEnumerableCount()
|
public void TestSelectInEnumerableCount()
|
||||||
{
|
{
|
||||||
@@ -87,7 +102,17 @@ namespace DynamORM.Tests.Select
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Test count with in steatement.</summary>
|
/// <summary>Test count with in statement.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSelectInEnumerableCount2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(4, GetTestBuilder()
|
||||||
|
.Where(x => x.last.In(new object[] { "Hendricks", "Goodwin", "Freeman" }.Take(3)))
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Test count with in statement.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestSelectInArrayCount()
|
public void TestSelectInArrayCount()
|
||||||
{
|
{
|
||||||
@@ -98,6 +123,16 @@ namespace DynamORM.Tests.Select
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test count with in statement.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSelectInArrayCount2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(4, GetTestBuilder()
|
||||||
|
.Where(x => x.last.In(new object[] { "Hendricks", "Goodwin", "Freeman" }))
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test dynamic <c>First</c> method.</summary>
|
/// <summary>Test dynamic <c>First</c> method.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestFirst()
|
public void TestFirst()
|
||||||
@@ -105,6 +140,16 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(1, GetTestTable().First(columns: "id").id);
|
Assert.AreEqual(1, GetTestTable().First(columns: "id").id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic <c>First</c> method.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestFirst2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(1, GetTestBuilder()
|
||||||
|
.Select(x => x.id)
|
||||||
|
.Execute()
|
||||||
|
.First().id);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test dynamic <c>Last</c> method.</summary>
|
/// <summary>Test dynamic <c>Last</c> method.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestLast()
|
public void TestLast()
|
||||||
@@ -112,6 +157,16 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(200, GetTestTable().Last(columns: "id").id);
|
Assert.AreEqual(200, GetTestTable().Last(columns: "id").id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic <c>Last</c> method.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestLast2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(200, GetTestBuilder()
|
||||||
|
.Select(x => x.id)
|
||||||
|
.Execute()
|
||||||
|
.Last().id);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test dynamic <c>Count</c> method.</summary>
|
/// <summary>Test dynamic <c>Count</c> method.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestCountSpecificRecord()
|
public void TestCountSpecificRecord()
|
||||||
@@ -119,6 +174,16 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(1, GetTestTable().Count(first: "Ori"));
|
Assert.AreEqual(1, GetTestTable().Count(first: "Ori"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic <c>Count</c> method.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestCountSpecificRecord2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(1, GetTestBuilder()
|
||||||
|
.Where(x => x.first == "Ori")
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test dynamic <c>Min</c> method.</summary>
|
/// <summary>Test dynamic <c>Min</c> method.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestMin()
|
public void TestMin()
|
||||||
@@ -126,6 +191,15 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(1, GetTestTable().Min(columns: "id"));
|
Assert.AreEqual(1, GetTestTable().Min(columns: "id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic <c>Min</c> method.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestMin2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(1, GetTestBuilder()
|
||||||
|
.Select(x => x.Min(x.id))
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test dynamic <c>Min</c> method.</summary>
|
/// <summary>Test dynamic <c>Min</c> method.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestMax()
|
public void TestMax()
|
||||||
@@ -133,6 +207,15 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(200, GetTestTable().Max(columns: "id"));
|
Assert.AreEqual(200, GetTestTable().Max(columns: "id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic <c>Min</c> method.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestMax2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(200, GetTestBuilder()
|
||||||
|
.Select(x => x.Max(x.id))
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test dynamic <c>Min</c> method.</summary>
|
/// <summary>Test dynamic <c>Min</c> method.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TesttAvg()
|
public void TesttAvg()
|
||||||
@@ -140,6 +223,15 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(100.5, GetTestTable().Avg(columns: "id"));
|
Assert.AreEqual(100.5, GetTestTable().Avg(columns: "id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic <c>Min</c> method.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TesttAvg2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(100.5, GetTestBuilder()
|
||||||
|
.Select(x => x.Avg(x.id))
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test dynamic <c>Sum</c> method.</summary>
|
/// <summary>Test dynamic <c>Sum</c> method.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestSum()
|
public void TestSum()
|
||||||
@@ -147,6 +239,15 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(20100, GetTestTable().Sum(columns: "id"));
|
Assert.AreEqual(20100, GetTestTable().Sum(columns: "id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic <c>Sum</c> method.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSum2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(20100, GetTestBuilder()
|
||||||
|
.Select(x => x.Sum(x.id))
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test dynamic <c>Scalar</c> method for invalid operation exception.</summary>
|
/// <summary>Test dynamic <c>Scalar</c> method for invalid operation exception.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestScalarException()
|
public void TestScalarException()
|
||||||
@@ -161,6 +262,16 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual("Ori", GetTestTable().Scalar(columns: "first", id: 19));
|
Assert.AreEqual("Ori", GetTestTable().Scalar(columns: "first", id: 19));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic <c>Scalar</c> method.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestScalar2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual("Ori", GetTestBuilder()
|
||||||
|
.Where(x => x.id == 19)
|
||||||
|
.Select(x => x.first)
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test dynamic <c>Scalar</c> method with SQLite specific aggregate.</summary>
|
/// <summary>Test dynamic <c>Scalar</c> method with SQLite specific aggregate.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestScalarGroupConcat()
|
public void TestScalarGroupConcat()
|
||||||
@@ -171,6 +282,19 @@ namespace DynamORM.Tests.Select
|
|||||||
GetTestTable().Scalar(columns: "first:first:group_concat", id: new DynamicColumn { Operator = DynamicColumn.CompareOperator.Lt, Value = 20 }));
|
GetTestTable().Scalar(columns: "first:first:group_concat", id: new DynamicColumn { Operator = DynamicColumn.CompareOperator.Lt, Value = 20 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic <c>Scalar</c> method with SQLite specific aggregate.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestScalarGroupConcat2()
|
||||||
|
{
|
||||||
|
// This test should produce something like this:
|
||||||
|
// select group_concat("first") AS first from "users" where "id" < 20;
|
||||||
|
Assert.AreEqual("Clarke,Marny,Dai,Forrest,Blossom,George,Ivory,Inez,Sigourney,Fulton,Logan,Anne,Alexandra,Adena,Lionel,Aimee,Selma,Lara,Ori",
|
||||||
|
GetTestBuilder()
|
||||||
|
.Where(x => x.id < 20)
|
||||||
|
.Select(x => x.group_concat(x.first).As(x.first))
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test dynamic <c>Scalar</c> method with SQLite specific aggregate not using aggregate field.</summary>
|
/// <summary>Test dynamic <c>Scalar</c> method with SQLite specific aggregate not using aggregate field.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestScalarGroupConcatNoAggregateField()
|
public void TestScalarGroupConcatNoAggregateField()
|
||||||
@@ -181,6 +305,19 @@ namespace DynamORM.Tests.Select
|
|||||||
GetTestTable().Scalar(columns: "group_concat(first):first", id: new DynamicColumn { Operator = DynamicColumn.CompareOperator.Lt, Value = 20 }));
|
GetTestTable().Scalar(columns: "group_concat(first):first", id: new DynamicColumn { Operator = DynamicColumn.CompareOperator.Lt, Value = 20 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic <c>Scalar</c> method with SQLite specific aggregate not using aggregate field.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestScalarGroupConcatNoAggregateField2()
|
||||||
|
{
|
||||||
|
// This test should produce something like this:
|
||||||
|
// select group_concat(first) AS first from "users" where "id" < 20;
|
||||||
|
Assert.AreEqual("Clarke,Marny,Dai,Forrest,Blossom,George,Ivory,Inez,Sigourney,Fulton,Logan,Anne,Alexandra,Adena,Lionel,Aimee,Selma,Lara,Ori",
|
||||||
|
GetTestBuilder()
|
||||||
|
.Where(x => x.id < 20)
|
||||||
|
.Select("group_concat(first):first")
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test something fancy... like: <code>select "first", count("first") occurs from "users" group by "first" order by 2 desc;</code>.</summary>
|
/// <summary>Test something fancy... like: <code>select "first", count("first") occurs from "users" group by "first" order by 2 desc;</code>.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestFancyAggregateQuery()
|
public void TestFancyAggregateQuery()
|
||||||
@@ -196,6 +333,26 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(1, v.Last().occurs);
|
Assert.AreEqual(1, v.Last().occurs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test something fancy... like: <code>select "first", count("first") occurs from "users" group by "first" order by 2 desc;</code>.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestFancyAggregateQuery2()
|
||||||
|
{
|
||||||
|
var v = GetTestBuilder()
|
||||||
|
.Select(x => x.first, x => x.Count(x.first).As(x.occurs))
|
||||||
|
.GroupBy(x => x.first)
|
||||||
|
.OrderBy(x => x.Desc(2))
|
||||||
|
.Execute()
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
Assert.IsNotNull(v);
|
||||||
|
Assert.AreEqual(187, v.Count());
|
||||||
|
Assert.AreEqual(4, v.First().occurs);
|
||||||
|
Assert.AreEqual("Logan", v.First().first);
|
||||||
|
Assert.AreEqual(2, v.Take(10).Last().occurs);
|
||||||
|
Assert.AreEqual(1, v.Take(11).Last().occurs);
|
||||||
|
Assert.AreEqual(1, v.Last().occurs);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>This time also something fancy... aggregate in aggregate <code>select AVG(LENGTH("login")) len from "users";</code>.</summary>
|
/// <summary>This time also something fancy... aggregate in aggregate <code>select AVG(LENGTH("login")) len from "users";</code>.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestAggregateInAggregate()
|
public void TestAggregateInAggregate()
|
||||||
@@ -203,6 +360,15 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(12.77, GetTestTable().Scalar(columns: @"length(""login""):len:avg"));
|
Assert.AreEqual(12.77, GetTestTable().Scalar(columns: @"length(""login""):len:avg"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>This time also something fancy... aggregate in aggregate <code>select AVG(LENGTH("login")) len from "users";</code>.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestAggregateInAggregate2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(12.77, GetTestBuilder()
|
||||||
|
.Select(x => x.Avg(x.Length(x.login)).As(x.len))
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>This time also something fancy... aggregate in aggregate <code>select AVG(LENGTH("email")) len from "users";</code>.</summary>
|
/// <summary>This time also something fancy... aggregate in aggregate <code>select AVG(LENGTH("email")) len from "users";</code>.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestAggregateInAggregateMark2()
|
public void TestAggregateInAggregateMark2()
|
||||||
@@ -210,6 +376,15 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(27.7, GetTestTable().Avg(columns: @"length(""email""):len"));
|
Assert.AreEqual(27.7, GetTestTable().Avg(columns: @"length(""email""):len"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>This time also something fancy... aggregate in aggregate <code>select AVG(LENGTH("email")) len from "users";</code>.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestAggregateInAggregateMark3()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(27.7, GetTestBuilder()
|
||||||
|
.Select(x => "AVG(LENGTH(email)) AS LEN")
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test emails longer than 27 chars. <code>select count(*) from "users" where length("email") > 27;</code>.</summary>
|
/// <summary>Test emails longer than 27 chars. <code>select count(*) from "users" where length("email") > 27;</code>.</summary>
|
||||||
public void TestFunctionInWhere()
|
public void TestFunctionInWhere()
|
||||||
{
|
{
|
||||||
@@ -224,6 +399,15 @@ namespace DynamORM.Tests.Select
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test emails longer than 27 chars. <code>select count(*) from "users" where length("email") > 27;</code>.</summary>
|
||||||
|
public void TestFunctionInWhere2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(97, GetTestBuilder()
|
||||||
|
.Where(x => x.Length(x.email) > 27)
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test dynamic <c>Single</c> multi.</summary>
|
/// <summary>Test dynamic <c>Single</c> multi.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestSingleObject()
|
public void TestSingleObject()
|
||||||
@@ -236,6 +420,22 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(exp.last, o.last);
|
Assert.AreEqual(exp.last, o.last);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic <c>Single</c> multi.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSingleObject2()
|
||||||
|
{
|
||||||
|
var exp = new { id = 19, first = "Ori", last = "Ellis" };
|
||||||
|
var o = GetTestBuilder()
|
||||||
|
.Where(x => x.id == 19)
|
||||||
|
.Select(x => new { id = x.id, first = x.first, last = x.last })
|
||||||
|
.Execute()
|
||||||
|
.First();
|
||||||
|
|
||||||
|
Assert.AreEqual(exp.id, o.id);
|
||||||
|
Assert.AreEqual(exp.first, o.first);
|
||||||
|
Assert.AreEqual(exp.last, o.last);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion Select
|
#endregion Select
|
||||||
|
|
||||||
#region Where
|
#region Where
|
||||||
@@ -247,6 +447,14 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual("hoyt.tran", GetTestTable().Single(where: new DynamicColumn("id").Eq(100)).login);
|
Assert.AreEqual("hoyt.tran", GetTestTable().Single(where: new DynamicColumn("id").Eq(100)).login);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic where expression equal.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereEq2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual("hoyt.tran", GetTestBuilder()
|
||||||
|
.Where(x => x.id == 100).Execute().First().login);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test dynamic where expression not equal.</summary>
|
/// <summary>Test dynamic where expression not equal.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestWhereNot()
|
public void TestWhereNot()
|
||||||
@@ -254,6 +462,16 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(199, GetTestTable().Count(where: new DynamicColumn("id").Not(100)));
|
Assert.AreEqual(199, GetTestTable().Count(where: new DynamicColumn("id").Not(100)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic where expression not equal.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereNot2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(199, GetTestBuilder()
|
||||||
|
.Where(x => x.id != 100)
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test dynamic where expression like.</summary>
|
/// <summary>Test dynamic where expression like.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestWhereLike()
|
public void TestWhereLike()
|
||||||
@@ -261,6 +479,14 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(100, GetTestTable().Single(where: new DynamicColumn("login").Like("Hoyt.%")).id);
|
Assert.AreEqual(100, GetTestTable().Single(where: new DynamicColumn("login").Like("Hoyt.%")).id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic where expression like.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereLike2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(100, GetTestBuilder()
|
||||||
|
.Where(x => x.login.Like("Hoyt.%")).Execute().First().id);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test dynamic where expression not like.</summary>
|
/// <summary>Test dynamic where expression not like.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestWhereNotLike()
|
public void TestWhereNotLike()
|
||||||
@@ -268,6 +494,26 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(199, GetTestTable().Count(where: new DynamicColumn("login").NotLike("Hoyt.%")));
|
Assert.AreEqual(199, GetTestTable().Count(where: new DynamicColumn("login").NotLike("Hoyt.%")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic where expression not like.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereNotLike2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(199, GetTestBuilder()
|
||||||
|
.Where(x => x.login.NotLike("Hoyt.%"))
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic where expression not like.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereNotLike3()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(199, GetTestBuilder()
|
||||||
|
.Where(x => !x.login.Like("Hoyt.%"))
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test dynamic where expression greater.</summary>
|
/// <summary>Test dynamic where expression greater.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestWhereGt()
|
public void TestWhereGt()
|
||||||
@@ -275,6 +521,16 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(100, GetTestTable().Count(where: new DynamicColumn("id").Greater(100)));
|
Assert.AreEqual(100, GetTestTable().Count(where: new DynamicColumn("id").Greater(100)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic where expression greater.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereGt2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(100, GetTestBuilder()
|
||||||
|
.Where(x => x.id > 100)
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test dynamic where expression greater or equal.</summary>
|
/// <summary>Test dynamic where expression greater or equal.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestWhereGte()
|
public void TestWhereGte()
|
||||||
@@ -282,6 +538,16 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(101, GetTestTable().Count(where: new DynamicColumn("id").GreaterOrEqual(100)));
|
Assert.AreEqual(101, GetTestTable().Count(where: new DynamicColumn("id").GreaterOrEqual(100)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic where expression greater or equal.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereGte2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(101, GetTestBuilder()
|
||||||
|
.Where(x => x.id >= 100)
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test dynamic where expression less.</summary>
|
/// <summary>Test dynamic where expression less.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestWhereLt()
|
public void TestWhereLt()
|
||||||
@@ -289,6 +555,16 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(99, GetTestTable().Count(where: new DynamicColumn("id").Less(100)));
|
Assert.AreEqual(99, GetTestTable().Count(where: new DynamicColumn("id").Less(100)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic where expression less.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereLt2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(99, GetTestBuilder()
|
||||||
|
.Where(x => x.id < 100)
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test dynamic where expression less or equal.</summary>
|
/// <summary>Test dynamic where expression less or equal.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestWhereLte()
|
public void TestWhereLte()
|
||||||
@@ -296,6 +572,16 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(100, GetTestTable().Count(where: new DynamicColumn("id").LessOrEqual(100)));
|
Assert.AreEqual(100, GetTestTable().Count(where: new DynamicColumn("id").LessOrEqual(100)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic where expression less or equal.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereLte2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(100, GetTestBuilder()
|
||||||
|
.Where(x => x.id <= 100)
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test dynamic where expression between.</summary>
|
/// <summary>Test dynamic where expression between.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestWhereBetween()
|
public void TestWhereBetween()
|
||||||
@@ -303,7 +589,17 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(26, GetTestTable().Count(where: new DynamicColumn("id").Between(75, 100)));
|
Assert.AreEqual(26, GetTestTable().Count(where: new DynamicColumn("id").Between(75, 100)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Test dynamic where expression in params.</summary>
|
/// <summary>Test dynamic where expression between.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereBetween2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(26, GetTestBuilder()
|
||||||
|
.Where(x => x.id.Between(75, 100))
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic where expression in parameters.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestWhereIn1()
|
public void TestWhereIn1()
|
||||||
{
|
{
|
||||||
@@ -317,6 +613,26 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(3, GetTestTable().Count(where: new DynamicColumn("id").In(new[] { 75, 99, 100 })));
|
Assert.AreEqual(3, GetTestTable().Count(where: new DynamicColumn("id").In(new[] { 75, 99, 100 })));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic where expression in parameters.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereIn3()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(3, GetTestBuilder()
|
||||||
|
.Where(x => x.id.In(75, 99, 100))
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Test dynamic where expression in parameters.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereIn4()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(3, GetTestBuilder()
|
||||||
|
.Where(x => x.id.In(new[] { 75, 99, 100 }))
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
#endregion Where
|
#endregion Where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
284
DynamORM.Tests/Select/LegacyParserTests.cs
Normal file
284
DynamORM.Tests/Select/LegacyParserTests.cs
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
/*
|
||||||
|
* 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.Linq;
|
||||||
|
using DynamORM.Builders;
|
||||||
|
using DynamORM.Builders.Implementation;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace DynamORM.Tests.Select
|
||||||
|
{
|
||||||
|
/// <summary>Tests of legacy parser methods.</summary>
|
||||||
|
public class LegacyParserTests : TestsBase
|
||||||
|
{
|
||||||
|
/// <summary>Setup test parameters.</summary>
|
||||||
|
[TestFixtureSetUp]
|
||||||
|
public virtual void SetUp()
|
||||||
|
{
|
||||||
|
CreateTestDatabase();
|
||||||
|
CreateDynamicDatabase(
|
||||||
|
DynamicDatabaseOptions.SingleConnection |
|
||||||
|
DynamicDatabaseOptions.SingleTransaction |
|
||||||
|
DynamicDatabaseOptions.SupportLimitOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Tear down test objects.</summary>
|
||||||
|
[TestFixtureTearDown]
|
||||||
|
public virtual void TearDown()
|
||||||
|
{
|
||||||
|
DestroyDynamicDatabase();
|
||||||
|
DestroyTestDatabase();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the where expression equal.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereEq()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(x => x.dbo.Users.As(x.u))
|
||||||
|
.Where(new DynamicColumn("u.Deleted").Eq(0));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS u WHERE (u.\"Deleted\" = [${0}])", cmd.Parameters.Keys.First()), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the where expression equal with brackets.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereBracketsEq()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(x => x.dbo.Users.As(x.u))
|
||||||
|
.Where(new DynamicColumn("u.Deleted").Eq(0).SetBeginBlock())
|
||||||
|
.Where(new DynamicColumn("u.IsActive").Eq(1).SetEndBlock());
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS u WHERE ((u.\"Deleted\" = [${0}]) AND (u.\"IsActive\" = [${1}]))", cmd.Parameters.Keys.First(), cmd.Parameters.Keys.Last()), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the where expression equal with brackets and or condition.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereBracketsOrEq()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(x => x.dbo.Users.As(x.u))
|
||||||
|
.Where(new DynamicColumn("u.Deleted").Eq(0).SetBeginBlock())
|
||||||
|
.Where(new DynamicColumn("u.IsActive").Eq(1).SetOr().SetEndBlock());
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS u WHERE ((u.\"Deleted\" = [${0}]) OR (u.\"IsActive\" = [${1}]))", cmd.Parameters.Keys.First(), cmd.Parameters.Keys.Last()), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the where expression not equal.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereNotEq()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(x => x.dbo.Users.As(x.u))
|
||||||
|
.Where(new DynamicColumn("u.Deleted").Not(0));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS u WHERE (u.\"Deleted\" <> [${0}])", cmd.Parameters.Keys.First()), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the where expression greater.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereGreater()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(x => x.dbo.Users.As(x.u))
|
||||||
|
.Where(new DynamicColumn("u.Deleted").Greater(0));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS u WHERE (u.\"Deleted\" > [${0}])", cmd.Parameters.Keys.First()), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the where expression greater or equal.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereGreaterOrEqual()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(x => x.dbo.Users.As(x.u))
|
||||||
|
.Where(new DynamicColumn("u.Deleted").GreaterOrEqual(0));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS u WHERE (u.\"Deleted\" >= [${0}])", cmd.Parameters.Keys.First()), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the where expression less.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereLess()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(x => x.dbo.Users.As(x.u))
|
||||||
|
.Where(new DynamicColumn("u.Deleted").Less(1));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS u WHERE (u.\"Deleted\" < [${0}])", cmd.Parameters.Keys.First()), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the where expression less or equal.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereLessOrEqual()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(x => x.dbo.Users.As(x.u))
|
||||||
|
.Where(new DynamicColumn("u.Deleted").LessOrEqual(1));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS u WHERE (u.\"Deleted\" <= [${0}])", cmd.Parameters.Keys.First()), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the where expression like.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereLike()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(x => x.dbo.Users.As(x.u))
|
||||||
|
.Where(new DynamicColumn("u.Deleted").Like("%1"));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS u WHERE u.\"Deleted\" LIKE [${0}]", cmd.Parameters.Keys.First()), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the where expression not like.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereNotLike()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(x => x.dbo.Users.As(x.u))
|
||||||
|
.Where(new DynamicColumn("u.Deleted").NotLike("%1"));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS u WHERE u.\"Deleted\" NOT LIKE [${0}]", cmd.Parameters.Keys.First()), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the where expression between.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereBetween()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(x => x.dbo.Users.As(x.u))
|
||||||
|
.Where(new DynamicColumn("u.Deleted").Between(0, 1));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS u WHERE u.\"Deleted\" BETWEEN [${0}] AND [${1}]", cmd.Parameters.Keys.First(), cmd.Parameters.Keys.Last()), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the where expression in.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereIn()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(x => x.dbo.Users.As(x.u))
|
||||||
|
.Where(new DynamicColumn("u.Deleted").In(0, 1));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS u WHERE u.\"Deleted\" IN([${0}], [${1}])", cmd.Parameters.Keys.First(), cmd.Parameters.Keys.Last()), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the where expression using anonymous types.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereAnon()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(x => x.dbo.Users.As(x.u))
|
||||||
|
.Where(new { Deleted = 0, IsActive = 1, _table = "u" });
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS u WHERE (u.\"Deleted\" = [${0}]) AND (u.\"IsActive\" = [${1}])", cmd.Parameters.Keys.First(), cmd.Parameters.Keys.Last()), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the order by column.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestOrderByCol()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(x => x.dbo.Users.As(x.u))
|
||||||
|
.OrderBy(new DynamicColumn("u.Name").Desc());
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS u ORDER BY u.\"Name\" DESC"), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the order by column number.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestOrderByNum()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(x => x.dbo.Users.As(x.u))
|
||||||
|
.OrderBy(new DynamicColumn("u.Name").SetAlias("1").Desc());
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS u ORDER BY 1 DESC"), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the group by column.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestGroupByCol()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(x => x.dbo.Users.As(x.u))
|
||||||
|
.GroupBy(new DynamicColumn("u.Name"));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS u GROUP BY u.\"Name\""), cmd.CommandText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
731
DynamORM.Tests/Select/ParserTests.cs
Normal file
731
DynamORM.Tests/Select/ParserTests.cs
Normal file
@@ -0,0 +1,731 @@
|
|||||||
|
/*
|
||||||
|
* 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.Linq;
|
||||||
|
using DynamORM.Builders;
|
||||||
|
using DynamORM.Builders.Implementation;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace DynamORM.Tests.Select
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// New parser tests.
|
||||||
|
/// </summary>
|
||||||
|
public class ParserTests : TestsBase
|
||||||
|
{
|
||||||
|
/// <summary>Setup test parameters.</summary>
|
||||||
|
[TestFixtureSetUp]
|
||||||
|
public virtual void SetUp()
|
||||||
|
{
|
||||||
|
CreateTestDatabase();
|
||||||
|
CreateDynamicDatabase(
|
||||||
|
DynamicDatabaseOptions.SingleConnection |
|
||||||
|
DynamicDatabaseOptions.SingleTransaction |
|
||||||
|
DynamicDatabaseOptions.SupportLimitOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Tear down test objects.</summary>
|
||||||
|
[TestFixtureTearDown]
|
||||||
|
public virtual void TearDown()
|
||||||
|
{
|
||||||
|
DestroyDynamicDatabase();
|
||||||
|
DestroyTestDatabase();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests from method.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestFromGet()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users);
|
||||||
|
Assert.AreEqual("SELECT * FROM \"dbo\".\"Users\"", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests from method with multi tables.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestFromGetMultiKulti()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users, c => c.Clients);
|
||||||
|
Assert.AreEqual("SELECT * FROM \"dbo\".\"Users\", \"Clients\"", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests from method with as expression in text.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestFromGetAs1()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As("c"));
|
||||||
|
Assert.AreEqual("SELECT * FROM \"dbo\".\"Users\" AS c", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests from method with as expression using lambda.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestFromGetAs2()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c));
|
||||||
|
Assert.AreEqual("SELECT * FROM \"dbo\".\"Users\" AS c", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests from method using text.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestFromText()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => "dbo.Users");
|
||||||
|
Assert.AreEqual("SELECT * FROM \"dbo\".\"Users\"", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests from method using text with decorators.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestFromDecoratedText()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => "\"dbo\".\"Users\"");
|
||||||
|
Assert.AreEqual("SELECT * FROM \"dbo\".\"Users\"", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests from method using text with as.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestFromTextAs1()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => "dbo.Users AS c");
|
||||||
|
Assert.AreEqual("SELECT * FROM \"dbo\".\"Users\" AS c", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests from method using invoke with as.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestFromTextAs2()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u(u.dbo.Users).As(u.u));
|
||||||
|
|
||||||
|
Assert.AreEqual("SELECT * FROM \"dbo\".\"Users\" AS u", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests from method using invoke with sub query.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestFromSubQuery1()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u(new DynamicSelectQueryBuilder(Database).From(x => x.dbo.Users)).As("u"));
|
||||||
|
|
||||||
|
Assert.AreEqual("SELECT * FROM (SELECT * FROM \"dbo\".\"Users\") AS u", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests from method using invoke with sub query.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestFromSubQuery2()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u(cmd.SubQuery(x => x.dbo.Users)).As("u"));
|
||||||
|
|
||||||
|
Assert.AreEqual("SELECT * FROM (SELECT * FROM \"dbo\".\"Users\") AS u", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests where method with alias.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereAlias()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.Where(u => u.c.UserName == "admin");
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS c WHERE (c.\"UserName\" = [${0}])", cmd.Parameters.Keys.First()), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests complex where method with alias.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereAliasComplex()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.Where(u => u.c.UserName == "admin" || u.c.UserName == "root")
|
||||||
|
.Where(u => u.c.IsActive = true);
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS c WHERE ((c.\"UserName\" = [${0}]) OR (c.\"UserName\" = [${1}])) AND c.\"IsActive\" = ([${2}])",
|
||||||
|
cmd.Parameters.Keys.ToArray()[0], cmd.Parameters.Keys.ToArray()[1], cmd.Parameters.Keys.ToArray()[2]), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests where method with alias using in.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereAliasIn()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
int[] ids = new int[] { 0, 1, 2, 3, 4, 5 };
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.Where(u => u.c.UserName == "admin" || u.c.UserName == "root")
|
||||||
|
.Where(u => u.c.IsActive == true)
|
||||||
|
.Where(u => u.c.Id_User.In(ids));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS c WHERE ((c.\"UserName\" = [${0}]) OR (c.\"UserName\" = [${1}])) AND (c.\"IsActive\" = [${2}]) AND c.\"Id_User\" IN({3})",
|
||||||
|
cmd.Parameters.Keys.ToArray()[0], cmd.Parameters.Keys.ToArray()[1], cmd.Parameters.Keys.ToArray()[2],
|
||||||
|
string.Join(", ", cmd.Parameters.Keys.Skip(3).Select(p => string.Format("[${0}]", p)))), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests where method with alias using between.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereAliasBetween1()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
int[] ids = new int[] { 0, 5 };
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.Where(u => u.c.UserName == "admin" || u.c.UserName == "root")
|
||||||
|
.Where(u => u.c.IsActive == true)
|
||||||
|
.Where(u => u.c.Id_User.Between(ids));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS c WHERE ((c.\"UserName\" = [${0}]) OR (c.\"UserName\" = [${1}])) AND (c.\"IsActive\" = [${2}]) AND c.\"Id_User\" BETWEEN [${3}] AND [${4}]",
|
||||||
|
cmd.Parameters.Keys.ToArray()[0], cmd.Parameters.Keys.ToArray()[1], cmd.Parameters.Keys.ToArray()[2],
|
||||||
|
cmd.Parameters.Keys.ToArray()[3], cmd.Parameters.Keys.ToArray()[4]), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests where method with alias using between.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereAliasBetween2()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
int[] ids = new int[] { 0, 5 };
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.Where(u => u.c.UserName == "admin" || u.c.UserName == "root")
|
||||||
|
.Where(u => u.c.IsActive == true)
|
||||||
|
.Where(u => u.c.Id_User.Between(ids[0], ids[1]));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS c WHERE ((c.\"UserName\" = [${0}]) OR (c.\"UserName\" = [${1}])) AND (c.\"IsActive\" = [${2}]) AND c.\"Id_User\" BETWEEN [${3}] AND [${4}]",
|
||||||
|
cmd.Parameters.Keys.ToArray()[0], cmd.Parameters.Keys.ToArray()[1], cmd.Parameters.Keys.ToArray()[2],
|
||||||
|
cmd.Parameters.Keys.ToArray()[3], cmd.Parameters.Keys.ToArray()[4]), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests where method without alias.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereNoAlias()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users)
|
||||||
|
.Where(u => u.UserName == "admin");
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" WHERE (\"UserName\" = [${0}])", cmd.Parameters.Keys.First()), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests where method with full column name.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestWhereNoAliasTableName()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users)
|
||||||
|
.Where(u => u.dbo.Users.UserName == "admin");
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" WHERE (\"dbo\".\"Users\".\"UserName\" = [${0}])", cmd.Parameters.Keys.First()), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests simple join method.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestJoinClassic()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.usr))
|
||||||
|
.Join(u => u.dbo.UserClients.AS(u.uc).On(u.usr.Id_User == u.uc.User_Id));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS usr JOIN \"dbo\".\"UserClients\" AS uc ON (usr.\"Id_User\" = uc.\"User_Id\")"), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests inner join method.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestInnerJoin()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.usr))
|
||||||
|
.Join(u => u.Inner().dbo.UserClients.AS(u.uc).On(u.usr.Id_User == u.uc.User_Id));
|
||||||
|
|
||||||
|
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 left outer join method.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestLeftOuterJoin()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.usr))
|
||||||
|
.Join(u => u.LeftOuter().dbo.UserClients.AS(u.uc).On(u.usr.Id_User == u.uc.User_Id));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS usr LEFT OUTER JOIN \"dbo\".\"UserClients\" AS uc ON (usr.\"Id_User\" = uc.\"User_Id\")"), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests left join method.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestLeftJoin()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.usr))
|
||||||
|
.Join(u => u.Left().dbo.UserClients.AS(u.uc).On(u.usr.Id_User == u.uc.User_Id));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS usr LEFT JOIN \"dbo\".\"UserClients\" AS uc ON (usr.\"Id_User\" = uc.\"User_Id\")"), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests right outer join method.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestRightOuterJoin()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.usr))
|
||||||
|
.Join(u => u.RightOuter().dbo.UserClients.AS(u.uc).On(u.usr.Id_User == u.uc.User_Id));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS usr RIGHT OUTER JOIN \"dbo\".\"UserClients\" AS uc ON (usr.\"Id_User\" = uc.\"User_Id\")"), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests right join method.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestRightJoin()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.usr))
|
||||||
|
.Join(u => u.Right().dbo.UserClients.AS(u.uc).On(u.usr.Id_User == u.uc.User_Id));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS usr RIGHT JOIN \"dbo\".\"UserClients\" AS uc ON (usr.\"Id_User\" = uc.\"User_Id\")"), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests complex join with parameters.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestJoinClassicWithParamAndWhere()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.usr))
|
||||||
|
.Join(u => u.dbo.UserClients.AS(u.uc).On(u.usr.Id_User == u.uc.User_Id && u.uc.Deleted == 0))
|
||||||
|
.Where(u => u.usr.Active == true);
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS usr JOIN \"dbo\".\"UserClients\" AS uc ON ((usr.\"Id_User\" = uc.\"User_Id\") AND (uc.\"Deleted\" = [${0}])) WHERE (usr.\"Active\" = [${1}])",
|
||||||
|
cmd.Parameters.Keys.First(), cmd.Parameters.Keys.Last()), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests select all.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSelectAll1()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.Select(u => u.c.All());
|
||||||
|
|
||||||
|
Assert.AreEqual("SELECT c.* FROM \"dbo\".\"Users\" AS c", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests select all.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSelectAll2()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users)
|
||||||
|
.Select(u => u.dbo.Users.All());
|
||||||
|
|
||||||
|
Assert.AreEqual("SELECT \"dbo\".\"Users\".* FROM \"dbo\".\"Users\"", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests select field.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSelectField1()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.Select(u => u.c.UserName);
|
||||||
|
|
||||||
|
Assert.AreEqual("SELECT c.\"UserName\" FROM \"dbo\".\"Users\" AS c", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests select field.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSelectField2()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users)
|
||||||
|
.Select(u => u.dbo.Users.UserName);
|
||||||
|
|
||||||
|
Assert.AreEqual("SELECT \"dbo\".\"Users\".\"UserName\" FROM \"dbo\".\"Users\"", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests select field with alias.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSelectFieldAlias1()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.Select(u => u.c.UserName.As(u.Name));
|
||||||
|
|
||||||
|
Assert.AreEqual("SELECT c.\"UserName\" AS \"Name\" FROM \"dbo\".\"Users\" AS c", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests select field with alias.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSelectFieldAlias2()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users)
|
||||||
|
.Select(u => u.dbo.Users.UserName.As(u.Name));
|
||||||
|
|
||||||
|
Assert.AreEqual("SELECT \"dbo\".\"Users\".\"UserName\" AS \"Name\" FROM \"dbo\".\"Users\"", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests select aggregate field with alias (Sum).
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSelectAggregateField1()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.Select(u => u.Sum(u.c.UserName).As(u.Name));
|
||||||
|
|
||||||
|
Assert.AreEqual("SELECT Sum(c.\"UserName\") AS \"Name\" FROM \"dbo\".\"Users\" AS c", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests select aggregate field with alias (Coalesce).
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSelectAggregateField2()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.Select(u => u.Coalesce(u.c.UserName, u.c.FirstName + " " + u.c.LastName).As(u.Name));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT Coalesce(c.\"UserName\", ((c.\"FirstName\" + [${0}]) + c.\"LastName\")) AS \"Name\" FROM \"dbo\".\"Users\" AS c",
|
||||||
|
cmd.Parameters.Keys.First()), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests select aggregate field with alias (Sum).
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSelectAggregateField3()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users)
|
||||||
|
.Select(u => u.Sum(u.dbo.Users.UserName));
|
||||||
|
|
||||||
|
Assert.AreEqual("SELECT Sum(\"dbo\".\"Users\".\"UserName\") FROM \"dbo\".\"Users\"", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests select from anonymous type.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSelectAnon()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.Select(u => new
|
||||||
|
{
|
||||||
|
Id_User = u.c.Id_User,
|
||||||
|
Name = u.c.UserName,
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.AreEqual("SELECT c.\"Id_User\" AS \"Id_User\", c.\"UserName\" AS \"Name\" FROM \"dbo\".\"Users\" AS c", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests select escaped case.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSelectCaseEscaped1()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.Select(u => u("CASE ", u.c.IsActive, " WHEN ", 1, " THEN ", 0, " ELSE ", 1, " END").As(u.Deleted));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT CASE c.\"IsActive\" WHEN [${0}] THEN [${1}] ELSE [${2}] END AS \"Deleted\" FROM \"dbo\".\"Users\" AS c",
|
||||||
|
cmd.Parameters.Keys.ToArray()[0], cmd.Parameters.Keys.ToArray()[1], cmd.Parameters.Keys.ToArray()[2]), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests select escaped case.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSelectCaseEscaped2()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.Select(u => u("CASE WHEN ", u.c.IsActive == 1, " THEN ", 0, " ELSE ", 1, " END").As(u.Deleted));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT CASE WHEN (c.\"IsActive\" = [${0}]) THEN [${1}] ELSE [${2}] END AS \"Deleted\" FROM \"dbo\".\"Users\" AS c",
|
||||||
|
cmd.Parameters.Keys.ToArray()[0], cmd.Parameters.Keys.ToArray()[1], cmd.Parameters.Keys.ToArray()[2]), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests select escaped case with sub query.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSelectCaseEscapedAndSub()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.Select(u => u("CASE WHEN ", u.c.IsActive == 1, " AND ", u.c.IsAdmin == u(cmd.SubQuery()
|
||||||
|
.From(x => x.dbo.AccessRights.As(x.a))
|
||||||
|
.Where(x => x.a.User_Id == x.c.Id_User)
|
||||||
|
.Select(x => x.a.IsAdmin)), " THEN ", 0, " ELSE ", 1, " END").As(u.Deleted));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT CASE WHEN (c.\"IsActive\" = [${0}]) AND (c.\"IsAdmin\" = (SELECT a.\"IsAdmin\" FROM \"dbo\".\"AccessRights\" AS a WHERE (a.\"User_Id\" = c.\"Id_User\"))) THEN [${1}] ELSE [${2}] END AS \"Deleted\" FROM \"dbo\".\"Users\" AS c",
|
||||||
|
cmd.Parameters.Keys.ToArray()[0], cmd.Parameters.Keys.ToArray()[1], cmd.Parameters.Keys.ToArray()[2]), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests group by.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestGroupBy()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.GroupBy(u => u.c.UserName);
|
||||||
|
|
||||||
|
Assert.AreEqual("SELECT * FROM \"dbo\".\"Users\" AS c GROUP BY c.\"UserName\"", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests order by.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestOrderBy()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.OrderBy(u => u.c.UserName);
|
||||||
|
|
||||||
|
Assert.AreEqual("SELECT * FROM \"dbo\".\"Users\" AS c ORDER BY c.\"UserName\" ASC", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests order by using string with number.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestOrderByNumberedColumnStr()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.OrderBy(u => "1 DESC");
|
||||||
|
|
||||||
|
Assert.AreEqual("SELECT * FROM \"dbo\".\"Users\" AS c ORDER BY 1 DESC", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests order by using member with number.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestOrderByNumberedColFn()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.OrderBy(u => u.Desc(1));
|
||||||
|
|
||||||
|
Assert.AreEqual("SELECT * FROM \"dbo\".\"Users\" AS c ORDER BY 1 DESC", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests order by using member with field.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestOrderByAlt()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.OrderBy(u => u.Desc(u.c.UserName));
|
||||||
|
|
||||||
|
Assert.AreEqual("SELECT * FROM \"dbo\".\"Users\" AS c ORDER BY c.\"UserName\" DESC", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests sub query select.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSubQuerySelect()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.Select(u => u(cmd.SubQuery()
|
||||||
|
.From(x => x.dbo.AccessRights.As(x.a))
|
||||||
|
.Where(x => x.a.User_Id == x.c.Id_User)
|
||||||
|
.Select(x => x.a.IsAdmin)).As(u.IsAdmin));
|
||||||
|
|
||||||
|
Assert.AreEqual("SELECT (SELECT a.\"IsAdmin\" FROM \"dbo\".\"AccessRights\" AS a WHERE (a.\"User_Id\" = c.\"Id_User\")) AS \"IsAdmin\" FROM \"dbo\".\"Users\" AS c", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests sub query where.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSubQueryWhere()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.Where(u => u.c.IsAdmin == u(cmd.SubQuery()
|
||||||
|
.From(x => x.dbo.AccessRights.As(x.a))
|
||||||
|
.Where(x => x.a.User_Id == x.c.Id_User)
|
||||||
|
.Select(x => x.a.IsAdmin)));
|
||||||
|
|
||||||
|
Assert.AreEqual("SELECT * FROM \"dbo\".\"Users\" AS c WHERE (c.\"IsAdmin\" = (SELECT a.\"IsAdmin\" FROM \"dbo\".\"AccessRights\" AS a WHERE (a.\"User_Id\" = c.\"Id_User\")))", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests sub query in.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSubQueryWhereIn()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.Where(u => u.c.Id_User.In(u(cmd.SubQuery()
|
||||||
|
.From(x => x.dbo.AccessRights.As(x.a))
|
||||||
|
.Where(x => x.a.IsAdmin == 1)
|
||||||
|
.Select(x => x.a.User_Id))));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS c WHERE c.\"Id_User\" IN((SELECT a.\"User_Id\" FROM \"dbo\".\"AccessRights\" AS a WHERE (a.\"IsAdmin\" = [${0}])))", cmd.Parameters.Keys.First()), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests sub query join.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSubQueryJoin()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.c))
|
||||||
|
.Join(u => u.Inner()(cmd.SubQuery()
|
||||||
|
.From(x => x.dbo.AccessRights.As(x.a))
|
||||||
|
.Select(x => x.a.IsAdmin, x => x.a.User_Id)).As(u.ar).On(u.ar.User_Id == u.c.Id_User));
|
||||||
|
|
||||||
|
Assert.AreEqual("SELECT * FROM \"dbo\".\"Users\" AS c INNER JOIN (SELECT a.\"IsAdmin\", a.\"User_Id\" FROM \"dbo\".\"AccessRights\" AS a) AS ar ON (ar.\"User_Id\" = c.\"Id_User\")", cmd.CommandText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using DynamORM.Builders;
|
||||||
using DynamORM.Tests.Helpers;
|
using DynamORM.Tests.Helpers;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
@@ -65,6 +66,13 @@ namespace DynamORM.Tests.Select
|
|||||||
return Database.Table();
|
return Database.Table();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Create table using specified method.</summary>
|
||||||
|
/// <returns>Dynamic table.</returns>
|
||||||
|
public virtual IDynamicSelectQueryBuilder GetTestBuilder()
|
||||||
|
{
|
||||||
|
return Database.Table().Query() as IDynamicSelectQueryBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
#region Select typed
|
#region Select typed
|
||||||
|
|
||||||
/// <summary>Test load all rows into mapped list alternate way.</summary>
|
/// <summary>Test load all rows into mapped list alternate way.</summary>
|
||||||
@@ -76,6 +84,19 @@ 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 TestTypedGetAll2()
|
||||||
|
{
|
||||||
|
var list = GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Execute()
|
||||||
|
.MapEnumerable<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()
|
||||||
@@ -90,7 +111,17 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(200, GetTestTable().Count(type: typeof(T), columns: "id"));
|
Assert.AreEqual(200, GetTestTable().Count(type: typeof(T), columns: "id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Test count with in steatement.</summary>
|
/// <summary>Test typed <c>Count</c> method.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedCount2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(200, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Select(x => x.Count(x.t.id))
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Test count with in statement.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedSelectInEnumerableCount()
|
public virtual void TestTypedSelectInEnumerableCount()
|
||||||
{
|
{
|
||||||
@@ -101,7 +132,18 @@ namespace DynamORM.Tests.Select
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Test count with in steatement.</summary>
|
/// <summary>Test count with in statement.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedSelectInEnumerableCount2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(4, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Where(x => x.last.In(new object[] { "Hendricks", "Goodwin", "Freeman" }.Take(3)))
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Test count with in statement.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedSelectInArrayCount()
|
public virtual void TestTypedSelectInArrayCount()
|
||||||
{
|
{
|
||||||
@@ -112,6 +154,17 @@ namespace DynamORM.Tests.Select
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test count with in statement.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedSelectInArrayCount2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(4, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Where(x => x.last.In(new object[] { "Hendricks", "Goodwin", "Freeman" }))
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test typed <c>First</c> method.</summary>
|
/// <summary>Test typed <c>First</c> method.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedFirst()
|
public virtual void TestTypedFirst()
|
||||||
@@ -119,6 +172,17 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(1, GetTestTable().First(type: typeof(T), columns: "id").id);
|
Assert.AreEqual(1, GetTestTable().First(type: typeof(T), columns: "id").id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed <c>First</c> method.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedFirst2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(1, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Select(x => x.t.id)
|
||||||
|
.Execute()
|
||||||
|
.First().id);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test typed <c>Last</c> method.</summary>
|
/// <summary>Test typed <c>Last</c> method.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedLast()
|
public virtual void TestTypedLast()
|
||||||
@@ -126,6 +190,17 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(200, GetTestTable().Last(type: typeof(T), columns: "id").id);
|
Assert.AreEqual(200, GetTestTable().Last(type: typeof(T), columns: "id").id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed <c>Last</c> method.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedLast2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(200, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Select(x => x.t.id)
|
||||||
|
.Execute()
|
||||||
|
.Last().id);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test typed <c>Count</c> method.</summary>
|
/// <summary>Test typed <c>Count</c> method.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedCountSpecificRecord()
|
public virtual void TestTypedCountSpecificRecord()
|
||||||
@@ -140,6 +215,16 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(1, GetTestTable().Min(type: typeof(T), columns: "id"));
|
Assert.AreEqual(1, GetTestTable().Min(type: typeof(T), columns: "id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed <c>Min</c> method.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedMin2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(1, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Select(x => x.Min(x.t.id))
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test typed <c>Min</c> method.</summary>
|
/// <summary>Test typed <c>Min</c> method.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedMax()
|
public virtual void TestTypedMax()
|
||||||
@@ -147,6 +232,16 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(200, GetTestTable().Max(type: typeof(T), columns: "id"));
|
Assert.AreEqual(200, GetTestTable().Max(type: typeof(T), columns: "id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed <c>Min</c> method.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedMax2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(200, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Select(x => x.Max(x.t.id))
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test typed <c>Min</c> method.</summary>
|
/// <summary>Test typed <c>Min</c> method.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedtAvg()
|
public virtual void TestTypedtAvg()
|
||||||
@@ -154,6 +249,16 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(100.5, GetTestTable().Avg(type: typeof(T), columns: "id"));
|
Assert.AreEqual(100.5, GetTestTable().Avg(type: typeof(T), columns: "id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed <c>Min</c> method.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedtAvg2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(100.5, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Select(x => x.Avg(x.t.id))
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test typed <c>Sum</c> method.</summary>
|
/// <summary>Test typed <c>Sum</c> method.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedSum()
|
public virtual void TestTypedSum()
|
||||||
@@ -161,6 +266,16 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(20100, GetTestTable().Sum(type: typeof(T), columns: "id"));
|
Assert.AreEqual(20100, GetTestTable().Sum(type: typeof(T), columns: "id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed <c>Sum</c> method.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedSum2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(20100, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Select(x => x.Sum(x.t.id))
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test typed <c>Scalar</c> method for invalid operation exception.</summary>
|
/// <summary>Test typed <c>Scalar</c> method for invalid operation exception.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedScalarException()
|
public virtual void TestTypedScalarException()
|
||||||
@@ -175,6 +290,17 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual("Ori", GetTestTable().Scalar(type: typeof(T), columns: "first", id: 19));
|
Assert.AreEqual("Ori", GetTestTable().Scalar(type: typeof(T), columns: "first", id: 19));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed <c>Scalar</c> method.</summary>
|
||||||
|
[Test]
|
||||||
|
public void TestTypedScalar2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual("Ori", GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Where(x => x.t.id == 19)
|
||||||
|
.Select(x => x.t.first)
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test typed <c>Scalar</c> method with SQLite specific aggregate.</summary>
|
/// <summary>Test typed <c>Scalar</c> method with SQLite specific aggregate.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedScalarGroupConcat()
|
public virtual void TestTypedScalarGroupConcat()
|
||||||
@@ -185,6 +311,20 @@ namespace DynamORM.Tests.Select
|
|||||||
GetTestTable().Scalar(type: typeof(T), columns: "first:first:group_concat", id: new DynamicColumn { Operator = DynamicColumn.CompareOperator.Lt, Value = 20 }));
|
GetTestTable().Scalar(type: typeof(T), columns: "first:first:group_concat", id: new DynamicColumn { Operator = DynamicColumn.CompareOperator.Lt, Value = 20 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed <c>Scalar</c> method with SQLite specific aggregate.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedScalarGroupConcat2()
|
||||||
|
{
|
||||||
|
// This test should produce something like this:
|
||||||
|
// select group_concat("first") AS first from "users" where "id" < 20;
|
||||||
|
Assert.AreEqual("Clarke,Marny,Dai,Forrest,Blossom,George,Ivory,Inez,Sigourney,Fulton,Logan,Anne,Alexandra,Adena,Lionel,Aimee,Selma,Lara,Ori",
|
||||||
|
GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Where(x => x.t.id < 20)
|
||||||
|
.Select(x => x.group_concat(x.t.first).As(x.first))
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test typed <c>Scalar</c> method with SQLite specific aggregate not using aggregate field.</summary>
|
/// <summary>Test typed <c>Scalar</c> method with SQLite specific aggregate not using aggregate field.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedScalarGroupConcatNoAggregateField()
|
public virtual void TestTypedScalarGroupConcatNoAggregateField()
|
||||||
@@ -195,6 +335,20 @@ namespace DynamORM.Tests.Select
|
|||||||
GetTestTable().Scalar(type: typeof(T), columns: "group_concat(first):first", id: new DynamicColumn { Operator = DynamicColumn.CompareOperator.Lt, Value = 20 }));
|
GetTestTable().Scalar(type: typeof(T), columns: "group_concat(first):first", id: new DynamicColumn { Operator = DynamicColumn.CompareOperator.Lt, Value = 20 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed <c>Scalar</c> method with SQLite specific aggregate not using aggregate field.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedScalarGroupConcatNoAggregateField2()
|
||||||
|
{
|
||||||
|
// This test should produce something like this:
|
||||||
|
// select group_concat("first") AS first from "users" where "id" < 20;
|
||||||
|
Assert.AreEqual("Clarke,Marny,Dai,Forrest,Blossom,George,Ivory,Inez,Sigourney,Fulton,Logan,Anne,Alexandra,Adena,Lionel,Aimee,Selma,Lara,Ori",
|
||||||
|
GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Where(x => x.t.id < 20)
|
||||||
|
.Select("group_concat(first):first")
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test something fancy... like: <code>select "first", count("first") aggregatefield from "users" group by "first" order by 2 desc;</code>.</summary>
|
/// <summary>Test something fancy... like: <code>select "first", count("first") aggregatefield from "users" group by "first" order by 2 desc;</code>.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedFancyAggregateQuery()
|
public virtual void TestTypedFancyAggregateQuery()
|
||||||
@@ -210,6 +364,27 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(1, v.Last().aggregatefield);
|
Assert.AreEqual(1, v.Last().aggregatefield);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test something fancy... like: <code>select "first", count("first") aggregatefield from "users" group by "first" order by 2 desc;</code>.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedFancyAggregateQuery2()
|
||||||
|
{
|
||||||
|
var v = GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Select(x => x.t.first, x => x.Count(x.t.first).As(x.aggregatefield))
|
||||||
|
.GroupBy(x => x.t.first)
|
||||||
|
.OrderBy(x => x.Desc(2))
|
||||||
|
.Execute()
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
Assert.IsNotNull(v);
|
||||||
|
Assert.AreEqual(187, v.Count());
|
||||||
|
Assert.AreEqual(4, v.First().aggregatefield);
|
||||||
|
Assert.AreEqual("Logan", v.First().first);
|
||||||
|
Assert.AreEqual(2, v.Take(10).Last().aggregatefield);
|
||||||
|
Assert.AreEqual(1, v.Take(11).Last().aggregatefield);
|
||||||
|
Assert.AreEqual(1, v.Last().aggregatefield);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>This time also something fancy... aggregate in aggregate <code>select AVG(LENGTH("login")) len from "users";</code>.</summary>
|
/// <summary>This time also something fancy... aggregate in aggregate <code>select AVG(LENGTH("login")) len from "users";</code>.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedAggregateInAggregate()
|
public virtual void TestTypedAggregateInAggregate()
|
||||||
@@ -217,6 +392,16 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(12.77, GetTestTable().Scalar(type: typeof(T), columns: @"length(""login""):len:avg"));
|
Assert.AreEqual(12.77, GetTestTable().Scalar(type: typeof(T), columns: @"length(""login""):len:avg"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>This time also something fancy... aggregate in aggregate <code>select AVG(LENGTH("login")) len from "users";</code>.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedAggregateInAggregate2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(12.77, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Select(x => x.Avg(x.Length(x.t.login)).As(x.len))
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>This time also something fancy... aggregate in aggregate <code>select AVG(LENGTH("email")) len from "users";</code>.</summary>
|
/// <summary>This time also something fancy... aggregate in aggregate <code>select AVG(LENGTH("email")) len from "users";</code>.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedAggregateInAggregateMark2()
|
public virtual void TestTypedAggregateInAggregateMark2()
|
||||||
@@ -224,6 +409,16 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(27.7, GetTestTable().Avg(type: typeof(T), columns: @"length(""email""):len"));
|
Assert.AreEqual(27.7, GetTestTable().Avg(type: typeof(T), columns: @"length(""email""):len"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>This time also something fancy... aggregate in aggregate <code>select AVG(LENGTH("email")) len from "users";</code>.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedAggregateInAggregateMark3()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(27.7, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Select(x => "AVG(LENGTH(t.email)) AS LEN")
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test emails longer than 27 chars. <code>select count(*) from "users" where length("email") > 27;</code>.</summary>
|
/// <summary>Test emails longer than 27 chars. <code>select count(*) from "users" where length("email") > 27;</code>.</summary>
|
||||||
public virtual void TestTypedFunctionInWhere()
|
public virtual void TestTypedFunctionInWhere()
|
||||||
{
|
{
|
||||||
@@ -238,6 +433,16 @@ namespace DynamORM.Tests.Select
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test emails longer than 27 chars. <code>select count(*) from "users" where length("email") > 27;</code>.</summary>
|
||||||
|
public virtual void TestTypedFunctionInWhere2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(97, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Where(x => x.Length(x.t.email) > 27)
|
||||||
|
.Select(x => x.Count(x.t.All()))
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test typed <c>Single</c> multi.</summary>
|
/// <summary>Test typed <c>Single</c> multi.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedSingleObject()
|
public virtual void TestTypedSingleObject()
|
||||||
@@ -250,6 +455,23 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(exp.last, o.last);
|
Assert.AreEqual(exp.last, o.last);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed <c>Single</c> multi.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedSingleObject2()
|
||||||
|
{
|
||||||
|
var exp = new { id = 19, first = "Ori", last = "Ellis" };
|
||||||
|
var o = GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Where(x => x.t.id == 19)
|
||||||
|
.Select(x => new { id = x.t.id, first = x.t.first, last = x.t.last })
|
||||||
|
.Execute()
|
||||||
|
.First();
|
||||||
|
|
||||||
|
Assert.AreEqual(exp.id, o.id);
|
||||||
|
Assert.AreEqual(exp.first, o.first);
|
||||||
|
Assert.AreEqual(exp.last, o.last);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion Select typed
|
#endregion Select typed
|
||||||
|
|
||||||
#region Where typed
|
#region Where typed
|
||||||
@@ -261,6 +483,15 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual("hoyt.tran", GetTestTable().Single(type: typeof(T), where: new DynamicColumn("id").Eq(100)).login);
|
Assert.AreEqual("hoyt.tran", GetTestTable().Single(type: typeof(T), where: new DynamicColumn("id").Eq(100)).login);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed where expression equal.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedWhereEq2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual("hoyt.tran", GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Where(x => x.t.id == 100).Execute().First().login);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test typed where expression not equal.</summary>
|
/// <summary>Test typed where expression not equal.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedWhereNot()
|
public virtual void TestTypedWhereNot()
|
||||||
@@ -268,6 +499,17 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(199, GetTestTable().Count(type: typeof(T), where: new DynamicColumn("id").Not(100)));
|
Assert.AreEqual(199, GetTestTable().Count(type: typeof(T), where: new DynamicColumn("id").Not(100)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed where expression not equal.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedWhereNot2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(199, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Where(x => x.t.id != 100)
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test typed where expression like.</summary>
|
/// <summary>Test typed where expression like.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedWhereLike()
|
public virtual void TestTypedWhereLike()
|
||||||
@@ -275,6 +517,15 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(100, GetTestTable().Single(type: typeof(T), where: new DynamicColumn("login").Like("Hoyt.%")).id);
|
Assert.AreEqual(100, GetTestTable().Single(type: typeof(T), where: new DynamicColumn("login").Like("Hoyt.%")).id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed where expression like.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedWhereLike2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(100, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Where(x => x.t.login.Like("Hoyt.%")).Execute().First().id);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test typed where expression not like.</summary>
|
/// <summary>Test typed where expression not like.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedWhereNotLike()
|
public virtual void TestTypedWhereNotLike()
|
||||||
@@ -282,6 +533,28 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(199, GetTestTable().Count(type: typeof(T), where: new DynamicColumn("login").NotLike("Hoyt.%")));
|
Assert.AreEqual(199, GetTestTable().Count(type: typeof(T), where: new DynamicColumn("login").NotLike("Hoyt.%")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed where expression not like.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedWhereNotLike2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(199, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Where(x => x.t.login.NotLike("Hoyt.%"))
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed where expression not like.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedWhereNotLike3()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(199, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Where(x => !x.t.login.Like("Hoyt.%"))
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test typed where expression greater.</summary>
|
/// <summary>Test typed where expression greater.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedWhereGt()
|
public virtual void TestTypedWhereGt()
|
||||||
@@ -289,6 +562,17 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(100, GetTestTable().Count(type: typeof(T), where: new DynamicColumn("id").Greater(100)));
|
Assert.AreEqual(100, GetTestTable().Count(type: typeof(T), where: new DynamicColumn("id").Greater(100)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed where expression greater.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedWhereGt2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(100, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Where(x => x.t.id > 100)
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test typed where expression greater or equal.</summary>
|
/// <summary>Test typed where expression greater or equal.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedWhereGte()
|
public virtual void TestTypedWhereGte()
|
||||||
@@ -296,6 +580,17 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(101, GetTestTable().Count(type: typeof(T), where: new DynamicColumn("id").GreaterOrEqual(100)));
|
Assert.AreEqual(101, GetTestTable().Count(type: typeof(T), where: new DynamicColumn("id").GreaterOrEqual(100)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed where expression greater or equal.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedWhereGte2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(101, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Where(x => x.t.id >= 100)
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test typed where expression less.</summary>
|
/// <summary>Test typed where expression less.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedWhereLt()
|
public virtual void TestTypedWhereLt()
|
||||||
@@ -303,6 +598,17 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(99, GetTestTable().Count(type: typeof(T), where: new DynamicColumn("id").Less(100)));
|
Assert.AreEqual(99, GetTestTable().Count(type: typeof(T), where: new DynamicColumn("id").Less(100)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed where expression less.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedWhereLt2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(99, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Where(x => x.t.id < 100)
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test typed where expression less or equal.</summary>
|
/// <summary>Test typed where expression less or equal.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedWhereLte()
|
public virtual void TestTypedWhereLte()
|
||||||
@@ -310,6 +616,17 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(100, GetTestTable().Count(type: typeof(T), where: new DynamicColumn("id").LessOrEqual(100)));
|
Assert.AreEqual(100, GetTestTable().Count(type: typeof(T), where: new DynamicColumn("id").LessOrEqual(100)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed where expression less or equal.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedWhereLte2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(100, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Where(x => x.t.id <= 100)
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Test typed where expression between.</summary>
|
/// <summary>Test typed where expression between.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedWhereBetween()
|
public virtual void TestTypedWhereBetween()
|
||||||
@@ -317,7 +634,18 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(26, GetTestTable().Count(type: typeof(T), where: new DynamicColumn("id").Between(75, 100)));
|
Assert.AreEqual(26, GetTestTable().Count(type: typeof(T), where: new DynamicColumn("id").Between(75, 100)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Test typed where expression in params.</summary>
|
/// <summary>Test typed where expression between.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedWhereBetween2()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(26, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Where(x => x.t.id.Between(75, 100))
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed where expression in parameters.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestTypedWhereIn1()
|
public virtual void TestTypedWhereIn1()
|
||||||
{
|
{
|
||||||
@@ -331,6 +659,28 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(3, GetTestTable().Count(type: typeof(T), where: new DynamicColumn("id").In(new[] { 75, 99, 100 })));
|
Assert.AreEqual(3, GetTestTable().Count(type: typeof(T), where: new DynamicColumn("id").In(new[] { 75, 99, 100 })));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed where expression in parameters.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedWhereIn3()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(3, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Where(x => x.t.id.In(75, 99, 100))
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Test typed where expression in array.</summary>
|
||||||
|
[Test]
|
||||||
|
public virtual void TestTypedWhereIn4()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(3, GetTestBuilder()
|
||||||
|
.From(x => x(typeof(T)).As(x.t))
|
||||||
|
.Where(x => x.t.id.In(new[] { 75, 99, 100 }))
|
||||||
|
.Select(x => x.Count())
|
||||||
|
.Scalar());
|
||||||
|
}
|
||||||
|
|
||||||
#endregion Where typed
|
#endregion Where typed
|
||||||
|
|
||||||
#region Select generic
|
#region Select generic
|
||||||
@@ -358,7 +708,7 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(200, GetTestTable().Count<T>(columns: "id"));
|
Assert.AreEqual(200, GetTestTable().Count<T>(columns: "id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Test count with in steatement.</summary>
|
/// <summary>Test count with in statement.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestGenericSelectInEnumerableCount()
|
public virtual void TestGenericSelectInEnumerableCount()
|
||||||
{
|
{
|
||||||
@@ -369,7 +719,7 @@ namespace DynamORM.Tests.Select
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Test count with in steatement.</summary>
|
/// <summary>Test count with in statement.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestGenericSelectInArrayCount()
|
public virtual void TestGenericSelectInArrayCount()
|
||||||
{
|
{
|
||||||
@@ -585,7 +935,7 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(26, GetTestTable().Count<T>(where: new DynamicColumn("id").Between(75, 100)));
|
Assert.AreEqual(26, GetTestTable().Count<T>(where: new DynamicColumn("id").Between(75, 100)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Test generic where expression in params.</summary>
|
/// <summary>Test generic where expression in parameters.</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public virtual void TestGenericWhereIn1()
|
public virtual void TestGenericWhereIn1()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ namespace DynamORM.Tests
|
|||||||
|
|
||||||
#region DynamORM Initialization
|
#region DynamORM Initialization
|
||||||
|
|
||||||
/// <summary>Create <see cref="DynamicDatabase"/> with default otions for SQLite.</summary>
|
/// <summary>Create <see cref="DynamicDatabase"/> with default options for SQLite.</summary>
|
||||||
public void CreateDynamicDatabase()
|
public void CreateDynamicDatabase()
|
||||||
{
|
{
|
||||||
CreateDynamicDatabase(
|
CreateDynamicDatabase(
|
||||||
|
|||||||
@@ -1,192 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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;
|
|
||||||
using System.Data;
|
|
||||||
using System.Text;
|
|
||||||
using DynamORM.Mapper;
|
|
||||||
|
|
||||||
namespace DynamORM.Builders
|
|
||||||
{
|
|
||||||
/// <summary>Insert query builder.</summary>
|
|
||||||
public class DynamicInsertQueryBuilder : DynamicQueryBuilder<DynamicInsertQueryBuilder>
|
|
||||||
{
|
|
||||||
/// <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>
|
|
||||||
/// <param name="table">Parent dynamic table.</param>
|
|
||||||
public DynamicInsertQueryBuilder(DynamicTable table)
|
|
||||||
: base(table)
|
|
||||||
{
|
|
||||||
ValueColumns = new Dictionary<string, DynamicColumn>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add insert fields.</summary>
|
|
||||||
/// <param name="column">Insert column and value.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public virtual DynamicInsertQueryBuilder Insert(DynamicColumn column)
|
|
||||||
{
|
|
||||||
if (ValueColumns.ContainsKey(column.ColumnName.ToLower()))
|
|
||||||
ValueColumns[column.ColumnName.ToLower()] = column;
|
|
||||||
else
|
|
||||||
ValueColumns.Add(column.ColumnName.ToLower(), column);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add insert fields.</summary>
|
|
||||||
/// <param name="column">Insert column.</param>
|
|
||||||
/// <param name="value">Insert value.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public virtual DynamicInsertQueryBuilder Insert(string column, object value)
|
|
||||||
{
|
|
||||||
if (value is DynamicColumn)
|
|
||||||
{
|
|
||||||
var v = (DynamicColumn)value;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(v.ColumnName))
|
|
||||||
v.ColumnName = column;
|
|
||||||
|
|
||||||
return Insert(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ValueColumns.ContainsKey(column.ToLower()))
|
|
||||||
ValueColumns[column.ToLower()].Value = value;
|
|
||||||
else
|
|
||||||
ValueColumns.Add(column.ToLower(), new DynamicColumn
|
|
||||||
{
|
|
||||||
ColumnName = column,
|
|
||||||
Value = value
|
|
||||||
});
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add insert fields.</summary>
|
|
||||||
/// <param name="o">Set insert value as properties and values of an object.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public virtual DynamicInsertQueryBuilder Insert(object o)
|
|
||||||
{
|
|
||||||
var dict = o.ToDictionary();
|
|
||||||
var mapper = DynamicMapperCache.GetMapper(o.GetType());
|
|
||||||
|
|
||||||
if (mapper != null)
|
|
||||||
{
|
|
||||||
foreach (var con in dict)
|
|
||||||
if (!mapper.Ignored.Contains(con.Key))
|
|
||||||
Insert(mapper.PropertyMap.TryGetValue(con.Key) ?? con.Key, con.Value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
foreach (var con in dict)
|
|
||||||
Insert(con.Key, con.Value);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add where condition.</summary>
|
|
||||||
/// <param name="column">Condition column with operator and value.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public override DynamicInsertQueryBuilder Where(DynamicColumn column)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add where condition.</summary>
|
|
||||||
/// <param name="column">Condition column.</param>
|
|
||||||
/// <param name="op">Condition operator.</param>
|
|
||||||
/// <param name="value">Condition value.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public override DynamicInsertQueryBuilder Where(string column, DynamicColumn.CompareOperator op, object value)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add where condition.</summary>
|
|
||||||
/// <param name="column">Condition column.</param>
|
|
||||||
/// <param name="value">Condition value.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public override DynamicInsertQueryBuilder Where(string column, object value)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add where condition.</summary>
|
|
||||||
/// <param name="conditions">Set conditions as properties and values of an object.</param>
|
|
||||||
/// <param name="schema">If <c>true</c> use schema to determine key columns and ignore those which
|
|
||||||
/// aren't keys.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public override DynamicInsertQueryBuilder Where(object conditions, bool schema = false)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Fill command with query.</summary>
|
|
||||||
/// <param name="command">Command to fill.</param>
|
|
||||||
/// <returns>Filled instance of <see cref="IDbCommand"/>.</returns>
|
|
||||||
public override IDbCommand FillCommand(IDbCommand command)
|
|
||||||
{
|
|
||||||
if (ValueColumns.Count == 0)
|
|
||||||
throw new InvalidOperationException("Insert query should contain columns to change.");
|
|
||||||
|
|
||||||
StringBuilder builderColumns = new StringBuilder();
|
|
||||||
StringBuilder builderValues = new StringBuilder();
|
|
||||||
|
|
||||||
bool first = true;
|
|
||||||
var db = DynamicTable.Database;
|
|
||||||
|
|
||||||
foreach (var v in ValueColumns)
|
|
||||||
{
|
|
||||||
int pos = command.Parameters.Count;
|
|
||||||
|
|
||||||
if (!first)
|
|
||||||
{
|
|
||||||
builderColumns.Append(", ");
|
|
||||||
builderValues.Append(", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
db.DecorateName(builderColumns, v.Value.ColumnName);
|
|
||||||
db.GetParameterName(builderValues, pos);
|
|
||||||
|
|
||||||
command.AddParameter(this, v.Value);
|
|
||||||
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return command.SetCommand("INSERT INTO {0} ({1}) VALUES ({2})", db.DecorateName(TableName), builderColumns, builderValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Execute this builder.</summary>
|
|
||||||
/// <returns>Number of affected rows.</returns>
|
|
||||||
public override dynamic Execute()
|
|
||||||
{
|
|
||||||
return DynamicTable.Execute(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,403 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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;
|
|
||||||
using System.Data;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using DynamORM.Mapper;
|
|
||||||
|
|
||||||
namespace DynamORM.Builders
|
|
||||||
{
|
|
||||||
/// <summary>Base query builder.</summary>
|
|
||||||
/// <typeparam name="T">Return type of methods that should return self.</typeparam>
|
|
||||||
public abstract class DynamicQueryBuilder<T> : IDynamicQueryBuilder where T : class
|
|
||||||
{
|
|
||||||
/// <summary>Gets <see cref="DynamicTable"/> instance.</summary>
|
|
||||||
public DynamicTable DynamicTable { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>Gets where conditions.</summary>
|
|
||||||
public List<DynamicColumn> WhereConditions { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>Gets table schema.</summary>
|
|
||||||
public Dictionary<string, DynamicSchemaColumn> Schema { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>Gets a value indicating whether database supports standard schema.</summary>
|
|
||||||
public bool SupportSchema { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>Gets or sets a value indicating whether set parameters for null values.</summary>
|
|
||||||
public bool VirtualMode { get; set; }
|
|
||||||
|
|
||||||
/// <summary>Gets table name.</summary>
|
|
||||||
public string TableName { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>Initializes a new instance of the DynamicQueryBuilder class.</summary>
|
|
||||||
/// <param name="table">Parent dynamic table.</param>
|
|
||||||
public DynamicQueryBuilder(DynamicTable table)
|
|
||||||
{
|
|
||||||
DynamicTable = table;
|
|
||||||
TableName = table.TableName;
|
|
||||||
VirtualMode = false;
|
|
||||||
|
|
||||||
WhereConditions = new List<DynamicColumn>();
|
|
||||||
|
|
||||||
SupportSchema = (DynamicTable.Database.Options & DynamicDatabaseOptions.SupportSchema) == DynamicDatabaseOptions.SupportSchema;
|
|
||||||
|
|
||||||
Schema = DynamicTable.Schema;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Set table name.</summary>
|
|
||||||
/// <param name="name">Name of table.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public virtual T Table(string name)
|
|
||||||
{
|
|
||||||
if (TableName.ToLower() != name.ToLower())
|
|
||||||
{
|
|
||||||
TableName = name;
|
|
||||||
|
|
||||||
Schema = DynamicTable.Database.GetSchema(TableName);
|
|
||||||
|
|
||||||
if (Schema == null)
|
|
||||||
throw new InvalidOperationException("Can't assign type as a table for which schema can't be build.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return this as T;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Set table name.</summary>
|
|
||||||
/// <typeparam name="Y">Type representing table.</typeparam>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public virtual T Table<Y>()
|
|
||||||
{
|
|
||||||
return Table(typeof(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Set table name.</summary>
|
|
||||||
/// <param name="type">Type representing table.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public virtual T Table(Type type)
|
|
||||||
{
|
|
||||||
var mapper = DynamicMapperCache.GetMapper(type);
|
|
||||||
string name = string.Empty;
|
|
||||||
|
|
||||||
if (mapper == null)
|
|
||||||
throw new InvalidOperationException("Cant assign unmapable type as a table.");
|
|
||||||
else
|
|
||||||
name = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Name) ?
|
|
||||||
mapper.Type.Name : mapper.Table.Name;
|
|
||||||
|
|
||||||
if (TableName.ToLower() != name.ToLower())
|
|
||||||
{
|
|
||||||
TableName = name;
|
|
||||||
|
|
||||||
Schema = DynamicTable.Database.GetSchema(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this as T;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add where condition.</summary>
|
|
||||||
/// <param name="column">Condition column with operator and value.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public virtual T Where(DynamicColumn column)
|
|
||||||
{
|
|
||||||
WhereConditions.Add(column);
|
|
||||||
|
|
||||||
return this as T;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add where condition.</summary>
|
|
||||||
/// <param name="column">Condition column.</param>
|
|
||||||
/// <param name="op">Condition operator.</param>
|
|
||||||
/// <param name="value">Condition value.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public virtual T Where(string column, DynamicColumn.CompareOperator op, object value)
|
|
||||||
{
|
|
||||||
if (value is DynamicColumn)
|
|
||||||
{
|
|
||||||
var v = (DynamicColumn)value;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(v.ColumnName))
|
|
||||||
v.ColumnName = column;
|
|
||||||
|
|
||||||
return Where(v);
|
|
||||||
}
|
|
||||||
else if (value is IEnumerable<DynamicColumn>)
|
|
||||||
{
|
|
||||||
foreach (var v in (IEnumerable<DynamicColumn>)value)
|
|
||||||
Where(v);
|
|
||||||
|
|
||||||
return this as T;
|
|
||||||
}
|
|
||||||
|
|
||||||
WhereConditions.Add(new DynamicColumn
|
|
||||||
{
|
|
||||||
ColumnName = column,
|
|
||||||
Operator = op,
|
|
||||||
Value = value
|
|
||||||
});
|
|
||||||
|
|
||||||
return this as T;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add where condition.</summary>
|
|
||||||
/// <param name="column">Condition column.</param>
|
|
||||||
/// <param name="value">Condition value.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public virtual T Where(string column, object value)
|
|
||||||
{
|
|
||||||
return Where(column, DynamicColumn.CompareOperator.Eq, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add where condition.</summary>
|
|
||||||
/// <param name="conditions">Set conditions as properties and values of an object.</param>
|
|
||||||
/// <param name="schema">If <c>true</c> use schema to determine key columns and ignore those which
|
|
||||||
/// aren't keys.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public virtual T Where(object conditions, bool schema = false)
|
|
||||||
{
|
|
||||||
if (conditions is DynamicColumn)
|
|
||||||
return Where((DynamicColumn)conditions);
|
|
||||||
|
|
||||||
var dict = conditions.ToDictionary();
|
|
||||||
var mapper = DynamicMapperCache.GetMapper(conditions.GetType());
|
|
||||||
|
|
||||||
foreach (var con in dict)
|
|
||||||
{
|
|
||||||
if (mapper.Ignored.Contains(con.Key))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
string colName = mapper != null ? mapper.PropertyMap.TryGetValue(con.Key) ?? con.Key : con.Key;
|
|
||||||
|
|
||||||
DynamicSchemaColumn? col = null;
|
|
||||||
|
|
||||||
if (schema)
|
|
||||||
{
|
|
||||||
col = Schema.TryGetNullable(colName.ToLower());
|
|
||||||
|
|
||||||
if (!col.HasValue)
|
|
||||||
throw new InvalidOperationException(string.Format("Column '{0}' not found in schema, can't use universal approach.", con.Key));
|
|
||||||
|
|
||||||
if (!col.Value.IsKey)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
colName = col.Value.Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
Where(colName, con.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this as T;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Get string representation of operator.</summary>
|
|
||||||
/// <param name="op">Operator object.</param>
|
|
||||||
/// <returns>String representation of operator.</returns>
|
|
||||||
public string ToOperator(DynamicColumn.CompareOperator op)
|
|
||||||
{
|
|
||||||
switch (op)
|
|
||||||
{
|
|
||||||
case DynamicColumn.CompareOperator.Eq: return "=";
|
|
||||||
case DynamicColumn.CompareOperator.Not: return "<>";
|
|
||||||
case DynamicColumn.CompareOperator.Like: return "LIKE";
|
|
||||||
case DynamicColumn.CompareOperator.NotLike: return "NOT LIKE";
|
|
||||||
case DynamicColumn.CompareOperator.Lt: return "<";
|
|
||||||
case DynamicColumn.CompareOperator.Lte: return "<=";
|
|
||||||
case DynamicColumn.CompareOperator.Gt: return ">";
|
|
||||||
case DynamicColumn.CompareOperator.Gte: return ">=";
|
|
||||||
case DynamicColumn.CompareOperator.Between:
|
|
||||||
case DynamicColumn.CompareOperator.In:
|
|
||||||
default:
|
|
||||||
throw new ArgumentException(string.Format("This operator ('{0}') requires more than conversion to string.", op));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Fill where part of a query.</summary>
|
|
||||||
/// <param name="command">Command to fill.</param>
|
|
||||||
/// <param name="sb">String builder.</param>
|
|
||||||
public virtual void FillWhere(IDbCommand command, StringBuilder sb)
|
|
||||||
{
|
|
||||||
// Yes, this method qualifies fo refactoring... but it's fast
|
|
||||||
bool first = true;
|
|
||||||
var db = DynamicTable.Database;
|
|
||||||
|
|
||||||
foreach (var v in WhereConditions)
|
|
||||||
{
|
|
||||||
var col = Schema.TryGetNullable(v.ColumnName.ToLower());
|
|
||||||
|
|
||||||
string column = col.HasValue ? col.Value.Name : v.ColumnName;
|
|
||||||
|
|
||||||
if ((column.IndexOf(db.LeftDecorator) == -1 || column.IndexOf(db.LeftDecorator) == -1) &&
|
|
||||||
(column.IndexOf('(') == -1 || column.IndexOf(')') == -1))
|
|
||||||
column = db.DecorateName(column);
|
|
||||||
|
|
||||||
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}{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.");
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
else if (v.Operator != DynamicColumn.CompareOperator.In &&
|
|
||||||
v.Operator != DynamicColumn.CompareOperator.Between)
|
|
||||||
{
|
|
||||||
#region Standard operators
|
|
||||||
|
|
||||||
int pos = command.Parameters.Count;
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
else if (((object)v.Value).GetType().IsCollection() || v.Value is IEnumerable<object>)
|
|
||||||
{
|
|
||||||
#region In or Between operator
|
|
||||||
|
|
||||||
if (v.Operator == DynamicColumn.CompareOperator.Between)
|
|
||||||
{
|
|
||||||
#region Between operator
|
|
||||||
|
|
||||||
var vals = (v.Value as IEnumerable<object>).Take(2).ToList();
|
|
||||||
|
|
||||||
if (vals == null && v.Value is Array)
|
|
||||||
vals = ((Array)v.Value).Cast<object>().ToList();
|
|
||||||
|
|
||||||
if (vals.Count == 2)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
v.Value = vals[0];
|
|
||||||
command.AddParameter(this, v);
|
|
||||||
|
|
||||||
sb.Append(" AND ");
|
|
||||||
|
|
||||||
// To parameter
|
|
||||||
db.GetParameterName(sb, command.Parameters.Count);
|
|
||||||
v.Value = vals[1];
|
|
||||||
command.AddParameter(this, v);
|
|
||||||
|
|
||||||
if (v.EndBlock)
|
|
||||||
sb.Append(")");
|
|
||||||
|
|
||||||
// Reset value
|
|
||||||
v.Value = vals;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw new InvalidOperationException("BETWEEN must have two values.");
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
else if (v.Operator == DynamicColumn.CompareOperator.In)
|
|
||||||
{
|
|
||||||
#region In operator
|
|
||||||
|
|
||||||
sb.AppendFormat(" {0} {1}{2} IN(",
|
|
||||||
first ? "WHERE" : v.Or ? "OR" : "AND",
|
|
||||||
v.BeginBlock ? "(" : string.Empty,
|
|
||||||
column);
|
|
||||||
|
|
||||||
bool firstParam = true;
|
|
||||||
|
|
||||||
var vals = v.Value as IEnumerable<object>;
|
|
||||||
|
|
||||||
if (vals == null && v.Value is Array)
|
|
||||||
vals = ((Array)v.Value).Cast<object>() as IEnumerable<object>;
|
|
||||||
|
|
||||||
foreach (var val in vals)
|
|
||||||
{
|
|
||||||
int pos = command.Parameters.Count;
|
|
||||||
|
|
||||||
if (!firstParam)
|
|
||||||
sb.Append(", ");
|
|
||||||
|
|
||||||
db.GetParameterName(sb, pos);
|
|
||||||
v.Value = val;
|
|
||||||
|
|
||||||
command.AddParameter(this, v);
|
|
||||||
|
|
||||||
firstParam = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
v.Value = vals;
|
|
||||||
|
|
||||||
sb.Append(")");
|
|
||||||
|
|
||||||
if (v.EndBlock)
|
|
||||||
sb.Append(")");
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw new Exception("BAZINGA. You have reached unreachable code.");
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw new InvalidOperationException(
|
|
||||||
string.Format("Operator was {0}, but value wasn't enumerable. Column: '{1}'", v.Operator.ToString().ToUpper(), col));
|
|
||||||
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Fill command with query.</summary>
|
|
||||||
/// <param name="command">Command to fill.</param>
|
|
||||||
/// <returns>Filled instance of <see cref="IDbCommand"/>.</returns>
|
|
||||||
public abstract IDbCommand FillCommand(IDbCommand command);
|
|
||||||
|
|
||||||
/// <summary>Execute this builder.</summary>
|
|
||||||
/// <returns>Result of an execution..</returns>
|
|
||||||
public abstract dynamic Execute();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,272 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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;
|
|
||||||
using System.Data;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace DynamORM.Builders
|
|
||||||
{
|
|
||||||
/// <summary>Select query builder.</summary>
|
|
||||||
public class DynamicSelectQueryBuilder : DynamicQueryBuilder<DynamicSelectQueryBuilder>
|
|
||||||
{
|
|
||||||
/// <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>
|
|
||||||
public List<DynamicColumn> Group { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>Gets dictionary of columns that will be used to order query.</summary>
|
|
||||||
public List<DynamicColumn> Order { get; private set; }
|
|
||||||
|
|
||||||
private int? _top = null;
|
|
||||||
private int? _limit = null;
|
|
||||||
private int? _offset = null;
|
|
||||||
private bool _distinct = false;
|
|
||||||
|
|
||||||
/// <summary>Initializes a new instance of the <see cref="DynamicSelectQueryBuilder" /> class.</summary>
|
|
||||||
/// <param name="table">Parent dynamic table.</param>
|
|
||||||
public DynamicSelectQueryBuilder(DynamicTable table)
|
|
||||||
: base(table)
|
|
||||||
{
|
|
||||||
Columns = new List<DynamicColumn>();
|
|
||||||
Group = new List<DynamicColumn>();
|
|
||||||
Order = new List<DynamicColumn>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add select columns.</summary>
|
|
||||||
/// <param name="columns">Columns to add to object.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public DynamicSelectQueryBuilder Select(params DynamicColumn[] columns)
|
|
||||||
{
|
|
||||||
foreach (var col in columns)
|
|
||||||
Columns.Add(col);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add select columns.</summary>
|
|
||||||
/// <param name="columns">Columns to add to object.</param>
|
|
||||||
/// <remarks>Column format consist of <c>Column Name</c>, <c>Alias</c> and
|
|
||||||
/// <c>Aggregate function</c> in this order separated by '<c>:</c>'.</remarks>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public DynamicSelectQueryBuilder Select(params string[] columns)
|
|
||||||
{
|
|
||||||
return Select(columns.Select(c => DynamicColumn.ParseSelectColumn(c)).ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add select columns.</summary>
|
|
||||||
/// <param name="columns">Columns to group by.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public DynamicSelectQueryBuilder GroupBy(params DynamicColumn[] columns)
|
|
||||||
{
|
|
||||||
foreach (var col in columns)
|
|
||||||
Group.Add(col);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add select columns.</summary>
|
|
||||||
/// <param name="columns">Columns to group by.</param>
|
|
||||||
/// <remarks>Column format consist of <c>Column Name</c> and
|
|
||||||
/// <c>Alias</c> in this order separated by '<c>:</c>'.</remarks>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public DynamicSelectQueryBuilder GroupBy(params string[] columns)
|
|
||||||
{
|
|
||||||
return GroupBy(columns.Select(c => DynamicColumn.ParseSelectColumn(c)).ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add select columns.</summary>
|
|
||||||
/// <param name="columns">Columns to order by.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public DynamicSelectQueryBuilder OrderBy(params DynamicColumn[] columns)
|
|
||||||
{
|
|
||||||
foreach (var col in columns)
|
|
||||||
Order.Add(col);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add select columns.</summary>
|
|
||||||
/// <param name="columns">Columns to order by.</param>
|
|
||||||
/// <remarks>Column format consist of <c>Column Name</c> and
|
|
||||||
/// <c>Alias</c> in this order separated by '<c>:</c>'.</remarks>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public DynamicSelectQueryBuilder OrderBy(params string[] columns)
|
|
||||||
{
|
|
||||||
return OrderBy(columns.Select(c => DynamicColumn.ParseOrderByColumn(c)).ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Set top if database support it.</summary>
|
|
||||||
/// <param name="top">How many objects select.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public DynamicSelectQueryBuilder Top(int? top)
|
|
||||||
{
|
|
||||||
if ((DynamicTable.Database.Options & DynamicDatabaseOptions.SupportTop) != DynamicDatabaseOptions.SupportTop)
|
|
||||||
throw new NotSupportedException("Database doesn't support TOP clause.");
|
|
||||||
|
|
||||||
_top = top;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Set top if database support it.</summary>
|
|
||||||
/// <param name="limit">How many objects select.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public DynamicSelectQueryBuilder Limit(int? limit)
|
|
||||||
{
|
|
||||||
if ((DynamicTable.Database.Options & DynamicDatabaseOptions.SupportLimitOffset) != DynamicDatabaseOptions.SupportLimitOffset)
|
|
||||||
throw new NotSupportedException("Database doesn't support LIMIT clause.");
|
|
||||||
|
|
||||||
_limit = limit;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Set top if database support it.</summary>
|
|
||||||
/// <param name="offset">How many objects skip selecting.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public DynamicSelectQueryBuilder Offset(int? offset)
|
|
||||||
{
|
|
||||||
if ((DynamicTable.Database.Options & DynamicDatabaseOptions.SupportLimitOffset) != DynamicDatabaseOptions.SupportLimitOffset)
|
|
||||||
throw new NotSupportedException("Database doesn't support OFFSET clause.");
|
|
||||||
|
|
||||||
_offset = offset;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Set distinct mode.</summary>
|
|
||||||
/// <param name="distinct">Distinct mode.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public DynamicSelectQueryBuilder Distinct(bool distinct = true)
|
|
||||||
{
|
|
||||||
_distinct = distinct;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Fill command with query.</summary>
|
|
||||||
/// <param name="command">Command to fill.</param>
|
|
||||||
/// <returns>Filled instance of <see cref="IDbCommand"/>.</returns>
|
|
||||||
public override IDbCommand FillCommand(IDbCommand command)
|
|
||||||
{
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
|
|
||||||
var db = DynamicTable.Database;
|
|
||||||
|
|
||||||
sb.AppendFormat("SELECT{0}{1} ",
|
|
||||||
_distinct ? " DISTINCT" : string.Empty,
|
|
||||||
_top.HasValue ? string.Format(" TOP {0}", _top.Value) : string.Empty);
|
|
||||||
|
|
||||||
BuildColumns(sb, db);
|
|
||||||
|
|
||||||
sb.Append(" FROM ");
|
|
||||||
db.DecorateName(sb, TableName);
|
|
||||||
|
|
||||||
FillWhere(command, sb);
|
|
||||||
|
|
||||||
BuildGroup(sb, db);
|
|
||||||
BuildOrder(sb, db);
|
|
||||||
|
|
||||||
if (_limit.HasValue)
|
|
||||||
sb.AppendFormat(" LIMIT {0}", _limit.Value);
|
|
||||||
|
|
||||||
if (_offset.HasValue)
|
|
||||||
sb.AppendFormat(" OFFSET {0}", _offset.Value);
|
|
||||||
|
|
||||||
return command.SetCommand(sb.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void BuildColumns(StringBuilder sb, DynamicDatabase db)
|
|
||||||
{
|
|
||||||
if (Columns.Count > 0)
|
|
||||||
{
|
|
||||||
bool first = true;
|
|
||||||
|
|
||||||
// Not pretty but blazing fast
|
|
||||||
Columns.ForEach(c =>
|
|
||||||
{
|
|
||||||
if (!first)
|
|
||||||
sb.Append(", ");
|
|
||||||
|
|
||||||
c.ToSQLSelectColumn(db, sb);
|
|
||||||
first = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sb.Append("*");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void BuildGroup(StringBuilder sb, DynamicDatabase db)
|
|
||||||
{
|
|
||||||
if (Group.Count > 0)
|
|
||||||
{
|
|
||||||
sb.Append(" GROUP BY ");
|
|
||||||
bool first = true;
|
|
||||||
|
|
||||||
// Not pretty but blazing fast
|
|
||||||
Group.ForEach(c =>
|
|
||||||
{
|
|
||||||
if (!first)
|
|
||||||
sb.Append(", ");
|
|
||||||
|
|
||||||
c.ToSQLGroupByColumn(db, sb);
|
|
||||||
first = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void BuildOrder(StringBuilder sb, DynamicDatabase db)
|
|
||||||
{
|
|
||||||
if (Order.Count > 0)
|
|
||||||
{
|
|
||||||
sb.Append(" ORDER BY ");
|
|
||||||
bool first = true;
|
|
||||||
|
|
||||||
// Not pretty but blazing fast
|
|
||||||
Order.ForEach(c =>
|
|
||||||
{
|
|
||||||
if (!first)
|
|
||||||
sb.Append(", ");
|
|
||||||
|
|
||||||
c.ToSQLOrderByColumn(db, sb);
|
|
||||||
first = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Execute this builder.</summary>
|
|
||||||
/// <returns>Enumerator of objects expanded from query.</returns>
|
|
||||||
public override dynamic Execute()
|
|
||||||
{
|
|
||||||
if (Columns.Count <= 1 && ((_top.HasValue && _top.Value == 1) || (_limit.HasValue && _limit.Value == 1)))
|
|
||||||
return DynamicTable.Scalar(this);
|
|
||||||
else
|
|
||||||
return DynamicTable.Query(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,238 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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;
|
|
||||||
using System.Data;
|
|
||||||
using System.Text;
|
|
||||||
using DynamORM.Mapper;
|
|
||||||
|
|
||||||
namespace DynamORM.Builders
|
|
||||||
{
|
|
||||||
/// <summary>Update query builder.</summary>
|
|
||||||
public class DynamicUpdateQueryBuilder : DynamicQueryBuilder<DynamicUpdateQueryBuilder>
|
|
||||||
{
|
|
||||||
/// <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>
|
|
||||||
/// <param name="table">Parent dynamic table.</param>
|
|
||||||
public DynamicUpdateQueryBuilder(DynamicTable table)
|
|
||||||
: base(table)
|
|
||||||
{
|
|
||||||
ValueColumns = new Dictionary<string, DynamicColumn>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add update value or where condition using schema.</summary>
|
|
||||||
/// <param name="column">Update or where column name and value.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public virtual DynamicUpdateQueryBuilder Update(DynamicColumn column)
|
|
||||||
{
|
|
||||||
var col = Schema.TryGetNullable(column.ColumnName.ToLower());
|
|
||||||
|
|
||||||
if (!col.HasValue && SupportSchema)
|
|
||||||
throw new InvalidOperationException(string.Format("Column '{0}' not found in schema, can't use universal approach.", column));
|
|
||||||
|
|
||||||
if (col.HasValue && col.Value.IsKey)
|
|
||||||
Where(column);
|
|
||||||
else
|
|
||||||
Values(column.ColumnName, column.Value);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add update value or where condition using schema.</summary>
|
|
||||||
/// <param name="column">Update or where column name.</param>
|
|
||||||
/// <param name="value">Column value.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public virtual DynamicUpdateQueryBuilder Update(string column, object value)
|
|
||||||
{
|
|
||||||
var col = Schema.TryGetNullable(column.ToLower());
|
|
||||||
|
|
||||||
if (!col.HasValue && SupportSchema)
|
|
||||||
throw new InvalidOperationException(string.Format("Column '{0}' not found in schema, can't use universal approach.", column));
|
|
||||||
|
|
||||||
if (col.HasValue && col.Value.IsKey)
|
|
||||||
Where(column, value);
|
|
||||||
else
|
|
||||||
Values(column, value);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add update values and where condition columns using schema.</summary>
|
|
||||||
/// <param name="conditions">Set values or conditions as properties and values of an object.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public virtual DynamicUpdateQueryBuilder Update(object conditions)
|
|
||||||
{
|
|
||||||
if (conditions is DynamicColumn)
|
|
||||||
return Update((DynamicColumn)conditions);
|
|
||||||
|
|
||||||
var dict = conditions.ToDictionary();
|
|
||||||
var mapper = DynamicMapperCache.GetMapper(conditions.GetType());
|
|
||||||
|
|
||||||
foreach (var con in dict)
|
|
||||||
{
|
|
||||||
if (mapper.Ignored.Contains(con.Key))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
string colName = mapper != null ? mapper.PropertyMap.TryGetValue(con.Key) ?? con.Key : con.Key;
|
|
||||||
var col = Schema.TryGetNullable(colName.ToLower());
|
|
||||||
|
|
||||||
if (!col.HasValue && SupportSchema)
|
|
||||||
throw new InvalidOperationException(string.Format("Column '{0}' not found in schema, can't use universal approach.", colName));
|
|
||||||
|
|
||||||
if (col.HasValue)
|
|
||||||
{
|
|
||||||
colName = col.Value.Name;
|
|
||||||
|
|
||||||
if (col.Value.IsKey)
|
|
||||||
{
|
|
||||||
Where(colName, con.Value);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Values(colName, con.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add update fields.</summary>
|
|
||||||
/// <param name="column">Update column and value.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public virtual DynamicUpdateQueryBuilder Values(DynamicColumn column)
|
|
||||||
{
|
|
||||||
if (ValueColumns.ContainsKey(column.ColumnName.ToLower()))
|
|
||||||
ValueColumns[column.ColumnName.ToLower()] = column;
|
|
||||||
else
|
|
||||||
ValueColumns.Add(column.ColumnName.ToLower(), column);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add update fields.</summary>
|
|
||||||
/// <param name="column">Update column.</param>
|
|
||||||
/// <param name="value">Update value.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public virtual DynamicUpdateQueryBuilder Values(string column, object value)
|
|
||||||
{
|
|
||||||
if (value is DynamicColumn)
|
|
||||||
{
|
|
||||||
var v = (DynamicColumn)value;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(v.ColumnName))
|
|
||||||
v.ColumnName = column;
|
|
||||||
|
|
||||||
return Values(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ValueColumns.ContainsKey(column.ToLower()))
|
|
||||||
ValueColumns[column.ToLower()].Value = value;
|
|
||||||
else
|
|
||||||
ValueColumns.Add(column.ToLower(), new DynamicColumn
|
|
||||||
{
|
|
||||||
ColumnName = column,
|
|
||||||
Value = value
|
|
||||||
});
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Add update fields.</summary>
|
|
||||||
/// <param name="values">Set update value as properties and values of an object.</param>
|
|
||||||
/// <returns>Builder instance.</returns>
|
|
||||||
public virtual DynamicUpdateQueryBuilder Values(object values)
|
|
||||||
{
|
|
||||||
if (values is DynamicColumn)
|
|
||||||
return Values((DynamicColumn)values);
|
|
||||||
|
|
||||||
var dict = values.ToDictionary();
|
|
||||||
var mapper = DynamicMapperCache.GetMapper(values.GetType());
|
|
||||||
|
|
||||||
if (mapper != null)
|
|
||||||
{
|
|
||||||
foreach (var con in dict)
|
|
||||||
if (!mapper.Ignored.Contains(con.Key))
|
|
||||||
Values(mapper.PropertyMap.TryGetValue(con.Key) ?? con.Key, con.Value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
foreach (var con in dict)
|
|
||||||
Values(con.Key, con.Value);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Fill command with query.</summary>
|
|
||||||
/// <param name="command">Command to fill.</param>
|
|
||||||
/// <returns>Filled instance of <see cref="IDbCommand"/>.</returns>
|
|
||||||
public override IDbCommand FillCommand(IDbCommand command)
|
|
||||||
{
|
|
||||||
if (ValueColumns.Count == 0)
|
|
||||||
throw new InvalidOperationException("Update query should contain columns to change.");
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
var db = DynamicTable.Database;
|
|
||||||
|
|
||||||
sb.Append("UPDATE ");
|
|
||||||
db.DecorateName(sb, TableName);
|
|
||||||
sb.Append(" SET ");
|
|
||||||
|
|
||||||
bool first = true;
|
|
||||||
|
|
||||||
foreach (var v in ValueColumns)
|
|
||||||
{
|
|
||||||
int pos = command.Parameters.Count;
|
|
||||||
|
|
||||||
if (!first)
|
|
||||||
sb.Append(", ");
|
|
||||||
|
|
||||||
db.DecorateName(sb, v.Value.ColumnName);
|
|
||||||
sb.Append(" = ");
|
|
||||||
db.GetParameterName(sb, pos);
|
|
||||||
|
|
||||||
command.AddParameter(this, v.Value);
|
|
||||||
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FillWhere(command, sb);
|
|
||||||
|
|
||||||
return command.SetCommand(sb.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Execute this builder.</summary>
|
|
||||||
/// <returns>Number of affected rows.</returns>
|
|
||||||
public override dynamic Execute()
|
|
||||||
{
|
|
||||||
return DynamicTable.Execute(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
78
DynamORM/Builders/IDynamicDeleteQueryBuilder.cs
Normal file
78
DynamORM/Builders/IDynamicDeleteQueryBuilder.cs
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
namespace DynamORM.Builders
|
||||||
|
{
|
||||||
|
/// <summary>Dynamic delete query builder interface.</summary>
|
||||||
|
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
||||||
|
public interface IDynamicDeleteQueryBuilder : IDynamicQueryBuilder
|
||||||
|
{
|
||||||
|
/// <summary>Execute this builder.</summary>
|
||||||
|
/// <returns>Result of an execution..</returns>
|
||||||
|
int Execute();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds to the 'Where' clause the contents obtained from parsing the dynamic lambda expression given. The condition
|
||||||
|
/// is parsed to the appropriate syntax, where the specific customs virtual methods supported by the parser are used
|
||||||
|
/// as needed.
|
||||||
|
/// <para>- If several Where() methods are chained their contents are, by default, concatenated with an 'AND' operator.</para>
|
||||||
|
/// <para>- The 'And()' and 'Or()' virtual method can be used to concatenate with an 'OR' or an 'AND' operator, as in:
|
||||||
|
/// 'Where( x => x.Or( condition ) )'.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="func">The specification.</param>
|
||||||
|
/// <returns>This instance to permit chaining.</returns>
|
||||||
|
IDynamicDeleteQueryBuilder Where(Func<dynamic, object> func);
|
||||||
|
|
||||||
|
/// <summary>Add where condition.</summary>
|
||||||
|
/// <param name="column">Condition column with operator and value.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicDeleteQueryBuilder Where(DynamicColumn column);
|
||||||
|
|
||||||
|
/// <summary>Add where condition.</summary>
|
||||||
|
/// <param name="column">Condition column.</param>
|
||||||
|
/// <param name="op">Condition operator.</param>
|
||||||
|
/// <param name="value">Condition value.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicDeleteQueryBuilder Where(string column, DynamicColumn.CompareOperator op, object value);
|
||||||
|
|
||||||
|
/// <summary>Add where condition.</summary>
|
||||||
|
/// <param name="column">Condition column.</param>
|
||||||
|
/// <param name="value">Condition value.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicDeleteQueryBuilder Where(string column, object value);
|
||||||
|
|
||||||
|
/// <summary>Add where condition.</summary>
|
||||||
|
/// <param name="conditions">Set conditions as properties and values of an object.</param>
|
||||||
|
/// <param name="schema">If <c>true</c> use schema to determine key columns and ignore those which
|
||||||
|
/// aren't keys.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicDeleteQueryBuilder Where(object conditions, bool schema = false);
|
||||||
|
}
|
||||||
|
}
|
||||||
67
DynamORM/Builders/IDynamicInsertQueryBuilder.cs
Normal file
67
DynamORM/Builders/IDynamicInsertQueryBuilder.cs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
namespace DynamORM.Builders
|
||||||
|
{
|
||||||
|
/// <summary>Dynamic insert query builder interface.</summary>
|
||||||
|
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
||||||
|
public interface IDynamicInsertQueryBuilder : IDynamicQueryBuilder
|
||||||
|
{
|
||||||
|
/// <summary>Execute this builder.</summary>
|
||||||
|
/// <returns>Result of an execution..</returns>
|
||||||
|
int Execute();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies the columns to insert using the dynamic lambda expressions given. Each expression correspond to one
|
||||||
|
/// column, and can:
|
||||||
|
/// <para>- Resolve to a string, in this case a '=' must appear in the string.</para>
|
||||||
|
/// <para>- Resolve to a expression with the form: 'x => x.Column = Value'.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="func">The specifications.</param>
|
||||||
|
/// <returns>This instance to permit chaining.</returns>
|
||||||
|
IDynamicInsertQueryBuilder Insert(params Func<dynamic, object>[] func);
|
||||||
|
|
||||||
|
/// <summary>Add insert fields.</summary>
|
||||||
|
/// <param name="column">Insert column and value.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicInsertQueryBuilder Insert(DynamicColumn column);
|
||||||
|
|
||||||
|
/// <summary>Add insert fields.</summary>
|
||||||
|
/// <param name="column">Insert column.</param>
|
||||||
|
/// <param name="value">Insert value.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicInsertQueryBuilder Insert(string column, object value);
|
||||||
|
|
||||||
|
/// <summary>Add insert fields.</summary>
|
||||||
|
/// <param name="o">Set insert value as properties and values of an object.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicInsertQueryBuilder Insert(object o);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,19 +26,24 @@
|
|||||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
|
|
||||||
namespace DynamORM.Builders
|
namespace DynamORM.Builders
|
||||||
{
|
{
|
||||||
/// <summary>Base query builder interface.</summary>
|
/// <summary>Dynamic query builder base interface.</summary>
|
||||||
|
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
||||||
public interface IDynamicQueryBuilder
|
public interface IDynamicQueryBuilder
|
||||||
{
|
{
|
||||||
/// <summary>Gets <see cref="DynamicTable"/> instance.</summary>
|
/// <summary>Gets <see cref="DynamicDatabase"/> instance.</summary>
|
||||||
DynamicTable DynamicTable { get; }
|
DynamicDatabase Database { get; }
|
||||||
|
|
||||||
/// <summary>Gets table schema.</summary>
|
/// <summary>Gets tables information.</summary>
|
||||||
Dictionary<string, DynamicSchemaColumn> Schema { get; }
|
IList<ITableInfo> Tables { get; }
|
||||||
|
|
||||||
|
/// <summary>Gets the tables used in this builder.</summary>
|
||||||
|
IDictionary<string, IParameter> Parameters { get; }
|
||||||
|
|
||||||
/// <summary>Gets a value indicating whether database supports standard schema.</summary>
|
/// <summary>Gets a value indicating whether database supports standard schema.</summary>
|
||||||
bool SupportSchema { get; }
|
bool SupportSchema { get; }
|
||||||
@@ -48,8 +53,26 @@ namespace DynamORM.Builders
|
|||||||
/// <returns>Filled instance of <see cref="IDbCommand"/>.</returns>
|
/// <returns>Filled instance of <see cref="IDbCommand"/>.</returns>
|
||||||
IDbCommand FillCommand(IDbCommand command);
|
IDbCommand FillCommand(IDbCommand command);
|
||||||
|
|
||||||
/// <summary>Execute this builder.</summary>
|
/// <summary>
|
||||||
/// <returns>Result of an execution..</returns>
|
/// Generates the text this command will execute against the underlying database.
|
||||||
dynamic Execute();
|
/// </summary>
|
||||||
|
/// <returns>The text to execute against the underlying database.</returns>
|
||||||
|
/// <remarks>This method must be override by derived classes.</remarks>
|
||||||
|
string CommandText();
|
||||||
|
|
||||||
|
/// <summary>Creates sub query.</summary>
|
||||||
|
/// <returns>Sub query builder.</returns>
|
||||||
|
IDynamicSelectQueryBuilder SubQuery();
|
||||||
|
|
||||||
|
/// <summary>Adds to the 'From' clause of sub query the contents obtained by
|
||||||
|
/// parsing the dynamic lambda expressions given. The supported formats are:
|
||||||
|
/// <para>- Resolve to a string: 'x => "Table AS Alias', where the alias part is optional.</para>
|
||||||
|
/// <para>- Resolve to an expression: 'x => x.Table.As( x.Alias )', where the alias part is optional.</para>
|
||||||
|
/// <para>- Generic expression: 'x => x( expression ).As( x.Alias )', where the alias part is mandatory. In this
|
||||||
|
/// case the alias is not annotated.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="func">The specification.</param>
|
||||||
|
/// <returns>This instance to permit chaining.</returns>
|
||||||
|
IDynamicSelectQueryBuilder SubQuery(params Func<dynamic, object>[] func);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
195
DynamORM/Builders/IDynamicSelectQueryBuilder.cs
Normal file
195
DynamORM/Builders/IDynamicSelectQueryBuilder.cs
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace DynamORM.Builders
|
||||||
|
{
|
||||||
|
/// <summary>Dynamic select query builder interface.</summary>
|
||||||
|
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
||||||
|
public interface IDynamicSelectQueryBuilder : IDynamicQueryBuilder, IEnumerable<object>
|
||||||
|
{
|
||||||
|
/// <summary>Execute this builder.</summary>
|
||||||
|
/// <returns>Enumerator of objects expanded from query.</returns>
|
||||||
|
IEnumerable<dynamic> Execute();
|
||||||
|
|
||||||
|
/// <summary>Returns a single result.</summary>
|
||||||
|
/// <returns>Result of a query.</returns>
|
||||||
|
object Scalar();
|
||||||
|
|
||||||
|
#region From/Join
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds to the 'From' clause the contents obtained by parsing the dynamic lambda expressions given. The supported
|
||||||
|
/// formats are:
|
||||||
|
/// <para>- Resolve to a string: 'x => "Table AS Alias', where the alias part is optional.</para>
|
||||||
|
/// <para>- Resolve to an expression: 'x => x.Table.As( x.Alias )', where the alias part is optional.</para>
|
||||||
|
/// <para>- Generic expression: 'x => x( expression ).As( x.Alias )', where the alias part is mandatory. In this
|
||||||
|
/// case the alias is not annotated.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="func">The specification.</param>
|
||||||
|
/// <returns>This instance to permit chaining.</returns>
|
||||||
|
IDynamicSelectQueryBuilder From(params Func<dynamic, object>[] func);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds to the 'Join' clause the contents obtained by parsing the dynamic lambda expressions given. The supported
|
||||||
|
/// formats are:
|
||||||
|
/// <para>- Resolve to a string: 'x => "Table AS Alias ON Condition', where the alias part is optional.</para>
|
||||||
|
/// <para>- Resolve to an expression: 'x => x.Table.As( x.Alias ).On( condition )', where the alias part is optional.</para>
|
||||||
|
/// <para>- Generic expression: 'x => x( expression ).As( x.Alias ).On( condition )', where the alias part is mandatory.
|
||||||
|
/// In this case the alias is not annotated.</para>
|
||||||
|
/// The expression might be prepended by a method that, in this case, is used to specify the specific join type you
|
||||||
|
/// want to perform, as in: 'x => x.Left()...". Two considerations apply:
|
||||||
|
/// <para>- If a 'false' argument is used when no 'Join' part appears in its name, then no 'Join' suffix is added
|
||||||
|
/// with a space in between.</para>
|
||||||
|
/// <para>- If a 'false' argument is used when a 'Join' part does appear, then no split is performed to separate the
|
||||||
|
/// 'Join' part.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="func">The specification.</param>
|
||||||
|
/// <returns>This instance to permit chaining.</returns>
|
||||||
|
IDynamicSelectQueryBuilder Join(params Func<dynamic, object>[] func);
|
||||||
|
|
||||||
|
#endregion From/Join
|
||||||
|
|
||||||
|
#region Where
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds to the 'Where' clause the contents obtained from parsing the dynamic lambda expression given. The condition
|
||||||
|
/// is parsed to the appropriate syntax, where the specific customs virtual methods supported by the parser are used
|
||||||
|
/// as needed.
|
||||||
|
/// <para>- If several Where() methods are chained their contents are, by default, concatenated with an 'AND' operator.</para>
|
||||||
|
/// <para>- The 'And()' and 'Or()' virtual method can be used to concatenate with an 'OR' or an 'AND' operator, as in:
|
||||||
|
/// 'Where( x => x.Or( condition ) )'.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="func">The specification.</param>
|
||||||
|
/// <returns>This instance to permit chaining.</returns>
|
||||||
|
IDynamicSelectQueryBuilder Where(Func<dynamic, object> func);
|
||||||
|
|
||||||
|
/// <summary>Add where condition.</summary>
|
||||||
|
/// <param name="column">Condition column with operator and value.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicSelectQueryBuilder Where(DynamicColumn column);
|
||||||
|
|
||||||
|
/// <summary>Add where condition.</summary>
|
||||||
|
/// <param name="column">Condition column.</param>
|
||||||
|
/// <param name="op">Condition operator.</param>
|
||||||
|
/// <param name="value">Condition value.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicSelectQueryBuilder Where(string column, DynamicColumn.CompareOperator op, object value);
|
||||||
|
|
||||||
|
/// <summary>Add where condition.</summary>
|
||||||
|
/// <param name="column">Condition column.</param>
|
||||||
|
/// <param name="value">Condition value.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicSelectQueryBuilder Where(string column, object value);
|
||||||
|
|
||||||
|
/// <summary>Add where condition.</summary>
|
||||||
|
/// <param name="conditions">Set conditions as properties and values of an object.</param>
|
||||||
|
/// <param name="schema">If <c>true</c> use schema to determine key columns and ignore those which
|
||||||
|
/// aren't keys.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicSelectQueryBuilder Where(object conditions, bool schema = false);
|
||||||
|
|
||||||
|
#endregion Where
|
||||||
|
|
||||||
|
#region Select
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds to the 'Select' clause the contents obtained by parsing the dynamic lambda expressions given. The supported
|
||||||
|
/// formats are:
|
||||||
|
/// <para>- Resolve to a string: 'x => "Table.Column AS Alias', where the alias part is optional.</para>
|
||||||
|
/// <para>- Resolve to an expression: 'x => x.Table.Column.As( x.Alias )', where the alias part is optional.</para>
|
||||||
|
/// <para>- Select all columns from a table: 'x => x.Table.All()'.</para>
|
||||||
|
/// <para>- Generic expression: 'x => x( expression ).As( x.Alias )', where the alias part is mandatory. In this case
|
||||||
|
/// the alias is not annotated.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="func">The specification.</param>
|
||||||
|
/// <returns>This instance to permit chaining.</returns>
|
||||||
|
IDynamicSelectQueryBuilder Select(params Func<dynamic, object>[] func);
|
||||||
|
|
||||||
|
/// <summary>Add select columns.</summary>
|
||||||
|
/// <param name="columns">Columns to add to object.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicSelectQueryBuilder Select(params DynamicColumn[] columns);
|
||||||
|
|
||||||
|
/// <summary>Add select columns.</summary>
|
||||||
|
/// <param name="columns">Columns to add to object.</param>
|
||||||
|
/// <remarks>Column format consist of <c>Column Name</c>, <c>Alias</c> and
|
||||||
|
/// <c>Aggregate function</c> in this order separated by '<c>:</c>'.</remarks>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicSelectQueryBuilder Select(params string[] columns);
|
||||||
|
|
||||||
|
#endregion Select
|
||||||
|
|
||||||
|
#region GroupBy
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds to the 'Group By' clause the contents obtained from from parsing the dynamic lambda expression given.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="func">The specification.</param>
|
||||||
|
/// <returns>This instance to permit chaining.</returns>
|
||||||
|
IDynamicSelectQueryBuilder GroupBy(params Func<dynamic, object>[] func);
|
||||||
|
|
||||||
|
/// <summary>Add select columns.</summary>
|
||||||
|
/// <param name="columns">Columns to group by.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicSelectQueryBuilder GroupBy(params DynamicColumn[] columns);
|
||||||
|
|
||||||
|
/// <summary>Add select columns.</summary>
|
||||||
|
/// <param name="columns">Columns to group by.</param>
|
||||||
|
/// <remarks>Column format consist of <c>Column Name</c> and
|
||||||
|
/// <c>Alias</c> in this order separated by '<c>:</c>'.</remarks>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicSelectQueryBuilder GroupBy(params string[] columns);
|
||||||
|
|
||||||
|
#endregion GroupBy
|
||||||
|
|
||||||
|
#region OrderBy
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds to the 'Order By' clause the contents obtained from from parsing the dynamic lambda expression given. It
|
||||||
|
/// accepts a multipart column specification followed by an optional <code>Ascending()</code> or <code>Descending()</code> virtual methods
|
||||||
|
/// to specify the direction. If no virtual method is used, the default is ascending order. You can also use the
|
||||||
|
/// shorter versions <code>Asc()</code> and <code>Desc()</code>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="func">The specification.</param>
|
||||||
|
/// <returns>This instance to permit chaining.</returns>
|
||||||
|
IDynamicSelectQueryBuilder OrderBy(params Func<dynamic, object>[] func);
|
||||||
|
|
||||||
|
/// <summary>Add select columns.</summary>
|
||||||
|
/// <param name="columns">Columns to order by.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicSelectQueryBuilder OrderBy(params DynamicColumn[] columns);
|
||||||
|
|
||||||
|
/// <summary>Add select columns.</summary>
|
||||||
|
/// <param name="columns">Columns to order by.</param>
|
||||||
|
/// <remarks>Column format consist of <c>Column Name</c> and
|
||||||
|
/// <c>Alias</c> in this order separated by '<c>:</c>'.</remarks>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicSelectQueryBuilder OrderBy(params string[] columns);
|
||||||
|
|
||||||
|
#endregion OrderBy
|
||||||
|
|
||||||
|
#region Top/Limit/Offset/Distinct
|
||||||
|
|
||||||
|
/// <summary>Set top if database support it.</summary>
|
||||||
|
/// <param name="top">How many objects select.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicSelectQueryBuilder Top(int? top);
|
||||||
|
|
||||||
|
/// <summary>Set top if database support it.</summary>
|
||||||
|
/// <param name="limit">How many objects select.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicSelectQueryBuilder Limit(int? limit);
|
||||||
|
|
||||||
|
/// <summary>Set top if database support it.</summary>
|
||||||
|
/// <param name="offset">How many objects skip selecting.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicSelectQueryBuilder Offset(int? offset);
|
||||||
|
|
||||||
|
/// <summary>Set distinct mode.</summary>
|
||||||
|
/// <param name="distinct">Distinct mode.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicSelectQueryBuilder Distinct(bool distinct = true);
|
||||||
|
|
||||||
|
#endregion Top/Limit/Offset/Distinct
|
||||||
|
}
|
||||||
|
}
|
||||||
132
DynamORM/Builders/IDynamicUpdateQueryBuilder.cs
Normal file
132
DynamORM/Builders/IDynamicUpdateQueryBuilder.cs
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
namespace DynamORM.Builders
|
||||||
|
{
|
||||||
|
/// <summary>Dynamic update query builder interface.</summary>
|
||||||
|
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
||||||
|
public interface IDynamicUpdateQueryBuilder : IDynamicQueryBuilder
|
||||||
|
{
|
||||||
|
/// <summary>Execute this builder.</summary>
|
||||||
|
/// <returns>Result of an execution..</returns>
|
||||||
|
int Execute();
|
||||||
|
|
||||||
|
#region Update
|
||||||
|
|
||||||
|
/// <summary>Add update value or where condition using schema.</summary>
|
||||||
|
/// <param name="column">Update or where column name and value.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicUpdateQueryBuilder Update(DynamicColumn column);
|
||||||
|
|
||||||
|
/// <summary>Add update value or where condition using schema.</summary>
|
||||||
|
/// <param name="column">Update or where column name.</param>
|
||||||
|
/// <param name="value">Column value.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicUpdateQueryBuilder Update(string column, object value);
|
||||||
|
|
||||||
|
/// <summary>Add update values and where condition columns using schema.</summary>
|
||||||
|
/// <param name="conditions">Set values or conditions as properties and values of an object.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicUpdateQueryBuilder Update(object conditions);
|
||||||
|
|
||||||
|
#endregion Update
|
||||||
|
|
||||||
|
#region Values
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies the columns to update using the dynamic lambda expressions given. Each expression correspond to one
|
||||||
|
/// column, and can:
|
||||||
|
/// <para>- Resolve to a string, in this case a '=' must appear in the string.</para>
|
||||||
|
/// <para>- Resolve to a expression with the form: 'x => x.Column = Value'.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="func">The specifications.</param>
|
||||||
|
/// <returns>This instance to permit chaining.</returns>
|
||||||
|
IDynamicUpdateQueryBuilder Values(params Func<dynamic, object>[] func);
|
||||||
|
|
||||||
|
/// <summary>Add insert fields.</summary>
|
||||||
|
/// <param name="column">Insert column and value.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicUpdateQueryBuilder Values(DynamicColumn column);
|
||||||
|
|
||||||
|
/// <summary>Add insert fields.</summary>
|
||||||
|
/// <param name="column">Insert column.</param>
|
||||||
|
/// <param name="value">Insert value.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicUpdateQueryBuilder Values(string column, object value);
|
||||||
|
|
||||||
|
/// <summary>Add insert fields.</summary>
|
||||||
|
/// <param name="o">Set insert value as properties and values of an object.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicUpdateQueryBuilder Values(object o);
|
||||||
|
|
||||||
|
#endregion Values
|
||||||
|
|
||||||
|
#region Where
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds to the 'Where' clause the contents obtained from parsing the dynamic lambda expression given. The condition
|
||||||
|
/// is parsed to the appropriate syntax, where the specific customs virtual methods supported by the parser are used
|
||||||
|
/// as needed.
|
||||||
|
/// <para>- If several Where() methods are chained their contents are, by default, concatenated with an 'AND' operator.</para>
|
||||||
|
/// <para>- The 'And()' and 'Or()' virtual method can be used to concatenate with an 'OR' or an 'AND' operator, as in:
|
||||||
|
/// 'Where( x => x.Or( condition ) )'.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="func">The specification.</param>
|
||||||
|
/// <returns>This instance to permit chaining.</returns>
|
||||||
|
IDynamicUpdateQueryBuilder Where(Func<dynamic, object> func);
|
||||||
|
|
||||||
|
/// <summary>Add where condition.</summary>
|
||||||
|
/// <param name="column">Condition column with operator and value.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicUpdateQueryBuilder Where(DynamicColumn column);
|
||||||
|
|
||||||
|
/// <summary>Add where condition.</summary>
|
||||||
|
/// <param name="column">Condition column.</param>
|
||||||
|
/// <param name="op">Condition operator.</param>
|
||||||
|
/// <param name="value">Condition value.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicUpdateQueryBuilder Where(string column, DynamicColumn.CompareOperator op, object value);
|
||||||
|
|
||||||
|
/// <summary>Add where condition.</summary>
|
||||||
|
/// <param name="column">Condition column.</param>
|
||||||
|
/// <param name="value">Condition value.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicUpdateQueryBuilder Where(string column, object value);
|
||||||
|
|
||||||
|
/// <summary>Add where condition.</summary>
|
||||||
|
/// <param name="conditions">Set conditions as properties and values of an object.</param>
|
||||||
|
/// <param name="schema">If <c>true</c> use schema to determine key columns and ignore those which
|
||||||
|
/// aren't keys.</param>
|
||||||
|
/// <returns>Builder instance.</returns>
|
||||||
|
IDynamicUpdateQueryBuilder Where(object conditions, bool schema = false);
|
||||||
|
|
||||||
|
#endregion Where
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,41 +26,21 @@
|
|||||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Data;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace DynamORM.Builders
|
namespace DynamORM.Builders
|
||||||
{
|
{
|
||||||
/// <summary>Delete query builder.</summary>
|
/// <summary>Interface describing parameter info.</summary>
|
||||||
public class DynamicDeleteQueryBuilder : DynamicQueryBuilder<DynamicDeleteQueryBuilder>
|
public interface IParameter
|
||||||
{
|
{
|
||||||
/// <summary>Initializes a new instance of the <see cref="DynamicDeleteQueryBuilder"/> class.</summary>
|
/// <summary>Gets the parameter temporary name.</summary>
|
||||||
/// <param name="table">Parent dynamic table.</param>
|
string Name { get; }
|
||||||
public DynamicDeleteQueryBuilder(DynamicTable table)
|
|
||||||
: base(table)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Fill command with query.</summary>
|
/// <summary>Gets or sets the parameter value.</summary>
|
||||||
/// <param name="command">Command to fill.</param>
|
object Value { get; set; }
|
||||||
/// <returns>Filled instance of <see cref="IDbCommand"/>.</returns>
|
|
||||||
public override IDbCommand FillCommand(IDbCommand command)
|
|
||||||
{
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
|
|
||||||
sb.Append("DELETE FROM ");
|
/// <summary>Gets or sets a value indicating whether this <see cref="Parameter"/> is virtual.</summary>
|
||||||
DynamicTable.Database.DecorateName(sb, TableName);
|
bool Virtual { get; set; }
|
||||||
|
|
||||||
FillWhere(command, sb);
|
/// <summary>Gets the parameter schema information.</summary>
|
||||||
|
DynamicSchemaColumn? Schema { get; }
|
||||||
return command.SetCommand(sb.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Execute this builder.</summary>
|
|
||||||
/// <returns>Number of affected rows.</returns>
|
|
||||||
public override dynamic Execute()
|
|
||||||
{
|
|
||||||
return DynamicTable.Execute(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
26
DynamORM/Builders/ITableInfo.cs
Normal file
26
DynamORM/Builders/ITableInfo.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// <copyright file="ITableInfo.cs" company="Microsoft">
|
||||||
|
// TODO: Update copyright text.
|
||||||
|
// </copyright>
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace DynamORM.Builders
|
||||||
|
{
|
||||||
|
/// <summary>Interface describing table information.</summary>
|
||||||
|
public interface ITableInfo
|
||||||
|
{
|
||||||
|
/// <summary>Gets table owner name.</summary>
|
||||||
|
string Owner { get; }
|
||||||
|
|
||||||
|
/// <summary>Gets table name.</summary>
|
||||||
|
string Name { get; }
|
||||||
|
|
||||||
|
/// <summary>Gets table alias.</summary>
|
||||||
|
string Alias { get; }
|
||||||
|
|
||||||
|
/// <summary>Gets table schema.</summary>
|
||||||
|
Dictionary<string, DynamicSchemaColumn> Schema { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
@@ -45,12 +45,21 @@
|
|||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Builders\DynamicDeleteQueryBuilder.cs" />
|
<Compile Include="Builders\IDynamicInsertQueryBuilder.cs" />
|
||||||
<Compile Include="Builders\DynamicInsertQueryBuilder.cs" />
|
<Compile Include="Builders\IDynamicSelectQueryBuilder.cs" />
|
||||||
<Compile Include="Builders\DynamicQueryBuilder.cs" />
|
<Compile Include="Builders\IDynamicUpdateQueryBuilder.cs" />
|
||||||
<Compile Include="Builders\DynamicSelectQueryBuilder.cs" />
|
<Compile Include="Builders\Implementation\DynamicDeleteQueryBuilder.cs" />
|
||||||
<Compile Include="Builders\DynamicUpdateQueryBuilder.cs" />
|
<Compile Include="Builders\Implementation\DynamicInsertQueryBuilder.cs" />
|
||||||
|
<Compile Include="Builders\Implementation\DynamicModifyBuilder.cs" />
|
||||||
|
<Compile Include="Builders\Implementation\DynamicQueryBuilder.cs" />
|
||||||
|
<Compile Include="Builders\Extensions\DynamicModifyBuilderExtensions.cs" />
|
||||||
|
<Compile Include="Builders\Extensions\DynamicWhereQueryExtensions.cs" />
|
||||||
|
<Compile Include="Builders\Implementation\DynamicSelectQueryBuilder.cs" />
|
||||||
|
<Compile Include="Builders\Implementation\DynamicUpdateQueryBuilder.cs" />
|
||||||
|
<Compile Include="Builders\IDynamicDeleteQueryBuilder.cs" />
|
||||||
<Compile Include="Builders\IDynamicQueryBuilder.cs" />
|
<Compile Include="Builders\IDynamicQueryBuilder.cs" />
|
||||||
|
<Compile Include="Builders\IParameter.cs" />
|
||||||
|
<Compile Include="Builders\ITableInfo.cs" />
|
||||||
<Compile Include="DynamicColumn.cs" />
|
<Compile Include="DynamicColumn.cs" />
|
||||||
<Compile Include="DynamicCommand.cs" />
|
<Compile Include="DynamicCommand.cs" />
|
||||||
<Compile Include="DynamicConnection.cs" />
|
<Compile Include="DynamicConnection.cs" />
|
||||||
@@ -61,7 +70,11 @@
|
|||||||
<Compile Include="DynamicTable.cs" />
|
<Compile Include="DynamicTable.cs" />
|
||||||
<Compile Include="DynamicTransaction.cs" />
|
<Compile Include="DynamicTransaction.cs" />
|
||||||
<Compile Include="Helpers\CollectionComparer.cs" />
|
<Compile Include="Helpers\CollectionComparer.cs" />
|
||||||
|
<Compile Include="Helpers\Dynamics\DynamicParser.cs" />
|
||||||
|
<Compile Include="Helpers\IExtendedDisposable.cs" />
|
||||||
<Compile Include="Helpers\FrameworkTools.cs" />
|
<Compile Include="Helpers\FrameworkTools.cs" />
|
||||||
|
<Compile Include="Helpers\StringExtensions.cs" />
|
||||||
|
<Compile Include="Helpers\UnclassifiedExtensions.cs" />
|
||||||
<Compile Include="Mapper\ColumnAttribute.cs" />
|
<Compile Include="Mapper\ColumnAttribute.cs" />
|
||||||
<Compile Include="Mapper\DynamicMapperCache.cs" />
|
<Compile Include="Mapper\DynamicMapperCache.cs" />
|
||||||
<Compile Include="Mapper\DynamicPropertyInvoker.cs" />
|
<Compile Include="Mapper\DynamicPropertyInvoker.cs" />
|
||||||
|
|||||||
@@ -86,7 +86,9 @@ namespace DynamORM
|
|||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
/// <summary>Initializes a new instance of the <see cref="DynamicColumn" /> class.</summary>
|
/// <summary>Initializes a new instance of the <see cref="DynamicColumn" /> class.</summary>
|
||||||
public DynamicColumn() { }
|
public DynamicColumn()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Initializes a new instance of the <see cref="DynamicColumn" /> class.</summary>
|
/// <summary>Initializes a new instance of the <see cref="DynamicColumn" /> class.</summary>
|
||||||
/// <remarks>Constructor provided for easier object creation in queries.</remarks>
|
/// <remarks>Constructor provided for easier object creation in queries.</remarks>
|
||||||
@@ -341,7 +343,7 @@ namespace DynamORM
|
|||||||
/// <summary>Sets the begin block flag.</summary>
|
/// <summary>Sets the begin block flag.</summary>
|
||||||
/// <param name="begin">If set to <c>true</c> [begin].</param>
|
/// <param name="begin">If set to <c>true</c> [begin].</param>
|
||||||
/// <returns>Returns self.</returns>
|
/// <returns>Returns self.</returns>
|
||||||
public DynamicColumn SetBeginBlock(bool begin)
|
public DynamicColumn SetBeginBlock(bool begin = true)
|
||||||
{
|
{
|
||||||
BeginBlock = begin;
|
BeginBlock = begin;
|
||||||
return this;
|
return this;
|
||||||
@@ -350,7 +352,7 @@ namespace DynamORM
|
|||||||
/// <summary>Sets the end block flag.</summary>
|
/// <summary>Sets the end block flag.</summary>
|
||||||
/// <param name="end">If set to <c>true</c> [end].</param>
|
/// <param name="end">If set to <c>true</c> [end].</param>
|
||||||
/// <returns>Returns self.</returns>
|
/// <returns>Returns self.</returns>
|
||||||
public DynamicColumn SetEndBlock(bool end)
|
public DynamicColumn SetEndBlock(bool end = true)
|
||||||
{
|
{
|
||||||
EndBlock = end;
|
EndBlock = end;
|
||||||
return this;
|
return this;
|
||||||
@@ -359,7 +361,7 @@ namespace DynamORM
|
|||||||
/// <summary>Sets the or flag.</summary>
|
/// <summary>Sets the or flag.</summary>
|
||||||
/// <param name="or">If set to <c>true</c> [or].</param>
|
/// <param name="or">If set to <c>true</c> [or].</param>
|
||||||
/// <returns>Returns self.</returns>
|
/// <returns>Returns self.</returns>
|
||||||
public DynamicColumn SetOr(bool or)
|
public DynamicColumn SetOr(bool or = true)
|
||||||
{
|
{
|
||||||
Or = or;
|
Or = or;
|
||||||
return this;
|
return this;
|
||||||
@@ -436,6 +438,13 @@ namespace DynamORM
|
|||||||
|
|
||||||
#region ToSQL
|
#region ToSQL
|
||||||
|
|
||||||
|
internal string ToSQLSelectColumn(DynamicDatabase db)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
ToSQLSelectColumn(db, sb);
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
internal void ToSQLSelectColumn(DynamicDatabase db, StringBuilder sb)
|
internal void ToSQLSelectColumn(DynamicDatabase db, StringBuilder sb)
|
||||||
{
|
{
|
||||||
string column = ColumnName == "*" ? "*" : ColumnName;
|
string column = ColumnName == "*" ? "*" : ColumnName;
|
||||||
@@ -462,11 +471,25 @@ namespace DynamORM
|
|||||||
sb.AppendFormat(" AS {0}", alias);
|
sb.AppendFormat(" AS {0}", alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal string ToSQLGroupByColumn(DynamicDatabase db)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
ToSQLGroupByColumn(db, sb);
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
internal void ToSQLGroupByColumn(DynamicDatabase db, StringBuilder sb)
|
internal void ToSQLGroupByColumn(DynamicDatabase db, StringBuilder sb)
|
||||||
{
|
{
|
||||||
sb.Append(db.DecorateName(ColumnName));
|
sb.Append(db.DecorateName(ColumnName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal string ToSQLOrderByColumn(DynamicDatabase db)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
ToSQLOrderByColumn(db, sb);
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
internal void ToSQLOrderByColumn(DynamicDatabase db, StringBuilder sb)
|
internal void ToSQLOrderByColumn(DynamicDatabase db, StringBuilder sb)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(Alias))
|
if (!string.IsNullOrEmpty(Alias))
|
||||||
|
|||||||
@@ -101,7 +101,9 @@ namespace DynamORM
|
|||||||
/// Connection object.</summary>
|
/// Connection object.</summary>
|
||||||
/// <remarks>Does nothing. <see cref="DynamicDatabase"/> handles
|
/// <remarks>Does nothing. <see cref="DynamicDatabase"/> handles
|
||||||
/// opening connections.</remarks>
|
/// opening connections.</remarks>
|
||||||
public void Open() { }
|
public void Open()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Closes the connection to the database.</summary>
|
/// <summary>Closes the connection to the database.</summary>
|
||||||
/// <remarks>Does nothing. <see cref="DynamicDatabase"/> handles
|
/// <remarks>Does nothing. <see cref="DynamicDatabase"/> handles
|
||||||
@@ -109,7 +111,9 @@ namespace DynamORM
|
|||||||
/// It will close if this is multi connection configuration, otherwise
|
/// It will close if this is multi connection configuration, otherwise
|
||||||
/// it will stay open until <see cref="DynamicDatabase"/> is not
|
/// it will stay open until <see cref="DynamicDatabase"/> is not
|
||||||
/// disposed.</remarks>
|
/// disposed.</remarks>
|
||||||
public void Close() { }
|
public void Close()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Gets or sets the string used to open a database.</summary>
|
/// <summary>Gets or sets the string used to open a database.</summary>
|
||||||
/// <remarks>Changing connection string operation is not supported in <c>DynamORM</c>.
|
/// <remarks>Changing connection string operation is not supported in <c>DynamORM</c>.
|
||||||
|
|||||||
@@ -32,6 +32,9 @@ using System.Data;
|
|||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using DynamORM.Builders;
|
||||||
|
using DynamORM.Builders.Implementation;
|
||||||
|
using DynamORM.Helpers;
|
||||||
using DynamORM.Mapper;
|
using DynamORM.Mapper;
|
||||||
|
|
||||||
namespace DynamORM
|
namespace DynamORM
|
||||||
@@ -47,6 +50,8 @@ namespace DynamORM
|
|||||||
private bool _singleTransaction;
|
private bool _singleTransaction;
|
||||||
private string _leftDecorator = "\"";
|
private string _leftDecorator = "\"";
|
||||||
private string _rightDecorator = "\"";
|
private string _rightDecorator = "\"";
|
||||||
|
private bool _leftDecoratorIsInInvalidMembersChars = true;
|
||||||
|
private bool _rightDecoratorIsInInvalidMembersChars = true;
|
||||||
private string _parameterFormat = "@{0}";
|
private string _parameterFormat = "@{0}";
|
||||||
private int? _commandTimeout = null;
|
private int? _commandTimeout = null;
|
||||||
private long _poolStamp = 0;
|
private long _poolStamp = 0;
|
||||||
@@ -162,9 +167,10 @@ namespace DynamORM
|
|||||||
/// <param name="action">The action with instance 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="table">Table name.</param>
|
||||||
/// <param name="keys">Override keys in schema.</param>
|
/// <param name="keys">Override keys in schema.</param>
|
||||||
public void Table(Action<dynamic> action, string table = "", string[] keys = null)
|
/// <param name="owner">Owner of the table.</param>
|
||||||
|
public void Table(Action<dynamic> action, string table = "", string[] keys = null, string owner = "")
|
||||||
{
|
{
|
||||||
using (dynamic t = Table(table, keys))
|
using (dynamic t = Table(table, keys, owner))
|
||||||
action(t);
|
action(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,8 +187,9 @@ namespace DynamORM
|
|||||||
/// <summary>Gets dynamic table which is a simple ORM using dynamic objects.</summary>
|
/// <summary>Gets dynamic table which is a simple ORM using dynamic objects.</summary>
|
||||||
/// <param name="table">Table name.</param>
|
/// <param name="table">Table name.</param>
|
||||||
/// <param name="keys">Override keys in schema.</param>
|
/// <param name="keys">Override keys in schema.</param>
|
||||||
|
/// <param name="owner">Owner of the table.</param>
|
||||||
/// <returns>Instance of <see cref="DynamicTable"/>.</returns>
|
/// <returns>Instance of <see cref="DynamicTable"/>.</returns>
|
||||||
public dynamic Table(string table = "", string[] keys = null)
|
public dynamic Table(string table = "", string[] keys = null, string owner = "")
|
||||||
{
|
{
|
||||||
string key = string.Concat(
|
string key = string.Concat(
|
||||||
table == null ? string.Empty : table,
|
table == null ? string.Empty : table,
|
||||||
@@ -192,7 +199,7 @@ namespace DynamORM
|
|||||||
lock (SyncLock)
|
lock (SyncLock)
|
||||||
dt = TablesCache.TryGetValue(key) ??
|
dt = TablesCache.TryGetValue(key) ??
|
||||||
TablesCache.AddAndPassValue(key,
|
TablesCache.AddAndPassValue(key,
|
||||||
new DynamicTable(this, table, keys));
|
new DynamicTable(this, table, owner, keys));
|
||||||
|
|
||||||
return dt;
|
return dt;
|
||||||
}
|
}
|
||||||
@@ -227,18 +234,38 @@ namespace DynamORM
|
|||||||
|
|
||||||
#endregion Table
|
#endregion Table
|
||||||
|
|
||||||
|
#region From
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds to the 'From' clause the contents obtained by parsing the dynamic lambda expressions given. The supported
|
||||||
|
/// formats are:
|
||||||
|
/// <para>- Resolve to a string: 'x => "Table AS Alias', where the alias part is optional.</para>
|
||||||
|
/// <para>- Resolve to an expression: 'x => x.Table.As( x.Alias )', where the alias part is optional.</para>
|
||||||
|
/// <para>- Generic expression: 'x => x( expression ).As( x.Alias )', where the alias part is mandatory. In this
|
||||||
|
/// case the alias is not annotated.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="func">The specification.</param>
|
||||||
|
/// <returns>This instance to permit chaining.</returns>
|
||||||
|
public virtual IDynamicSelectQueryBuilder From(params Func<dynamic, object>[] func)
|
||||||
|
{
|
||||||
|
return new DynamicSelectQueryBuilder(this).From(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion From
|
||||||
|
|
||||||
#region Schema
|
#region Schema
|
||||||
|
|
||||||
/// <summary>Builds table cache if necessary 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>
|
/// <param name="table">Name of table for which build schema.</param>
|
||||||
|
/// <param name="owner">Owner of table for which build schema.</param>
|
||||||
/// <returns>Table schema.</returns>
|
/// <returns>Table schema.</returns>
|
||||||
public Dictionary<string, DynamicSchemaColumn> GetSchema(string table)
|
public Dictionary<string, DynamicSchemaColumn> GetSchema(string table, string owner = null)
|
||||||
{
|
{
|
||||||
Dictionary<string, DynamicSchemaColumn> schema = null;
|
Dictionary<string, DynamicSchemaColumn> schema = null;
|
||||||
|
|
||||||
lock (SyncLock)
|
lock (SyncLock)
|
||||||
schema = Schema.TryGetValue(table.ToLower()) ??
|
schema = Schema.TryGetValue(table.ToLower()) ??
|
||||||
BuildAndCacheSchema(table, null);
|
BuildAndCacheSchema(table, null, owner);
|
||||||
|
|
||||||
return schema;
|
return schema;
|
||||||
}
|
}
|
||||||
@@ -279,15 +306,18 @@ namespace DynamORM
|
|||||||
|
|
||||||
/// <summary>Get schema describing objects from reader.</summary>
|
/// <summary>Get schema describing objects from reader.</summary>
|
||||||
/// <param name="table">Table from which extract column info.</param>
|
/// <param name="table">Table from which extract column info.</param>
|
||||||
|
/// <param name="owner">Owner of table from which extract column info.</param>
|
||||||
/// <returns>List of <see cref="DynamicSchemaColumn"/> objects .
|
/// <returns>List of <see cref="DynamicSchemaColumn"/> objects .
|
||||||
/// If your database doesn't get those values in upper case (like most of the databases) you should override this method.</returns>
|
/// If your database doesn't get those values in upper case (like most of the databases) you should override this method.</returns>
|
||||||
protected virtual IEnumerable<DynamicSchemaColumn> ReadSchema(string table)
|
protected virtual IEnumerable<DynamicSchemaColumn> ReadSchema(string table, string owner)
|
||||||
{
|
{
|
||||||
using (var con = Open())
|
using (var con = Open())
|
||||||
using (var cmd = con.CreateCommand())
|
using (var cmd = con.CreateCommand())
|
||||||
{
|
{
|
||||||
using (var rdr = cmd
|
using (var rdr = cmd
|
||||||
.SetCommand(string.Format("SELECT * FROM {0} WHERE 1 = 0", DecorateName(table)))
|
.SetCommand(string.Format("SELECT * FROM {0}{1} WHERE 1 = 0",
|
||||||
|
!string.IsNullOrEmpty(owner) ? string.Format("{0}.", DecorateName(owner)) : string.Empty,
|
||||||
|
DecorateName(table)))
|
||||||
.ExecuteReader(CommandBehavior.SchemaOnly | CommandBehavior.KeyInfo))
|
.ExecuteReader(CommandBehavior.SchemaOnly | CommandBehavior.KeyInfo))
|
||||||
foreach (DataRow col in rdr.GetSchemaTable().Rows)
|
foreach (DataRow col in rdr.GetSchemaTable().Rows)
|
||||||
{
|
{
|
||||||
@@ -307,7 +337,7 @@ namespace DynamORM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Dictionary<string, DynamicSchemaColumn> BuildAndCacheSchema(string tableName, DynamicTypeMap mapper)
|
private Dictionary<string, DynamicSchemaColumn> BuildAndCacheSchema(string tableName, DynamicTypeMap mapper, string owner = null)
|
||||||
{
|
{
|
||||||
Dictionary<string, DynamicSchemaColumn> schema = null;
|
Dictionary<string, DynamicSchemaColumn> schema = null;
|
||||||
|
|
||||||
@@ -323,7 +353,7 @@ namespace DynamORM
|
|||||||
|
|
||||||
if (databaseSchemaSupport && !Schema.ContainsKey(tableName.ToLower()))
|
if (databaseSchemaSupport && !Schema.ContainsKey(tableName.ToLower()))
|
||||||
{
|
{
|
||||||
schema = ReadSchema(tableName)
|
schema = ReadSchema(tableName, owner)
|
||||||
.ToDictionary(k => k.Name.ToLower(), k => k);
|
.ToDictionary(k => k.Name.ToLower(), k => k);
|
||||||
|
|
||||||
Schema[tableName.ToLower()] = schema;
|
Schema[tableName.ToLower()] = schema;
|
||||||
@@ -406,10 +436,28 @@ namespace DynamORM
|
|||||||
#region Decorators
|
#region Decorators
|
||||||
|
|
||||||
/// <summary>Gets or sets left side decorator for database objects.</summary>
|
/// <summary>Gets or sets left side decorator for database objects.</summary>
|
||||||
public string LeftDecorator { get { return _leftDecorator; } set { _leftDecorator = value; } }
|
public string LeftDecorator
|
||||||
|
{
|
||||||
|
get { return _leftDecorator; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_leftDecorator = value;
|
||||||
|
_leftDecoratorIsInInvalidMembersChars =
|
||||||
|
_leftDecorator.Length == 1 && StringExtensions.InvalidMemberChars.Contains(_leftDecorator[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Gets or sets right side decorator for database objects.</summary>
|
/// <summary>Gets or sets right side decorator for database objects.</summary>
|
||||||
public string RightDecorator { get { return _rightDecorator; } set { _rightDecorator = value; } }
|
public string RightDecorator
|
||||||
|
{
|
||||||
|
get { return _rightDecorator; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_rightDecorator = value;
|
||||||
|
_rightDecoratorIsInInvalidMembersChars =
|
||||||
|
_rightDecorator.Length == 1 && StringExtensions.InvalidMemberChars.Contains(_rightDecorator[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Gets or sets parameter name format.</summary>
|
/// <summary>Gets or sets parameter name format.</summary>
|
||||||
public string ParameterFormat { get { return _parameterFormat; } set { _parameterFormat = value; } }
|
public string ParameterFormat { get { return _parameterFormat; } set { _parameterFormat = value; } }
|
||||||
@@ -422,6 +470,22 @@ namespace DynamORM
|
|||||||
return String.Concat(_leftDecorator, name, _rightDecorator);
|
return String.Concat(_leftDecorator, name, _rightDecorator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Strip string representing name of database object from decorators.</summary>
|
||||||
|
/// <param name="name">Decorated name of database object.</param>
|
||||||
|
/// <returns>Not decorated name of database object.</returns>
|
||||||
|
public string StripName(string name)
|
||||||
|
{
|
||||||
|
string res = name.Trim(StringExtensions.InvalidMemberChars);
|
||||||
|
|
||||||
|
if (!_leftDecoratorIsInInvalidMembersChars && res.StartsWith(_leftDecorator))
|
||||||
|
res = res.Substring(_leftDecorator.Length);
|
||||||
|
|
||||||
|
if (!_rightDecoratorIsInInvalidMembersChars && res.EndsWith(_rightDecorator))
|
||||||
|
res = res.Substring(0, res.Length - _rightDecorator.Length);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Decorate string representing name of database object.</summary>
|
/// <summary>Decorate string representing name of database object.</summary>
|
||||||
/// <param name="sb">String builder to which add decorated name.</param>
|
/// <param name="sb">String builder to which add decorated name.</param>
|
||||||
/// <param name="name">Name of database object.</param>
|
/// <param name="name">Name of database object.</param>
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ using System.Reflection;
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using DynamORM.Builders;
|
using DynamORM.Builders;
|
||||||
|
using DynamORM.Builders.Implementation;
|
||||||
|
using DynamORM.Helpers;
|
||||||
using DynamORM.Mapper;
|
using DynamORM.Mapper;
|
||||||
|
|
||||||
namespace DynamORM
|
namespace DynamORM
|
||||||
@@ -270,6 +272,52 @@ namespace DynamORM
|
|||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Extension for adding single parameter determining only type of object.</summary>
|
||||||
|
/// <param name="cmd">Command to handle.</param>
|
||||||
|
/// <param name="builder">Query builder containing schema.</param>
|
||||||
|
/// <param name="col">Column schema to use.</param>
|
||||||
|
/// <param name="value">Parameter value.</param>
|
||||||
|
/// <returns>Returns edited <see cref="System.Data.IDbCommand"/> instance.</returns>
|
||||||
|
public static IDbCommand AddParameter(this IDbCommand cmd, IDynamicQueryBuilder builder, DynamicSchemaColumn? col, object value)
|
||||||
|
{
|
||||||
|
var p = cmd.CreateParameter();
|
||||||
|
p.ParameterName = builder.Database.GetParameterName(cmd.Parameters.Count);
|
||||||
|
|
||||||
|
if (col.HasValue)
|
||||||
|
{
|
||||||
|
p.DbType = col.Value.Type;
|
||||||
|
|
||||||
|
if ((builder.Database.Options & DynamicDatabaseOptions.SupportSchema) == DynamicDatabaseOptions.SupportSchema)
|
||||||
|
{
|
||||||
|
p.Size = col.Value.Size;
|
||||||
|
p.Precision = col.Value.Precision;
|
||||||
|
p.Scale = col.Value.Scale;
|
||||||
|
|
||||||
|
// Quick fix - review that
|
||||||
|
// Quick fix 2 - use item.Schema in that case
|
||||||
|
if (p.Scale > p.Precision)
|
||||||
|
p.Scale = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Value = value == null ? DBNull.Value : value;
|
||||||
|
}
|
||||||
|
else if (value == null || value == DBNull.Value)
|
||||||
|
p.Value = DBNull.Value;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p.DbType = TypeMap.TryGetNullable(value.GetType()) ?? DbType.String;
|
||||||
|
|
||||||
|
if (p.DbType == DbType.String)
|
||||||
|
p.Size = value.ToString().Length > 4000 ? -1 : 4000;
|
||||||
|
|
||||||
|
p.Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Parameters.Add(p);
|
||||||
|
|
||||||
|
return cmd;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Extension for adding single parameter determining only type of object.</summary>
|
/// <summary>Extension for adding single parameter determining only type of object.</summary>
|
||||||
/// <param name="cmd">Command to handle.</param>
|
/// <param name="cmd">Command to handle.</param>
|
||||||
/// <param name="builder">Query builder containing schema.</param>
|
/// <param name="builder">Query builder containing schema.</param>
|
||||||
@@ -278,9 +326,13 @@ namespace DynamORM
|
|||||||
public static IDbCommand AddParameter(this IDbCommand cmd, IDynamicQueryBuilder builder, DynamicColumn item)
|
public static IDbCommand AddParameter(this IDbCommand cmd, IDynamicQueryBuilder builder, DynamicColumn item)
|
||||||
{
|
{
|
||||||
var p = cmd.CreateParameter();
|
var p = cmd.CreateParameter();
|
||||||
p.ParameterName = builder.DynamicTable.Database.GetParameterName(cmd.Parameters.Count);
|
p.ParameterName = builder.Database.GetParameterName(cmd.Parameters.Count);
|
||||||
|
|
||||||
var col = item.Schema ?? builder.Schema.TryGetNullable(item.ColumnName.ToLower());
|
var col = item.Schema ?? (builder as DynamicQueryBuilder)
|
||||||
|
.NullOr(b => b.GetColumnFromSchema(item.ColumnName),
|
||||||
|
builder.Tables.FirstOrDefault()
|
||||||
|
.NullOr(t => t.Schema
|
||||||
|
.NullOr(s => s.TryGetNullable(item.ColumnName.ToLower()), null), null));
|
||||||
|
|
||||||
if (col.HasValue)
|
if (col.HasValue)
|
||||||
{
|
{
|
||||||
@@ -910,6 +962,19 @@ namespace DynamORM
|
|||||||
typeof(IEnumerable<>).IsAssignableFrom(type.GetGenericTypeDefinition());
|
typeof(IEnumerable<>).IsAssignableFrom(type.GetGenericTypeDefinition());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Check if type implements IEnumerable<> interface.</summary>
|
||||||
|
/// <param name="type">Type to check.</param>
|
||||||
|
/// <returns>Returns <c>true</c> if it does.</returns>
|
||||||
|
public static bool IsNullableType(this Type type)
|
||||||
|
{
|
||||||
|
Type generic = type.IsGenericType ? type.GetGenericTypeDefinition() : null;
|
||||||
|
|
||||||
|
if (generic != null && generic.Equals(typeof(Nullable<>)) && type.IsClass)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Check if type is collection of any kind.</summary>
|
/// <summary>Check if type is collection of any kind.</summary>
|
||||||
/// <param name="type">Type to check.</param>
|
/// <param name="type">Type to check.</param>
|
||||||
/// <returns>Returns <c>true</c> if it is.</returns>
|
/// <returns>Returns <c>true</c> if it is.</returns>
|
||||||
@@ -1094,7 +1159,7 @@ namespace DynamORM
|
|||||||
/// <typeparam name="T">Type to parse to.</typeparam>
|
/// <typeparam name="T">Type to parse to.</typeparam>
|
||||||
/// <param name="value">Value to parse.</param>
|
/// <param name="value">Value to parse.</param>
|
||||||
/// <param name="handler">Handler of a try parse method.</param>
|
/// <param name="handler">Handler of a try parse method.</param>
|
||||||
/// <returns>Returns <c>true</c> if conversion was sucessfull.</returns>
|
/// <returns>Returns <c>true</c> if conversion was successful.</returns>
|
||||||
public static T? TryParse<T>(this string value, TryParseHandler<T> handler) where T : struct
|
public static T? TryParse<T>(this string value, TryParseHandler<T> handler) where T : struct
|
||||||
{
|
{
|
||||||
if (String.IsNullOrEmpty(value))
|
if (String.IsNullOrEmpty(value))
|
||||||
@@ -1113,7 +1178,7 @@ namespace DynamORM
|
|||||||
/// <param name="value">Value to parse.</param>
|
/// <param name="value">Value to parse.</param>
|
||||||
/// <param name="defaultValue">Default value of a result.</param>
|
/// <param name="defaultValue">Default value of a result.</param>
|
||||||
/// <param name="handler">Handler of a try parse method.</param>
|
/// <param name="handler">Handler of a try parse method.</param>
|
||||||
/// <returns>Returns <c>true</c> if conversion was sucessfull.</returns>
|
/// <returns>Returns <c>true</c> if conversion was successful.</returns>
|
||||||
public static T TryParseDefault<T>(this string value, T defaultValue, TryParseHandler<T> handler)
|
public static T TryParseDefault<T>(this string value, T defaultValue, TryParseHandler<T> handler)
|
||||||
{
|
{
|
||||||
if (String.IsNullOrEmpty(value))
|
if (String.IsNullOrEmpty(value))
|
||||||
@@ -1131,7 +1196,7 @@ namespace DynamORM
|
|||||||
/// <typeparam name="T">Type which implements this function.</typeparam>
|
/// <typeparam name="T">Type which implements this function.</typeparam>
|
||||||
/// <param name="value">Value to parse.</param>
|
/// <param name="value">Value to parse.</param>
|
||||||
/// <param name="result">Resulting value.</param>
|
/// <param name="result">Resulting value.</param>
|
||||||
/// <returns>Returns <c>true</c> if conversion was sucessfull.</returns>
|
/// <returns>Returns <c>true</c> if conversion was successful.</returns>
|
||||||
public delegate bool TryParseHandler<T>(string value, out T result);
|
public delegate bool TryParseHandler<T>(string value, out T result);
|
||||||
|
|
||||||
#endregion TryParse extensions
|
#endregion TryParse extensions
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ using System.Data;
|
|||||||
using System.Dynamic;
|
using System.Dynamic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using DynamORM.Builders;
|
using DynamORM.Builders;
|
||||||
|
using DynamORM.Builders.Extensions;
|
||||||
|
using DynamORM.Builders.Implementation;
|
||||||
using DynamORM.Helpers;
|
using DynamORM.Helpers;
|
||||||
using DynamORM.Mapper;
|
using DynamORM.Mapper;
|
||||||
|
|
||||||
@@ -211,6 +213,20 @@ namespace DynamORM
|
|||||||
/// <summary>Gets name of table.</summary>
|
/// <summary>Gets name of table.</summary>
|
||||||
public virtual string TableName { get; private set; }
|
public virtual string TableName { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>Gets name of owner.</summary>
|
||||||
|
public virtual string OwnerName { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>Gets full name of table containing owner and table name.</summary>
|
||||||
|
public virtual string FullName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return string.IsNullOrEmpty(OwnerName) ?
|
||||||
|
Database.DecorateName(TableName) :
|
||||||
|
string.Format("{0}.{1}", Database.DecorateName(OwnerName), Database.DecorateName(TableName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Gets table schema.</summary>
|
/// <summary>Gets table schema.</summary>
|
||||||
/// <remarks>If database doesn't support schema, only key columns are listed here.</remarks>
|
/// <remarks>If database doesn't support schema, only key columns are listed here.</remarks>
|
||||||
public virtual Dictionary<string, DynamicSchemaColumn> Schema { get; private set; }
|
public virtual Dictionary<string, DynamicSchemaColumn> Schema { get; private set; }
|
||||||
@@ -222,11 +238,13 @@ namespace DynamORM
|
|||||||
/// <summary>Initializes a new instance of the <see cref="DynamicTable" /> class.</summary>
|
/// <summary>Initializes a new instance of the <see cref="DynamicTable" /> class.</summary>
|
||||||
/// <param name="database">Database and connection management.</param>
|
/// <param name="database">Database and connection management.</param>
|
||||||
/// <param name="table">Table name.</param>
|
/// <param name="table">Table name.</param>
|
||||||
|
/// <param name="owner">Owner of the table.</param>
|
||||||
/// <param name="keys">Override keys in schema.</param>
|
/// <param name="keys">Override keys in schema.</param>
|
||||||
public DynamicTable(DynamicDatabase database, string table = "", string[] keys = null)
|
public DynamicTable(DynamicDatabase database, string table = "", string owner = "", string[] keys = null)
|
||||||
{
|
{
|
||||||
Database = database;
|
Database = database;
|
||||||
TableName = table;
|
TableName = Database.StripName(table);
|
||||||
|
OwnerName = Database.StripName(owner);
|
||||||
TableType = null;
|
TableType = null;
|
||||||
|
|
||||||
BuildAndCacheSchema(keys);
|
BuildAndCacheSchema(keys);
|
||||||
@@ -350,9 +368,14 @@ namespace DynamORM
|
|||||||
|
|
||||||
/// <summary>Create new <see cref="DynamicSelectQueryBuilder"/>.</summary>
|
/// <summary>Create new <see cref="DynamicSelectQueryBuilder"/>.</summary>
|
||||||
/// <returns>New <see cref="DynamicSelectQueryBuilder"/> instance.</returns>
|
/// <returns>New <see cref="DynamicSelectQueryBuilder"/> instance.</returns>
|
||||||
public virtual DynamicSelectQueryBuilder Query()
|
public virtual IDynamicSelectQueryBuilder Query()
|
||||||
{
|
{
|
||||||
return new DynamicSelectQueryBuilder(this);
|
var builder = new DynamicSelectQueryBuilder(this.Database);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(this.TableName))
|
||||||
|
builder.From(x => this.TableName);
|
||||||
|
|
||||||
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Returns a single result.</summary>
|
/// <summary>Returns a single result.</summary>
|
||||||
@@ -469,9 +492,9 @@ namespace DynamORM
|
|||||||
|
|
||||||
/// <summary>Create new <see cref="DynamicInsertQueryBuilder"/>.</summary>
|
/// <summary>Create new <see cref="DynamicInsertQueryBuilder"/>.</summary>
|
||||||
/// <returns>New <see cref="DynamicInsertQueryBuilder"/> instance.</returns>
|
/// <returns>New <see cref="DynamicInsertQueryBuilder"/> instance.</returns>
|
||||||
public DynamicInsertQueryBuilder Insert()
|
public IDynamicInsertQueryBuilder Insert()
|
||||||
{
|
{
|
||||||
return new DynamicInsertQueryBuilder(this);
|
return new DynamicInsertQueryBuilder(this.Database, this.TableName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Adds a record to the database. You can pass in an Anonymous object, an <see cref="ExpandoObject"/>,
|
/// <summary>Adds a record to the database. You can pass in an Anonymous object, an <see cref="ExpandoObject"/>,
|
||||||
@@ -492,9 +515,9 @@ namespace DynamORM
|
|||||||
|
|
||||||
/// <summary>Create new <see cref="DynamicUpdateQueryBuilder"/>.</summary>
|
/// <summary>Create new <see cref="DynamicUpdateQueryBuilder"/>.</summary>
|
||||||
/// <returns>New <see cref="DynamicUpdateQueryBuilder"/> instance.</returns>
|
/// <returns>New <see cref="DynamicUpdateQueryBuilder"/> instance.</returns>
|
||||||
public DynamicUpdateQueryBuilder Update()
|
public IDynamicUpdateQueryBuilder Update()
|
||||||
{
|
{
|
||||||
return new DynamicUpdateQueryBuilder(this);
|
return new DynamicUpdateQueryBuilder(this.Database, this.TableName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Updates a record in the database. You can pass in an Anonymous object, an ExpandoObject,
|
/// <summary>Updates a record in the database. You can pass in an Anonymous object, an ExpandoObject,
|
||||||
@@ -530,9 +553,9 @@ namespace DynamORM
|
|||||||
|
|
||||||
/// <summary>Create new <see cref="DynamicDeleteQueryBuilder"/>.</summary>
|
/// <summary>Create new <see cref="DynamicDeleteQueryBuilder"/>.</summary>
|
||||||
/// <returns>New <see cref="DynamicDeleteQueryBuilder"/> instance.</returns>
|
/// <returns>New <see cref="DynamicDeleteQueryBuilder"/> instance.</returns>
|
||||||
public DynamicDeleteQueryBuilder Delete()
|
public IDynamicDeleteQueryBuilder Delete()
|
||||||
{
|
{
|
||||||
return new DynamicDeleteQueryBuilder(this);
|
return new DynamicDeleteQueryBuilder(this.Database, this.TableName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Removes a record from the database. You can pass in an Anonymous object, an <see cref="ExpandoObject"/>,
|
/// <summary>Removes a record from the database. You can pass in an Anonymous object, an <see cref="ExpandoObject"/>,
|
||||||
@@ -600,11 +623,14 @@ namespace DynamORM
|
|||||||
|
|
||||||
private object DynamicInsert(object[] args, CallInfo info, IList<Type> types)
|
private object DynamicInsert(object[] args, CallInfo info, IList<Type> types)
|
||||||
{
|
{
|
||||||
var builder = new DynamicInsertQueryBuilder(this);
|
var builder = new DynamicInsertQueryBuilder(this.Database);
|
||||||
|
|
||||||
if (types != null && types.Count == 1)
|
if (types != null && types.Count == 1)
|
||||||
HandleTypeArgument<DynamicInsertQueryBuilder>(null, info, ref types, builder, 0);
|
HandleTypeArgument<DynamicInsertQueryBuilder>(null, info, ref types, builder, 0);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(this.TableName) && builder.Tables.Count == 0)
|
||||||
|
builder.Table(this.TableName, this.Schema);
|
||||||
|
|
||||||
// loop the named args - see if we have order, columns and constraints
|
// loop the named args - see if we have order, columns and constraints
|
||||||
if (info.ArgumentNames.Count > 0)
|
if (info.ArgumentNames.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -643,11 +669,14 @@ namespace DynamORM
|
|||||||
|
|
||||||
private object DynamicUpdate(object[] args, CallInfo info, IList<Type> types)
|
private object DynamicUpdate(object[] args, CallInfo info, IList<Type> types)
|
||||||
{
|
{
|
||||||
var builder = new DynamicUpdateQueryBuilder(this);
|
var builder = new DynamicUpdateQueryBuilder(this.Database);
|
||||||
|
|
||||||
if (types != null && types.Count == 1)
|
if (types != null && types.Count == 1)
|
||||||
HandleTypeArgument<DynamicUpdateQueryBuilder>(null, info, ref types, builder, 0);
|
HandleTypeArgument<DynamicUpdateQueryBuilder>(null, info, ref types, builder, 0);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(this.TableName) && builder.Tables.Count == 0)
|
||||||
|
builder.Table(this.TableName, this.Schema);
|
||||||
|
|
||||||
// loop the named args - see if we have order, columns and constraints
|
// loop the named args - see if we have order, columns and constraints
|
||||||
if (info.ArgumentNames.Count > 0)
|
if (info.ArgumentNames.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -694,11 +723,14 @@ namespace DynamORM
|
|||||||
|
|
||||||
private object DynamicDelete(object[] args, CallInfo info, IList<Type> types)
|
private object DynamicDelete(object[] args, CallInfo info, IList<Type> types)
|
||||||
{
|
{
|
||||||
var builder = new DynamicDeleteQueryBuilder(this);
|
var builder = new DynamicDeleteQueryBuilder(this.Database);
|
||||||
|
|
||||||
if (types != null && types.Count == 1)
|
if (types != null && types.Count == 1)
|
||||||
HandleTypeArgument<DynamicDeleteQueryBuilder>(null, info, ref types, builder, 0);
|
HandleTypeArgument<DynamicDeleteQueryBuilder>(null, info, ref types, builder, 0);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(this.TableName) && builder.Tables.Count == 0)
|
||||||
|
builder.Table(this.TableName, this.Schema);
|
||||||
|
|
||||||
// loop the named args - see if we have order, columns and constraints
|
// loop the named args - see if we have order, columns and constraints
|
||||||
if (info.ArgumentNames.Count > 0)
|
if (info.ArgumentNames.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -742,11 +774,14 @@ namespace DynamORM
|
|||||||
private object DynamicQuery(object[] args, CallInfo info, string op, IList<Type> types)
|
private object DynamicQuery(object[] args, CallInfo info, string op, IList<Type> types)
|
||||||
{
|
{
|
||||||
object result;
|
object result;
|
||||||
var builder = new DynamicSelectQueryBuilder(this);
|
var builder = new DynamicSelectQueryBuilder(this.Database);
|
||||||
|
|
||||||
if (types != null && types.Count == 1)
|
if (types != null && types.Count == 1)
|
||||||
HandleTypeArgument<DynamicSelectQueryBuilder>(null, info, ref types, builder, 0);
|
HandleTypeArgument<DynamicSelectQueryBuilder>(null, info, ref types, builder, 0);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(this.TableName) && builder.Tables.Count == 0)
|
||||||
|
builder.From(x => this.TableName);
|
||||||
|
|
||||||
// loop the named args - see if we have order, columns and constraints
|
// loop the named args - see if we have order, columns and constraints
|
||||||
if (info.ArgumentNames.Count > 0)
|
if (info.ArgumentNames.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -782,15 +817,32 @@ namespace DynamORM
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case "columns":
|
case "columns":
|
||||||
if (args[i] is string)
|
{
|
||||||
builder.Select(((string)args[i]).Split(','));
|
var agregate = (op == "Sum" || op == "Max" || op == "Min" || op == "Avg" || op == "Count") ?
|
||||||
else if (args[i] is string[])
|
op.ToUpper() : null;
|
||||||
builder.Select(args[i] as string);
|
|
||||||
else if (args[i] is DynamicColumn[])
|
if (args[i] is string || args[i] is string[])
|
||||||
builder.Select((DynamicColumn[])args[i]);
|
builder.Select((args[i] as String).NullOr(s => s.Split(','), args[i] as String[])
|
||||||
else if (args[i] is DynamicColumn)
|
.Select(c =>
|
||||||
builder.Select((DynamicColumn)args[i]);
|
{
|
||||||
else goto default;
|
var col = DynamicColumn.ParseSelectColumn(c);
|
||||||
|
if (string.IsNullOrEmpty(col.Aggregate))
|
||||||
|
col.Aggregate = agregate;
|
||||||
|
|
||||||
|
return col;
|
||||||
|
}).ToArray());
|
||||||
|
else if (args[i] is DynamicColumn || args[i] is DynamicColumn[])
|
||||||
|
builder.Select((args[i] as DynamicColumn).NullOr(c => new DynamicColumn[] { c }, args[i] as DynamicColumn[])
|
||||||
|
.Select(c =>
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(c.Aggregate))
|
||||||
|
c.Aggregate = agregate;
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}).ToArray());
|
||||||
|
else goto default;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "where":
|
case "where":
|
||||||
@@ -799,7 +851,7 @@ namespace DynamORM
|
|||||||
|
|
||||||
case "table":
|
case "table":
|
||||||
if (args[i] is string)
|
if (args[i] is string)
|
||||||
builder.Table(args[i].ToString());
|
builder.From(x => args[i].ToString());
|
||||||
else goto default;
|
else goto default;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -816,14 +868,9 @@ namespace DynamORM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op == "Count" && builder.Columns.Count == 0)
|
if (op == "Count" && !builder.HasSelectColumns)
|
||||||
{
|
{
|
||||||
result = Scalar(builder.Select(new DynamicColumn
|
result = Scalar(builder.Select(x => x.Count()));
|
||||||
{
|
|
||||||
ColumnName = "*",
|
|
||||||
Aggregate = op.ToUpper(),
|
|
||||||
Alias = "Count"
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (result is long)
|
if (result is long)
|
||||||
result = (int)(long)result;
|
result = (int)(long)result;
|
||||||
@@ -831,25 +878,15 @@ namespace DynamORM
|
|||||||
else if (op == "Sum" || op == "Max" ||
|
else if (op == "Sum" || op == "Max" ||
|
||||||
op == "Min" || op == "Avg" || op == "Count")
|
op == "Min" || op == "Avg" || op == "Count")
|
||||||
{
|
{
|
||||||
if (builder.Columns.Count == 0)
|
if (!builder.HasSelectColumns)
|
||||||
throw new InvalidOperationException("You must select at least one column to agregate.");
|
throw new InvalidOperationException("You must select one column to agregate.");
|
||||||
|
|
||||||
foreach (var o in builder.Columns)
|
result = Scalar(builder);
|
||||||
o.Aggregate = op.ToUpper();
|
|
||||||
|
|
||||||
if (builder.Columns.Count == 1)
|
if (op == "Count" && result is long)
|
||||||
{
|
result = (int)(long)result;
|
||||||
result = Scalar(builder);
|
else if (result == DBNull.Value)
|
||||||
|
result = null;
|
||||||
if (op == "Count" && result is long)
|
|
||||||
result = (int)(long)result;
|
|
||||||
else if (result == DBNull.Value)
|
|
||||||
result = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = Query(builder).FirstOrDefault(); // return lots
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -857,15 +894,15 @@ namespace DynamORM
|
|||||||
var justOne = op == "First" || op == "Last" || op == "Get" || op == "Single";
|
var justOne = op == "First" || op == "Last" || op == "Get" || op == "Single";
|
||||||
|
|
||||||
// Be sure to sort by DESC on selected columns
|
// Be sure to sort by DESC on selected columns
|
||||||
if (op == "Last")
|
/*if (op == "Last")
|
||||||
{
|
{
|
||||||
if (builder.Order.Count > 0)
|
if (builder.Order.Count > 0)
|
||||||
foreach (var o in builder.Order)
|
foreach (var o in builder.Order)
|
||||||
o.Order = o.Order == DynamicColumn.SortOrder.Desc ?
|
o.Order = o.Order == DynamicColumn.SortOrder.Desc ?
|
||||||
DynamicColumn.SortOrder.Asc : DynamicColumn.SortOrder.Desc;
|
DynamicColumn.SortOrder.Asc : DynamicColumn.SortOrder.Desc;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if (justOne && !(op == "Last" && builder.Order.Count == 0))
|
if (justOne && !(op == "Last"))
|
||||||
{
|
{
|
||||||
if ((Database.Options & DynamicDatabaseOptions.SupportLimitOffset) == DynamicDatabaseOptions.SupportLimitOffset)
|
if ((Database.Options & DynamicDatabaseOptions.SupportLimitOffset) == DynamicDatabaseOptions.SupportLimitOffset)
|
||||||
builder.Limit(1);
|
builder.Limit(1);
|
||||||
@@ -875,7 +912,7 @@ namespace DynamORM
|
|||||||
|
|
||||||
if (op == "Scalar")
|
if (op == "Scalar")
|
||||||
{
|
{
|
||||||
if (builder.Columns.Count != 1)
|
if (!builder.HasSelectColumns)
|
||||||
throw new InvalidOperationException("You must select one column in scalar statement.");
|
throw new InvalidOperationException("You must select one column in scalar statement.");
|
||||||
|
|
||||||
result = Scalar(builder);
|
result = Scalar(builder);
|
||||||
@@ -884,7 +921,7 @@ namespace DynamORM
|
|||||||
{
|
{
|
||||||
if (justOne)
|
if (justOne)
|
||||||
{
|
{
|
||||||
if (op == "Last" && builder.Order.Count == 0)
|
if (op == "Last")
|
||||||
result = Query(builder).LastOrDefault(); // Last record fallback
|
result = Query(builder).LastOrDefault(); // Last record fallback
|
||||||
else
|
else
|
||||||
result = Query(builder).FirstOrDefault(); // return a single record
|
result = Query(builder).FirstOrDefault(); // return a single record
|
||||||
@@ -908,7 +945,7 @@ namespace DynamORM
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleTypeArgument<T>(object[] args, CallInfo info, ref IList<Type> types, DynamicQueryBuilder<T> builder, int i) where T : class
|
private void HandleTypeArgument<T>(object[] args, CallInfo info, ref IList<Type> types, T builder, int i) where T : DynamicQueryBuilder
|
||||||
{
|
{
|
||||||
if (args != null)
|
if (args != null)
|
||||||
{
|
{
|
||||||
|
|||||||
1136
DynamORM/Helpers/Dynamics/DynamicParser.cs
Normal file
1136
DynamORM/Helpers/Dynamics/DynamicParser.cs
Normal file
File diff suppressed because it is too large
Load Diff
44
DynamORM/Helpers/IExtendedDisposable.cs
Normal file
44
DynamORM/Helpers/IExtendedDisposable.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
namespace DynamORM.Helpers
|
||||||
|
{
|
||||||
|
/// <summary>Extends <see cref="IDisposable"/> interface.</summary>
|
||||||
|
public interface IExtendedDisposable : IDisposable
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether this instance is disposed.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// <c>true</c> if this instance is disposed; otherwise, <c>false</c>.
|
||||||
|
/// </value>
|
||||||
|
bool IsDisposed { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
332
DynamORM/Helpers/StringExtensions.cs
Normal file
332
DynamORM/Helpers/StringExtensions.cs
Normal file
@@ -0,0 +1,332 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace DynamORM.Helpers
|
||||||
|
{
|
||||||
|
/// <summary>Class containing useful string extensions.</summary>
|
||||||
|
internal static class StringExtensions
|
||||||
|
{
|
||||||
|
static StringExtensions()
|
||||||
|
{
|
||||||
|
InvalidMultipartMemberChars = _InvalidMultipartMemberChars.ToCharArray();
|
||||||
|
InvalidMemberChars = _InvalidMemberChars.ToCharArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly string _InvalidMultipartMemberChars = " +-*/^%[]{}()!\"\\&=?¿";
|
||||||
|
private static readonly string _InvalidMemberChars = "." + _InvalidMultipartMemberChars;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets an array with some invalid characters that cannot be used with multipart names for class members.
|
||||||
|
/// </summary>
|
||||||
|
public static char[] InvalidMultipartMemberChars { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets an array with some invalid characters that cannot be used with names for class members.
|
||||||
|
/// </summary>
|
||||||
|
public static char[] InvalidMemberChars { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides with an alternate and generic way to obtain an alternate string representation for this instance,
|
||||||
|
/// applying the following rules:
|
||||||
|
/// <para>- Null values are returned as with the <see cref="NullString"/> value, or a null object.</para>
|
||||||
|
/// <para>- Enum values are translated into their string representation.</para>
|
||||||
|
/// <para>- If the type has override the 'ToString' method then it is used.</para>
|
||||||
|
/// <para>- If it is a dictionary, then a collection of key/value pairs where the value part is also translated.</para>
|
||||||
|
/// <para>- If it is a collection, then a collection of value items also translated.</para>
|
||||||
|
/// <para>- If it has public public properties (or if not, if it has public fields), the collection of name/value
|
||||||
|
/// pairs, with the values translated.</para>
|
||||||
|
/// <para>- Finally it falls back to the standard 'type.FullName' mechanism.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">The object to obtain its alternate string representation from.</param>
|
||||||
|
/// <param name="brackets">The brackets to use if needed. If not null it must be at least a 2-chars' array containing
|
||||||
|
/// the opening and closing brackets.</param>
|
||||||
|
/// <param name="nullString">Representation of null string..</param>
|
||||||
|
/// <returns>The alternate string representation of this object.</returns>
|
||||||
|
public static string Sketch(this object obj, char[] brackets = null, string nullString = "(null)")
|
||||||
|
{
|
||||||
|
if (obj == null) return nullString;
|
||||||
|
if (obj is string) return (string)obj;
|
||||||
|
|
||||||
|
Type type = obj.GetType();
|
||||||
|
if (type.IsEnum) return obj.ToString();
|
||||||
|
|
||||||
|
// If the ToString() method has been overriden (by the type itself, or by its parents), let's use it...
|
||||||
|
MethodInfo method = type.GetMethod("ToString", Type.EmptyTypes);
|
||||||
|
if (method.DeclaringType != typeof(object)) return obj.ToString();
|
||||||
|
|
||||||
|
// For alll other cases...
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
|
// Dictionaries...
|
||||||
|
if (obj is IDictionary)
|
||||||
|
{
|
||||||
|
if (brackets == null || brackets.Length < 2)
|
||||||
|
brackets = "[]".ToCharArray();
|
||||||
|
|
||||||
|
sb.AppendFormat("{0}", brackets[0]); first = true; foreach (DictionaryEntry kvp in (IDictionary)obj)
|
||||||
|
{
|
||||||
|
if (!first) sb.Append(", "); else first = false;
|
||||||
|
sb.AppendFormat("'{0}'='{1}'", kvp.Key.Sketch(), kvp.Value.Sketch());
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.AppendFormat("{0}", brackets[1]);
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// IEnumerables...
|
||||||
|
IEnumerator ator = null;
|
||||||
|
if (obj is IEnumerable)
|
||||||
|
ator = ((IEnumerable)obj).GetEnumerator();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
method = type.GetMethod("GetEnumerator", Type.EmptyTypes);
|
||||||
|
if (method != null)
|
||||||
|
ator = (IEnumerator)method.Invoke(obj, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ator != null)
|
||||||
|
{
|
||||||
|
if (brackets == null || brackets.Length < 2) brackets = "[]".ToCharArray();
|
||||||
|
sb.AppendFormat("{0}", brackets[0]); first = true; while (ator.MoveNext())
|
||||||
|
{
|
||||||
|
if (!first) sb.Append(", "); else first = false;
|
||||||
|
sb.AppendFormat("{0}", ator.Current.Sketch());
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.AppendFormat("{0}", brackets[1]);
|
||||||
|
|
||||||
|
if (ator is IDisposable)
|
||||||
|
((IDisposable)ator).Dispose();
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// As a last resort, using the public properties (or fields if needed, or type name)...
|
||||||
|
BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy;
|
||||||
|
PropertyInfo[] props = type.GetProperties(flags);
|
||||||
|
FieldInfo[] infos = type.GetFields(flags);
|
||||||
|
|
||||||
|
if (props.Length == 0 && infos.Length == 0) sb.Append(type.FullName); // Fallback if needed
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (brackets == null || brackets.Length < 2) brackets = "{}".ToCharArray();
|
||||||
|
sb.AppendFormat("{0}", brackets[0]);
|
||||||
|
first = true;
|
||||||
|
|
||||||
|
if (props.Length != 0)
|
||||||
|
{
|
||||||
|
foreach (var prop in props)
|
||||||
|
{
|
||||||
|
if (!first) sb.Append(", "); else first = false;
|
||||||
|
sb.AppendFormat("{0}='{1}'", prop.Name, prop.GetValue(obj, null).Sketch());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (infos.Length != 0)
|
||||||
|
{
|
||||||
|
foreach (var info in infos)
|
||||||
|
{
|
||||||
|
if (!first) sb.Append(", "); else first = false;
|
||||||
|
sb.AppendFormat("{0}='{1}'", info.Name, info.GetValue(obj).Sketch());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.AppendFormat("{0}", brackets[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// And returning...
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if the target string contains any of the characters given.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="source">The target string. It cannot be null.</param>
|
||||||
|
/// <param name="items">An array containing the characters to test. It cannot be null. If empty false is returned.</param>
|
||||||
|
/// <returns>True if the target string contains any of the characters given, false otherwise.</returns>
|
||||||
|
public static bool ContainsAny(this string source, char[] items)
|
||||||
|
{
|
||||||
|
if (source == null) throw new ArgumentNullException("source", "Source string cannot be null.");
|
||||||
|
if (items == null) throw new ArgumentNullException("items", "Array of characters to test cannot be null.");
|
||||||
|
|
||||||
|
if (items.Length == 0) return false; // No characters to validate
|
||||||
|
int ix = source.IndexOfAny(items);
|
||||||
|
return ix >= 0 ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a new validated string using the rules given.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="source">The source string.</param>
|
||||||
|
/// <param name="desc">A description of the source string to build errors and exceptions if needed.</param>
|
||||||
|
/// <param name="canbeNull">True if the returned string can be null.</param>
|
||||||
|
/// <param name="canbeEmpty">True if the returned string can be empty.</param>
|
||||||
|
/// <param name="trim">True to trim the returned string.</param>
|
||||||
|
/// <param name="trimStart">True to left-trim the returned string.</param>
|
||||||
|
/// <param name="trimEnd">True to right-trim the returned string.</param>
|
||||||
|
/// <param name="minLen">If >= 0, the min valid length for the returned string.</param>
|
||||||
|
/// <param name="maxLen">If >= 0, the max valid length for the returned string.</param>
|
||||||
|
/// <param name="padLeft">If not '\0', the character to use to left-pad the returned string if needed.</param>
|
||||||
|
/// <param name="padRight">If not '\0', the character to use to right-pad the returned string if needed.</param>
|
||||||
|
/// <param name="invalidChars">If not null, an array containing invalid chars that must not appear in the returned
|
||||||
|
/// string.</param>
|
||||||
|
/// <param name="validChars">If not null, an array containing the only characters that are considered valid for the
|
||||||
|
/// returned string.</param>
|
||||||
|
/// <returns>A new validated string.</returns>
|
||||||
|
public static string Validated(this string source, string desc = null,
|
||||||
|
bool canbeNull = false, bool canbeEmpty = false,
|
||||||
|
bool trim = true, bool trimStart = false, bool trimEnd = false,
|
||||||
|
int minLen = -1, int maxLen = -1, char padLeft = '\0', char padRight = '\0',
|
||||||
|
char[] invalidChars = null, char[] validChars = null)
|
||||||
|
{
|
||||||
|
// Assuring a valid descriptor...
|
||||||
|
if (string.IsNullOrWhiteSpace(desc)) desc = "Source";
|
||||||
|
|
||||||
|
// Validating if null sources are accepted...
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
if (!canbeNull) throw new ArgumentNullException(desc, string.Format("{0} cannot be null.", desc));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trimming if needed...
|
||||||
|
if (trim && !(trimStart || trimEnd)) source = source.Trim();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (trimStart) source = source.TrimStart(' ');
|
||||||
|
if (trimEnd) source = source.TrimEnd(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjusting lenght...
|
||||||
|
if (minLen > 0)
|
||||||
|
{
|
||||||
|
if (padLeft != '\0') source = source.PadLeft(minLen, padLeft);
|
||||||
|
if (padRight != '\0') source = source.PadRight(minLen, padRight);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxLen > 0)
|
||||||
|
{
|
||||||
|
if (padLeft != '\0') source = source.PadLeft(maxLen, padLeft);
|
||||||
|
if (padRight != '\0') source = source.PadRight(maxLen, padRight);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validating emptyness and lenghts...
|
||||||
|
if (source.Length == 0)
|
||||||
|
{
|
||||||
|
if (!canbeEmpty) throw new ArgumentException(string.Format("{0} cannot be empty.", desc));
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minLen >= 0 && source.Length < minLen) throw new ArgumentException(string.Format("Lenght of {0} '{1}' is lower than '{2}'.", desc, source, minLen));
|
||||||
|
if (maxLen >= 0 && source.Length > maxLen) throw new ArgumentException(string.Format("Lenght of {0} '{1}' is bigger than '{2}'.", desc, source, maxLen));
|
||||||
|
|
||||||
|
// Checking invalid chars...
|
||||||
|
if (invalidChars != null)
|
||||||
|
{
|
||||||
|
int n = source.IndexOfAny(invalidChars);
|
||||||
|
if (n >= 0) throw new ArgumentException(string.Format("Invalid character '{0}' found in {1} '{2}'.", source[n], desc, source));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checking valid chars...
|
||||||
|
if (validChars != null)
|
||||||
|
{
|
||||||
|
int n = validChars.ToString().IndexOfAny(source.ToCharArray());
|
||||||
|
if (n >= 0) throw new ArgumentException(string.Format("Invalid character '{0}' found in {1} '{2}'.", validChars.ToString()[n], desc, source));
|
||||||
|
}
|
||||||
|
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Splits the given string with the 'something AS alias' format, returning a tuple containing its 'something' and 'alias' parts.
|
||||||
|
/// If no alias is detected, then its component in the tuple returned is null and all the contents from the source
|
||||||
|
/// string are considered as the 'something' part.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="source">The source string.</param>
|
||||||
|
/// <returns>A tuple containing the 'something' and 'alias' parts.</returns>
|
||||||
|
public static Tuple<string, string> SplitSomethingAndAlias(this string source)
|
||||||
|
{
|
||||||
|
source = source.Validated("[Something AS Alias]");
|
||||||
|
|
||||||
|
string something = null;
|
||||||
|
string alias = null;
|
||||||
|
int n = source.LastIndexOf(" AS ", StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
if (n < 0)
|
||||||
|
something = source;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
something = source.Substring(0, n);
|
||||||
|
alias = source.Substring(n + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Tuple<string, string>(something, alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Allows to replace parameters inside of string.</summary>
|
||||||
|
/// <param name="stringToFill">String containing parameters in format <c>[$ParameterName]</c>.</param>
|
||||||
|
/// <param name="getValue">Function that should return value that will be placed in string in place of placed parameter.</param>
|
||||||
|
/// <param name="prefix">Prefix of the parameter. This value can't be null or empty, default value <code>[$</code>.</param>
|
||||||
|
/// <param name="sufix">Suffix of the parameter. This value can't be null or empty, default value <code>]</code>.</param>
|
||||||
|
/// <returns>Parsed string.</returns>
|
||||||
|
public static string FillStringWithVariables(this string stringToFill, Func<string, string> getValue, string prefix = "[$", string sufix = "]")
|
||||||
|
{
|
||||||
|
int startPos = 0, endPos = 0;
|
||||||
|
prefix.Validated();
|
||||||
|
sufix.Validated();
|
||||||
|
|
||||||
|
startPos = stringToFill.IndexOf(prefix, startPos);
|
||||||
|
while (startPos >= 0)
|
||||||
|
{
|
||||||
|
endPos = stringToFill.IndexOf(sufix, startPos + prefix.Length);
|
||||||
|
int nextStartPos = stringToFill.IndexOf(prefix, startPos + prefix.Length);
|
||||||
|
|
||||||
|
if (endPos > startPos + prefix.Length + 1 && (nextStartPos > endPos || nextStartPos == -1))
|
||||||
|
{
|
||||||
|
string paramName = stringToFill.Substring(startPos + prefix.Length, endPos - (startPos + prefix.Length));
|
||||||
|
|
||||||
|
stringToFill = stringToFill
|
||||||
|
.Remove(startPos, (endPos - startPos) + sufix.Length)
|
||||||
|
.Insert(startPos, getValue(paramName));
|
||||||
|
}
|
||||||
|
|
||||||
|
startPos = stringToFill.IndexOf(prefix, startPos + prefix.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringToFill;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
75
DynamORM/Helpers/UnclassifiedExtensions.cs
Normal file
75
DynamORM/Helpers/UnclassifiedExtensions.cs
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
namespace DynamORM.Helpers
|
||||||
|
{
|
||||||
|
/// <summary>Class contains unclassified extensions.</summary>
|
||||||
|
public static class UnclassifiedExtensions
|
||||||
|
{
|
||||||
|
/// <summary>Easy way to use conditional value.</summary>
|
||||||
|
/// <remarks>Includes <see cref="DBNull.Value"/>.</remarks>
|
||||||
|
/// <typeparam name="T">Input object type to check.</typeparam>
|
||||||
|
/// <typeparam name="R">Result type.</typeparam>
|
||||||
|
/// <param name="obj">The object to check.</param>
|
||||||
|
/// <param name="func">The select function.</param>
|
||||||
|
/// <param name="elseValue">The else value.</param>
|
||||||
|
/// <returns>Selected value or default value.</returns>
|
||||||
|
/// <example>It lets you do this:
|
||||||
|
/// <code>var lname = thingy.NullOr(t => t.Name).NullOr(n => n.ToLower());</code>
|
||||||
|
/// which is more fluent and (IMO) easier to read than this:
|
||||||
|
/// <code>var lname = (thingy != null ? thingy.Name : null) != null ? thingy.Name.ToLower() : null;</code>
|
||||||
|
/// </example>
|
||||||
|
public static R NullOr<T, R>(this T obj, Func<T, R> func, R elseValue = default(R)) where T : class
|
||||||
|
{
|
||||||
|
return obj != null && obj != DBNull.Value ?
|
||||||
|
func(obj) : elseValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Easy way to use conditional value.</summary>
|
||||||
|
/// <remarks>Includes <see cref="DBNull.Value"/>.</remarks>
|
||||||
|
/// <typeparam name="T">Input object type to check.</typeparam>
|
||||||
|
/// <typeparam name="R">Result type.</typeparam>
|
||||||
|
/// <param name="obj">The object to check.</param>
|
||||||
|
/// <param name="func">The select function.</param>
|
||||||
|
/// <param name="elseFunc">The else value function.</param>
|
||||||
|
/// <returns>Selected value or default value.</returns>
|
||||||
|
/// <example>It lets you do this:
|
||||||
|
/// <code>var lname = thingy.NullOr(t => t.Name).NullOr(n => n.ToLower());</code>
|
||||||
|
/// which is more fluent and (IMO) easier to read than this:
|
||||||
|
/// <code>var lname = (thingy != null ? thingy.Name : null) != null ? thingy.Name.ToLower() : null;</code>
|
||||||
|
/// </example>
|
||||||
|
public static R NullOrFn<T, R>(this T obj, Func<T, R> func, Func<R> elseFunc = null) where T : class
|
||||||
|
{
|
||||||
|
// Old if to avoid recurency.
|
||||||
|
return obj != null && obj != DBNull.Value ?
|
||||||
|
func(obj) : elseFunc != null ? elseFunc() : default(R);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,6 +34,9 @@ namespace DynamORM.Mapper
|
|||||||
[AttributeUsage(AttributeTargets.Class)]
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
public class TableAttribute : Attribute
|
public class TableAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
/// <summary>Gets or sets table owner name.</summary>
|
||||||
|
public string Owner { get; set; }
|
||||||
|
|
||||||
/// <summary>Gets or sets name.</summary>
|
/// <summary>Gets or sets name.</summary>
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
@@ -62,4 +63,5 @@ using System.Runtime.InteropServices;
|
|||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.0.0.1")]
|
[assembly: AssemblyVersion("1.0.0.1")]
|
||||||
[assembly: AssemblyFileVersion("1.0.0.1")]
|
[assembly: AssemblyFileVersion("1.0.0.1")]
|
||||||
|
[assembly: InternalsVisibleTo("DynamORM.Tests")]
|
||||||
Reference in New Issue
Block a user