mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 02:32:50 +08:00
- 增加 DuckDB 数据库支持;
This commit is contained in:
parent
867e28f2f0
commit
a1013a39bf
@ -91,6 +91,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.Xugu", "Pr
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.ZeroEntity", "Extensions\FreeSql.Extensions.ZeroEntity\FreeSql.Extensions.ZeroEntity.csproj", "{4367B7AC-604F-4503-A1D4-643ADBFCF703}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Extensions.ZeroEntity", "Extensions\FreeSql.Extensions.ZeroEntity\FreeSql.Extensions.ZeroEntity.csproj", "{4367B7AC-604F-4503-A1D4-643ADBFCF703}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.Duckdb", "Providers\FreeSql.Provider.Duckdb\FreeSql.Provider.Duckdb.csproj", "{02CFB50A-D8C4-470D-AC93-5540D6029430}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Provider.Duckdb", "FreeSql.Tests\FreeSql.Tests.Provider.Duckdb\FreeSql.Tests.Provider.Duckdb.csproj", "{B9787A81-D537-45ED-B413-61BF03C8FEBE}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -509,6 +513,30 @@ Global
|
|||||||
{4367B7AC-604F-4503-A1D4-643ADBFCF703}.Release|x64.Build.0 = Release|Any CPU
|
{4367B7AC-604F-4503-A1D4-643ADBFCF703}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{4367B7AC-604F-4503-A1D4-643ADBFCF703}.Release|x86.ActiveCfg = Release|Any CPU
|
{4367B7AC-604F-4503-A1D4-643ADBFCF703}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{4367B7AC-604F-4503-A1D4-643ADBFCF703}.Release|x86.Build.0 = Release|Any CPU
|
{4367B7AC-604F-4503-A1D4-643ADBFCF703}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{02CFB50A-D8C4-470D-AC93-5540D6029430}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{02CFB50A-D8C4-470D-AC93-5540D6029430}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{02CFB50A-D8C4-470D-AC93-5540D6029430}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{02CFB50A-D8C4-470D-AC93-5540D6029430}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{02CFB50A-D8C4-470D-AC93-5540D6029430}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{02CFB50A-D8C4-470D-AC93-5540D6029430}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{02CFB50A-D8C4-470D-AC93-5540D6029430}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{02CFB50A-D8C4-470D-AC93-5540D6029430}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{02CFB50A-D8C4-470D-AC93-5540D6029430}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{02CFB50A-D8C4-470D-AC93-5540D6029430}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{02CFB50A-D8C4-470D-AC93-5540D6029430}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{02CFB50A-D8C4-470D-AC93-5540D6029430}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{B9787A81-D537-45ED-B413-61BF03C8FEBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{B9787A81-D537-45ED-B413-61BF03C8FEBE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{B9787A81-D537-45ED-B413-61BF03C8FEBE}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{B9787A81-D537-45ED-B413-61BF03C8FEBE}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{B9787A81-D537-45ED-B413-61BF03C8FEBE}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{B9787A81-D537-45ED-B413-61BF03C8FEBE}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{B9787A81-D537-45ED-B413-61BF03C8FEBE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{B9787A81-D537-45ED-B413-61BF03C8FEBE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{B9787A81-D537-45ED-B413-61BF03C8FEBE}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{B9787A81-D537-45ED-B413-61BF03C8FEBE}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{B9787A81-D537-45ED-B413-61BF03C8FEBE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{B9787A81-D537-45ED-B413-61BF03C8FEBE}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@ -544,10 +572,11 @@ Global
|
|||||||
{FEE501EB-60D1-4370-BC65-F939BCA7F32E} = {2A381C57-2697-427B-9F10-55DA11FD02E4}
|
{FEE501EB-60D1-4370-BC65-F939BCA7F32E} = {2A381C57-2697-427B-9F10-55DA11FD02E4}
|
||||||
{353F3732-0704-40F2-972B-036E9CC01881} = {2A381C57-2697-427B-9F10-55DA11FD02E4}
|
{353F3732-0704-40F2-972B-036E9CC01881} = {2A381C57-2697-427B-9F10-55DA11FD02E4}
|
||||||
{4367B7AC-604F-4503-A1D4-643ADBFCF703} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA}
|
{4367B7AC-604F-4503-A1D4-643ADBFCF703} = {4A92E8A6-9A6D-41A1-9CDA-DE10899648AA}
|
||||||
|
{02CFB50A-D8C4-470D-AC93-5540D6029430} = {2A381C57-2697-427B-9F10-55DA11FD02E4}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
RESX_NeutralResourcesLanguage = en-US
|
|
||||||
RESX_PrefixTranslations = True
|
|
||||||
SolutionGuid = {089687FA-5D21-40AC-BA8A-AA0D1E1H7F98}
|
SolutionGuid = {089687FA-5D21-40AC-BA8A-AA0D1E1H7F98}
|
||||||
|
RESX_PrefixTranslations = True
|
||||||
|
RESX_NeutralResourcesLanguage = en-US
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
@ -99,9 +99,7 @@ namespace FreeSql
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_fsql?.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(_tranBefore, "失败", ex));
|
_fsql?.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(_tranBefore, "失败", ex));
|
||||||
#pragma warning disable CA2200 // 再次引发以保留堆栈详细信息
|
throw;
|
||||||
throw ex;
|
|
||||||
#pragma warning restore CA2200 // 再次引发以保留堆栈详细信息
|
|
||||||
}
|
}
|
||||||
return _tran;
|
return _tran;
|
||||||
}
|
}
|
||||||
@ -125,9 +123,7 @@ namespace FreeSql
|
|||||||
{
|
{
|
||||||
if (isCommited == false)
|
if (isCommited == false)
|
||||||
_fsql?.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(_tranBefore, "提交失败", ex));
|
_fsql?.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(_tranBefore, "提交失败", ex));
|
||||||
#pragma warning disable CA2200 // 再次引发以保留堆栈详细信息
|
throw;
|
||||||
throw ex;
|
|
||||||
#pragma warning restore CA2200 // 再次引发以保留堆栈详细信息
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -151,9 +147,7 @@ namespace FreeSql
|
|||||||
{
|
{
|
||||||
if (isRollbacked == false)
|
if (isRollbacked == false)
|
||||||
_fsql?.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(_tranBefore, "回滚失败", ex));
|
_fsql?.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(_tranBefore, "回滚失败", ex));
|
||||||
#pragma warning disable CA2200 // 再次引发以保留堆栈详细信息
|
throw;
|
||||||
throw ex;
|
|
||||||
#pragma warning restore CA2200 // 再次引发以保留堆栈详细信息
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,98 @@
|
|||||||
|
using FreeSql.DataAnnotations;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace FreeSql.Tests.Duckdb
|
||||||
|
{
|
||||||
|
public class DuckdbDeleteTest
|
||||||
|
{
|
||||||
|
IFreeSql fsql => g.duckdb;
|
||||||
|
IDelete<Topic> delete => fsql.Delete<Topic>();
|
||||||
|
|
||||||
|
[Table(Name = "tb_topic_del")]
|
||||||
|
class Topic
|
||||||
|
{
|
||||||
|
[Column(IsIdentity = true, IsPrimary = true)]
|
||||||
|
public int Id { get; set; }
|
||||||
|
public int Clicks { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Dywhere()
|
||||||
|
{
|
||||||
|
Assert.Null(fsql.Delete<Topic>().ToSql());
|
||||||
|
var sql = fsql.Delete<Topic>(new[] { 1, 2 }).ToSql();
|
||||||
|
Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" IN (1,2))", sql);
|
||||||
|
|
||||||
|
sql = fsql.Delete<Topic>(new Topic { Id = 1, Title = "test" }).ToSql();
|
||||||
|
Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql);
|
||||||
|
|
||||||
|
sql = fsql.Delete<Topic>(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql();
|
||||||
|
Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" IN (1,2))", sql);
|
||||||
|
|
||||||
|
sql = fsql.Delete<Topic>(new { id = 1 }).ToSql();
|
||||||
|
Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql);
|
||||||
|
|
||||||
|
sql = fsql.Delete<MultiPkTopic>(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql();
|
||||||
|
Assert.Equal("DELETE FROM \"multipktopic\" WHERE (\"id1\" = 1 AND \"id2\" = 10 OR \"id1\" = 2 AND \"id2\" = 20)", sql);
|
||||||
|
}
|
||||||
|
class MultiPkTopic
|
||||||
|
{
|
||||||
|
[Column(IsPrimary = true)]
|
||||||
|
public int Id1 { get; set; }
|
||||||
|
[Column(IsPrimary = true)]
|
||||||
|
public int Id2 { get; set; }
|
||||||
|
public int Clicks { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Where()
|
||||||
|
{
|
||||||
|
var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", "");
|
||||||
|
Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql);
|
||||||
|
|
||||||
|
sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", "");
|
||||||
|
Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (id = @id)", sql);
|
||||||
|
|
||||||
|
var item = new Topic { Id = 1, Title = "newtitle" };
|
||||||
|
sql = delete.Where(item).ToSql().Replace("\r\n", "");
|
||||||
|
Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql);
|
||||||
|
|
||||||
|
var items = new List<Topic>();
|
||||||
|
for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 });
|
||||||
|
|
||||||
|
sql = delete.Where(items).ToSql().Replace("\r\n", "");
|
||||||
|
Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql);
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void ExecuteAffrows()
|
||||||
|
{
|
||||||
|
|
||||||
|
var id = fsql.Insert<Topic>(new Topic { Title = "xxxx" }).ExecuteIdentity();
|
||||||
|
Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void AsTable()
|
||||||
|
{
|
||||||
|
Assert.Null(fsql.Delete<Topic>().ToSql());
|
||||||
|
var sql = fsql.Delete<Topic>(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql();
|
||||||
|
Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" IN (1,2))", sql);
|
||||||
|
|
||||||
|
sql = fsql.Delete<Topic>(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql();
|
||||||
|
Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" = 1)", sql);
|
||||||
|
|
||||||
|
sql = fsql.Delete<Topic>(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql();
|
||||||
|
Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" IN (1,2))", sql);
|
||||||
|
|
||||||
|
sql = fsql.Delete<Topic>(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql();
|
||||||
|
Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" = 1)", sql);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,266 @@
|
|||||||
|
using FreeSql.DataAnnotations;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace FreeSql.Tests.Duckdb
|
||||||
|
{
|
||||||
|
public class DuckdbInsertOrUpdateIfExistsDoNotingTest
|
||||||
|
{
|
||||||
|
IFreeSql fsql => g.duckdb;
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InsertOrUpdate_OnlyPrimary()
|
||||||
|
{
|
||||||
|
fsql.Delete<tbioudb01>().Where("1=1").ExecuteAffrows();
|
||||||
|
var iou = fsql.InsertOrUpdate<tbioudb01>().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 });
|
||||||
|
var sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1)
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb01>().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1)
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(0, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb01>().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(2)
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb01>().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1), (2), (3), (4)
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(2, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb01>().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1), (2), (3), (4)
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(0, iou.ExecuteAffrows());
|
||||||
|
}
|
||||||
|
class tbioudb01
|
||||||
|
{
|
||||||
|
public int id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InsertOrUpdate_OnePrimary()
|
||||||
|
{
|
||||||
|
fsql.Delete<tbioudb02>().Where("1=1").ExecuteAffrows();
|
||||||
|
var iou = fsql.InsertOrUpdate<tbioudb02>().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" });
|
||||||
|
var sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '01')
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb02>().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '011')
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(0, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb02>().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(2, '02')
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb02>().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04')
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(2, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb02>().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004')
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(0, iou.ExecuteAffrows());
|
||||||
|
var lst = fsql.Select<tbioudb02>().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList();
|
||||||
|
Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count());
|
||||||
|
}
|
||||||
|
class tbioudb02
|
||||||
|
{
|
||||||
|
public int id { get; set; }
|
||||||
|
public string name { get; set; }
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void InsertOrUpdate_OnePrimaryAndIdentity()
|
||||||
|
{
|
||||||
|
fsql.Delete<tbioudb022>().Where("1=1").ExecuteAffrows();
|
||||||
|
var iou = fsql.InsertOrUpdate<tbioudb022>().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" });
|
||||||
|
var sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '01')
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb022>().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '011')
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(0, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb022>().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(2, '02')
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb022>().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04')
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(2, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb022>().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004')
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(0, iou.ExecuteAffrows());
|
||||||
|
var lst = fsql.Select<tbioudb022>().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList();
|
||||||
|
Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count());
|
||||||
|
|
||||||
|
//--no primary
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb022>().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('01')", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb022>().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('011')", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb022>().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('02')", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb022>().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('01'), ('02'), ('03'), ('04')", sql);
|
||||||
|
Assert.Equal(4, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb022>().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('001'), ('002'), ('003'), ('004')", sql);
|
||||||
|
Assert.Equal(4, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
//--no primary and yes
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb022>().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004')
|
||||||
|
ON CONFLICT(""id"") DO NOTHING
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO ""tbioudb022""(""name"") VALUES('00001'), ('00002'), ('00003'), ('00004')", sql);
|
||||||
|
Assert.Equal(4, iou.ExecuteAffrows());
|
||||||
|
lst = fsql.Select<tbioudb022>().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList();
|
||||||
|
Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count());
|
||||||
|
}
|
||||||
|
class tbioudb022
|
||||||
|
{
|
||||||
|
[Column(IsIdentity = true)]
|
||||||
|
public int id { get; set; }
|
||||||
|
public string name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InsertOrUpdate_TwoPrimary()
|
||||||
|
{
|
||||||
|
fsql.Delete<tbioudb03>().Where("1=1").ExecuteAffrows();
|
||||||
|
var iou = fsql.InsertOrUpdate<tbioudb03>().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" });
|
||||||
|
var sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01')
|
||||||
|
ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb03>().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '011')
|
||||||
|
ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(0, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb03>().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(2, '02', '02')
|
||||||
|
ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb03>().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01'), (2, '02', '02'), (3, '03', '03'), (4, '04', '04')
|
||||||
|
ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(2, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb03>().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '001'), (2, '02', '002'), (3, '03', '003'), (4, '04', '004')
|
||||||
|
ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(0, iou.ExecuteAffrows());
|
||||||
|
var lst = fsql.Select<tbioudb03>().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList();
|
||||||
|
Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count());
|
||||||
|
}
|
||||||
|
class tbioudb03
|
||||||
|
{
|
||||||
|
[Column(IsPrimary = true)]
|
||||||
|
public int id1 { get; set; }
|
||||||
|
[Column(IsPrimary = true)]
|
||||||
|
public string id2 { get; set; }
|
||||||
|
public string name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate()
|
||||||
|
{
|
||||||
|
fsql.Delete<tbioudb04>().Where("1=1").ExecuteAffrows();
|
||||||
|
var iou = fsql.InsertOrUpdate<tbioudb04>().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" });
|
||||||
|
var sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '01', 0, current_timestamp)
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb04>().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '011', 0, current_timestamp)
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(0, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb04>().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(2, '02', 0, current_timestamp)
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb04>().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '01', 0, current_timestamp), (2, '02', 0, current_timestamp), (3, '03', 0, current_timestamp), (4, '04', 0, current_timestamp)
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(2, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbioudb04>().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '001', 0, current_timestamp), (2, '002', 0, current_timestamp), (3, '003', 0, current_timestamp), (4, '004', 0, current_timestamp)
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(0, iou.ExecuteAffrows());
|
||||||
|
var lst = fsql.Select<tbioudb04>().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList();
|
||||||
|
Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count());
|
||||||
|
}
|
||||||
|
class tbioudb04
|
||||||
|
{
|
||||||
|
public int id { get; set; }
|
||||||
|
public string name { get; set; }
|
||||||
|
[Column(IsVersion = true)]
|
||||||
|
public int version { get; set; }
|
||||||
|
[Column(CanUpdate = false, ServerTime = DateTimeKind.Local)]
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,300 @@
|
|||||||
|
using FreeSql.DataAnnotations;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace FreeSql.Tests.Duckdb
|
||||||
|
{
|
||||||
|
public class DuckdbInsertOrUpdateTest
|
||||||
|
{
|
||||||
|
IFreeSql fsql => g.duckdb;
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InsertOrUpdate_OnlyPrimary()
|
||||||
|
{
|
||||||
|
fsql.Delete<tbiou01>().Where("1=1").ExecuteAffrows();
|
||||||
|
|
||||||
|
var iou = fsql.InsertOrUpdate<tbiou01>().SetSource(fsql.Select<tbiou022>().ToSql(a => new { id = a.id + 1 }, FieldAliasOptions.AsProperty));
|
||||||
|
var sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou01""(""id"")
|
||||||
|
SELECT (a.""id"" + 1) ""id""
|
||||||
|
FROM ""tbiou022"" a
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou01>().SetSource(new tbiou01 { id = 1 });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou01""(""id"") VALUES(1)
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou01>().SetSource(new tbiou01 { id = 1 });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou01""(""id"") VALUES(1)
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(0, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou01>().SetSource(new tbiou01 { id = 2 });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou01""(""id"") VALUES(2)
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou01>().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou01""(""id"") VALUES(1), (2), (3), (4)
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(2, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou01>().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou01""(""id"") VALUES(1), (2), (3), (4)
|
||||||
|
ON CONFLICT(""id"") DO NOTHING", sql);
|
||||||
|
Assert.Equal(0, iou.ExecuteAffrows());
|
||||||
|
}
|
||||||
|
class tbiou01
|
||||||
|
{
|
||||||
|
public int id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InsertOrUpdate_OnePrimary()
|
||||||
|
{
|
||||||
|
fsql.Delete<tbiou02>().Where("1=1").ExecuteAffrows();
|
||||||
|
var iou = fsql.InsertOrUpdate<tbiou02>().SetSource(new tbiou02 { id = 1, name = "01" });
|
||||||
|
var sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou02""(""id"", ""name"") VALUES(1, '01')
|
||||||
|
ON CONFLICT(""id"") DO UPDATE SET
|
||||||
|
""name"" = EXCLUDED.""name""", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou02>().SetSource(new tbiou02 { id = 1, name = "011" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou02""(""id"", ""name"") VALUES(1, '011')
|
||||||
|
ON CONFLICT(""id"") DO UPDATE SET
|
||||||
|
""name"" = EXCLUDED.""name""", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou02>().SetSource(new tbiou02 { id = 2, name = "02" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou02""(""id"", ""name"") VALUES(2, '02')
|
||||||
|
ON CONFLICT(""id"") DO UPDATE SET
|
||||||
|
""name"" = EXCLUDED.""name""", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou02>().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou02""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04')
|
||||||
|
ON CONFLICT(""id"") DO UPDATE SET
|
||||||
|
""name"" = EXCLUDED.""name""", sql);
|
||||||
|
Assert.Equal(4, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou02>().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou02""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004')
|
||||||
|
ON CONFLICT(""id"") DO UPDATE SET
|
||||||
|
""name"" = EXCLUDED.""name""", sql);
|
||||||
|
Assert.Equal(4, iou.ExecuteAffrows());
|
||||||
|
var lst = fsql.Select<tbiou02>().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList();
|
||||||
|
Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count());
|
||||||
|
}
|
||||||
|
class tbiou02
|
||||||
|
{
|
||||||
|
public int id { get; set; }
|
||||||
|
public string name { get; set; }
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void InsertOrUpdate_OnePrimaryAndIdentity()
|
||||||
|
{
|
||||||
|
fsql.Delete<tbiou022>().Where("1=1").ExecuteAffrows();
|
||||||
|
var iou = fsql.InsertOrUpdate<tbiou022>().SetSource(new tbiou022 { id = 1, name = "01" });
|
||||||
|
var sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '01')
|
||||||
|
ON CONFLICT(""id"") DO UPDATE SET
|
||||||
|
""name"" = EXCLUDED.""name""", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou022>().SetSource(new tbiou022 { id = 1, name = "011" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '011')
|
||||||
|
ON CONFLICT(""id"") DO UPDATE SET
|
||||||
|
""name"" = EXCLUDED.""name""", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou022>().SetSource(new tbiou022 { id = 2, name = "02" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(2, '02')
|
||||||
|
ON CONFLICT(""id"") DO UPDATE SET
|
||||||
|
""name"" = EXCLUDED.""name""", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou022>().SetSource(new[] { new tbiou022 { id = 1, name = "01" }, new tbiou022 { id = 2, name = "02" }, new tbiou022 { id = 3, name = "03" }, new tbiou022 { id = 4, name = "04" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04')
|
||||||
|
ON CONFLICT(""id"") DO UPDATE SET
|
||||||
|
""name"" = EXCLUDED.""name""", sql);
|
||||||
|
Assert.Equal(4, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou022>().SetSource(new[] { new tbiou022 { id = 1, name = "001" }, new tbiou022 { id = 2, name = "002" }, new tbiou022 { id = 3, name = "003" }, new tbiou022 { id = 4, name = "004" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004')
|
||||||
|
ON CONFLICT(""id"") DO UPDATE SET
|
||||||
|
""name"" = EXCLUDED.""name""", sql);
|
||||||
|
Assert.Equal(4, iou.ExecuteAffrows());
|
||||||
|
var lst = fsql.Select<tbiou022>().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList();
|
||||||
|
Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count());
|
||||||
|
|
||||||
|
//--no primary
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou022>().SetSource(new tbiou022 { name = "01" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('01')", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou022>().SetSource(new tbiou022 { name = "011" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('011')", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou022>().SetSource(new tbiou022 { name = "02" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('02')", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou022>().SetSource(new[] { new tbiou022 { name = "01" }, new tbiou022 { name = "02" }, new tbiou022 { name = "03" }, new tbiou022 { name = "04" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('01'), ('02'), ('03'), ('04')", sql);
|
||||||
|
Assert.Equal(4, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou022>().SetSource(new[] { new tbiou022 { name = "001" }, new tbiou022 { name = "002" }, new tbiou022 { name = "003" }, new tbiou022 { name = "004" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('001'), ('002'), ('003'), ('004')", sql);
|
||||||
|
Assert.Equal(4, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
//--no primary and yes
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou022>().SetSource(new[] { new tbiou022 { id = 1, name = "100001" }, new tbiou022 { name = "00001" }, new tbiou022 { id = 2, name = "100002" }, new tbiou022 { name = "00002" }, new tbiou022 { id = 3, name = "100003" }, new tbiou022 { name = "00003" }, new tbiou022 { id = 4, name = "100004" }, new tbiou022 { name = "00004" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004')
|
||||||
|
ON CONFLICT(""id"") DO UPDATE SET
|
||||||
|
""name"" = EXCLUDED.""name""
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO ""tbiou022""(""name"") VALUES('00001'), ('00002'), ('00003'), ('00004')", sql);
|
||||||
|
Assert.Equal(8, iou.ExecuteAffrows());
|
||||||
|
lst = fsql.Select<tbiou022>().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList();
|
||||||
|
Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count());
|
||||||
|
}
|
||||||
|
class tbiou022
|
||||||
|
{
|
||||||
|
[Column(IsIdentity = true)]
|
||||||
|
public int id { get; set; }
|
||||||
|
public string name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InsertOrUpdate_TwoPrimary()
|
||||||
|
{
|
||||||
|
fsql.Delete<tbiou03>().Where("1=1").ExecuteAffrows();
|
||||||
|
var iou = fsql.InsertOrUpdate<tbiou03>().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" });
|
||||||
|
var sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01')
|
||||||
|
ON CONFLICT(""id1"", ""id2"") DO UPDATE SET
|
||||||
|
""name"" = EXCLUDED.""name""", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou03>().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '011')
|
||||||
|
ON CONFLICT(""id1"", ""id2"") DO UPDATE SET
|
||||||
|
""name"" = EXCLUDED.""name""", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou03>().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(2, '02', '02')
|
||||||
|
ON CONFLICT(""id1"", ""id2"") DO UPDATE SET
|
||||||
|
""name"" = EXCLUDED.""name""", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou03>().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01'), (2, '02', '02'), (3, '03', '03'), (4, '04', '04')
|
||||||
|
ON CONFLICT(""id1"", ""id2"") DO UPDATE SET
|
||||||
|
""name"" = EXCLUDED.""name""", sql);
|
||||||
|
Assert.Equal(4, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou03>().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '001'), (2, '02', '002'), (3, '03', '003'), (4, '04', '004')
|
||||||
|
ON CONFLICT(""id1"", ""id2"") DO UPDATE SET
|
||||||
|
""name"" = EXCLUDED.""name""", sql);
|
||||||
|
Assert.Equal(4, iou.ExecuteAffrows());
|
||||||
|
var lst = fsql.Select<tbiou03>().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList();
|
||||||
|
Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count());
|
||||||
|
}
|
||||||
|
class tbiou03
|
||||||
|
{
|
||||||
|
[Column(IsPrimary = true)]
|
||||||
|
public int id1 { get; set; }
|
||||||
|
[Column(IsPrimary = true)]
|
||||||
|
public string id2 { get; set; }
|
||||||
|
public string name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate()
|
||||||
|
{
|
||||||
|
fsql.Delete<tbiou04>().Where("1=1").ExecuteAffrows();
|
||||||
|
var iou = fsql.InsertOrUpdate<tbiou04>().SetSource(new tbiou04 { id = 1, name = "01" });
|
||||||
|
var sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '01', 0, current_timestamp)
|
||||||
|
ON CONFLICT(""id"") DO UPDATE SET
|
||||||
|
""name"" = EXCLUDED.""name"",
|
||||||
|
""version"" = ""tbiou04"".""version"" + 1", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou04>().SetSource(new tbiou04 { id = 1, name = "011" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '011', 0, current_timestamp)
|
||||||
|
ON CONFLICT(""id"") DO UPDATE SET
|
||||||
|
""name"" = EXCLUDED.""name"",
|
||||||
|
""version"" = ""tbiou04"".""version"" + 1", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou04>().SetSource(new tbiou04 { id = 2, name = "02" });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou04""(""id"", ""name"", ""version"", ""createtime"") VALUES(2, '02', 0, current_timestamp)
|
||||||
|
ON CONFLICT(""id"") DO UPDATE SET
|
||||||
|
""name"" = EXCLUDED.""name"",
|
||||||
|
""version"" = ""tbiou04"".""version"" + 1", sql);
|
||||||
|
Assert.Equal(1, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou04>().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '01', 0, current_timestamp), (2, '02', 0, current_timestamp), (3, '03', 0, current_timestamp), (4, '04', 0, current_timestamp)
|
||||||
|
ON CONFLICT(""id"") DO UPDATE SET
|
||||||
|
""name"" = EXCLUDED.""name"",
|
||||||
|
""version"" = ""tbiou04"".""version"" + 1", sql);
|
||||||
|
Assert.Equal(4, iou.ExecuteAffrows());
|
||||||
|
|
||||||
|
iou = fsql.InsertOrUpdate<tbiou04>().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } });
|
||||||
|
sql = iou.ToSql();
|
||||||
|
Assert.Equal(@"INSERT INTO ""tbiou04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '001', 0, current_timestamp), (2, '002', 0, current_timestamp), (3, '003', 0, current_timestamp), (4, '004', 0, current_timestamp)
|
||||||
|
ON CONFLICT(""id"") DO UPDATE SET
|
||||||
|
""name"" = EXCLUDED.""name"",
|
||||||
|
""version"" = ""tbiou04"".""version"" + 1", sql);
|
||||||
|
Assert.Equal(4, iou.ExecuteAffrows());
|
||||||
|
var lst = fsql.Select<tbiou04>().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList();
|
||||||
|
Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count());
|
||||||
|
}
|
||||||
|
class tbiou04
|
||||||
|
{
|
||||||
|
public int id { get; set; }
|
||||||
|
public string name { get; set; }
|
||||||
|
[Column(IsVersion = true)]
|
||||||
|
public int version { get; set; }
|
||||||
|
[Column(CanUpdate = false, ServerTime = DateTimeKind.Local)]
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,71 @@
|
|||||||
|
using FreeSql.DataAnnotations;
|
||||||
|
using System;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace FreeSql.Tests.Duckdb
|
||||||
|
{
|
||||||
|
public class DuckdbAdoTest
|
||||||
|
{
|
||||||
|
IFreeSql fsql => g.duckdb;
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SlavePools()
|
||||||
|
{
|
||||||
|
var t2 = fsql.Ado.SlavePools.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ExecuteTest()
|
||||||
|
{
|
||||||
|
Assert.True(fsql.Ado.ExecuteConnectTest());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void ExecuteReader()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void ExecuteArray()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void ExecuteNonQuery()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void ExecuteScalar()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Query()
|
||||||
|
{
|
||||||
|
|
||||||
|
fsql.CodeFirst.SyncStructure<xxx>();
|
||||||
|
var t3 = fsql.Ado.Query<xxx>("select * from xxx");
|
||||||
|
|
||||||
|
var t4 = fsql.Ado.Query<(int, string, string)>("select * from xxx");
|
||||||
|
|
||||||
|
var t5 = fsql.Ado.Query<dynamic>("select * from xxx");
|
||||||
|
|
||||||
|
//var t6 = fsql.Ado.Query<xxx>("select * from xxx where id in $ids", new { ids = new[] { "1", "2", "3" } });
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void QueryMultipline()
|
||||||
|
{
|
||||||
|
fsql.CodeFirst.SyncStructure<xxx>();
|
||||||
|
var t3 = fsql.Ado.Query<xxx, (int, string, string), dynamic>("select * from xxx; select * from xxx; select * from xxx");
|
||||||
|
}
|
||||||
|
|
||||||
|
class xxx
|
||||||
|
{
|
||||||
|
public string Id { get; set; }
|
||||||
|
public string Path { get; set; }
|
||||||
|
public string Title2 { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace FreeSql.Tests.Duckdb
|
||||||
|
{
|
||||||
|
public class DuckdbAopTest
|
||||||
|
{
|
||||||
|
IFreeSql fsql => g.duckdb;
|
||||||
|
|
||||||
|
class TestAuditValue
|
||||||
|
{
|
||||||
|
public Guid id { get; set; }
|
||||||
|
[Now]
|
||||||
|
public DateTime createtime { get; set; }
|
||||||
|
}
|
||||||
|
class NowAttribute: Attribute { }
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void AuditValue()
|
||||||
|
{
|
||||||
|
var date = DateTime.Now.Date;
|
||||||
|
var item = new TestAuditValue();
|
||||||
|
|
||||||
|
EventHandler<Aop.AuditValueEventArgs> audit = (s, e) =>
|
||||||
|
{
|
||||||
|
if (e.Property.GetCustomAttribute<NowAttribute>(false) != null)
|
||||||
|
e.Value = DateTime.Now.Date;
|
||||||
|
};
|
||||||
|
fsql.Aop.AuditValue += audit;
|
||||||
|
|
||||||
|
fsql.Insert(item).ExecuteAffrows();
|
||||||
|
|
||||||
|
fsql.Aop.AuditValue -= audit;
|
||||||
|
|
||||||
|
Assert.Equal(item.createtime, date);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,296 @@
|
|||||||
|
using FreeSql.DataAnnotations;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.NetworkInformation;
|
||||||
|
using System.Numerics;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace FreeSql.Tests.Duckdb
|
||||||
|
{
|
||||||
|
public class DuckdbCodeFirstTest
|
||||||
|
{
|
||||||
|
IFreeSql fsql => g.duckdb;
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void UInt256Crud2()
|
||||||
|
{
|
||||||
|
var num = BigInteger.Parse("170141183460469231731687303715884105727");
|
||||||
|
fsql.Delete<tuint256tb_01>().Where("1=1").ExecuteAffrows();
|
||||||
|
Assert.Equal(1, fsql.Insert(new tuint256tb_01()).ExecuteAffrows());
|
||||||
|
var find = fsql.Select<tuint256tb_01>().ToList();
|
||||||
|
Assert.Single(find);
|
||||||
|
Assert.Equal("0", find[0].Number.ToString());
|
||||||
|
var item = new tuint256tb_01 { Number = num };
|
||||||
|
Assert.Equal(1, fsql.Insert(item).ExecuteAffrows());
|
||||||
|
find = fsql.Select<tuint256tb_01>().Where(a => a.Id == item.Id).ToList();
|
||||||
|
Assert.Single(find);
|
||||||
|
Assert.Equal(item.Number, find[0].Number);
|
||||||
|
num = num - 1;
|
||||||
|
item.Number = num;
|
||||||
|
Assert.Equal(1, fsql.Update<tuint256tb_01>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = fsql.Select<tuint256tb_01>().Where(a => a.Id == item.Id).ToList();
|
||||||
|
Assert.Single(find);
|
||||||
|
Assert.Equal("170141183460469231731687303715884105726", find[0].Number.ToString());
|
||||||
|
|
||||||
|
num = BigInteger.Parse("170141183460469231731687303715884105727");
|
||||||
|
fsql.Delete<tuint256tb_01>().Where("1=1").ExecuteAffrows();
|
||||||
|
Assert.Equal(1, fsql.Insert(new tuint256tb_01()).NoneParameter().ExecuteAffrows());
|
||||||
|
find = fsql.Select<tuint256tb_01>().ToList();
|
||||||
|
Assert.Single(find);
|
||||||
|
Assert.Equal("0", find[0].Number.ToString());
|
||||||
|
item = new tuint256tb_01 { Number = num };
|
||||||
|
Assert.Equal(1, fsql.Insert(item).NoneParameter().ExecuteAffrows());
|
||||||
|
find = fsql.Select<tuint256tb_01>().Where(a => a.Id == item.Id).ToList();
|
||||||
|
Assert.Single(find);
|
||||||
|
Assert.Equal(item.Number, find[0].Number);
|
||||||
|
num = num - 1;
|
||||||
|
item.Number = num;
|
||||||
|
Assert.Equal(1, fsql.Update<tuint256tb_01>().NoneParameter().SetSource(item).ExecuteAffrows());
|
||||||
|
find = fsql.Select<tuint256tb_01>().Where(a => a.Id == item.Id).ToList();
|
||||||
|
Assert.Single(find);
|
||||||
|
Assert.Equal("170141183460469231731687303715884105726", find[0].Number.ToString());
|
||||||
|
}
|
||||||
|
class tuint256tb_01
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public BigInteger Number { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
IInsert<TableAllType> insert => fsql.Insert<TableAllType>();
|
||||||
|
ISelect<TableAllType> select => fsql.Select<TableAllType>();
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CurdAllField()
|
||||||
|
{
|
||||||
|
var sql1 = select.Where(a => a.testFieldIntArray.Contains(1)).ToSql();
|
||||||
|
var lst1 = select.Where(a => a.testFieldIntArray.Contains(1)).ToList();
|
||||||
|
|
||||||
|
var item = new TableAllType { };
|
||||||
|
item.Id = (int)insert.AppendData(item).ExecuteIdentity();
|
||||||
|
|
||||||
|
var newitem = select.Where(a => a.Id == item.Id).ToOne();
|
||||||
|
|
||||||
|
var item2 = new TableAllType
|
||||||
|
{
|
||||||
|
testFieldBitArray = new BitArray(Encoding.UTF8.GetBytes("我是")),
|
||||||
|
testFieldBitArrayArray = new[] { new BitArray(Encoding.UTF8.GetBytes("中国")), new BitArray(Encoding.UTF8.GetBytes("公民")) },
|
||||||
|
testFieldBool = true,
|
||||||
|
testFieldBoolArray = new[] { true, true, false, false },
|
||||||
|
testFieldBoolArrayNullable = new bool?[] { true, true, null, false, false },
|
||||||
|
testFieldBoolNullable = true,
|
||||||
|
testFieldByte = byte.MaxValue,
|
||||||
|
testFieldByteArray = new byte[] { 0, 1, 2, 3, 4, 5, 6 },
|
||||||
|
testFieldByteArrayNullable = new byte?[] { 0, 1, 2, 3, null, 4, 5, 6 },
|
||||||
|
testFieldByteNullable = byte.MinValue,
|
||||||
|
testFieldBytes = Encoding.UTF8.GetBytes("我是中国人"),
|
||||||
|
testFieldBytesArray = new[] { Encoding.UTF8.GetBytes("我是中国人"), Encoding.UTF8.GetBytes("我是中国人") },
|
||||||
|
testFieldDateTime = DateTime.Now,
|
||||||
|
testFieldDateTimeArray = new[] { DateTime.Now, DateTime.Now.AddHours(2) },
|
||||||
|
testFieldDateTimeArrayNullable = new DateTime?[] { DateTime.Now, null, DateTime.Now.AddHours(2) },
|
||||||
|
testFieldDateTimeNullable = DateTime.Now.AddDays(-1),
|
||||||
|
testFieldDateOnly = DateOnly.FromDateTime(DateTime.Now),
|
||||||
|
testFieldDateOnlyArray = new[] { DateOnly.FromDateTime(DateTime.Now), DateOnly.FromDateTime(DateTime.Now.AddHours(2)) },
|
||||||
|
testFieldDateOnlyArrayNullable = new DateOnly?[] { DateOnly.FromDateTime(DateTime.Now), null, DateOnly.FromDateTime(DateTime.Now.AddHours(2)) },
|
||||||
|
testFieldDateOnlyNullable = DateOnly.FromDateTime(DateTime.Now.AddDays(-1)),
|
||||||
|
testFieldDecimal = 999.99M,
|
||||||
|
testFieldDecimalArray = new[] { 999.91M, 999.92M, 999.93M },
|
||||||
|
testFieldDecimalArrayNullable = new decimal?[] { 998.11M, 998.12M, 998.13M },
|
||||||
|
testFieldDecimalNullable = 111.11M,
|
||||||
|
testFieldDouble = 888.88,
|
||||||
|
testFieldDoubleArray = new[] { 888.81, 888.82, 888.83 },
|
||||||
|
testFieldDoubleArrayNullable = new double?[] { 888.11, 888.12, null, 888.13 },
|
||||||
|
testFieldDoubleNullable = 222.22,
|
||||||
|
testFieldEnum1 = TableAllTypeEnumType1.e3,
|
||||||
|
testFieldEnum1Array = new[] { TableAllTypeEnumType1.e5, TableAllTypeEnumType1.e2, TableAllTypeEnumType1.e1 },
|
||||||
|
testFieldEnum1ArrayNullable = new TableAllTypeEnumType1?[] { TableAllTypeEnumType1.e5, TableAllTypeEnumType1.e2, null, TableAllTypeEnumType1.e1 },
|
||||||
|
testFieldEnum1Nullable = TableAllTypeEnumType1.e2,
|
||||||
|
testFieldEnum2 = TableAllTypeEnumType2.f2,
|
||||||
|
testFieldEnum2Array = new[] { TableAllTypeEnumType2.f3, TableAllTypeEnumType2.f1 },
|
||||||
|
testFieldEnum2ArrayNullable = new TableAllTypeEnumType2?[] { TableAllTypeEnumType2.f3, null, TableAllTypeEnumType2.f1 },
|
||||||
|
testFieldEnum2Nullable = TableAllTypeEnumType2.f3,
|
||||||
|
testFieldFloat = 777.77F,
|
||||||
|
testFieldFloatArray = new[] { 777.71F, 777.72F, 777.73F },
|
||||||
|
testFieldFloatArrayNullable = new float?[] { 777.71F, 777.72F, null, 777.73F },
|
||||||
|
testFieldFloatNullable = 333.33F,
|
||||||
|
testFieldGuid = Guid.NewGuid(),
|
||||||
|
testFieldGuidArray = new[] { Guid.NewGuid(), Guid.NewGuid() },
|
||||||
|
testFieldGuidArrayNullable = new Guid?[] { Guid.NewGuid(), null, Guid.NewGuid() },
|
||||||
|
testFieldGuidNullable = Guid.NewGuid(),
|
||||||
|
testFieldStruct = new Dictionary<string, object> { { "111", "value111" }, { "222", 222 }, { "333", "value333" } },
|
||||||
|
testFieldStructArray = new[] { new Dictionary<string, object> { { "111", "value111" }, { "222", 222 }, { "333", "value333" } }, new Dictionary<string, object> { { "444", "value444" }, { "555", 555 }, { "666", "value666" } } },
|
||||||
|
testFieldInt = int.MaxValue,
|
||||||
|
testFieldIntArray = new[] { 1, 2, 3, 4, 5 },
|
||||||
|
testFieldIntArrayNullable = new int?[] { 1, 2, 3, null, 4, 5 },
|
||||||
|
testFieldIntNullable = int.MinValue,
|
||||||
|
testFieldLong = long.MaxValue,
|
||||||
|
testFieldLongArray = new long[] { 10, 20, 30, 40, 50 },
|
||||||
|
|
||||||
|
testFieldSByte = sbyte.MaxValue,
|
||||||
|
testFieldSByteArray = new sbyte[] { 1, 2, 3, 4, 5 },
|
||||||
|
testFieldSByteArrayNullable = new sbyte?[] { 1, 2, 3, null, 4, 5 },
|
||||||
|
testFieldSByteNullable = sbyte.MinValue,
|
||||||
|
testFieldShort = short.MaxValue,
|
||||||
|
testFieldShortArray = new short[] { 1, 2, 3, 4, 5 },
|
||||||
|
testFieldShortArrayNullable = new short?[] { 1, 2, 3, null, 4, 5 },
|
||||||
|
testFieldShortNullable = short.MinValue,
|
||||||
|
testFieldString = "我是中国人string'\\?!@#$%^&*()_+{}}{~?><<>",
|
||||||
|
testFieldChar = 'X',
|
||||||
|
testFieldStringArray = new[] { "我是中国人String1", "我是中国人String2", null, "我是中国人String3" },
|
||||||
|
testFieldTimeSpan = TimeSpan.FromHours(11),
|
||||||
|
testFieldTimeSpanArray = new[] { TimeSpan.FromHours(11), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(60) },
|
||||||
|
testFieldTimeSpanArrayNullable = new TimeSpan?[] { TimeSpan.FromHours(11), TimeSpan.FromSeconds(10), null, TimeSpan.FromSeconds(60) },
|
||||||
|
testFieldTimeSpanNullable = TimeSpan.FromSeconds(90),
|
||||||
|
testFieldTimeOnly = TimeOnly.FromTimeSpan(TimeSpan.FromHours(11)),
|
||||||
|
testFieldTimeOnlyArray = new[] { TimeOnly.FromTimeSpan(TimeSpan.FromHours(11)), TimeOnly.FromTimeSpan(TimeSpan.FromSeconds(10)), TimeOnly.FromTimeSpan(TimeSpan.FromSeconds(60)) },
|
||||||
|
testFieldTimeOnlyArrayNullable = new TimeOnly?[] { TimeOnly.FromTimeSpan(TimeSpan.FromHours(11)), TimeOnly.FromTimeSpan(TimeSpan.FromSeconds(10)), null, TimeOnly.FromTimeSpan(TimeSpan.FromSeconds(60)) },
|
||||||
|
testFieldTimeOnlyNullable = TimeOnly.FromTimeSpan(TimeSpan.FromSeconds(90)),
|
||||||
|
testFieldUInt = uint.MaxValue,
|
||||||
|
testFieldUIntArray = new uint[] { 1, 2, 3, 4, 5 },
|
||||||
|
testFieldUIntArrayNullable = new uint?[] { 1, 2, 3, null, 4, 5 },
|
||||||
|
testFieldUIntNullable = uint.MinValue,
|
||||||
|
testFieldULong = ulong.MaxValue,
|
||||||
|
testFieldULongArray = new ulong[] { 10, 20, 30, 40, 50 },
|
||||||
|
testFieldULongArrayNullable = new ulong?[] { 10, 20, 30, null, 40, 50 },
|
||||||
|
testFieldULongNullable = ulong.MinValue,
|
||||||
|
testFieldUShort = ushort.MaxValue,
|
||||||
|
testFieldUShortArray = new ushort[] { 11, 12, 13, 14, 15 },
|
||||||
|
testFieldUShortArrayNullable = new ushort?[] { 11, 12, 13, null, 14, 15 },
|
||||||
|
testFieldUShortNullable = ushort.MinValue,
|
||||||
|
testFielLongArrayNullable = new long?[] { 500, 600, 700, null, 999, 1000 },
|
||||||
|
testFielLongNullable = long.MinValue
|
||||||
|
};
|
||||||
|
|
||||||
|
var sqlPar = insert.AppendData(item2).ToSql();
|
||||||
|
var sqlText = insert.AppendData(item2).NoneParameter().ToSql();
|
||||||
|
var item3NP = insert.AppendData(item2).NoneParameter().ExecuteInserted();
|
||||||
|
|
||||||
|
var item3 = insert.AppendData(item2).ExecuteInserted().First();
|
||||||
|
var newitem2 = select.Where(a => a.Id == item3.Id).ToOne();
|
||||||
|
Assert.Equal(item2.testFieldString, newitem2.testFieldString);
|
||||||
|
Assert.Equal(item2.testFieldChar, newitem2.testFieldChar);
|
||||||
|
|
||||||
|
item3 = insert.NoneParameter().AppendData(item2).ExecuteInserted().First();
|
||||||
|
newitem2 = select.Where(a => a.Id == item3.Id).ToOne();
|
||||||
|
Assert.Equal(item2.testFieldString, newitem2.testFieldString);
|
||||||
|
Assert.Equal(item2.testFieldChar, newitem2.testFieldChar);
|
||||||
|
|
||||||
|
var items = select.ToList();
|
||||||
|
var itemstb = select.ToDataTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Table(Name = "tb_alltype")]
|
||||||
|
class TableAllType
|
||||||
|
{
|
||||||
|
[Column(IsIdentity = true, IsPrimary = true)]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public bool testFieldBool { get; set; }
|
||||||
|
public sbyte testFieldSByte { get; set; }
|
||||||
|
public short testFieldShort { get; set; }
|
||||||
|
public int testFieldInt { get; set; }
|
||||||
|
public long testFieldLong { get; set; }
|
||||||
|
public byte testFieldByte { get; set; }
|
||||||
|
public ushort testFieldUShort { get; set; }
|
||||||
|
public uint testFieldUInt { get; set; }
|
||||||
|
public ulong testFieldULong { get; set; }
|
||||||
|
public double testFieldDouble { get; set; }
|
||||||
|
public float testFieldFloat { get; set; }
|
||||||
|
public decimal testFieldDecimal { get; set; }
|
||||||
|
public TimeSpan testFieldTimeSpan { get; set; }
|
||||||
|
public TimeOnly testFieldTimeOnly{ get; set; }
|
||||||
|
|
||||||
|
[Column(ServerTime = DateTimeKind.Local)]
|
||||||
|
public DateTime testFieldDateTime { get; set; }
|
||||||
|
public DateOnly testFieldDateOnly { get; set; }
|
||||||
|
|
||||||
|
public byte[] testFieldBytes { get; set; }
|
||||||
|
public string testFieldString { get; set; }
|
||||||
|
public char testFieldChar { get; set; }
|
||||||
|
public Guid testFieldGuid { get; set; }
|
||||||
|
|
||||||
|
public bool? testFieldBoolNullable { get; set; }
|
||||||
|
public sbyte? testFieldSByteNullable { get; set; }
|
||||||
|
public short? testFieldShortNullable { get; set; }
|
||||||
|
public int? testFieldIntNullable { get; set; }
|
||||||
|
public long? testFielLongNullable { get; set; }
|
||||||
|
public byte? testFieldByteNullable { get; set; }
|
||||||
|
public ushort? testFieldUShortNullable { get; set; }
|
||||||
|
public uint? testFieldUIntNullable { get; set; }
|
||||||
|
public ulong? testFieldULongNullable { get; set; }
|
||||||
|
public double? testFieldDoubleNullable { get; set; }
|
||||||
|
public float? testFieldFloatNullable { get; set; }
|
||||||
|
public decimal? testFieldDecimalNullable { get; set; }
|
||||||
|
public TimeSpan? testFieldTimeSpanNullable { get; set; }
|
||||||
|
public TimeOnly? testFieldTimeOnlyNullable { get; set; }
|
||||||
|
|
||||||
|
[Column(ServerTime = DateTimeKind.Local)]
|
||||||
|
public DateTime? testFieldDateTimeNullable { get; set; }
|
||||||
|
public DateOnly? testFieldDateOnlyNullable { get; set; }
|
||||||
|
|
||||||
|
public Guid? testFieldGuidNullable { get; set; }
|
||||||
|
|
||||||
|
public BitArray testFieldBitArray { get; set; }
|
||||||
|
public Dictionary<string, object> testFieldStruct { get; set; }
|
||||||
|
|
||||||
|
public TableAllTypeEnumType1 testFieldEnum1 { get; set; }
|
||||||
|
public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; }
|
||||||
|
public TableAllTypeEnumType2 testFieldEnum2 { get; set; }
|
||||||
|
public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; }
|
||||||
|
|
||||||
|
/* array */
|
||||||
|
public bool[] testFieldBoolArray { get; set; }
|
||||||
|
public sbyte[] testFieldSByteArray { get; set; }
|
||||||
|
public short[] testFieldShortArray { get; set; }
|
||||||
|
public int[] testFieldIntArray { get; set; }
|
||||||
|
public long[] testFieldLongArray { get; set; }
|
||||||
|
public byte[] testFieldByteArray { get; set; }
|
||||||
|
public ushort[] testFieldUShortArray { get; set; }
|
||||||
|
public uint[] testFieldUIntArray { get; set; }
|
||||||
|
public ulong[] testFieldULongArray { get; set; }
|
||||||
|
public double[] testFieldDoubleArray { get; set; }
|
||||||
|
public float[] testFieldFloatArray { get; set; }
|
||||||
|
public decimal[] testFieldDecimalArray { get; set; }
|
||||||
|
public TimeSpan[] testFieldTimeSpanArray { get; set; }
|
||||||
|
public TimeOnly[] testFieldTimeOnlyArray { get; set; }
|
||||||
|
public DateTime[] testFieldDateTimeArray { get; set; }
|
||||||
|
public DateOnly[] testFieldDateOnlyArray { get; set; }
|
||||||
|
public byte[][] testFieldBytesArray { get; set; }
|
||||||
|
public string[] testFieldStringArray { get; set; }
|
||||||
|
public Guid[] testFieldGuidArray { get; set; }
|
||||||
|
|
||||||
|
public bool?[] testFieldBoolArrayNullable { get; set; }
|
||||||
|
public sbyte?[] testFieldSByteArrayNullable { get; set; }
|
||||||
|
public short?[] testFieldShortArrayNullable { get; set; }
|
||||||
|
public int?[] testFieldIntArrayNullable { get; set; }
|
||||||
|
public long?[] testFielLongArrayNullable { get; set; }
|
||||||
|
public byte?[] testFieldByteArrayNullable { get; set; }
|
||||||
|
public ushort?[] testFieldUShortArrayNullable { get; set; }
|
||||||
|
public uint?[] testFieldUIntArrayNullable { get; set; }
|
||||||
|
public ulong?[] testFieldULongArrayNullable { get; set; }
|
||||||
|
public double?[] testFieldDoubleArrayNullable { get; set; }
|
||||||
|
public float?[] testFieldFloatArrayNullable { get; set; }
|
||||||
|
public decimal?[] testFieldDecimalArrayNullable { get; set; }
|
||||||
|
public TimeSpan?[] testFieldTimeSpanArrayNullable { get; set; }
|
||||||
|
public TimeOnly?[] testFieldTimeOnlyArrayNullable { get; set; }
|
||||||
|
public DateTime?[] testFieldDateTimeArrayNullable { get; set; }
|
||||||
|
public DateOnly?[] testFieldDateOnlyArrayNullable { get; set; }
|
||||||
|
public Guid?[] testFieldGuidArrayNullable { get; set; }
|
||||||
|
|
||||||
|
public BitArray[] testFieldBitArrayArray { get; set; }
|
||||||
|
public Dictionary<string, object>[] testFieldStructArray { get; set; }
|
||||||
|
|
||||||
|
public TableAllTypeEnumType1[] testFieldEnum1Array { get; set; }
|
||||||
|
public TableAllTypeEnumType1?[] testFieldEnum1ArrayNullable { get; set; }
|
||||||
|
public TableAllTypeEnumType2[] testFieldEnum2Array { get; set; }
|
||||||
|
public TableAllTypeEnumType2?[] testFieldEnum2ArrayNullable { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum TableAllTypeEnumType1 { e1, e2, e3, e5 }
|
||||||
|
[Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
using FreeSql.DataAnnotations;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace FreeSql.Tests.Duckdb
|
||||||
|
{
|
||||||
|
public class DuckdbDbFirstTest
|
||||||
|
{
|
||||||
|
IFreeSql fsql => g.duckdb;
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetDatabases()
|
||||||
|
{
|
||||||
|
var t1 = fsql.DbFirst.GetDatabases();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetTablesByDatabase()
|
||||||
|
{
|
||||||
|
var t2 = fsql.DbFirst.GetTablesByDatabase(fsql.DbFirst.GetDatabases()[0]);
|
||||||
|
Assert.True(t2.Count > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetTableByName()
|
||||||
|
{
|
||||||
|
fsql.Ado.ExecuteNonQuery(@"CREATE TABLE IF NOT EXISTS table_test
|
||||||
|
(
|
||||||
|
id integer NOT NULL,
|
||||||
|
coin_list decimal[],
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
)");
|
||||||
|
var t111 = fsql.DbFirst.GetTableByName("table_test");
|
||||||
|
Assert.True(t111.Columns.Find(a => a.Name == "id").IsPrimary);
|
||||||
|
Assert.False(t111.Columns.Find(a => a.Name == "coin_list").IsPrimary);
|
||||||
|
|
||||||
|
var t1 = fsql.DbFirst.GetTableByName("tb_alltype");
|
||||||
|
var t2 = fsql.DbFirst.GetTableByName("main.tb_alltype");
|
||||||
|
Assert.NotNull(t1);
|
||||||
|
Assert.NotNull(t2);
|
||||||
|
Assert.True(t1.Columns.Count > 0);
|
||||||
|
Assert.True(t2.Columns.Count > 0);
|
||||||
|
Assert.Equal(t1.Columns.Count, t2.Columns.Count);
|
||||||
|
var t3 = fsql.DbFirst.GetTableByName("notexists_tb");
|
||||||
|
Assert.Null(t3);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ExistsTable()
|
||||||
|
{
|
||||||
|
Assert.False(fsql.DbFirst.ExistsTable("test_existstb01"));
|
||||||
|
Assert.False(fsql.DbFirst.ExistsTable("main.test_existstb01"));
|
||||||
|
Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false));
|
||||||
|
Assert.False(fsql.DbFirst.ExistsTable("main.test_existstb01", false));
|
||||||
|
fsql.CodeFirst.SyncStructure(typeof(test_existstb01));
|
||||||
|
Assert.True(fsql.DbFirst.ExistsTable("test_existstb01"));
|
||||||
|
Assert.True(fsql.DbFirst.ExistsTable("main.test_existstb01"));
|
||||||
|
Assert.False(fsql.DbFirst.ExistsTable("Test_existstb01", false));
|
||||||
|
Assert.False(fsql.DbFirst.ExistsTable("main.Test_existstb01", false));
|
||||||
|
fsql.Ado.ExecuteNonQuery("drop table test_existstb01");
|
||||||
|
}
|
||||||
|
class test_existstb01
|
||||||
|
{
|
||||||
|
public Guid id { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,169 @@
|
|||||||
|
using FreeSql.DataAnnotations;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace FreeSql.Tests.DuckdbExpression
|
||||||
|
{
|
||||||
|
public class ConvertTest
|
||||||
|
{
|
||||||
|
IFreeSql fsql => g.duckdb;
|
||||||
|
ISelect<Topic> select => fsql.Select<Topic>();
|
||||||
|
|
||||||
|
[Table(Name = "tb_topic")]
|
||||||
|
class Topic
|
||||||
|
{
|
||||||
|
[Column(IsIdentity = true, IsPrimary = true)]
|
||||||
|
public int Id { get; set; }
|
||||||
|
public int Clicks { get; set; }
|
||||||
|
public int TypeGuid { get; set; }
|
||||||
|
public TestTypeInfo Type { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
}
|
||||||
|
class TestTypeInfo
|
||||||
|
{
|
||||||
|
public int Guid { get; set; }
|
||||||
|
public int ParentId { get; set; }
|
||||||
|
public TestTypeParentInfo Parent { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
class TestTypeParentInfo
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public List<TestTypeInfo> Types { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ToBoolean()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList());
|
||||||
|
data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void ToByte()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList());
|
||||||
|
data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void ToChar()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
//data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList());
|
||||||
|
//data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void ToDateTime()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList());
|
||||||
|
data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void ToDecimal()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList());
|
||||||
|
data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void ToDouble()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList());
|
||||||
|
data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void ToInt16()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList());
|
||||||
|
data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void ToInt32()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => (int)a.Clicks > 0).ToList());
|
||||||
|
data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList());
|
||||||
|
data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void ToInt64()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList());
|
||||||
|
data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void ToSByte()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList());
|
||||||
|
data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void ToSingle()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList());
|
||||||
|
data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void this_ToString()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList());
|
||||||
|
data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void ToUInt16()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList());
|
||||||
|
data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void ToUInt32()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList());
|
||||||
|
data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void ToUInt64()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList());
|
||||||
|
data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Guid_Parse()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Guid_NewGuid()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
//data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Random()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList());
|
||||||
|
data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,591 @@
|
|||||||
|
using FreeSql.DataAnnotations;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace FreeSql.Tests.DuckdbExpression
|
||||||
|
{
|
||||||
|
public class DateTimeTest
|
||||||
|
{
|
||||||
|
IFreeSql fsql => g.duckdb;
|
||||||
|
ISelect<Topic> select => fsql.Select<Topic>();
|
||||||
|
|
||||||
|
[Table(Name = "tb_topic111333")]
|
||||||
|
class Topic
|
||||||
|
{
|
||||||
|
[Column(IsIdentity = true, IsPrimary = true)]
|
||||||
|
public int Id { get; set; }
|
||||||
|
public int Clicks { get; set; }
|
||||||
|
public int TypeGuid { get; set; }
|
||||||
|
public TestTypeInfo Type { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
}
|
||||||
|
[Table(Name = "TestTypeInfo333")]
|
||||||
|
class TestTypeInfo
|
||||||
|
{
|
||||||
|
[Column(IsIdentity = true)]
|
||||||
|
public int Guid { get; set; }
|
||||||
|
public int ParentId { get; set; }
|
||||||
|
public TestTypeParentInfo Parent { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public DateTime Time { get; set; }
|
||||||
|
}
|
||||||
|
[Table(Name = "TestTypeParentInfo23123")]
|
||||||
|
class TestTypeParentInfo
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public List<TestTypeInfo> Types { get; set; }
|
||||||
|
public DateTime Time2 { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void this_ToString()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now()));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now()));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now()))
|
||||||
|
|
||||||
|
fsql.Insert(new Topic()).ExecuteAffrows();
|
||||||
|
var dtn = DateTime.Parse("2020-1-1 0:0:0");
|
||||||
|
var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a))
|
||||||
|
.Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a)))
|
||||||
|
.Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a)))
|
||||||
|
.Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a)))
|
||||||
|
.Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a)));
|
||||||
|
foreach (var dt in dts)
|
||||||
|
{
|
||||||
|
Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString()));
|
||||||
|
Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss")));
|
||||||
|
Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm")));
|
||||||
|
Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH")));
|
||||||
|
Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd")));
|
||||||
|
Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM")));
|
||||||
|
Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss")));
|
||||||
|
Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm")));
|
||||||
|
Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH")));
|
||||||
|
Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd")));
|
||||||
|
Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM")));
|
||||||
|
Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy")));
|
||||||
|
Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss")));
|
||||||
|
Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h")));
|
||||||
|
Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t").Replace("上午", "AM").Replace("下午", "PM").Replace("上", "A").Replace("下", "P"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Now()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime))
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void UtcNow()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime))
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void MinValue()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime))
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void MaxValue()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime))
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Date()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void TimeOfDay()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000))
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void DayOfWeek()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1))
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Day()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now()));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now()));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now()))
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void DayOfYear()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (dayofyear(a.`CreateTime`) > dayofyear(now()));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE (dayofyear(a__Type.`Time`) > dayofyear(now()));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now()))
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Month()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (month(a.`CreateTime`) > month(now()));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE (month(a__Type.`Time`) > month(now()));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE (month(a__Type__Parent.`Time2`) > month(now()))
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Year()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (year(a.`CreateTime`) > year(now()));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE (year(a__Type.`Time`) > year(now()));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE (year(a__Type__Parent.`Time2`) > year(now()))
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Hour()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (hour(a.`CreateTime`) > hour(now()));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE (hour(a__Type.`Time`) > hour(now()));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE (hour(a__Type__Parent.`Time2`) > hour(now()))
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Minute()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (minute(a.`CreateTime`) > minute(now()));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE (minute(a__Type.`Time`) > minute(now()));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE (minute(a__Type__Parent.`Time2`) > minute(now()))
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Second()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (second(a.`CreateTime`) > second(now()));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE (second(a__Type.`Time`) > second(now()));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE (second(a__Type__Parent.`Time2`) > second(now()))
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Millisecond()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000))
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void AddDays()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (date_add(a.`CreateTime`, interval (1) day) > now());
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE (date_add(a__Type.`Time`, interval (1) day) > now());
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now())
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void AddHours()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (date_add(a.`CreateTime`, interval (1) hour) > now());
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE (date_add(a__Type.`Time`, interval (1) hour) > now());
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now())
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void AddMilliseconds()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now());
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now());
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now())
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void AddMinutes()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (date_add(a.`CreateTime`, interval (1) minute) > now());
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE (date_add(a__Type.`Time`, interval (1) minute) > now());
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now())
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void AddMonths()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (date_add(a.`CreateTime`, interval (1) month) > now());
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE (date_add(a__Type.`Time`, interval (1) month) > now());
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now())
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void AddSeconds()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (date_add(a.`CreateTime`, interval (1) second) > now());
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE (date_add(a__Type.`Time`, interval (1) second) > now());
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now())
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void AddTicks()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now());
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now());
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now())
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void AddYears()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (date_add(a.`CreateTime`, interval (1) year) > now());
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE (date_add(a__Type.`Time`, interval (1) year) > now());
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now())
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void this_Equals()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE ((date_add(a.`CreateTime`, interval (1) year) = now()));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE ((date_add(a__Type.`Time`, interval (1) year) = now()));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now()))
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void DateTime_Compare()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList());
|
||||||
|
data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (((a.`CreateTime`) - (now())) = 0);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0)
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void DateTime_DaysInMonth()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList());
|
||||||
|
data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList());
|
||||||
|
data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30)
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void DateTime_Equals()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList());
|
||||||
|
data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList());
|
||||||
|
data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE ((date_add(a.`CreateTime`, interval (1) year) = now()));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE ((date_add(a__Type.`Time`, interval (1) year) = now()));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now()))
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void DateTime_IsLeapYear()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList());
|
||||||
|
data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList());
|
||||||
|
data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0))
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void DateTime_Parse()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList());
|
||||||
|
data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList());
|
||||||
|
data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic111333` a
|
||||||
|
//WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now());
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type
|
||||||
|
//WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now());
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9
|
||||||
|
//FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent
|
||||||
|
//WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,156 @@
|
|||||||
|
using FreeSql.DataAnnotations;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace FreeSql.Tests.DuckdbExpression
|
||||||
|
{
|
||||||
|
public class MathTest
|
||||||
|
{
|
||||||
|
IFreeSql fsql => g.duckdb;
|
||||||
|
ISelect<Topic> select => fsql.Select<Topic>();
|
||||||
|
|
||||||
|
[Table(Name = "tb_topic")]
|
||||||
|
class Topic
|
||||||
|
{
|
||||||
|
[Column(IsIdentity = true, IsPrimary = true)]
|
||||||
|
public int Id { get; set; }
|
||||||
|
public int Clicks { get; set; }
|
||||||
|
public int TypeGuid { get; set; }
|
||||||
|
public TestTypeInfo Type { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
}
|
||||||
|
class TestTypeInfo
|
||||||
|
{
|
||||||
|
public int Guid { get; set; }
|
||||||
|
public int ParentId { get; set; }
|
||||||
|
public TestTypeParentInfo Parent { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
class TestTypeParentInfo
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public List<TestTypeInfo> Types { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void PI()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Abs()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Sign()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Floor()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Ceiling()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Round()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList());
|
||||||
|
data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Exp()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Exp(1) == a.Clicks + 1).Limit(10).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Log()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
//data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).Limit(10).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Log10()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
//data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).Limit(10).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Pow()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Pow(2, a.Clicks) == a.Clicks + 1).Limit(10).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Sqrt()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Sqrt(Math.Pow(2, a.Clicks)) == a.Clicks + 1).Limit(10).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Cos()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Cos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).Limit(10).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Sin()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Sin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).Limit(10).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Tan()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Tan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).Limit(10).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Acos()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
//data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Acos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).Limit(10).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Asin()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
//data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Asin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).Limit(10).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Atan()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Atan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).Limit(10).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Atan2()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).Limit(10).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Truncate()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).Limit(10).ToList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,256 @@
|
|||||||
|
using FreeSql.DataAnnotations;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.NetworkInformation;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace FreeSql.Tests.DuckdbExpression
|
||||||
|
{
|
||||||
|
public class OtherTest
|
||||||
|
{
|
||||||
|
IFreeSql fsql => g.duckdb;
|
||||||
|
ISelect<TableAllType> select => fsql.Select<TableAllType>();
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Div()
|
||||||
|
{
|
||||||
|
var t1 = select.Where(a => a.testFieldInt / 3 > 3).Limit(10).ToList();
|
||||||
|
var t2 = select.Where(a => a.testFieldLong / 3 > 3).Limit(10).ToList();
|
||||||
|
var t3 = select.Where(a => a.testFieldShort / 3 > 3).Limit(10).ToList();
|
||||||
|
|
||||||
|
var t4 = select.Where(a => a.testFieldInt / 3.0 > 3).Limit(10).ToList();
|
||||||
|
var t5 = select.Where(a => a.testFieldLong / 3.0 > 3).Limit(10).ToList();
|
||||||
|
var t6 = select.Where(a => a.testFieldShort / 3.0 > 3).Limit(10).ToList();
|
||||||
|
|
||||||
|
var t7 = select.Where(a => a.testFieldDouble / 3 > 3).Limit(10).ToList();
|
||||||
|
var t8 = select.Where(a => a.testFieldDecimal / 3 > 3).Limit(10).ToList();
|
||||||
|
var t9 = select.Where(a => a.testFieldFloat / 3 > 3).Limit(10).ToList();
|
||||||
|
}
|
||||||
|
[Table(DisableSyncStructure = true)]
|
||||||
|
public class Student
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
[Column(MapType = typeof(int))]
|
||||||
|
public bool IsDelete { get; set; }
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Boolean()
|
||||||
|
{
|
||||||
|
var mapintSql01 = fsql.Select<Student>().Where(d => d.IsDelete).ToSql("1");
|
||||||
|
var mapintSql02 = fsql.Select<Student>().Where(d => d.IsDelete == true).ToSql("1");
|
||||||
|
Assert.Equal(mapintSql02, mapintSql01);
|
||||||
|
Assert.Equal(@"SELECT 1
|
||||||
|
FROM ""student"" a
|
||||||
|
WHERE (a.""isdelete"" = 1)", mapintSql01);
|
||||||
|
|
||||||
|
var t1 = select.Where(a => a.testFieldBool == true).Limit(10).ToList();
|
||||||
|
var t2 = select.Where(a => a.testFieldBool != true).Limit(10).ToList();
|
||||||
|
var t3 = select.Where(a => a.testFieldBool == false).Limit(10).ToList();
|
||||||
|
var t4 = select.Where(a => !a.testFieldBool).Limit(10).ToList();
|
||||||
|
var t5 = select.Where(a => a.testFieldBool).Limit(10).ToList();
|
||||||
|
var t51 = select.WhereCascade(a => a.testFieldBool).Limit(10).ToList();
|
||||||
|
|
||||||
|
var t11 = select.Where(a => a.testFieldBoolNullable == true).Limit(10).ToList();
|
||||||
|
var t22 = select.Where(a => a.testFieldBoolNullable != true).Limit(10).ToList();
|
||||||
|
var t33 = select.Where(a => a.testFieldBoolNullable == false).Limit(10).ToList();
|
||||||
|
var t44 = select.Where(a => !a.testFieldBoolNullable.Value).Limit(10).ToList();
|
||||||
|
var t55 = select.Where(a => a.testFieldBoolNullable.Value).Limit(10).ToList();
|
||||||
|
|
||||||
|
var t111 = select.Where(a => a.testFieldBool == true && a.Id > 0).Limit(10).ToList();
|
||||||
|
var t222 = select.Where(a => a.testFieldBool != true && a.Id > 0).Limit(10).ToList();
|
||||||
|
var t333 = select.Where(a => a.testFieldBool == false && a.Id > 0).Limit(10).ToList();
|
||||||
|
var t444 = select.Where(a => !a.testFieldBool && a.Id > 0).Limit(10).ToList();
|
||||||
|
var t555 = select.Where(a => a.testFieldBool && a.Id > 0).Limit(10).ToList();
|
||||||
|
|
||||||
|
var t1111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0).Limit(10).ToList();
|
||||||
|
var t2222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0).Limit(10).ToList();
|
||||||
|
var t3333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0).Limit(10).ToList();
|
||||||
|
var t4444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0).Limit(10).ToList();
|
||||||
|
var t5555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0).Limit(10).ToList();
|
||||||
|
|
||||||
|
var t11111 = select.Where(a => a.testFieldBool == true && a.Id > 0 && a.testFieldBool == true).Limit(10).ToList();
|
||||||
|
var t22222 = select.Where(a => a.testFieldBool != true && a.Id > 0 && a.testFieldBool != true).Limit(10).ToList();
|
||||||
|
var t33333 = select.Where(a => a.testFieldBool == false && a.Id > 0 && a.testFieldBool == false).Limit(10).ToList();
|
||||||
|
var t44444 = select.Where(a => !a.testFieldBool && a.Id > 0 && !a.testFieldBool).Limit(10).ToList();
|
||||||
|
var t55555 = select.Where(a => a.testFieldBool && a.Id > 0 && a.testFieldBool).Limit(10).ToList();
|
||||||
|
|
||||||
|
var t111111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0 && a.testFieldBoolNullable == true).Limit(10).ToList();
|
||||||
|
var t222222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0 && a.testFieldBoolNullable != true).Limit(10).ToList();
|
||||||
|
var t333333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0 && a.testFieldBoolNullable == false).Limit(10).ToList();
|
||||||
|
var t444444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0 && !a.testFieldBoolNullable.Value).Limit(10).ToList();
|
||||||
|
var t555555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0 && a.testFieldBoolNullable.Value).Limit(10).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Array()
|
||||||
|
{
|
||||||
|
//fsql.Aop.CurdAfter = (s, e) => {
|
||||||
|
// Trace.WriteLine(e.CurdType + ": " + e.ElapsedMilliseconds + "ms " + e.Sql.Replace("\n", ""));
|
||||||
|
//};
|
||||||
|
IEnumerable<int> testlinqlist = new List<int>(new[] { 1, 2, 3 });
|
||||||
|
var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList();
|
||||||
|
|
||||||
|
var sql1 = select.Where(a => a.testFieldIntArray.Contains(1)).ToList();
|
||||||
|
var sql2 = select.Where(a => a.testFieldIntArray.Contains(1) == false).ToList();
|
||||||
|
var sql121 = select.Where(a => a.testFieldStringArray.Contains("aaa") == false).ToList();
|
||||||
|
|
||||||
|
//in not in
|
||||||
|
var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList();
|
||||||
|
var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList();
|
||||||
|
var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList();
|
||||||
|
|
||||||
|
var inarray = new[] { 1, 2, 3 };
|
||||||
|
var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToSql();
|
||||||
|
var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToSql();
|
||||||
|
var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToSql();
|
||||||
|
|
||||||
|
//in not in
|
||||||
|
var sql11111 = select.Where(a => new List<int>() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList();
|
||||||
|
var sql11222 = select.Where(a => new List<int>() { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList();
|
||||||
|
var sql11333 = select.Where(a => !new List<int>() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList();
|
||||||
|
|
||||||
|
var sql11111a = select.Where(a => new List<int>(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList();
|
||||||
|
var sql11222b = select.Where(a => new List<int>(new[] { 1, 2, 3 }).Contains(a.testFieldInt) == false).ToList();
|
||||||
|
var sql11333c = select.Where(a => !new List<int>(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList();
|
||||||
|
|
||||||
|
var inarray2 = new List<int>() { 1, 2, 3 };
|
||||||
|
var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList();
|
||||||
|
var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList();
|
||||||
|
var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList();
|
||||||
|
|
||||||
|
var sql1111112 = select.ToList(a => inarray);
|
||||||
|
var sql1111113 = select.ToList(a => a.testFieldIntArray);
|
||||||
|
|
||||||
|
|
||||||
|
var sql3 = select.Where(a => a.testFieldIntArray.Any()).ToList();
|
||||||
|
var sql4 = select.Where(a => a.testFieldIntArray.Any() == false).ToList();
|
||||||
|
|
||||||
|
//var sql5 = select.ToList(a => a.testFieldIntArray.Concat(new[] { 1, 2, 3 }));
|
||||||
|
//v5.0.1.1 Unable to cast object of type 'System.Nullable`1[System.Int32][]' to type 'System.Collections.Generic.IEnumerable`1[System.Int32]'.
|
||||||
|
|
||||||
|
var sql6 = select.Where(a => a.testFieldIntArray.GetLength(1) > 0).ToList();
|
||||||
|
var sql7 = select.Where(a => a.testFieldIntArray.GetLongLength(1) > 0).ToList();
|
||||||
|
var sql8 = select.Where(a => a.testFieldIntArray.Length > 0).ToList();
|
||||||
|
var sql9 = select.Where(a => a.testFieldIntArray.Count() > 0).ToList();
|
||||||
|
|
||||||
|
var inarray2n = Enumerable.Range(1, 3333).ToArray();
|
||||||
|
var sql1111111 = select.Where(a => inarray2n.Contains(a.testFieldInt)).ToList();
|
||||||
|
var sql1122222 = select.Where(a => inarray2n.Contains(a.testFieldInt) == false).ToList();
|
||||||
|
var sql1133333 = select.Where(a => !inarray2n.Contains(a.testFieldInt)).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Table(Name = "tb_alltype")]
|
||||||
|
class TableAllType
|
||||||
|
{
|
||||||
|
[Column(IsIdentity = true, IsPrimary = true)]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public bool testFieldBool { get; set; }
|
||||||
|
public sbyte testFieldSByte { get; set; }
|
||||||
|
public short testFieldShort { get; set; }
|
||||||
|
public int testFieldInt { get; set; }
|
||||||
|
public long testFieldLong { get; set; }
|
||||||
|
public byte testFieldByte { get; set; }
|
||||||
|
public ushort testFieldUShort { get; set; }
|
||||||
|
public uint testFieldUInt { get; set; }
|
||||||
|
public ulong testFieldULong { get; set; }
|
||||||
|
public double testFieldDouble { get; set; }
|
||||||
|
public float testFieldFloat { get; set; }
|
||||||
|
public decimal testFieldDecimal { get; set; }
|
||||||
|
public TimeSpan testFieldTimeSpan { get; set; }
|
||||||
|
public TimeOnly testFieldTimeOnly { get; set; }
|
||||||
|
|
||||||
|
[Column(ServerTime = DateTimeKind.Local)]
|
||||||
|
public DateTime testFieldDateTime { get; set; }
|
||||||
|
public DateOnly testFieldDateOnly { get; set; }
|
||||||
|
|
||||||
|
public byte[] testFieldBytes { get; set; }
|
||||||
|
public string testFieldString { get; set; }
|
||||||
|
public char testFieldChar { get; set; }
|
||||||
|
public Guid testFieldGuid { get; set; }
|
||||||
|
|
||||||
|
public bool? testFieldBoolNullable { get; set; }
|
||||||
|
public sbyte? testFieldSByteNullable { get; set; }
|
||||||
|
public short? testFieldShortNullable { get; set; }
|
||||||
|
public int? testFieldIntNullable { get; set; }
|
||||||
|
public long? testFielLongNullable { get; set; }
|
||||||
|
public byte? testFieldByteNullable { get; set; }
|
||||||
|
public ushort? testFieldUShortNullable { get; set; }
|
||||||
|
public uint? testFieldUIntNullable { get; set; }
|
||||||
|
public ulong? testFieldULongNullable { get; set; }
|
||||||
|
public double? testFieldDoubleNullable { get; set; }
|
||||||
|
public float? testFieldFloatNullable { get; set; }
|
||||||
|
public decimal? testFieldDecimalNullable { get; set; }
|
||||||
|
public TimeSpan? testFieldTimeSpanNullable { get; set; }
|
||||||
|
public TimeOnly? testFieldTimeOnlyNullable { get; set; }
|
||||||
|
|
||||||
|
[Column(ServerTime = DateTimeKind.Local)]
|
||||||
|
public DateTime? testFieldDateTimeNullable { get; set; }
|
||||||
|
public DateOnly? testFieldDateOnlyNullable { get; set; }
|
||||||
|
|
||||||
|
public Guid? testFieldGuidNullable { get; set; }
|
||||||
|
|
||||||
|
public BitArray testFieldBitArray { get; set; }
|
||||||
|
public Dictionary<string, object> testFieldStruct { get; set; }
|
||||||
|
|
||||||
|
public TableAllTypeEnumType1 testFieldEnum1 { get; set; }
|
||||||
|
public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; }
|
||||||
|
public TableAllTypeEnumType2 testFieldEnum2 { get; set; }
|
||||||
|
public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; }
|
||||||
|
|
||||||
|
/* array */
|
||||||
|
public bool[] testFieldBoolArray { get; set; }
|
||||||
|
public sbyte[] testFieldSByteArray { get; set; }
|
||||||
|
public short[] testFieldShortArray { get; set; }
|
||||||
|
public int[] testFieldIntArray { get; set; }
|
||||||
|
public long[] testFieldLongArray { get; set; }
|
||||||
|
public byte[] testFieldByteArray { get; set; }
|
||||||
|
public ushort[] testFieldUShortArray { get; set; }
|
||||||
|
public uint[] testFieldUIntArray { get; set; }
|
||||||
|
public ulong[] testFieldULongArray { get; set; }
|
||||||
|
public double[] testFieldDoubleArray { get; set; }
|
||||||
|
public float[] testFieldFloatArray { get; set; }
|
||||||
|
public decimal[] testFieldDecimalArray { get; set; }
|
||||||
|
public TimeSpan[] testFieldTimeSpanArray { get; set; }
|
||||||
|
public TimeOnly[] testFieldTimeOnlyArray { get; set; }
|
||||||
|
public DateTime[] testFieldDateTimeArray { get; set; }
|
||||||
|
public DateOnly[] testFieldDateOnlyArray { get; set; }
|
||||||
|
public byte[][] testFieldBytesArray { get; set; }
|
||||||
|
public string[] testFieldStringArray { get; set; }
|
||||||
|
public Guid[] testFieldGuidArray { get; set; }
|
||||||
|
|
||||||
|
public bool?[] testFieldBoolArrayNullable { get; set; }
|
||||||
|
public sbyte?[] testFieldSByteArrayNullable { get; set; }
|
||||||
|
public short?[] testFieldShortArrayNullable { get; set; }
|
||||||
|
public int?[] testFieldIntArrayNullable { get; set; }
|
||||||
|
public long?[] testFielLongArrayNullable { get; set; }
|
||||||
|
public byte?[] testFieldByteArrayNullable { get; set; }
|
||||||
|
public ushort?[] testFieldUShortArrayNullable { get; set; }
|
||||||
|
public uint?[] testFieldUIntArrayNullable { get; set; }
|
||||||
|
public ulong?[] testFieldULongArrayNullable { get; set; }
|
||||||
|
public double?[] testFieldDoubleArrayNullable { get; set; }
|
||||||
|
public float?[] testFieldFloatArrayNullable { get; set; }
|
||||||
|
public decimal?[] testFieldDecimalArrayNullable { get; set; }
|
||||||
|
public TimeSpan?[] testFieldTimeSpanArrayNullable { get; set; }
|
||||||
|
public TimeOnly?[] testFieldTimeOnlyArrayNullable { get; set; }
|
||||||
|
public DateTime?[] testFieldDateTimeArrayNullable { get; set; }
|
||||||
|
public DateOnly?[] testFieldDateOnlyArrayNullable { get; set; }
|
||||||
|
public Guid?[] testFieldGuidArrayNullable { get; set; }
|
||||||
|
|
||||||
|
public BitArray[] testFieldBitArrayArray { get; set; }
|
||||||
|
public Dictionary<string, object>[] testFieldStructArray { get; set; }
|
||||||
|
|
||||||
|
public TableAllTypeEnumType1[] testFieldEnum1Array { get; set; }
|
||||||
|
public TableAllTypeEnumType1?[] testFieldEnum1ArrayNullable { get; set; }
|
||||||
|
public TableAllTypeEnumType2[] testFieldEnum2Array { get; set; }
|
||||||
|
public TableAllTypeEnumType2?[] testFieldEnum2ArrayNullable { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum TableAllTypeEnumType1 { e1, e2, e3, e5 }
|
||||||
|
[Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,831 @@
|
|||||||
|
using FreeSql.DataAnnotations;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace FreeSql.Tests.DuckdbExpression
|
||||||
|
{
|
||||||
|
public class StringTest
|
||||||
|
{
|
||||||
|
IFreeSql fsql => g.duckdb;
|
||||||
|
ISelect<Topic> select => fsql.Select<Topic>();
|
||||||
|
|
||||||
|
[Table(Name = "tb_topic")]
|
||||||
|
class Topic
|
||||||
|
{
|
||||||
|
[Column(IsIdentity = true, IsPrimary = true)]
|
||||||
|
public int Id { get; set; }
|
||||||
|
public int Clicks { get; set; }
|
||||||
|
public int TypeGuid { get; set; }
|
||||||
|
public TestTypeInfo Type { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
}
|
||||||
|
class TestTypeInfo
|
||||||
|
{
|
||||||
|
[Column(IsIdentity = true)]
|
||||||
|
public int Guid { get; set; }
|
||||||
|
public int ParentId { get; set; }
|
||||||
|
public TestTypeParentInfo Parent { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
class TestTypeParentInfo
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public List<TestTypeInfo> Types { get; set; }
|
||||||
|
}
|
||||||
|
class TestEqualsGuid
|
||||||
|
{
|
||||||
|
public Guid id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Equals__()
|
||||||
|
{
|
||||||
|
var list = new List<object>();
|
||||||
|
list.Add(select.Where(a => a.Title.Equals("aaa")).ToList());
|
||||||
|
list.Add(fsql.Select<TestEqualsGuid>().Where(a => a.id.Equals(Guid.Empty)).ToList());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void StringJoin()
|
||||||
|
{
|
||||||
|
fsql.Delete<StringJoin01>().Where("1=1").ExecuteAffrows();
|
||||||
|
fsql.Insert(new[] { new StringJoin01 { name = "北京" }, new StringJoin01 { name = "上海" }, new StringJoin01 { name = "深圳" }, }).ExecuteAffrows();
|
||||||
|
|
||||||
|
var val1 = string.Join(",", fsql.Select<StringJoin01>().ToList(a => a.name));
|
||||||
|
var val2 = fsql.Select<StringJoin01>().ToList(a => string.Join(",", fsql.Select<StringJoin01>().As("b").ToList(b => b.name)));
|
||||||
|
Assert.Equal(val1, val2[0]);
|
||||||
|
|
||||||
|
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.name));
|
||||||
|
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.name)));
|
||||||
|
Assert.Equal(val1, val2[0]);
|
||||||
|
|
||||||
|
val1 = string.Join(",", fsql.Select<StringJoin01>().ToList(a => a.id));
|
||||||
|
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join(",", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
|
||||||
|
Assert.Equal(val1, val2[0]);
|
||||||
|
|
||||||
|
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.id));
|
||||||
|
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
|
||||||
|
Assert.Equal(val1, val2[0]);
|
||||||
|
|
||||||
|
//fsql.GlobalFilter.Apply<StringJoin01>("test001", a => a.name.Length > 0);
|
||||||
|
//val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
|
||||||
|
}
|
||||||
|
class StringJoin01
|
||||||
|
{
|
||||||
|
[Column(IsIdentity = true)]
|
||||||
|
public int id { get; set; }
|
||||||
|
public string name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void First()
|
||||||
|
{
|
||||||
|
Assert.Equal('x', select.First(a => "x1".First()));
|
||||||
|
Assert.Equal('z', select.First(a => "z1".First()));
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void FirstOrDefault()
|
||||||
|
{
|
||||||
|
Assert.Equal('x', select.First(a => "x1".FirstOrDefault()));
|
||||||
|
Assert.Equal('z', select.First(a => "z1".FirstOrDefault()));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Format()
|
||||||
|
{
|
||||||
|
var item = fsql.GetRepository<Topic>().Insert(new Topic { Clicks = 101, Title = "我是中国人101", CreateTime = DateTime.Parse("2020-7-5") });
|
||||||
|
var sql = select.WhereDynamic(item).ToSql(a => new
|
||||||
|
{
|
||||||
|
str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}",
|
||||||
|
str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title)
|
||||||
|
});
|
||||||
|
Assert.Equal($@"SELECT 'x'||coalesce(((a.""id"" + 1))::text, '')||'z-'||coalesce(strftime(a.""createtime"",'%Y%m'), '')||''||coalesce(a.""title"", '')||'' as1, ''||coalesce(((a.""id"" + 1))::text, '')||'x'||coalesce(((a.""id"" + 1))::text, '')||'z-'||coalesce(strftime(a.""createtime"",'%Y%m'), '')||''||coalesce(a.""title"", '')||'' as2
|
||||||
|
FROM ""tb_topic"" a
|
||||||
|
WHERE (a.""id"" = {item.Id})", sql);
|
||||||
|
|
||||||
|
var item2 = select.WhereDynamic(item).First(a => new
|
||||||
|
{
|
||||||
|
str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}",
|
||||||
|
str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title)
|
||||||
|
});
|
||||||
|
Assert.NotNull(item2);
|
||||||
|
Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str);
|
||||||
|
Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Format4()
|
||||||
|
{
|
||||||
|
//3个 {} 时,Arguments 解析出来是分开的
|
||||||
|
//4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray []
|
||||||
|
var item = fsql.GetRepository<Topic>().Insert(new Topic { Clicks = 101, Title = "我是中国人101", CreateTime = DateTime.Parse("2020-7-5") });
|
||||||
|
var sql = select.WhereDynamic(item).ToSql(a => new
|
||||||
|
{
|
||||||
|
str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}",
|
||||||
|
str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title)
|
||||||
|
});
|
||||||
|
Assert.Equal($@"SELECT 'x'||coalesce(((a.""id"" + 1))::text, '')||'z-'||coalesce(strftime(a.""createtime"",'%Y%m'), '')||''||coalesce(a.""title"", '')||''||coalesce(a.""title"", '')||'' as1, ''||coalesce(((a.""id"" + 1))::text, '')||'x'||coalesce(((a.""id"" + 1))::text, '')||'z-'||coalesce(strftime(a.""createtime"",'%Y%m'), '')||''||coalesce(a.""title"", '')||''||coalesce(a.""title"", '')||'' as2
|
||||||
|
FROM ""tb_topic"" a
|
||||||
|
WHERE (a.""id"" = {item.Id})", sql);
|
||||||
|
|
||||||
|
var item2 = select.WhereDynamic(item).First(a => new
|
||||||
|
{
|
||||||
|
str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}",
|
||||||
|
str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title)
|
||||||
|
});
|
||||||
|
Assert.NotNull(item2);
|
||||||
|
Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str);
|
||||||
|
Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Empty()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (ifnull(a.`Title`, '') = '')
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void StartsWith()
|
||||||
|
{
|
||||||
|
var list = new List<object>();
|
||||||
|
list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList());
|
||||||
|
list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList());
|
||||||
|
list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList());
|
||||||
|
list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE((a.`Title`) LIKE '%aaa')
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE((a.`Title`) LIKE concat('%', a.`Title`))
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1)))
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`))
|
||||||
|
list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList());
|
||||||
|
list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList());
|
||||||
|
list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList());
|
||||||
|
list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa')
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`))
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1)))
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`))
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void EndsWith()
|
||||||
|
{
|
||||||
|
var list = new List<object>();
|
||||||
|
list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList());
|
||||||
|
list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList());
|
||||||
|
list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList());
|
||||||
|
list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE((a.`Title`) LIKE 'aaa%')
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE((a.`Title`) LIKE concat(a.`Title`, '%'))
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%'))
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE((a.`Title`) LIKE concat(a__Type.`Name`, '%'))
|
||||||
|
list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList());
|
||||||
|
list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList());
|
||||||
|
list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList());
|
||||||
|
list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%')
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%'))
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%'))
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%'))
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Contains()
|
||||||
|
{
|
||||||
|
var list = new List<object>();
|
||||||
|
list.Add(select.Where(a => a.Title.Contains("aaa")).ToList());
|
||||||
|
list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList());
|
||||||
|
list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList());
|
||||||
|
list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE((a.`Title`) LIKE '%aaa%')
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%'))
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%'))
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE((a.`Title`) LIKE concat('%', a__Type.`Name`, '%'))
|
||||||
|
list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList());
|
||||||
|
list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList());
|
||||||
|
list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList());
|
||||||
|
list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%')
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%'))
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%'))
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%'))
|
||||||
|
|
||||||
|
|
||||||
|
list.Add(select.Where(a => a.Title.Contains("%")).ToList());
|
||||||
|
list.Add(select.Where(a => a.Title.Contains(a.Title + "%")).ToList());
|
||||||
|
list.Add(select.Where(a => a.Title.Contains(a.Title + 1 + "%")).ToList());
|
||||||
|
list.Add(select.Where(a => a.Title.Contains(a.Type.Name + "%")).ToList());
|
||||||
|
|
||||||
|
list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa" + "%")).ToList());
|
||||||
|
list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + "%")).ToList());
|
||||||
|
list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1 + "%")).ToList());
|
||||||
|
list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name + "%")).ToList());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void ToLower()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE(lower(a.`Title`) = 'aaa');
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE(lower(a.`Title`) = a.`Title`);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE(lower(a.`Title`) = concat(a.`Title`, 1));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE(lower(a.`Title`) = a__Type.`Name`);
|
||||||
|
data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa');
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`)
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void ToUpper()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (upper(a.`Title`) = 'aaa');
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (upper(a.`Title`) = a.`Title`);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (upper(a.`Title`) = concat(a.`Title`, 1));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE (upper(a.`Title`) = a__Type.`Name`);
|
||||||
|
data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa');
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`)
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Substring()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (substr(a.`Title`, 1) = 'aaa');
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (substr(a.`Title`, 1) = a.`Title`);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE (substr(a.`Title`, 1) = a__Type.`Name`);
|
||||||
|
data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa');
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`)
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Length()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.Title.Length == 0).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.Length == 1).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (char_length(a.`Title`) = 0);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (char_length(a.`Title`) = 1);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE (char_length(a.`Title`) = char_length(a__Type.`Name`));
|
||||||
|
data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (char_length(concat(a.`Title`, 'aaa')) = 0);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (char_length(concat(a.`Title`, 'aaa')) = 1);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`))
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void IndexOf()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE ((locate(a.`Title`, 'aaa') - 1) = -1);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1);
|
||||||
|
data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1)
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void PadLeft()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (lpad(a.`Title`, 10, 'a') = 'aaa');
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE (lpad(a.`Title`, 10, 'a') = a__Type.`Name`);
|
||||||
|
data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa');
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`)
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void PadRight()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (rpad(a.`Title`, 10, 'a') = 'aaa');
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE (rpad(a.`Title`, 10, 'a') = a__Type.`Name`);
|
||||||
|
data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa');
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`)
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Trim()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (trim(a.`Title`) = 'aaa');
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (trim('a' from a.`Title`) = a.`Title`);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`);
|
||||||
|
data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa');
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`)
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void TrimStart()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (ltrim(a.`Title`) = 'aaa');
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`);
|
||||||
|
data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa');
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`)
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void TrimEnd()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (rtrim(a.`Title`) = 'aaa');
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`);
|
||||||
|
data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa');
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`)
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void Replace()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (replace(a.`Title`, 'a', 'b') = 'aaa');
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`);
|
||||||
|
data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa');
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1));
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`)
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void CompareTo()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList());
|
||||||
|
data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (strcmp(a.`Title`, a.`Title`) = 0);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (strcmp(a.`Title`, a.`Title`) > 0);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0);
|
||||||
|
data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList());
|
||||||
|
data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList());
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5
|
||||||
|
//FROM `tb_topic` a
|
||||||
|
//WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0);
|
||||||
|
|
||||||
|
//SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8
|
||||||
|
//FROM `tb_topic` a, `TestTypeInfo` a__Type
|
||||||
|
//WHERE (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void string_IsNullOrEmpty()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList());
|
||||||
|
data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList());
|
||||||
|
data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void string_IsNullOrWhiteSpace()
|
||||||
|
{
|
||||||
|
var data = new List<object>();
|
||||||
|
data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList());
|
||||||
|
data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title) == false).ToList());
|
||||||
|
data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,56 @@
|
|||||||
|
using FreeSql.DataAnnotations;
|
||||||
|
using System;
|
||||||
|
using System.Numerics;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace FreeSql.Tests.DuckdbMapType
|
||||||
|
{
|
||||||
|
public class DateTimeOffSetTest
|
||||||
|
{
|
||||||
|
IFreeSql fsql => g.duckdb;
|
||||||
|
|
||||||
|
class DateTimeOffSetTestMap
|
||||||
|
{
|
||||||
|
public Guid id { get; set; }
|
||||||
|
|
||||||
|
[Column(MapType = typeof(DateTime))]
|
||||||
|
public DateTimeOffset dtos_to_dt { get; set; }
|
||||||
|
[Column(MapType = typeof(DateTime))]
|
||||||
|
public DateTimeOffset? dtosnullable_to_dt { get; set; }
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void DateTimeToDateTimeOffSet()
|
||||||
|
{
|
||||||
|
//insert
|
||||||
|
var orm = fsql;
|
||||||
|
var item = new DateTimeOffSetTestMap { dtos_to_dt = DateTimeOffset.Now, dtosnullable_to_dt = DateTimeOffset.Now };
|
||||||
|
Assert.Equal(1, orm.Insert<DateTimeOffSetTestMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
var find = orm.Select<DateTimeOffSetTestMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g"));
|
||||||
|
Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g"));
|
||||||
|
|
||||||
|
//update all
|
||||||
|
item.dtos_to_dt = DateTimeOffset.Now;
|
||||||
|
Assert.Equal(1, orm.Update<DateTimeOffSetTestMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<DateTimeOffSetTestMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g"));
|
||||||
|
Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g"));
|
||||||
|
|
||||||
|
//update set
|
||||||
|
Assert.Equal(1, orm.Update<DateTimeOffSetTestMap>().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows());
|
||||||
|
find = orm.Select<DateTimeOffSetTestMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g"));
|
||||||
|
Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g"));
|
||||||
|
|
||||||
|
//delete
|
||||||
|
Assert.Equal(1, orm.Delete<DateTimeOffSetTestMap>().Where(a => a.id == item.id).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<DateTimeOffSetTestMap>().Where(a => a.id == item.id).First());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,263 @@
|
|||||||
|
using FreeSql.DataAnnotations;
|
||||||
|
using System;
|
||||||
|
using System.Numerics;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace FreeSql.Tests.DuckdbMapType
|
||||||
|
{
|
||||||
|
public class EnumTest
|
||||||
|
{
|
||||||
|
IFreeSql fsql => g.duckdb;
|
||||||
|
|
||||||
|
class EnumTestMap
|
||||||
|
{
|
||||||
|
public Guid id { get; set; }
|
||||||
|
|
||||||
|
[Column(MapType = typeof(string))]
|
||||||
|
public ToStringMapEnum enum_to_string { get; set; }
|
||||||
|
[Column(MapType = typeof(string))]
|
||||||
|
public ToStringMapEnum? enumnullable_to_string { get; set; }
|
||||||
|
|
||||||
|
[Column(MapType = typeof(int))]
|
||||||
|
public ToStringMapEnum enum_to_int { get; set; }
|
||||||
|
[Column(MapType = typeof(int?))]
|
||||||
|
public ToStringMapEnum? enumnullable_to_int { get; set; }
|
||||||
|
}
|
||||||
|
public enum ToStringMapEnum { 中国人, abc, 香港 }
|
||||||
|
[Fact]
|
||||||
|
public void EnumToString()
|
||||||
|
{
|
||||||
|
//insert
|
||||||
|
var orm = fsql;
|
||||||
|
var item = new EnumTestMap { };
|
||||||
|
Assert.Equal(1, orm.Insert<EnumTestMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
var find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.中国人).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enum_to_string, find.enum_to_string);
|
||||||
|
Assert.Equal(ToStringMapEnum.中国人, find.enum_to_string);
|
||||||
|
|
||||||
|
item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc };
|
||||||
|
Assert.Equal(1, orm.Insert<EnumTestMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enum_to_string, find.enum_to_string);
|
||||||
|
Assert.Equal(ToStringMapEnum.abc, find.enum_to_string);
|
||||||
|
|
||||||
|
//update all
|
||||||
|
item.enum_to_string = ToStringMapEnum.香港;
|
||||||
|
Assert.Equal(1, orm.Update<EnumTestMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.香港).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enum_to_string, find.enum_to_string);
|
||||||
|
Assert.Equal(ToStringMapEnum.香港, find.enum_to_string);
|
||||||
|
|
||||||
|
item.enum_to_string = ToStringMapEnum.中国人;
|
||||||
|
Assert.Equal(1, orm.Update<EnumTestMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.中国人).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enum_to_string, find.enum_to_string);
|
||||||
|
Assert.Equal(ToStringMapEnum.中国人, find.enum_to_string);
|
||||||
|
|
||||||
|
//update set
|
||||||
|
Assert.Equal(1, orm.Update<EnumTestMap>().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.香港).ExecuteAffrows());
|
||||||
|
find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.香港).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(ToStringMapEnum.香港, find.enum_to_string);
|
||||||
|
|
||||||
|
Assert.Equal(1, orm.Update<EnumTestMap>().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows());
|
||||||
|
find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(ToStringMapEnum.abc, find.enum_to_string);
|
||||||
|
|
||||||
|
//delete
|
||||||
|
Assert.Equal(0, orm.Delete<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.中国人).ExecuteAffrows());
|
||||||
|
Assert.Equal(0, orm.Delete<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.香港).ExecuteAffrows());
|
||||||
|
Assert.Equal(1, orm.Delete<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<EnumTestMap>().Where(a => a.id == item.id).First());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void EnumNullableToString()
|
||||||
|
{
|
||||||
|
//insert
|
||||||
|
var orm = fsql;
|
||||||
|
var item = new EnumTestMap { };
|
||||||
|
Assert.Equal(1, orm.Insert<EnumTestMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
var find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_string == null).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string);
|
||||||
|
Assert.Null(find.enumnullable_to_string);
|
||||||
|
|
||||||
|
item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.中国人 };
|
||||||
|
Assert.Equal(1, orm.Insert<EnumTestMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.中国人).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string);
|
||||||
|
Assert.Equal(ToStringMapEnum.中国人, find.enumnullable_to_string);
|
||||||
|
|
||||||
|
//update all
|
||||||
|
item.enumnullable_to_string = ToStringMapEnum.香港;
|
||||||
|
Assert.Equal(1, orm.Update<EnumTestMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.香港).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string);
|
||||||
|
Assert.Equal(ToStringMapEnum.香港, find.enumnullable_to_string);
|
||||||
|
|
||||||
|
item.enumnullable_to_string = null;
|
||||||
|
Assert.Equal(1, orm.Update<EnumTestMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.香港).First());
|
||||||
|
find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_string == null).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string);
|
||||||
|
Assert.Null(find.enumnullable_to_string);
|
||||||
|
|
||||||
|
//update set
|
||||||
|
Assert.Equal(1, orm.Update<EnumTestMap>().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows());
|
||||||
|
find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string);
|
||||||
|
|
||||||
|
|
||||||
|
Assert.Equal(1, orm.Update<EnumTestMap>().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First());
|
||||||
|
find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_string == null).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Null(find.enumnullable_to_string);
|
||||||
|
|
||||||
|
//delete
|
||||||
|
Assert.Equal(0, orm.Delete<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.中国人).ExecuteAffrows());
|
||||||
|
Assert.Equal(0, orm.Delete<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.香港).ExecuteAffrows());
|
||||||
|
Assert.Equal(1, orm.Delete<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<EnumTestMap>().Where(a => a.id == item.id).First());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void EnumToInt()
|
||||||
|
{
|
||||||
|
//insert
|
||||||
|
var orm = fsql;
|
||||||
|
var item = new EnumTestMap { };
|
||||||
|
Assert.Equal(1, orm.Insert<EnumTestMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
var find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.中国人).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enum_to_int, find.enum_to_int);
|
||||||
|
Assert.Equal(ToStringMapEnum.中国人, find.enum_to_int);
|
||||||
|
|
||||||
|
item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc };
|
||||||
|
Assert.Equal(1, orm.Insert<EnumTestMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enum_to_int, find.enum_to_int);
|
||||||
|
Assert.Equal(ToStringMapEnum.abc, find.enum_to_int);
|
||||||
|
|
||||||
|
//update all
|
||||||
|
item.enum_to_int = ToStringMapEnum.香港;
|
||||||
|
Assert.Equal(1, orm.Update<EnumTestMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.香港).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enum_to_int, find.enum_to_int);
|
||||||
|
Assert.Equal(ToStringMapEnum.香港, find.enum_to_int);
|
||||||
|
|
||||||
|
item.enum_to_int = ToStringMapEnum.中国人;
|
||||||
|
Assert.Equal(1, orm.Update<EnumTestMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.中国人).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enum_to_int, find.enum_to_int);
|
||||||
|
Assert.Equal(ToStringMapEnum.中国人, find.enum_to_int);
|
||||||
|
|
||||||
|
//update set
|
||||||
|
Assert.Equal(1, orm.Update<EnumTestMap>().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.香港).ExecuteAffrows());
|
||||||
|
find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.香港).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(ToStringMapEnum.香港, find.enum_to_int);
|
||||||
|
|
||||||
|
Assert.Equal(1, orm.Update<EnumTestMap>().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows());
|
||||||
|
find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(ToStringMapEnum.abc, find.enum_to_int);
|
||||||
|
|
||||||
|
//delete
|
||||||
|
Assert.Equal(0, orm.Delete<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.中国人).ExecuteAffrows());
|
||||||
|
Assert.Equal(0, orm.Delete<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.香港).ExecuteAffrows());
|
||||||
|
Assert.Equal(1, orm.Delete<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<EnumTestMap>().Where(a => a.id == item.id).First());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void EnumNullableToInt()
|
||||||
|
{
|
||||||
|
//insert
|
||||||
|
var orm = fsql;
|
||||||
|
var item = new EnumTestMap { };
|
||||||
|
Assert.Equal(1, orm.Insert<EnumTestMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
var find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_int == null).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int);
|
||||||
|
Assert.Null(find.enumnullable_to_int);
|
||||||
|
|
||||||
|
item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.中国人 };
|
||||||
|
Assert.Equal(1, orm.Insert<EnumTestMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.中国人).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int);
|
||||||
|
Assert.Equal(ToStringMapEnum.中国人, find.enumnullable_to_int);
|
||||||
|
|
||||||
|
//update all
|
||||||
|
item.enumnullable_to_int = ToStringMapEnum.香港;
|
||||||
|
Assert.Equal(1, orm.Update<EnumTestMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.香港).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int);
|
||||||
|
Assert.Equal(ToStringMapEnum.香港, find.enumnullable_to_int);
|
||||||
|
|
||||||
|
item.enumnullable_to_int = null;
|
||||||
|
Assert.Equal(1, orm.Update<EnumTestMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.香港).First());
|
||||||
|
find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_int == null).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int);
|
||||||
|
Assert.Null(find.enumnullable_to_int);
|
||||||
|
|
||||||
|
//update set
|
||||||
|
Assert.Equal(1, orm.Update<EnumTestMap>().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows());
|
||||||
|
find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int);
|
||||||
|
|
||||||
|
|
||||||
|
Assert.Equal(1, orm.Update<EnumTestMap>().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First());
|
||||||
|
find = orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_int == null).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Null(find.enumnullable_to_int);
|
||||||
|
|
||||||
|
//delete
|
||||||
|
Assert.Equal(0, orm.Delete<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.中国人).ExecuteAffrows());
|
||||||
|
Assert.Equal(0, orm.Delete<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.香港).ExecuteAffrows());
|
||||||
|
Assert.Equal(1, orm.Delete<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<EnumTestMap>().Where(a => a.id == item.id).First());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,572 @@
|
|||||||
|
using FreeSql.DataAnnotations;
|
||||||
|
using System;
|
||||||
|
using System.Numerics;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace FreeSql.Tests.DuckdbMapType
|
||||||
|
{
|
||||||
|
public class ToStringTest
|
||||||
|
{
|
||||||
|
IFreeSql fsql => g.duckdb;
|
||||||
|
|
||||||
|
class ToStringMap
|
||||||
|
{
|
||||||
|
public Guid id { get; set; }
|
||||||
|
|
||||||
|
[Column(MapType = typeof(string))]
|
||||||
|
public TimeSpan timespan_to_string { get; set; }
|
||||||
|
[Column(MapType = typeof(string))]
|
||||||
|
public TimeSpan? timespannullable_to_string { get; set; }
|
||||||
|
|
||||||
|
[Column(MapType = typeof(string))]
|
||||||
|
public DateTime datetime_to_string { get; set; }
|
||||||
|
[Column(MapType = typeof(string))]
|
||||||
|
public DateTime? datetimenullable_to_string { get; set; }
|
||||||
|
|
||||||
|
[Column(MapType = typeof(string))]
|
||||||
|
public Guid guid_to_string { get; set; }
|
||||||
|
[Column(MapType = typeof(string))]
|
||||||
|
public Guid? guidnullable_to_string { get; set; }
|
||||||
|
|
||||||
|
[Column(MapType = typeof(string))]
|
||||||
|
public ToStringMapEnum enum_to_string { get; set; }
|
||||||
|
[Column(MapType = typeof(string))]
|
||||||
|
public ToStringMapEnum? enumnullable_to_string { get; set; }
|
||||||
|
|
||||||
|
[Column(MapType = typeof(string))]
|
||||||
|
public BigInteger biginteger_to_string { get; set; }
|
||||||
|
[Column(MapType = typeof(string))]
|
||||||
|
public BigInteger? bigintegernullable_to_string { get; set; }
|
||||||
|
}
|
||||||
|
public enum ToStringMapEnum { 中国人, abc, 香港 }
|
||||||
|
[Fact]
|
||||||
|
public void Enum1()
|
||||||
|
{
|
||||||
|
//insert
|
||||||
|
var orm = fsql;
|
||||||
|
var item = new ToStringMap { };
|
||||||
|
Assert.Equal(1, orm.Insert<ToStringMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
var find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.中国人).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enum_to_string, find.enum_to_string);
|
||||||
|
Assert.Equal(ToStringMapEnum.中国人, find.enum_to_string);
|
||||||
|
|
||||||
|
item = new ToStringMap { enum_to_string = ToStringMapEnum.abc };
|
||||||
|
Assert.Equal(1, orm.Insert<ToStringMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enum_to_string, find.enum_to_string);
|
||||||
|
Assert.Equal(ToStringMapEnum.abc, find.enum_to_string);
|
||||||
|
|
||||||
|
//update all
|
||||||
|
item.enum_to_string = ToStringMapEnum.香港;
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.香港).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enum_to_string, find.enum_to_string);
|
||||||
|
Assert.Equal(ToStringMapEnum.香港, find.enum_to_string);
|
||||||
|
|
||||||
|
item.enum_to_string = ToStringMapEnum.中国人;
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.中国人).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enum_to_string, find.enum_to_string);
|
||||||
|
Assert.Equal(ToStringMapEnum.中国人, find.enum_to_string);
|
||||||
|
|
||||||
|
//update set
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.香港).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.香港).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(ToStringMapEnum.香港, find.enum_to_string);
|
||||||
|
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(ToStringMapEnum.abc, find.enum_to_string);
|
||||||
|
|
||||||
|
//delete
|
||||||
|
Assert.Equal(0, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.中国人).ExecuteAffrows());
|
||||||
|
Assert.Equal(0, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.香港).ExecuteAffrows());
|
||||||
|
Assert.Equal(1, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<ToStringMap>().Where(a => a.id == item.id).First());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void EnumNullable()
|
||||||
|
{
|
||||||
|
//insert
|
||||||
|
var orm = fsql;
|
||||||
|
var item = new ToStringMap { };
|
||||||
|
Assert.Equal(1, orm.Insert<ToStringMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
var find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.enumnullable_to_string == null).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string);
|
||||||
|
Assert.Null(find.enumnullable_to_string);
|
||||||
|
|
||||||
|
item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.中国人 };
|
||||||
|
Assert.Equal(1, orm.Insert<ToStringMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.中国人).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string);
|
||||||
|
Assert.Equal(ToStringMapEnum.中国人, find.enumnullable_to_string);
|
||||||
|
|
||||||
|
//update all
|
||||||
|
item.enumnullable_to_string = ToStringMapEnum.香港;
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.香港).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string);
|
||||||
|
Assert.Equal(ToStringMapEnum.香港, find.enumnullable_to_string);
|
||||||
|
|
||||||
|
item.enumnullable_to_string = null;
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<ToStringMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.香港).First());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.enumnullable_to_string == null).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string);
|
||||||
|
Assert.Null(find.enumnullable_to_string);
|
||||||
|
|
||||||
|
//update set
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string);
|
||||||
|
|
||||||
|
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<ToStringMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.enumnullable_to_string == null).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Null(find.enumnullable_to_string);
|
||||||
|
|
||||||
|
//delete
|
||||||
|
Assert.Equal(0, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.中国人).ExecuteAffrows());
|
||||||
|
Assert.Equal(0, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.香港).ExecuteAffrows());
|
||||||
|
Assert.Equal(1, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<ToStringMap>().Where(a => a.id == item.id).First());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void BigInteger1()
|
||||||
|
{
|
||||||
|
//insert
|
||||||
|
var orm = fsql;
|
||||||
|
var item = new ToStringMap { };
|
||||||
|
Assert.Equal(1, orm.Insert<ToStringMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
var find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.biginteger_to_string == 0).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.biginteger_to_string, find.biginteger_to_string);
|
||||||
|
Assert.Equal(0, find.biginteger_to_string);
|
||||||
|
|
||||||
|
item = new ToStringMap { biginteger_to_string = 100 };
|
||||||
|
Assert.Equal(1, orm.Insert<ToStringMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.biginteger_to_string == 100).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.biginteger_to_string, find.biginteger_to_string);
|
||||||
|
Assert.Equal(100, find.biginteger_to_string);
|
||||||
|
|
||||||
|
//update all
|
||||||
|
item.biginteger_to_string = 200;
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.biginteger_to_string == 200).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.biginteger_to_string, find.biginteger_to_string);
|
||||||
|
Assert.Equal(200, find.biginteger_to_string);
|
||||||
|
|
||||||
|
item.biginteger_to_string = 205;
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.biginteger_to_string == 205).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.biginteger_to_string, find.biginteger_to_string);
|
||||||
|
Assert.Equal(205, find.biginteger_to_string);
|
||||||
|
|
||||||
|
//update set
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.biginteger_to_string == 522).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(522, find.biginteger_to_string);
|
||||||
|
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(10005, find.biginteger_to_string);
|
||||||
|
|
||||||
|
//delete
|
||||||
|
Assert.Equal(0, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows());
|
||||||
|
Assert.Equal(0, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows());
|
||||||
|
Assert.Equal(1, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<ToStringMap>().Where(a => a.id == item.id).First());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void BigIntegerNullable()
|
||||||
|
{
|
||||||
|
//insert
|
||||||
|
var orm = fsql;
|
||||||
|
var item = new ToStringMap { };
|
||||||
|
Assert.Equal(1, orm.Insert<ToStringMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
var find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string);
|
||||||
|
Assert.Null(find.bigintegernullable_to_string);
|
||||||
|
|
||||||
|
item = new ToStringMap { bigintegernullable_to_string = 101 };
|
||||||
|
Assert.Equal(1, orm.Insert<ToStringMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string);
|
||||||
|
Assert.Equal(101, find.bigintegernullable_to_string);
|
||||||
|
|
||||||
|
//update all
|
||||||
|
item.bigintegernullable_to_string = 2004;
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string);
|
||||||
|
Assert.Equal(2004, find.bigintegernullable_to_string);
|
||||||
|
|
||||||
|
item.bigintegernullable_to_string = null;
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<ToStringMap>().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string);
|
||||||
|
Assert.Null(find.bigintegernullable_to_string);
|
||||||
|
|
||||||
|
//update set
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(998, find.bigintegernullable_to_string);
|
||||||
|
|
||||||
|
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<ToStringMap>().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Null(find.bigintegernullable_to_string);
|
||||||
|
|
||||||
|
//delete
|
||||||
|
Assert.Equal(0, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows());
|
||||||
|
Assert.Equal(0, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows());
|
||||||
|
Assert.Equal(1, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<ToStringMap>().Where(a => a.id == item.id).First());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void TimeSpan1()
|
||||||
|
{
|
||||||
|
//insert
|
||||||
|
var orm = fsql;
|
||||||
|
var item = new ToStringMap { };
|
||||||
|
Assert.Equal(1, orm.Insert<ToStringMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
var find = orm.Select<ToStringMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.timespan_to_string, find.timespan_to_string);
|
||||||
|
Assert.Equal(TimeSpan.Zero, find.timespan_to_string);
|
||||||
|
|
||||||
|
item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) };
|
||||||
|
Assert.Equal(1, orm.Insert<ToStringMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.timespan_to_string, find.timespan_to_string);
|
||||||
|
Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string);
|
||||||
|
|
||||||
|
//update all
|
||||||
|
item.timespan_to_string = TimeSpan.FromHours(10);
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.timespan_to_string, find.timespan_to_string);
|
||||||
|
Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string);
|
||||||
|
|
||||||
|
//update set
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string);
|
||||||
|
|
||||||
|
//delete
|
||||||
|
Assert.Equal(1, orm.Delete<ToStringMap>().Where(a => a.id == item.id).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<ToStringMap>().Where(a => a.id == item.id).First());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void TimeSpanNullable()
|
||||||
|
{
|
||||||
|
//insert
|
||||||
|
var orm = fsql;
|
||||||
|
var item = new ToStringMap { };
|
||||||
|
Assert.Equal(1, orm.Insert<ToStringMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
var find = orm.Select<ToStringMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string);
|
||||||
|
Assert.Null(find.timespannullable_to_string);
|
||||||
|
|
||||||
|
item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) };
|
||||||
|
Assert.Equal(1, orm.Insert<ToStringMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string);
|
||||||
|
Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string);
|
||||||
|
|
||||||
|
//update all
|
||||||
|
item.timespannullable_to_string = TimeSpan.FromHours(10);
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string);
|
||||||
|
Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string);
|
||||||
|
|
||||||
|
item.timespannullable_to_string = null;
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string);
|
||||||
|
Assert.Null(find.timespannullable_to_string);
|
||||||
|
|
||||||
|
//update set
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string);
|
||||||
|
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Null(find.timespannullable_to_string);
|
||||||
|
|
||||||
|
//delete
|
||||||
|
Assert.Equal(1, orm.Delete<ToStringMap>().Where(a => a.id == item.id).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<ToStringMap>().Where(a => a.id == item.id).First());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void DateTime1()
|
||||||
|
{
|
||||||
|
//insert
|
||||||
|
var orm = fsql;
|
||||||
|
var item = new ToStringMap { };
|
||||||
|
Assert.Equal(1, orm.Insert<ToStringMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
var find = orm.Select<ToStringMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.datetime_to_string, find.datetime_to_string);
|
||||||
|
Assert.Equal(DateTime.MinValue, find.datetime_to_string);
|
||||||
|
|
||||||
|
item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") };
|
||||||
|
Assert.Equal(1, orm.Insert<ToStringMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.datetime_to_string, find.datetime_to_string);
|
||||||
|
Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string);
|
||||||
|
|
||||||
|
//update all
|
||||||
|
item.datetime_to_string = DateTime.Parse("2000-1-11");
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.datetime_to_string, find.datetime_to_string);
|
||||||
|
Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string);
|
||||||
|
|
||||||
|
//update set
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string);
|
||||||
|
|
||||||
|
//delete
|
||||||
|
Assert.Equal(1, orm.Delete<ToStringMap>().Where(a => a.id == item.id).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<ToStringMap>().Where(a => a.id == item.id).First());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void DateTimeNullable()
|
||||||
|
{
|
||||||
|
//insert
|
||||||
|
var orm = fsql;
|
||||||
|
var item = new ToStringMap { };
|
||||||
|
Assert.Equal(1, orm.Insert<ToStringMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
var find = orm.Select<ToStringMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string);
|
||||||
|
Assert.Null(find.datetimenullable_to_string);
|
||||||
|
|
||||||
|
item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") };
|
||||||
|
Assert.Equal(1, orm.Insert<ToStringMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string);
|
||||||
|
Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string);
|
||||||
|
|
||||||
|
//update all
|
||||||
|
item.datetimenullable_to_string = DateTime.Parse("2000-1-11");
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string);
|
||||||
|
Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string);
|
||||||
|
|
||||||
|
item.datetimenullable_to_string = null;
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string);
|
||||||
|
Assert.Null(find.datetimenullable_to_string);
|
||||||
|
|
||||||
|
//update set
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string);
|
||||||
|
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Null(find.datetimenullable_to_string);
|
||||||
|
|
||||||
|
//delete
|
||||||
|
Assert.Equal(1, orm.Delete<ToStringMap>().Where(a => a.id == item.id).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<ToStringMap>().Where(a => a.id == item.id).First());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Guid1()
|
||||||
|
{
|
||||||
|
//insert
|
||||||
|
var orm = fsql;
|
||||||
|
var item = new ToStringMap { };
|
||||||
|
Assert.Equal(1, orm.Insert<ToStringMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
var find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.guid_to_string, find.guid_to_string);
|
||||||
|
Assert.Equal(Guid.Empty, find.guid_to_string);
|
||||||
|
|
||||||
|
var newid = Guid.NewGuid();
|
||||||
|
item = new ToStringMap { guid_to_string = newid };
|
||||||
|
Assert.Equal(1, orm.Insert<ToStringMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.guid_to_string == newid).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.guid_to_string, find.guid_to_string);
|
||||||
|
Assert.Equal(newid, find.guid_to_string);
|
||||||
|
|
||||||
|
//update all
|
||||||
|
newid = Guid.NewGuid();
|
||||||
|
item.guid_to_string = newid;
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.guid_to_string == newid).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.guid_to_string, find.guid_to_string);
|
||||||
|
Assert.Equal(newid, find.guid_to_string);
|
||||||
|
|
||||||
|
//update set
|
||||||
|
newid = Guid.NewGuid();
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.guid_to_string == newid).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(newid, find.guid_to_string);
|
||||||
|
|
||||||
|
//delete
|
||||||
|
Assert.Equal(1, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<ToStringMap>().Where(a => a.id == item.id).First());
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public void GuidNullable()
|
||||||
|
{
|
||||||
|
//insert
|
||||||
|
var orm = fsql;
|
||||||
|
var item = new ToStringMap { };
|
||||||
|
Assert.Equal(1, orm.Insert<ToStringMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
var find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.guidnullable_to_string == null).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string);
|
||||||
|
Assert.Null(find.guidnullable_to_string);
|
||||||
|
|
||||||
|
var newid = Guid.NewGuid();
|
||||||
|
item = new ToStringMap { guidnullable_to_string = newid };
|
||||||
|
Assert.Equal(1, orm.Insert<ToStringMap>().AppendData(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string);
|
||||||
|
Assert.Equal(newid, find.guidnullable_to_string);
|
||||||
|
|
||||||
|
//update all
|
||||||
|
newid = Guid.NewGuid();
|
||||||
|
item.guidnullable_to_string = newid;
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string);
|
||||||
|
Assert.Equal(newid, find.guidnullable_to_string);
|
||||||
|
|
||||||
|
item.guidnullable_to_string = null;
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().SetSource(item).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.guidnullable_to_string == null).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string);
|
||||||
|
Assert.Null(find.guidnullable_to_string);
|
||||||
|
|
||||||
|
//update set
|
||||||
|
newid = Guid.NewGuid();
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Equal(newid, find.guidnullable_to_string);
|
||||||
|
|
||||||
|
Assert.Equal(1, orm.Update<ToStringMap>().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows());
|
||||||
|
find = orm.Select<ToStringMap>().Where(a => a.id == item.id && a.guidnullable_to_string == null).First();
|
||||||
|
Assert.NotNull(find);
|
||||||
|
Assert.Equal(item.id, find.id);
|
||||||
|
Assert.Null(find.guidnullable_to_string);
|
||||||
|
|
||||||
|
//delete
|
||||||
|
Assert.Equal(1, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows());
|
||||||
|
Assert.Null(orm.Select<ToStringMap>().Where(a => a.id == item.id).First());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
|
<WarningLevel>3</WarningLevel>
|
||||||
|
<NoWarn>1701;1702;1591</NoWarn>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
||||||
|
<PackageReference Include="xunit" Version="2.4.1" />
|
||||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\FreeSql.DbContext\FreeSql.DbContext.csproj" />
|
||||||
|
<ProjectReference Include="..\..\FreeSql\FreeSql.csproj" />
|
||||||
|
<ProjectReference Include="..\..\Providers\FreeSql.Provider.Duckdb\FreeSql.Provider.Duckdb.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
22
FreeSql.Tests/FreeSql.Tests.Provider.Duckdb/g.cs
Normal file
22
FreeSql.Tests/FreeSql.Tests.Provider.Duckdb/g.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
public class g
|
||||||
|
{
|
||||||
|
static Lazy<IFreeSql> duckdbLazy = new Lazy<IFreeSql>(() =>
|
||||||
|
{
|
||||||
|
return new FreeSql.FreeSqlBuilder()
|
||||||
|
.UseConnectionString(FreeSql.DataType.DuckDB, "DataSource=duckdb01.db")
|
||||||
|
.UseAutoSyncStructure(true)
|
||||||
|
.UseNameConvert(FreeSql.Internal.NameConvertType.ToLower)
|
||||||
|
.UseMonitorCommand(
|
||||||
|
cmd => Trace.WriteLine("\r\n线程" + Thread.CurrentThread.ManagedThreadId + ": " + cmd.CommandText) //监听SQL命令对象,在执行前
|
||||||
|
//, (cmd, traceLog) => Console.WriteLine(traceLog)
|
||||||
|
)
|
||||||
|
.Build();
|
||||||
|
});
|
||||||
|
public static IFreeSql duckdb => duckdbLazy.Value;
|
||||||
|
}
|
@ -63,6 +63,8 @@ namespace FreeSql
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Xugu,
|
Xugu,
|
||||||
|
|
||||||
CustomOracle, CustomSqlServer, CustomMySql, CustomPostgreSQL
|
CustomOracle, CustomSqlServer, CustomMySql, CustomPostgreSQL,
|
||||||
|
|
||||||
|
DuckDB
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -750,6 +750,7 @@ JOIN {select._commonUtils.QuoteSqlName(tbDbName)} a ON cte_tbc.cte_id = a.{selec
|
|||||||
case DataType.CustomSqlServer:
|
case DataType.CustomSqlServer:
|
||||||
case DataType.Firebird:
|
case DataType.Firebird:
|
||||||
case DataType.ClickHouse:
|
case DataType.ClickHouse:
|
||||||
|
case DataType.DuckDB:
|
||||||
sql1ctePath = select._commonExpression.ExpressionWhereLambda(select._tables, select._tableRule,
|
sql1ctePath = select._commonExpression.ExpressionWhereLambda(select._tables, select._tableRule,
|
||||||
Expression.Call(typeof(Convert).GetMethod("ToString", new Type[] { typeof(string) }), pathSelector?.Body), select._diymemexpWithTempQuery, null, null);
|
Expression.Call(typeof(Convert).GetMethod("ToString", new Type[] { typeof(string) }), pathSelector?.Body), select._diymemexpWithTempQuery, null, null);
|
||||||
break;
|
break;
|
||||||
@ -845,6 +846,7 @@ JOIN {select._commonUtils.QuoteSqlName(tbDbName)} a ON cte_tbc.cte_id = a.{selec
|
|||||||
case DataType.OdbcMySql:
|
case DataType.OdbcMySql:
|
||||||
case DataType.CustomMySql:
|
case DataType.CustomMySql:
|
||||||
case DataType.Firebird:
|
case DataType.Firebird:
|
||||||
|
case DataType.DuckDB:
|
||||||
nsselsb.Append("RECURSIVE ");
|
nsselsb.Append("RECURSIVE ");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -874,7 +876,7 @@ SELECT ");
|
|||||||
#region OrderBy Random 随机排序
|
#region OrderBy Random 随机排序
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 随机排序<para></para>
|
/// 随机排序<para></para>
|
||||||
/// 支持:MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/金仓/神通<para></para>
|
/// 支持:MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/DuckDB/达梦/金仓/神通<para></para>
|
||||||
/// 不支持:MsAcess
|
/// 不支持:MsAcess
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
@ -897,6 +899,7 @@ SELECT ");
|
|||||||
case DataType.CustomPostgreSQL:
|
case DataType.CustomPostgreSQL:
|
||||||
case DataType.KingbaseES:
|
case DataType.KingbaseES:
|
||||||
case DataType.ShenTong:
|
case DataType.ShenTong:
|
||||||
|
case DataType.DuckDB:
|
||||||
return that.OrderBy("random()");
|
return that.OrderBy("random()");
|
||||||
case DataType.Oracle:
|
case DataType.Oracle:
|
||||||
case DataType.OdbcOracle:
|
case DataType.OdbcOracle:
|
||||||
@ -980,6 +983,7 @@ SELECT ");
|
|||||||
/// SqlServer 2008+: merge into<para></para>
|
/// SqlServer 2008+: merge into<para></para>
|
||||||
/// Oracle 11+: merge into<para></para>
|
/// Oracle 11+: merge into<para></para>
|
||||||
/// Sqlite: replace into<para></para>
|
/// Sqlite: replace into<para></para>
|
||||||
|
/// DuckDB: on conflict do update<para></para>
|
||||||
/// 达梦: merge into<para></para>
|
/// 达梦: merge into<para></para>
|
||||||
/// 人大金仓:on conflict do update<para></para>
|
/// 人大金仓:on conflict do update<para></para>
|
||||||
/// 神通:merge into<para></para>
|
/// 神通:merge into<para></para>
|
||||||
|
@ -1087,6 +1087,93 @@
|
|||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="T:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder">
|
||||||
|
<summary>
|
||||||
|
动态创建实体类型
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.#ctor(IFreeSql,System.String,System.Attribute[])">
|
||||||
|
<summary>
|
||||||
|
配置Class
|
||||||
|
</summary>
|
||||||
|
<param name="className">类名</param>
|
||||||
|
<param name="attributes">类标记的特性[Table(Name = "xxx")] [Index(xxxx)]</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="P:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.TypeBuilder">
|
||||||
|
<summary>
|
||||||
|
获取类型构建器,可作为要构建的Type来引用
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.Property(System.String,System.Type,System.Attribute[])">
|
||||||
|
<summary>
|
||||||
|
配置属性
|
||||||
|
</summary>
|
||||||
|
<param name="propertyName">属性名称</param>
|
||||||
|
<param name="propertyType">属性类型</param>
|
||||||
|
<param name="attributes">属性标记的特性-支持多个</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.Property(System.String,System.Type,System.Boolean,System.Attribute[])">
|
||||||
|
<summary>
|
||||||
|
配置属性
|
||||||
|
</summary>
|
||||||
|
<param name="propertyName">属性名称</param>
|
||||||
|
<param name="propertyType">属性类型</param>
|
||||||
|
<param name="isOverride">该属性是否重写父类属性</param>
|
||||||
|
<param name="attributes">属性标记的特性-支持多个</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.Property(System.String,System.Type,System.Boolean,System.Object,System.Attribute[])">
|
||||||
|
<summary>
|
||||||
|
配置属性
|
||||||
|
</summary>
|
||||||
|
<param name="propertyName">属性名称</param>
|
||||||
|
<param name="propertyType">属性类型</param>
|
||||||
|
<param name="isOverride">该属性是否重写父类属性</param>
|
||||||
|
<param name="defaultValue">属性默认值</param>
|
||||||
|
<param name="attributes">属性标记的特性-支持多个</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.Extend(System.Type)">
|
||||||
|
<summary>
|
||||||
|
配置父类
|
||||||
|
</summary>
|
||||||
|
<param name="superClass">父类类型</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.OverrideProperty(System.Reflection.Emit.TypeBuilder@,System.Reflection.Emit.MethodBuilder,FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.PropertyMethodEnum,System.String)">
|
||||||
|
<summary>
|
||||||
|
Override属性
|
||||||
|
</summary>
|
||||||
|
<param name="typeBuilder"></param>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.Build">
|
||||||
|
<summary>
|
||||||
|
Emit动态创建出Class - Type
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.BuildJustType">
|
||||||
|
<summary>
|
||||||
|
Emit动态创建出Class - Type,不附带获取TableInfo
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.FirstCharToLower(System.String)">
|
||||||
|
<summary>
|
||||||
|
首字母小写
|
||||||
|
</summary>
|
||||||
|
<param name="input"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.FirstCharToUpper(System.String)">
|
||||||
|
<summary>
|
||||||
|
首字母大写
|
||||||
|
</summary>
|
||||||
|
<param name="input"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:FreeSql.Extensions.EntityUtil.EntityUtilExtensions.GetEntityKeyString(IFreeSql,System.Type,System.Object,System.Boolean,System.String)">
|
<member name="M:FreeSql.Extensions.EntityUtil.EntityUtilExtensions.GetEntityKeyString(IFreeSql,System.Type,System.Object,System.Boolean,System.String)">
|
||||||
<summary>
|
<summary>
|
||||||
获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 ""
|
获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 ""
|
||||||
@ -1631,7 +1718,7 @@
|
|||||||
<member name="M:FreeSql.IDelete`1.ExecuteDeleted">
|
<member name="M:FreeSql.IDelete`1.ExecuteDeleted">
|
||||||
<summary>
|
<summary>
|
||||||
执行SQL语句,返回被删除的记录<para></para>
|
执行SQL语句,返回被删除的记录<para></para>
|
||||||
注意:此方法只有 Postgresql/SqlServer 有效果
|
注意:此方法只有 Postgresql/SqlServer/Maridb/Firebird/人大金仓 有效果
|
||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
@ -1792,7 +1879,7 @@
|
|||||||
<member name="M:FreeSql.IInsert`1.ExecuteInserted">
|
<member name="M:FreeSql.IInsert`1.ExecuteInserted">
|
||||||
<summary>
|
<summary>
|
||||||
执行SQL语句,返回插入后的记录<para></para>
|
执行SQL语句,返回插入后的记录<para></para>
|
||||||
注意:此方法只有 Postgresql/SqlServer 有效果
|
注意:此方法只有 Postgresql/SqlServer/Maridb/Firebird/DuckDB/人大金仓 有效果
|
||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
@ -3267,7 +3354,7 @@
|
|||||||
<member name="M:FreeSql.IUpdate`1.ExecuteUpdated">
|
<member name="M:FreeSql.IUpdate`1.ExecuteUpdated">
|
||||||
<summary>
|
<summary>
|
||||||
执行SQL语句,返回更新后的记录<para></para>
|
执行SQL语句,返回更新后的记录<para></para>
|
||||||
注意:此方法只有 Postgresql/SqlServer 有效果
|
注意:此方法只有 Postgresql/SqlServer/Maridb/Firebird/人大金仓 有效果
|
||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
@ -5809,6 +5896,28 @@
|
|||||||
请使用 fsql.InsertDict(dict) 方法插入字典数据
|
请使用 fsql.InsertDict(dict) 方法插入字典数据
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:FreeSqlGlobalDynamicEntityExtensions.DynamicEntity(FreeSql.ICodeFirst,System.String,System.Attribute[])">
|
||||||
|
<summary>
|
||||||
|
动态构建Class Type
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSqlGlobalDynamicEntityExtensions.CreateInstance(FreeSql.Internal.Model.TableInfo,System.Collections.Generic.Dictionary{System.String,System.Object})">
|
||||||
|
<summary>
|
||||||
|
根据字典,创建 table 对应的实体对象
|
||||||
|
</summary>
|
||||||
|
<param name="table"></param>
|
||||||
|
<param name="dict"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:FreeSqlGlobalDynamicEntityExtensions.CreateDictionary(FreeSql.Internal.Model.TableInfo,System.Object)">
|
||||||
|
<summary>
|
||||||
|
根据实体对象,创建 table 对应的字典
|
||||||
|
</summary>
|
||||||
|
<param name="table"></param>
|
||||||
|
<param name="instance"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:FreeSqlGlobalExpressionCallExtensions.Between(System.DateTime,System.DateTime,System.DateTime)">
|
<member name="M:FreeSqlGlobalExpressionCallExtensions.Between(System.DateTime,System.DateTime,System.DateTime)">
|
||||||
<summary>
|
<summary>
|
||||||
C#: that >= between && that <= and<para></para>
|
C#: that >= between && that <= and<para></para>
|
||||||
@ -5923,7 +6032,7 @@
|
|||||||
<member name="M:FreeSqlGlobalExtensions.OrderByRandom``2(FreeSql.ISelect0{``0,``1})">
|
<member name="M:FreeSqlGlobalExtensions.OrderByRandom``2(FreeSql.ISelect0{``0,``1})">
|
||||||
<summary>
|
<summary>
|
||||||
随机排序<para></para>
|
随机排序<para></para>
|
||||||
支持:MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/金仓/神通<para></para>
|
支持:MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/DuckDB/达梦/金仓/神通<para></para>
|
||||||
不支持:MsAcess
|
不支持:MsAcess
|
||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
@ -5964,6 +6073,7 @@
|
|||||||
SqlServer 2008+: merge into<para></para>
|
SqlServer 2008+: merge into<para></para>
|
||||||
Oracle 11+: merge into<para></para>
|
Oracle 11+: merge into<para></para>
|
||||||
Sqlite: replace into<para></para>
|
Sqlite: replace into<para></para>
|
||||||
|
DuckDB: on conflict do update<para></para>
|
||||||
达梦: merge into<para></para>
|
达梦: merge into<para></para>
|
||||||
人大金仓:on conflict do update<para></para>
|
人大金仓:on conflict do update<para></para>
|
||||||
神通:merge into<para></para>
|
神通:merge into<para></para>
|
||||||
@ -6247,6 +6357,7 @@
|
|||||||
SqlServer 2008+: merge into<para></para>
|
SqlServer 2008+: merge into<para></para>
|
||||||
Oracle 11+: merge into<para></para>
|
Oracle 11+: merge into<para></para>
|
||||||
Sqlite: replace into<para></para>
|
Sqlite: replace into<para></para>
|
||||||
|
DuckDB: on conflict do update<para></para>
|
||||||
达梦: merge into<para></para>
|
达梦: merge into<para></para>
|
||||||
人大金仓:on conflict do update<para></para>
|
人大金仓:on conflict do update<para></para>
|
||||||
神通:merge into<para></para>
|
神通:merge into<para></para>
|
||||||
|
@ -377,6 +377,11 @@ namespace FreeSql
|
|||||||
if (type == null) throwNotFind("FreeSql.Provider.Custom.dll", "FreeSql.Custom.PostgreSQL.CustomPostgreSQLProvider<>");
|
if (type == null) throwNotFind("FreeSql.Provider.Custom.dll", "FreeSql.Custom.PostgreSQL.CustomPostgreSQLProvider<>");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DataType.DuckDB:
|
||||||
|
type = Type.GetType("FreeSql.Duckdb.DuckdbProvider`1,FreeSql.Provider.Duckdb")?.MakeGenericType(typeof(TMark));
|
||||||
|
if (type == null) throwNotFind("FreeSql.Provider.Duckdb.dll", "FreeSql.Duckdb.DuckdbProvider<>");
|
||||||
|
break;
|
||||||
|
|
||||||
default: throw new Exception(CoreStrings.NotSpecified_UseConnectionString_UseConnectionFactory);
|
default: throw new Exception(CoreStrings.NotSpecified_UseConnectionString_UseConnectionFactory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ namespace FreeSql
|
|||||||
int ExecuteAffrows();
|
int ExecuteAffrows();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 执行SQL语句,返回被删除的记录<para></para>
|
/// 执行SQL语句,返回被删除的记录<para></para>
|
||||||
/// 注意:此方法只有 Postgresql/SqlServer 有效果
|
/// 注意:此方法只有 Postgresql/SqlServer/Maridb/Firebird/人大金仓 有效果
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
List<T1> ExecuteDeleted();
|
List<T1> ExecuteDeleted();
|
||||||
|
@ -156,7 +156,7 @@ namespace FreeSql
|
|||||||
long ExecuteIdentity();
|
long ExecuteIdentity();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 执行SQL语句,返回插入后的记录<para></para>
|
/// 执行SQL语句,返回插入后的记录<para></para>
|
||||||
/// 注意:此方法只有 Postgresql/SqlServer 有效果
|
/// 注意:此方法只有 Postgresql/SqlServer/Maridb/Firebird/DuckDB/人大金仓 有效果
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
List<T1> ExecuteInserted();
|
List<T1> ExecuteInserted();
|
||||||
|
@ -294,7 +294,7 @@ namespace FreeSql
|
|||||||
int ExecuteAffrows();
|
int ExecuteAffrows();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 执行SQL语句,返回更新后的记录<para></para>
|
/// 执行SQL语句,返回更新后的记录<para></para>
|
||||||
/// 注意:此方法只有 Postgresql/SqlServer 有效果
|
/// 注意:此方法只有 Postgresql/SqlServer/Maridb/Firebird/人大金仓 有效果
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
List<T1> ExecuteUpdated();
|
List<T1> ExecuteUpdated();
|
||||||
|
@ -51,6 +51,7 @@ public interface IFreeSql : IDisposable
|
|||||||
/// SqlServer 2008+: merge into<para></para>
|
/// SqlServer 2008+: merge into<para></para>
|
||||||
/// Oracle 11+: merge into<para></para>
|
/// Oracle 11+: merge into<para></para>
|
||||||
/// Sqlite: replace into<para></para>
|
/// Sqlite: replace into<para></para>
|
||||||
|
/// DuckDB: on conflict do update<para></para>
|
||||||
/// 达梦: merge into<para></para>
|
/// 达梦: merge into<para></para>
|
||||||
/// 人大金仓:on conflict do update<para></para>
|
/// 人大金仓:on conflict do update<para></para>
|
||||||
/// 神通:merge into<para></para>
|
/// 神通:merge into<para></para>
|
||||||
|
@ -1157,6 +1157,7 @@ namespace FreeSql.Internal
|
|||||||
case "System.String": other3Exp = ExpressionLambdaToSqlCallString(exp3, tsc); break;
|
case "System.String": other3Exp = ExpressionLambdaToSqlCallString(exp3, tsc); break;
|
||||||
case "System.Math": other3Exp = ExpressionLambdaToSqlCallMath(exp3, tsc); break;
|
case "System.Math": other3Exp = ExpressionLambdaToSqlCallMath(exp3, tsc); break;
|
||||||
case "System.DateTime": other3Exp = ExpressionLambdaToSqlCallDateTime(exp3, tsc); break;
|
case "System.DateTime": other3Exp = ExpressionLambdaToSqlCallDateTime(exp3, tsc); break;
|
||||||
|
case "System.TimeSpan": throw new Exception(CoreStrings.Unable_Parse_ExpressionMethod(callType.FullName));
|
||||||
case "System.Convert": other3Exp = ExpressionLambdaToSqlCallConvert(exp3, tsc); break;
|
case "System.Convert": other3Exp = ExpressionLambdaToSqlCallConvert(exp3, tsc); break;
|
||||||
}
|
}
|
||||||
if (string.IsNullOrEmpty(other3Exp) == false) return other3Exp;
|
if (string.IsNullOrEmpty(other3Exp) == false) return other3Exp;
|
||||||
@ -1754,6 +1755,7 @@ namespace FreeSql.Internal
|
|||||||
{
|
{
|
||||||
case "System.String": extRet = ExpressionLambdaToSqlMemberAccessString(exp4, tsc); break;
|
case "System.String": extRet = ExpressionLambdaToSqlMemberAccessString(exp4, tsc); break;
|
||||||
case "System.DateTime": extRet = ExpressionLambdaToSqlMemberAccessDateTime(exp4, tsc); break;
|
case "System.DateTime": extRet = ExpressionLambdaToSqlMemberAccessDateTime(exp4, tsc); break;
|
||||||
|
case "System.TimeSpan": throw new Exception(CoreStrings.Unable_Parse_Expression(exp4));
|
||||||
}
|
}
|
||||||
if (string.IsNullOrEmpty(extRet) == false) return extRet;
|
if (string.IsNullOrEmpty(extRet) == false) return extRet;
|
||||||
var other4Exp = ExpressionLambdaToSqlOther(exp4, tsc);
|
var other4Exp = ExpressionLambdaToSqlOther(exp4, tsc);
|
||||||
@ -1808,7 +1810,7 @@ namespace FreeSql.Internal
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (expStack.First().NodeType != ExpressionType.Parameter)
|
if (exp4.IsParameter() == false && expStack.First().NodeType != ExpressionType.Parameter)
|
||||||
{
|
{
|
||||||
if (expStackConstOrMemberCount == expStack.Count)
|
if (expStackConstOrMemberCount == expStack.Count)
|
||||||
{
|
{
|
||||||
@ -2024,6 +2026,7 @@ namespace FreeSql.Internal
|
|||||||
}
|
}
|
||||||
name2 = col2.Attribute.Name;
|
name2 = col2.Attribute.Name;
|
||||||
tsc.SetMapColumnTmp(col2);
|
tsc.SetMapColumnTmp(col2);
|
||||||
|
if (expStack.Count > 0) throw new Exception(CoreStrings.Unable_Parse_Expression(expStack.Pop()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//判断 [JsonMap] 并非导航对象,所以在上面提前判断 ColumnsByCs
|
//判断 [JsonMap] 并非导航对象,所以在上面提前判断 ColumnsByCs
|
||||||
|
@ -81,6 +81,7 @@ namespace FreeSql.Internal.CommonProvider
|
|||||||
case DataType.CustomPostgreSQL:
|
case DataType.CustomPostgreSQL:
|
||||||
case DataType.KingbaseES:
|
case DataType.KingbaseES:
|
||||||
case DataType.ShenTong:
|
case DataType.ShenTong:
|
||||||
|
case DataType.DuckDB:
|
||||||
InterceptPostgreSQL?.Invoke(); break;
|
InterceptPostgreSQL?.Invoke(); break;
|
||||||
case DataType.Oracle:
|
case DataType.Oracle:
|
||||||
case DataType.OdbcOracle:
|
case DataType.OdbcOracle:
|
||||||
|
@ -2103,7 +2103,7 @@ namespace FreeSql.Internal
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal static MethodInfo MethodExecuteArrayRowReadClassOrTuple = typeof(Utils).GetMethod("ExecuteArrayRowReadClassOrTuple", BindingFlags.Static | BindingFlags.NonPublic);
|
internal static MethodInfo MethodExecuteArrayRowReadClassOrTuple = typeof(Utils).GetMethod("ExecuteArrayRowReadClassOrTuple", BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
internal static MethodInfo MethodGetDataReaderValue = typeof(Utils).GetMethod("GetDataReaderValue", BindingFlags.Static | BindingFlags.NonPublic);
|
internal static MethodInfo MethodGetDataReaderValue = typeof(Utils).GetMethod("GetDataReaderValue", BindingFlags.Static | BindingFlags.Public);
|
||||||
|
|
||||||
static ConcurrentDictionary<string, Action<object, object>> _dicFillPropertyValue = new ConcurrentDictionary<string, Action<object, object>>();
|
static ConcurrentDictionary<string, Action<object, object>> _dicFillPropertyValue = new ConcurrentDictionary<string, Action<object, object>>();
|
||||||
internal static void FillPropertyValue(object info, string memberAccessPath, object value)
|
internal static void FillPropertyValue(object info, string memberAccessPath, object value)
|
||||||
@ -2136,6 +2136,7 @@ namespace FreeSql.Internal
|
|||||||
public static string ToStringConcat(object obj)
|
public static string ToStringConcat(object obj)
|
||||||
{
|
{
|
||||||
if (obj == null) return null;
|
if (obj == null) return null;
|
||||||
|
if (obj is bool || obj is bool?) return (bool)obj == true ? "1" : "0";
|
||||||
return string.Concat(obj);
|
return string.Concat(obj);
|
||||||
}
|
}
|
||||||
public static byte[] GuidToBytes(Guid guid)
|
public static byte[] GuidToBytes(Guid guid)
|
||||||
@ -2156,10 +2157,37 @@ namespace FreeSql.Internal
|
|||||||
if (string.IsNullOrEmpty(str)) return default(char);
|
if (string.IsNullOrEmpty(str)) return default(char);
|
||||||
return str.ToCharArray(0, 1)[0];
|
return str.ToCharArray(0, 1)[0];
|
||||||
}
|
}
|
||||||
|
public static BitArray StringToBitArray(string str1010)
|
||||||
|
{
|
||||||
|
if (str1010 == null) return null;
|
||||||
|
BitArray ret = new BitArray(str1010.Length);
|
||||||
|
for (int a = 0; a < str1010.Length; a++) ret[a] = str1010[a] == '1';
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
public static TElement[] ListOrArrayToArray<TElement>(object listOrArray)
|
||||||
|
{
|
||||||
|
if (listOrArray is TElement[] arr2) return arr2;
|
||||||
|
if (listOrArray is Array arr)
|
||||||
|
{
|
||||||
|
var len = arr.GetLength(0);
|
||||||
|
arr2 = new TElement[len];
|
||||||
|
for (var a = 0; a < len; a++)
|
||||||
|
arr2[a] = (TElement)Utils.GetDataReaderValue(typeof(TElement), arr.GetValue(a));
|
||||||
|
return arr2;
|
||||||
|
}
|
||||||
|
if (listOrArray is IList list)
|
||||||
|
{
|
||||||
|
var len = list.Count;
|
||||||
|
arr2 = new TElement[len];
|
||||||
|
for (var a = 0; a < len; a++)
|
||||||
|
arr2[a] = (TElement)Utils.GetDataReaderValue(typeof(TElement), list[a]);
|
||||||
|
return arr2;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public static List<TElement> ListOrArrayToList<TElement>(object listOrArray) => ListOrArrayToArray<TElement>(listOrArray)?.ToList();
|
||||||
|
|
||||||
static ConcurrentDictionary<Type, ConcurrentDictionary<Type, Func<object, object>>> _dicGetDataReaderValue = new ConcurrentDictionary<Type, ConcurrentDictionary<Type, Func<object, object>>>();
|
static ConcurrentDictionary<Type, ConcurrentDictionary<Type, Func<object, object>>> _dicGetDataReaderValue = new ConcurrentDictionary<Type, ConcurrentDictionary<Type, Func<object, object>>>();
|
||||||
static MethodInfo MethodArrayGetValue = typeof(Array).GetMethod("GetValue", new[] { typeof(int) });
|
|
||||||
static MethodInfo MethodArrayGetLength = typeof(Array).GetMethod("GetLength", new[] { typeof(int) });
|
|
||||||
static MethodInfo MethodGuidTryParse = typeof(Guid).GetMethod("TryParse", new[] { typeof(string), typeof(Guid).MakeByRefType() });
|
static MethodInfo MethodGuidTryParse = typeof(Guid).GetMethod("TryParse", new[] { typeof(string), typeof(Guid).MakeByRefType() });
|
||||||
static MethodInfo MethodEnumParse = typeof(Enum).GetMethod("Parse", new[] { typeof(Type), typeof(string), typeof(bool) });
|
static MethodInfo MethodEnumParse = typeof(Enum).GetMethod("Parse", new[] { typeof(Type), typeof(string), typeof(bool) });
|
||||||
static MethodInfo MethodConvertChangeType = typeof(Convert).GetMethod("ChangeType", new[] { typeof(object), typeof(Type) });
|
static MethodInfo MethodConvertChangeType = typeof(Convert).GetMethod("ChangeType", new[] { typeof(object), typeof(Type) });
|
||||||
@ -2188,8 +2216,11 @@ namespace FreeSql.Internal
|
|||||||
static MethodInfo MethodEncodingGetString = typeof(Encoding).GetMethod("GetString", new[] { typeof(byte[]) });
|
static MethodInfo MethodEncodingGetString = typeof(Encoding).GetMethod("GetString", new[] { typeof(byte[]) });
|
||||||
static MethodInfo MethodStringToCharArray = typeof(string).GetMethod("ToCharArray", new Type[0]);
|
static MethodInfo MethodStringToCharArray = typeof(string).GetMethod("ToCharArray", new Type[0]);
|
||||||
static MethodInfo MethodStringToChar = typeof(Utils).GetMethod("StringToChar", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(string) }, null);
|
static MethodInfo MethodStringToChar = typeof(Utils).GetMethod("StringToChar", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(string) }, null);
|
||||||
|
static MethodInfo MethodStringToBitArray = typeof(Utils).GetMethod("StringToBitArray", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(string) }, null);
|
||||||
static MethodInfo MethodGuidToBytes = typeof(Utils).GetMethod("GuidToBytes", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(Guid) }, null);
|
static MethodInfo MethodGuidToBytes = typeof(Utils).GetMethod("GuidToBytes", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(Guid) }, null);
|
||||||
static MethodInfo MethodBytesToGuid = typeof(Utils).GetMethod("BytesToGuid", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(byte[]) }, null);
|
static MethodInfo MethodBytesToGuid = typeof(Utils).GetMethod("BytesToGuid", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(byte[]) }, null);
|
||||||
|
static MethodInfo MethodListOrArrayToArray = typeof(Utils).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(a => a.Name == "ListOrArrayToArray").FirstOrDefault();
|
||||||
|
static MethodInfo MethodListOrArrayToList = typeof(Utils).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(a => a.Name == "ListOrArrayToList").FirstOrDefault();
|
||||||
|
|
||||||
|
|
||||||
public static ConcurrentDictionary<Type, ITypeHandler> TypeHandlers { get; } = new ConcurrentDictionary<Type, ITypeHandler>();
|
public static ConcurrentDictionary<Type, ITypeHandler> TypeHandlers { get; } = new ConcurrentDictionary<Type, ITypeHandler>();
|
||||||
@ -2234,47 +2265,25 @@ namespace FreeSql.Internal
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
var elementType = type.GetElementType();
|
|
||||||
var arrNewExp = Expression.Variable(type, "arrNew");
|
|
||||||
var arrExp = Expression.Variable(typeof(Array), "arr");
|
|
||||||
var arrLenExp = Expression.Variable(typeof(int), "arrLen");
|
|
||||||
var arrXExp = Expression.Variable(typeof(int), "arrX");
|
|
||||||
var arrReadValExp = Expression.Variable(typeof(object), "arrReadVal");
|
|
||||||
var label = Expression.Label(typeof(int));
|
|
||||||
return Expression.IfThenElse(
|
return Expression.IfThenElse(
|
||||||
Expression.TypeEqual(valueExp, type),
|
Expression.TypeEqual(valueExp, type),
|
||||||
Expression.Return(returnTarget, valueExp),
|
Expression.Return(returnTarget, valueExp),
|
||||||
Expression.IfThenElse(
|
Expression.IfThenElse(
|
||||||
Expression.TypeEqual(valueExp, typeof(string)), //JSON
|
Expression.TypeEqual(valueExp, typeof(string)), //JSON
|
||||||
LocalFuncGetExpression(true),
|
LocalFuncGetExpression(true),
|
||||||
Expression.Block(
|
Expression.Return(returnTarget, Expression.Call(MethodListOrArrayToArray.MakeGenericMethod(type.GetElementType()), valueExp))
|
||||||
new[] { arrNewExp, arrExp, arrLenExp, arrXExp, arrReadValExp },
|
)
|
||||||
Expression.Assign(arrExp, Expression.TypeAs(valueExp, typeof(Array))),
|
);
|
||||||
Expression.IfThenElse(
|
}
|
||||||
Expression.Equal(arrExp, Expression.Constant(null)),
|
if (!ignoreArray && type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>))
|
||||||
Expression.Assign(arrLenExp, Expression.Constant(0)),
|
{
|
||||||
Expression.Assign(arrLenExp, Expression.Call(arrExp, MethodArrayGetLength, Expression.Constant(0)))
|
return Expression.IfThenElse(
|
||||||
),
|
Expression.TypeEqual(valueExp, type),
|
||||||
Expression.Assign(arrXExp, Expression.Constant(0)),
|
Expression.Return(returnTarget, valueExp),
|
||||||
Expression.Assign(arrNewExp, Expression.NewArrayBounds(elementType, arrLenExp)),
|
Expression.IfThenElse(
|
||||||
Expression.Loop(
|
Expression.TypeEqual(valueExp, typeof(string)), //JSON
|
||||||
Expression.IfThenElse(
|
LocalFuncGetExpression(true),
|
||||||
Expression.LessThan(arrXExp, arrLenExp),
|
Expression.Return(returnTarget, Expression.Call(MethodListOrArrayToList.MakeGenericMethod(type.GetGenericArguments().FirstOrDefault()), valueExp))
|
||||||
Expression.Block(
|
|
||||||
Expression.Assign(arrReadValExp, GetDataReaderValueBlockExpression(elementType, Expression.Call(arrExp, MethodArrayGetValue, arrXExp))),
|
|
||||||
Expression.IfThenElse(
|
|
||||||
Expression.Equal(arrReadValExp, Expression.Constant(null)),
|
|
||||||
Expression.Assign(Expression.ArrayAccess(arrNewExp, arrXExp), Expression.Default(elementType)),
|
|
||||||
Expression.Assign(Expression.ArrayAccess(arrNewExp, arrXExp), Expression.Convert(arrReadValExp, elementType))
|
|
||||||
),
|
|
||||||
Expression.PostIncrementAssign(arrXExp)
|
|
||||||
),
|
|
||||||
Expression.Break(label, arrXExp)
|
|
||||||
),
|
|
||||||
label
|
|
||||||
),
|
|
||||||
Expression.Return(returnTarget, arrNewExp)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -2503,6 +2512,16 @@ namespace FreeSql.Internal
|
|||||||
typeof(object))
|
typeof(object))
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
case "System.Collections.BitArray":
|
||||||
|
return Expression.IfThenElse(
|
||||||
|
Expression.TypeEqual(valueExp, type),
|
||||||
|
Expression.Return(returnTarget, valueExp),
|
||||||
|
Expression.IfThenElse(
|
||||||
|
Expression.TypeEqual(valueExp, typeof(string)),
|
||||||
|
Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodStringToBitArray, Expression.Convert(valueExp, typeof(string))), typeof(object))),
|
||||||
|
Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodStringToBitArray, Expression.Call(MethodToString, valueExp)), typeof(object)))
|
||||||
|
)
|
||||||
|
);
|
||||||
default:
|
default:
|
||||||
if (type.IsEnum && TypeHandlers.ContainsKey(type) == false)
|
if (type.IsEnum && TypeHandlers.ContainsKey(type) == false)
|
||||||
return Expression.Block(
|
return Expression.Block(
|
||||||
@ -2525,6 +2544,7 @@ namespace FreeSql.Internal
|
|||||||
Expression switchExp = Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type))));
|
Expression switchExp = Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type))));
|
||||||
Expression defaultRetExp = switchExp;
|
Expression defaultRetExp = switchExp;
|
||||||
if (tryparseExp != null)
|
if (tryparseExp != null)
|
||||||
|
{
|
||||||
switchExp = Expression.Switch(
|
switchExp = Expression.Switch(
|
||||||
Expression.Constant(type),
|
Expression.Constant(type),
|
||||||
Expression.SwitchCase(tryparseExp,
|
Expression.SwitchCase(tryparseExp,
|
||||||
@ -2535,6 +2555,9 @@ namespace FreeSql.Internal
|
|||||||
Expression.Constant(typeof(DateTime)), Expression.Constant(typeof(DateTimeOffset))
|
Expression.Constant(typeof(DateTime)), Expression.Constant(typeof(DateTimeOffset))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
// BigInteger/bool -> int
|
||||||
|
//defaultRetExp = Expression.Return(returnTarget, Expression.Call(MethodGetDataReaderValue, Expression.Constant(type), Expression.Convert(Expression.Call(MethodToString, valueExp), typeof(object))));
|
||||||
|
}
|
||||||
else if (tryparseBooleanExp != null)
|
else if (tryparseBooleanExp != null)
|
||||||
switchExp = Expression.Switch(
|
switchExp = Expression.Switch(
|
||||||
Expression.Constant(type),
|
Expression.Constant(type),
|
||||||
|
26
Providers/FreeSql.Provider.Duckdb/Curd/DuckdbDelete.cs
Normal file
26
Providers/FreeSql.Provider.Duckdb/Curd/DuckdbDelete.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using FreeSql.Internal;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FreeSql.Duckdb.Curd
|
||||||
|
{
|
||||||
|
|
||||||
|
class DuckdbDelete<T1> : Internal.CommonProvider.DeleteProvider<T1>
|
||||||
|
{
|
||||||
|
public DuckdbDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere)
|
||||||
|
: base(orm, commonUtils, commonExpression, dywhere)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override List<T1> ExecuteDeleted() => throw new NotImplementedException($"FreeSql.Provider.Duckdb {CoreStrings.S_Not_Implemented_Feature}");
|
||||||
|
|
||||||
|
#if net40
|
||||||
|
#else
|
||||||
|
public override Task<List<T1>> ExecuteDeletedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException($"FreeSql.Provider.Duckdb {CoreStrings.S_Not_Implemented_Feature}");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
217
Providers/FreeSql.Provider.Duckdb/Curd/DuckdbInsert.cs
Normal file
217
Providers/FreeSql.Provider.Duckdb/Curd/DuckdbInsert.cs
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
using FreeSql.Internal;
|
||||||
|
using FreeSql.Internal.Model;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Data.Common;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FreeSql.Duckdb.Curd
|
||||||
|
{
|
||||||
|
|
||||||
|
class DuckdbInsert<T1> : Internal.CommonProvider.InsertProvider<T1> where T1 : class
|
||||||
|
{
|
||||||
|
public DuckdbInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression)
|
||||||
|
: base(orm, commonUtils, commonExpression)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal IFreeSql InternalOrm => _orm;
|
||||||
|
internal TableInfo InternalTable => _table;
|
||||||
|
internal DbParameter[] InternalParams => _params;
|
||||||
|
internal DbConnection InternalConnection => _connection;
|
||||||
|
internal DbTransaction InternalTransaction => _transaction;
|
||||||
|
internal CommonUtils InternalCommonUtils => _commonUtils;
|
||||||
|
internal CommonExpression InternalCommonExpression => _commonExpression;
|
||||||
|
internal List<T1> InternalSource => _source;
|
||||||
|
internal Dictionary<string, bool> InternalIgnore => _ignore;
|
||||||
|
internal void InternalClearData() => ClearData();
|
||||||
|
|
||||||
|
public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000);
|
||||||
|
public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000);
|
||||||
|
public override List<T1> ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000);
|
||||||
|
|
||||||
|
protected override long RawExecuteIdentity()
|
||||||
|
{
|
||||||
|
var sql = this.ToSql();
|
||||||
|
if (string.IsNullOrEmpty(sql)) return 0;
|
||||||
|
|
||||||
|
long ret = 0;
|
||||||
|
Exception exception = null;
|
||||||
|
Aop.CurdBeforeEventArgs before = null;
|
||||||
|
|
||||||
|
var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true);
|
||||||
|
if (identCols.Any() == false)
|
||||||
|
{
|
||||||
|
before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params);
|
||||||
|
_orm.Aop.CurdBeforeHandler?.Invoke(this, before);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
exception = ex;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||||
|
_orm.Aop.CurdAfterHandler?.Invoke(this, after);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name));
|
||||||
|
before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params);
|
||||||
|
_orm.Aop.CurdBeforeHandler?.Invoke(this, before);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
exception = ex;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||||
|
_orm.Aop.CurdAfterHandler?.Invoke(this, after);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override List<T1> RawExecuteInserted()
|
||||||
|
{
|
||||||
|
var sql = this.ToSql();
|
||||||
|
if (string.IsNullOrEmpty(sql)) return new List<T1>();
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
sb.Append(sql).Append(" RETURNING ");
|
||||||
|
|
||||||
|
var colidx = 0;
|
||||||
|
foreach (var col in _table.Columns.Values)
|
||||||
|
{
|
||||||
|
if (colidx > 0) sb.Append(", ");
|
||||||
|
sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
|
||||||
|
++colidx;
|
||||||
|
}
|
||||||
|
sql = sb.ToString();
|
||||||
|
var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params);
|
||||||
|
_orm.Aop.CurdBeforeHandler?.Invoke(this, before);
|
||||||
|
var ret = new List<T1>();
|
||||||
|
Exception exception = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ret = _orm.Ado.Query<T1>(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
exception = ex;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||||
|
_orm.Aop.CurdAfterHandler?.Invoke(this, after);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if net40
|
||||||
|
#else
|
||||||
|
public override Task<int> ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken);
|
||||||
|
public override Task<long> ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken);
|
||||||
|
public override Task<List<T1>> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken);
|
||||||
|
|
||||||
|
async protected override Task<long> RawExecuteIdentityAsync(CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var sql = this.ToSql();
|
||||||
|
if (string.IsNullOrEmpty(sql)) return 0;
|
||||||
|
|
||||||
|
long ret = 0;
|
||||||
|
Exception exception = null;
|
||||||
|
Aop.CurdBeforeEventArgs before = null;
|
||||||
|
|
||||||
|
var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true);
|
||||||
|
if (identCols.Any() == false)
|
||||||
|
{
|
||||||
|
before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params);
|
||||||
|
_orm.Aop.CurdBeforeHandler?.Invoke(this, before);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
exception = ex;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||||
|
_orm.Aop.CurdAfterHandler?.Invoke(this, after);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name));
|
||||||
|
before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params);
|
||||||
|
_orm.Aop.CurdBeforeHandler?.Invoke(this, before);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken)), out ret);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
exception = ex;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||||
|
_orm.Aop.CurdAfterHandler?.Invoke(this, after);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
async protected override Task<List<T1>> RawExecuteInsertedAsync(CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var sql = this.ToSql();
|
||||||
|
if (string.IsNullOrEmpty(sql)) return new List<T1>();
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
sb.Append(sql).Append(" RETURNING ");
|
||||||
|
|
||||||
|
var colidx = 0;
|
||||||
|
foreach (var col in _table.Columns.Values)
|
||||||
|
{
|
||||||
|
if (colidx > 0) sb.Append(", ");
|
||||||
|
sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
|
||||||
|
++colidx;
|
||||||
|
}
|
||||||
|
sql = sb.ToString();
|
||||||
|
var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params);
|
||||||
|
_orm.Aop.CurdBeforeHandler?.Invoke(this, before);
|
||||||
|
var ret = new List<T1>();
|
||||||
|
Exception exception = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ret = await _orm.Ado.QueryAsync<T1>(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
exception = ex;
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
|
||||||
|
_orm.Aop.CurdAfterHandler?.Invoke(this, after);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
using FreeSql.Internal;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data.Common;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace FreeSql.Duckdb.Curd
|
||||||
|
{
|
||||||
|
|
||||||
|
class DuckdbInsertOrUpdate<T1> : Internal.CommonProvider.InsertOrUpdateProvider<T1> where T1 : class
|
||||||
|
{
|
||||||
|
public DuckdbInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression)
|
||||||
|
: base(orm, commonUtils, commonExpression)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToSql()
|
||||||
|
{
|
||||||
|
var dbParams = new List<DbParameter>();
|
||||||
|
if (_sourceSql != null)
|
||||||
|
{
|
||||||
|
var data = new List<T1>();
|
||||||
|
data.Add((T1)_table.Type.CreateInstanceGetDefaultValue());
|
||||||
|
var sql = getInsertSql(data, false, false);
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
sb.Append(sql.Substring(0, sql.IndexOf(") VALUES")));
|
||||||
|
sb.Append(") \r\n");
|
||||||
|
WriteSourceSelectUnionAll(null, sb, null);
|
||||||
|
sb.Append(sql.Substring(sql.IndexOf("\r\nON CONFLICT(") + 2));
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
if (_source?.Any() != true) return null;
|
||||||
|
|
||||||
|
var sqls = new string[2];
|
||||||
|
var ds = SplitSourceByIdentityValueIsNull(_source);
|
||||||
|
if (ds.Item1.Any()) sqls[0] = string.Join("\r\n\r\n;\r\n\r\n", ds.Item1.Select(a => getInsertSql(a, false, true)));
|
||||||
|
if (ds.Item2.Any()) sqls[1] = string.Join("\r\n\r\n;\r\n\r\n", ds.Item2.Select(a => getInsertSql(a, true, true)));
|
||||||
|
_params = dbParams.ToArray();
|
||||||
|
if (ds.Item2.Any() == false) return sqls[0];
|
||||||
|
if (ds.Item1.Any() == false) return sqls[1];
|
||||||
|
return string.Join("\r\n\r\n;\r\n\r\n", sqls);
|
||||||
|
|
||||||
|
string getInsertSql(List<T1> data, bool flagInsert, bool noneParameter)
|
||||||
|
{
|
||||||
|
var insert = _orm.Insert<T1>()
|
||||||
|
.AsTable(_tableRule).AsType(_table.Type)
|
||||||
|
.WithConnection(_connection)
|
||||||
|
.WithTransaction(_transaction)
|
||||||
|
.NoneParameter(noneParameter) as Internal.CommonProvider.InsertProvider<T1>;
|
||||||
|
insert._source = data;
|
||||||
|
insert._table = _table;
|
||||||
|
insert._noneParameterFlag = flagInsert ? "cuc" : "cu";
|
||||||
|
|
||||||
|
string sql = "";
|
||||||
|
if (IdentityColumn != null && flagInsert) sql = insert.ToSql();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var ocdu = new OnConflictDoUpdate<T1>(insert.InsertIdentity());
|
||||||
|
ocdu._tempPrimarys = _tempPrimarys;
|
||||||
|
var cols = _table.Columns.Values.Where(a => _updateSetDict.ContainsKey(a.Attribute.Name) ||
|
||||||
|
_tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && a.Attribute.IsIdentity == false && _updateIgnore.ContainsKey(a.Attribute.Name) == false);
|
||||||
|
ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray());
|
||||||
|
if (_doNothing == true || cols.Any() == false)
|
||||||
|
ocdu.DoNothing();
|
||||||
|
sql = ocdu.ToSql();
|
||||||
|
|
||||||
|
if (_updateSetDict.Any())
|
||||||
|
{
|
||||||
|
var findregex = new Regex("(t1|t2)." + _commonUtils.QuoteSqlName("test").Replace("test", "(\\w+)"));
|
||||||
|
var tableName = _commonUtils.QuoteSqlName(TableRuleInvoke());
|
||||||
|
foreach (var usd in _updateSetDict)
|
||||||
|
{
|
||||||
|
var field = _commonUtils.QuoteSqlName(usd.Key);
|
||||||
|
var findsql = $"{field} = EXCLUDED.{field}";
|
||||||
|
var usdval = findregex.Replace(usd.Value, m =>
|
||||||
|
{
|
||||||
|
if (m.Groups[1].Value == "t1") return $"{tableName}.{_commonUtils.QuoteSqlName(m.Groups[2].Value)}";
|
||||||
|
return $"EXCLUDED.{_commonUtils.QuoteSqlName(m.Groups[2].Value)}";
|
||||||
|
});
|
||||||
|
sql = sql.Replace(findsql, $"{field} = {usdval}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (string.IsNullOrEmpty(sql)) return null;
|
||||||
|
if (insert._params?.Any() == true) dbParams.AddRange(insert._params);
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
222
Providers/FreeSql.Provider.Duckdb/Curd/DuckdbSelect.cs
Normal file
222
Providers/FreeSql.Provider.Duckdb/Curd/DuckdbSelect.cs
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
using FreeSql.Internal;
|
||||||
|
using FreeSql.Internal.Model;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace FreeSql.Duckdb.Curd
|
||||||
|
{
|
||||||
|
|
||||||
|
class DuckdbSelect<T1> : FreeSql.Internal.CommonProvider.Select1Provider<T1>
|
||||||
|
{
|
||||||
|
|
||||||
|
internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List<SelectTableInfo> _tables, List<Dictionary<Type, string>> tbUnions, Func<Type, string, string> _aliasRule, string _tosqlAppendContent, List<GlobalFilter.Item> _whereGlobalFilter, IFreeSql _orm)
|
||||||
|
{
|
||||||
|
if (_orm.CodeFirst.IsAutoSyncStructure)
|
||||||
|
_orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray());
|
||||||
|
|
||||||
|
if (_whereGlobalFilter.Any())
|
||||||
|
foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent))
|
||||||
|
{
|
||||||
|
tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter.Where(a => a.Before == false), true);
|
||||||
|
tb.CascadeBefore = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter.Where(a => a.Before == true), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
var tbUnionsGt0 = tbUnions.Count > 1;
|
||||||
|
for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++)
|
||||||
|
{
|
||||||
|
if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n");
|
||||||
|
if (tbUnionsGt0) sb.Append(_select).Append(" * from (");
|
||||||
|
var tbUnion = tbUnions[tbUnionsIdx];
|
||||||
|
|
||||||
|
var sbnav = new StringBuilder();
|
||||||
|
sb.Append(_select);
|
||||||
|
if (_distinct) sb.Append("DISTINCT ");
|
||||||
|
sb.Append(field).Append(" \r\nFROM ");
|
||||||
|
var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray();
|
||||||
|
var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray();
|
||||||
|
for (var a = 0; a < tbsfrom.Length; a++)
|
||||||
|
{
|
||||||
|
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias);
|
||||||
|
if (tbsjoin.Length > 0)
|
||||||
|
{
|
||||||
|
//如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1
|
||||||
|
for (var b = 1; b < tbsfrom.Length; b++)
|
||||||
|
{
|
||||||
|
sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias);
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) &&
|
||||||
|
string.IsNullOrEmpty(tbsfrom[b].On) &&
|
||||||
|
string.IsNullOrEmpty(tbsfrom[b].Cascade) &&
|
||||||
|
string.IsNullOrEmpty(tbsfrom[b].CascadeBefore)) sb.Append(" ON 1 = 1");
|
||||||
|
else sb.Append(" ON ").Append(string.Join(" AND ", new[]
|
||||||
|
{
|
||||||
|
tbsfrom[b].CascadeBefore,
|
||||||
|
tbsfrom[b].NavigateCondition ?? tbsfrom[b].On,
|
||||||
|
tbsfrom[b].Cascade
|
||||||
|
}.Where(sql => string.IsNullOrEmpty(sql) == false)));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].CascadeBefore)) sbnav.Append(" AND ").Append(tbsfrom[a].CascadeBefore);
|
||||||
|
if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")");
|
||||||
|
if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")");
|
||||||
|
if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade);
|
||||||
|
}
|
||||||
|
if (a < tbsfrom.Length - 1) sb.Append(", ");
|
||||||
|
}
|
||||||
|
foreach (var tb in tbsjoin)
|
||||||
|
{
|
||||||
|
switch (tb.Type)
|
||||||
|
{
|
||||||
|
case SelectTableInfoType.Parent:
|
||||||
|
case SelectTableInfoType.RawJoin:
|
||||||
|
continue;
|
||||||
|
case SelectTableInfoType.LeftJoin:
|
||||||
|
sb.Append(" \r\nLEFT JOIN ");
|
||||||
|
break;
|
||||||
|
case SelectTableInfoType.InnerJoin:
|
||||||
|
sb.Append(" \r\nINNER JOIN ");
|
||||||
|
break;
|
||||||
|
case SelectTableInfoType.RightJoin:
|
||||||
|
sb.Append(" \r\nRIGHT JOIN ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias)
|
||||||
|
.Append(" ON ").Append(string.Join(" AND ", new[]
|
||||||
|
{
|
||||||
|
tb.CascadeBefore,
|
||||||
|
tb.On ?? tb.NavigateCondition,
|
||||||
|
tb.Cascade
|
||||||
|
}.Where(sql => string.IsNullOrEmpty(sql) == false)));
|
||||||
|
if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")");
|
||||||
|
}
|
||||||
|
if (_join.Length > 0) sb.Append(_join);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(_tables[0].CascadeBefore)) sbnav.Append(" AND ").Append(_tables[0].CascadeBefore);
|
||||||
|
sbnav.Append(_where);
|
||||||
|
if (!string.IsNullOrEmpty(_tables[0].Cascade)) sbnav.Append(" AND ").Append(_tables[0].Cascade);
|
||||||
|
|
||||||
|
if (sbnav.Length > 0)
|
||||||
|
{
|
||||||
|
sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5));
|
||||||
|
}
|
||||||
|
if (string.IsNullOrEmpty(_groupby) == false)
|
||||||
|
{
|
||||||
|
sb.Append(_groupby);
|
||||||
|
if (string.IsNullOrEmpty(_having) == false)
|
||||||
|
sb.Append(" \r\nHAVING ").Append(_having.Substring(5));
|
||||||
|
}
|
||||||
|
sb.Append(_orderby);
|
||||||
|
if (_limit > 0)
|
||||||
|
sb.Append(" \r\nlimit ").Append(_limit);
|
||||||
|
if (_skip > 0)
|
||||||
|
sb.Append(" \r\noffset ").Append(_skip);
|
||||||
|
|
||||||
|
sbnav.Clear();
|
||||||
|
if (tbUnionsGt0) sb.Append(") ftb");
|
||||||
|
}
|
||||||
|
return sb.Append(_tosqlAppendContent).ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public DuckdbSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
|
||||||
|
public override ISelect<T1, T2> From<T2>(Expression<Func<ISelectFromExpression<T1>, T2, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp); var ret = new DuckdbSelect<T1, T2>(_orm, _commonUtils, _commonExpression, null); DuckdbSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
|
||||||
|
public override ISelect<T1, T2, T3> From<T2, T3>(Expression<Func<ISelectFromExpression<T1>, T2, T3, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp); var ret = new DuckdbSelect<T1, T2, T3>(_orm, _commonUtils, _commonExpression, null); DuckdbSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
|
||||||
|
public override ISelect<T1, T2, T3, T4> From<T2, T3, T4>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp); var ret = new DuckdbSelect<T1, T2, T3, T4>(_orm, _commonUtils, _commonExpression, null); DuckdbSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
|
||||||
|
public override ISelect<T1, T2, T3, T4, T5> From<T2, T3, T4, T5>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp); var ret = new DuckdbSelect<T1, T2, T3, T4, T5>(_orm, _commonUtils, _commonExpression, null); DuckdbSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
|
||||||
|
public override ISelect<T1, T2, T3, T4, T5, T6> From<T2, T3, T4, T5, T6>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp); var ret = new DuckdbSelect<T1, T2, T3, T4, T5, T6>(_orm, _commonUtils, _commonExpression, null); DuckdbSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
|
||||||
|
public override ISelect<T1, T2, T3, T4, T5, T6, T7> From<T2, T3, T4, T5, T6, T7>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp); var ret = new DuckdbSelect<T1, T2, T3, T4, T5, T6, T7>(_orm, _commonUtils, _commonExpression, null); DuckdbSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
|
||||||
|
public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8> From<T2, T3, T4, T5, T6, T7, T8>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp); var ret = new DuckdbSelect<T1, T2, T3, T4, T5, T6, T7, T8>(_orm, _commonUtils, _commonExpression, null); DuckdbSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
|
||||||
|
public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> From<T2, T3, T4, T5, T6, T7, T8, T9>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp); var ret = new DuckdbSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>(_orm, _commonUtils, _commonExpression, null); DuckdbSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
|
||||||
|
public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> From<T2, T3, T4, T5, T6, T7, T8, T9, T10>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp); var ret = new DuckdbSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(_orm, _commonUtils, _commonExpression, null); DuckdbSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
|
||||||
|
|
||||||
|
public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> From<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp); var ret = new DuckdbSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(_orm, _commonUtils, _commonExpression, null); DuckdbSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
|
||||||
|
public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> From<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp); var ret = new DuckdbSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(_orm, _commonUtils, _commonExpression, null); DuckdbSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
|
||||||
|
public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> From<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp); var ret = new DuckdbSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(_orm, _commonUtils, _commonExpression, null); DuckdbSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
|
||||||
|
public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> From<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp); var ret = new DuckdbSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(_orm, _commonUtils, _commonExpression, null); DuckdbSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
|
||||||
|
public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> From<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp); var ret = new DuckdbSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(_orm, _commonUtils, _commonExpression, null); DuckdbSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
|
||||||
|
public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> From<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp); var ret = new DuckdbSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(_orm, _commonUtils, _commonExpression, null); DuckdbSelect<T1>.CopyData(this, ret, exp?.Parameters); return ret; }
|
||||||
|
public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm);
|
||||||
|
}
|
||||||
|
class DuckdbSelect<T1, T2> : FreeSql.Internal.CommonProvider.Select2Provider<T1, T2> where T2 : class
|
||||||
|
{
|
||||||
|
public DuckdbSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
|
||||||
|
public override string ToSql(string field = null) => DuckdbSelect<T1>.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm);
|
||||||
|
}
|
||||||
|
class DuckdbSelect<T1, T2, T3> : FreeSql.Internal.CommonProvider.Select3Provider<T1, T2, T3> where T2 : class where T3 : class
|
||||||
|
{
|
||||||
|
public DuckdbSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
|
||||||
|
public override string ToSql(string field = null) => DuckdbSelect<T1>.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm);
|
||||||
|
}
|
||||||
|
class DuckdbSelect<T1, T2, T3, T4> : FreeSql.Internal.CommonProvider.Select4Provider<T1, T2, T3, T4> where T2 : class where T3 : class where T4 : class
|
||||||
|
{
|
||||||
|
public DuckdbSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
|
||||||
|
public override string ToSql(string field = null) => DuckdbSelect<T1>.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm);
|
||||||
|
}
|
||||||
|
class DuckdbSelect<T1, T2, T3, T4, T5> : FreeSql.Internal.CommonProvider.Select5Provider<T1, T2, T3, T4, T5> where T2 : class where T3 : class where T4 : class where T5 : class
|
||||||
|
{
|
||||||
|
public DuckdbSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
|
||||||
|
public override string ToSql(string field = null) => DuckdbSelect<T1>.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm);
|
||||||
|
}
|
||||||
|
class DuckdbSelect<T1, T2, T3, T4, T5, T6> : FreeSql.Internal.CommonProvider.Select6Provider<T1, T2, T3, T4, T5, T6> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class
|
||||||
|
{
|
||||||
|
public DuckdbSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
|
||||||
|
public override string ToSql(string field = null) => DuckdbSelect<T1>.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm);
|
||||||
|
}
|
||||||
|
class DuckdbSelect<T1, T2, T3, T4, T5, T6, T7> : FreeSql.Internal.CommonProvider.Select7Provider<T1, T2, T3, T4, T5, T6, T7> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class
|
||||||
|
{
|
||||||
|
public DuckdbSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
|
||||||
|
public override string ToSql(string field = null) => DuckdbSelect<T1>.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm);
|
||||||
|
}
|
||||||
|
class DuckdbSelect<T1, T2, T3, T4, T5, T6, T7, T8> : FreeSql.Internal.CommonProvider.Select8Provider<T1, T2, T3, T4, T5, T6, T7, T8> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class
|
||||||
|
{
|
||||||
|
public DuckdbSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
|
||||||
|
public override string ToSql(string field = null) => DuckdbSelect<T1>.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm);
|
||||||
|
}
|
||||||
|
class DuckdbSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> : FreeSql.Internal.CommonProvider.Select9Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class
|
||||||
|
{
|
||||||
|
public DuckdbSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
|
||||||
|
public override string ToSql(string field = null) => DuckdbSelect<T1>.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm);
|
||||||
|
}
|
||||||
|
class DuckdbSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : FreeSql.Internal.CommonProvider.Select10Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class
|
||||||
|
{
|
||||||
|
public DuckdbSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
|
||||||
|
public override string ToSql(string field = null) => DuckdbSelect<T1>.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm);
|
||||||
|
}
|
||||||
|
|
||||||
|
class DuckdbSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> : FreeSql.Internal.CommonProvider.Select11Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class
|
||||||
|
{
|
||||||
|
public DuckdbSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
|
||||||
|
public override string ToSql(string field = null) => DuckdbSelect<T1>.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm);
|
||||||
|
}
|
||||||
|
class DuckdbSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> : FreeSql.Internal.CommonProvider.Select12Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class
|
||||||
|
{
|
||||||
|
public DuckdbSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
|
||||||
|
public override string ToSql(string field = null) => DuckdbSelect<T1>.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm);
|
||||||
|
}
|
||||||
|
class DuckdbSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> : FreeSql.Internal.CommonProvider.Select13Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class
|
||||||
|
{
|
||||||
|
public DuckdbSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
|
||||||
|
public override string ToSql(string field = null) => DuckdbSelect<T1>.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm);
|
||||||
|
}
|
||||||
|
class DuckdbSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> : FreeSql.Internal.CommonProvider.Select14Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class
|
||||||
|
{
|
||||||
|
public DuckdbSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
|
||||||
|
public override string ToSql(string field = null) => DuckdbSelect<T1>.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm);
|
||||||
|
}
|
||||||
|
class DuckdbSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> : FreeSql.Internal.CommonProvider.Select15Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class
|
||||||
|
{
|
||||||
|
public DuckdbSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
|
||||||
|
public override string ToSql(string field = null) => DuckdbSelect<T1>.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm);
|
||||||
|
}
|
||||||
|
class DuckdbSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> : FreeSql.Internal.CommonProvider.Select16Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class
|
||||||
|
{
|
||||||
|
public DuckdbSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
|
||||||
|
public override string ToSql(string field = null) => DuckdbSelect<T1>.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm);
|
||||||
|
}
|
||||||
|
}
|
96
Providers/FreeSql.Provider.Duckdb/Curd/DuckdbUpdate.cs
Normal file
96
Providers/FreeSql.Provider.Duckdb/Curd/DuckdbUpdate.cs
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
using FreeSql.Internal;
|
||||||
|
using FreeSql.Internal.Model;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Data.Common;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FreeSql.Duckdb.Curd
|
||||||
|
{
|
||||||
|
|
||||||
|
class DuckdbUpdate<T1> : Internal.CommonProvider.UpdateProvider<T1>
|
||||||
|
{
|
||||||
|
|
||||||
|
public DuckdbUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere)
|
||||||
|
: base(orm, commonUtils, commonExpression, dywhere)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal string InternalTableAlias { get; set; }
|
||||||
|
internal StringBuilder InternalSbSet => _set;
|
||||||
|
internal StringBuilder InternalSbSetIncr => _setIncr;
|
||||||
|
internal Dictionary<string, bool> InternalIgnore => _ignore;
|
||||||
|
internal void InternalResetSource(List<T1> source) => _source = source;
|
||||||
|
internal string InternalWhereCaseSource(string CsName, Func<string, string> thenValue) => WhereCaseSource(CsName, thenValue);
|
||||||
|
internal void InternalToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) => ToSqlCaseWhenEnd(sb, col);
|
||||||
|
|
||||||
|
public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000);
|
||||||
|
protected override List<TReturn> ExecuteUpdated<TReturn>(IEnumerable<ColumnInfo> columns) => base.SplitExecuteUpdated<TReturn>(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, columns);
|
||||||
|
protected override List<TReturn> RawExecuteUpdated<TReturn>(IEnumerable<ColumnInfo> columns) => throw new NotImplementedException($"FreeSql.Provider.Duckdb {CoreStrings.S_Not_Implemented_Feature}");
|
||||||
|
|
||||||
|
protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys)
|
||||||
|
{
|
||||||
|
if (primarys.Length == 1)
|
||||||
|
{
|
||||||
|
var pk = primarys.First();
|
||||||
|
if (string.IsNullOrEmpty(InternalTableAlias) == false) caseWhen.Append(InternalTableAlias).Append(".");
|
||||||
|
caseWhen.Append(_commonUtils.RereadColumn(pk, _commonUtils.QuoteSqlName(pk.Attribute.Name)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
caseWhen.Append("(");
|
||||||
|
var pkidx = 0;
|
||||||
|
foreach (var pk in primarys)
|
||||||
|
{
|
||||||
|
if (pkidx > 0) caseWhen.Append(" || '+' || ");
|
||||||
|
if (string.IsNullOrEmpty(InternalTableAlias) == false) caseWhen.Append(InternalTableAlias).Append(".");
|
||||||
|
caseWhen.Append(_commonUtils.RereadColumn(pk, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::text");
|
||||||
|
++pkidx;
|
||||||
|
}
|
||||||
|
caseWhen.Append(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d)
|
||||||
|
{
|
||||||
|
if (primarys.Length == 1)
|
||||||
|
{
|
||||||
|
sb.Append(_commonUtils.FormatSql("{0}", primarys[0].GetDbValue(d)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sb.Append("(");
|
||||||
|
var pkidx = 0;
|
||||||
|
foreach (var pk in primarys)
|
||||||
|
{
|
||||||
|
if (pkidx > 0) sb.Append(" || '+' || ");
|
||||||
|
sb.Append(_commonUtils.FormatSql("{0}", pk.GetDbValue(d))).Append("::text");
|
||||||
|
++pkidx;
|
||||||
|
}
|
||||||
|
sb.Append(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col)
|
||||||
|
{
|
||||||
|
if (_noneParameter == false) return;
|
||||||
|
if (col.Attribute.MapType == typeof(string))
|
||||||
|
{
|
||||||
|
sb.Append("::text");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var dbtype = _commonUtils.CodeFirst.GetDbInfo(col.Attribute.MapType)?.dbtype;
|
||||||
|
if (dbtype == null) return;
|
||||||
|
|
||||||
|
sb.Append("::").Append(dbtype);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if net40
|
||||||
|
#else
|
||||||
|
public override Task<int> ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken);
|
||||||
|
protected override Task<List<TReturn>> ExecuteUpdatedAsync<TReturn>(IEnumerable<ColumnInfo> columns, CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync<TReturn>(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, columns, cancellationToken);
|
||||||
|
protected override Task<List<TReturn>> RawExecuteUpdatedAsync<TReturn>(IEnumerable<ColumnInfo> columns, CancellationToken cancellationToken = default) => throw new NotImplementedException($"FreeSql.Provider.Duckdb {CoreStrings.S_Not_Implemented_Feature}");
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
217
Providers/FreeSql.Provider.Duckdb/Curd/OnConflictDoUpdate.cs
Normal file
217
Providers/FreeSql.Provider.Duckdb/Curd/OnConflictDoUpdate.cs
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
using FreeSql.Aop;
|
||||||
|
using FreeSql.Internal.Model;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FreeSql.Duckdb.Curd
|
||||||
|
{
|
||||||
|
public class OnConflictDoUpdate<T1> where T1 : class
|
||||||
|
{
|
||||||
|
internal DuckdbInsert<T1> _duckdbInsert;
|
||||||
|
internal DuckdbUpdate<T1> _duckdbUpdatePriv;
|
||||||
|
internal DuckdbUpdate<T1> _duckdbUpdate => _duckdbUpdatePriv ??
|
||||||
|
(_duckdbUpdatePriv = new DuckdbUpdate<T1>(_duckdbInsert.InternalOrm, _duckdbInsert.InternalCommonUtils, _duckdbInsert.InternalCommonExpression, null) { InternalTableAlias = "EXCLUDED" }
|
||||||
|
.NoneParameter().SetSource(_duckdbInsert.InternalSource) as DuckdbUpdate<T1>);
|
||||||
|
internal ColumnInfo[] _tempPrimarys;
|
||||||
|
bool _doNothing;
|
||||||
|
|
||||||
|
public OnConflictDoUpdate(IInsert<T1> insert, Expression<Func<T1, object>> columns = null)
|
||||||
|
{
|
||||||
|
_duckdbInsert = insert as DuckdbInsert<T1>;
|
||||||
|
if (_duckdbInsert == null) throw new Exception(CoreStrings.S_Features_Unique("OnConflictDoUpdate", "Duckdb"));
|
||||||
|
if (_duckdbInsert._noneParameterFlag == "c") _duckdbInsert._noneParameterFlag = "cu";
|
||||||
|
|
||||||
|
if (columns != null)
|
||||||
|
{
|
||||||
|
var colsList = new List<ColumnInfo>();
|
||||||
|
var cols = _duckdbInsert.InternalCommonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, null, columns?.Body, false, null).ToDictionary(a => a, a => true);
|
||||||
|
foreach (var col in _duckdbInsert.InternalTable.Columns.Values)
|
||||||
|
if (cols.ContainsKey(col.Attribute.Name))
|
||||||
|
colsList.Add(col);
|
||||||
|
_tempPrimarys = colsList.ToArray();
|
||||||
|
}
|
||||||
|
if (_tempPrimarys == null || _tempPrimarys.Any() == false)
|
||||||
|
_tempPrimarys = _duckdbInsert.InternalTable.Primarys;
|
||||||
|
if (_tempPrimarys.Any() == false) throw new Exception(CoreStrings.S_OnConflictDoUpdate_MustIsPrimary);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void ClearData()
|
||||||
|
{
|
||||||
|
_duckdbInsert.InternalClearData();
|
||||||
|
_duckdbUpdatePriv = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OnConflictDoUpdate<T1> IgnoreColumns(Expression<Func<T1, object>> columns)
|
||||||
|
{
|
||||||
|
_duckdbUpdate.IgnoreColumns(columns);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public OnConflictDoUpdate<T1> UpdateColumns(Expression<Func<T1, object>> columns)
|
||||||
|
{
|
||||||
|
_duckdbUpdate.UpdateColumns(columns);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public OnConflictDoUpdate<T1> IgnoreColumns(string[] columns)
|
||||||
|
{
|
||||||
|
_duckdbUpdate.IgnoreColumns(columns);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public OnConflictDoUpdate<T1> UpdateColumns(string[] columns)
|
||||||
|
{
|
||||||
|
_duckdbUpdate.UpdateColumns(columns);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OnConflictDoUpdate<T1> Set<TMember>(Expression<Func<T1, TMember>> column, TMember value)
|
||||||
|
{
|
||||||
|
_duckdbUpdate.Set(column, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
//由于表达式解析问题,ON CONFLICT("id") DO UPDATE SET 需要指定表别名,如 Set(a => a.Clicks + 1) 解析会失败
|
||||||
|
//暂时不开放这个功能,如有需要使用 SetRaw("click = t.click + 1") 替代该操作
|
||||||
|
//public OnConflictDoUpdate<T1> Set<TMember>(Expression<Func<T1, TMember>> exp)
|
||||||
|
//{
|
||||||
|
// _duckdbUpdate.Set(exp);
|
||||||
|
// return this;
|
||||||
|
//}
|
||||||
|
public OnConflictDoUpdate<T1> SetRaw(string sql)
|
||||||
|
{
|
||||||
|
_duckdbUpdate.SetRaw(sql);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OnConflictDoUpdate<T1> DoNothing()
|
||||||
|
{
|
||||||
|
_doNothing = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ToSql()
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
sb.Append(_duckdbInsert.ToSql()).Append("\r\nON CONFLICT(");
|
||||||
|
for (var a = 0; a < _tempPrimarys.Length; a++)
|
||||||
|
{
|
||||||
|
if (a > 0) sb.Append(", ");
|
||||||
|
sb.Append(_duckdbInsert.InternalCommonUtils.QuoteSqlName(_tempPrimarys[a].Attribute.Name));
|
||||||
|
}
|
||||||
|
if (_doNothing)
|
||||||
|
{
|
||||||
|
sb.Append(") DO NOTHING");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.Append(") DO UPDATE SET\r\n");
|
||||||
|
|
||||||
|
if (_duckdbUpdate._tempPrimarys.Any() == false) _duckdbUpdate._tempPrimarys = _tempPrimarys;
|
||||||
|
var sbSetEmpty = _duckdbUpdate.InternalSbSet.Length == 0;
|
||||||
|
var sbSetIncrEmpty = _duckdbUpdate.InternalSbSetIncr.Length == 0;
|
||||||
|
if (sbSetEmpty == false || sbSetIncrEmpty == false)
|
||||||
|
{
|
||||||
|
if (sbSetEmpty == false) sb.Append(_duckdbUpdate.InternalSbSet.ToString().Substring(2));
|
||||||
|
if (sbSetIncrEmpty == false) sb.Append(sbSetEmpty ? _duckdbUpdate.InternalSbSetIncr.ToString().Substring(2) : _duckdbUpdate.InternalSbSetIncr.ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var colidx = 0;
|
||||||
|
foreach (var col in _duckdbInsert.InternalTable.Columns.Values)
|
||||||
|
{
|
||||||
|
if (col.Attribute.IsPrimary || _duckdbUpdate.InternalIgnore.ContainsKey(col.Attribute.Name)) continue;
|
||||||
|
|
||||||
|
if (colidx > 0) sb.Append(", \r\n");
|
||||||
|
|
||||||
|
if (col.Attribute.IsVersion == true && col.Attribute.MapType != typeof(byte[]))
|
||||||
|
{
|
||||||
|
var field = _duckdbInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name);
|
||||||
|
sb.Append(field).Append(" = ").Append(_duckdbInsert.InternalCommonUtils.QuoteSqlName(_duckdbInsert.InternalTable.DbName)).Append(".").Append(field).Append(" + 1");
|
||||||
|
}
|
||||||
|
else if (_duckdbInsert.InternalIgnore.ContainsKey(col.Attribute.Name))
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(col.DbUpdateValue) == false)
|
||||||
|
{
|
||||||
|
sb.Append(_duckdbInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append(col.DbUpdateValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var caseWhen = _duckdbUpdate.InternalWhereCaseSource(col.CsName, sqlval => sqlval).Trim();
|
||||||
|
sb.Append(caseWhen);
|
||||||
|
if (caseWhen.EndsWith(" END")) _duckdbUpdate.InternalToSqlCaseWhenEnd(sb, col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var field = _duckdbInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name);
|
||||||
|
sb.Append(field).Append(" = EXCLUDED.").Append(field);
|
||||||
|
}
|
||||||
|
++colidx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long ExecuteAffrows()
|
||||||
|
{
|
||||||
|
var sql = this.ToSql();
|
||||||
|
if (string.IsNullOrEmpty(sql)) return 0;
|
||||||
|
|
||||||
|
var before = new CurdBeforeEventArgs(_duckdbInsert.InternalTable.Type, _duckdbInsert.InternalTable, CurdType.Insert, sql, _duckdbInsert.InternalParams);
|
||||||
|
_duckdbInsert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_duckdbInsert, before);
|
||||||
|
long ret = 0;
|
||||||
|
Exception exception = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ret = _duckdbInsert.InternalOrm.Ado.ExecuteNonQuery(_duckdbInsert.InternalConnection, _duckdbInsert.InternalTransaction, CommandType.Text, sql, _duckdbInsert._commandTimeout, _duckdbInsert.InternalParams);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
exception = ex;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
var after = new CurdAfterEventArgs(before, exception, ret);
|
||||||
|
_duckdbInsert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_duckdbInsert, after);
|
||||||
|
ClearData();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if net40
|
||||||
|
#else
|
||||||
|
async public Task<long> ExecuteAffrowsAsync(CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var sql = this.ToSql();
|
||||||
|
if (string.IsNullOrEmpty(sql)) return 0;
|
||||||
|
|
||||||
|
var before = new CurdBeforeEventArgs(_duckdbInsert.InternalTable.Type, _duckdbInsert.InternalTable, CurdType.Insert, sql, _duckdbInsert.InternalParams);
|
||||||
|
_duckdbInsert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_duckdbInsert, before);
|
||||||
|
long ret = 0;
|
||||||
|
Exception exception = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ret = await _duckdbInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_duckdbInsert.InternalConnection, _duckdbInsert.InternalTransaction, CommandType.Text, sql, _duckdbInsert._commandTimeout, _duckdbInsert.InternalParams, cancellationToken);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
exception = ex;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
var after = new CurdAfterEventArgs(before, exception, ret);
|
||||||
|
_duckdbInsert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_duckdbInsert, after);
|
||||||
|
ClearData();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
116
Providers/FreeSql.Provider.Duckdb/DuckdbAdo/DuckdbAdo.cs
Normal file
116
Providers/FreeSql.Provider.Duckdb/DuckdbAdo/DuckdbAdo.cs
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
using FreeSql.Internal;
|
||||||
|
using FreeSql.Internal.Model;
|
||||||
|
using FreeSql.Internal.ObjectPool;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Data.Common;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Linq;
|
||||||
|
using FreeSql.Internal.CommonProvider;
|
||||||
|
using DuckDB.NET.Data;
|
||||||
|
using static DuckDB.NET.Native.NativeMethods;
|
||||||
|
|
||||||
|
namespace FreeSql.Duckdb
|
||||||
|
{
|
||||||
|
class DuckdbAdo : FreeSql.Internal.CommonProvider.AdoProvider
|
||||||
|
{
|
||||||
|
public DuckdbAdo() : base(DataType.DuckDB, null, null) { }
|
||||||
|
public DuckdbAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func<DbConnection> connectionFactory) : base(DataType.DuckDB, masterConnectionString, slaveConnectionStrings)
|
||||||
|
{
|
||||||
|
base._util = util;
|
||||||
|
if (connectionFactory != null)
|
||||||
|
{
|
||||||
|
var pool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.DuckDB, connectionFactory);
|
||||||
|
ConnectionString = pool.TestConnection?.ConnectionString;
|
||||||
|
MasterPool = pool;
|
||||||
|
_CreateCommandConnection = pool.TestConnection;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var isAdoPool = masterConnectionString?.StartsWith("AdoConnectionPool,") ?? false;
|
||||||
|
if (isAdoPool) masterConnectionString = masterConnectionString.Substring("AdoConnectionPool,".Length);
|
||||||
|
if (!string.IsNullOrEmpty(masterConnectionString))
|
||||||
|
MasterPool = isAdoPool ?
|
||||||
|
new DbConnectionStringPool(base.DataType, CoreStrings.S_MasterDatabase, () => DuckdbConnectionPool.CreateConnection(masterConnectionString)) as IObjectPool<DbConnection> :
|
||||||
|
new DuckdbConnectionPool(CoreStrings.S_MasterDatabase, masterConnectionString, null, null);
|
||||||
|
|
||||||
|
slaveConnectionStrings?.ToList().ForEach(slaveConnectionString =>
|
||||||
|
{
|
||||||
|
var slavePool = isAdoPool ?
|
||||||
|
new DbConnectionStringPool(base.DataType, $"{CoreStrings.S_SlaveDatabase}{SlavePools.Count + 1}", () => DuckdbConnectionPool.CreateConnection(slaveConnectionString)) as IObjectPool<DbConnection> :
|
||||||
|
new DuckdbConnectionPool($"{CoreStrings.S_SlaveDatabase}{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables));
|
||||||
|
SlavePools.Add(slavePool);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn)
|
||||||
|
{
|
||||||
|
if (param == null) return "NULL";
|
||||||
|
if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false))
|
||||||
|
param = Utils.GetDataReaderValue(mapType, param);
|
||||||
|
|
||||||
|
if (param is bool || param is bool?)
|
||||||
|
return (bool)param ? "true" : "false";
|
||||||
|
else if (param is string)
|
||||||
|
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
|
||||||
|
else if (param is char)
|
||||||
|
return string.Concat("'", param.ToString().Replace("'", "''").Replace('\0', ' '), "'");
|
||||||
|
else if (param is Enum)
|
||||||
|
return AddslashesTypeHandler(param.GetType(), param) ?? ((Enum)param).ToInt64();
|
||||||
|
else if (decimal.TryParse(string.Concat(param), out var trydec))
|
||||||
|
return param;
|
||||||
|
|
||||||
|
else if (param is DateTime)
|
||||||
|
return AddslashesTypeHandler(typeof(DateTime), param) ?? string.Concat("timestamp '", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "'");
|
||||||
|
else if (param is DateTime?)
|
||||||
|
return AddslashesTypeHandler(typeof(DateTime?), param) ?? string.Concat("timestamp '", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "'");
|
||||||
|
|
||||||
|
#if net60
|
||||||
|
else if (param is DateOnly || param is DateOnly?)
|
||||||
|
return AddslashesTypeHandler(typeof(DateOnly), param) ?? string.Concat("date '", ((DateOnly)param).ToString("yyyy-MM-dd"), "'");
|
||||||
|
else if (param is TimeOnly || param is TimeOnly?)
|
||||||
|
{
|
||||||
|
var ts = (TimeOnly)param;
|
||||||
|
return $"'{ts.Hour}:{ts.Minute}:{ts.Second}.{ts.Millisecond}'";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
else if (param is TimeSpan || param is TimeSpan?)
|
||||||
|
{
|
||||||
|
var ts = (TimeSpan)param;
|
||||||
|
return $"time '{Math.Min(24, (int)Math.Floor(ts.TotalHours))}:{ts.Minutes}:{ts.Seconds}.{ts.Milliseconds}'";
|
||||||
|
}
|
||||||
|
else if (param is byte[])
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder().Append("'");
|
||||||
|
foreach (var vc in param as byte[]) sb.Append("\\x").Append(vc.ToString("X2"));
|
||||||
|
return sb.Append("'::blob").ToString();
|
||||||
|
}
|
||||||
|
else if (param is IEnumerable)
|
||||||
|
return AddslashesIEnumerable(param, mapType, mapColumn);
|
||||||
|
|
||||||
|
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
DbConnection _CreateCommandConnection;
|
||||||
|
public override DbCommand CreateCommand()
|
||||||
|
{
|
||||||
|
if (_CreateCommandConnection != null)
|
||||||
|
{
|
||||||
|
var cmd = _CreateCommandConnection.CreateCommand();
|
||||||
|
cmd.Connection = null;
|
||||||
|
return cmd;
|
||||||
|
}
|
||||||
|
return new DuckDBCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ReturnConnection(IObjectPool<DbConnection> pool, Object<DbConnection> conn, Exception ex)
|
||||||
|
{
|
||||||
|
var rawPool = pool as DuckdbConnectionPool;
|
||||||
|
if (rawPool != null) rawPool.Return(conn, ex);
|
||||||
|
else pool.Return(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,244 @@
|
|||||||
|
using DuckDB.NET.Data;
|
||||||
|
using FreeSql.Internal.ObjectPool;
|
||||||
|
using System;
|
||||||
|
using System.Data;
|
||||||
|
using System.Data.Common;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FreeSql.Duckdb
|
||||||
|
{
|
||||||
|
|
||||||
|
class DuckdbConnectionPool : ObjectPool<DbConnection>
|
||||||
|
{
|
||||||
|
|
||||||
|
internal Action availableHandler;
|
||||||
|
internal Action unavailableHandler;
|
||||||
|
|
||||||
|
public DuckdbConnectionPool(string name, string connectionString, Action availableHandler, Action unavailableHandler) : base(null)
|
||||||
|
{
|
||||||
|
this.availableHandler = availableHandler;
|
||||||
|
this.unavailableHandler = unavailableHandler;
|
||||||
|
policy = new DuckdbConnectionPoolPolicy
|
||||||
|
{
|
||||||
|
_pool = this,
|
||||||
|
Name = name
|
||||||
|
};
|
||||||
|
this.Policy = policy;
|
||||||
|
policy.ConnectionString = connectionString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Return(Object<DbConnection> obj, Exception exception, bool isRecreate = false)
|
||||||
|
{
|
||||||
|
base.Return(obj, isRecreate);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal DuckdbConnectionPoolPolicy policy;
|
||||||
|
|
||||||
|
public static DbConnection CreateConnection(string connectionString)
|
||||||
|
{
|
||||||
|
var conn = new DuckDBConnection(connectionString);
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DuckdbConnectionPoolPolicy : IPolicy<DbConnection>
|
||||||
|
{
|
||||||
|
|
||||||
|
internal DuckdbConnectionPool _pool;
|
||||||
|
public string Name { get; set; } = $"Duckdb DuckDBConnection {CoreStrings.S_ObjectPool}";
|
||||||
|
public int PoolSize { get; set; } = 1;
|
||||||
|
public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10);
|
||||||
|
public TimeSpan IdleTimeout { get; set; } = TimeSpan.Zero;
|
||||||
|
public int AsyncGetCapacity { get; set; } = 10000;
|
||||||
|
public bool IsThrowGetTimeoutException { get; set; } = true;
|
||||||
|
public bool IsAutoDisposeWithSystem { get; set; } = true;
|
||||||
|
public int CheckAvailableInterval { get; set; } = 2;
|
||||||
|
public int Weight { get; set; } = 1;
|
||||||
|
public string[] Attaches = new string[0];
|
||||||
|
|
||||||
|
private string _connectionString;
|
||||||
|
public string ConnectionString
|
||||||
|
{
|
||||||
|
get => _connectionString;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_connectionString = value ?? "";
|
||||||
|
|
||||||
|
PoolSize = 1;
|
||||||
|
var minPoolSize = 1;
|
||||||
|
|
||||||
|
if (Regex.IsMatch(_connectionString, @"ACCESS_MODE\s*=\s*READ_ONLY", RegexOptions.IgnoreCase))
|
||||||
|
{
|
||||||
|
//One process can both read and write to the database.
|
||||||
|
//Multiple processes can read from the database, but no processes can write (access_mode = 'READ_ONLY').
|
||||||
|
|
||||||
|
var pattern = @"Min\s*pool\s*size\s*=\s*(\d+)";
|
||||||
|
var m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
|
||||||
|
if (m.Success)
|
||||||
|
{
|
||||||
|
minPoolSize = int.Parse(m.Groups[1].Value);
|
||||||
|
_connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
pattern = @"Max\s*pool\s*size\s*=\s*(\d+)";
|
||||||
|
m = Regex.Match(_connectionString, pattern, RegexOptions.IgnoreCase);
|
||||||
|
if (m.Success)
|
||||||
|
{
|
||||||
|
PoolSize = int.Parse(m.Groups[1].Value);
|
||||||
|
_connectionString = Regex.Replace(_connectionString, pattern, "", RegexOptions.IgnoreCase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FreeSql.Internal.CommonUtils.PrevReheatConnectionPool(_pool, minPoolSize);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool OnCheckAvailable(Object<DbConnection> obj)
|
||||||
|
{
|
||||||
|
if (obj.Value == null) return false;
|
||||||
|
if (obj.Value.State == ConnectionState.Closed) obj.Value.OpenAndAttach(Attaches);
|
||||||
|
return obj.Value.Ping(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DbConnection OnCreate() => DuckdbConnectionPool.CreateConnection(_connectionString);
|
||||||
|
|
||||||
|
public void OnDestroy(DbConnection obj)
|
||||||
|
{
|
||||||
|
if (obj.State != ConnectionState.Closed) obj.Close();
|
||||||
|
obj.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnGet(Object<DbConnection> obj)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (_pool.IsAvailable)
|
||||||
|
{
|
||||||
|
if (obj.Value == null)
|
||||||
|
throw new Exception(CoreStrings.S_ConnectionStringError_CheckProjectConnection(this.Name));
|
||||||
|
|
||||||
|
if (obj.Value.State != ConnectionState.Open)
|
||||||
|
obj.Value.OpenAndAttach(Attaches);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if net40
|
||||||
|
#else
|
||||||
|
async public Task OnGetAsync(Object<DbConnection> obj)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (_pool.IsAvailable)
|
||||||
|
{
|
||||||
|
if (obj.Value == null)
|
||||||
|
throw new Exception(CoreStrings.S_ConnectionStringError_Check(this.Name));
|
||||||
|
|
||||||
|
if (obj.Value.State != ConnectionState.Open)
|
||||||
|
await obj.Value.OpenAndAttachAsync(Attaches);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public void OnGetTimeout()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnReturn(Object<DbConnection> obj)
|
||||||
|
{
|
||||||
|
//if (obj?.Value != null && obj.Value.State != ConnectionState.Closed) try { obj.Value.Close(); } catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnAvailable()
|
||||||
|
{
|
||||||
|
_pool.availableHandler?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnUnavailable()
|
||||||
|
{
|
||||||
|
_pool.unavailableHandler?.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static class DbConnectionExtensions
|
||||||
|
{
|
||||||
|
|
||||||
|
static DbCommand PingCommand(DbConnection conn)
|
||||||
|
{
|
||||||
|
var cmd = conn.CreateCommand();
|
||||||
|
cmd.CommandTimeout = 5;
|
||||||
|
cmd.CommandText = "select 1";
|
||||||
|
return cmd;
|
||||||
|
}
|
||||||
|
public static bool Ping(this DbConnection that, bool isThrow = false)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var cmd = PingCommand(that))
|
||||||
|
{
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
if (that.State != ConnectionState.Closed) try { that.Close(); } catch { }
|
||||||
|
if (isThrow) throw;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static void OpenAndAttach(this DbConnection that, string[] attach)
|
||||||
|
{
|
||||||
|
that.Open();
|
||||||
|
|
||||||
|
if (attach?.Any() == true)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
foreach (var att in attach)
|
||||||
|
sb.Append($"attach database [{att}] as [{att.Split('/', '\\').Last().Split('.').First()}];\r\n");
|
||||||
|
|
||||||
|
var cmd = that.CreateCommand();
|
||||||
|
cmd.CommandText = sb.ToString();
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
cmd.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if net40
|
||||||
|
#else
|
||||||
|
async public static Task<bool> PingAsync(this DbConnection that, bool isThrow = false)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var cmd = PingCommand(that))
|
||||||
|
{
|
||||||
|
await cmd.ExecuteNonQueryAsync();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
if (that.State != ConnectionState.Closed) try { that.Close(); } catch { }
|
||||||
|
if (isThrow) throw;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async public static Task OpenAndAttachAsync(this DbConnection that, string[] attach)
|
||||||
|
{
|
||||||
|
await that.OpenAsync();
|
||||||
|
|
||||||
|
if (attach?.Any() == true)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
foreach (var att in attach)
|
||||||
|
sb.Append($"attach database [{att}] as [{att.Split('/', '\\').Last().Split('.').First()}];\r\n");
|
||||||
|
|
||||||
|
var cmd = that.CreateCommand();
|
||||||
|
cmd.CommandText = sb.ToString();
|
||||||
|
await cmd.ExecuteNonQueryAsync();
|
||||||
|
cmd.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
216
Providers/FreeSql.Provider.Duckdb/DuckdbCodeFirst.cs
Normal file
216
Providers/FreeSql.Provider.Duckdb/DuckdbCodeFirst.cs
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
using FreeSql.Internal;
|
||||||
|
using FreeSql.Internal.Model;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using DuckDB.NET.Native;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace FreeSql.Duckdb
|
||||||
|
{
|
||||||
|
|
||||||
|
class DuckdbCodeFirst : Internal.CommonProvider.CodeFirstProvider
|
||||||
|
{
|
||||||
|
|
||||||
|
public override bool IsNoneCommandParameter { get => true; set => base.IsNoneCommandParameter = true; }
|
||||||
|
public DuckdbCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { }
|
||||||
|
|
||||||
|
static object _dicCsToDbLock = new object();
|
||||||
|
static Dictionary<string, CsToDb<DuckDBType>> _dicCsToDb = new Dictionary<string, CsToDb<DuckDBType>>() {
|
||||||
|
{ typeof(bool).FullName, CsToDb.New(DuckDBType.Boolean, "boolean","boolean NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(DuckDBType.Boolean, "boolean","boolean", null, true, null) },
|
||||||
|
|
||||||
|
{ typeof(sbyte).FullName, CsToDb.New(DuckDBType.TinyInt, "tinyint", "tinyint NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(DuckDBType.TinyInt, "tinyint", "tinyint", false, true, null) },
|
||||||
|
{ typeof(short).FullName, CsToDb.New(DuckDBType.SmallInt, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(DuckDBType.SmallInt, "smallint", "smallint", false, true, null) },
|
||||||
|
{ typeof(int).FullName, CsToDb.New(DuckDBType.Integer, "integer", "integer NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(DuckDBType.Integer, "integer", "integer", false, true, null) },
|
||||||
|
{ typeof(long).FullName, CsToDb.New(DuckDBType.BigInt, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(DuckDBType.BigInt, "bigint","bigint", false, true, null) },
|
||||||
|
|
||||||
|
{ typeof(byte).FullName, CsToDb.New(DuckDBType.UnsignedTinyInt, "utinyint","utinyint NOT NULL", true, false, 0) },{ typeof(byte?).FullName, CsToDb.New(DuckDBType.UnsignedTinyInt, "utinyint","utinyint", true, true, null) },
|
||||||
|
{ typeof(ushort).FullName, CsToDb.New(DuckDBType.UnsignedSmallInt, "usmallint","usmallint NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(DuckDBType.UnsignedSmallInt, "usmallint", "usmallint", true, true, null) },
|
||||||
|
{ typeof(uint).FullName, CsToDb.New(DuckDBType.UnsignedInteger, "uinteger", "uinteger NOT NULL", true, false, 0) },{ typeof(uint?).FullName, CsToDb.New(DuckDBType.UnsignedInteger, "uinteger", "uinteger", true, true, null) },
|
||||||
|
{ typeof(ulong).FullName, CsToDb.New(DuckDBType.UnsignedBigInt, "ubigint", "ubigint NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(DuckDBType.UnsignedBigInt, "ubigint", "ubigint", true, true, null) },
|
||||||
|
|
||||||
|
{ typeof(double).FullName, CsToDb.New(DuckDBType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(DuckDBType.Double, "double", "double", false, true, null) },
|
||||||
|
{ typeof(float).FullName, CsToDb.New(DuckDBType.Float, "float","float NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(DuckDBType.Float, "float","float", false, true, null) },
|
||||||
|
{ typeof(decimal).FullName, CsToDb.New(DuckDBType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(DuckDBType.Decimal, "decimal", "decimal(10,2)", false, true, null) },
|
||||||
|
|
||||||
|
{ typeof(TimeSpan).FullName, CsToDb.New(DuckDBType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(DuckDBType.Time, "time", "time",false, true, null) },
|
||||||
|
{ typeof(DateTime).FullName, CsToDb.New(DuckDBType.Timestamp, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(DuckDBType.Timestamp, "timestamp", "timestamp", false, true, null) },
|
||||||
|
|
||||||
|
#if net60
|
||||||
|
{ typeof(TimeOnly).FullName, CsToDb.New(DuckDBType.Time, "time", "time NOT NULL", false, false, 0) },{ typeof(TimeOnly?).FullName, CsToDb.New(DuckDBType.Time, "time", "time", false, true, null) },
|
||||||
|
{ typeof(DateOnly).FullName, CsToDb.New(DuckDBType.Date, "date", "date NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateOnly?).FullName, CsToDb.New(DuckDBType.Date, "date", "date", false, true, null) },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{ typeof(byte[]).FullName, CsToDb.New(DuckDBType.Blob, "blob", "blob", false, null, new byte[0]) },
|
||||||
|
{ typeof(string).FullName, CsToDb.New(DuckDBType.Varchar, "varchar", "varchar(255)", false, null, "") },
|
||||||
|
{ typeof(char).FullName, CsToDb.New(DuckDBType.Varchar, "char", "char(1)", false, null, '\0') },
|
||||||
|
|
||||||
|
{ typeof(Guid).FullName, CsToDb.New(DuckDBType.Uuid, "uuid", "uuid NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(DuckDBType.Uuid, "uuid", "uuid", false, true, null) },
|
||||||
|
|
||||||
|
{ typeof(BitArray).FullName, CsToDb.New(DuckDBType.Bit, "bit", "bit", false, null, new BitArray(new byte[64])) },
|
||||||
|
{ typeof(BigInteger).FullName, CsToDb.New(DuckDBType.HugeInt, "hugeint","hugeint NOT NULL", false, false, 0) },{ typeof(BigInteger?).FullName, CsToDb.New(DuckDBType.HugeInt, "hugeint","hugeint", false, true, null) },
|
||||||
|
};
|
||||||
|
|
||||||
|
public override DbInfoResult GetDbInfo(Type type)
|
||||||
|
{
|
||||||
|
var isarray = type.FullName != "System.Byte[]" && type.IsArray;
|
||||||
|
var elementType = isarray ? type.GetElementType() : type;
|
||||||
|
var info = GetDbInfoNoneArray(elementType);
|
||||||
|
if (info == null) return null;
|
||||||
|
if (isarray == false) return new DbInfoResult((int)info.type, info.dbtype, info.dbtypeFull, info.isnullable, info.defaultValue);
|
||||||
|
var dbtypefull = Regex.Replace(info.dbtypeFull, $@"{info.dbtype}(\s*\([^\)]+\))?", "$0[]").Replace(" NOT NULL", "");
|
||||||
|
return new DbInfoResult((int)(info.type | DuckDBType.Array), $"{info.dbtype}[]", dbtypefull, null, Array.CreateInstance(elementType, 0));
|
||||||
|
}
|
||||||
|
CsToDb<DuckDBType> GetDbInfoNoneArray(Type type)
|
||||||
|
{
|
||||||
|
if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return trydc;
|
||||||
|
if (type.IsArray) return null;
|
||||||
|
var enumType = type.IsEnum ? type : null;
|
||||||
|
if (enumType == null && type.IsNullableType() && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First();
|
||||||
|
if (enumType != null)
|
||||||
|
{
|
||||||
|
var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ?
|
||||||
|
CsToDb.New(DuckDBType.BigInt, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) :
|
||||||
|
CsToDb.New(DuckDBType.Integer, "integer", $"integer{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue());
|
||||||
|
if (_dicCsToDb.ContainsKey(type.FullName) == false)
|
||||||
|
{
|
||||||
|
lock (_dicCsToDbLock)
|
||||||
|
{
|
||||||
|
if (_dicCsToDb.ContainsKey(type.FullName) == false)
|
||||||
|
_dicCsToDb.Add(type.FullName, newItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newItem;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string GetComparisonDDLStatements(params TypeSchemaAndName[] objects)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
var seqcols = new List<NativeTuple<ColumnInfo, string[], bool>>(); //序列
|
||||||
|
foreach (var obj in objects)
|
||||||
|
{
|
||||||
|
if (sb.Length > 0) sb.Append("\r\n");
|
||||||
|
var tb = obj.tableSchema;
|
||||||
|
if (tb == null) throw new Exception(CoreStrings.S_Type_IsNot_Migrable(obj.tableSchema.Type.FullName));
|
||||||
|
if (tb.Columns.Any() == false) throw new Exception(CoreStrings.S_Type_IsNot_Migrable_0Attributes(obj.tableSchema.Type.FullName));
|
||||||
|
var tbname = _commonUtils.SplitTableName(tb.DbName);
|
||||||
|
if (tbname?.Length == 1) tbname = new[] { "main", tbname[0] };
|
||||||
|
|
||||||
|
var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名
|
||||||
|
if (tboldname?.Length == 1) tboldname = new[] { "main", tboldname[0] };
|
||||||
|
if (string.IsNullOrEmpty(obj.tableName) == false)
|
||||||
|
{
|
||||||
|
var tbtmpname = _commonUtils.SplitTableName(obj.tableName);
|
||||||
|
if (tbtmpname?.Length == 1) tbtmpname = new[] { "main", tbtmpname[0] };
|
||||||
|
if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1])
|
||||||
|
{
|
||||||
|
tbname = tbtmpname;
|
||||||
|
tboldname = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var sbalter = new StringBuilder();
|
||||||
|
if (_orm.Ado.ExecuteScalar(CommandType.Text, $" select 1 from {tbname[0]}.sqlite_master where type='table' and name='{tbname[1]}'") == null)
|
||||||
|
{ //表不存在
|
||||||
|
if (tboldname != null)
|
||||||
|
{
|
||||||
|
if (_orm.Ado.ExecuteScalar(CommandType.Text, $" select 1 from {tboldname[0]}.sqlite_master where type='table' and name='{tboldname[1]}'") == null)
|
||||||
|
//模式或表不存在
|
||||||
|
tboldname = null;
|
||||||
|
}
|
||||||
|
if (tboldname == null)
|
||||||
|
{
|
||||||
|
//创建表
|
||||||
|
var createTableName = _commonUtils.QuoteSqlName(tbname[0], tbname[1]);
|
||||||
|
sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( ");
|
||||||
|
foreach (var tbcol in tb.ColumnsByPosition)
|
||||||
|
{
|
||||||
|
sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType);
|
||||||
|
if (tbcol.Attribute.IsIdentity == true)
|
||||||
|
seqcols.Add(NativeTuple.Create(tbcol, tbname, true));
|
||||||
|
sb.Append(",");
|
||||||
|
}
|
||||||
|
if (tb.Primarys.Any())
|
||||||
|
{
|
||||||
|
sb.Append(" \r\n PRIMARY KEY (");
|
||||||
|
foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
|
||||||
|
sb.Remove(sb.Length - 2, 2).Append("),");
|
||||||
|
}
|
||||||
|
sb.Remove(sb.Length - 1, 1);
|
||||||
|
sb.Append("\r\n) \r\n;\r\n");
|
||||||
|
//创建表的索引
|
||||||
|
foreach (var uk in tb.Indexes)
|
||||||
|
{
|
||||||
|
sb.Append("CREATE ");
|
||||||
|
if (uk.IsUnique) sb.Append("UNIQUE ");
|
||||||
|
sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(tbname[0], ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(tbname[1]).Append("(");
|
||||||
|
foreach (var tbcol in uk.Columns)
|
||||||
|
{
|
||||||
|
sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name));
|
||||||
|
if (tbcol.IsDesc) sb.Append(" DESC");
|
||||||
|
sb.Append(", ");
|
||||||
|
}
|
||||||
|
sb.Remove(sb.Length - 2, 2).Append(");\r\n");
|
||||||
|
}
|
||||||
|
//创建表的索引
|
||||||
|
foreach (var uk in tb.Indexes)
|
||||||
|
{
|
||||||
|
sb.Append("CREATE ");
|
||||||
|
if (uk.IsUnique) sb.Append("UNIQUE ");
|
||||||
|
sb.Append("INDEX ");
|
||||||
|
sb.Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(createTableName);
|
||||||
|
sb.Append("(");
|
||||||
|
foreach (var tbcol in uk.Columns)
|
||||||
|
{
|
||||||
|
sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name));
|
||||||
|
if (tbcol.IsDesc) sb.Append(" DESC");
|
||||||
|
sb.Append(", ");
|
||||||
|
}
|
||||||
|
sb.Remove(sb.Length - 2, 2).Append(");\r\n");
|
||||||
|
}
|
||||||
|
//备注
|
||||||
|
foreach (var tbcol in tb.ColumnsByPosition)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(tbcol.Comment) == false)
|
||||||
|
sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n");
|
||||||
|
}
|
||||||
|
if (string.IsNullOrEmpty(tb.Comment) == false)
|
||||||
|
sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//如果新表,旧表在一个模式下,直接修改表名
|
||||||
|
if (string.Compare(tbname[0], tboldname[0], true) == 0)
|
||||||
|
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tboldname[0], tboldname[1])).Append(" RENAME TO \"").Append(tbname[1]).Append("\";\r\n");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//如果新表,旧表不在一起,创建新表,导入数据,删除旧表
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tboldname = null; //如果新表已经存在,不走改表名逻辑
|
||||||
|
}
|
||||||
|
foreach (var seqcol in seqcols)
|
||||||
|
{
|
||||||
|
var tbname = seqcol.Item2;
|
||||||
|
var seqname = Internal.Utils.GetCsName($"{tbname[0]}.{tbname[1]}_{seqcol.Item1.Attribute.Name}_sequence_name").ToLower();
|
||||||
|
var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}");
|
||||||
|
var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name);
|
||||||
|
sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT null;\r\n");
|
||||||
|
sb.Append("DROP SEQUENCE IF EXISTS ").Append(seqname).Append(";\r\n");
|
||||||
|
if (seqcol.Item3)
|
||||||
|
{
|
||||||
|
sb.Append("CREATE SEQUENCE ").Append(seqname).Append(";\r\n");
|
||||||
|
sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT nextval('").Append(seqname).Append("');\r\n");
|
||||||
|
//sb.Append(" SELECT case when max(").Append(colname2).Append(") is null then 0 else setval('").Append(seqname).Append("', max(").Append(colname2).Append(")) end FROM ").Append(tbname2).Append(";\r\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.Length == 0 ? null : sb.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
370
Providers/FreeSql.Provider.Duckdb/DuckdbDbFirst.cs
Normal file
370
Providers/FreeSql.Provider.Duckdb/DuckdbDbFirst.cs
Normal file
@ -0,0 +1,370 @@
|
|||||||
|
using DuckDB.NET.Native;
|
||||||
|
using FreeSql.DatabaseModel;
|
||||||
|
using FreeSql.Internal;
|
||||||
|
using FreeSql.Internal.Model;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace FreeSql.Duckdb
|
||||||
|
{
|
||||||
|
class DuckdbDbFirst : IDbFirst
|
||||||
|
{
|
||||||
|
IFreeSql _orm;
|
||||||
|
protected CommonUtils _commonUtils;
|
||||||
|
protected CommonExpression _commonExpression;
|
||||||
|
public DuckdbDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression)
|
||||||
|
{
|
||||||
|
_orm = orm;
|
||||||
|
_commonUtils = commonUtils;
|
||||||
|
_commonExpression = commonExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetDbType(DbColumnInfo column) => (int)GetSqlDbType(column);
|
||||||
|
DuckDBType GetSqlDbType(DbColumnInfo column)
|
||||||
|
{
|
||||||
|
var dbtype = column.DbTypeText ?? "";
|
||||||
|
var isarray = Regex.IsMatch(dbtype, @"\[\d*\]$") == true;
|
||||||
|
if (isarray) dbtype = dbtype.Remove(dbtype.Length - 2);
|
||||||
|
DuckDBType ret = DuckDBType.Invalid;
|
||||||
|
switch (dbtype.ToLower())
|
||||||
|
{
|
||||||
|
case "bigint":
|
||||||
|
case "int8":
|
||||||
|
case "long":
|
||||||
|
_dicDbToCs.TryAdd(dbtype, _dicDbToCs["bigint"]);
|
||||||
|
ret = DuckDBType.BigInt; break;
|
||||||
|
case "ubigint": ret = DuckDBType.UnsignedBigInt; break;
|
||||||
|
case "bit":
|
||||||
|
case "bitstring": ret = DuckDBType.Bit; break;
|
||||||
|
case "blob":
|
||||||
|
case "bytea":
|
||||||
|
case "binary":
|
||||||
|
case "varbinary":
|
||||||
|
_dicDbToCs.TryAdd(dbtype, _dicDbToCs["blob"]);
|
||||||
|
ret = DuckDBType.Blob; break;
|
||||||
|
case "boolean":
|
||||||
|
case "bool":
|
||||||
|
case "logical":
|
||||||
|
_dicDbToCs.TryAdd(dbtype, _dicDbToCs["boolean"]);
|
||||||
|
ret = DuckDBType.Boolean; break;
|
||||||
|
case "date":
|
||||||
|
_dicDbToCs.TryAdd(dbtype, _dicDbToCs["timestamp"]);
|
||||||
|
ret = DuckDBType.Date; break;
|
||||||
|
case "decimal":
|
||||||
|
case "numeric":
|
||||||
|
_dicDbToCs.TryAdd(dbtype, _dicDbToCs["decimal(10,2)"]);
|
||||||
|
ret = DuckDBType.Decimal; break;
|
||||||
|
case "double":
|
||||||
|
case "float8":
|
||||||
|
_dicDbToCs.TryAdd(dbtype, _dicDbToCs["double"]);
|
||||||
|
ret = DuckDBType.Double; break;
|
||||||
|
case "float":
|
||||||
|
case "float4":
|
||||||
|
case "real":
|
||||||
|
_dicDbToCs.TryAdd(dbtype, _dicDbToCs["float"]);
|
||||||
|
ret = DuckDBType.Float; break;
|
||||||
|
case "hugeint": ret = DuckDBType.HugeInt; break;
|
||||||
|
case "uhugeint":
|
||||||
|
_dicDbToCs.TryAdd(dbtype, _dicDbToCs["hugeint"]);
|
||||||
|
ret = DuckDBType.UnsignedHugeInt; break;
|
||||||
|
case "integer":
|
||||||
|
case "int4":
|
||||||
|
case "int":
|
||||||
|
case "signed":
|
||||||
|
_dicDbToCs.TryAdd(dbtype, _dicDbToCs["integer"]);
|
||||||
|
ret = DuckDBType.Integer; break;
|
||||||
|
case "uinteger": ret = DuckDBType.UnsignedInteger; break;
|
||||||
|
case "interval":
|
||||||
|
_dicDbToCs.TryAdd(dbtype, _dicDbToCs["time"]);
|
||||||
|
ret = DuckDBType.Interval; break;
|
||||||
|
case "smallint":
|
||||||
|
case "int2":
|
||||||
|
case "short":
|
||||||
|
_dicDbToCs.TryAdd(dbtype, _dicDbToCs["smallint"]);
|
||||||
|
ret = DuckDBType.SmallInt; break;
|
||||||
|
case "usmallint": ret = DuckDBType.UnsignedSmallInt; break;
|
||||||
|
case "time": ret = DuckDBType.Time; break;
|
||||||
|
case "timestamp with time zone":
|
||||||
|
case "timestamptz":
|
||||||
|
_dicDbToCs.TryAdd(dbtype, _dicDbToCs["timestamp"]);
|
||||||
|
ret = DuckDBType.TimestampTz; break;
|
||||||
|
case "timestamp":
|
||||||
|
case "datetime":
|
||||||
|
_dicDbToCs.TryAdd(dbtype, _dicDbToCs["timestamp"]);
|
||||||
|
ret = DuckDBType.Timestamp; break;
|
||||||
|
case "tinyint":
|
||||||
|
case "int1":
|
||||||
|
_dicDbToCs.TryAdd(dbtype, _dicDbToCs["tinyint"]);
|
||||||
|
ret = DuckDBType.TinyInt; break;
|
||||||
|
case "utinyint": ret = DuckDBType.UnsignedTinyInt; break;
|
||||||
|
case "uuid": ret = DuckDBType.Uuid; break;
|
||||||
|
case "varchar":
|
||||||
|
case "char":
|
||||||
|
case "bpchar":
|
||||||
|
case "text":
|
||||||
|
case "string":
|
||||||
|
_dicDbToCs.TryAdd(dbtype, _dicDbToCs["varchar(255)"]);
|
||||||
|
ret = DuckDBType.Varchar; break;
|
||||||
|
default:
|
||||||
|
if (dbtype.StartsWith("struct("))
|
||||||
|
ret = DuckDBType.Struct;
|
||||||
|
else if (dbtype.StartsWith("map("))
|
||||||
|
ret = DuckDBType.Map;
|
||||||
|
else if (dbtype.StartsWith("union("))
|
||||||
|
ret = DuckDBType.Union;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return isarray ? (ret | DuckDBType.Array) : ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ConcurrentDictionary<string, DbToCs> _dicDbToCs = new ConcurrentDictionary<string, DbToCs>(StringComparer.CurrentCultureIgnoreCase);
|
||||||
|
static DuckdbDbFirst()
|
||||||
|
{
|
||||||
|
var defaultDbToCs = new Dictionary<string, DbToCs>() {
|
||||||
|
{ "boolean", new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") },
|
||||||
|
|
||||||
|
{ "tinyint", new DbToCs("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetByte") },
|
||||||
|
{ "smallint", new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") },
|
||||||
|
{ "integer", new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") },
|
||||||
|
{ "bigint", new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") },
|
||||||
|
|
||||||
|
{ "utinyint", new DbToCs("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt16") },
|
||||||
|
{ "usmallint", new DbToCs("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt32") },
|
||||||
|
{ "uinteger", new DbToCs("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt64") },
|
||||||
|
{ "ubigint", new DbToCs("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetDecimal") },
|
||||||
|
|
||||||
|
{ "double", new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") },
|
||||||
|
{ "float", new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") },
|
||||||
|
{ "decimal(10,2)", new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") },
|
||||||
|
|
||||||
|
{ "time", new DbToCs("(TimeSpan?)", "TimeSpan.FromSeconds(long.Parse({0}))", "{0}.TotalSeconds.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") },
|
||||||
|
{ "timestamp", new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") },
|
||||||
|
|
||||||
|
{ "blob", new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") },
|
||||||
|
|
||||||
|
{ "varchar(255)", new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") },
|
||||||
|
{ "uuid", new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") },
|
||||||
|
|
||||||
|
{ "hugeint", new DbToCs("(BigInteger?)", "FreeSql.Internal.Utils.ToBigInteger({0})", "{0}.ToString()", "BigInteger?", typeof(BigInteger), typeof(BigInteger?), "{0}.Value", "GetValue") },
|
||||||
|
};
|
||||||
|
foreach (var kv in defaultDbToCs)
|
||||||
|
_dicDbToCs.TryAdd(kv.Key, kv.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null;
|
||||||
|
public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csParse : null;
|
||||||
|
public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csStringify : null;
|
||||||
|
public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null;
|
||||||
|
public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csTypeInfo : null;
|
||||||
|
public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csTypeValue : null;
|
||||||
|
public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.dataReaderMethod : null;
|
||||||
|
|
||||||
|
public List<string> GetDatabases()
|
||||||
|
{
|
||||||
|
return _orm.Ado.ExecuteArray("PRAGMA database_list").Select(a => string.Concat(a[1])).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ExistsTable(string name, bool ignoreCase)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(name)) return false;
|
||||||
|
var tbname = _commonUtils.SplitTableName(name);
|
||||||
|
if (tbname?.Length == 1) tbname = new[] { "main", tbname[0] };
|
||||||
|
if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray();
|
||||||
|
var sql = $@" select 1 from {_commonUtils.QuoteSqlName(tbname[0])}.sqlite_master where type='table' and {(ignoreCase ? "lower(tbl_name)" : "tbl_name")}={_commonUtils.FormatSql("{0}", tbname[1])}";
|
||||||
|
return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1";
|
||||||
|
}
|
||||||
|
|
||||||
|
public DbTableInfo GetTableByName(string name, bool ignoreCase = true) => GetTables(null, name, ignoreCase)?.FirstOrDefault();
|
||||||
|
public List<DbTableInfo> GetTablesByDatabase(params string[] database) => GetTables(database, null, false);
|
||||||
|
|
||||||
|
public List<DbTableInfo> GetTables(string[] database, string tablename, bool ignoreCase)
|
||||||
|
{
|
||||||
|
var loc1 = new List<DbTableInfo>();
|
||||||
|
var loc2 = new Dictionary<string, DbTableInfo>();
|
||||||
|
var loc3 = new Dictionary<string, Dictionary<string, DbColumnInfo>>();
|
||||||
|
string[] tbname = null;
|
||||||
|
if (string.IsNullOrEmpty(tablename) == false)
|
||||||
|
{
|
||||||
|
tbname = _commonUtils.SplitTableName(tablename);
|
||||||
|
if (tbname?.Length == 1) tbname = new[] { "main", tbname[0] };
|
||||||
|
if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray();
|
||||||
|
database = new[] { tbname[0] };
|
||||||
|
}
|
||||||
|
else if (database == null || database.Any() == false)
|
||||||
|
database = GetDatabases().ToArray();
|
||||||
|
if (database.Any() == false) return loc1;
|
||||||
|
|
||||||
|
Action<object[], int> addColumn = (row, position) =>
|
||||||
|
{
|
||||||
|
string table_id = string.Concat(row[0]);
|
||||||
|
string column = string.Concat(row[1]);
|
||||||
|
string type = string.Concat(row[2]);
|
||||||
|
//long max_length = long.Parse(string.Concat(row[3]));
|
||||||
|
string sqlType = string.Concat(row[4]);
|
||||||
|
var m_len = Regex.Match(sqlType, @"\w+\((\d+)");
|
||||||
|
int max_length = m_len.Success ? int.Parse(m_len.Groups[1].Value) : -1;
|
||||||
|
bool is_nullable = string.Concat(row[5]) == "1";
|
||||||
|
bool is_identity = string.Concat(row[6]) == "1";
|
||||||
|
bool is_primary = string.Concat(row[7]) == "1";
|
||||||
|
string comment = string.Concat(row[8]);
|
||||||
|
string defaultValue = string.Concat(row[9]);
|
||||||
|
if (max_length == 0) max_length = -1;
|
||||||
|
loc3[table_id].Add(column, new DbColumnInfo
|
||||||
|
{
|
||||||
|
Name = column,
|
||||||
|
MaxLength = max_length,
|
||||||
|
IsIdentity = is_identity,
|
||||||
|
IsNullable = is_nullable,
|
||||||
|
IsPrimary = is_primary,
|
||||||
|
DbTypeText = type,
|
||||||
|
DbTypeTextFull = sqlType,
|
||||||
|
Table = loc2[table_id],
|
||||||
|
Comment = comment,
|
||||||
|
DefaultValue = defaultValue,
|
||||||
|
Position = position
|
||||||
|
});
|
||||||
|
loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]);
|
||||||
|
loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]);
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var db in database)
|
||||||
|
{
|
||||||
|
var sql = $@"
|
||||||
|
select
|
||||||
|
'{db}.' || tbl_name,
|
||||||
|
'{db}',
|
||||||
|
tbl_name,
|
||||||
|
'',
|
||||||
|
'TABLE',
|
||||||
|
sql
|
||||||
|
from {db}.sqlite_master where type='table'{(tbname == null ? "" : $" and {(ignoreCase ? "lower(tbl_name)" : "tbl_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")}";
|
||||||
|
var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
|
||||||
|
if (ds == null) continue;
|
||||||
|
|
||||||
|
var loc6 = new List<string[]>();
|
||||||
|
var loc66 = new List<string[]>();
|
||||||
|
var loc6_1000 = new List<string>();
|
||||||
|
var loc66_1000 = new List<string>();
|
||||||
|
foreach (var row in ds)
|
||||||
|
{
|
||||||
|
var table_id = string.Concat(row[0]);
|
||||||
|
var schema = string.Concat(row[1]);
|
||||||
|
var table = string.Concat(row[2]);
|
||||||
|
var comment = string.Concat(row[3]);
|
||||||
|
var type = string.Concat(row[4]) == "VIEW" ? DbTableType.VIEW : DbTableType.TABLE;
|
||||||
|
if (database.Length == 1)
|
||||||
|
{
|
||||||
|
table_id = table_id.Substring(table_id.IndexOf('.') + 1);
|
||||||
|
schema = "";
|
||||||
|
}
|
||||||
|
loc2.Add(table_id, new DbTableInfo { Id = table_id, Schema = schema, Name = table, Comment = comment, Type = type });
|
||||||
|
loc3.Add(table_id, new Dictionary<string, DbColumnInfo>());
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case DbTableType.TABLE:
|
||||||
|
case DbTableType.VIEW:
|
||||||
|
loc6_1000.Add(table.Replace("'", "''"));
|
||||||
|
if (loc6_1000.Count >= 999)
|
||||||
|
{
|
||||||
|
loc6.Add(loc6_1000.ToArray());
|
||||||
|
loc6_1000.Clear();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DbTableType.StoreProcedure:
|
||||||
|
loc66_1000.Add(table.Replace("'", "''"));
|
||||||
|
if (loc66_1000.Count >= 999)
|
||||||
|
{
|
||||||
|
loc66.Add(loc66_1000.ToArray());
|
||||||
|
loc66_1000.Clear();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == DbTableType.TABLE && table != "sqlite_sequence")
|
||||||
|
{
|
||||||
|
var cols = _orm.Ado.ExecuteArray(CommandType.Text, $"PRAGMA table_info({_commonUtils.FormatSql("{0}", $"{db}.{table}")})");
|
||||||
|
var position = 0;
|
||||||
|
foreach (var col in cols)
|
||||||
|
{
|
||||||
|
var col_name = string.Concat(col[1]);
|
||||||
|
var is_identity = string.Concat(col[4]).StartsWith("nextval('");
|
||||||
|
|
||||||
|
var ds2item = new object[10];
|
||||||
|
ds2item[0] = table_id;
|
||||||
|
ds2item[1] = col_name;
|
||||||
|
ds2item[2] = Regex.Replace(string.Concat(col[2]), @"\(\d+(\b*,\b*\d+)?\)", "").ToUpper();
|
||||||
|
ds2item[4] = string.Concat(col[2]).ToUpper();
|
||||||
|
ds2item[5] = string.Concat(col[5]) == "False" && string.Concat(col[3]) == "False" ? 1 : 0;
|
||||||
|
ds2item[6] = is_identity ? 1 : 0;
|
||||||
|
ds2item[7] = string.Concat(col[5]) == "True" ? 1 : 0;
|
||||||
|
ds2item[8] = "";
|
||||||
|
ds2item[9] = string.Concat(col[4]);
|
||||||
|
addColumn(ds2item, ++position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray());
|
||||||
|
if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray());
|
||||||
|
|
||||||
|
if (loc6.Count == 0) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var table_id in loc3.Keys)
|
||||||
|
{
|
||||||
|
foreach (var loc5 in loc3[table_id].Values)
|
||||||
|
{
|
||||||
|
loc2[table_id].Columns.Add(loc5);
|
||||||
|
if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5);
|
||||||
|
if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var loc4 in loc2.Values)
|
||||||
|
{
|
||||||
|
//if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0)
|
||||||
|
//{
|
||||||
|
// foreach (var loc5 in loc4.UniquesDict.First().Value.Columns)
|
||||||
|
// {
|
||||||
|
// loc5.Column.IsPrimary = true;
|
||||||
|
// loc4.Primarys.Add(loc5.Column);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name));
|
||||||
|
loc4.Columns.Sort((c1, c2) =>
|
||||||
|
{
|
||||||
|
int compare = c2.IsPrimary.CompareTo(c1.IsPrimary);
|
||||||
|
if (compare == 0)
|
||||||
|
{
|
||||||
|
bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any();
|
||||||
|
bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any();
|
||||||
|
compare = b2.CompareTo(b1);
|
||||||
|
}
|
||||||
|
//if (compare == 0) compare = c1.Name.CompareTo(c2.Name);
|
||||||
|
return compare;
|
||||||
|
});
|
||||||
|
loc1.Add(loc4);
|
||||||
|
}
|
||||||
|
loc1.Sort((t1, t2) =>
|
||||||
|
{
|
||||||
|
var ret = t1.Schema.CompareTo(t2.Schema);
|
||||||
|
if (ret == 0) ret = t1.Name.CompareTo(t2.Name);
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
|
|
||||||
|
loc2.Clear();
|
||||||
|
loc3.Clear();
|
||||||
|
return loc1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DbEnumInfo> GetEnumsByDatabase(params string[] database)
|
||||||
|
{
|
||||||
|
return new List<DbEnumInfo>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
560
Providers/FreeSql.Provider.Duckdb/DuckdbExpression.cs
Normal file
560
Providers/FreeSql.Provider.Duckdb/DuckdbExpression.cs
Normal file
@ -0,0 +1,560 @@
|
|||||||
|
using FreeSql.Internal;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace FreeSql.Duckdb
|
||||||
|
{
|
||||||
|
class DuckdbExpression : CommonExpression
|
||||||
|
{
|
||||||
|
|
||||||
|
public DuckdbExpression(CommonUtils common) : base(common) { }
|
||||||
|
|
||||||
|
public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc)
|
||||||
|
{
|
||||||
|
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||||
|
switch (exp.NodeType)
|
||||||
|
{
|
||||||
|
case ExpressionType.ArrayLength:
|
||||||
|
var arrOper = (exp as UnaryExpression)?.Operand;
|
||||||
|
var arrOperExp = getExp(arrOper);
|
||||||
|
if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"len([{arrOperExp.TrimStart('(').TrimEnd(')')}])";
|
||||||
|
if (arrOper.Type == typeof(byte[])) return $"octet_length({getExp(arrOper)})";
|
||||||
|
return $"case when {arrOperExp} is null then 0 else len({arrOperExp}) end";
|
||||||
|
case ExpressionType.Convert:
|
||||||
|
var operandExp = (exp as UnaryExpression)?.Operand;
|
||||||
|
var gentype = exp.Type.NullableTypeOrThis();
|
||||||
|
if (gentype != operandExp.Type.NullableTypeOrThis())
|
||||||
|
{
|
||||||
|
switch (exp.Type.NullableTypeOrThis().ToString())
|
||||||
|
{
|
||||||
|
case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))";
|
||||||
|
case "System.Byte": return $"cast({getExp(operandExp)} as utinyint)";
|
||||||
|
case "System.Char": return $"substr(cast({getExp(operandExp)} as char), 1, 1)";
|
||||||
|
case "System.DateTime": return ExpressionConstDateTime(operandExp) ?? $"cast({getExp(operandExp)} as timestamp)";
|
||||||
|
case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(36,18))";
|
||||||
|
case "System.Double": return $"cast({getExp(operandExp)} as double)";
|
||||||
|
case "System.Int16": return $"cast({getExp(operandExp)} as smallint)";
|
||||||
|
case "System.Int32": return $"cast({getExp(operandExp)} as integer)";
|
||||||
|
case "System.Int64": return $"cast({getExp(operandExp)} as bigint)";
|
||||||
|
case "System.SByte": return $"cast({getExp(operandExp)} as tinyint)";
|
||||||
|
case "System.Single": return $"cast({getExp(operandExp)} as float)";
|
||||||
|
case "System.String": return $"cast({getExp(operandExp)} as text)";
|
||||||
|
case "System.UInt16": return $"cast({getExp(operandExp)} as usmallint)";
|
||||||
|
case "System.UInt32": return $"cast({getExp(operandExp)} as uinteger)";
|
||||||
|
case "System.UInt64": return $"cast({getExp(operandExp)} as ubigint)";
|
||||||
|
case "System.Guid": return $"cast({getExp(operandExp)} as uuid)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ExpressionType.Call:
|
||||||
|
var callExp = exp as MethodCallExpression;
|
||||||
|
|
||||||
|
switch (callExp.Method.Name)
|
||||||
|
{
|
||||||
|
case "Parse":
|
||||||
|
case "TryParse":
|
||||||
|
switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString())
|
||||||
|
{
|
||||||
|
case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))";
|
||||||
|
case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as utinyint)";
|
||||||
|
case "System.Char": return $"substr(cast({getExp(callExp.Arguments[0])} as char), 1, 1)";
|
||||||
|
case "System.DateTime": return ExpressionConstDateTime(callExp.Arguments[0]) ?? $"cast({getExp(callExp.Arguments[0])} as timestamp)";
|
||||||
|
case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(36,18))";
|
||||||
|
case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as double)";
|
||||||
|
case "System.Int16": return $"cast({getExp(callExp.Arguments[0])} as smallint)";
|
||||||
|
case "System.Int32": return $"cast({getExp(callExp.Arguments[0])} as integer)";
|
||||||
|
case "System.Int64": return $"cast({getExp(callExp.Arguments[0])} as bigint)";
|
||||||
|
case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as tinyint)";
|
||||||
|
case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as float)";
|
||||||
|
case "System.UInt16": return $"cast({getExp(callExp.Arguments[0])} as usmallint)";
|
||||||
|
case "System.UInt32": return $"cast({getExp(callExp.Arguments[0])} as uinteger)";
|
||||||
|
case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as ubigint)";
|
||||||
|
case "System.Guid": return $"cast({getExp(callExp.Arguments[0])} as uuid)";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
case "NewGuid":
|
||||||
|
return null;
|
||||||
|
case "Next":
|
||||||
|
if (callExp.Object?.Type == typeof(Random)) return "cast(random()*1000000000 as int)";
|
||||||
|
return null;
|
||||||
|
case "NextDouble":
|
||||||
|
if (callExp.Object?.Type == typeof(Random)) return "random()";
|
||||||
|
return null;
|
||||||
|
case "Random":
|
||||||
|
if (callExp.Method.DeclaringType.IsNumberType()) return "random()";
|
||||||
|
return null;
|
||||||
|
case "ToString":
|
||||||
|
if (callExp.Object != null)
|
||||||
|
{
|
||||||
|
if (callExp.Object.Type.NullableTypeOrThis().IsEnum)
|
||||||
|
{
|
||||||
|
tsc.SetMapColumnTmp(null);
|
||||||
|
var oldMapType = tsc.SetMapTypeReturnOld(typeof(string));
|
||||||
|
var enumStr = ExpressionLambdaToSql(callExp.Object, tsc);
|
||||||
|
tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType);
|
||||||
|
return enumStr;
|
||||||
|
}
|
||||||
|
var value = ExpressionGetValue(callExp.Object, out var success);
|
||||||
|
if (success) return formatSql(value, typeof(string), null, null);
|
||||||
|
return callExp.Arguments.Count == 0 ? $"({getExp(callExp.Object)})::text" : null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var objExp = callExp.Object;
|
||||||
|
var objType = objExp?.Type;
|
||||||
|
if (objType?.FullName == "System.Byte[]") return null;
|
||||||
|
|
||||||
|
var argIndex = 0;
|
||||||
|
if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable))
|
||||||
|
{
|
||||||
|
objExp = callExp.Arguments.FirstOrDefault();
|
||||||
|
objType = objExp?.Type;
|
||||||
|
argIndex++;
|
||||||
|
|
||||||
|
if (objType == typeof(string))
|
||||||
|
{
|
||||||
|
switch (callExp.Method.Name)
|
||||||
|
{
|
||||||
|
case "First":
|
||||||
|
case "FirstOrDefault":
|
||||||
|
return $"substring({getExp(callExp.Arguments[0])}, 1, 1)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (objType == null) objType = callExp.Method.DeclaringType;
|
||||||
|
if (objType != null || objType.IsArrayOrList())
|
||||||
|
{
|
||||||
|
string left = null;
|
||||||
|
switch (callExp.Method.Name)
|
||||||
|
{
|
||||||
|
case "Any":
|
||||||
|
left = objExp == null ? null : getExp(objExp);
|
||||||
|
if (left.StartsWith("(") || left.EndsWith(")")) left = $"[{left.TrimStart('(').TrimEnd(')')}]";
|
||||||
|
return $"(case when {left} is null then 0 else len({left}) end > 0)";
|
||||||
|
case "Contains":
|
||||||
|
tsc.SetMapColumnTmp(null);
|
||||||
|
var args1 = getExp(callExp.Arguments[argIndex]);
|
||||||
|
var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp);
|
||||||
|
var oldDbParams = objExp?.NodeType == ExpressionType.MemberAccess ? tsc.SetDbParamsReturnOld(null) : null; //#900 UseGenerateCommandParameterWithLambda(true) 子查询 bug、以及 #1173 参数化 bug
|
||||||
|
tsc.isNotSetMapColumnTmp = true;
|
||||||
|
left = objExp == null ? null : getExp(objExp);
|
||||||
|
tsc.isNotSetMapColumnTmp = false;
|
||||||
|
tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType);
|
||||||
|
if (oldDbParams != null) tsc.SetDbParamsReturnOld(oldDbParams);
|
||||||
|
//判断 in 或 array @> array
|
||||||
|
if (left.StartsWith("[") && left.EndsWith("]"))
|
||||||
|
return $"({args1}) in ({left.TrimStart('[').TrimEnd(']')})";
|
||||||
|
if (left.StartsWith("(") && left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格
|
||||||
|
return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})";
|
||||||
|
return $"list_contains({left}, {args1})";
|
||||||
|
case "Concat":
|
||||||
|
left = objExp == null ? null : getExp(objExp);
|
||||||
|
if (left.StartsWith("(") || left.EndsWith(")")) left = $"[{left.TrimStart('(').TrimEnd(')')}]";
|
||||||
|
var right2 = getExp(callExp.Arguments[argIndex]);
|
||||||
|
if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"[{right2.TrimStart('(').TrimEnd(')')}]";
|
||||||
|
return $"list_concat({left}, {right2})";
|
||||||
|
case "GetLength":
|
||||||
|
case "GetLongLength":
|
||||||
|
case "Length":
|
||||||
|
case "Count":
|
||||||
|
left = objExp == null ? null : getExp(objExp);
|
||||||
|
if (left.StartsWith("(") || left.EndsWith(")")) left = $"[{left.TrimStart('(').TrimEnd(')')}]";
|
||||||
|
return $"case when {left} is null then 0 else len({left}) end";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ExpressionType.MemberAccess:
|
||||||
|
var memExp = exp as MemberExpression;
|
||||||
|
var memParentExp = memExp.Expression?.Type;
|
||||||
|
if (memParentExp?.FullName == "System.Byte[]") return null;
|
||||||
|
if (memParentExp != null)
|
||||||
|
{
|
||||||
|
if (memParentExp.IsArrayOrList())
|
||||||
|
{
|
||||||
|
var left = getExp(memExp.Expression);
|
||||||
|
if (left.StartsWith("(") || left.EndsWith(")")) left = $"[{left.TrimStart('(').TrimEnd(')')}]";
|
||||||
|
switch (memExp.Member.Name)
|
||||||
|
{
|
||||||
|
case "Length":
|
||||||
|
case "Count": return $"case when {left} is null then 0 else len({left}) end";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ExpressionType.NewArrayInit:
|
||||||
|
var arrExp = exp as NewArrayExpression;
|
||||||
|
var arrSb = new StringBuilder();
|
||||||
|
arrSb.Append("[");
|
||||||
|
for (var a = 0; a < arrExp.Expressions.Count; a++)
|
||||||
|
{
|
||||||
|
if (a > 0) arrSb.Append(",");
|
||||||
|
arrSb.Append(getExp(arrExp.Expressions[a]));
|
||||||
|
}
|
||||||
|
if (arrSb.Length == 1) arrSb.Append("NULL");
|
||||||
|
return arrSb.Append("]").ToString();
|
||||||
|
case ExpressionType.ListInit:
|
||||||
|
var listExp = exp as ListInitExpression;
|
||||||
|
var listSb = new StringBuilder();
|
||||||
|
listSb.Append("(");
|
||||||
|
for (var a = 0; a < listExp.Initializers.Count; a++)
|
||||||
|
{
|
||||||
|
if (listExp.Initializers[a].Arguments.Any() == false) continue;
|
||||||
|
if (a > 0) listSb.Append(",");
|
||||||
|
listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault()));
|
||||||
|
}
|
||||||
|
if (listSb.Length == 1) listSb.Append("NULL");
|
||||||
|
return listSb.Append(")").ToString();
|
||||||
|
case ExpressionType.New:
|
||||||
|
var newExp = exp as NewExpression;
|
||||||
|
if (typeof(IList).IsAssignableFrom(newExp.Type))
|
||||||
|
{
|
||||||
|
if (newExp.Arguments.Count == 0) return "(NULL)";
|
||||||
|
if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)";
|
||||||
|
return getExp(newExp.Arguments[0]);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc)
|
||||||
|
{
|
||||||
|
if (exp.Expression == null)
|
||||||
|
{
|
||||||
|
switch (exp.Member.Name)
|
||||||
|
{
|
||||||
|
case "Empty": return "''";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var left = ExpressionLambdaToSql(exp.Expression, tsc);
|
||||||
|
switch (exp.Member.Name)
|
||||||
|
{
|
||||||
|
case "Length": return $"length({left})";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc)
|
||||||
|
{
|
||||||
|
if (exp.Expression == null)
|
||||||
|
{
|
||||||
|
switch (exp.Member.Name)
|
||||||
|
{
|
||||||
|
case "Now": return _common.Now;
|
||||||
|
case "UtcNow": return _common.NowUtc;
|
||||||
|
case "Today": return "current_date";
|
||||||
|
case "MinValue": return "timestamp '0001-01-01 00:00:00.000'";
|
||||||
|
case "MaxValue": return "timestamp '9999-12-31 23:59:59.999'";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var left = ExpressionLambdaToSql(exp.Expression, tsc);
|
||||||
|
switch (exp.Member.Name)
|
||||||
|
{
|
||||||
|
case "Date": return $"({left})::date";
|
||||||
|
case "TimeOfDay": return $"strftime({left},'%H:%M:%S')::time";
|
||||||
|
case "DayOfWeek": return $"dayofweek({left})";
|
||||||
|
case "Day": return $"day({left})";
|
||||||
|
case "DayOfYear": return $"dayofyear({left})";
|
||||||
|
case "Month": return $"month({left})";
|
||||||
|
case "Year": return $"year({left})";
|
||||||
|
case "Hour": return $"hour({left})";
|
||||||
|
case "Minute": return $"minute({left})";
|
||||||
|
case "Second": return $"second({left})";
|
||||||
|
case "Millisecond": return $"millisecond({left})";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc)
|
||||||
|
{
|
||||||
|
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||||
|
if (exp.Object == null)
|
||||||
|
{
|
||||||
|
switch (exp.Method.Name)
|
||||||
|
{
|
||||||
|
case "IsNullOrEmpty":
|
||||||
|
var arg1 = getExp(exp.Arguments[0]);
|
||||||
|
return $"({arg1} is null or {arg1} = '')";
|
||||||
|
case "IsNullOrWhiteSpace":
|
||||||
|
var arg2 = getExp(exp.Arguments[0]);
|
||||||
|
return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')";
|
||||||
|
case "Concat":
|
||||||
|
if (exp.Arguments.Count == 1 && exp.Arguments[0].NodeType == ExpressionType.NewArrayInit && exp.Arguments[0] is NewArrayExpression concatNewArrExp)
|
||||||
|
return _common.StringConcat(concatNewArrExp.Expressions.Select(a => getExp(a)).ToArray(), null);
|
||||||
|
return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null);
|
||||||
|
case "Format":
|
||||||
|
if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception(CoreStrings.Not_Implemented_Expression_ParameterUseConstant(exp, exp.Arguments[0]));
|
||||||
|
var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ?
|
||||||
|
(exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0);
|
||||||
|
//3个 {} 时,Arguments 解析出来是分开的
|
||||||
|
//4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray []
|
||||||
|
var expArgs = expArgsHack.Select(a =>
|
||||||
|
{
|
||||||
|
var atype = (a as UnaryExpression)?.Operand.Type.NullableTypeOrThis() ?? a.Type.NullableTypeOrThis();
|
||||||
|
if (atype == typeof(string)) return $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'";
|
||||||
|
return $"'||{_common.IsNull($"({ExpressionLambdaToSql(a, tsc)})::text", "''")}||'";
|
||||||
|
}).ToArray();
|
||||||
|
return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs);
|
||||||
|
case "Join":
|
||||||
|
if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1))
|
||||||
|
{
|
||||||
|
var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod,
|
||||||
|
Expression.Lambda(
|
||||||
|
Expression.Call(
|
||||||
|
typeof(SqlExtExtensions).GetMethod("StringJoinPgsqlGroupConcat"),
|
||||||
|
Expression.Convert(toListArgs1.Body, typeof(object)),
|
||||||
|
Expression.Convert(exp.Arguments[0], typeof(object))),
|
||||||
|
toListArgs1.Parameters));
|
||||||
|
var newToListSql = getExp(newToListArgs0);
|
||||||
|
return newToListSql;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var left = getExp(exp.Object);
|
||||||
|
switch (exp.Method.Name)
|
||||||
|
{
|
||||||
|
case "StartsWith":
|
||||||
|
case "EndsWith":
|
||||||
|
case "Contains":
|
||||||
|
var leftLike = exp.Object.NodeType == ExpressionType.MemberAccess ? left : $"({left})";
|
||||||
|
var args0Value = getExp(exp.Arguments[0]);
|
||||||
|
if (args0Value == "NULL") return $"{leftLike} IS NULL";
|
||||||
|
if (exp.Method.Name == "StartsWith") return $"{left} ^@ ({args0Value})";
|
||||||
|
if (args0Value.Contains("%"))
|
||||||
|
{
|
||||||
|
if (exp.Method.Name == "EndsWith") return $"strpos({left}, {args0Value}) = length({left})-length({args0Value})+1";
|
||||||
|
return $"strpos({left}, {args0Value}) > 0";
|
||||||
|
}
|
||||||
|
if (exp.Method.Name == "EndsWith") return $"{leftLike} LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::text)")}";
|
||||||
|
if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"{leftLike} LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}";
|
||||||
|
return $"{leftLike} LIKE ('%' || ({args0Value})::text || '%')";
|
||||||
|
case "ToLower": return $"lower({left})";
|
||||||
|
case "ToUpper": return $"upper({left})";
|
||||||
|
case "Substring":
|
||||||
|
var substrArgs1 = getExp(exp.Arguments[0]);
|
||||||
|
if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString();
|
||||||
|
else substrArgs1 += "+1";
|
||||||
|
if (exp.Arguments.Count == 1) return $"substring({left}, {substrArgs1})";
|
||||||
|
return $"substring({left}, {substrArgs1}, {getExp(exp.Arguments[1])})";
|
||||||
|
case "IndexOf":
|
||||||
|
var indexOfFindStr = getExp(exp.Arguments[0]);
|
||||||
|
//if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") {
|
||||||
|
// var locateArgs1 = getExp(exp.Arguments[1]);
|
||||||
|
// if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString();
|
||||||
|
// else locateArgs1 += "+1";
|
||||||
|
// return $"(instr({left}, {indexOfFindStr}, {locateArgs1})-1)";
|
||||||
|
//}
|
||||||
|
return $"(strpos({left}, {indexOfFindStr})-1)";
|
||||||
|
case "PadLeft":
|
||||||
|
if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])}, ' ')";
|
||||||
|
return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})";
|
||||||
|
case "PadRight":
|
||||||
|
if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])}, ' ')";
|
||||||
|
return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})";
|
||||||
|
case "Trim":
|
||||||
|
case "TrimStart":
|
||||||
|
case "TrimEnd":
|
||||||
|
if (exp.Arguments.Count == 0)
|
||||||
|
{
|
||||||
|
if (exp.Method.Name == "Trim") return $"trim({left})";
|
||||||
|
if (exp.Method.Name == "TrimStart") return $"ltrim({left})";
|
||||||
|
if (exp.Method.Name == "TrimEnd") return $"rtrim({left})";
|
||||||
|
}
|
||||||
|
var trimArg1 = "";
|
||||||
|
var trimArg2 = "";
|
||||||
|
foreach (var argsTrim02 in exp.Arguments)
|
||||||
|
{
|
||||||
|
var argsTrim01s = new[] { argsTrim02 };
|
||||||
|
if (argsTrim02.NodeType == ExpressionType.NewArrayInit)
|
||||||
|
{
|
||||||
|
var arritem = argsTrim02 as NewArrayExpression;
|
||||||
|
argsTrim01s = arritem.Expressions.ToArray();
|
||||||
|
}
|
||||||
|
foreach (var argsTrim01 in argsTrim01s)
|
||||||
|
{
|
||||||
|
var trimChr = getExp(argsTrim01).Trim('\'');
|
||||||
|
if (trimChr.Length == 1) trimArg1 += trimChr;
|
||||||
|
else trimArg2 += $" || ({trimChr})";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (exp.Method.Name == "Trim") left = $"trim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})";
|
||||||
|
if (exp.Method.Name == "TrimStart") left = $"ltrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})";
|
||||||
|
if (exp.Method.Name == "TrimEnd") left = $"rtrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})";
|
||||||
|
return left;
|
||||||
|
case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})";
|
||||||
|
case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end";
|
||||||
|
case "Equals": return $"({left} = {getExp(exp.Arguments[0])})";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc)
|
||||||
|
{
|
||||||
|
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||||
|
switch (exp.Method.Name)
|
||||||
|
{
|
||||||
|
case "Abs": return $"abs({getExp(exp.Arguments[0])})";
|
||||||
|
case "Sign": return $"sign({getExp(exp.Arguments[0])})";
|
||||||
|
case "Floor": return $"floor({getExp(exp.Arguments[0])})";
|
||||||
|
case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})";
|
||||||
|
case "Round":
|
||||||
|
if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})";
|
||||||
|
return $"round({getExp(exp.Arguments[0])}, 2)";
|
||||||
|
case "Exp": return $"exp({getExp(exp.Arguments[0])})";
|
||||||
|
case "Log": return $"log({getExp(exp.Arguments[0])})";
|
||||||
|
case "Log10": return $"log10({getExp(exp.Arguments[0])})";
|
||||||
|
case "Pow": return $"power({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})";
|
||||||
|
case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})";
|
||||||
|
case "Cos": return $"cos({getExp(exp.Arguments[0])})";
|
||||||
|
case "Sin": return $"sin({getExp(exp.Arguments[0])})";
|
||||||
|
case "Tan": return $"tan({getExp(exp.Arguments[0])})";
|
||||||
|
case "Acos": return $"acos({getExp(exp.Arguments[0])})";
|
||||||
|
case "Asin": return $"asin({getExp(exp.Arguments[0])})";
|
||||||
|
case "Atan": return $"atan({getExp(exp.Arguments[0])})";
|
||||||
|
case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})";
|
||||||
|
case "Truncate": return $"trunc({getExp(exp.Arguments[0])})";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc)
|
||||||
|
{
|
||||||
|
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||||
|
if (exp.Object == null)
|
||||||
|
{
|
||||||
|
switch (exp.Method.Name)
|
||||||
|
{
|
||||||
|
case "Compare": return $"(epoch({getExp(exp.Arguments[0])})-epoch({getExp(exp.Arguments[1])}))";
|
||||||
|
case "DaysInMonth": return $"day(last_day(cast({getExp(exp.Arguments[0])}||'-'||{getExp(exp.Arguments[1])}||'-01' as date)))";
|
||||||
|
case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})";
|
||||||
|
|
||||||
|
case "IsLeapYear":
|
||||||
|
var isLeapYearArgs1 = getExp(exp.Arguments[0]);
|
||||||
|
return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)";
|
||||||
|
|
||||||
|
case "Parse": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as timestamp)";
|
||||||
|
case "ParseExact":
|
||||||
|
case "TryParse":
|
||||||
|
case "TryParseExact": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as timestamp)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var left = getExp(exp.Object);
|
||||||
|
var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]);
|
||||||
|
switch (exp.Method.Name)
|
||||||
|
{
|
||||||
|
case "AddDays": return $"date_add({left},cast(({args1})||' days' as interval))";
|
||||||
|
case "AddHours": return $"date_add({left},cast(({args1})||' hours' as interval))";
|
||||||
|
case "AddMilliseconds": return $"date_add({left},cast(({args1})||' milliseconds' as interval))";
|
||||||
|
case "AddMinutes": return $"date_add({left},cast(({args1})||' minutes' as interval))";
|
||||||
|
case "AddMonths": return $"date_add({left},cast(({args1})||' months' as interval))";
|
||||||
|
case "AddSeconds": return $"date_add({left},cast(({args1})||' seconds' as interval))";
|
||||||
|
case "AddTicks": return $"date_add({left},cast((({args1})/10)||' microseconds' as interval))";
|
||||||
|
case "AddYears": return $"date_add({left},cast(({args1})||' years' as interval))";
|
||||||
|
case "Subtract":
|
||||||
|
switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName)
|
||||||
|
{
|
||||||
|
case "System.DateTime": return $"cast((epoch({left})-epoch({args1}))||' seconds' as interval)";
|
||||||
|
case "System.TimeSpan": return $"date_add({left},{args1})";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "Equals": return $"({left} = {args1})";
|
||||||
|
case "CompareTo": return $"(epoch({left})-epoch({args1}))";
|
||||||
|
case "ToString":
|
||||||
|
if (exp.Arguments.Count == 0) return $"strftime({left},'%Y-%m-%d %H:%M:%S')";
|
||||||
|
switch (args1)
|
||||||
|
{
|
||||||
|
case "'yyyy-MM-dd HH:mm:ss'": return $"strftime({left},'%Y-%m-%d %H:%M:%S')";
|
||||||
|
case "'yyyy-MM-dd HH:mm'": return $"strftime({left},'%Y-%m-%d %H:%M')";
|
||||||
|
case "'yyyy-MM-dd HH'": return $"strftime({left},'%Y-%m-%d %H')";
|
||||||
|
case "'yyyy-MM-dd'": return $"strftime({left},'%Y-%m-%d')";
|
||||||
|
case "'yyyy-MM'": return $"strftime({left},'%Y-%m')";
|
||||||
|
case "'yyyyMMddHHmmss'": return $"strftime({left},'%Y%m%d%H%M%S')";
|
||||||
|
case "'yyyyMMddHHmm'": return $"strftime({left},'%Y%m%d%H%M')";
|
||||||
|
case "'yyyyMMddHH'": return $"strftime({left},'%Y%m%d%H')";
|
||||||
|
case "'yyyyMMdd'": return $"strftime({left},'%Y%m%d')";
|
||||||
|
case "'yyyyMM'": return $"strftime({left},'%Y%m')";
|
||||||
|
case "'yyyy'": return $"strftime({left},'%Y')";
|
||||||
|
case "'HH:mm:ss'": return $"strftime({left},'%H:%M:%S')";
|
||||||
|
}
|
||||||
|
args1 = Regex.Replace(args1, "(yyyy|MM|dd|HH|mm|ss)", m =>
|
||||||
|
{
|
||||||
|
switch (m.Groups[1].Value)
|
||||||
|
{
|
||||||
|
case "yyyy": return $"%Y";
|
||||||
|
case "MM": return $"%_a1";
|
||||||
|
case "dd": return $"%_a2";
|
||||||
|
case "HH": return $"%_a3";
|
||||||
|
case "mm": return $"%_a4";
|
||||||
|
case "ss": return $"%S";
|
||||||
|
}
|
||||||
|
return m.Groups[0].Value;
|
||||||
|
});
|
||||||
|
var argsFinds = new[] { "%Y", "%_a1", "%_a2", "%_a3", "%_a4", "%S" };
|
||||||
|
var argsSpts = Regex.Split(args1, "(yy|M|d|H|hh|h|m|s|tt|t)");
|
||||||
|
for (var a = 0; a < argsSpts.Length; a++)
|
||||||
|
{
|
||||||
|
switch (argsSpts[a])
|
||||||
|
{
|
||||||
|
case "yy": argsSpts[a] = $"substr(strftime({left},'%Y'),3,2)"; break;
|
||||||
|
case "M": argsSpts[a] = $"strftime({left},'%-m')"; break;
|
||||||
|
case "d": argsSpts[a] = $"strftime({left},'%-d')"; break;
|
||||||
|
case "H": argsSpts[a] = $"strftime({left},'%-H')"; break;
|
||||||
|
case "hh": argsSpts[a] = $"strftime({left},'%I')"; break;
|
||||||
|
case "h": argsSpts[a] = $"strftime({left},'%-I')"; break;
|
||||||
|
case "m": argsSpts[a] = $"strftime({left},'%-M')"; break;
|
||||||
|
case "s": argsSpts[a] = $"strftime({left},'%-S')"; break;
|
||||||
|
case "tt": argsSpts[a] = $"strftime({left},'%p')"; break;
|
||||||
|
case "t": argsSpts[a] = $"substr(strftime({left},'%p'),1,1)"; break;
|
||||||
|
default:
|
||||||
|
var argsSptsA = argsSpts[a];
|
||||||
|
if (argsSptsA.StartsWith("'")) argsSptsA = argsSptsA.Substring(1);
|
||||||
|
if (argsSptsA.EndsWith("'")) argsSptsA = argsSptsA.Remove(argsSptsA.Length - 1);
|
||||||
|
argsSpts[a] = argsFinds.Any(m => argsSptsA.Contains(m)) ? $"strftime({left},'{argsSptsA}')" : $"'{argsSptsA}'";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (argsSpts.Length > 0) args1 = $"({string.Join(" || ", argsSpts.Where(a => a != "''"))})";
|
||||||
|
return args1.Replace("%_a1", "%m").Replace("%_a2", "%d").Replace("%_a3", "%H").Replace("%_a4", "%M");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc)
|
||||||
|
{
|
||||||
|
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
|
||||||
|
if (exp.Object == null)
|
||||||
|
{
|
||||||
|
switch (exp.Method.Name)
|
||||||
|
{
|
||||||
|
case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))";
|
||||||
|
case "ToByte": return $"cast({getExp(exp.Arguments[0])} as utinyint)";
|
||||||
|
case "ToChar": return $"substr(cast({getExp(exp.Arguments[0])} as char), 1, 1)";
|
||||||
|
case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as timestamp)";
|
||||||
|
case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as decimal(36,18))";
|
||||||
|
case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as double)";
|
||||||
|
case "ToInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)";
|
||||||
|
case "ToInt32": return $"cast({getExp(exp.Arguments[0])} as integer)";
|
||||||
|
case "ToInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)";
|
||||||
|
case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)";
|
||||||
|
case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as float)";
|
||||||
|
case "ToString": return $"cast({getExp(exp.Arguments[0])} as text)";
|
||||||
|
case "ToUInt16": return $"cast({getExp(exp.Arguments[0])} as usmallint)";
|
||||||
|
case "ToUInt32": return $"cast({getExp(exp.Arguments[0])} as uinteger)";
|
||||||
|
case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as ubigint)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
Providers/FreeSql.Provider.Duckdb/DuckdbExtensions.cs
Normal file
17
Providers/FreeSql.Provider.Duckdb/DuckdbExtensions.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using FreeSql;
|
||||||
|
using FreeSql.Duckdb.Curd;
|
||||||
|
|
||||||
|
public static partial class FreeSqlDuckdbGlobalExtensions
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="that"></param>
|
||||||
|
/// <param name="args"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string FormatDuckdb(this string that, params object[] args) => _duckdbAdo.Addslashes(that, args);
|
||||||
|
static FreeSql.Duckdb.DuckdbAdo _duckdbAdo = new FreeSql.Duckdb.DuckdbAdo();
|
||||||
|
}
|
54
Providers/FreeSql.Provider.Duckdb/DuckdbProvider.cs
Normal file
54
Providers/FreeSql.Provider.Duckdb/DuckdbProvider.cs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
using FreeSql.Internal;
|
||||||
|
using FreeSql.Internal.CommonProvider;
|
||||||
|
using FreeSql.Duckdb.Curd;
|
||||||
|
using System;
|
||||||
|
using System.Data.Common;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Numerics;
|
||||||
|
|
||||||
|
namespace FreeSql.Duckdb
|
||||||
|
{
|
||||||
|
|
||||||
|
public class DuckdbProvider<TMark> : BaseDbProvider, IFreeSql<TMark>
|
||||||
|
{
|
||||||
|
static int _firstInit = 1;
|
||||||
|
static void InitInternal()
|
||||||
|
{
|
||||||
|
if (Interlocked.Exchange(ref _firstInit, 0) == 1) //不能放在 static ctor .NetFramework 可能报初始化类型错误
|
||||||
|
{
|
||||||
|
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(BigInteger)] = true;
|
||||||
|
Utils.dicExecuteArrayRowReadClassOrTuple[typeof(BitArray)] = true;
|
||||||
|
Select0Provider._dicMethodDataReaderGetValue[typeof(Guid)] = typeof(DbDataReader).GetMethod("GetGuid", new Type[] { typeof(int) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ISelect<T1> CreateSelectProvider<T1>(object dywhere) => new DuckdbSelect<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);
|
||||||
|
public override IInsert<T1> CreateInsertProvider<T1>() => new DuckdbInsert<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression);
|
||||||
|
public override IUpdate<T1> CreateUpdateProvider<T1>(object dywhere) => new DuckdbUpdate<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);
|
||||||
|
public override IDelete<T1> CreateDeleteProvider<T1>(object dywhere) => new DuckdbDelete<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);
|
||||||
|
public override IInsertOrUpdate<T1> CreateInsertOrUpdateProvider<T1>() => new DuckdbInsertOrUpdate<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression);
|
||||||
|
|
||||||
|
public DuckdbProvider(string masterConnectionString, string[] slaveConnectionString, Func<DbConnection> connectionFactory = null)
|
||||||
|
{
|
||||||
|
InitInternal();
|
||||||
|
this.InternalCommonUtils = new DuckdbUtils(this);
|
||||||
|
this.InternalCommonExpression = new DuckdbExpression(this.InternalCommonUtils);
|
||||||
|
|
||||||
|
this.Ado = new DuckdbAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory);
|
||||||
|
this.Aop = new AopProvider();
|
||||||
|
|
||||||
|
this.CodeFirst = new DuckdbCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
|
||||||
|
this.DbFirst = new DuckdbDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
|
||||||
|
if (connectionFactory != null) this.CodeFirst.IsNoneCommandParameter = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
~DuckdbProvider() => this.Dispose();
|
||||||
|
int _disposeCounter;
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
if (Interlocked.Increment(ref _disposeCounter) != 1) return;
|
||||||
|
(this.Ado as AdoProvider)?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
242
Providers/FreeSql.Provider.Duckdb/DuckdbUtils.cs
Normal file
242
Providers/FreeSql.Provider.Duckdb/DuckdbUtils.cs
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
using DuckDB.NET.Data;
|
||||||
|
using FreeSql.Internal;
|
||||||
|
using FreeSql.Internal.Model;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Data.Common;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Numerics;
|
||||||
|
using static DuckDB.NET.Native.NativeMethods;
|
||||||
|
using System.Text;
|
||||||
|
using System.Security.AccessControl;
|
||||||
|
|
||||||
|
namespace FreeSql.Duckdb
|
||||||
|
{
|
||||||
|
|
||||||
|
class DuckdbUtils : CommonUtils
|
||||||
|
{
|
||||||
|
public DuckdbUtils(IFreeSql orm) : base(orm)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static Array getParamterArrayValue(Type arrayType, object value, object defaultValue)
|
||||||
|
{
|
||||||
|
var valueArr = value as Array;
|
||||||
|
var len = valueArr.GetLength(0);
|
||||||
|
var ret = Array.CreateInstance(arrayType, len);
|
||||||
|
for (var a = 0; a < len; a++)
|
||||||
|
{
|
||||||
|
var item = valueArr.GetValue(a);
|
||||||
|
ret.SetValue(item == null ? defaultValue : getParamterValue(item.GetType(), item, 1), a);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
static Dictionary<string, Func<object, object>> dicGetParamterValue = new Dictionary<string, Func<object, object>> {
|
||||||
|
{ typeof(uint).FullName, a => long.Parse(string.Concat(a)) }, { typeof(uint[]).FullName, a => getParamterArrayValue(typeof(long), a, 0) }, { typeof(uint?[]).FullName, a => getParamterArrayValue(typeof(long?), a, null) },
|
||||||
|
{ typeof(ulong).FullName, a => decimal.Parse(string.Concat(a)) }, { typeof(ulong[]).FullName, a => getParamterArrayValue(typeof(decimal), a, 0) }, { typeof(ulong?[]).FullName, a => getParamterArrayValue(typeof(decimal?), a, null) },
|
||||||
|
{ typeof(ushort).FullName, a => int.Parse(string.Concat(a)) }, { typeof(ushort[]).FullName, a => getParamterArrayValue(typeof(int), a, 0) }, { typeof(ushort?[]).FullName, a => getParamterArrayValue(typeof(int?), a, null) },
|
||||||
|
{ typeof(byte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(byte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(byte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) },
|
||||||
|
{ typeof(sbyte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(sbyte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(sbyte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) },
|
||||||
|
{ typeof(char).FullName, a => string.Concat(a).Replace('\0', ' ').ToCharArray().FirstOrDefault() },
|
||||||
|
{ typeof(BigInteger).FullName, a => BigInteger.Parse(string.Concat(a), System.Globalization.NumberStyles.Any) }, { typeof(BigInteger[]).FullName, a => getParamterArrayValue(typeof(BigInteger), a, 0) }, { typeof(BigInteger?[]).FullName, a => getParamterArrayValue(typeof(BigInteger?), a, null) },
|
||||||
|
};
|
||||||
|
static object getParamterValue(Type type, object value, int level = 0)
|
||||||
|
{
|
||||||
|
if (type.FullName == "System.Byte[]") return value;
|
||||||
|
if (type.FullName == "System.Char[]") return value;
|
||||||
|
if (type.IsArray && level == 0)
|
||||||
|
{
|
||||||
|
var elementType = type.GetElementType();
|
||||||
|
Type enumType = null;
|
||||||
|
if (elementType.IsEnum) enumType = elementType;
|
||||||
|
else if (elementType.IsNullableType() && elementType.GenericTypeArguments.First().IsEnum) enumType = elementType.GenericTypeArguments.First();
|
||||||
|
if (enumType != null) return enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ?
|
||||||
|
getParamterArrayValue(typeof(long), value, elementType.IsEnum ? null : enumType.CreateInstanceGetDefaultValue()) :
|
||||||
|
getParamterArrayValue(typeof(int), value, elementType.IsEnum ? null : enumType.CreateInstanceGetDefaultValue());
|
||||||
|
return dicGetParamterValue.TryGetValue(type.FullName, out var trydicarr) ? trydicarr(value) : value;
|
||||||
|
}
|
||||||
|
if (type.IsNullableType()) type = type.GenericTypeArguments.First();
|
||||||
|
if (type.IsEnum) return (int)value;
|
||||||
|
if (dicGetParamterValue.TryGetValue(type.FullName, out var trydic)) return trydic(value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, ColumnInfo col, Type type, object value)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}";
|
||||||
|
if (value != null) value = getParamterValue(type, value);
|
||||||
|
var ret = new DuckDBParameter { ParameterName = QuoteParamterName(parameterName), Value = value };
|
||||||
|
//var tp = _orm.CodeFirst.GetDbInfo(type)?.type;
|
||||||
|
//if (tp != null) ret.DbType = (DbType)tp.Value;
|
||||||
|
//if (col != null)
|
||||||
|
//{
|
||||||
|
// var dbtype = (DbType)_orm.DbFirst.GetDbType(new DatabaseModel.DbColumnInfo { DbTypeText = col.DbTypeText });
|
||||||
|
// if (dbtype != 0)
|
||||||
|
// {
|
||||||
|
// ret.DbType = dbtype;
|
||||||
|
// //if (col.DbSize != 0) ret.Size = col.DbSize;
|
||||||
|
// if (col.DbPrecision != 0) ret.Precision = col.DbPrecision;
|
||||||
|
// if (col.DbScale != 0) ret.Scale = col.DbScale;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
_params?.Add(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override DbParameter[] GetDbParamtersByObject(string sql, object obj) =>
|
||||||
|
Utils.GetDbParamtersByObject<DuckDBParameter>(sql, obj, "$", (name, type, value) =>
|
||||||
|
{
|
||||||
|
if (value != null) value = getParamterValue(type, value);
|
||||||
|
var ret = new DuckDBParameter { ParameterName = name, Value = value };
|
||||||
|
//if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) {
|
||||||
|
// ret.DataTypeName = "";
|
||||||
|
//} else {
|
||||||
|
//var tp = _orm.CodeFirst.GetDbInfo(type)?.type;
|
||||||
|
//if (tp != null) ret.DbType = (DbType)tp.Value; DuckDBParameter DbType 未对齐
|
||||||
|
//}
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
|
|
||||||
|
public override string FormatSql(string sql, params object[] args) => sql?.FormatDuckdb(args);
|
||||||
|
public override string QuoteSqlNameAdapter(params string[] name)
|
||||||
|
{
|
||||||
|
if (name.Length == 1)
|
||||||
|
{
|
||||||
|
var nametrim = name[0].Trim();
|
||||||
|
if (nametrim.StartsWith("(") && nametrim.EndsWith(")"))
|
||||||
|
return nametrim; //原生SQL
|
||||||
|
if (nametrim.StartsWith("\"") && nametrim.EndsWith("\""))
|
||||||
|
return nametrim;
|
||||||
|
return $"\"{nametrim.Replace(".", "\".\"")}\"";
|
||||||
|
}
|
||||||
|
return $"\"{string.Join("\".\"", name)}\"";
|
||||||
|
}
|
||||||
|
public override string TrimQuoteSqlName(string name)
|
||||||
|
{
|
||||||
|
var nametrim = name.Trim();
|
||||||
|
if (nametrim.StartsWith("(") && nametrim.EndsWith(")"))
|
||||||
|
return nametrim; //原生SQL
|
||||||
|
return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}";
|
||||||
|
}
|
||||||
|
public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2);
|
||||||
|
public override string QuoteParamterName(string name) => $"${name}";
|
||||||
|
public override string IsNull(string sql, object value) => $"coalesce({sql}, {value})";
|
||||||
|
public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}";
|
||||||
|
public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}";
|
||||||
|
public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}";
|
||||||
|
public override string Now => "current_timestamp";
|
||||||
|
public override string NowUtc => "current_timestamp";
|
||||||
|
|
||||||
|
public override string QuoteWriteParamterAdapter(Type type, string paramterName) => paramterName;
|
||||||
|
protected override string QuoteReadColumnAdapter(Type type, Type mapType, string columnName) => columnName;
|
||||||
|
|
||||||
|
public override string GetNoneParamaterSqlValue(List<DbParameter> specialParams, string specialParamFlag, ColumnInfo col, Type type, object value)
|
||||||
|
{
|
||||||
|
if (value == null) return "NULL";
|
||||||
|
if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value);
|
||||||
|
var type2 = type;
|
||||||
|
if (type2 == typeof(byte[])) return FormatSql("{0}", value, 1);
|
||||||
|
//array
|
||||||
|
if (value is Array)
|
||||||
|
{
|
||||||
|
var valueArr = value as Array;
|
||||||
|
var eleType = type2.GetElementType();
|
||||||
|
var eleTypeNullable = eleType.NullableTypeOrThis();
|
||||||
|
var len = valueArr.GetLength(0);
|
||||||
|
var sb = new StringBuilder().Append("[");
|
||||||
|
for (var a = 0; a < len; a++)
|
||||||
|
{
|
||||||
|
var item = valueArr.GetValue(a);
|
||||||
|
if (eleType != eleTypeNullable) item = Utils.GetDataReaderValue(eleTypeNullable, item);
|
||||||
|
if (a > 0) sb.Append(",");
|
||||||
|
sb.Append(GetNoneParamaterSqlValue(specialParams, specialParamFlag, col, eleType, item));
|
||||||
|
}
|
||||||
|
sb.Append("]");
|
||||||
|
//var dbinfo = _orm.CodeFirst.GetDbInfo(type);
|
||||||
|
//if (dbinfo != null) sb.Append("::").Append(dbinfo.dbtype);
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
if (type2.IsGenericType)
|
||||||
|
{
|
||||||
|
var typeDefinition = type2.GetGenericTypeDefinition();
|
||||||
|
//list
|
||||||
|
if (typeDefinition == typeof(List<>))
|
||||||
|
{
|
||||||
|
var valueArr = value as IList;
|
||||||
|
var eleType = type2.GenericTypeArguments.FirstOrDefault().NullableTypeOrThis();
|
||||||
|
var eleTypeNullable = eleType.NullableTypeOrThis();
|
||||||
|
var len = valueArr.Count;
|
||||||
|
var sb = new StringBuilder().Append("[");
|
||||||
|
for (var a = 0; a < len; a++)
|
||||||
|
{
|
||||||
|
var item = valueArr[a];
|
||||||
|
if (eleType != eleTypeNullable) item = Utils.GetDataReaderValue(eleTypeNullable, item);
|
||||||
|
if (a > 0) sb.Append(",");
|
||||||
|
sb.Append(GetNoneParamaterSqlValue(specialParams, specialParamFlag, col, eleType, item));
|
||||||
|
}
|
||||||
|
sb.Append("]");
|
||||||
|
//var dbinfo = _orm.CodeFirst.GetDbInfo(type);
|
||||||
|
//if (dbinfo != null) sb.Append("::").Append(dbinfo.dbtype);
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
//struct
|
||||||
|
if (typeDefinition == typeof(Dictionary<string, object>))
|
||||||
|
{
|
||||||
|
var dict = value as Dictionary<string, object>;
|
||||||
|
if (dict.Count == 0) return "NULL";
|
||||||
|
var sb = new StringBuilder("{");
|
||||||
|
var idx = 0;
|
||||||
|
foreach (var key in dict.Keys)
|
||||||
|
{
|
||||||
|
var val = dict[key];
|
||||||
|
if (val == null) continue;
|
||||||
|
if (idx > 0) sb.Append(",");
|
||||||
|
sb.Append("'").Append(FormatSql("{0}", val, 1)).Append("':");
|
||||||
|
sb.Append(GetNoneParamaterSqlValue(specialParams, specialParamFlag, col, val.GetType(), val));
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
return sb.Append("}").ToString();
|
||||||
|
}
|
||||||
|
//map
|
||||||
|
if (typeDefinition == typeof(Dictionary<,>))
|
||||||
|
{
|
||||||
|
var dict = value as IDictionary;
|
||||||
|
var sb = new StringBuilder("map([");
|
||||||
|
var idx = 0;
|
||||||
|
Type tkey = null;
|
||||||
|
foreach (var key in dict.Keys)
|
||||||
|
{
|
||||||
|
if (tkey == null) tkey = key.GetType();
|
||||||
|
if (idx > 0) sb.Append(",");
|
||||||
|
sb.Append(GetNoneParamaterSqlValue(specialParams, specialParamFlag, col, tkey, key));
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
sb.Append("],[");
|
||||||
|
idx = 0;
|
||||||
|
tkey = null;
|
||||||
|
foreach (var val in dict.Values)
|
||||||
|
{
|
||||||
|
if (val == null) continue;
|
||||||
|
if (tkey == null) tkey = val.GetType();
|
||||||
|
if (idx > 0) sb.Append(",");
|
||||||
|
sb.Append(GetNoneParamaterSqlValue(specialParams, specialParamFlag, col, tkey, val));
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
return sb.Append("])").ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (type2 == typeof(BitArray))
|
||||||
|
{
|
||||||
|
var ba = value as BitArray;
|
||||||
|
char[] ba1010 = new char[ba.Length];
|
||||||
|
for (int a = 0; a < ba.Length; a++) ba1010[a] = ba[a] ? '1' : '0';
|
||||||
|
return $"bit '{new string(ba1010)}'";
|
||||||
|
}
|
||||||
|
return FormatSql("{0}", value, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFrameworks>net8.0;net7.0;net6.0;netstandard2.0</TargetFrameworks>
|
||||||
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
|
<Authors>FreeSql;ncc;YeXiangQin</Authors>
|
||||||
|
<Description>FreeSql + DuckDB is a fast in-process analytical database,supports .NetCore、.NetFramework4.6.1+</Description>
|
||||||
|
<PackageProjectUrl>https://github.com/2881099/FreeSql</PackageProjectUrl>
|
||||||
|
<RepositoryUrl>https://github.com/2881099/FreeSql</RepositoryUrl>
|
||||||
|
<RepositoryType>git</RepositoryType>
|
||||||
|
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||||
|
<PackageTags>FreeSql;ORM;duckdb</PackageTags>
|
||||||
|
<PackageId>$(AssemblyName)</PackageId>
|
||||||
|
<PackageIcon>logo.png</PackageIcon>
|
||||||
|
<Title>$(AssemblyName)</Title>
|
||||||
|
<IsPackable>true</IsPackable>
|
||||||
|
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
||||||
|
<SignAssembly>true</SignAssembly>
|
||||||
|
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
|
||||||
|
<DelaySign>false</DelaySign>
|
||||||
|
<Version>3.5.100-preview20240725</Version>
|
||||||
|
<PackageReadmeFile>readme.md</PackageReadmeFile>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="../../readme.md" Pack="true" PackagePath="\"/>
|
||||||
|
<None Include="../../logo.png" Pack="true" PackagePath="\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="DuckDB.NET.Data.Full" Version="1.0.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\FreeSql\FreeSql.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(TargetFramework)' == 'net8.0' or '$(TargetFramework)' == 'net7.0' or '$(TargetFramework)' == 'net6.0'">
|
||||||
|
<DefineConstants>net60</DefineConstants>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
BIN
Providers/FreeSql.Provider.Duckdb/key.snk
Normal file
BIN
Providers/FreeSql.Provider.Duckdb/key.snk
Normal file
Binary file not shown.
@ -32,11 +32,6 @@ namespace FreeSql.Firebird
|
|||||||
|
|
||||||
public void Return(Object<DbConnection> obj, Exception exception, bool isRecreate = false)
|
public void Return(Object<DbConnection> obj, Exception exception, bool isRecreate = false)
|
||||||
{
|
{
|
||||||
if (exception != null && exception is FbException)
|
|
||||||
{
|
|
||||||
if (obj.Value.Ping() == false)
|
|
||||||
base.SetUnavailable(exception, obj.LastGetTimeCopy);
|
|
||||||
}
|
|
||||||
base.Return(obj, isRecreate);
|
base.Return(obj, isRecreate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,25 +115,10 @@ namespace FreeSql.Firebird
|
|||||||
if (_pool.IsAvailable)
|
if (_pool.IsAvailable)
|
||||||
{
|
{
|
||||||
if (obj.Value == null)
|
if (obj.Value == null)
|
||||||
{
|
|
||||||
_pool.SetUnavailable(new Exception(CoreStrings.S_ConnectionStringError), obj.LastGetTimeCopy);
|
|
||||||
throw new Exception(CoreStrings.S_ConnectionStringError_Check(this.Name));
|
throw new Exception(CoreStrings.S_ConnectionStringError_Check(this.Name));
|
||||||
}
|
|
||||||
|
|
||||||
if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false)
|
if (obj.Value.State != ConnectionState.Open)
|
||||||
{
|
obj.Value.Open();
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
obj.Value.Open();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
if (_pool.SetUnavailable(ex, obj.LastGetTimeCopy) == true)
|
|
||||||
throw new Exception($"【{this.Name}】Block access and wait for recovery: {ex.Message}");
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,25 +130,10 @@ namespace FreeSql.Firebird
|
|||||||
if (_pool.IsAvailable)
|
if (_pool.IsAvailable)
|
||||||
{
|
{
|
||||||
if (obj.Value == null)
|
if (obj.Value == null)
|
||||||
{
|
|
||||||
_pool.SetUnavailable(new Exception(CoreStrings.S_ConnectionStringError), obj.LastGetTimeCopy);
|
|
||||||
throw new Exception(CoreStrings.S_ConnectionStringError_Check(this.Name));
|
throw new Exception(CoreStrings.S_ConnectionStringError_Check(this.Name));
|
||||||
}
|
|
||||||
|
|
||||||
if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false)
|
if (obj.Value.State != ConnectionState.Open)
|
||||||
{
|
await obj.Value.OpenAsync();
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await obj.Value.OpenAsync();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
if (_pool.SetUnavailable(ex, obj.LastGetTimeCopy) == true)
|
|
||||||
throw new Exception($"【{this.Name}】Block access and wait for recovery: {ex.Message}");
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,11 +32,6 @@ namespace FreeSql.MsAccess
|
|||||||
|
|
||||||
public void Return(Object<DbConnection> obj, Exception exception, bool isRecreate = false)
|
public void Return(Object<DbConnection> obj, Exception exception, bool isRecreate = false)
|
||||||
{
|
{
|
||||||
if (exception != null && exception is OleDbException)
|
|
||||||
{
|
|
||||||
if (obj.Value.Ping() == false)
|
|
||||||
base.SetUnavailable(exception, obj.LastGetTimeCopy);
|
|
||||||
}
|
|
||||||
base.Return(obj, isRecreate);
|
base.Return(obj, isRecreate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,25 +114,10 @@ namespace FreeSql.MsAccess
|
|||||||
{
|
{
|
||||||
|
|
||||||
if (obj.Value == null)
|
if (obj.Value == null)
|
||||||
{
|
|
||||||
_pool.SetUnavailable(new Exception(CoreStrings.S_ConnectionStringError), obj.LastGetTimeCopy);
|
|
||||||
throw new Exception(CoreStrings.S_ConnectionStringError_Check(this.Name));
|
throw new Exception(CoreStrings.S_ConnectionStringError_Check(this.Name));
|
||||||
}
|
|
||||||
|
|
||||||
if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false)
|
if (obj.Value.State != ConnectionState.Open)
|
||||||
{
|
obj.Value.Open();
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
obj.Value.Open();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
if (_pool.SetUnavailable(ex, obj.LastGetTimeCopy) == true)
|
|
||||||
throw new Exception($"【{this.Name}】Block access and wait for recovery: {ex.Message}");
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,25 +130,10 @@ namespace FreeSql.MsAccess
|
|||||||
{
|
{
|
||||||
|
|
||||||
if (obj.Value == null)
|
if (obj.Value == null)
|
||||||
{
|
|
||||||
_pool.SetUnavailable(new Exception(CoreStrings.S_ConnectionStringError), obj.LastGetTimeCopy);
|
|
||||||
throw new Exception(CoreStrings.S_ConnectionStringError_Check(this.Name));
|
throw new Exception(CoreStrings.S_ConnectionStringError_Check(this.Name));
|
||||||
}
|
|
||||||
|
|
||||||
if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false)
|
if (obj.Value.State != ConnectionState.Open)
|
||||||
{
|
await obj.Value.OpenAsync();
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await obj.Value.OpenAsync();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
if (_pool.SetUnavailable(ex, obj.LastGetTimeCopy) == true)
|
|
||||||
throw new Exception($"【{this.Name}】Block access and wait for recovery: {ex.Message}");
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -36,15 +36,6 @@ namespace FreeSql.Sqlite
|
|||||||
|
|
||||||
public void Return(Object<DbConnection> obj, Exception exception, bool isRecreate = false)
|
public void Return(Object<DbConnection> obj, Exception exception, bool isRecreate = false)
|
||||||
{
|
{
|
||||||
#if MicrosoftData
|
|
||||||
if (exception != null && exception is SqliteException)
|
|
||||||
#else
|
|
||||||
if (exception != null && exception is SQLiteException)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
if (obj.Value.Ping() == false)
|
|
||||||
base.SetUnavailable(exception, obj.LastGetTimeCopy);
|
|
||||||
}
|
|
||||||
base.Return(obj, isRecreate);
|
base.Return(obj, isRecreate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,25 +155,10 @@ namespace FreeSql.Sqlite
|
|||||||
if (_pool.IsAvailable)
|
if (_pool.IsAvailable)
|
||||||
{
|
{
|
||||||
if (obj.Value == null)
|
if (obj.Value == null)
|
||||||
{
|
|
||||||
_pool.SetUnavailable(new Exception(CoreStrings.S_ConnectionStringError_CheckProject), obj.LastGetTimeCopy);
|
|
||||||
throw new Exception(CoreStrings.S_ConnectionStringError_CheckProjectConnection(this.Name));
|
throw new Exception(CoreStrings.S_ConnectionStringError_CheckProjectConnection(this.Name));
|
||||||
}
|
|
||||||
|
|
||||||
if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && obj.Value.Ping() == false)
|
if (obj.Value.State != ConnectionState.Open)
|
||||||
{
|
obj.Value.OpenAndAttach(Attaches);
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
obj.Value.OpenAndAttach(Attaches);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
if (_pool.SetUnavailable(ex, obj.LastGetTimeCopy) == true)
|
|
||||||
throw new Exception($"【{this.Name}】Block access and wait for recovery: {ex.Message}");
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,25 +170,10 @@ namespace FreeSql.Sqlite
|
|||||||
if (_pool.IsAvailable)
|
if (_pool.IsAvailable)
|
||||||
{
|
{
|
||||||
if (obj.Value == null)
|
if (obj.Value == null)
|
||||||
{
|
|
||||||
_pool.SetUnavailable(new Exception(CoreStrings.S_ConnectionStringError), obj.LastGetTimeCopy);
|
|
||||||
throw new Exception(CoreStrings.S_ConnectionStringError_Check(this.Name));
|
throw new Exception(CoreStrings.S_ConnectionStringError_Check(this.Name));
|
||||||
}
|
|
||||||
|
|
||||||
if (obj.Value.State != ConnectionState.Open || DateTime.Now.Subtract(obj.LastReturnTime).TotalSeconds > 60 && (await obj.Value.PingAsync()) == false)
|
if (obj.Value.State != ConnectionState.Open)
|
||||||
{
|
await obj.Value.OpenAndAttachAsync(Attaches);
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await obj.Value.OpenAndAttachAsync(Attaches);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
if (_pool.SetUnavailable(ex, obj.LastGetTimeCopy) == true)
|
|
||||||
throw new Exception($"【{this.Name}】Block access and wait for recovery: {ex.Message}");
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -217,7 +217,7 @@ namespace FreeSql.Sqlite
|
|||||||
switch (exp.Member.Name)
|
switch (exp.Member.Name)
|
||||||
{
|
{
|
||||||
case "Date": return $"date({left})";
|
case "Date": return $"date({left})";
|
||||||
case "TimeOfDay": return $"strftime('%H:%M:%f',{left})";
|
case "TimeOfDay": return $"strftime('%H:%M:%S',{left})";
|
||||||
case "DayOfWeek": return $"CAST(strftime('%w',{left}) AS INTEGER) ";
|
case "DayOfWeek": return $"CAST(strftime('%w',{left}) AS INTEGER) ";
|
||||||
case "Day": return $"CAST(strftime('%d',{left}) AS INTEGER) ";
|
case "Day": return $"CAST(strftime('%d',{left}) AS INTEGER) ";
|
||||||
case "DayOfYear": return $"CAST(strftime('%j',{left}) AS INTEGER) ";
|
case "DayOfYear": return $"CAST(strftime('%j',{left}) AS INTEGER) ";
|
||||||
@ -441,7 +441,7 @@ namespace FreeSql.Sqlite
|
|||||||
case "Equals": return $"({left} = {args1})";
|
case "Equals": return $"({left} = {args1})";
|
||||||
case "CompareTo": return $"(strftime('%s',{left})-strftime('%s',{args1}))";
|
case "CompareTo": return $"(strftime('%s',{left})-strftime('%s',{args1}))";
|
||||||
case "ToString":
|
case "ToString":
|
||||||
if (exp.Arguments.Count == 0) return $"strftime('%Y-%m-%d %H:%M:%f',{left})";
|
if (exp.Arguments.Count == 0) return $"strftime('%Y-%m-%d %H:%M:%S',{left})";
|
||||||
switch (args1)
|
switch (args1)
|
||||||
{
|
{
|
||||||
case "'yyyy-MM-dd HH:mm:ss'": return $"strftime('%Y-%m-%d %H:%M:%S',{left})";
|
case "'yyyy-MM-dd HH:mm:ss'": return $"strftime('%Y-%m-%d %H:%M:%S',{left})";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user