diff --git a/COMPATIBILITY_MANTAINERS.MD b/COMPATIBILITY_MANTAINERS.MD
index b088bb7f..c47e8017 100644
--- a/COMPATIBILITY_MANTAINERS.MD
+++ b/COMPATIBILITY_MANTAINERS.MD
@@ -12,13 +12,15 @@ If you use a Delphi version that is not the latest, and you find an issue, check
|Delphi Version | Compatibility Mantainer |
|---|---|
-|Delphi 10.4 Sydney | Daniele Teti |
-|Delphi 10.3.1 Rio |Daniele Teti, João Fernandes, Emilio Perez |
+|Delphi 11 Alexandria | Daniele Teti |
+|Delphi 10.4 Sydney | ... |
+|Delphi 10.3.1 Rio |João Fernandes, Emilio Perez |
|Delphi 10.2.3 Tokyo |Daniele Barbato, Mohammed Nasman, MJ Wille |
|Delphi 10.2 Community Edition|Akrom Obidov|
|Delphi 10.1.2 Berlin | Emilio Perez, Akrom Obidov, Akbar Khayitov |
|Delphi 10.0 Seattle | Davut Eryılmaz |
-| | |
+
+
### What is expected by a compatibility mantainer?
diff --git a/README.md b/README.md
index 66879fa9..cafe2696 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# DelphiMVCFramework ![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg) ![GitHub All Releases](https://img.shields.io/github/downloads/danieleteti/delphimvcframework/total?label=Downloads)
-![](https://img.shields.io/badge/Current%20Version-dmvcframework--3.4.0--neon-blue)
-![](https://img.shields.io/badge/Beta%20Version-dmvcframework--4.0.0--oxygen--beta-red)
+![](https://img.shields.io/badge/stable-dmvcframework--3.4.0--neon-blue)
+![](https://img.shields.io/badge/beta-dmvcframework--3.4.1--sodium--beta-red)
@@ -215,7 +215,7 @@ Congratulations to Daniele Teti and all the staff for the excellent work!" -- Ma
> "I managed to generate an API for my application thanks to this framework, it is truly useful and efficient!" -- J. Urbani
-## What's New in DelphiMVCFramework-3.4.0-neon (current stable version)
+## What's New in DelphiMVCFramework-3.4.0-neon (stable version)
>👉 Deeper analisys of what's new in DelphiMVCFramework-3.4.0-neone is available on [Daniele Teti Blog](http://www.danieleteti.it/post/delphimvcframework-3-4-0-neon/) 👈
@@ -336,7 +336,7 @@ Congratulations to Daniele Teti and all the staff for the excellent work!" -- Ma
- ⚡ Improved `TMVCResponse` type to better suits the new functional actions.
`TMVCResponse` can be used with "message based" responses and also with "data based" responses (with single object, with a list of objects or with a dictionary of objects).
-
+
More info [here](http://www.danieleteti.it/post/delphimvcframework-3-4-0-neon/)
- Removed `statuscode`, `reasonstring` and all the field with a default value from exception's JSON rendering. All the high-level rendering methods will emit standard `ReasonString`.
diff --git a/packages/d110/dmvcframework_group.groupproj b/packages/d110/dmvcframework_group.groupproj
index 21a707de..09884fdb 100644
--- a/packages/d110/dmvcframework_group.groupproj
+++ b/packages/d110/dmvcframework_group.groupproj
@@ -13,7 +13,7 @@
-
+ dmvcframeworkRT.dproj
@@ -50,13 +50,13 @@
-
+
-
+
-
+
diff --git a/samples/activerecord_showcase/EntitiesU.pas b/samples/activerecord_showcase/EntitiesU.pas
index 87f50c57..362aef5e 100644
--- a/samples/activerecord_showcase/EntitiesU.pas
+++ b/samples/activerecord_showcase/EntitiesU.pas
@@ -105,12 +105,15 @@ type
[MVCNameCase(ncLowerCase)]
[MVCTable('customers')]
+ [MVCNamedSQLQuery('BestCustomers', 'select * from customers where rating >=4')]
+ [MVCNamedSQLQuery('WithRatingGtOrEqTo', 'select * from customers where rating >=?')]
[MVCNamedSQLQuery('RatingLessThanPar', 'select * from customers where rating < ? order by code, city desc')]
[MVCNamedSQLQuery('RatingEqualsToPar', 'select /*firebird*/ * from customers where rating = ? order by code, city desc', TMVCActiveRecordBackEnd.FirebirdSQL)]
[MVCNamedSQLQuery('RatingEqualsToPar', 'select /*postgres*/ * from customers where rating = ? order by code, city desc', TMVCActiveRecordBackEnd.PostgreSQL)]
[MVCNamedSQLQuery('RatingEqualsToPar', 'select /*all*/ * from customers where rating = ? order by code, city desc')]
[MVCNamedRQLQuery('RatingLessThanPar', 'lt(rating,%d);sort(+code,-city)')]
[MVCNamedRQLQuery('RatingEqualsToPar', 'eq(rating,%d);sort(+code,-city)')]
+ [MVCNamedSQLQuery('GetAllCustomers', 'select * from sp_get_customers()', TMVCActiveRecordBackEnd.PostgreSQL)]
TCustomer = class(TCustomEntity)
private
{$IFNDEF USE_SEQUENCES}
diff --git a/samples/activerecord_showcase/MainFormU.pas b/samples/activerecord_showcase/MainFormU.pas
index 32e042ee..7ec62ea4 100644
--- a/samples/activerecord_showcase/MainFormU.pas
+++ b/samples/activerecord_showcase/MainFormU.pas
@@ -94,7 +94,7 @@ type
procedure btnIntegersAsBoolClick(Sender: TObject);
private
procedure Log(const Value: string);
- procedure LoadCustomers;
+ procedure LoadCustomers(const HowManyCustomers: Integer = 50);
public
{ Public declarations }
end;
@@ -712,8 +712,35 @@ end;
procedure TMainForm.btnNamedQueryClick(Sender: TObject);
begin
Log('** Named SQL Query');
+
+ LoadCustomers(10);
+
+ Log('QuerySQL: BestCustomers');
+ var lCustomers := TMVCActiveRecord.SelectByNamedQuery('BestCustomers', [], []);
+ try
+ for var lCustomer in lCustomers do
+ begin
+ Log(Format('%4d - %8.5s - %s', [lCustomer.ID.ValueOrDefault, lCustomer.Code.ValueOrDefault,
+ lCustomer.CompanyName.ValueOrDefault]));
+ end;
+ finally
+ lCustomers.Free;
+ end;
+
+ Log('QuerySQL: WithRatingGtOrEqTo');
+ lCustomers := TMVCActiveRecord.SelectByNamedQuery('WithRatingGtOrEqTo', [4], [ftInteger]);
+ try
+ for var lCustomer in lCustomers do
+ begin
+ Log(Format('%4d - %8.5s - %s', [lCustomer.ID.ValueOrDefault, lCustomer.Code.ValueOrDefault,
+ lCustomer.CompanyName.ValueOrDefault]));
+ end;
+ finally
+ lCustomers.Free;
+ end;
+
Log('QuerySQL: RatingLessThanPar');
- var lCustomers := TMVCActiveRecord.SelectByNamedQuery('RatingLessThanPar', [4], [ftInteger]);
+ lCustomers := TMVCActiveRecord.SelectByNamedQuery('RatingLessThanPar', [4], [ftInteger]);
try
for var lCustomer in lCustomers do
begin
@@ -749,6 +776,23 @@ begin
lCustomers.Free;
end;
+
+ var lTmpSQLQueryWithName: TSQLQueryWithName;
+ if TMVCActiveRecord.TryGetSQLQuery('GetAllCustomers', lTmpSQLQueryWithName) then
+ begin
+ Log('QuerySQL: Stored Procedure "GetAllCustomers"');
+ lCustomers := TMVCActiveRecord.SelectByNamedQuery('GetAllCustomers', [], [], [loIgnoreNotExistentFields]);
+ try
+ for var lCustomer in lCustomers do
+ begin
+ Log(Format('%4d - %8.5s - %s', [lCustomer.ID.ValueOrDefault, lCustomer.Code.ValueOrDefault,
+ lCustomer.CompanyName.ValueOrDefault]));
+ end;
+ finally
+ lCustomers.Free;
+ end;
+ end;
+
Log('** Named RQL Query');
Log('QueryRQL: RatingLessThanPar');
lCustomers := TMVCActiveRecord.SelectRQLByNamedQuery('RatingLessThanPar', [4], 1000);
@@ -774,7 +818,6 @@ begin
lCustomersList.Free;
end;
-
Log('QueryRQL: RatingEqualsToPar');
lCustomers := TMVCActiveRecord.SelectRQLByNamedQuery('RatingEqualsToPar', [3], 1000);
try
@@ -787,7 +830,16 @@ begin
lCustomers.Free;
end;
-
+ //RatingLessThanPar
+ var lTmpRQLQueryWithName: TRQLQueryWithName;
+ if TMVCActiveRecord.TryGetRQLQuery('RatingLessThanPar', lTmpRQLQueryWithName) then
+ begin
+ Log(Format('"%s" RQLQuery is available with text: %s', [lTmpRQLQueryWithName.Name, lTmpRQLQueryWithName.RQLText]));
+ end
+ else
+ begin
+ Log(Format('"%s" RQLQuery is not available', ['RatingLessThanPar']));
+ end;
end;
procedure TMainForm.btnNullablesClick(Sender: TObject);
@@ -2033,20 +2085,20 @@ begin
btnJSON_XML_Types.Enabled := ActiveRecordConnectionsRegistry.GetCurrentBackend = 'postgresql';
end;
-procedure TMainForm.LoadCustomers;
+procedure TMainForm.LoadCustomers(const HowManyCustomers: Integer = 50);
var
lCustomer: TCustomer;
I: Integer;
begin
TMVCActiveRecord.DeleteAll(TCustomer);
- for I := 1 to 50 do
+ for I := 1 to HowManyCustomers do
begin
lCustomer := TCustomer.Create;
try
lCustomer.CompanyName := Stuff[Random(4)] + ' ' + CompanySuffix[Random(5)];
lCustomer.Code := Random(100).ToString.PadLeft(5, '0');
lCustomer.City := Cities[Random(4)];
- lCustomer.Rating := Random(5);
+ lCustomer.Rating := I mod 6;
lCustomer.Note := Stuff[Random(4)];
lCustomer.Insert;
finally
diff --git a/samples/activerecord_showcase/activerecord_showcase.dproj b/samples/activerecord_showcase/activerecord_showcase.dproj
index c52c1bab..aaae4003 100644
--- a/samples/activerecord_showcase/activerecord_showcase.dproj
+++ b/samples/activerecord_showcase/activerecord_showcase.dproj
@@ -593,6 +593,197 @@
0
+
+
+ 1
+
+
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+
+
+ ..\
+ 1
+
+
+ ..\
+ 1
+
+
+ ..\
+ 1
+
+
+
+
+ Contents
+ 1
+
+
+ Contents
+ 1
+
+
+ Contents
+ 1
+
+
+
+
+ Contents\Resources
+ 1
+
+
+ Contents\Resources
+ 1
+
+
+ Contents\Resources
+ 1
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+ library\lib\arm64-v8a
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ Contents\MacOS
+ 1
+
+
+ Contents\MacOS
+ 1
+
+
+ Contents\MacOS
+ 1
+
+
+ 0
+
+
+
+
+ library\lib\armeabi-v7a
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
+
+
+
+ ..\
+ 1
+
+
+ ..\
+ 1
+
+
+ ..\
+ 1
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ ..\$(PROJECTNAME).launchscreen
+ 64
+
+
+ ..\$(PROJECTNAME).launchscreen
+ 64
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
+
+
+ Assets
+ 1
+
+
+ Assets
+ 1
+
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
@@ -793,197 +984,6 @@
1
-
-
- 1
-
-
- 1
-
-
-
-
- ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
- 1
-
-
- ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
- 1
-
-
- ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
- 1
-
-
-
-
- ..\
- 1
-
-
- ..\
- 1
-
-
- ..\
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- ..\$(PROJECTNAME).launchscreen
- 64
-
-
- ..\$(PROJECTNAME).launchscreen
- 64
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
- 1
-
-
- ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
- 1
-
-
-
-
- ..\
- 1
-
-
- ..\
- 1
-
-
- ..\
- 1
-
-
-
-
- Contents
- 1
-
-
- Contents
- 1
-
-
- Contents
- 1
-
-
-
-
- Contents\Resources
- 1
-
-
- Contents\Resources
- 1
-
-
- Contents\Resources
- 1
-
-
-
-
- library\lib\armeabi-v7a
- 1
-
-
- library\lib\arm64-v8a
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- Contents\MacOS
- 1
-
-
- Contents\MacOS
- 1
-
-
- Contents\MacOS
- 1
-
-
- 0
-
-
-
-
- library\lib\armeabi-v7a
- 1
-
-
-
-
- 1
-
-
- 1
-
-
-
-
- Assets
- 1
-
-
- Assets
- 1
-
-
-
-
- Assets
- 1
-
-
- Assets
- 1
-
-
diff --git a/samples/data/activerecorddb_postgresql_script.sql b/samples/data/activerecorddb_postgresql_script.sql
index 74786eab..7962fb46 100644
--- a/samples/data/activerecorddb_postgresql_script.sql
+++ b/samples/data/activerecorddb_postgresql_script.sql
@@ -598,3 +598,25 @@ ALTER TABLE ONLY public.phones
-- PostgreSQL database dump complete
--
+
+drop function if exists sp_get_customers;
+create or replace function sp_get_customers() returns table(
+ id bigint,
+ code varchar,
+ description varchar,
+ city varchar,
+ rating integer)
+language plpgsql
+as
+$$
+begin
+ return query
+ select
+ c.id, c.code, c.description, c.city, c.rating
+ from
+ customers c
+ order by c.description;
+end
+$$;
+
+select * from sp_get_customers();
\ No newline at end of file
diff --git a/samples/funcion_actions_showcase/ControllerU.pas b/samples/functional_actions_showcase/ControllerU.pas
similarity index 100%
rename from samples/funcion_actions_showcase/ControllerU.pas
rename to samples/functional_actions_showcase/ControllerU.pas
index e09b672a..6f8b3bef 100644
--- a/samples/funcion_actions_showcase/ControllerU.pas
+++ b/samples/functional_actions_showcase/ControllerU.pas
@@ -102,6 +102,17 @@ begin
Result := StrToJSONObject('{"name":"Daniele","surname":"Teti"}');
end;
+function TMyController.GetSingleDataSet: TDataSet;
+begin
+ var lDM := TdmMain.Create(nil);
+ try
+ lDM.dsPeople.Open;
+ Result := TFDMemTable.CloneFrom(lDM.dsPeople);
+ finally
+ lDM.Free;
+ end;
+end;
+
function TMyController.GetMultipleDataSet: TEnumerable;
begin
var lDM := TdmMain.Create(nil);
@@ -234,17 +245,6 @@ begin
.Build;
end;
-function TMyController.GetSingleDataSet: TDataSet;
-begin
- var lDM := TdmMain.Create(nil);
- try
- lDM.dsPeople.Open;
- Result := TFDMemTable.CloneFrom(lDM.dsPeople);
- finally
- lDM.Free;
- end;
-end;
-
function TMyController.GetSingleObject: TPerson;
begin
Result := TPerson.Create('Daniele', 'Teti', YearsBetween(Date, EncodeDateDay(1979, 1)));
diff --git a/samples/funcion_actions_showcase/MainDMU.dfm b/samples/functional_actions_showcase/MainDMU.dfm
similarity index 100%
rename from samples/funcion_actions_showcase/MainDMU.dfm
rename to samples/functional_actions_showcase/MainDMU.dfm
diff --git a/samples/funcion_actions_showcase/MainDMU.pas b/samples/functional_actions_showcase/MainDMU.pas
similarity index 100%
rename from samples/funcion_actions_showcase/MainDMU.pas
rename to samples/functional_actions_showcase/MainDMU.pas
diff --git a/samples/funcion_actions_showcase/WebModuleU.dfm b/samples/functional_actions_showcase/WebModuleU.dfm
similarity index 100%
rename from samples/funcion_actions_showcase/WebModuleU.dfm
rename to samples/functional_actions_showcase/WebModuleU.dfm
diff --git a/samples/funcion_actions_showcase/WebModuleU.pas b/samples/functional_actions_showcase/WebModuleU.pas
similarity index 100%
rename from samples/funcion_actions_showcase/WebModuleU.pas
rename to samples/functional_actions_showcase/WebModuleU.pas
diff --git a/samples/funcion_actions_showcase/function_actions_showcase.dpr b/samples/functional_actions_showcase/function_actions_showcase.dpr
similarity index 100%
rename from samples/funcion_actions_showcase/function_actions_showcase.dpr
rename to samples/functional_actions_showcase/function_actions_showcase.dpr
diff --git a/samples/funcion_actions_showcase/function_actions_showcase.dproj b/samples/functional_actions_showcase/function_actions_showcase.dproj
similarity index 100%
rename from samples/funcion_actions_showcase/function_actions_showcase.dproj
rename to samples/functional_actions_showcase/function_actions_showcase.dproj