diff --git a/README.md b/README.md
index c37c08c6..bd6d2062 100644
--- a/README.md
+++ b/README.md
@@ -269,13 +269,13 @@ Congratulations to Daniele Teti and all the staff for the excellent work!" -- Ma
- ✅ Improved! The unit tests fully test PostgreSQL, FirebirdSQL and SQLite while testing MVCActiveRecord framework. The other engines are tested using `activerecord_showcase` sample project.
-- ✅ Improved! MVCActiveRecord doeas a better job to handle TDate/TTime/TDateTime types for SQLite (it is automatic because SQLite doesn't support date/time types).
+- ✅ Improved! MVCActiveRecord does a better job to handle TDate/TTime/TDateTime types for SQLite (it is automatic because SQLite doesn't support date/time types).
- ✅ Improved! PostgreSQL, FirebirdSQL, Interbase and SQLite now support tablename and fields with spaces.
- ✅ Improved Nullable Types. Now it's possible to assign `nil` to a nullable type and to check its state using the new property `IsNull` which is the negation of the already available property `HasValue`.
-- ✅ Improved! Now `TMVCStaticFileMiddleware` is able to manage high-level criteria to show/hide/mask specific files in the documetn web root. Check [Issue 548](https://github.com/danieleteti/delphimvcframework/issues/548) and the updated sample `samples\middleware_staticfiles\` for more info.
+- ✅ Improved! Now `TMVCStaticFileMiddleware` is able to manage high-level criteria to show/hide/mask specific files in the document web root. Check [Issue 548](https://github.com/danieleteti/delphimvcframework/issues/548) and the updated sample `samples\middleware_staticfiles\` for more info.
- ✅ Improved! In case of multiple MVCPath, Swagger consider only the first one (Thanks to V. Ferri and our sponsors)
@@ -1415,6 +1415,11 @@ The current beta release is named 3.2.3-radium-beta. If you want to stay on the-
### What's New in 3.2.3-radium-beta
- Fixed a rendering problem in swagger interface format in case of specific JSON structure
+- Default error responses contains the official "reason string" associated to the HTTP status code (this can be a breaking change for some generic client which doesn't correctly interpret the http status code)
+- Added static method `HTTP_STATUS.ReasonStringFor(HTTPStatusCode)` wich returns the standard `ReasonString` for a given HTTP status code.
+- Improved handling of `TMVCErrorResponse` information
+- mid-air-collision handling now uses SHA1 instead of MD5
+- Added `MVCFramework.Commons.MVC_HTTP_STATUS_CODES` const array containing all the HTTP status codes wich its `ReasonString`
## Trainings, consultancy or custom development service
diff --git a/samples/activerecord_restful_crud/Entities.pas b/samples/activerecord_restful_crud/Entities.pas
index 653e6d54..42e9e1a4 100644
--- a/samples/activerecord_restful_crud/Entities.pas
+++ b/samples/activerecord_restful_crud/Entities.pas
@@ -7,7 +7,10 @@ uses
MVCFramework.ActiveRecord,
MVCFramework.Nullables,
System.Classes,
- MVCFramework, System.Generics.Collections;
+ System.DateUtils,
+ MVCFramework,
+ MVCFramework.Utils,
+ System.Generics.Collections;
type
@@ -51,6 +54,8 @@ type
public
constructor Create; override;
destructor Destroy; override;
+ function GetUniqueString: String;
+ procedure Assign(ActiveRecord: TMVCActiveRecord); override;
property ID: Int64 read fID write SetID;
[MVCNameAs('person_surname')]
property LastName: string read fLastName write SetLastName;
@@ -119,11 +124,28 @@ type
implementation
uses
- System.DateUtils,
System.SysUtils;
{ TPersona }
+procedure TPerson.Assign(ActiveRecord: TMVCActiveRecord);
+begin
+ if ActiveRecord is TPerson then
+ begin
+ var lPerson := TPerson(ActiveRecord);
+ Self.LastName := lPerson.LastName;
+ Self.FirstName := lPerson.FirstName;
+ Self.DOB := lPerson.DOB;
+ Self.IsMale := lPerson.IsMale;
+ Self.Note := lPerson.Note;
+ Self.Photo.Size := 0;
+ Self.Photo.CopyFrom(lPerson.Photo);
+ Self.Photo.Position := 0;
+ end
+ else
+ inherited;
+end;
+
constructor TPerson.Create;
begin
inherited;
@@ -141,6 +163,17 @@ begin
Result := fFullName;
end;
+function TPerson.GetUniqueString: String;
+begin
+ Result :=
+ fID.ToString + '|' +
+ fFirstName + '|' +
+ fLastName + '|' +
+ DateToISODate(fDOB.ValueOrDefault) + '|' +
+ BoolToStr(fIsMale.ValueOrDefault, True) + '|' +
+ GetSHA1HashFromStream(fPhoto);
+end;
+
procedure TPerson.OnAfterLoad;
begin
inherited;
@@ -157,7 +190,6 @@ end;
procedure TPerson.OnBeforeInsert;
begin
inherited;
- // TMemoryStream(fPhoto).LoadFromFile('C:\DEV\dmvcframework\samples\_\customer_small.png');
end;
procedure TPerson.OnBeforeInsertOrUpdate;
diff --git a/samples/activerecord_restful_crud/activerecord_restful_crud.dpr b/samples/activerecord_restful_crud/activerecord_restful_crud.dpr
index d3492b1c..33f6da6d 100644
--- a/samples/activerecord_restful_crud/activerecord_restful_crud.dpr
+++ b/samples/activerecord_restful_crud/activerecord_restful_crud.dpr
@@ -67,6 +67,7 @@ begin
lServer.MaxConnections := 0;
lServer.ListenQueue := 200;
lServer.Active := True;
+ WriteLn('Running on port ', APort);
Write('CTRL+C to Quit');
WaitForTerminationSignal;
finally
diff --git a/samples/activerecord_restful_crud/activerecord_restful_crud.dproj b/samples/activerecord_restful_crud/activerecord_restful_crud.dproj
index e55877a0..aa8d9b92 100644
--- a/samples/activerecord_restful_crud/activerecord_restful_crud.dproj
+++ b/samples/activerecord_restful_crud/activerecord_restful_crud.dproj
@@ -7,7 +7,7 @@
32897
Console
None
- 19.4
+ 19.5
Win32
@@ -183,7 +183,7 @@
True
False
-
+
true
@@ -199,12 +199,7 @@
true
-
-
- activerecord_restful_crud.exe
- true
-
-
+
1
@@ -223,16 +218,6 @@
64
-
-
- classes
- 1
-
-
- classes
- 1
-
-
res\xml
@@ -556,7 +541,7 @@
1
.dylib
-
+
1
.dylib
@@ -590,7 +575,7 @@
0
-
+
0
@@ -611,13 +596,17 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -627,137 +616,27 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -767,7 +646,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -777,7 +656,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -787,7 +666,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -797,7 +676,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -807,191 +686,37 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -1001,7 +726,7 @@
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -1011,7 +736,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1021,7 +746,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1031,7 +756,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1041,7 +766,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1051,7 +776,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1061,7 +786,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1083,8 +808,11 @@
..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
1
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
-
@@ -1095,7 +823,7 @@
1
-
+
1
@@ -1131,7 +859,7 @@
1
-
+
1
@@ -1188,6 +916,7 @@
+
diff --git a/samples/articles_crud_server/articles_crud.dproj b/samples/articles_crud_server/articles_crud.dproj
index 8d863706..9b745001 100644
--- a/samples/articles_crud_server/articles_crud.dproj
+++ b/samples/articles_crud_server/articles_crud.dproj
@@ -1,7 +1,7 @@
{41237016-48D9-45F1-8FFC-66D1B61A206B}
- 19.4
+ 19.5
VCL
articles_crud.dpr
True
@@ -163,181 +163,36 @@
Embarcadero C++Builder Office XP Servers Package
-
-
-
- articles_crud.exe
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
-
-
- .\
- true
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
1
@@ -356,16 +211,6 @@
64
-
-
- classes
- 1
-
-
- classes
- 1
-
-
res\xml
@@ -408,7 +253,6 @@
1
-
library\lib\armeabi-v7a
@@ -690,7 +534,7 @@
1
.dylib
-
+
1
.dylib
@@ -724,7 +568,7 @@
0
-
+
0
@@ -745,13 +589,17 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -761,181 +609,27 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -945,7 +639,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -955,7 +649,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -965,7 +659,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -975,7 +669,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -985,191 +679,37 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -1179,7 +719,7 @@
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -1189,7 +729,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1199,7 +739,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1209,7 +749,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1219,7 +759,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1229,7 +769,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1239,7 +779,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1261,8 +801,11 @@
..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
1
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
-
@@ -1273,7 +816,7 @@
1
-
+
1
@@ -1309,7 +852,7 @@
1
-
+
1
@@ -1366,6 +909,7 @@
+
diff --git a/samples/avoid_mid_air_collisions_sample/MainControllerU.pas b/samples/avoid_mid_air_collisions_sample/MainControllerU.pas
index d2083c08..891f5fe3 100644
--- a/samples/avoid_mid_air_collisions_sample/MainControllerU.pas
+++ b/samples/avoid_mid_air_collisions_sample/MainControllerU.pas
@@ -3,35 +3,17 @@ unit MainControllerU;
interface
uses
- MVCFramework, MVCFramework.Commons, MVCFramework.Serializer.Commons;
+ MVCFramework, MVCFramework.Commons, MVCFramework.Serializer.Commons, Entities;
type
- [MVCNameCase(ncCamelCase)]
- TPerson = class
- private
- fName: String;
- fSurname: String;
- fID: Integer;
- public
- function GetHash: String;
- class function GetNew(const id: Integer; const Name, Surname: String): TPerson;
- property ID: Integer read fID write fID;
- property Name: String read fName write fName;
- property Surname: String read fSurname write fSurname;
- end;
-
-
[MVCPath('/api/people')]
TMyController = class(TMVCController)
- private
- function GetPersonByID(const ID: Integer): TPerson;
- procedure UpdatePersonByID(const ID: Integer; const Person: TPerson);
public
[MVCPath]
[MVCHTTPMethod([httpGET])]
- procedure Index;
- public
- // Sample CRUD Actions for a "person" entity
+ procedure GetPeople;
+
+
[MVCPath('/($id)')]
[MVCHTTPMethod([httpGET])]
procedure Getperson(id: Integer);
@@ -55,37 +37,19 @@ implementation
uses
System.SysUtils, MVCFramework.Logger, System.StrUtils, MVCFramework.Cache,
- System.Rtti, MVCFramework.Rtti.Utils;
+ System.Rtti, MVCFramework.Rtti.Utils, MVCFramework.ActiveRecord;
-procedure TMyController.Index;
+procedure TMyController.GetPeople;
begin
- // use Context property to access to the HTTP request and response
- Render('Hello DelphiMVCFramework World');
-end;
-
-function TMyController.GetPersonByID(const ID: Integer): TPerson;
-var
- lPerson: TPerson;
-begin
- lPerson := nil;
- if not TMVCCacheSingleton.Instance.ExecOnItemWithWriteLock(id.ToString,
- procedure(Value: TValue)
- begin
- lPerson := TRttiUtils.Clone(Value.AsObject) as TPerson;
- end) then
- begin
- raise EMVCException.Create(HTTP_STATUS.NotFound, 'Person not found');
- end;
- Result := lPerson;
+ Render(ObjectDict().Add('people', TMVCActiveRecord.All));
end;
procedure TMyController.Getperson(id: Integer);
var
- lItem: TMVCCacheItem;
lPerson: TPerson;
begin
- lPerson := GetPersonByID(id);
- SetETag(lPerson.GetHash);
+ lPerson := TMVCActiveRecord.GetByPK(ID);
+ SetETag(lPerson.GetUniqueString);
Render(lPerson, True);
end;
@@ -111,57 +75,43 @@ end;
procedure TMyController.UpdatePerson(id: Integer; [MVCFromBody] const Person: TPerson);
var
- lItem: TMVCCacheItem;
lPerson: TPerson;
begin
// retrieve data from storage
- lPerson := GetPersonByID(id);
+ lPerson := TMVCActiveRecord.GetByPK(ID);
+ try
+ //check if the client modified the current version (a.k.a. mid-air collisions)
+ //raises an exception if client send a wrong If-Match header value
+ CheckIfMatch(lPerson.GetUniqueString);
- //check if the client modified the current version (a.k.a. mid-air collisions)
- //raises an exception if client send a wrong If-Match header value
- CheckIfMatch(lPerson.GetHash);
+ //perform the actual update and save to the storage
+ lPerson.Assign(Person);
+ lPerson.Update();
- //perform the actual update and save to the storage
- lPerson.Name := Person.Name;
- lPerson.Surname := Person.Surname;
- UpdatePersonByID(lPerson.ID, lPerson);
+ //set the new ETag value base on the data status
+ SetETag(lPerson.GetUniqueString);
- //set the new ETag value base on the data status
- SetETag(lPerson.GetHash);
-
- //reply with a 200 OK
- Render(HTTP_STATUS.OK);
+ //reply with a 200 OK
+ Render(HTTP_STATUS.OK);
+ finally
+ lPerson.Free;
+ end;
end;
-procedure TMyController.UpdatePersonByID(const ID: Integer;
- const Person: TPerson);
-begin
- TMVCCacheSingleton.Instance.SetValue(ID.ToString, Person);
-end;
procedure TMyController.DeletePerson(id: Integer);
var
lPerson: TPerson;
begin
- lPerson := GetPersonByID(ID);
- CheckIfMatch(lPerson.GetHash);
- TMVCCacheSingleton.Instance.RemoveItem(ID.ToString);
- Render204NoContent();
-end;
-
-{ TPerson }
-
-function TPerson.GetHash: String;
-begin
- Result := Format('%d|%s|%s', [fID, fName, fSurname]);
-end;
-
-class function TPerson.GetNew(const id: Integer; const Name, Surname: String): TPerson;
-begin
- Result := TPerson.Create;
- Result.fID := id;
- Result.fName := Name;
- Result.fSurname := Surname;
+ lPerson := TMVCActiveRecord.GetByPK(ID);
+ try
+ CheckIfMatch(lPerson.GetUniqueString);
+ lPerson.Delete();
+ Render204NoContent();
+ except
+ lPerson.Free;
+ raise;
+ end;
end;
end.
diff --git a/samples/avoid_mid_air_collisions_sample/WebModuleU.pas b/samples/avoid_mid_air_collisions_sample/WebModuleU.pas
index fdb73ef0..c8db1d7b 100644
--- a/samples/avoid_mid_air_collisions_sample/WebModuleU.pas
+++ b/samples/avoid_mid_air_collisions_sample/WebModuleU.pas
@@ -81,17 +81,18 @@ begin
// CORS middleware handles... well, CORS
//FMVC.AddMiddleware(TMVCCORSMiddleware.Create);
-
+
// Simplifies TMVCActiveRecord connection definition
- //FMVC.AddMiddleware(TMVCActiveRecordMiddleware.Create('MyConnDef','FDConnectionDefs.ini'));
-
+ FMVC.AddMiddleware(TMVCActiveRecordMiddleware.Create('activerecorddb'));
+
+
// Compression middleware must be the last in the chain, just before the ETag, if present.
//FMVC.AddMiddleware(TMVCCompressionMiddleware.Create);
-
+
// ETag middleware must be the latest in the chain
//FMVC.AddMiddleware(TMVCETagMiddleware.Create);
-
-
+
+
end;
procedure TMyWebModule.WebModuleDestroy(Sender: TObject);
diff --git a/samples/avoid_mid_air_collisions_sample/avoid_mid_air_collisions_sample.dpr b/samples/avoid_mid_air_collisions_sample/avoid_mid_air_collisions_sample.dpr
index 42ebde84..fd354656 100644
--- a/samples/avoid_mid_air_collisions_sample/avoid_mid_air_collisions_sample.dpr
+++ b/samples/avoid_mid_air_collisions_sample/avoid_mid_air_collisions_sample.dpr
@@ -13,10 +13,32 @@ uses
Web.WebReq,
Web.WebBroker,
IdContext,
+ FireDAC.Stan.Intf,
+ FireDAC.Stan.Option,
+ FireDAC.Stan.Error,
+ FireDAC.UI.Intf,
+ FireDAC.Phys.Intf,
+ FireDAC.Stan.Def,
+ FireDAC.Stan.Pool,
+ FireDAC.Stan.Async,
+ FireDAC.Phys,
+ FireDAC.Phys.MySQL,
+ FireDAC.Phys.MySQLDef,
+ FireDAC.VCLUI.Wait,
+ Data.DB,
+ FireDAC.Comp.Client,
+ FireDAC.Stan.Param,
+ FireDAC.DatS,
+ FireDAC.DApt.Intf,
+ FireDAC.DApt,
+ FireDAC.Comp.DataSet,
+ MVCFramework.SQLGenerators.PostgreSQL,
IdHTTPWebBrokerBridge,
MainControllerU in 'MainControllerU.pas',
WebModuleU in 'WebModuleU.pas' {MyWebModule: TWebModule},
- MVCFramework.Utils in '..\..\sources\MVCFramework.Utils.pas';
+ MVCFramework.Utils in '..\..\sources\MVCFramework.Utils.pas',
+ Entities in '..\activerecord_restful_crud\Entities.pas',
+ MVCFramework.ActiveRecord;
{$R *.res}
@@ -53,10 +75,46 @@ end;
procedure LoadFakeData;
begin
- TMVCCacheSingleton.Instance.SetValue('1', TPerson.GetNew(1, 'Daniele','Teti'));
- TMVCCacheSingleton.Instance.SetValue('2', TPerson.GetNew(2, 'Peter','Parker'));
- TMVCCacheSingleton.Instance.SetValue('3', TPerson.GetNew(3, 'Bruce','Banner'));
- TMVCCacheSingleton.Instance.SetValue('4', TPerson.GetNew(4, 'Sue','Storm'));
+ ActiveRecordConnectionsRegistry.AddDefaultConnection('activerecorddb');
+ try
+ TMVCActiveRecord.DeleteAll(TPerson);
+
+ with TPerson.Create do
+ try
+ FirstName := 'Daniele';
+ LastName := 'Teti';
+ DOB := nil;
+ IsMale := True;
+ Insert;
+ finally
+ Free;
+ end;
+
+ with TPerson.Create do
+ try
+ FirstName := 'Peter';
+ LastName := 'Parker';
+ DOB := EncodeDate(1960,10,11);
+ IsMale := True;
+ Insert;
+ finally
+ Free;
+ end;
+
+ with TPerson.Create do
+ try
+ FirstName := 'Sue';
+ LastName := 'Storm';
+ DOB := EncodeDate(1970,2,11);
+ IsMale := False;
+ Insert;
+ finally
+ Free;
+ end;
+
+ finally
+ ActiveRecordConnectionsRegistry.RemoveDefaultConnection();
+ end;
end;
begin
diff --git a/samples/avoid_mid_air_collisions_sample/avoid_mid_air_collisions_sample.dproj b/samples/avoid_mid_air_collisions_sample/avoid_mid_air_collisions_sample.dproj
index a2a7849b..f41d734a 100644
--- a/samples/avoid_mid_air_collisions_sample/avoid_mid_air_collisions_sample.dproj
+++ b/samples/avoid_mid_air_collisions_sample/avoid_mid_air_collisions_sample.dproj
@@ -1,7 +1,7 @@
{03D8066E-D767-4E59-8D05-7C3341BECDFC}
- 19.4
+ 19.5
None
True
Debug
@@ -126,6 +126,7 @@
TWebModule
+
Base
@@ -153,7 +154,7 @@
Embarcadero C++Builder Office XP Servers Package
-
+
true
@@ -516,7 +517,7 @@
1
.dylib
-
+
1
.dylib
@@ -550,7 +551,7 @@
0
-
+
0
@@ -571,13 +572,17 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -587,7 +592,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -597,7 +602,7 @@
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -607,7 +612,7 @@
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -617,7 +622,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -627,7 +632,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -637,7 +642,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -647,7 +652,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -657,7 +662,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -667,7 +672,7 @@
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -677,7 +682,7 @@
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -687,7 +692,7 @@
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -697,7 +702,7 @@
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -707,7 +712,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -717,7 +722,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -727,7 +732,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -737,7 +742,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -747,7 +752,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -757,7 +762,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -779,6 +784,10 @@
..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
1
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
@@ -790,7 +799,7 @@
1
-
+
1
@@ -826,7 +835,7 @@
1
-
+
1
@@ -883,6 +892,7 @@
+
diff --git a/samples/middleware_activerecord/MainControllerU.pas b/samples/middleware_activerecord/MainControllerU.pas
index 017805da..0130549d 100644
--- a/samples/middleware_activerecord/MainControllerU.pas
+++ b/samples/middleware_activerecord/MainControllerU.pas
@@ -27,8 +27,8 @@ uses
procedure TMyController.Index;
begin
Render(ObjectDict().Add('people',
- TMVCActiveRecord.SelectRQL('and(gt(id, 2),lt(id,6))', 100)
- //TMVCActiveRecord.All
+ //TMVCActiveRecord.SelectRQL('and(gt(id, 2),lt(id,6))', 100)
+ TMVCActiveRecord.SelectRQL('sort(+personSurname)', 10)
));
end;
diff --git a/samples/middleware_activerecord/middleware_activerecord.dproj b/samples/middleware_activerecord/middleware_activerecord.dproj
index 5bb434d9..01badd12 100644
--- a/samples/middleware_activerecord/middleware_activerecord.dproj
+++ b/samples/middleware_activerecord/middleware_activerecord.dproj
@@ -1,7 +1,7 @@
{0BE611DE-35B1-4B03-8B00-181E5DBFFF4A}
- 19.4
+ 19.5
None
True
Debug
@@ -153,7 +153,7 @@
Embarcadero C++Builder Office XP Servers Package
-
+
true
@@ -169,12 +169,7 @@
true
-
-
- middleware_activerecord.exe
- true
-
-
+
1
@@ -516,7 +511,7 @@
1
.dylib
-
+
1
.dylib
@@ -550,7 +545,7 @@
0
-
+
0
@@ -571,13 +566,17 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -587,7 +586,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -597,7 +596,7 @@
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -607,7 +606,7 @@
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -617,7 +616,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -627,7 +626,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -637,7 +636,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -647,7 +646,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -657,7 +656,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -667,7 +666,7 @@
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -677,7 +676,7 @@
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -687,7 +686,7 @@
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -697,7 +696,7 @@
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -707,7 +706,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -717,7 +716,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -727,7 +726,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -737,7 +736,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -747,7 +746,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -757,7 +756,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -779,6 +778,10 @@
..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
1
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
@@ -790,7 +793,7 @@
1
-
+
1
@@ -826,7 +829,7 @@
1
-
+
1
@@ -883,6 +886,7 @@
+
diff --git a/samples/renders/renders.dproj b/samples/renders/renders.dproj
index a89dbcd8..64c973ee 100644
--- a/samples/renders/renders.dproj
+++ b/samples/renders/renders.dproj
@@ -1,7 +1,7 @@
{8CCDACDA-3FA5-486E-AD8E-63E4113177EE}
- 19.4
+ 19.5
None
renders.dpr
True
@@ -214,55 +214,28 @@
Microsoft Office XP Sample Automation Server Wrapper Components
-
+
true
-
-
- true
-
-
true
-
-
- true
-
-
+
+
true
-
-
- true
-
-
-
-
- renders.exe
- true
-
-
-
-
- renders.exe
- true
-
-
-
-
- renders
- true
-
-
+
+
+
+
1
@@ -281,16 +254,6 @@
64
-
-
- classes
- 1
-
-
- classes
- 1
-
-
res\xml
@@ -333,7 +296,6 @@
1
-
library\lib\armeabi-v7a
@@ -615,7 +577,7 @@
1
.dylib
-
+
1
.dylib
@@ -649,7 +611,7 @@
0
-
+
0
@@ -670,13 +632,17 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -686,181 +652,27 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -870,7 +682,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -880,7 +692,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -890,7 +702,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -900,7 +712,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -910,191 +722,37 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -1104,7 +762,7 @@
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -1114,7 +772,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1124,7 +782,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1134,7 +792,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1144,7 +802,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1154,7 +812,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1164,7 +822,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1186,8 +844,11 @@
..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
1
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
-
@@ -1198,7 +859,7 @@
1
-
+
1
@@ -1234,7 +895,7 @@
1
-
+
1
@@ -1291,6 +952,7 @@
+
diff --git a/sources/MVCFramework.Commons.pas b/sources/MVCFramework.Commons.pas
index b5aea1dc..f172fbc0 100644
--- a/sources/MVCFramework.Commons.pas
+++ b/sources/MVCFramework.Commons.pas
@@ -352,6 +352,11 @@ type
/// request MUST NOT be repeated until it is requested by a separate user action.
///
InsufficientStorage = 507;
+
+ ///
+ /// Returns standard ReasonString for a given HTTP status code
+ ///
+ class function ReasonStringFor(const HTTPStatusCode: Integer): String; static;
end;
EMVCException = class(Exception)
@@ -608,6 +613,11 @@ type
{$SCOPEDENUMS ON}
TMVCCompressionType = (ctNone, ctDeflate, ctGZIP);
+ TMVCHTTPStatusCode = record
+ Code: Integer;
+ ReasonString: String;
+ end;
+
{ GENERIC TYPE ALIASES }
TMVCListOfString = TList;
@@ -677,6 +687,71 @@ const
('224.0.0.0', '239.255.255.255'),
('240.0.0.0', '255.255.255.255'));
+
+const
+ MVC_HTTP_STATUS_CODES: array [0..57] of TMVCHTTPStatusCode =
+ (
+ (Code: 100; ReasonString: 'Continue'),
+ (Code: 101; ReasonString: 'Switching Protocols'),
+ (Code: 102; ReasonString: 'Processing'),
+ (Code: 200; ReasonString: 'OK'),
+ (Code: 201; ReasonString: 'Created'),
+ (Code: 202; ReasonString: 'Accepted'),
+ (Code: 203; ReasonString: 'Non-Authoritative Information'),
+ (Code: 204; ReasonString: 'No Content'),
+ (Code: 205; ReasonString: 'Reset Content'),
+ (Code: 206; ReasonString: 'Partial Content'),
+ (Code: 207; ReasonString: 'Multi-Status'),
+ (Code: 208; ReasonString: 'Already Reported'),
+ (Code: 226; ReasonString: 'IM Used'),
+ (Code: 300; ReasonString: 'Multiple Choices'),
+ (Code: 301; ReasonString: 'Moved Permanently'),
+ (Code: 302; ReasonString: 'Found'),
+ (Code: 303; ReasonString: 'See Other'),
+ (Code: 304; ReasonString: 'Not Modified'),
+ (Code: 305; ReasonString: 'Use Proxy'),
+ (Code: 306; ReasonString: 'Reserved'),
+ (Code: 307; ReasonString: 'Temporary Redirect'),
+ (Code: 308; ReasonString: 'Permanent Redirect'),
+ (Code: 400; ReasonString: 'Bad Request'),
+ (Code: 401; ReasonString: 'Unauthorized'),
+ (Code: 402; ReasonString: 'Payment Required'),
+ (Code: 403; ReasonString: 'Forbidden'),
+ (Code: 404; ReasonString: 'Not Found'),
+ (Code: 405; ReasonString: 'Method Not Allowed'),
+ (Code: 406; ReasonString: 'Not Acceptable'),
+ (Code: 407; ReasonString: 'Proxy Authentication Required'),
+ (Code: 408; ReasonString: 'Request Timeout'),
+ (Code: 409; ReasonString: 'Conflict'),
+ (Code: 410; ReasonString: 'Gone'),
+ (Code: 411; ReasonString: 'Length Required'),
+ (Code: 412; ReasonString: 'Precondition Failed'),
+ (Code: 413; ReasonString: 'Request Entity Too Large'),
+ (Code: 414; ReasonString: 'Request-URI Too Long'),
+ (Code: 415; ReasonString: 'Unsupported Media Type'),
+ (Code: 416; ReasonString: 'Requested Range Not Satisfiable'),
+ (Code: 417; ReasonString: 'Expectation Failed'),
+ (Code: 422; ReasonString: 'Unprocessable Entity'),
+ (Code: 423; ReasonString: 'Locked'),
+ (Code: 424; ReasonString: 'Failed Dependency'),
+ (Code: 426; ReasonString: 'Upgrade Required'),
+ (Code: 428; ReasonString: 'Precondition Required'),
+ (Code: 429; ReasonString: 'Too Many Requests'),
+ (Code: 431; ReasonString: 'Request Header Fields Too Large'),
+ (Code: 500; ReasonString: 'Internal Server Error'),
+ (Code: 501; ReasonString: 'Not Implemented'),
+ (Code: 502; ReasonString: 'Bad Gateway'),
+ (Code: 503; ReasonString: 'Service Unavailable'),
+ (Code: 504; ReasonString: 'Gateway Timeout'),
+ (Code: 505; ReasonString: 'HTTP Version Not Supported'),
+ (Code: 506; ReasonString: 'Variant Also Negotiates (Experimental)'),
+ (Code: 507; ReasonString: 'Insufficient Storage'),
+ (Code: 508; ReasonString: 'Loop Detected'),
+ (Code: 510; ReasonString: 'Not Extended'),
+ (Code: 511; ReasonString: 'Network Authentication Required')
+ );
+
+
type
TMVCParseAuthentication = class
public
@@ -1616,6 +1691,27 @@ begin
end;
+function ReasonStringByHTTPStatusCode(const HTTPStatusCode: Integer): String;
+var
+ I: Integer;
+begin
+ for I := Low(MVC_HTTP_STATUS_CODES) to High(MVC_HTTP_STATUS_CODES) do
+ begin
+ if MVC_HTTP_STATUS_CODES[I].Code = HTTPStatusCode then
+ begin
+ Exit(MVC_HTTP_STATUS_CODES[I].ReasonString);
+ end;
+ end;
+ raise EMVCException.Create('Invalid HTTP status code: ' + IntToStr(HTTPStatusCode));
+end;
+
+{ HTTP_STATUS }
+
+class function HTTP_STATUS.ReasonStringFor(const HTTPStatusCode: Integer): String;
+begin
+ Result := ReasonStringByHTTPStatusCode(HTTPStatusCode);
+end;
+
initialization
gLock := TObject.Create;
diff --git a/sources/MVCFramework.Middleware.ActiveRecord.pas b/sources/MVCFramework.Middleware.ActiveRecord.pas
index 87e4b439..6e1eb20e 100644
--- a/sources/MVCFramework.Middleware.ActiveRecord.pas
+++ b/sources/MVCFramework.Middleware.ActiveRecord.pas
@@ -112,7 +112,10 @@ begin
begin
FDManager.ConnectionDefFileAutoLoad := False;
FDManager.ConnectionDefFileName := fConnectionDefFileName;
- FDManager.LoadConnectionDefFile;
+ if not FDManager.ConnectionDefFileLoaded then
+ begin
+ FDManager.LoadConnectionDefFile;
+ end;
if not FDManager.IsConnectionDef(fConnectionDefName) then
begin
raise EMVCConfigException.CreateFmt('ConnectionDefName "%s" not found in config file "%s"',
diff --git a/sources/MVCFramework.Serializer.JsonDataObjects.pas b/sources/MVCFramework.Serializer.JsonDataObjects.pas
index 1394aeb5..ac232e70 100644
--- a/sources/MVCFramework.Serializer.JsonDataObjects.pas
+++ b/sources/MVCFramework.Serializer.JsonDataObjects.pas
@@ -1391,14 +1391,21 @@ begin
if lOwnedAttribute.ClassRef <> nil then
begin
ChildObject := TMVCSerializerHelper.CreateObject(lOwnedAttribute.ClassRef.QualifiedClassName);
+ AValue := ChildObject; //dt20221006
end
else
begin
case AType of
stUnknown, stDefault, stProperties:
+ begin
ChildObject := TMVCSerializerHelper.CreateObject(TRttiProperty(ARttiMember).PropertyType);
+ AValue := ChildObject; //dt20221006
+ end;
stFields:
+ begin
ChildObject := TMVCSerializerHelper.CreateObject(TRttiField(ARttiMember).FieldType);
+ AValue := ChildObject; //dt20221006
+ end;
end;
end;
lTypeInfo := ChildObject.ClassInfo;
diff --git a/sources/MVCFramework.Utils.pas b/sources/MVCFramework.Utils.pas
index 3597016f..26cd0c00 100644
--- a/sources/MVCFramework.Utils.pas
+++ b/sources/MVCFramework.Utils.pas
@@ -24,6 +24,8 @@
unit MVCFramework.Utils;
+{$I dmvcframework.inc}
+
interface
uses
@@ -37,6 +39,8 @@ function StrToJSONArray(const aString: String; ARaiseExceptionOnError: Boolean =
function WrapAsList(const AObject: TObject; AOwnsObject: Boolean = False): IMVCList;
function GetMD5HashFromStream(AStream: TStream): string;
function GetMD5HashFromString(const AString: String): string;
+function GetSHA1HashFromString(const AString: String): string;
+function GetSHA1HashFromStream(AStream: TStream): string;
implementation
@@ -45,6 +49,7 @@ uses
System.Hash,
{$ELSE}
IdHashMessageDigest,
+ IdHashSHA,
{$ENDIF}
MVCFramework.Serializer.JsonDataObjects,
MVCFramework.Commons,
@@ -69,6 +74,24 @@ begin
{$ENDIF}
end;
+function GetSHA1HashFromStream(AStream: TStream): string;
+{$IF not defined(TOKYOORBETTER)}
+var
+ lSHA1Hash: TIdHashSHA1;
+{$ENDIF}
+begin
+{$IF defined(TOKYOORBETTER)}
+ Result := THashSHA1.GetHashString(AStream);
+{$ELSE}
+ lSHA1Hash := TIdHashSHA1.Create;
+ try
+ Result := lSHA1Hash.HashStreamAsHex(AStream);
+ finally
+ lSHA1Hash.Free;
+ end;
+{$ENDIF}
+end;
+
function GetMD5HashFromString(const AString: String): string;
{$IF not defined(TOKYOORBETTER)}
var
@@ -76,7 +99,7 @@ var
{$ENDIF}
begin
{$IF defined(TOKYOORBETTER)}
- Result := THashMD5.GetHashString(AStream);
+ Result := THashMD5.GetHashString(AString);
{$ELSE}
lMD5Hash := TIdHashMessageDigest5.Create;
try
@@ -87,6 +110,24 @@ begin
{$ENDIF}
end;
+function GetSHA1HashFromString(const AString: String): string;
+{$IF not defined(TOKYOORBETTER)}
+var
+ lSHA1Hash: TIdHashSHA1;
+{$ENDIF}
+begin
+{$IF defined(TOKYOORBETTER)}
+ Result := THashSHA1.GetHashString(AString);
+{$ELSE}
+ lSHA1Hash := TIdHashSHA1.Create;
+ try
+ Result := lSHA1Hash.HashStringAsHex(AString);
+ finally
+ lSHA1Hash.Free;
+ end;
+{$ENDIF}
+end;
+
function NewJSONSerializer: IMVCJSONSerializer;
begin
diff --git a/sources/MVCFramework.pas b/sources/MVCFramework.pas
index 9eb118d9..18be3521 100644
--- a/sources/MVCFramework.pas
+++ b/sources/MVCFramework.pas
@@ -681,7 +681,7 @@ type
/// https://restfulapi.net/http-status-201-created/
///
procedure Render201Created(const Location: string = '';
- const Reason: string = 'Created'); virtual;
+ const Reason: string = ''); virtual;
///
/// Allow a server to accept a request for some other process (perhaps a batch-oriented process that is only run once per day) without requiring that the user agents connection to the server persist until the process is completed.
/// The entity returned with this response SHOULD describe the requests current status and point to (or embed) a status monitor that can provide the user with (or without) an estimate of when the request will be fulfilled.
@@ -696,7 +696,7 @@ type
/// The 204 response MUST NOT include a message-body and thus is always terminated by the first empty line after the header fields.
///
procedure Render204NoContent(const Location: string = '';
- const Reason: string = 'No Content'); virtual;
+ const Reason: string = ''); virtual;
function Serializer: IMVCSerializer; overload;
function Serializer(const AContentType: string;
const ARaiseExceptionIfNotExists: Boolean = True): IMVCSerializer; overload;
@@ -811,6 +811,7 @@ type
// Avoiding mid-air collisions - support
procedure SetETag(const Data: String);
+ function GetIfMatch(): String;
procedure CheckIfMatch(const Data: String);
// END - Avoiding mid-air collisions - support
@@ -1048,6 +1049,7 @@ type
public
constructor Create; overload; virtual;
constructor Create(AStatusCode: Integer; AReasonString: string; AMessage: string); overload;
+ destructor Destroy; override;
property StatusCode: Integer read FStatusCode write FStatusCode;
property ReasonString: string read FReasonString write FReasonString;
property Message: string read FMessage write FMessage;
@@ -1072,6 +1074,8 @@ type
property Items: TObjectList read FItems;
end;
+
+
TMVCBaseViewEngine = class(TMVCBase)
private
FViewName: string;
@@ -3386,13 +3390,13 @@ begin
end;
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag#avoiding_mid-air_collisions
- lReqETag := Context.Request.GetHeader('If-Match');
+ lReqETag := GetIfMatch;
if lReqETag.IsEmpty then
begin
raise EMVCException.Create(HTTP_STATUS.PreconditionFailed, 'If-Match header is empty');
end;
- if lReqETag <> GetMD5HashFromString(Data) then
+ if lReqETag <> GetSHA1HashFromString(Data) then
begin
raise EMVCException.Create(HTTP_STATUS.PreconditionFailed, 'mid-air collisions detected, cannot update or delete resource.');
end;
@@ -3452,6 +3456,11 @@ begin
Result := Engine.WebModule;
end;
+function TMVCController.GetIfMatch: String;
+begin
+ Result := Context.Request.GetHeader('If-Match');
+end;
+
function TMVCController.GetSession: TWebSession;
begin
Result := GetContext.Session;
@@ -3635,7 +3644,10 @@ end;
procedure TMVCRenderer.ResponseStatus(const AStatusCode: Integer; const AReasonString: string);
begin
SetStatusCode(AStatusCode);
- GetContext.Response.ReasonString := AReasonString;
+ if AReasonString = '' then
+ GetContext.Response.ReasonString := HTTP_STATUS.ReasonStringFor(AStatusCode)
+ else
+ GetContext.Response.ReasonString := AReasonString;
end;
function TMVCRenderer.ResponseStream: TStringBuilder;
@@ -3730,7 +3742,7 @@ end;
procedure TMVCController.SetETag(const Data: String);
begin
- Context.Response.SetCustomHeader('ETag', GetMD5HashFromString(Data));
+ Context.Response.SetCustomHeader('ETag', GetSHA1HashFromString(Data));
end;
procedure TMVCController.SetViewData(const aModelName: string; const Value: TObject);
@@ -3763,18 +3775,18 @@ begin
SendStream(AStream, AOwns);
end;
-procedure TMVCRenderer.Render(const AErrorCode: Integer;
-const AErrorMessage, AErrorClassName: string; const ADataObject: TObject);
-var R: TMVCErrorResponse;
+procedure TMVCRenderer.Render(
+ const AErrorCode: Integer;
+ const AErrorMessage, AErrorClassName: string;
+ const ADataObject: TObject);
+var
+ R: TMVCErrorResponse;
begin
ResponseStatus(AErrorCode, AErrorMessage);
R := TMVCErrorResponse.Create;
try
R.StatusCode := AErrorCode;
- if ((R.StatusCode div 100) = 2) then
- R.ReasonString := 'ok'
- else
- R.ReasonString := 'error';
+ R.ReasonString := HTTP_STATUS.ReasonStringFor(AErrorCode);
R.Message := AErrorMessage;
R.Classname := AErrorClassName;
R.Data := ADataObject;
@@ -4041,7 +4053,7 @@ begin
R := TMVCErrorResponse.Create;
try
R.StatusCode := GetContext.Response.StatusCode;
- R.ReasonString := 'error';
+ R.ReasonString := HTTP_STATUS.ReasonStringFor(R.StatusCode);
R.Message := AException.Message;
R.Classname := AException.Classname;
if AException is EMVCException then
@@ -4087,6 +4099,7 @@ begin
begin
try
GetContext.Response.StatusCode := AResponse.StatusCode;
+ GetContext.Response.ReasonString := HTTP_STATUS.ReasonStringFor(AResponse.StatusCode);
Render(AResponse, False, stProperties);
finally
if AOwns then
@@ -4136,6 +4149,7 @@ end;
constructor TMVCResponse.Create;
begin
inherited Create;
+ fDataObject := nil;
end;
constructor TMVCErrorResponse.Create;
@@ -4152,6 +4166,12 @@ begin
message := AMessage;
end;
+destructor TMVCResponse.Destroy;
+begin
+ fDataObject.Free;
+ inherited;
+end;
+
destructor TMVCErrorResponse.Destroy;
begin
FItems.Free;
diff --git a/unittests/general/Several/BOs.pas b/unittests/general/Several/BOs.pas
index b2cd09b0..e23f1bc2 100644
--- a/unittests/general/Several/BOs.pas
+++ b/unittests/general/Several/BOs.pas
@@ -120,7 +120,7 @@ type
[MVCTableField('creation_date')]
fCreationDate: NullableTDate;
public
- procedure Assign(Customer: TCustomer); overload;
+ procedure Assign(Customer: TCustomer); reintroduce; overload;
function Clone: TCustomer;
function ToString: String; override;
property ID: NullableInt32 read fID write fID;
diff --git a/unittests/general/Several/DMVCFrameworkTests.dproj b/unittests/general/Several/DMVCFrameworkTests.dproj
index 98aa86c0..33c6749e 100644
--- a/unittests/general/Several/DMVCFrameworkTests.dproj
+++ b/unittests/general/Several/DMVCFrameworkTests.dproj
@@ -1,7 +1,7 @@
{0582DE6A-D716-46D3-8CBD-84AD73A4B536}
- 19.4
+ 19.5
VCL
True
TESTINSIGHT
@@ -323,65 +323,17 @@
Microsoft Office XP Sample Automation Server Wrapper Components
-
-
-
- true
-
-
-
-
- true
-
-
-
-
- DMVCFrameworkTests.exe
- true
-
-
-
-
- DMVCFrameworkTests.exe
- true
-
-
-
-
- DMVCFrameworkTests.exe
- true
-
-
-
-
- DMVCFrameworkTests.rsm
- true
-
-
-
-
- DMVCFrameworkTests.rsm
- true
-
-
-
-
- DMVCFrameworkTests.rsm
- true
-
-
-
-
- DMVCFrameworkTests.exe
- true
-
-
-
-
- DMVCFrameworkTests.rsm
- true
-
-
+
+
+
+
+
+
+
+
+
+
+
1
@@ -400,16 +352,6 @@
64
-
-
- classes
- 1
-
-
- classes
- 1
-
-
res\xml
@@ -452,12 +394,6 @@
1
-
-
- library\lib\x86
- 1
-
-
library\lib\armeabi-v7a
@@ -739,7 +675,7 @@
1
.dylib
-
+
1
.dylib
@@ -773,7 +709,7 @@
0
-
+
0
@@ -794,13 +730,17 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -810,169 +750,27 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -982,7 +780,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -992,7 +790,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1002,7 +800,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1012,7 +810,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1022,191 +820,37 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -1216,7 +860,7 @@
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -1226,7 +870,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1236,7 +880,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1246,7 +890,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1256,7 +900,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1266,7 +910,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1276,7 +920,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1298,9 +942,11 @@
..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
1
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
-
-
@@ -1311,11 +957,10 @@
1
-
+
1
-
@@ -1348,7 +993,7 @@
1
-
+
1
@@ -1406,6 +1051,7 @@
+
diff --git a/unittests/general/Several/LiveServerTestU.pas b/unittests/general/Several/LiveServerTestU.pas
index bf8465c9..fa378839 100644
--- a/unittests/general/Several/LiveServerTestU.pas
+++ b/unittests/general/Several/LiveServerTestU.pas
@@ -983,7 +983,7 @@ begin
Assert.areEqual('message', lJSON.S['message'], lJSON.ToJSON());
Assert.areEqual('EMVCException', lJSON.S['classname'], lJSON.ToJSON());
Assert.areEqual(500, lJSON.I['statuscode'], lJSON.ToJSON());
- Assert.areEqual('error', lJSON.S['reasonstring'], lJSON.ToJSON());
+ Assert.areEqual('Internal Server Error', lJSON.S['reasonstring'], lJSON.ToJSON());
Assert.areEqual(0, lJSON.A['items'].Count, lJSON.ToJSON());
Assert.isTrue(lJSON.IsNull('data'), lJSON.ToJSON());
finally
@@ -1004,7 +1004,7 @@ begin
Assert.areEqual('message', lJSON.S['message'], lJSON.ToJSON());
Assert.areEqual('EMVCException', lJSON.S['classname'], lJSON.ToJSON());
Assert.areEqual(HTTP_STATUS.BadRequest, lJSON.I['statuscode'], lJSON.ToJSON());
- Assert.areEqual('error', lJSON.S['reasonstring'], lJSON.ToJSON());
+ Assert.areEqual('Bad Request', lJSON.S['reasonstring'], lJSON.ToJSON());
Assert.areEqual(0, lJSON.A['items'].Count, lJSON.ToJSON());
Assert.isTrue(lJSON.IsNull('data'), lJSON.ToJSON());
finally
@@ -1024,7 +1024,7 @@ begin
Assert.areEqual('message', lJSON.S['message'], lJSON.ToJSON());
Assert.areEqual('EMVCException', lJSON.S['classname'], lJSON.ToJSON());
Assert.areEqual(HTTP_STATUS.Created, lJSON.I['statuscode'], lJSON.ToJSON());
- Assert.areEqual('error', lJSON.S['reasonstring'], lJSON.ToJSON());
+ Assert.areEqual('Created', lJSON.S['reasonstring'], lJSON.ToJSON());
Assert.areEqual(999, lJSON.I['apperrorcode'], lJSON.ToJSON());
Assert.areEqual(0, lJSON.A['items'].Count, lJSON.ToJSON());
Assert.isTrue(lJSON.IsNull('data'), lJSON.ToJSON());
@@ -1046,7 +1046,7 @@ begin
Assert.areEqual('detailedmessage', lJSON.S['detailedmessage'], lJSON.ToJSON());
Assert.areEqual('EMVCException', lJSON.S['classname'], lJSON.ToJSON());
Assert.areEqual(HTTP_STATUS.Created, lJSON.I['statuscode'], lJSON.ToJSON());
- Assert.areEqual('error', lJSON.S['reasonstring'], lJSON.ToJSON());
+ Assert.areEqual('Created', lJSON.S['reasonstring'], lJSON.ToJSON());
Assert.areEqual(999, lJSON.I['apperrorcode'], lJSON.ToJSON());
Assert.areEqual(2, lJSON.A['items'].Count, lJSON.ToJSON());
Assert.areEqual('erritem1', lJSON.A['items'].O[0].S['message'], lJSON.ToJSON());
diff --git a/unittests/general/TestServer/TestServer.dproj b/unittests/general/TestServer/TestServer.dproj
index 5db91cfe..000e11ab 100644
--- a/unittests/general/TestServer/TestServer.dproj
+++ b/unittests/general/TestServer/TestServer.dproj
@@ -7,7 +7,7 @@
129
Console
None
- 19.4
+ 19.5
Win32
@@ -154,7 +154,7 @@
True
False
-
+
true
@@ -182,12 +182,7 @@
true
-
-
- TestServer.exe
- true
-
-
+
.\www
@@ -202,12 +197,7 @@
true
-
-
- TestServer
- true
-
-
+
1
@@ -226,16 +216,6 @@
64
-
-
- classes
- 1
-
-
- classes
- 1
-
-
res\xml
@@ -559,7 +539,7 @@
1
.dylib
-
+
1
.dylib
@@ -593,7 +573,7 @@
0
-
+
0
@@ -614,13 +594,17 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
+
+ ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
+ 1
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -630,137 +614,27 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -770,7 +644,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -780,7 +654,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -790,7 +664,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -800,7 +674,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -810,191 +684,37 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -1004,7 +724,7 @@
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset
1
@@ -1014,7 +734,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1024,7 +744,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1034,7 +754,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1044,7 +764,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1054,7 +774,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1064,7 +784,7 @@
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
-
+
..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset
1
@@ -1086,8 +806,11 @@
..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
1
+
+ ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF
+ 1
+
-
@@ -1098,7 +821,7 @@
1
-
+
1
@@ -1134,7 +857,7 @@
1
-
+
1
@@ -1191,6 +914,7 @@
+