diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdUpdateTest.cs index 0cb43def..84f02ff4 100644 --- a/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdUpdateTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/Curd/FirebirdUpdateTest.cs @@ -20,6 +20,17 @@ namespace FreeSql.Tests.Firebird public string Title { get; set; } public DateTime CreateTime { get; set; } } + [Table(Name = "tb_topic_setsource")] + class Topic22 + { + [Column(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; } + } [Fact] public void Dywhere() @@ -64,6 +75,28 @@ namespace FreeSql.Tests.Firebird public string xx { get; set; } } [Fact] + public void SetSourceNoIdentity() + { + var fsql = g.firebird; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var sql = fsql.Update().SetSource(new Topic22 { Id = 1, Title = "newtitle" }).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_SETSOURCE\" SET \"CLICKS\" = @p_0, \"TITLE\" = @p_1, \"CREATETIME\" = @p_2 WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic22 { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + Assert.Equal(10, fsql.Insert(items).ExecuteAffrows()); + items[0].Clicks = null; + + sql = fsql.Update().SetSource(items).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_SETSOURCE\" SET \"CLICKS\" = CASE \"ID\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END, \"TITLE\" = CASE \"ID\" WHEN 1 THEN @p_10 WHEN 2 THEN @p_11 WHEN 3 THEN @p_12 WHEN 4 THEN @p_13 WHEN 5 THEN @p_14 WHEN 6 THEN @p_15 WHEN 7 THEN @p_16 WHEN 8 THEN @p_17 WHEN 9 THEN @p_18 WHEN 10 THEN @p_19 END, \"CREATETIME\" = CASE \"ID\" WHEN 1 THEN @p_20 WHEN 2 THEN @p_21 WHEN 3 THEN @p_22 WHEN 4 THEN @p_23 WHEN 5 THEN @p_24 WHEN 6 THEN @p_25 WHEN 7 THEN @p_26 WHEN 8 THEN @p_27 WHEN 9 THEN @p_28 WHEN 10 THEN @p_29 END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = fsql.Update().SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_SETSOURCE\" SET \"TITLE\" = CASE \"ID\" WHEN 1 THEN @p_0 WHEN 2 THEN @p_1 WHEN 3 THEN @p_2 WHEN 4 THEN @p_3 WHEN 5 THEN @p_4 WHEN 6 THEN @p_5 WHEN 7 THEN @p_6 WHEN 8 THEN @p_7 WHEN 9 THEN @p_8 WHEN 10 THEN @p_9 END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = fsql.Update().SetSource(items).IgnoreColumns(a => a.TypeGuid).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_SETSOURCE\" SET \"CREATETIME\" = @p_0 WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] public void SetSourceIgnore() { Assert.Equal("UPDATE \"TSSI01\" SET \"TINT\" = 10 WHERE (\"ID\" = '00000000-0000-0000-0000-000000000000')", @@ -82,6 +115,20 @@ namespace FreeSql.Tests.Firebird { var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); + + sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new object[] { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); + + sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new[] { "Clicks", "CreateTime" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); + + var cols = new[] { "Clicks", "CreateTime" }; + sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => cols).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); + + cols = new[] { "Clicks", "CreateTime" }; + sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(cols).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"TITLE\" = @p_0 WHERE (\"ID\" = 1)", sql); } [Fact] public void UpdateColumns() @@ -123,6 +170,9 @@ namespace FreeSql.Tests.Firebird sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = NULL WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC_INSERT\" SET \"CLICKS\" = NULL WHERE (\"ID\" = 1)", sql); } [Fact] public void SetRaw() diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/DateTimeTest.cs index 57f8512e..4dc4735c 100644 --- a/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/DateTimeTest.cs @@ -41,6 +41,42 @@ namespace FreeSql.Tests.FirebirdExpression public List Types { get; set; } public DateTime Time2 { get; set; } } + + [Fact] + public void this_ToString() + { + var data = new List(); + 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()); + + g.firebird.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() { @@ -301,25 +337,6 @@ namespace FreeSql.Tests.FirebirdExpression //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) } [Fact] - public void Ticks() - { - var data = new List(); - data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); - data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); - //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 - //FROM `tb_topic111333` a - //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); - - //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, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); - - //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, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) - } - [Fact] public void Add() { var data = new List(); @@ -494,40 +511,9 @@ namespace FreeSql.Tests.FirebirdExpression public void Subtract() { var data = new List(); - data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) - - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) - - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" - //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) - data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" - //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalMinutes > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalMinutes > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalMinutes > 0).ToList()); } [Fact] public void 两个日期相减_效果同Subtract() @@ -536,37 +522,6 @@ namespace FreeSql.Tests.FirebirdExpression data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) - - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) - - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" - //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) - data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" - //FROM "TB_TOPIC111333" a - //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") - //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" - - //FROM "TB_TOPIC111333" a - //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" - //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" - //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") } [Fact] public void this_Equals() @@ -587,25 +542,6 @@ namespace FreeSql.Tests.FirebirdExpression //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_ToString() - { - var data = new List(); - 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())) - } [Fact] public void DateTime_Compare() diff --git a/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/StringTest.cs index a58e6eb1..b3dceb92 100644 --- a/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Firebird/FirebirdExpression/StringTest.cs @@ -50,6 +50,96 @@ namespace FreeSql.Tests.FirebirdExpression list.Add(g.firebird.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.sqlite; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "北京" }, new StringJoin01 { name = "上海" }, new StringJoin01 { name = "深圳" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + } + 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 = g.firebird.GetRepository().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), '')||'z-'||coalesce(lpad(extract(year from cast(a.""CREATETIME"" as timestamp)),4,'0')||lpad(extract(month from cast(a.""CREATETIME"" as timestamp)),2,'0'), '')||''||coalesce(a.""TITLE"", '')||'' as1, ''||coalesce((a.""ID"" + 1), '')||'x'||coalesce((a.""ID"" + 1), '')||'z-'||coalesce(lpad(extract(year from cast(a.""CREATETIME"" as timestamp)),4,'0')||lpad(extract(month from cast(a.""CREATETIME"" as timestamp)),2,'0'), '')||''||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 = g.firebird.GetRepository().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), '')||'z-'||coalesce(lpad(extract(year from cast(a.""CREATETIME"" as timestamp)),4,'0')||lpad(extract(month from cast(a.""CREATETIME"" as timestamp)),2,'0'), '')||''||coalesce(a.""TITLE"", '')||''||coalesce(a.""TITLE"", '')||'' as1, ''||coalesce((a.""ID"" + 1), '')||'x'||coalesce((a.""ID"" + 1), '')||'z-'||coalesce(lpad(extract(year from cast(a.""CREATETIME"" as timestamp)),4,'0')||lpad(extract(month from cast(a.""CREATETIME"" as timestamp)),2,'0'), '')||''||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() @@ -58,7 +148,7 @@ namespace FreeSql.Tests.FirebirdExpression 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`, '') = '') + //WHERE (coalesce(a.`Title`, '') = '') } [Fact] diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs index 0ca17964..c0c76b6a 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/DateTimeTest.cs @@ -49,17 +49,6 @@ namespace FreeSql.Tests.SqliteExpression 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())) g.sqlite.Insert(new Topic()).ExecuteAffrows(); var dtn = DateTime.Parse("2020-1-1 0:0:0"); diff --git a/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs b/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs index 02e20989..203022c4 100644 --- a/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs +++ b/Providers/FreeSql.Provider.Firebird/FirebirdExpression.cs @@ -1,11 +1,10 @@ 锘縰sing FreeSql.Internal; -using FreeSql.Internal.Model; 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.Firebird { @@ -41,7 +40,7 @@ namespace FreeSql.Firebird case "System.UInt16": return $"cast({getExp(operandExp)} as integer)"; case "System.UInt32": return $"cast({getExp(operandExp)} as bigint)"; case "System.UInt64": return $"cast({getExp(operandExp)} as decimal(21,0))"; - case "System.Guid": return $"substring(cast({getExp(operandExp)} as char) from 1 for 36)"; + case "System.Guid": return $"substring(cast({getExp(operandExp)} as char(36)) from 1 for 36)"; } } break; @@ -69,7 +68,7 @@ namespace FreeSql.Firebird case "System.UInt16": return $"cast({getExp(callExp.Arguments[0])} as integer)"; case "System.UInt32": return $"cast({getExp(callExp.Arguments[0])} as bigint)"; case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as decimal(18,0))"; - case "System.Guid": return $"substring(cast({getExp(callExp.Arguments[0])} as char) from 1 for 36)"; + case "System.Guid": return $"substring(cast({getExp(callExp.Arguments[0])} as char(36)) from 1 for 36)"; } return null; case "NewGuid": @@ -84,7 +83,7 @@ namespace FreeSql.Firebird if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; return null; case "ToString": - if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"cast({getExp(callExp.Object)} as char)" : null; + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"cast({getExp(callExp.Object)} as blob sub_type 1)" : null; return null; } @@ -401,7 +400,41 @@ namespace FreeSql.Firebird break; case "Equals": return $"({left} = {args1})"; case "CompareTo": return $"datediff(second from {left} to {args1})"; - case "ToString": return exp.Arguments.Count == 0 ? $"cast({left} as varchar(50))" : null; + case "ToString": + if (left.EndsWith(" as timestamp)") == false && left.StartsWith("timestamp") == false) left = $"cast({left} as timestamp)"; + if (exp.Arguments.Count == 0) return $"lpad(extract(year from {left}),4,'0')||'-'||lpad(extract(month from {left}),2,'0')||'-'||lpad(extract(day from {left}),2,'0')||' '||lpad(extract(hour from {left}),2,'0')||':'||lpad(extract(minute from {left}),2,'0')||':'||lpad(trunc(extract(second from {left})),2,'0')"; + switch (args1.TrimStart('N')) + { + case "'yyyyMMdd'": return $"lpad(extract(year from {left}),4,'0')||lpad(extract(month from {left}),2,'0')||lpad(extract(day from {left}),2,'0')"; + case "'yyyyMM'": return $"lpad(extract(year from {left}),4,'0')||lpad(extract(month from {left}),2,'0')"; + case "'yyyy'": return $"lpad(extract(year from {left}),4,'0')"; + } + var isMatched = false; + args1 = Regex.Replace(args1, "(yyyy|yy|MM|M|dd|d|HH|H|hh|h|mm|m|ss|s|tt|t)", m => + { + isMatched = true; + switch (m.Groups[1].Value) + { + case "yyyy": return $"'||lpad(extract(year from {left}),4,'0')||'"; + case "yy": return $"'||substring(lpad(extract(year from {left}),4,'0') from 3 for 2)||'"; + case "MM": return $"'||lpad(extract(month from {left}),2,'0')||'"; + case "M": return $"'||extract(month from {left})||'"; + case "dd": return $"'||lpad(extract(day from {left}),2,'0')||'"; + case "d": return $"'||extract(day from {left})||'"; + case "HH": return $"'||lpad(extract(hour from {left}),2,'0')||'"; + case "H": return $"'||extract(hour from {left})||'"; + case "hh": return $"'||case when mod(extract(hour from {left}),12) = 0 then '12' else lpad(mod(extract(hour from {left}),12),2,'0') end||'"; + case "h": return $"'||trim(case when mod(extract(hour from {left}),12) = 0 then '12' else mod(extract(hour from {left}),12) end)||'"; + case "mm": return $"'||lpad(extract(minute from {left}),2,'0')||'"; + case "m": return $"'||extract(minute from {left})||'"; + case "ss": return $"'||lpad(trunc(extract(second from {left})),2,'0')||'"; + case "s": return $"'||trunc(extract(second from {left}))||'"; + case "tt": return $"'||case when extract(hour from {left}) >= 12 then 'PM' else 'AM' end||'"; + case "t": return $"'||case when extract(hour from {left}) >= 12 then 'P' else 'A' end||'"; + } + return m.Groups[0].Value; + }); + return isMatched == false ? args1 : $"({args1})"; } } return null;