mirror of
https://github.com/danieleteti/delphimvcframework.git
synced 2024-11-15 07:45:54 +01:00
This commit is contained in:
parent
4a27f8b64d
commit
c201c916cb
@ -245,6 +245,8 @@ Congratulations to Daniele Teti and all the staff for the excellent work!" -- Ma
|
|||||||
|
|
||||||
- ⚡ Wizard updated to be dotEnv aware
|
- ⚡ Wizard updated to be dotEnv aware
|
||||||
|
|
||||||
|
- ⚡ Added "Load Style" methods to `TMVCActiveRecord` as suggested by https://github.com/danieleteti/delphimvcframework/issues/675
|
||||||
|
|
||||||
- ⚡ Better error message in case of serialization of `TArray<TObject>`
|
- ⚡ Better error message in case of serialization of `TArray<TObject>`
|
||||||
|
|
||||||
- ⚡ Improved serialization of `TObjectList<TDataSet>` (however `ObjectDict` is still the preferred way to serialize multiple datasets).
|
- ⚡ Improved serialization of `TObjectList<TDataSet>` (however `ObjectDict` is still the preferred way to serialize multiple datasets).
|
||||||
|
@ -2,62 +2,49 @@ object MainForm: TMainForm
|
|||||||
Left = 0
|
Left = 0
|
||||||
Top = 0
|
Top = 0
|
||||||
Caption = 'TMVCActiveRecord - ShowCase'
|
Caption = 'TMVCActiveRecord - ShowCase'
|
||||||
ClientHeight = 1423
|
ClientHeight = 569
|
||||||
ClientWidth = 2760
|
ClientWidth = 1104
|
||||||
Color = clBtnFace
|
Color = clBtnFace
|
||||||
Font.Charset = DEFAULT_CHARSET
|
Font.Charset = DEFAULT_CHARSET
|
||||||
Font.Color = clWindowText
|
Font.Color = clWindowText
|
||||||
Font.Height = -28
|
Font.Height = -11
|
||||||
Font.Name = 'Tahoma'
|
Font.Name = 'Tahoma'
|
||||||
Font.Style = []
|
Font.Style = []
|
||||||
OnDestroy = FormDestroy
|
OnDestroy = FormDestroy
|
||||||
OnShow = FormShow
|
OnShow = FormShow
|
||||||
PixelsPerInch = 240
|
|
||||||
DesignSize = (
|
DesignSize = (
|
||||||
2760
|
1104
|
||||||
1423)
|
569)
|
||||||
TextHeight = 34
|
TextHeight = 13
|
||||||
object btnCRUD: TButton
|
object btnCRUD: TButton
|
||||||
Left = 20
|
Left = 8
|
||||||
Top = 20
|
Top = 8
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 83
|
Height = 33
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'CRUD'
|
Caption = 'CRUD'
|
||||||
TabOrder = 0
|
TabOrder = 0
|
||||||
OnClick = btnCRUDClick
|
OnClick = btnCRUDClick
|
||||||
end
|
end
|
||||||
object btnSelect: TButton
|
object btnSelect: TButton
|
||||||
Left = 20
|
Left = 8
|
||||||
Top = 605
|
Top = 242
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 83
|
Height = 33
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'Queries'
|
Caption = 'Queries'
|
||||||
TabOrder = 1
|
TabOrder = 1
|
||||||
OnClick = btnSelectClick
|
OnClick = btnSelectClick
|
||||||
end
|
end
|
||||||
object Memo1: TMemo
|
object Memo1: TMemo
|
||||||
Left = 700
|
Left = 280
|
||||||
Top = 20
|
Top = 8
|
||||||
Width = 2040
|
Width = 816
|
||||||
Height = 1383
|
Height = 553
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Anchors = [akLeft, akTop, akRight, akBottom]
|
Anchors = [akLeft, akTop, akRight, akBottom]
|
||||||
Ctl3D = True
|
Ctl3D = True
|
||||||
DoubleBuffered = True
|
DoubleBuffered = True
|
||||||
Font.Charset = ANSI_CHARSET
|
Font.Charset = ANSI_CHARSET
|
||||||
Font.Color = clWindowText
|
Font.Color = clWindowText
|
||||||
Font.Height = -33
|
Font.Height = -13
|
||||||
Font.Name = 'Consolas'
|
Font.Name = 'Consolas'
|
||||||
Font.Style = []
|
Font.Style = []
|
||||||
ParentCtl3D = False
|
ParentCtl3D = False
|
||||||
@ -68,306 +55,214 @@ object MainForm: TMainForm
|
|||||||
TabOrder = 2
|
TabOrder = 2
|
||||||
WantReturns = False
|
WantReturns = False
|
||||||
WordWrap = False
|
WordWrap = False
|
||||||
ExplicitWidth = 2020
|
ExplicitWidth = 812
|
||||||
ExplicitHeight = 1381
|
ExplicitHeight = 552
|
||||||
end
|
end
|
||||||
object btnRelations: TButton
|
object btnRelations: TButton
|
||||||
Left = 20
|
Left = 8
|
||||||
Top = 703
|
Top = 281
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 87
|
Height = 35
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'Relations'
|
Caption = 'Relations'
|
||||||
TabOrder = 3
|
TabOrder = 3
|
||||||
OnClick = btnRelationsClick
|
OnClick = btnRelationsClick
|
||||||
end
|
end
|
||||||
object btnInheritance: TButton
|
object btnInheritance: TButton
|
||||||
Left = 20
|
Left = 8
|
||||||
Top = 805
|
Top = 322
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 85
|
Height = 34
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'Inheritance'
|
Caption = 'Inheritance'
|
||||||
TabOrder = 4
|
TabOrder = 4
|
||||||
OnClick = btnInheritanceClick
|
OnClick = btnInheritanceClick
|
||||||
end
|
end
|
||||||
object btnValidation: TButton
|
object btnValidation: TButton
|
||||||
Left = 20
|
Left = 8
|
||||||
Top = 905
|
Top = 362
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 85
|
Height = 34
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'Validation'
|
Caption = 'Validation'
|
||||||
TabOrder = 5
|
TabOrder = 5
|
||||||
OnClick = btnValidationClick
|
OnClick = btnValidationClick
|
||||||
end
|
end
|
||||||
object btnMultiThreading: TButton
|
object btnMultiThreading: TButton
|
||||||
Left = 360
|
Left = 144
|
||||||
Top = 20
|
Top = 8
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 83
|
Height = 33
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'Multi Threading'
|
Caption = 'Multi Threading'
|
||||||
TabOrder = 6
|
TabOrder = 6
|
||||||
OnClick = btnMultiThreadingClick
|
OnClick = btnMultiThreadingClick
|
||||||
end
|
end
|
||||||
object btnRQL: TButton
|
object btnRQL: TButton
|
||||||
Left = 20
|
Left = 8
|
||||||
Top = 1005
|
Top = 402
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 85
|
Height = 34
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'RQL Query'
|
Caption = 'RQL Query'
|
||||||
TabOrder = 7
|
TabOrder = 7
|
||||||
OnClick = btnRQLClick
|
OnClick = btnRQLClick
|
||||||
end
|
end
|
||||||
object btnReadOnlyFields: TButton
|
object btnReadOnlyFields: TButton
|
||||||
Left = 20
|
Left = 8
|
||||||
Top = 508
|
Top = 203
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 82
|
Height = 33
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'CRUD With R/O Field'
|
Caption = 'CRUD With R/O Field'
|
||||||
TabOrder = 8
|
TabOrder = 8
|
||||||
OnClick = btnReadOnlyFieldsClick
|
OnClick = btnReadOnlyFieldsClick
|
||||||
end
|
end
|
||||||
object btnNullTest: TButton
|
object btnNullTest: TButton
|
||||||
Left = 360
|
Left = 144
|
||||||
Top = 118
|
Top = 47
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 82
|
Height = 33
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'Nullables'
|
Caption = 'Nullables'
|
||||||
TabOrder = 9
|
TabOrder = 9
|
||||||
OnClick = btnNullTestClick
|
OnClick = btnNullTestClick
|
||||||
end
|
end
|
||||||
object btnCRUDNoAutoInc: TButton
|
object btnCRUDNoAutoInc: TButton
|
||||||
Left = 20
|
Left = 8
|
||||||
Top = 215
|
Top = 86
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 83
|
Height = 33
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'CRUD (no autoinc)'
|
Caption = 'CRUD (no autoinc)'
|
||||||
TabOrder = 10
|
TabOrder = 10
|
||||||
OnClick = btnCRUDNoAutoIncClick
|
OnClick = btnCRUDNoAutoIncClick
|
||||||
end
|
end
|
||||||
object btnCRUDWithStringPKs: TButton
|
object btnCRUDWithStringPKs: TButton
|
||||||
Left = 20
|
Left = 8
|
||||||
Top = 313
|
Top = 125
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 82
|
Height = 33
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'CRUD (string pks)'
|
Caption = 'CRUD (string pks)'
|
||||||
TabOrder = 11
|
TabOrder = 11
|
||||||
OnClick = btnCRUDWithStringPKsClick
|
OnClick = btnCRUDWithStringPKsClick
|
||||||
end
|
end
|
||||||
object btnWithSpaces: TButton
|
object btnWithSpaces: TButton
|
||||||
Left = 20
|
Left = 8
|
||||||
Top = 410
|
Top = 164
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 83
|
Height = 33
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'CRUD (entity with spaces)'
|
Caption = 'CRUD (entity with spaces)'
|
||||||
TabOrder = 12
|
TabOrder = 12
|
||||||
WordWrap = True
|
WordWrap = True
|
||||||
OnClick = btnWithSpacesClick
|
OnClick = btnWithSpacesClick
|
||||||
end
|
end
|
||||||
object btnCountWithRQL: TButton
|
object btnCountWithRQL: TButton
|
||||||
Left = 360
|
Left = 144
|
||||||
Top = 215
|
Top = 86
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 83
|
Height = 33
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'Count with RQL'
|
Caption = 'Count with RQL'
|
||||||
TabOrder = 13
|
TabOrder = 13
|
||||||
OnClick = btnCountWithRQLClick
|
OnClick = btnCountWithRQLClick
|
||||||
end
|
end
|
||||||
object btnReadAndWriteOnly: TButton
|
object btnReadAndWriteOnly: TButton
|
||||||
Left = 360
|
Left = 144
|
||||||
Top = 313
|
Top = 125
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 82
|
Height = 33
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'R/O, R/W'
|
Caption = 'R/O, R/W'
|
||||||
TabOrder = 14
|
TabOrder = 14
|
||||||
OnClick = btnReadAndWriteOnlyClick
|
OnClick = btnReadAndWriteOnlyClick
|
||||||
end
|
end
|
||||||
object btnClientGeneratedPK: TButton
|
object btnClientGeneratedPK: TButton
|
||||||
Left = 360
|
Left = 144
|
||||||
Top = 410
|
Top = 164
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 83
|
Height = 33
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'Client Generated PKs'
|
Caption = 'Client Generated PKs'
|
||||||
TabOrder = 15
|
TabOrder = 15
|
||||||
OnClick = btnClientGeneratedPKClick
|
OnClick = btnClientGeneratedPKClick
|
||||||
end
|
end
|
||||||
object btnAttributes: TButton
|
object btnAttributes: TButton
|
||||||
Left = 360
|
Left = 144
|
||||||
Top = 508
|
Top = 203
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 82
|
Height = 33
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'Attributes'
|
Caption = 'Attributes'
|
||||||
TabOrder = 16
|
TabOrder = 16
|
||||||
OnClick = btnAttributesClick
|
OnClick = btnAttributesClick
|
||||||
end
|
end
|
||||||
object btnJSON_XML_Types: TButton
|
object btnJSON_XML_Types: TButton
|
||||||
Left = 360
|
Left = 144
|
||||||
Top = 605
|
Top = 242
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 88
|
Height = 35
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'JSON && XML'
|
Caption = 'JSON && XML'
|
||||||
TabOrder = 17
|
TabOrder = 17
|
||||||
OnClick = btnJSON_XML_TypesClick
|
OnClick = btnJSON_XML_TypesClick
|
||||||
end
|
end
|
||||||
object btnMerge: TButton
|
object btnMerge: TButton
|
||||||
Left = 360
|
Left = 144
|
||||||
Top = 708
|
Top = 283
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 85
|
Height = 34
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'Merge'
|
Caption = 'Merge'
|
||||||
TabOrder = 18
|
TabOrder = 18
|
||||||
OnClick = btnMergeClick
|
OnClick = btnMergeClick
|
||||||
end
|
end
|
||||||
object btnTableFilter: TButton
|
object btnTableFilter: TButton
|
||||||
Left = 360
|
Left = 144
|
||||||
Top = 808
|
Top = 323
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 85
|
Height = 34
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'Table Filter'
|
Caption = 'Table Filter'
|
||||||
TabOrder = 19
|
TabOrder = 19
|
||||||
OnClick = btnTableFilterClick
|
OnClick = btnTableFilterClick
|
||||||
end
|
end
|
||||||
object btnPartitioning: TButton
|
object btnPartitioning: TButton
|
||||||
Left = 360
|
Left = 144
|
||||||
Top = 908
|
Top = 363
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 82
|
Height = 33
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'Table Partitioning'
|
Caption = 'Table Partitioning'
|
||||||
TabOrder = 20
|
TabOrder = 20
|
||||||
OnClick = btnPartitioningClick
|
OnClick = btnPartitioningClick
|
||||||
end
|
end
|
||||||
object btnCRUDWithGUID: TButton
|
object btnCRUDWithGUID: TButton
|
||||||
Left = 20
|
Left = 8
|
||||||
Top = 118
|
Top = 47
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 82
|
Height = 33
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'CRUD (with GUID PK)'
|
Caption = 'CRUD (with GUID PK)'
|
||||||
TabOrder = 21
|
TabOrder = 21
|
||||||
OnClick = btnCRUDWithGUIDClick
|
OnClick = btnCRUDWithGUIDClick
|
||||||
end
|
end
|
||||||
object btnOOP: TButton
|
object btnOOP: TButton
|
||||||
Left = 360
|
Left = 144
|
||||||
Top = 1005
|
Top = 402
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 85
|
Height = 34
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'OOP with Partitioning and Filtering'
|
Caption = 'OOP with Partitioning and Filtering'
|
||||||
TabOrder = 22
|
TabOrder = 22
|
||||||
WordWrap = True
|
WordWrap = True
|
||||||
OnClick = btnOOPClick
|
OnClick = btnOOPClick
|
||||||
end
|
end
|
||||||
object btnReadOnly: TButton
|
object btnReadOnly: TButton
|
||||||
Left = 20
|
Left = 8
|
||||||
Top = 1105
|
Top = 442
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 85
|
Height = 34
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'Read/Only Entities'
|
Caption = 'Read/Only Entities'
|
||||||
TabOrder = 23
|
TabOrder = 23
|
||||||
OnClick = btnReadOnlyClick
|
OnClick = btnReadOnlyClick
|
||||||
end
|
end
|
||||||
object btnSpeed: TButton
|
object btnSpeed: TButton
|
||||||
Left = 20
|
Left = 8
|
||||||
Top = 1205
|
Top = 482
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 85
|
Height = 34
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'Metadata Speed Test'
|
Caption = 'Metadata Speed Test'
|
||||||
TabOrder = 24
|
TabOrder = 24
|
||||||
OnClick = btnSpeedClick
|
OnClick = btnSpeedClick
|
||||||
end
|
end
|
||||||
object btnRefresh: TButton
|
object btnRefresh: TButton
|
||||||
Left = 360
|
Left = 144
|
||||||
Top = 1105
|
Top = 442
|
||||||
Width = 303
|
Width = 121
|
||||||
Height = 85
|
Height = 34
|
||||||
Margins.Left = 8
|
|
||||||
Margins.Top = 8
|
|
||||||
Margins.Right = 8
|
|
||||||
Margins.Bottom = 8
|
|
||||||
Caption = 'Manual Refresh'
|
Caption = 'Manual Refresh'
|
||||||
TabOrder = 25
|
TabOrder = 25
|
||||||
OnClick = btnRefreshClick
|
OnClick = btnRefreshClick
|
||||||
|
@ -1040,6 +1040,7 @@ var
|
|||||||
lItem: TMVCActiveRecord;
|
lItem: TMVCActiveRecord;
|
||||||
lCustomer: TCustomer;
|
lCustomer: TCustomer;
|
||||||
lCustList: TObjectList<TCustomer>;
|
lCustList: TObjectList<TCustomer>;
|
||||||
|
lRecCount: Integer;
|
||||||
const
|
const
|
||||||
cRQL1 = 'in(City,["Rome","London"]);sort(+code);limit(0,50)';
|
cRQL1 = 'in(City,["Rome","London"]);sort(+code);limit(0,50)';
|
||||||
cRQL2 = 'and(eq(City,"Rome"),or(contains(CompanyName,"GAS"),contains(CompanyName,"Motors")))';
|
cRQL2 = 'and(eq(City,"Rome"),or(contains(CompanyName,"GAS"),contains(CompanyName,"Motors")))';
|
||||||
@ -1133,6 +1134,114 @@ begin
|
|||||||
lList.Free;
|
lList.Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
//******************************************************
|
||||||
|
// Using "Load" methods ********************************
|
||||||
|
//******************************************************
|
||||||
|
Log('*************************************************');
|
||||||
|
Log('** RQL Queries Test (using "Load" style methods)');
|
||||||
|
Log('*************************************************');
|
||||||
|
Log('>> RQL Query (1) - ' + cRQL1);
|
||||||
|
lList := TMVCActiveRecordList.Create;
|
||||||
|
try
|
||||||
|
TMVCActiveRecord.SelectRQL(TCustomer, cRQL1, 20, lList);
|
||||||
|
Log(lList.Count.ToString + ' record/s found');
|
||||||
|
for lItem in lList do
|
||||||
|
begin
|
||||||
|
lCustomer := TCustomer(lItem);
|
||||||
|
Log(Format('%5s - %s (%s)', [lCustomer.Code.ValueOrDefault,
|
||||||
|
lCustomer.CompanyName.ValueOrDefault, lCustomer.City]));
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
lList.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Log('>> RQL Query (2) - ' + cRQL2);
|
||||||
|
lCustList := TObjectList<TCustomer>.Create;
|
||||||
|
try
|
||||||
|
lRecCount := TMVCActiveRecord.SelectRQL<TCustomer>(cRQL2, 20, lCustList);
|
||||||
|
Log(lRecCount.ToString + ' record/s found');
|
||||||
|
for lCustomer in lCustList do
|
||||||
|
begin
|
||||||
|
Log(Format('%5s - %s (%s)', [lCustomer.Code.ValueOrDefault,
|
||||||
|
lCustomer.CompanyName.ValueOrDefault, lCustomer.City]));
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
lCustList.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Log('**RQL Query (3) - ' + cRQL2);
|
||||||
|
lList := TMVCActiveRecordList.Create;
|
||||||
|
try
|
||||||
|
lRecCount := TMVCActiveRecord.SelectRQL(TCustomer, cRQL2, 20, lList);
|
||||||
|
Log(lRecCount.ToString + ' record/s found');
|
||||||
|
for lItem in lList do
|
||||||
|
begin
|
||||||
|
lCustomer := TCustomer(lItem);
|
||||||
|
Log(Format('%5s - %s (%s)', [lCustomer.Code.ValueOrDefault,
|
||||||
|
lCustomer.CompanyName.ValueOrDefault, lCustomer.City]));
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
lList.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Log('**RQL Query (4) - <empty> with limit 20');
|
||||||
|
lList := TMVCActiveRecordList.Create;
|
||||||
|
try
|
||||||
|
lRecCount := TMVCActiveRecord.SelectRQL(TCustomer, '', 20, lList);
|
||||||
|
Log(lRecCount.ToString + ' record/s found');
|
||||||
|
Assert(lRecCount = 20);
|
||||||
|
Assert(lList.Count = lRecCount);
|
||||||
|
finally
|
||||||
|
lList.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Log('**RQL Query (5) - <empty> sort by code with limit 20');
|
||||||
|
lList := TMVCActiveRecordList.Create;
|
||||||
|
try
|
||||||
|
lRecCount := TMVCActiveRecord.SelectRQL(TCustomer, 'sort(+code)', 20, lList);
|
||||||
|
Log(lRecCount.ToString + ' record/s found');
|
||||||
|
Assert(lRecCount = lList.Count);
|
||||||
|
Assert(lList.Count = 20);
|
||||||
|
finally
|
||||||
|
lList.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Log('**RQL Query (6) - <empty> with limit 10');
|
||||||
|
lList := TMVCActiveRecordList.Create;
|
||||||
|
try
|
||||||
|
lRecCount := TMVCActiveRecord.SelectRQL(TCustomer, '', 10, lList);
|
||||||
|
Log(lList.Count.ToString + ' record/s found');
|
||||||
|
Assert(lRecCount = lList.Count);
|
||||||
|
Assert(lList.Count = 10);
|
||||||
|
finally
|
||||||
|
lList.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Log('**RQL Query (7) - <empty> with limit 1');
|
||||||
|
lList := TMVCActiveRecordList.Create;
|
||||||
|
try
|
||||||
|
lRecCount := TMVCActiveRecord.SelectRQL(TCustomer, '', 1, lList);
|
||||||
|
Log(lList.Count.ToString + ' record/s found');
|
||||||
|
Assert(lList.Count = 1);
|
||||||
|
Assert(lRecCount = lList.Count);
|
||||||
|
finally
|
||||||
|
lList.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Log('**RQL Query (8) - <empty> with limit 0');
|
||||||
|
lList := TMVCActiveRecordList.Create;
|
||||||
|
try
|
||||||
|
lRecCount := TMVCActiveRecord.SelectRQL(TCustomer, '', 0, lList);
|
||||||
|
Log(lList.Count.ToString + ' record/s found');
|
||||||
|
Assert(lList.Count = 0);
|
||||||
|
Assert(lRecCount = lList.Count);
|
||||||
|
finally
|
||||||
|
lList.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainForm.btnSelectClick(Sender: TObject);
|
procedure TMainForm.btnSelectClick(Sender: TObject);
|
||||||
|
@ -333,7 +333,9 @@ type
|
|||||||
|
|
||||||
function InternalCount(const RQL: string): int64;
|
function InternalCount(const RQL: string): int64;
|
||||||
function InternalSelectRQL(const RQL: string; const MaxRecordCount: Integer)
|
function InternalSelectRQL(const RQL: string; const MaxRecordCount: Integer)
|
||||||
: TMVCActiveRecordList;
|
: TMVCActiveRecordList; overload;
|
||||||
|
function InternalSelectRQL(const RQL: string; const MaxRecordCount: Integer;
|
||||||
|
const OutList: TMVCActiveRecordList): UInt32; overload;
|
||||||
public
|
public
|
||||||
constructor Create(aLazyLoadConnection: Boolean); overload;
|
constructor Create(aLazyLoadConnection: Boolean); overload;
|
||||||
{ cannot be virtual! }
|
{ cannot be virtual! }
|
||||||
@ -392,18 +394,33 @@ type
|
|||||||
class function Select(const aClass: TMVCActiveRecordClass; const SQL: string;
|
class function Select(const aClass: TMVCActiveRecordClass; const SQL: string;
|
||||||
const Params: array of Variant;
|
const Params: array of Variant;
|
||||||
const Connection: TFDConnection): TMVCActiveRecordList; overload;
|
const Connection: TFDConnection): TMVCActiveRecordList; overload;
|
||||||
|
class function Select(const aClass: TMVCActiveRecordClass; const SQL: string;
|
||||||
|
const Params: array of Variant;
|
||||||
|
const Connection: TFDConnection; const OutList: TMVCActiveRecordList): UInt32; overload;
|
||||||
class function SelectRQL(const aClass: TMVCActiveRecordClass; const RQL: string;
|
class function SelectRQL(const aClass: TMVCActiveRecordClass; const RQL: string;
|
||||||
const MaxRecordCount: Integer)
|
const MaxRecordCount: Integer)
|
||||||
: TMVCActiveRecordList; overload;
|
: TMVCActiveRecordList; overload;
|
||||||
|
class function SelectRQL(const aClass: TMVCActiveRecordClass; const RQL: string;
|
||||||
|
const MaxRecordCount: Integer; const OutList: TMVCActiveRecordList): UInt32; overload;
|
||||||
class function DeleteRQL(const aClass: TMVCActiveRecordClass; const RQL: string): int64;
|
class function DeleteRQL(const aClass: TMVCActiveRecordClass; const RQL: string): int64;
|
||||||
function SelectRQL(const RQL: string; const MaxRecordCount: Integer)
|
function SelectRQL(const RQL: string; const MaxRecordCount: Integer)
|
||||||
: TMVCActiveRecordList; overload;
|
: TMVCActiveRecordList; overload;
|
||||||
class function Where(const aClass: TMVCActiveRecordClass; const SQLWhere: string;
|
class function Where(
|
||||||
|
const aClass: TMVCActiveRecordClass;
|
||||||
|
const SQLWhere: string;
|
||||||
const Params: array of Variant)
|
const Params: array of Variant)
|
||||||
: TMVCActiveRecordList; overload;
|
: TMVCActiveRecordList; overload;
|
||||||
class function Where(const aClass: TMVCActiveRecordClass; const SQLWhere: string;
|
class function Where(
|
||||||
|
const aClass: TMVCActiveRecordClass;
|
||||||
|
const SQLWhere: string;
|
||||||
const Params: array of Variant;
|
const Params: array of Variant;
|
||||||
const Connection: TFDConnection): TMVCActiveRecordList; overload;
|
const Connection: TFDConnection): TMVCActiveRecordList; overload;
|
||||||
|
class function Where(
|
||||||
|
const aClass: TMVCActiveRecordClass;
|
||||||
|
const SQLWhere: string;
|
||||||
|
const Params: array of Variant;
|
||||||
|
const Connection: TFDConnection;
|
||||||
|
const OutList: TMVCActiveRecordList): UInt32; overload;
|
||||||
class function All(const aClass: TMVCActiveRecordClass): TObjectList<TMVCActiveRecord>;
|
class function All(const aClass: TMVCActiveRecordClass): TObjectList<TMVCActiveRecord>;
|
||||||
overload;
|
overload;
|
||||||
class function DeleteAll(const aClass: TMVCActiveRecordClass): int64; overload;
|
class function DeleteAll(const aClass: TMVCActiveRecordClass): int64; overload;
|
||||||
@ -451,13 +468,27 @@ type
|
|||||||
const RaiseExceptionIfNotFound: Boolean = True): T; overload;
|
const RaiseExceptionIfNotFound: Boolean = True): T; overload;
|
||||||
class function GetByPK<T: TMVCActiveRecord, constructor>(const aValue: TGuid;
|
class function GetByPK<T: TMVCActiveRecord, constructor>(const aValue: TGuid;
|
||||||
const RaiseExceptionIfNotFound: Boolean = True): T; overload;
|
const RaiseExceptionIfNotFound: Boolean = True): T; overload;
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a TObjectList<TMVCActiveRecord> from a SQL using variant params
|
||||||
|
/// </summary>
|
||||||
class function Select<T: TMVCActiveRecord, constructor>(const SQL: string;
|
class function Select<T: TMVCActiveRecord, constructor>(const SQL: string;
|
||||||
const Params: array of Variant;
|
const Params: array of Variant;
|
||||||
const Options: TMVCActiveRecordLoadOptions = []): TObjectList<T>; overload;
|
const Options: TMVCActiveRecordLoadOptions = []): TObjectList<T>; overload;
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a TObjectList<TMVCActiveRecord> from a SQL using typed params
|
||||||
|
/// </summary>
|
||||||
class function Select<T: TMVCActiveRecord, constructor>(const SQL: string;
|
class function Select<T: TMVCActiveRecord, constructor>(const SQL: string;
|
||||||
const Params: array of Variant;
|
const Params: array of Variant;
|
||||||
const ParamTypes: array of TFieldType; const Options: TMVCActiveRecordLoadOptions = [])
|
const ParamTypes: array of TFieldType; const Options: TMVCActiveRecordLoadOptions = [])
|
||||||
: TObjectList<T>; overload;
|
: TObjectList<T>; overload;
|
||||||
|
/// <summary>
|
||||||
|
/// Fills a TObjectList<TMVCActiveRecord> from a SQL using typed params.
|
||||||
|
/// Returns number of the records in the list (not only the selected records, but the current .Count of the list)
|
||||||
|
/// </summary>
|
||||||
|
class function Select<T: TMVCActiveRecord, constructor>(const SQL: string; const Params: array of Variant;
|
||||||
|
const ParamTypes: array of TFieldType; const Options: TMVCActiveRecordLoadOptions;
|
||||||
|
const OutList: TObjectList<T>): UInt32; overload;
|
||||||
|
|
||||||
class function SelectOne<T: TMVCActiveRecord, constructor>(const SQL: string;
|
class function SelectOne<T: TMVCActiveRecord, constructor>(const SQL: string;
|
||||||
const Params: array of Variant;
|
const Params: array of Variant;
|
||||||
const ParamTypes: array of TFieldType; const Options: TMVCActiveRecordLoadOptions = [];
|
const ParamTypes: array of TFieldType; const Options: TMVCActiveRecordLoadOptions = [];
|
||||||
@ -468,6 +499,8 @@ type
|
|||||||
class function SelectRQL<T: constructor, TMVCActiveRecord>(const RQL: string;
|
class function SelectRQL<T: constructor, TMVCActiveRecord>(const RQL: string;
|
||||||
const MaxRecordCount: Integer)
|
const MaxRecordCount: Integer)
|
||||||
: TObjectList<T>; overload;
|
: TObjectList<T>; overload;
|
||||||
|
class function SelectRQL<T: constructor, TMVCActiveRecord>(const RQL: string;
|
||||||
|
const MaxRecordCount: Integer; const OutList: TObjectList<T>): UInt32; overload;
|
||||||
class function SelectOneByRQL<T: constructor, TMVCActiveRecord>(const RQL: string;
|
class function SelectOneByRQL<T: constructor, TMVCActiveRecord>(const RQL: string;
|
||||||
const RaiseExceptionIfNotFound: Boolean = True): T; overload;
|
const RaiseExceptionIfNotFound: Boolean = True): T; overload;
|
||||||
class function All<T: TMVCActiveRecord, constructor>: TObjectList<T>; overload;
|
class function All<T: TMVCActiveRecord, constructor>: TObjectList<T>; overload;
|
||||||
@ -483,6 +516,10 @@ type
|
|||||||
class function Where<T: TMVCActiveRecord, constructor>(const SQLWhere: string;
|
class function Where<T: TMVCActiveRecord, constructor>(const SQLWhere: string;
|
||||||
const Params: array of Variant;
|
const Params: array of Variant;
|
||||||
const ParamTypes: array of TFieldType): TObjectList<T>; overload;
|
const ParamTypes: array of TFieldType): TObjectList<T>; overload;
|
||||||
|
class function Where<T: TMVCActiveRecord, constructor>(const SQLWhere: string;
|
||||||
|
const Params: array of Variant;
|
||||||
|
const ParamTypes: array of TFieldType;
|
||||||
|
const OutList: TObjectList<T>): UInt32; overload;
|
||||||
class function GetOneByWhere<T: TMVCActiveRecord, constructor>(const SQLWhere: string;
|
class function GetOneByWhere<T: TMVCActiveRecord, constructor>(const SQLWhere: string;
|
||||||
const Params: array of Variant; const RaiseExceptionIfNotFound: Boolean = True): T; overload;
|
const Params: array of Variant; const RaiseExceptionIfNotFound: Boolean = True): T; overload;
|
||||||
class function GetOneByWhere<T: TMVCActiveRecord, constructor>(const SQLWhere: string;
|
class function GetOneByWhere<T: TMVCActiveRecord, constructor>(const SQLWhere: string;
|
||||||
@ -1419,6 +1456,16 @@ begin
|
|||||||
Result := GetScalar(lSQL, []);
|
Result := GetScalar(lSQL, []);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TMVCActiveRecord.InternalSelectRQL(const RQL: string;
|
||||||
|
const MaxRecordCount: Integer; const OutList: TMVCActiveRecordList): UInt32;
|
||||||
|
var
|
||||||
|
lSQL: string;
|
||||||
|
begin
|
||||||
|
lSQL := SQLGenerator.CreateSQLWhereByRQL(RQL, GetMapping, True, false, MaxRecordCount);
|
||||||
|
LogD(Format('RQL [%s] => SQL [%s]', [RQL, lSQL]));
|
||||||
|
Result := Where(TMVCActiveRecordClass(Self.ClassType), lSQL, [], nil, OutList);
|
||||||
|
end;
|
||||||
|
|
||||||
function TMVCActiveRecord.InternalSelectRQL(const RQL: string; const MaxRecordCount: Integer): TMVCActiveRecordList;
|
function TMVCActiveRecord.InternalSelectRQL(const RQL: string; const MaxRecordCount: Integer): TMVCActiveRecordList;
|
||||||
var
|
var
|
||||||
lSQL: string;
|
lSQL: string;
|
||||||
@ -1657,6 +1704,52 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class function TMVCActiveRecordHelper.SelectRQL<T>(const RQL: string;
|
||||||
|
const MaxRecordCount: Integer; const OutList: TObjectList<T>): UInt32;
|
||||||
|
var
|
||||||
|
lAR: TMVCActiveRecord;
|
||||||
|
lSQL: string;
|
||||||
|
begin
|
||||||
|
lAR := T.Create;
|
||||||
|
try
|
||||||
|
lSQL := lAR.SQLGenerator.CreateSQLWhereByRQL(RQL, lAR.GetMapping, MaxRecordCount > -1, false, MaxRecordCount).Trim;
|
||||||
|
lSQL := TMVCSQLGenerator.RemoveInitialWhereKeyword(lSQL);
|
||||||
|
Result := Where<T>(lSQL, [], [], OutList);
|
||||||
|
finally
|
||||||
|
lAR.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
class function TMVCActiveRecordHelper.Where<T>(const SQLWhere: string;
|
||||||
|
const Params: array of Variant; const ParamTypes: array of TFieldType;
|
||||||
|
const OutList: TObjectList<T>): UInt32;
|
||||||
|
var
|
||||||
|
lAR: TMVCActiveRecord;
|
||||||
|
lFilter: string;
|
||||||
|
begin
|
||||||
|
lAR := T.Create;
|
||||||
|
try
|
||||||
|
lFilter := lAR.SQLGenerator.GetDefaultSQLFilter(True);
|
||||||
|
if SQLWhere.Trim.IsEmpty() or SQLWhere.Trim.StartsWith('/*limit*/') or SQLWhere.Trim.StartsWith('/*sort*/') then
|
||||||
|
begin
|
||||||
|
Result := Select<T>(lAR.GenerateSelectSQL + lFilter + SQLWhere, Params, ParamTypes, [], OutList);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if lFilter.IsEmpty then
|
||||||
|
begin
|
||||||
|
Result := Select<T>(lAR.GenerateSelectSQL + ' WHERE ' + SQLWhere, Params, ParamTypes, [], OutList);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Result := Select<T>(lAR.GenerateSelectSQL + lFilter + ' AND ' + SQLWhere, Params, ParamTypes, [], OutList);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
lAR.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function TMVCActiveRecord.GetPartitionInfo: TPartitionInfo;
|
function TMVCActiveRecord.GetPartitionInfo: TPartitionInfo;
|
||||||
var
|
var
|
||||||
lRQLCompilerClass: TRQLCompilerClass;
|
lRQLCompilerClass: TRQLCompilerClass;
|
||||||
@ -2454,29 +2547,14 @@ end;
|
|||||||
|
|
||||||
class function TMVCActiveRecord.Select(const aClass: TMVCActiveRecordClass; const SQL: string;
|
class function TMVCActiveRecord.Select(const aClass: TMVCActiveRecordClass; const SQL: string;
|
||||||
const Params: array of Variant; const Connection: TFDConnection): TMVCActiveRecordList;
|
const Params: array of Variant; const Connection: TFDConnection): TMVCActiveRecordList;
|
||||||
var
|
|
||||||
lDataSet: TDataSet;
|
|
||||||
lAR: TMVCActiveRecord;
|
|
||||||
begin
|
begin
|
||||||
Result := TMVCActiveRecordList.Create;
|
Result := TMVCActiveRecordList.Create;
|
||||||
try
|
try
|
||||||
lDataSet := ExecQuery(SQL, Params, Connection, True, False);
|
Select(aClass, SQL, Params, Connection, Result);
|
||||||
try
|
|
||||||
while not lDataSet.Eof do
|
|
||||||
begin
|
|
||||||
lAR := aClass.Create;
|
|
||||||
Result.Add(lAR);
|
|
||||||
lAR.LoadByDataset(lDataSet);
|
|
||||||
lDataSet.Next;
|
|
||||||
end;
|
|
||||||
finally
|
|
||||||
lDataSet.Free;
|
|
||||||
end;
|
|
||||||
except
|
except
|
||||||
Result.Free;
|
Result.Free;
|
||||||
raise;
|
raise;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
class function TMVCActiveRecord.SelectDataSet(const SQL: string; const Params: array of Variant;
|
class function TMVCActiveRecord.SelectDataSet(const SQL: string; const Params: array of Variant;
|
||||||
@ -2502,6 +2580,41 @@ begin
|
|||||||
Result := InternalSelectRQL(RQL, MaxRecordCount);
|
Result := InternalSelectRQL(RQL, MaxRecordCount);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class function TMVCActiveRecord.SelectRQL(const aClass: TMVCActiveRecordClass;
|
||||||
|
const RQL: string; const MaxRecordCount: Integer;
|
||||||
|
const OutList: TMVCActiveRecordList): UInt32;
|
||||||
|
var
|
||||||
|
lAR: TMVCActiveRecord;
|
||||||
|
begin
|
||||||
|
lAR := aClass.Create(True);
|
||||||
|
try
|
||||||
|
Result := lAR.InternalSelectRQL(RQL, MaxRecordCount, OutList);
|
||||||
|
finally
|
||||||
|
lAR.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
class function TMVCActiveRecordHelper.Select<T>(const SQL: string; const Params: array of Variant;
|
||||||
|
const ParamTypes: array of TFieldType; const Options: TMVCActiveRecordLoadOptions; const OutList: TObjectList<T>): UInt32;
|
||||||
|
var
|
||||||
|
lDataSet: TDataSet;
|
||||||
|
lAR: TMVCActiveRecord;
|
||||||
|
begin
|
||||||
|
lDataSet := ExecQuery(SQL, Params, ParamTypes, True, False);
|
||||||
|
try
|
||||||
|
while not lDataSet.Eof do
|
||||||
|
begin
|
||||||
|
lAR := T.Create;
|
||||||
|
OutList.Add(lAR);
|
||||||
|
lAR.LoadByDataset(lDataSet, Options);
|
||||||
|
lDataSet.Next;
|
||||||
|
end;
|
||||||
|
Result := OutList.Count;
|
||||||
|
finally
|
||||||
|
lDataSet.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
class function TMVCActiveRecordHelper.Select<T>(const SQL: string; const Params: array of Variant;
|
class function TMVCActiveRecordHelper.Select<T>(const SQL: string; const Params: array of Variant;
|
||||||
const ParamTypes: array of TFieldType; const Options: TMVCActiveRecordLoadOptions): TObjectList<T>;
|
const ParamTypes: array of TFieldType; const Options: TMVCActiveRecordLoadOptions): TObjectList<T>;
|
||||||
var
|
var
|
||||||
@ -2511,18 +2624,7 @@ var
|
|||||||
begin
|
begin
|
||||||
Result := TObjectList<T>.Create(True);
|
Result := TObjectList<T>.Create(True);
|
||||||
try
|
try
|
||||||
lDataSet := ExecQuery(SQL, Params, ParamTypes, True, False);
|
Select<T>(SQL, Params, ParamTypes, Options, Result);
|
||||||
try
|
|
||||||
while not lDataSet.Eof do
|
|
||||||
begin
|
|
||||||
lAR := T.Create;
|
|
||||||
Result.Add(lAR);
|
|
||||||
lAR.LoadByDataset(lDataSet, Options);
|
|
||||||
lDataSet.Next;
|
|
||||||
end;
|
|
||||||
finally
|
|
||||||
lDataSet.Free;
|
|
||||||
end;
|
|
||||||
except
|
except
|
||||||
Result.Free;
|
Result.Free;
|
||||||
raise;
|
raise;
|
||||||
@ -2581,28 +2683,13 @@ end;
|
|||||||
|
|
||||||
class function TMVCActiveRecordHelper.Where<T>(const SQLWhere: string; const Params: array of Variant;
|
class function TMVCActiveRecordHelper.Where<T>(const SQLWhere: string; const Params: array of Variant;
|
||||||
const ParamTypes: array of TFieldType): TObjectList<T>;
|
const ParamTypes: array of TFieldType): TObjectList<T>;
|
||||||
var
|
|
||||||
lAR: TMVCActiveRecord;
|
|
||||||
lFilter: string;
|
|
||||||
begin
|
begin
|
||||||
lAR := T.Create;
|
Result := TObjectList<T>.Create(True);
|
||||||
try
|
try
|
||||||
lFilter := lAR.SQLGenerator.GetDefaultSQLFilter(True);
|
Where<T>(SQLWhere, Params, ParamTypes, Result);
|
||||||
if SQLWhere.Trim.IsEmpty() or SQLWhere.Trim.StartsWith('/*limit*/') or SQLWhere.Trim.StartsWith('/*sort*/') then
|
except
|
||||||
begin
|
Result.Free;
|
||||||
Result := Select<T>(lAR.GenerateSelectSQL + lFilter + SQLWhere, Params, ParamTypes)
|
raise;
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
if lFilter.IsEmpty then
|
|
||||||
Result := Select<T>(lAR.GenerateSelectSQL + ' WHERE ' + SQLWhere, Params, ParamTypes)
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
Result := Select<T>(lAR.GenerateSelectSQL + lFilter + ' AND ' + SQLWhere, Params, ParamTypes);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
finally
|
|
||||||
lAR.Free;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -3000,6 +3087,20 @@ begin
|
|||||||
OnAfterInsertOrUpdate;
|
OnAfterInsertOrUpdate;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class function TMVCActiveRecord.Where(const aClass: TMVCActiveRecordClass;
|
||||||
|
const SQLWhere: string; const Params: array of Variant;
|
||||||
|
const Connection: TFDConnection; const OutList: TMVCActiveRecordList): UInt32;
|
||||||
|
var
|
||||||
|
lAR: TMVCActiveRecord;
|
||||||
|
begin
|
||||||
|
lAR := aClass.Create;
|
||||||
|
try
|
||||||
|
Result := Select(aClass, lAR.GenerateSelectSQL + SQLWhere, Params, Connection, OutList);
|
||||||
|
finally
|
||||||
|
lAR.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TMVCActiveRecord.AddChildren(const ChildObject: TObject);
|
procedure TMVCActiveRecord.AddChildren(const ChildObject: TObject);
|
||||||
begin
|
begin
|
||||||
if fChildren = nil then
|
if fChildren = nil then
|
||||||
@ -3051,14 +3152,13 @@ end;
|
|||||||
|
|
||||||
class function TMVCActiveRecord.Where(const aClass: TMVCActiveRecordClass; const SQLWhere: string;
|
class function TMVCActiveRecord.Where(const aClass: TMVCActiveRecordClass; const SQLWhere: string;
|
||||||
const Params: array of Variant; const Connection: TFDConnection): TMVCActiveRecordList;
|
const Params: array of Variant; const Connection: TFDConnection): TMVCActiveRecordList;
|
||||||
var
|
|
||||||
lAR: TMVCActiveRecord;
|
|
||||||
begin
|
begin
|
||||||
lAR := aClass.Create;
|
Result := TMVCActiveRecordList.Create;
|
||||||
try
|
try
|
||||||
Result := Select(aClass, lAR.GenerateSelectSQL + SQLWhere, Params, Connection);
|
Where(aClass, SQLWhere, Params, Connection, Result);
|
||||||
finally
|
except
|
||||||
lAR.Free;
|
Result.Free;
|
||||||
|
raise;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -4063,6 +4163,28 @@ begin
|
|||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class function TMVCActiveRecord.Select(const aClass: TMVCActiveRecordClass;
|
||||||
|
const SQL: string; const Params: array of Variant;
|
||||||
|
const Connection: TFDConnection; const OutList: TMVCActiveRecordList): UInt32;
|
||||||
|
var
|
||||||
|
lDataSet: TDataSet;
|
||||||
|
lAR: TMVCActiveRecord;
|
||||||
|
begin
|
||||||
|
lDataSet := ExecQuery(SQL, Params, Connection, True, False);
|
||||||
|
try
|
||||||
|
while not lDataSet.Eof do
|
||||||
|
begin
|
||||||
|
lAR := aClass.Create;
|
||||||
|
OutList.Add(lAR);
|
||||||
|
lAR.LoadByDataset(lDataSet);
|
||||||
|
lDataSet.Next;
|
||||||
|
end;
|
||||||
|
Result := OutList.Count;
|
||||||
|
finally
|
||||||
|
lDataSet.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
|
|
||||||
gConnectionsLock := TObject.Create;
|
gConnectionsLock := TObject.Create;
|
||||||
|
Loading…
Reference in New Issue
Block a user