Daniele Teti 2023-08-30 16:34:36 +02:00
parent f5f9220f70
commit f21bb1144b
4 changed files with 57 additions and 24 deletions

View File

@ -243,13 +243,52 @@ Congratulations to Daniele Teti and all the staff for the excellent work!" -- Ma
- 🐞 FIX [Issue 680](https://github.com/danieleteti/delphimvcframework/issues/680)
- 🐞 FIX [Issue 682](https://github.com/danieleteti/delphimvcframework/issues/682) (Thanks to [wuhao13](https://github.com/wuhao13))
- 🐞 FIX Wrong comparison in checks for ro/RW/PK fields in `TMVCActiveRecord`
- 🐞 FIX wrong default initialization for JWT (thanks to Flavio Basile)
- ⚡ Wizard updated to be dotEnv aware
- ⚡ Added "Load Style" methods to `TMVCActiveRecord` as suggested by https://github.com/danieleteti/delphimvcframework/issues/675
- ⚡ Added "Load Style" methods to `TMVCActiveRecord` (more info https://github.com/danieleteti/delphimvcframework/issues/675)
- `TMVCActiveRecord` support "Factory Style" and "Load Style" methods when loads data from database.
Using "Factory Style" methods (available from the first version) the result list is returned by the loader method (as shown in this piece of code from the `activerecord_showcase` sample).
```delphi
Log('>> RQL Query (2) - ' + cRQL2);
lCustList := TMVCActiveRecord.SelectRQL<TCustomer>(cRQL2, 20);
try
Log(lCustList.Count.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;
```
For some scenarios would be useful to have also "Load Style" methods where the list is filled by the loader method (not instantiated internally).
```delphi
Log('>> RQL Query (2) - ' + cRQL2);
lCustList := TObjectList<TCustomer>.Create;
try
lRecCount := TMVCActiveRecord.SelectRQL<TCustomer>(cRQL2, 20, lCustList); //new in 3.4.0-neon
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;
```
- ⚡ Better error message in case of serialization of `TArray<TObject>`
@ -344,20 +383,20 @@ Congratulations to Daniele Teti and all the staff for the excellent work!" -- Ma
"message":"My Message"
}
```
**Data based response with single object**
```pascal
function TMyController.GetMVCResponse2: TMVCResponse;
begin
Result := MVCResponse(HTTP_STATUS.OK, TPerson.Create('Daniele','Teti', 99));
end;
```
Produces
```json
{
"data": {
@ -367,9 +406,9 @@ Congratulations to Daniele Teti and all the staff for the excellent work!" -- Ma
}
}
```
**Data based response with list of objects**
```pascal
function TMyController.GetMVCResponse3: TMVCResponse;
begin
@ -382,9 +421,9 @@ Congratulations to Daniele Teti and all the staff for the excellent work!" -- Ma
);
end;
```
Produces
```json
{
"data": [
@ -408,7 +447,7 @@ Congratulations to Daniele Teti and all the staff for the excellent work!" -- Ma
```
**Data dictionary based response with `IMVCObjectDictionary` **
```pascal
function TMyController.GetMVCResponseWithObjectDictionary: IMVCResponse;
begin
@ -430,9 +469,9 @@ Congratulations to Daniele Teti and all the staff for the excellent work!" -- Ma
);
end;
```
Produces
```json
{
"employees": [

View File

@ -1617,7 +1617,6 @@ constructor TMVCActiveRecord.Create(aLazyLoadConnection: Boolean);
begin
inherited Create;
fConn := nil;
{ TODO -oDanieleT -cGeneral : Consider lazyconnection }
if not aLazyLoadConnection then
begin
GetConnection;
@ -3366,7 +3365,6 @@ end;
class function TMVCActiveRecordHelper.All(const aQualifiedClassName: String): TObjectList<TMVCActiveRecord>;
var
lTmp: TObject;
lAR: TMVCActiveRecord;
begin
lAR := TMVCActiveRecord.CreateMVCActiveRecord<TMVCActiveRecord>(aQualifiedClassName, []);

View File

@ -100,10 +100,6 @@ var
implementation
uses
WinAPI.Windows;
{ TObjectPool<T> }
constructor TObjectPool<T>.Create(MaxSize: Integer; ShrinkTriggerSize, ShrinkTargetSize: Integer; const Factory: TFunc<T>);
@ -243,7 +239,7 @@ begin
fObjectPool.Lock;
try
fObjectPool.ShrinkPoolTo(fObjectPool.fShrinkTargetSize);
ZeroMemory(@lAvgSize, SizeOf(lAvgSize));
FillChar(lAvgSize, SizeOf(lAvgSize), 0);
finally
fObjectPool.UnLock;
end;

View File

@ -757,14 +757,14 @@ end;
class function TRttiUtils.CreateObject(AQualifiedClassName: string; const AParams: TArray<TValue> = nil): TObject;
var
rttitype: TRttiType;
lRTTIType: TRttiType;
begin
rttitype := GlContext.FindType(AQualifiedClassName);
if Assigned(rttitype) then
Result := CreateObject(rttitype, AParams)
lRTTIType := GlContext.FindType(AQualifiedClassName);
if Assigned(lRTTIType) then
Result := CreateObject(lRTTIType, AParams)
else
raise Exception.Create('Cannot find RTTI for ' + AQualifiedClassName +
'. Hint: Is the specified classtype linked in the module?');
'. HINT: Is the specified "QualifiedClassName" linked in the module?');
end;
class function TRttiUtils.CreateObject(ARttiType: TRttiType; const AParams: TArray<TValue> = nil): TObject;