From 0fac2dd2faa9c179201db595aba4daafad75f70f Mon Sep 17 00:00:00 2001 From: Daniele Teti Date: Tue, 12 Apr 2022 12:12:08 +0200 Subject: [PATCH] https://github.com/danieleteti/delphimvcframework/issues/550 --- .../host_application/UsingServerInDLL.dproj | 84 ++++++++++++++++--- sources/MVCFramework.RQL.AST2FirebirdSQL.pas | 15 +++- sources/MVCFramework.RQL.AST2InterbaseSQL.pas | 14 ++++ sources/MVCFramework.RQL.AST2SQLite.pas | 9 ++ sources/MVCFramework.Serializer.Commons.pas | 11 ++- .../general/Several/ActiveRecordTestsU.pas | 50 +++++++++++ unittests/general/Several/BOs.pas | 29 +++++-- 7 files changed, 190 insertions(+), 22 deletions(-) diff --git a/samples/server_in_dll/host_application/UsingServerInDLL.dproj b/samples/server_in_dll/host_application/UsingServerInDLL.dproj index 141d4d2c..2cd19f9a 100644 --- a/samples/server_in_dll/host_application/UsingServerInDLL.dproj +++ b/samples/server_in_dll/host_application/UsingServerInDLL.dproj @@ -1,7 +1,7 @@  {70BE99D7-37AE-4063-9A7C-4A9E9A5600D3} - 19.1 + 19.4 VCL UsingServerInDLL.dpr True @@ -104,10 +104,6 @@ TWebModule - - Cfg_2 - Base - Base @@ -115,6 +111,10 @@ Cfg_1 Base + + Cfg_2 + Base + Delphi.Personality.12 @@ -132,13 +132,13 @@ - UsingServerInDLL.exe true + 1 @@ -151,6 +151,16 @@ 0 + + + classes + 64 + + + classes + 64 + + classes @@ -279,6 +289,16 @@ 1 + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + res\drawable-ldpi @@ -442,6 +462,11 @@ 1 .framework + + Contents\MacOS + 1 + .framework + 0 @@ -469,6 +494,11 @@ 1 .dylib + + Contents\MacOS + 1 + .dylib + 0 .dll;.bpl @@ -497,6 +527,11 @@ 1 .dylib + + Contents\MacOS + 1 + .dylib + 0 .bpl @@ -526,6 +561,10 @@ Contents\Resources\StartUp\ 0 + + Contents\Resources\StartUp\ + 0 + 0 @@ -1107,6 +1146,10 @@ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF 1 + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + @@ -1117,6 +1160,10 @@ ..\ 1 + + ..\ + 1 + @@ -1127,6 +1174,10 @@ Contents 1 + + Contents + 1 + @@ -1137,6 +1188,10 @@ Contents\Resources 1 + + Contents\Resources + 1 + @@ -1167,6 +1222,10 @@ Contents\MacOS 1 + + Contents\MacOS + 1 + 0 @@ -1205,16 +1264,17 @@ 1 - - + + - + + - - - + + + True diff --git a/sources/MVCFramework.RQL.AST2FirebirdSQL.pas b/sources/MVCFramework.RQL.AST2FirebirdSQL.pas index c9bdbbfd..6441141e 100644 --- a/sources/MVCFramework.RQL.AST2FirebirdSQL.pas +++ b/sources/MVCFramework.RQL.AST2FirebirdSQL.pas @@ -63,8 +63,8 @@ const type TRQLFirebirdCompiler = class(TRQLCompiler) - protected + function GetLiteralBoolean(const Value: Boolean): String; virtual; function RQLFilterToSQL(const aRQLFIlter: TRQLFilter): string; virtual; function RQLSortToSQL(const aRQLSort: TRQLSort): string; virtual; function RQLLimitToSQL(const aRQLLimit: TRQLLimit): string; virtual; @@ -93,6 +93,15 @@ begin Result := inherited; end; +function TRQLFirebirdCompiler.GetLiteralBoolean(const Value: Boolean): String; +begin + if Value then + begin + Exit('true'); + end; + Exit('false'); +end; + function TRQLFirebirdCompiler.RQLCustom2SQL( const aRQLCustom: TRQLCustom): string; begin @@ -129,9 +138,9 @@ begin else if aRQLFIlter.RightValueType = vtBoolean then begin if SameText(aRQLFIlter.OpRight, 'true') then - lValue := '1' + lValue := GetLiteralBoolean(true) else - lValue := '0'; + lValue := GetLiteralBoolean(false); end else lValue := aRQLFIlter.OpRight; diff --git a/sources/MVCFramework.RQL.AST2InterbaseSQL.pas b/sources/MVCFramework.RQL.AST2InterbaseSQL.pas index 5e3cca05..84be8281 100644 --- a/sources/MVCFramework.RQL.AST2InterbaseSQL.pas +++ b/sources/MVCFramework.RQL.AST2InterbaseSQL.pas @@ -27,11 +27,14 @@ unit MVCFramework.RQL.AST2InterbaseSQL; interface uses + System.Generics.Defaults, MVCFramework.RQL.Parser, MVCFramework.RQL.AST2FirebirdSQL; type TRQLInterbaseCompiler = class(TRQLFirebirdCompiler) + protected + function GetLiteralBoolean(const Value: Boolean): String; override; end; implementation @@ -40,6 +43,17 @@ uses System.SysUtils, MVCFramework.ActiveRecord; +{ TRQLInterbaseCompiler } + +function TRQLInterbaseCompiler.GetLiteralBoolean(const Value: Boolean): String; +begin + if Value then + begin + Exit('1'); + end; + Exit('0'); +end; + initialization TRQLCompilerRegistry.Instance.RegisterCompiler('interbase', TRQLInterbaseCompiler); diff --git a/sources/MVCFramework.RQL.AST2SQLite.pas b/sources/MVCFramework.RQL.AST2SQLite.pas index 90075eb5..813c1aca 100644 --- a/sources/MVCFramework.RQL.AST2SQLite.pas +++ b/sources/MVCFramework.RQL.AST2SQLite.pas @@ -84,8 +84,17 @@ var begin if (aRQLFIlter.RightValueType = vtString) and (aRQLFIlter.Token <> tkContains) then lValue := aRQLFIlter.OpRight.QuotedString('''') + else if aRQLFIlter.RightValueType = vtBoolean then + begin + if SameText(aRQLFIlter.OpRight, 'true') then + lValue := '1' + else + lValue := '0'; + end else + begin lValue := aRQLFIlter.OpRight; + end; lDBFieldName := GetDatabaseFieldName(aRQLFIlter.OpLeft, True); diff --git a/sources/MVCFramework.Serializer.Commons.pas b/sources/MVCFramework.Serializer.Commons.pas index 262c27ab..3bdb3890 100644 --- a/sources/MVCFramework.Serializer.Commons.pas +++ b/sources/MVCFramework.Serializer.Commons.pas @@ -1099,7 +1099,16 @@ begin end; ftInteger, ftSmallint, ftShortint, ftByte: begin - aRTTIField.SetValue(AObject, AField.AsInteger); + // sqlite doesn't support boolean, so are identified as integers + // so we need to do some more checks... + if (aRTTIField.FieldType.TypeKind = tkEnumeration) and (aRTTIField.Name.ToLower.Contains('bool')) then + begin + aRTTIField.SetValue(AObject, AField.AsInteger = 1); + end + else + begin + aRTTIField.SetValue(AObject, AField.AsInteger); + end; end; ftLongWord, ftWord: begin diff --git a/unittests/general/Several/ActiveRecordTestsU.pas b/unittests/general/Several/ActiveRecordTestsU.pas index 01af9ee8..5114357b 100644 --- a/unittests/general/Several/ActiveRecordTestsU.pas +++ b/unittests/general/Several/ActiveRecordTestsU.pas @@ -72,6 +72,8 @@ type [Test] procedure TestRQL; [Test] + procedure TestRQLWithBoolean; + [Test] procedure TestRQLWithDateTime; [Test] procedure TestRQLLimit; @@ -1453,6 +1455,54 @@ begin Assert.AreEqual(Int64(0), TMVCActiveRecord.Count(RQL1)); end; +procedure TTestActiveRecordBase.TestRQLWithBoolean; +const + RQL1 = 'or(eq(City, "Rome"),eq(City, "London"))'; +var + lBoolTable, lBoolValue2: TBoolTest; +begin + TMVCActiveRecord.DeleteAll(TBoolTest); + Assert.AreEqual(Int64(0), TMVCActiveRecord.Count(TBoolTest)); + lBoolTable := TBoolTest.Create; + try + lBoolTable.BoolValue := True; + lBoolTable.Store; + lBoolValue2 := TMVCActiveRecord.SelectOneByRQL('eq(boolvalue, true)'); + try + Assert.AreEqual(True, lBoolValue2.BoolValue); + finally + lBoolValue2.Free; + end; + lBoolTable.BoolValue := False; + lBoolTable.Store; + + lBoolValue2 := TMVCActiveRecord.SelectOneByRQL('eq(boolvalue, false)'); + try + Assert.AreEqual(False, lBoolValue2.BoolValue); + finally + lBoolValue2.Free; + end; + + Assert.IsNull(TMVCActiveRecord.SelectOneByRQL('eq(boolvalue, true)', False)); + finally + lBoolTable.Free; + end; +// LoadData; +// lCustomers := TMVCActiveRecord.SelectRQL(RQL1, MAXINT); +// try +// Assert.AreEqual(240, lCustomers.Count); +// for var lCustomer in lCustomers do +// begin +// Assert.IsMatch('^(Rome|London)$', lCustomer.City); +// end; +// finally +// lCustomers.Free; +// end; +// TMVCActiveRecord.DeleteRQL(TCustomer, RQL1); +// Assert.AreEqual(Int64(0), TMVCActiveRecord.Count(RQL1)); +end; + + procedure TTestActiveRecordBase.TestRQLLimit; var lCustomers: TObjectList; diff --git a/unittests/general/Several/BOs.pas b/unittests/general/Several/BOs.pas index e157e82d..2f8d9496 100644 --- a/unittests/general/Several/BOs.pas +++ b/unittests/general/Several/BOs.pas @@ -35,7 +35,7 @@ uses FireDAC.Stan.Param, Data.DB, System.SysUtils; const - SQLs_SQLITE: array [0 .. 4] of string = + SQLs_SQLITE: array [0 .. 5] of string = ('CREATE TABLE customers (id INTEGER NOT NULL, code varchar (20), description varchar (200), city varchar (200), note TEXT, rating INTEGER, creation_time TIME, creation_date date, PRIMARY KEY (id))', 'CREATE TABLE customers2 (id INTEGER NOT NULL, code varchar (20), description varchar (200), city varchar (200), note TEXT, rating INTEGER, creation_time TIME, creation_date date, PRIMARY KEY (id))', 'CREATE TABLE customers_with_code (code varchar (20) not null, description varchar (200), city varchar (200), note TEXT, rating INTEGER, PRIMARY KEY(code))', @@ -51,10 +51,11 @@ const '"rating with spaces" INTEGER, ' + '"creation_time with spaces" TEXT, ' + '"creation_date with spaces" TEXT' + - ') ' + ') ', + 'CREATE TABLE booltest(id integer primary key AUTOINCREMENT, boolvalue integer)' ); - SQLs_FIREBIRD: array [0 .. 4] of string = + SQLs_FIREBIRD: array [0 .. 5] of string = ('CREATE TABLE customers (id integer generated by default as identity primary key, code varchar (20), description varchar (200), city varchar (200), note varchar(200), rating INTEGER, creation_time TIME, creation_date date)', 'CREATE TABLE customers2 (id integer generated by default as identity primary key,code varchar (20), description varchar (200), city varchar (200), note varchar(200), rating INTEGER, creation_time TIME, creation_date date)', 'CREATE TABLE customers_with_code (code varchar (20) not null, description varchar (200), city varchar (200), note varchar(200), rating INTEGER, PRIMARY KEY(code))', @@ -70,10 +71,11 @@ const '"rating with spaces" INTEGER, ' + '"creation_time with spaces" time, ' + '"creation_date with spaces" date' + - ') ' + ') ', + 'CREATE TABLE booltest(id integer generated by default as identity primary key, boolvalue boolean)' ); - SQLs_POSTGRESQL: array [0 .. 4] of string = + SQLs_POSTGRESQL: array [0 .. 5] of string = ('CREATE TABLE customers (id integer generated by default as identity primary key, code varchar (20), description varchar (200), city varchar (200), note varchar(200), rating INTEGER, creation_time TIME, creation_date date)', 'CREATE TABLE customers2 (id integer generated by default as identity primary key,code varchar (20), description varchar (200), city varchar (200), note varchar(200), rating INTEGER, creation_time TIME, creation_date date)', 'CREATE TABLE customers_with_code (code varchar (20) not null, description varchar (200), city varchar (200), note varchar(200), rating INTEGER, PRIMARY KEY(code))', @@ -89,7 +91,8 @@ const '"rating with spaces" int4 NULL, ' + '"creation_time with spaces" time NULL, ' + '"creation_date with spaces" date NULL' + - ')' + ')', + 'CREATE TABLE booltest(id integer generated by default as identity primary key, boolvalue boolean)' ); type @@ -352,6 +355,20 @@ type property f_blob: TStream read ff_blob write ff_blob; end; + + [MVCTable('booltest')] + TBoolTest = class(TMVCActiveRecord) + private + [MVCTableField('id', [foPrimaryKey, foAutoGenerated])] + fID: NullableInt32; + [MVCTableField('boolvalue')] + fBoolValue: Boolean; + public + property ID: NullableInt32 read FID write fID; + property BoolValue: Boolean read FBoolValue write fBoolValue; + end; + + TMyObject = class private FPropString: string;