diff --git a/.gitignore b/.gitignore index 6a1cf11c..d94145c8 100644 --- a/.gitignore +++ b/.gitignore @@ -144,3 +144,4 @@ samples/WineCellarSample/winecellarclient_mobile/Android/Debug/styles.xml samples/WineCellarSample/winecellarclient_mobile/Android/Debug/styles-v21.xml samples/WineCellarSample/winecellarclient_mobile/Android/Debug/WineCellarMobileClient.classes/classes.dex samples/apachemodule/Apache24/logs/httpd.pid +samples/session_file_based/Win32/DEBUG/sessions/ diff --git a/README.md b/README.md index b73f38a3..5541abe8 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ - [What users say about DMVCFramework](#what-users-say-about-dmvcframework) - [What's New in dmvcframework-3.3.0-fluorine (last stable version)](#whats-new-in-dmvcframework-330-fluorine-last-stable-version) - [What's New in the next "repo version" a.k.a. 3.4.0-neon](#whats-new-in-the-next-repo-version-aka-340-neon) - - [Hystorical Versions](#hystorical-versions) + - [Old Versions](#old-versions) - [What's New in dmvcframework-3.2.3-radium](#whats-new-in-dmvcframework-323-radium) - [Bug Fix in 3.2.3-radium](#bug-fix-in-323-radium) - [What's new in DelphiMVCFramework-3.2.2-nitrogen](#whats-new-in-delphimvcframework-322-nitrogen) @@ -214,6 +214,8 @@ Congratulations to Daniele Teti and all the staff for the excellent work!" -- Ma > "Thank you for the great framework! We are very happy with this!" -- Andreas +> "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 dmvcframework-3.3.0-fluorine (last stable version) @@ -231,20 +233,400 @@ Congratulations to Daniele Teti and all the staff for the excellent work!" -- Ma ## What's New in the next "repo version" a.k.a. 3.4.0-neon -- Added support for dotEnv multiline keys - added dotEnv show case -- Added MSHeap memory manager for Win32 and Win64 (https://github.com/RDP1974/DelphiMSHeap) +- ⚡ Added support for dotEnv multiline keys - added dotEnv show case + +- ⚡ Added MSHeap memory manager for Win32 and Win64 (https://github.com/RDP1974/DelphiMSHeap) + - 🐞 FIX [Issue 664](https://github.com/danieleteti/delphimvcframework/issues/664) Thanks to [MPannier](https://github.com/MPannier) + - 🐞 FIX [Issue 667](https://github.com/danieleteti/delphimvcframework/issues/667) + +- 🐞 FIX [Issue 680](https://github.com/danieleteti/delphimvcframework/issues/680) + - 🐞 FIX Wrong comparison in checks for ro/RW/PK fields in `TMVCActiveRecord` -- Wizard updated to be dotEnv aware -- Removed Controller Application Session (very seldom used but potentially breaking change) -- Removed Middlewares in favor of a simpler alternative named "Filters" - - Added Protocol Filters - - Added Controller Filters -- `TMVCRouterLogHandlerProc` changed prototype (breaking change) + +- 🐞 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 + +- ⚡ Better error message in case of serialization of `TArray` + +- ⚡ Improved CORS handling - [Issue 679](https://github.com/danieleteti/delphimvcframework/issues/679) (Thanks to [David Moorhouse](https://github.com/fastbike)) + +- ⚡ Improved serialization of `TObjectList` (however `ObjectDict` is still the preferred way to serialize multiple datasets). + +- ⚡ Added static method for easier cloning of FireDAC dataset into `TFDMemTable`. + + - `class function CloneFrom(const FDDataSet: TFDDataSet): TFDMemTable` + + - Check sample "function_actions_showcase.dproj" for more info. + +- ⚡ Functional Actions + + - In addition to the classic `procedure` based actions, now it's possibile to use functions as actions. The `Result` variable is automatically rendered and, if it is an object, its memory is freed. + + ```pascal + type + [MVCNameCase(ncCamelCase)] + TPersonRec = record + FirstName, LastName: String; + Age: Integer; + class function Create: TPersonRec; static; + end; + + [MVCNameCase(ncCamelCase)] + TPerson = class + private + fAge: Integer; + fFirstName, fLastName: String; + public + property FirstName: String read fFirstName write fFirstName; + property LastName: String read fLastName write fLastName; + property Age: Integer read fAge write fAge; + end; + + [MVCPath('/api')] + TMyController = class(TMVCController) + public + { actions returning a simple type } + [MVCPath('/sumsasinteger/($A)/($B)')] + function GetSum(const A, B: Integer): Integer; + [MVCPath('/sumsasfloat/($A)/($B)')] + function GetSumAsFloat(const A, B: Extended): Extended; + + { actions returning records } + [MVCPath('/records/single')] + function GetSingleRecord: TPersonRec; + [MVCPath('/records/multiple')] + function GetMultipleRecords: TArray; + + { actions returning objects } + [MVCPath('/objects/single')] + function GetSingleObject: TPerson; + [MVCPath('/objects/multiple')] + function GetMultipleObjects: TObjectList; + + { actions returning datasets } + [MVCPath('/datasets/single')] + function GetSingleDataSet: TDataSet; + [MVCPath('/datasets/multiple')] + function GetMultipleDataSet: TEnumerable; + [MVCPath('/datasets/multiple2')] + function GetMultipleDataSet2: IMVCObjectDictionary; + + { customize response headers } + [MVCPath('/headers')] + function GetWithCustomHeaders: TObjectList; + end; + ``` + + Check sample "function_actions_showcase.dproj" for more info. + +- ⚡ 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). + + **Message based responses** + + ```pascal + function TMyController.GetMVCResponse: TMVCResponse; + begin + Result := MVCResponse(HTTP_STATUS.OK, 'My Message'); + end; + ``` + + Produces + + ```json + { + "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": { + "firstName": "Daniele", + "lastName": "Teti", + "age": 99 + } + } + ``` + + **Data based response with list of objects** + + ```pascal + function TMyController.GetMVCResponse3: TMVCResponse; + begin + Result := MVCResponse(HTTP_STATUS.OK, + TObjectList.Create([ + TPerson.Create('Daniele','Teti', 99), + TPerson.Create('Peter','Parker', 25), + TPerson.Create('Bruce','Banner', 45) + ]) + ); + end; + ``` + + Produces + + ```json + { + "data": [ + { + "firstName": "Daniele", + "lastName": "Teti", + "age": 99 + }, + { + "firstName": "Peter", + "lastName": "Parker", + "age": 25 + }, + { + "firstName": "Bruce", + "lastName": "Banner", + "age": 45 + } + ] + } + ``` + + **Data dictionary based response with `IMVCObjectDictionary` ** + + ```pascal + function TMyController.GetMVCResponseWithObjectDictionary: IMVCResponse; + begin + Result := MVCResponse( + HTTP_STATUS.OK, + ObjectDict() + .Add('employees', TObjectList.Create([ + TPerson.Create('Daniele','Teti', 99), + TPerson.Create('Peter','Parker', 25), + TPerson.Create('Bruce','Banner', 45) + ]) + ) + .Add('customers', TObjectList.Create([ + TPerson.Create('Daniele','Teti', 99), + TPerson.Create('Peter','Parker', 25), + TPerson.Create('Bruce','Banner', 45) + ]) + ) + ); + end; + ``` + + Produces + + ```json + { + "employees": [ + { + "firstName": "Daniele", + "lastName": "Teti", + "age": 99 + }, + { + "firstName": "Peter", + "lastName": "Parker", + "age": 25 + }, + { + "firstName": "Bruce", + "lastName": "Banner", + "age": 45 + } + ], + "customers": [ + { + "firstName": "Daniele", + "lastName": "Teti", + "age": 99 + }, + { + "firstName": "Peter", + "lastName": "Parker", + "age": 25 + }, + { + "firstName": "Bruce", + "lastName": "Banner", + "age": 45 + } + ] + } + ``` + +- Removed `statuscode` and `reasonstring` from exception's JSON rendering. + +- ⚡ New! NamedQueries support for TMVCActiveRecord. + + - `MVCNamedSQLQuery` allows to define a "named query" which is, well, a SQL query with a name. Then such query can be used by the method `SelectByNamedQuery`. MOreover in the attribute it is possible to define on which backend engine that query is usable. In this way you can define optimized query for each supported DMBS you need. Check the example below. + + ```delphi + type + [MVCTable('customers')] + [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')] + TCustomer = class(TCustomEntity) + private + // usual field declaration + end; + + //** then in the code + + Log('** Named SQL Query'); + Log('QuerySQL: RatingLessThanPar'); + var lCustomers := TMVCActiveRecord.SelectByNamedQuery('RatingLessThanPar', [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: RatingEqualsToPar'); + lCustomers := TMVCActiveRecord.SelectByNamedQuery('RatingEqualsToPar', [3], [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; + + ``` + + The same approach is available for RQL query, which can be used also for Count and Delete operations but doesnt allows to specify the backend (because RQL has an actual compiler to adapt the generated SQL to each RDBMS) + + ```delphi + type + [MVCTable('customers')] + [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)')] + TCustomer = class(TCustomEntity) + private + // usual field declaration + end; + + //** then in the code + + Log('** Named RQL Query'); + Log('QueryRQL: RatingLessThanPar'); + lCustomers := TMVCActiveRecord.SelectRQLByNamedQuery('RatingLessThanPar', [4], 1000); + 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('QueryRQL: RatingEqualsToPar'); + lCustomers := TMVCActiveRecord.SelectRQLByNamedQuery('RatingEqualsToPar', [3], 1000); + 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; + + ``` + + Now, having SQL and RQL named queries, it is possibile to have an entity which is not mapped on a specific table but loaded only by named queries. + + ```delphi + type + [MVCEntityActions([eaRetrieve])] + [MVCNamedSQLQuery('CustomersInTheSameCity', + 'SELECT c.id, c.DESCRIPTION, c.city, c.code, c.rating, (SELECT count(*) - 1 FROM customers c2 WHERE c2.CITY = c.CITY) customers_in_the_same_city ' + + 'FROM CUSTOMERS c WHERE city IS NOT NULL AND city <> '''' ORDER BY customers_in_the_same_city')] + TCustomerStats = class(TCustomEntity) {not mapped on an actual table or view} + private + [MVCTableField('id', [foPrimaryKey, foAutoGenerated])] + fID: NullableInt64; + [MVCTableField('code')] + fCode: NullableString; + [MVCTableField('description')] + fCompanyName: NullableString; + [MVCTableField('city')] + fCity: string; + [MVCTableField('rating')] + fRating: NullableInt32; + [MVCTableField('customers_in_the_same_city')] + fCustomersInTheSameCity: Int32; + public + property ID: NullableInt64 read fID write fID; + property Code: NullableString read fCode write fCode; + property CompanyName: NullableString read fCompanyName write fCompanyName; + property City: string read fCity write fCity; + property Rating: NullableInt32 read fRating write fRating; + property CustomersInTheSameCity: Int32 read fCustomersInTheSameCity write fCustomersInTheSameCity; + end; + + + //** then in the code + + procedure TMainForm.btnVirtualEntitiesClick(Sender: TObject); + begin + var lCustStats := TMVCActiveRecord.SelectByNamedQuery('CustomersInTheSameCity', [], []); + try + for var lCustomer in lCustStats do + begin + Log(Format('%4d - %8.5s - %s - (%d other customers in the same city)', [ + lCustomer.ID.ValueOrDefault, + lCustomer.Code.ValueOrDefault, + lCustomer.CompanyName.ValueOrDefault, + lCustomer.CustomersInTheSameCity + ])); + end; + finally + lCustStats.Free; + end; + end; + + + ``` + + -## Hystorical Versions +## Old Versions ### What's New in dmvcframework-3.2.3-radium diff --git a/ideexpert/DMVC.Expert.CodeGen.NewControllerUnit.pas b/ideexpert/DMVC.Expert.CodeGen.NewControllerUnit.pas index 43108ee1..f9e3d738 100644 --- a/ideexpert/DMVC.Expert.CodeGen.NewControllerUnit.pas +++ b/ideexpert/DMVC.Expert.CodeGen.NewControllerUnit.pas @@ -104,12 +104,19 @@ var lActionFiltersMethodsImpl: string; lCRUDMethodsIntf: string; lCRUDMethodsImpl: string; + lBOClassesIntf: string; + lBOClassesImpl: string; begin lControllerUnit := sControllerUnit; + lIndexMethodIntf := sIndexMethodIntf; lIndexMethodImpl := Format(sIndexMethodImpl, [FControllerClassName]); + lCRUDMethodsIntf := sCRUDMethodsIntf; lCRUDMethodsImpl := Format(sCRUDMethodsImpl, [FControllerClassName]); + lBOClassesIntf := sBOClassesIntf; + lBOClassesImpl := Format(sBOClassesImpl, ['TPerson']); + if not FCreateIndexMethod then begin @@ -121,6 +128,8 @@ begin begin lCRUDMethodsIntf := ''; lCRUDMethodsImpl := ''; + lBOClassesIntf := ''; + lBOClassesImpl := ''; end; lActionFiltersMethodsIntf := sActionFiltersIntf; @@ -138,7 +147,18 @@ begin (BorlandIDEServices as IOTAModuleServices).GetNewModuleAndClassName('', lUnitIdent, lFormName, lFileName); Result := TSourceFile.Create(sControllerUnit, - [lUnitIdent, FControllerClassName, lIndexMethodIntf, lIndexMethodImpl, lActionFiltersMethodsIntf, lActionFiltersMethodsImpl, lCRUDMethodsIntf, lCRUDMethodsImpl]); + [ + lUnitIdent, + FControllerClassName, + lIndexMethodIntf, + lIndexMethodImpl, + lActionFiltersMethodsIntf, + lActionFiltersMethodsImpl, + lCRUDMethodsIntf, + lCRUDMethodsImpl, + lBOClassesIntf, + lBOClassesImpl + ]); end; { TNewJSONRPCUnitEx } @@ -155,7 +175,6 @@ function TNewJSONRPCUnitEx.NewImplSource(const ModuleIdent, FormIdent, AncestorIdent: string): IOTAFile; var lUnitIdent: string; -// lFormName: string; lFileName: string; lDummy: String; begin diff --git a/ideexpert/DMVC.Expert.CodeGen.Templates.pas b/ideexpert/DMVC.Expert.CodeGen.Templates.pas index 0cc5763a..39be6dbc 100644 --- a/ideexpert/DMVC.Expert.CodeGen.Templates.pas +++ b/ideexpert/DMVC.Expert.CodeGen.Templates.pas @@ -130,14 +130,18 @@ resourcestring // 3 - Sample Methods - Implementation // 4 - Action Filters - Interface // 5 - Action Filters - Implementation + // 8 - BO - Interface + // 9 - BO - Implementation + sControllerUnit = 'unit %0:s;' + sLineBreak + sLineBreak + 'interface' + sLineBreak + sLineBreak + 'uses' + sLineBreak + - ' MVCFramework, MVCFramework.Commons, MVCFramework.Serializer.Commons;' + sLineBreak + + ' MVCFramework, MVCFramework.Commons, MVCFramework.Serializer.Commons, System.Generics.Collections;' + sLineBreak + sLineBreak + 'type' + sLineBreak + + '%8:s' + sLineBreak + ' [MVCPath(''/api'')]' + sLineBreak + ' %1:s = class(TMVCController) ' + sLineBreak + ' public' + sLineBreak + @@ -154,6 +158,7 @@ resourcestring '%5:s' + sLineBreak + '%7:s' + sLineBreak + sLineBreak + + '%9:s' + sLineBreak + 'end.' + sLineBreak; sIndexMethodIntf = @@ -162,6 +167,7 @@ resourcestring ' procedure Index;' + sLineBreak + sLineBreak + ' [MVCPath(''/reversedstrings/($Value)'')]' + sLineBreak + ' [MVCHTTPMethod([httpGET])]' + sLineBreak + + ' [MVCProduces(TMVCMediaType.TEXT_PLAIN)]' + sLineBreak + ' procedure GetReversedString(const Value: String);' + sLineBreak; // 0 - Class Name @@ -179,45 +185,66 @@ resourcestring sCRUDMethodsIntf = sLineBreak + ' public' + sLineBreak + - ' //Sample CRUD Actions for a "Customer" entity' + sLineBreak + - ' [MVCPath(''/customers'')]' + sLineBreak + + ' //Sample CRUD Actions for a "People" entity' + sLineBreak + + ' [MVCPath(''/people'')]' + sLineBreak + ' [MVCHTTPMethod([httpGET])]' + sLineBreak + - ' procedure GetCustomers;' + sLineBreak + sLineBreak + - ' [MVCPath(''/customers/($id)'')]' + sLineBreak + + ' function GetPeople: TObjectList;' + sLineBreak + sLineBreak + + ' [MVCPath(''/people/($ID)'')]' + sLineBreak + ' [MVCHTTPMethod([httpGET])]' + sLineBreak + - ' procedure GetCustomer(id: Integer);' + sLineBreak + sLineBreak + - ' [MVCPath(''/customers'')]' + sLineBreak + + ' function GetPerson(ID: Integer): TPerson;' + sLineBreak + sLineBreak + + ' [MVCPath(''/people'')]' + sLineBreak + ' [MVCHTTPMethod([httpPOST])]' + sLineBreak + - ' procedure CreateCustomer;' + sLineBreak + sLineBreak + - ' [MVCPath(''/customers/($id)'')]' + sLineBreak + + ' function CreatePerson([MVCFromBody] Person: TPerson): TMVCResponse;' + sLineBreak + sLineBreak + + ' [MVCPath(''/people/($ID)'')]' + sLineBreak + ' [MVCHTTPMethod([httpPUT])]' + sLineBreak + - ' procedure UpdateCustomer(id: Integer);' + sLineBreak + sLineBreak + - ' [MVCPath(''/customers/($id)'')]' + sLineBreak + + ' function UpdatePerson(ID: Integer; [MVCFromBody] Person: TPerson): TMVCResponse;' + sLineBreak + sLineBreak + + ' [MVCPath(''/people/($ID)'')]' + sLineBreak + ' [MVCHTTPMethod([httpDELETE])]' + sLineBreak + - ' procedure DeleteCustomer(id: Integer);' + sLineBreak + sLineBreak; + ' function DeletePerson(ID: Integer): TMVCResponse;' + sLineBreak + sLineBreak; sCRUDMethodsImpl = - '//Sample CRUD Actions for a "Customer" entity' + sLineBreak + - 'procedure %0:s.GetCustomers;' + sLineBreak + + '//Sample CRUD Actions for a "People" entity' + sLineBreak + + 'function %0:s.GetPeople: TObjectList;' + sLineBreak + + 'var' + sLineBreak + + ' lPeople: TObjectList;' + sLineBreak + 'begin' + sLineBreak + - ' //todo: render a list of customers' + sLineBreak + + ' lPeople := TObjectList.Create(True);' + sLineBreak + + ' try' + sLineBreak + + ' lPeople.Add(TPerson.Create(''Peter'',''Parker'', EncodeDate(1965, 10, 4)));' + sLineBreak + + ' lPeople.Add(TPerson.Create(''Bruce'',''Banner'', EncodeDate(1945, 9, 6)));' + sLineBreak + + ' lPeople.Add(TPerson.Create(''Reed'',''Richards'', EncodeDate(1955, 3, 7)));' + sLineBreak + + ' Result := lPeople;' + sLineBreak + + ' except' + sLineBreak + + ' lPeople.Free;' + sLineBreak + + ' raise;' + sLineBreak + + ' end;' + sLineBreak + 'end;' + sLineBreak + sLineBreak + - 'procedure %0:s.GetCustomer(id: Integer);' + sLineBreak + + 'function %0:s.GetPerson(ID: Integer): TPerson;' + sLineBreak + + 'var' + sLineBreak + + ' lPeople: TObjectList;' + sLineBreak + 'begin' + sLineBreak + - ' //todo: render the customer by id' + sLineBreak + + ' lPeople := GetPeople;' + sLineBreak + + ' try' + sLineBreak + + ' Result := lPeople.ExtractAt(ID mod lPeople.Count);' + sLineBreak + + ' finally' + sLineBreak + + ' lPeople.Free;' + sLineBreak + + ' end;' + sLineBreak + 'end;' + sLineBreak + sLineBreak + - 'procedure %0:s.CreateCustomer;' + sLineBreak + + 'function %0:s.CreatePerson([MVCFromBody] Person: TPerson): TMVCResponse;' + sLineBreak + 'begin' + sLineBreak + - ' //todo: create a new customer' + sLineBreak + + ' LogI(''Created '' + Person.FirstName + '' '' + Person.LastName);' + sLineBreak + + ' Result := TMVCResponse.Create(HTTP_STATUS.Created, ''Person created'');' + sLineBreak + 'end;' + sLineBreak + sLineBreak + - 'procedure %0:s.UpdateCustomer(id: Integer);' + sLineBreak + + 'function %0:s.UpdatePerson(ID: Integer; [MVCFromBody] Person: TPerson): TMVCResponse;' + sLineBreak + 'begin' + sLineBreak + - ' //todo: update customer by id' + sLineBreak + + ' LogI(''Updated '' + Person.FirstName + '' '' + Person.LastName);' + sLineBreak + + ' Result := TMVCResponse.Create(HTTP_STATUS.OK, ''Person updated'');' + sLineBreak + 'end;' + sLineBreak + sLineBreak + - 'procedure %0:s.DeleteCustomer(id: Integer);' + sLineBreak + + 'function %0:s.DeletePerson(ID: Integer): TMVCResponse;' + sLineBreak + 'begin' + sLineBreak + - ' //todo: delete customer by id' + sLineBreak + - 'end;' + sLineBreak + sLineBreak; + ' LogI(''Deleted person with id '' + ID.ToString);' + sLineBreak + + ' Result := TMVCResponse.Create(HTTP_STATUS.OK, ''Person deleted'');' + sLineBreak + + 'end;' + sLineBreak; sActionFiltersIntf = ' protected' + sLineBreak + @@ -242,6 +269,30 @@ resourcestring ' inherited;' + sLineBreak + 'end;' + sLineBreak; + sBOClassesIntf = + ' [MVCNameCase(ncCamelCase)]' + sLineBreak + + ' TPerson = class' + sLineBreak + + ' private' + sLineBreak + + ' fFirstName: String;' + sLineBreak + + ' fLastName: String;' + sLineBreak + + ' fDOB: TDate;' + sLineBreak + + ' public' + sLineBreak + + ' property FirstName: String read fFirstName write fFirstName;' + sLineBreak + + ' property LastName: String read fLastName write fLastName;' + sLineBreak + + ' property DOB: TDate read fDOB write fDOB; ' + sLineBreak + + ' constructor Create(FirstName, LastName: String; DOB: TDate);' + sLineBreak + + ' end;' + sLineBreak; + + sBOClassesImpl = + sLineBreak + + 'constructor %0:s.Create(FirstName, LastName: String; DOB: TDate);' + sLineBreak + + 'begin' + sLineBreak + + ' inherited Create;' + sLineBreak + + ' fFirstName := FirstName;' + sLineBreak + + ' fLastName := LastName;' + sLineBreak + + ' fDOB := DOB;' + sLineBreak + + 'end;' + sLineBreak; + sDefaultControllerName = 'TMyController'; sDefaultWebModuleName = 'TMyWebModule'; sDefaultServerPort = '8080'; diff --git a/ideexpert/DMVC.Expert.ProjectWizardEx.pas b/ideexpert/DMVC.Expert.ProjectWizardEx.pas index 22153672..42ed4ac1 100644 --- a/ideexpert/DMVC.Expert.ProjectWizardEx.pas +++ b/ideexpert/DMVC.Expert.ProjectWizardEx.pas @@ -94,7 +94,7 @@ begin JSONRPCUnitCreator: IOTACreator; WebModuleCreator: IOTAModuleCreator; lProjectSourceCreator: IOTACreator; - lJSONRPCUnitName: string; + lJSONRPCUnitName: string; begin WizardForm := TfrmDMVCNewProject.Create(Application); try diff --git a/lib/loggerpro/LoggerPro.pas b/lib/loggerpro/LoggerPro.pas index a03201f1..57ecf29c 100644 --- a/lib/loggerpro/LoggerPro.pas +++ b/lib/loggerpro/LoggerPro.pas @@ -358,6 +358,7 @@ function GetDefaultFormatSettings: TFormatSettings; begin Result.DateSeparator := '-'; Result.TimeSeparator := ':'; + Result.DecimalSeparator := '.'; Result.ShortDateFormat := 'YYYY-MM-DD HH:NN:SS:ZZZ'; Result.ShortTimeFormat := 'HH:NN:SS'; end; diff --git a/lib/swagdoc/Source/SwagDoc.dpk b/lib/swagdoc/Source/SwagDoc.dpk index 0620b52d..cb1561ab 100644 --- a/lib/swagdoc/Source/SwagDoc.dpk +++ b/lib/swagdoc/Source/SwagDoc.dpk @@ -26,6 +26,7 @@ package SwagDoc; {$DEFINE DEBUG} {$ENDIF IMPLICITBUILDING} {$DESCRIPTION 'SwagDoc Library'} +{$LIBSUFFIX '113'} {$RUNONLY} {$IMPLICITBUILD OFF} diff --git a/lib/swagdoc/Source/SwagDoc.dproj b/lib/swagdoc/Source/SwagDoc.dproj index 3fb504e8..e741e6e6 100644 --- a/lib/swagdoc/Source/SwagDoc.dproj +++ b/lib/swagdoc/Source/SwagDoc.dproj @@ -97,6 +97,7 @@ 0 1033 CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 113 false diff --git a/packages/d111/dmvcframeworkDT.dpk b/packages/d111/dmvcframeworkDT.dpk deleted file mode 100644 index 12457b25..00000000 --- a/packages/d111/dmvcframeworkDT.dpk +++ /dev/null @@ -1,58 +0,0 @@ -package dmvcframeworkDT; - -{$R *.res} -{$R *.dres} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$ENDIF IMPLICITBUILDING} -{$DESCRIPTION 'DelphiMVCFramework 3.x - Design Time Support'} -{$LIBSUFFIX '111'} -{$IMPLICITBUILD ON} - -requires - rtl, - designide, - ExpertsCreators, - IndySystem, - IndyProtocols, - IndyCore, - dbrtl, - dmvcframeworkRT; - -contains - DMVC.Expert.CodeGen.NewControllerUnit in '..\..\ideexpert\DMVC.Expert.CodeGen.NewControllerUnit.pas', - DMVC.Expert.CodeGen.NewDMVCProject in '..\..\ideexpert\DMVC.Expert.CodeGen.NewDMVCProject.pas', - DMVC.Expert.CodeGen.NewProject in '..\..\ideexpert\DMVC.Expert.CodeGen.NewProject.pas', - DMVC.Expert.CodeGen.NewUnit in '..\..\ideexpert\DMVC.Expert.CodeGen.NewUnit.pas', - DMVC.Expert.CodeGen.NewWebModuleUnit in '..\..\ideexpert\DMVC.Expert.CodeGen.NewWebModuleUnit.pas', - DMVC.Expert.CodeGen.SourceFile in '..\..\ideexpert\DMVC.Expert.CodeGen.SourceFile.pas', - DMVC.Expert.CodeGen.Templates in '..\..\ideexpert\DMVC.Expert.CodeGen.Templates.pas', - DMVC.Expert.Forms.NewProjectWizard in '..\..\ideexpert\DMVC.Expert.Forms.NewProjectWizard.pas' {frmDMVCNewProject}, - DMVC.Expert.Forms.NewUnitWizard in '..\..\ideexpert\DMVC.Expert.Forms.NewUnitWizard.pas' {frmDMVCNewUnit}, - DMVC.Expert.NewUnitWizardEx in '..\..\ideexpert\DMVC.Expert.NewUnitWizardEx.pas', - DMVC.Expert.ProjectWizardEx in '..\..\ideexpert\DMVC.Expert.ProjectWizardEx.pas', - DMVC.Expert.Registration in '..\..\ideexpert\DMVC.Expert.Registration.pas', - DMVC.Splash.Registration in '..\..\ideexpert\DMVC.Splash.Registration.pas'; - -end. diff --git a/packages/d111/dmvcframeworkRT.dpk b/packages/d111/dmvcframeworkRT.dpk deleted file mode 100644 index 3f9d64df..00000000 --- a/packages/d111/dmvcframeworkRT.dpk +++ /dev/null @@ -1,120 +0,0 @@ -package dmvcframeworkRT; - -{$R *.res} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$ENDIF IMPLICITBUILDING} -{$DESCRIPTION 'DMVCFramework - CopyRight (2010-2023) Daniele Teti and the DMVCFramework Team'} -{$LIBSUFFIX '111'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - rtl, - inet, - FireDAC, - IndyCore, - IndyProtocols, - FireDACIBDriver, - FireDACMySQLDriver, - loggerproRT, - FireDACPgDriver, - FireDACSqliteDriver, - SwagDoc; - -contains - Web.HTTPDImpl, - Web.ApacheConst, - Web.ApacheHTTP, - Web.Win.IsapiHTTP, - Web.HTTPDMethods, - MVCFramework in '..\..\sources\MVCFramework.pas', - MVCFramework.AsyncTask in '..\..\sources\MVCFramework.AsyncTask.pas', - MVCFramework.Middleware.Swagger in '..\..\sources\MVCFramework.Middleware.Swagger.pas', - MVCFramework.Middleware.Trace in '..\..\sources\MVCFramework.Middleware.Trace.pas', - MVCFramework.Middleware.ETag in '..\..\sources\MVCFramework.Middleware.ETag.pas', - MVCFramework.ActiveRecord in '..\..\sources\MVCFramework.ActiveRecord.pas', - MVCFramework.ActiveRecordController in '..\..\sources\MVCFramework.ActiveRecordController.pas', - MVCFramework.ApplicationSession in '..\..\sources\MVCFramework.ApplicationSession.pas', - MVCFramework.Cache in '..\..\sources\MVCFramework.Cache.pas', - MVCFramework.Commons in '..\..\sources\MVCFramework.Commons.pas', - MVCFramework.Console in '..\..\sources\MVCFramework.Console.pas', - MVCFramework.DataSet.Utils in '..\..\sources\MVCFramework.DataSet.Utils.pas', - MVCFramework.DuckTyping in '..\..\sources\MVCFramework.DuckTyping.pas', - MVCFramework.FireDAC.Utils in '..\..\sources\MVCFramework.FireDAC.Utils.pas', - MVCFramework.HMAC in '..\..\sources\MVCFramework.HMAC.pas', - MVCFramework.JSONRPC.Client in '..\..\sources\MVCFramework.JSONRPC.Client.pas', - MVCFramework.JSONRPC in '..\..\sources\MVCFramework.JSONRPC.pas', - MVCFramework.JWT in '..\..\sources\MVCFramework.JWT.pas', - MVCFramework.Logger in '..\..\sources\MVCFramework.Logger.pas', - MVCFramework.Middleware.Analytics in '..\..\sources\MVCFramework.Middleware.Analytics.pas', - MVCFramework.Middleware.Authentication in '..\..\sources\MVCFramework.Middleware.Authentication.pas', - MVCFramework.Middleware.Authentication.RoleBasedAuthHandler in '..\..\sources\MVCFramework.Middleware.Authentication.RoleBasedAuthHandler.pas', - MVCFramework.Middleware.Compression in '..\..\sources\MVCFramework.Middleware.Compression.pas', - MVCFramework.Middleware.CORS in '..\..\sources\MVCFramework.Middleware.CORS.pas', - MVCFramework.Middleware.JWT in '..\..\sources\MVCFramework.Middleware.JWT.pas', - MVCFramework.Middleware.SecurityHeaders in '..\..\sources\MVCFramework.Middleware.SecurityHeaders.pas', - MVCFramework.MultiMap in '..\..\sources\MVCFramework.MultiMap.pas', - MVCFramework.Patches in '..\..\sources\MVCFramework.Patches.pas', - MVCFramework.RESTAdapter in '..\..\sources\MVCFramework.RESTAdapter.pas', - MVCFramework.Router in '..\..\sources\MVCFramework.Router.pas', - MVCFramework.RQL.AST2FirebirdSQL in '..\..\sources\MVCFramework.RQL.AST2FirebirdSQL.pas', - MVCFramework.RQL.AST2InterbaseSQL in '..\..\sources\MVCFramework.RQL.AST2InterbaseSQL.pas', - MVCFramework.RQL.AST2MySQL in '..\..\sources\MVCFramework.RQL.AST2MySQL.pas', - MVCFramework.RQL.AST2PostgreSQL in '..\..\sources\MVCFramework.RQL.AST2PostgreSQL.pas', - MVCFramework.RQL.AST2SQLite in '..\..\sources\MVCFramework.RQL.AST2SQLite.pas', - MVCFramework.RQL.Parser in '..\..\sources\MVCFramework.RQL.Parser.pas', - MVCFramework.Rtti.Utils in '..\..\sources\MVCFramework.Rtti.Utils.pas', - MVCFramework.Serializer.Abstract in '..\..\sources\MVCFramework.Serializer.Abstract.pas', - MVCFramework.Serializer.Commons in '..\..\sources\MVCFramework.Serializer.Commons.pas', - MVCFramework.Serializer.Defaults in '..\..\sources\MVCFramework.Serializer.Defaults.pas', - MVCFramework.Serializer.Intf in '..\..\sources\MVCFramework.Serializer.Intf.pas', - MVCFramework.Serializer.JsonDataObjects.CustomTypes in '..\..\sources\MVCFramework.Serializer.JsonDataObjects.CustomTypes.pas', - MVCFramework.Serializer.JsonDataObjects in '..\..\sources\MVCFramework.Serializer.JsonDataObjects.pas', - MVCFramework.Session in '..\..\sources\MVCFramework.Session.pas', - MVCFramework.SysControllers in '..\..\sources\MVCFramework.SysControllers.pas', - MVCFramework.SystemJSONUtils in '..\..\sources\MVCFramework.SystemJSONUtils.pas', - MVCFramework.View.Cache in '..\..\sources\MVCFramework.View.Cache.pas', - MVCFramework.Controllers.Register in '..\..\sources\MVCFramework.Controllers.Register.pas', - MVCFramework.SQLGenerators.Firebird in '..\..\sources\MVCFramework.SQLGenerators.Firebird.pas', - MVCFramework.SQLGenerators.Interbase in '..\..\sources\MVCFramework.SQLGenerators.Interbase.pas', - MVCFramework.SQLGenerators.MySQL in '..\..\sources\MVCFramework.SQLGenerators.MySQL.pas', - MVCFramework.SQLGenerators.PostgreSQL in '..\..\sources\MVCFramework.SQLGenerators.PostgreSQL.pas', - MVCFramework.SQLGenerators.Sqlite in '..\..\sources\MVCFramework.SQLGenerators.Sqlite.pas', - MVCFramework.Swagger.Commons in '..\..\sources\MVCFramework.Swagger.Commons.pas', - MVCFramework.Nullables in '..\..\sources\MVCFramework.Nullables.pas', - MVCFramework.Serializer.HTML in '..\..\sources\MVCFramework.Serializer.HTML.pas', - MVCFramework.LRUCache in '..\..\sources\MVCFramework.LRUCache.pas', - MVCFramework.RESTClient.Commons in '..\..\sources\MVCFramework.RESTClient.Commons.pas', - MVCFramework.RESTClient.Indy in '..\..\sources\MVCFramework.RESTClient.Indy.pas', - MVCFramework.RESTClient.Intf in '..\..\sources\MVCFramework.RESTClient.Intf.pas', - MVCFramework.RESTClient in '..\..\sources\MVCFramework.RESTClient.pas', - MVCFramework.Utils in '..\..\sources\MVCFramework.Utils.pas', - JsonDataObjects in '..\..\sources\JsonDataObjects.pas'; - -end. - - - - diff --git a/packages/d111/dmvcframework_group.groupproj b/packages/d111/dmvcframework_group.groupproj deleted file mode 100644 index 7349df03..00000000 --- a/packages/d111/dmvcframework_group.groupproj +++ /dev/null @@ -1,72 +0,0 @@ - - - {EA879EE4-1245-4456-AED9-57FDF63577E6} - - - - - - - - - - ..\..\lib\loggerpro\packages\d111\loggerproRT.dproj - - - dmvcframeworkRT.dproj - - - - Default.Personality.12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/d112/dmvcframeworkDT.dpk b/packages/d112/dmvcframeworkDT.dpk deleted file mode 100644 index 6fd2dc2e..00000000 --- a/packages/d112/dmvcframeworkDT.dpk +++ /dev/null @@ -1,58 +0,0 @@ -package dmvcframeworkDT; - -{$R *.res} -{$R *.dres} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$ENDIF IMPLICITBUILDING} -{$DESCRIPTION 'DelphiMVCFramework 3.x - Design Time Support'} -{$LIBSUFFIX '112'} -{$IMPLICITBUILD ON} - -requires - rtl, - designide, - ExpertsCreators, - IndySystem, - IndyProtocols, - IndyCore, - dbrtl, - dmvcframeworkRT; - -contains - DMVC.Expert.CodeGen.NewControllerUnit in '..\..\ideexpert\DMVC.Expert.CodeGen.NewControllerUnit.pas', - DMVC.Expert.CodeGen.NewDMVCProject in '..\..\ideexpert\DMVC.Expert.CodeGen.NewDMVCProject.pas', - DMVC.Expert.CodeGen.NewProject in '..\..\ideexpert\DMVC.Expert.CodeGen.NewProject.pas', - DMVC.Expert.CodeGen.NewUnit in '..\..\ideexpert\DMVC.Expert.CodeGen.NewUnit.pas', - DMVC.Expert.CodeGen.NewWebModuleUnit in '..\..\ideexpert\DMVC.Expert.CodeGen.NewWebModuleUnit.pas', - DMVC.Expert.CodeGen.SourceFile in '..\..\ideexpert\DMVC.Expert.CodeGen.SourceFile.pas', - DMVC.Expert.CodeGen.Templates in '..\..\ideexpert\DMVC.Expert.CodeGen.Templates.pas', - DMVC.Expert.Forms.NewProjectWizard in '..\..\ideexpert\DMVC.Expert.Forms.NewProjectWizard.pas' {frmDMVCNewProject}, - DMVC.Expert.Forms.NewUnitWizard in '..\..\ideexpert\DMVC.Expert.Forms.NewUnitWizard.pas' {frmDMVCNewUnit}, - DMVC.Expert.NewUnitWizardEx in '..\..\ideexpert\DMVC.Expert.NewUnitWizardEx.pas', - DMVC.Expert.ProjectWizardEx in '..\..\ideexpert\DMVC.Expert.ProjectWizardEx.pas', - DMVC.Expert.Registration in '..\..\ideexpert\DMVC.Expert.Registration.pas', - DMVC.Splash.Registration in '..\..\ideexpert\DMVC.Splash.Registration.pas'; - -end. diff --git a/packages/d112/dmvcframeworkRT.dpk b/packages/d112/dmvcframeworkRT.dpk deleted file mode 100644 index 49a16eef..00000000 --- a/packages/d112/dmvcframeworkRT.dpk +++ /dev/null @@ -1,120 +0,0 @@ -package dmvcframeworkRT; - -{$R *.res} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$ENDIF IMPLICITBUILDING} -{$DESCRIPTION 'DMVCFramework - CopyRight (2010-2023) Daniele Teti and the DMVCFramework Team'} -{$LIBSUFFIX '112'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - rtl, - inet, - FireDAC, - IndyCore, - IndyProtocols, - FireDACIBDriver, - FireDACMySQLDriver, - loggerproRT, - FireDACPgDriver, - FireDACSqliteDriver, - SwagDoc; - -contains - Web.HTTPDImpl, - Web.ApacheConst, - Web.ApacheHTTP, - Web.Win.IsapiHTTP, - Web.HTTPDMethods, - MVCFramework in '..\..\sources\MVCFramework.pas', - MVCFramework.AsyncTask in '..\..\sources\MVCFramework.AsyncTask.pas', - MVCFramework.Middleware.Swagger in '..\..\sources\MVCFramework.Middleware.Swagger.pas', - MVCFramework.Middleware.Trace in '..\..\sources\MVCFramework.Middleware.Trace.pas', - MVCFramework.Middleware.ETag in '..\..\sources\MVCFramework.Middleware.ETag.pas', - MVCFramework.ActiveRecord in '..\..\sources\MVCFramework.ActiveRecord.pas', - MVCFramework.ActiveRecordController in '..\..\sources\MVCFramework.ActiveRecordController.pas', - MVCFramework.ApplicationSession in '..\..\sources\MVCFramework.ApplicationSession.pas', - MVCFramework.Cache in '..\..\sources\MVCFramework.Cache.pas', - MVCFramework.Commons in '..\..\sources\MVCFramework.Commons.pas', - MVCFramework.Console in '..\..\sources\MVCFramework.Console.pas', - MVCFramework.DataSet.Utils in '..\..\sources\MVCFramework.DataSet.Utils.pas', - MVCFramework.DuckTyping in '..\..\sources\MVCFramework.DuckTyping.pas', - MVCFramework.FireDAC.Utils in '..\..\sources\MVCFramework.FireDAC.Utils.pas', - MVCFramework.HMAC in '..\..\sources\MVCFramework.HMAC.pas', - MVCFramework.JSONRPC.Client in '..\..\sources\MVCFramework.JSONRPC.Client.pas', - MVCFramework.JSONRPC in '..\..\sources\MVCFramework.JSONRPC.pas', - MVCFramework.JWT in '..\..\sources\MVCFramework.JWT.pas', - MVCFramework.Logger in '..\..\sources\MVCFramework.Logger.pas', - MVCFramework.Middleware.Analytics in '..\..\sources\MVCFramework.Middleware.Analytics.pas', - MVCFramework.Middleware.Authentication in '..\..\sources\MVCFramework.Middleware.Authentication.pas', - MVCFramework.Middleware.Authentication.RoleBasedAuthHandler in '..\..\sources\MVCFramework.Middleware.Authentication.RoleBasedAuthHandler.pas', - MVCFramework.Middleware.Compression in '..\..\sources\MVCFramework.Middleware.Compression.pas', - MVCFramework.Middleware.CORS in '..\..\sources\MVCFramework.Middleware.CORS.pas', - MVCFramework.Middleware.JWT in '..\..\sources\MVCFramework.Middleware.JWT.pas', - MVCFramework.Middleware.SecurityHeaders in '..\..\sources\MVCFramework.Middleware.SecurityHeaders.pas', - MVCFramework.MultiMap in '..\..\sources\MVCFramework.MultiMap.pas', - MVCFramework.Patches in '..\..\sources\MVCFramework.Patches.pas', - MVCFramework.RESTAdapter in '..\..\sources\MVCFramework.RESTAdapter.pas', - MVCFramework.Router in '..\..\sources\MVCFramework.Router.pas', - MVCFramework.RQL.AST2FirebirdSQL in '..\..\sources\MVCFramework.RQL.AST2FirebirdSQL.pas', - MVCFramework.RQL.AST2InterbaseSQL in '..\..\sources\MVCFramework.RQL.AST2InterbaseSQL.pas', - MVCFramework.RQL.AST2MySQL in '..\..\sources\MVCFramework.RQL.AST2MySQL.pas', - MVCFramework.RQL.AST2PostgreSQL in '..\..\sources\MVCFramework.RQL.AST2PostgreSQL.pas', - MVCFramework.RQL.AST2SQLite in '..\..\sources\MVCFramework.RQL.AST2SQLite.pas', - MVCFramework.RQL.Parser in '..\..\sources\MVCFramework.RQL.Parser.pas', - MVCFramework.Rtti.Utils in '..\..\sources\MVCFramework.Rtti.Utils.pas', - MVCFramework.Serializer.Abstract in '..\..\sources\MVCFramework.Serializer.Abstract.pas', - MVCFramework.Serializer.Commons in '..\..\sources\MVCFramework.Serializer.Commons.pas', - MVCFramework.Serializer.Defaults in '..\..\sources\MVCFramework.Serializer.Defaults.pas', - MVCFramework.Serializer.Intf in '..\..\sources\MVCFramework.Serializer.Intf.pas', - MVCFramework.Serializer.JsonDataObjects.CustomTypes in '..\..\sources\MVCFramework.Serializer.JsonDataObjects.CustomTypes.pas', - MVCFramework.Serializer.JsonDataObjects in '..\..\sources\MVCFramework.Serializer.JsonDataObjects.pas', - MVCFramework.Session in '..\..\sources\MVCFramework.Session.pas', - MVCFramework.SysControllers in '..\..\sources\MVCFramework.SysControllers.pas', - MVCFramework.SystemJSONUtils in '..\..\sources\MVCFramework.SystemJSONUtils.pas', - MVCFramework.View.Cache in '..\..\sources\MVCFramework.View.Cache.pas', - MVCFramework.Controllers.Register in '..\..\sources\MVCFramework.Controllers.Register.pas', - MVCFramework.SQLGenerators.Firebird in '..\..\sources\MVCFramework.SQLGenerators.Firebird.pas', - MVCFramework.SQLGenerators.Interbase in '..\..\sources\MVCFramework.SQLGenerators.Interbase.pas', - MVCFramework.SQLGenerators.MySQL in '..\..\sources\MVCFramework.SQLGenerators.MySQL.pas', - MVCFramework.SQLGenerators.PostgreSQL in '..\..\sources\MVCFramework.SQLGenerators.PostgreSQL.pas', - MVCFramework.SQLGenerators.Sqlite in '..\..\sources\MVCFramework.SQLGenerators.Sqlite.pas', - MVCFramework.Swagger.Commons in '..\..\sources\MVCFramework.Swagger.Commons.pas', - MVCFramework.Nullables in '..\..\sources\MVCFramework.Nullables.pas', - MVCFramework.Serializer.HTML in '..\..\sources\MVCFramework.Serializer.HTML.pas', - MVCFramework.LRUCache in '..\..\sources\MVCFramework.LRUCache.pas', - MVCFramework.RESTClient.Commons in '..\..\sources\MVCFramework.RESTClient.Commons.pas', - MVCFramework.RESTClient.Indy in '..\..\sources\MVCFramework.RESTClient.Indy.pas', - MVCFramework.RESTClient.Intf in '..\..\sources\MVCFramework.RESTClient.Intf.pas', - MVCFramework.RESTClient in '..\..\sources\MVCFramework.RESTClient.pas', - MVCFramework.Utils in '..\..\sources\MVCFramework.Utils.pas', - JsonDataObjects in '..\..\sources\JsonDataObjects.pas'; - -end. - - - - diff --git a/packages/d112/dmvcframework_group.groupproj b/packages/d112/dmvcframework_group.groupproj deleted file mode 100644 index 7349df03..00000000 --- a/packages/d112/dmvcframework_group.groupproj +++ /dev/null @@ -1,72 +0,0 @@ - - - {EA879EE4-1245-4456-AED9-57FDF63577E6} - - - - - - - - - - ..\..\lib\loggerpro\packages\d111\loggerproRT.dproj - - - dmvcframeworkRT.dproj - - - - Default.Personality.12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/samples/ISAPI/ISAPI/isapiapp.dpr b/samples/ISAPI/ISAPI/isapiapp.dpr index 9352efa0..5af55ee6 100644 --- a/samples/ISAPI/ISAPI/isapiapp.dpr +++ b/samples/ISAPI/ISAPI/isapiapp.dpr @@ -1,22 +1,28 @@ library isapiapp; - - - - uses Winapi.ActiveX, System.Win.ComObj, + MVCFramework.DotEnv, + MVCFramework.Commons, + MVCFramework.Logger, Web.WebBroker, Web.Win.ISAPIApp, Web.Win.ISAPIThreadPool, MainDataModuleUnit in '..\..\WineCellarSample\winecellarserver\MainDataModuleUnit.pas' {WineCellarDataModule: TDataModule}, MainWebModuleUnit in '..\..\WineCellarSample\winecellarserver\MainWebModuleUnit.pas' {wm: TWebModule}, WinesBO in '..\..\WineCellarSample\winecellarserver\WinesBO.pas', - WineCellarAppControllerU in '..\..\WineCellarSample\winecellarserver\WineCellarAppControllerU.pas'; + WineCellarAppControllerU in '..\..\WineCellarSample\winecellarserver\WineCellarAppControllerU.pas', + Winapi.Windows; {$R *.res} +function TerminateExtension(dwFlags: DWORD): BOOL; stdcall; +begin + ReleaseGlobalLogger; + Result := Web.Win.ISAPIThreadPool.TerminateExtension(dwFlags); +end; + exports GetExtensionVersion, HttpExtensionProc, @@ -26,5 +32,19 @@ begin CoInitFlags := COINIT_MULTITHREADED; Application.Initialize; Application.WebModuleClass := WebModuleClass; + dotEnvConfigure( + function: IMVCDotEnv + begin + Result := NewDotEnv + .WithStrategy(TMVCDotEnvPriority.FileThenEnv) + //if available, by default, loads default environment (.env) + .UseProfile('test') //if available loads the test environment (.env.test) + .UseProfile('prod') //if available loads the prod environment (.env.prod) + .UseLogger(procedure(LogItem: String) + begin + LogW('dotEnv: ' + LogItem); + end) + .Build(); //uses the executable folder to look for .env* files + end); Application.Run; end. diff --git a/samples/ISAPI/ISAPI/isapiapp.dproj b/samples/ISAPI/ISAPI/isapiapp.dproj index aa952676..68a11e56 100644 --- a/samples/ISAPI/ISAPI/isapiapp.dproj +++ b/samples/ISAPI/ISAPI/isapiapp.dproj @@ -6,8 +6,8 @@ isapiapp.dpr True Debug - Win32 - 1 + Win64 + 2 Library @@ -34,6 +34,12 @@ true true + + true + Cfg_1 + true + true + true Base @@ -66,6 +72,14 @@ FireDACSqliteDriver;DBXSqliteDriver;FireDACPgDriver;fmx;TreeViewPresenter;IndySystem;TeeDB;vclib;DBXInterBaseDriver;DataSnapClient;DataSnapCommon;DataSnapServer;DataSnapProviderClient;DBXSybaseASEDriver;DbxCommonDriver;vclimg;dbxcds;DatasnapConnectorsFreePascal;MetropolisUILiveTile;vcldb;vcldsnap;fmxFireDAC;DBXDb2Driver;DBXOracleDriver;CustomIPTransport;vclribbon;dsnap;IndyIPServer;fmxase;vcl;IndyCore;IndyIPCommon;CloudService;DBXMSSQLDriver;FmxTeeUI;FireDACIBDriver;DataSnapFireDAC;FireDACDBXDriver;inetdbxpress;FireDACDb2Driver;adortl;DataBindingsVCL;FireDACASADriver;bindcompfmx;FireDACODBCDriver;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;inetdb;Tee;DataBindings;DBXOdbcDriver;vclFireDAC;xmlrtl;ibxpress;IndyProtocols;DBXMySQLDriver;FireDACCommonDriver;bindengine;vclactnband;soaprtl;bindcompdbx;FMXTee;TeeUI;bindcompvcl;vclie;FireDACADSDriver;vcltouch;fmxinfopower;VclSmp;FireDACMSSQLDriver;FireDAC;VCLRESTComponents;Intraweb;DBXInformixDriver;DataSnapConnectors;FireDACDataSnapDriver;dsnapcon;DBXFirebirdDriver;inet;fmxobj;FireDACMySQLDriver;vclx;DBXSybaseASADriver;FireDACOracleDriver;fmxdae;RESTComponents;VirtualTreesR;FireDACMSAccDriver;DataSnapIndy10ServerTransport;dbexpress;IndyIPClient;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + Debug + true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + ..\bin + (None) + none DEBUG;$(DCC_Define) @@ -82,6 +96,15 @@ 1033 false + + true + 1033 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + (None) + none + C:\Windows\System32\inetsrv\w3wp.exe + -debug + false RELEASE;$(DCC_Define) @@ -94,12 +117,10 @@
WineCellarDataModule
- dfm TDataModule
wm
- dfm TWebModule
@@ -175,10 +196,10 @@ isapiapp.dpr - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components @@ -579,6 +600,127 @@ 0 + + + 1 + + + 1 + + + + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 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 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset @@ -779,127 +921,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 - - - - - - - - Contents\Resources - 1 - - - Contents\Resources - 1 - - - Contents\Resources - 1 - - - - - library\lib\armeabi-v7a - 1 - - - library\lib\arm64-v8a - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 0 - - - - - library\lib\armeabi-v7a - 1 - - - - - 1 - - - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - Assets - 1 - - - Assets - 1 - - @@ -914,8 +935,8 @@ - True - False + False + True 12 diff --git a/samples/ISAPI/ProjectGroup.groupproj b/samples/ISAPI/ProjectGroup.groupproj new file mode 100644 index 00000000..91db9ac1 --- /dev/null +++ b/samples/ISAPI/ProjectGroup.groupproj @@ -0,0 +1,48 @@ + + + {5EA2FE29-4523-4296-8CFA-94B6AC904435} + + + + + + + + + + + Default.Personality.12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/ISAPI/StandAlone/ConsoleApp.dpr b/samples/ISAPI/StandAlone/ConsoleApp.dpr new file mode 100644 index 00000000..561ffb2f --- /dev/null +++ b/samples/ISAPI/StandAlone/ConsoleApp.dpr @@ -0,0 +1,65 @@ +program ConsoleApp; +{$APPTYPE CONSOLE} + + +uses + MVCFramework, + MVCFramework.Commons, + MVCFramework.Signal, + MVCFramework.DotEnv, + MVCFramework.Logger, + System.SysUtils, + Winapi.Windows, + IdHTTPWebBrokerBridge, + Web.WebReq, + Web.WebBroker, + WinesBO in '..\..\WineCellarSample\winecellarserver\WinesBO.pas', + WineCellarAppControllerU in '..\..\WineCellarSample\winecellarserver\WineCellarAppControllerU.pas', + MainWebModuleUnit in '..\..\WineCellarSample\winecellarserver\MainWebModuleUnit.pas' {wm: TWebModule}, + MainDataModuleUnit in '..\..\WineCellarSample\winecellarserver\MainDataModuleUnit.pas' {WineCellarDataModule: TDataModule}; + +{$R *.res} + + +procedure RunServer(APort: Integer); +var + LServer: TIdHTTPWebBrokerBridge; +begin + Writeln(Format('Starting HTTP Server or port %d', [APort])); + LServer := TIdHTTPWebBrokerBridge.Create(nil); + try + LServer.DefaultPort := APort; + LServer.Active := True; + Write('CTRL+C to stop the server'); + WaitForTerminationSignal; + EnterInShutdownState; + finally + LServer.Free; + end; +end; + +begin + try + if WebRequestHandler <> nil then + WebRequestHandler.WebModuleClass := WebModuleClass; + dotEnvConfigure( + function: IMVCDotEnv + begin + Result := NewDotEnv + .WithStrategy(TMVCDotEnvPriority.FileThenEnv) + //if available, by default, loads default environment (.env) + .UseProfile('test') //if available loads the test environment (.env.test) + .UseProfile('prod') //if available loads the prod environment (.env.prod) + .UseLogger(procedure(LogItem: String) + begin + LogW('dotEnv: ' + LogItem); + end) + .Build(); //uses the executable folder to look for .env* files + end); + RunServer(8080); + except + on E: Exception do + Writeln(E.ClassName, ': ', E.Message); + end + +end. diff --git a/samples/ISAPI/StandAlone/StandAloneServer.dproj b/samples/ISAPI/StandAlone/ConsoleApp.dproj similarity index 79% rename from samples/ISAPI/StandAlone/StandAloneServer.dproj rename to samples/ISAPI/StandAlone/ConsoleApp.dproj index 52a2c519..3de05e42 100644 --- a/samples/ISAPI/StandAlone/StandAloneServer.dproj +++ b/samples/ISAPI/StandAlone/ConsoleApp.dproj @@ -1,1027 +1,980 @@ - - - {89FED123-CDD0-460A-9CC6-5810B281BF84} - 18.8 - VCL - StandAloneServer.dpr - True - Debug - Win32 - 1 - Console - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_1 - true - true - - - true - Base - true - - - StandAloneServer - CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName) - $(BDS)\bin\delphi_PROJECTICON.ico - 1040 - ..\..\..\sources;..\..\..\lib\delphistompclient;..\..\..\lib\loggerpro;..\..\..\lib\dmustache;$(DCC_UnitSearchPath) - $(BDS)\bin\delphi_PROJECTICNS.icns - System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) - .\$(Platform)\$(Config) - .\$(Platform)\$(Config) - false - false - false - false - false - - - true - Base - true - true - true - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png - true - true - true - $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png - true - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png - true - $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png - android-support-v4.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar - $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png - $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png - package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= - $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png - true - true - Debug - true - - - true - Base - true - Debug - - - None - ..\bin - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - 1033 - FireDACSqliteDriver;TsiLang_XE5r;DBXSqliteDriver;FireDACPgDriver;fmx;TreeViewPresenter;IndySystem;i18n;TeeDB;frx19;vclib;inetdbbde;DBXInterBaseDriver;DataSnapClient;DataSnapCommon;DataSnapServer;DataSnapProviderClient;DPFAndroidPackagesXE5;DBXSybaseASEDriver;DbxCommonDriver;vclimg;dbxcds;DatasnapConnectorsFreePascal;MetropolisUILiveTile;vcldb;vcldsnap;fmxFireDAC;DBXDb2Driver;DBXOracleDriver;CustomIPTransport;vclribbon;dsnap;IndyIPServer;i18nDB;fmxase;vcl;IndyCore;IndyIPCommon;CloudService;DBXMSSQLDriver;FmxTeeUI;FireDACIBDriver;CodeSiteExpressPkg;DataSnapFireDAC;FireDACDBXDriver;inetdbxpress;FireDACDb2Driver;adortl;CustomAdaptersMDPackage;DataBindingsVCL;FireDACASADriver;bindcompfmx;vcldbx;FireDACODBCDriver;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;inetdb;Tee;DataBindings;DBXOdbcDriver;vclFireDAC;CPortLibDXE;xmlrtl;svnui;ibxpress;IndyProtocols;DBXMySQLDriver;FireDACCommonDriver;bindengine;vclactnband;soaprtl;bindcompdbx;FMXTee;TeeUI;bindcompvcl;vclie;FireDACADSDriver;vcltouch;fmxinfopower;VclSmp;FireDACMSSQLDriver;FireDAC;VCLRESTComponents;Intraweb;DBXInformixDriver;DataSnapConnectors;FireDACDataSnapDriver;dsnapcon;DBXFirebirdDriver;inet;fmxobj;FireDACMySQLDriver;vclx;svn;DBXSybaseASADriver;FireDACOracleDriver;fmxdae;RESTComponents;bdertl;VirtualTreesR;FireDACMSAccDriver;DataSnapIndy10ServerTransport;dbexpress;IndyIPClient;$(DCC_UsePackage) - CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName) - - - FireDACSqliteDriver;DBXSqliteDriver;FireDACPgDriver;fmx;TreeViewPresenter;IndySystem;TeeDB;vclib;DBXInterBaseDriver;DataSnapClient;DataSnapCommon;DataSnapServer;DataSnapProviderClient;DBXSybaseASEDriver;DbxCommonDriver;vclimg;dbxcds;DatasnapConnectorsFreePascal;MetropolisUILiveTile;vcldb;vcldsnap;fmxFireDAC;DBXDb2Driver;DBXOracleDriver;CustomIPTransport;vclribbon;dsnap;IndyIPServer;fmxase;vcl;IndyCore;IndyIPCommon;CloudService;DBXMSSQLDriver;FmxTeeUI;FireDACIBDriver;DataSnapFireDAC;FireDACDBXDriver;inetdbxpress;FireDACDb2Driver;adortl;DataBindingsVCL;FireDACASADriver;bindcompfmx;FireDACODBCDriver;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;inetdb;Tee;DataBindings;DBXOdbcDriver;vclFireDAC;xmlrtl;ibxpress;IndyProtocols;DBXMySQLDriver;FireDACCommonDriver;bindengine;vclactnband;soaprtl;bindcompdbx;FMXTee;TeeUI;bindcompvcl;vclie;FireDACADSDriver;vcltouch;fmxinfopower;VclSmp;FireDACMSSQLDriver;FireDAC;VCLRESTComponents;Intraweb;DBXInformixDriver;DataSnapConnectors;FireDACDataSnapDriver;dsnapcon;DBXFirebirdDriver;inet;fmxobj;FireDACMySQLDriver;vclx;DBXSybaseASADriver;FireDACOracleDriver;fmxdae;RESTComponents;VirtualTreesR;FireDACMSAccDriver;DataSnapIndy10ServerTransport;dbexpress;IndyIPClient;$(DCC_UsePackage) - - - DEBUG;$(DCC_Define) - true - false - true - true - true - - - CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName) - 1033 - false - - - false - RELEASE;$(DCC_Define) - 0 - 0 - - - - MainSource - - -
WebModule1
- dfm - TWebModule -
- - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - -
- - Delphi.Personality.12 - - - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1040 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - - - - - - - - - - - - - - - - - - - - - - - StandAloneServer.dpr - - - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - - - 1 - - - 0 - - - - - classes - 1 - - - classes - 1 - - - - - res\xml - 1 - - - res\xml - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - library\lib\armeabi - 1 - - - library\lib\armeabi - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - library\lib\mips - 1 - - - library\lib\mips - 1 - - - - - library\lib\armeabi-v7a - 1 - - - library\lib\arm64-v8a - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - res\drawable - 1 - - - res\drawable - 1 - - - - - res\values - 1 - - - res\values - 1 - - - - - res\values-v21 - 1 - - - res\values-v21 - 1 - - - - - res\values - 1 - - - res\values - 1 - - - - - res\drawable - 1 - - - res\drawable - 1 - - - - - res\drawable-xxhdpi - 1 - - - res\drawable-xxhdpi - 1 - - - - - res\drawable-ldpi - 1 - - - res\drawable-ldpi - 1 - - - - - res\drawable-mdpi - 1 - - - res\drawable-mdpi - 1 - - - - - res\drawable-hdpi - 1 - - - res\drawable-hdpi - 1 - - - - - res\drawable-xhdpi - 1 - - - res\drawable-xhdpi - 1 - - - - - res\drawable-mdpi - 1 - - - res\drawable-mdpi - 1 - - - - - res\drawable-hdpi - 1 - - - res\drawable-hdpi - 1 - - - - - res\drawable-xhdpi - 1 - - - res\drawable-xhdpi - 1 - - - - - res\drawable-xxhdpi - 1 - - - res\drawable-xxhdpi - 1 - - - - - res\drawable-xxxhdpi - 1 - - - res\drawable-xxxhdpi - 1 - - - - - res\drawable-small - 1 - - - res\drawable-small - 1 - - - - - res\drawable-normal - 1 - - - res\drawable-normal - 1 - - - - - res\drawable-large - 1 - - - res\drawable-large - 1 - - - - - res\drawable-xlarge - 1 - - - res\drawable-xlarge - 1 - - - - - res\values - 1 - - - res\values - 1 - - - - - 1 - - - 1 - - - 0 - - - - - 1 - .framework - - - 1 - .framework - - - 0 - - - - - 1 - .dylib - - - 1 - .dylib - - - 0 - .dll;.bpl - - - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 0 - .bpl - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 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 - - - 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 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - - - - - - 1 - - - 1 - - - 1 - - - - - - - - Contents\Resources - 1 - - - Contents\Resources - 1 - - - - - library\lib\armeabi-v7a - 1 - - - library\lib\arm64-v8a - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 0 - - - - - library\lib\armeabi-v7a - 1 - - - - - 1 - - - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - - - - - - - - - - - False - False - True - False - - - 12 - - - - -
+ + + {89FED123-CDD0-460A-9CC6-5810B281BF84} + 19.5 + VCL + ConsoleApp.dpr + True + Debug + Win64 + 2 + Console + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + ConsoleApp + CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName) + $(BDS)\bin\delphi_PROJECTICON.ico + 1040 + ..\..\..\sources;..\..\..\lib\delphistompclient;..\..\..\lib\loggerpro;..\..\..\lib\dmustache;$(DCC_UnitSearchPath) + $(BDS)\bin\delphi_PROJECTICNS.icns + System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + false + false + false + false + false + + + true + Base + true + true + true + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png + true + true + true + $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png + true + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png + true + $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png + android-support-v4.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar + $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= + $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png + true + true + Debug + true + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + + + None + ..\bin + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + 1033 + FireDACSqliteDriver;TsiLang_XE5r;DBXSqliteDriver;FireDACPgDriver;fmx;TreeViewPresenter;IndySystem;i18n;TeeDB;frx19;vclib;inetdbbde;DBXInterBaseDriver;DataSnapClient;DataSnapCommon;DataSnapServer;DataSnapProviderClient;DPFAndroidPackagesXE5;DBXSybaseASEDriver;DbxCommonDriver;vclimg;dbxcds;DatasnapConnectorsFreePascal;MetropolisUILiveTile;vcldb;vcldsnap;fmxFireDAC;DBXDb2Driver;DBXOracleDriver;CustomIPTransport;vclribbon;dsnap;IndyIPServer;i18nDB;fmxase;vcl;IndyCore;IndyIPCommon;CloudService;DBXMSSQLDriver;FmxTeeUI;FireDACIBDriver;CodeSiteExpressPkg;DataSnapFireDAC;FireDACDBXDriver;inetdbxpress;FireDACDb2Driver;adortl;CustomAdaptersMDPackage;DataBindingsVCL;FireDACASADriver;bindcompfmx;vcldbx;FireDACODBCDriver;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;inetdb;Tee;DataBindings;DBXOdbcDriver;vclFireDAC;CPortLibDXE;xmlrtl;svnui;ibxpress;IndyProtocols;DBXMySQLDriver;FireDACCommonDriver;bindengine;vclactnband;soaprtl;bindcompdbx;FMXTee;TeeUI;bindcompvcl;vclie;FireDACADSDriver;vcltouch;fmxinfopower;VclSmp;FireDACMSSQLDriver;FireDAC;VCLRESTComponents;Intraweb;DBXInformixDriver;DataSnapConnectors;FireDACDataSnapDriver;dsnapcon;DBXFirebirdDriver;inet;fmxobj;FireDACMySQLDriver;vclx;svn;DBXSybaseASADriver;FireDACOracleDriver;fmxdae;RESTComponents;bdertl;VirtualTreesR;FireDACMSAccDriver;DataSnapIndy10ServerTransport;dbexpress;IndyIPClient;$(DCC_UsePackage) + CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName) + + + FireDACSqliteDriver;DBXSqliteDriver;FireDACPgDriver;fmx;TreeViewPresenter;IndySystem;TeeDB;vclib;DBXInterBaseDriver;DataSnapClient;DataSnapCommon;DataSnapServer;DataSnapProviderClient;DBXSybaseASEDriver;DbxCommonDriver;vclimg;dbxcds;DatasnapConnectorsFreePascal;MetropolisUILiveTile;vcldb;vcldsnap;fmxFireDAC;DBXDb2Driver;DBXOracleDriver;CustomIPTransport;vclribbon;dsnap;IndyIPServer;fmxase;vcl;IndyCore;IndyIPCommon;CloudService;DBXMSSQLDriver;FmxTeeUI;FireDACIBDriver;DataSnapFireDAC;FireDACDBXDriver;inetdbxpress;FireDACDb2Driver;adortl;DataBindingsVCL;FireDACASADriver;bindcompfmx;FireDACODBCDriver;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;inetdb;Tee;DataBindings;DBXOdbcDriver;vclFireDAC;xmlrtl;ibxpress;IndyProtocols;DBXMySQLDriver;FireDACCommonDriver;bindengine;vclactnband;soaprtl;bindcompdbx;FMXTee;TeeUI;bindcompvcl;vclie;FireDACADSDriver;vcltouch;fmxinfopower;VclSmp;FireDACMSSQLDriver;FireDAC;VCLRESTComponents;Intraweb;DBXInformixDriver;DataSnapConnectors;FireDACDataSnapDriver;dsnapcon;DBXFirebirdDriver;inet;fmxobj;FireDACMySQLDriver;vclx;DBXSybaseASADriver;FireDACOracleDriver;fmxdae;RESTComponents;VirtualTreesR;FireDACMSAccDriver;DataSnapIndy10ServerTransport;dbexpress;IndyIPClient;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + Debug + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + ..\bin + (None) + none + + + DEBUG;$(DCC_Define) + true + false + true + true + true + + + CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName) + 1033 + false + + + 1033 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + none + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + + MainSource + + + + +
wm
+ dfm + TWebModule +
+ +
WineCellarDataModule
+ dfm + TDataModule +
+ + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + +
+ + Delphi.Personality.12 + + + + + False + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1040 + 1252 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + ConsoleApp.dpr + + + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + + + ConsoleApp.exe + true + + + + + ConsoleApp.rsm + true + + + + + 1 + + + 0 + + + + + classes + 64 + + + classes + 64 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + 1 + + + 1 + + + 0 + + + + + 1 + .framework + + + 1 + .framework + + + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 1 + + + 1 + + + + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 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 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + + + + + + + + + + + + False + False + True + + + 12 + + + + +
diff --git a/samples/ISAPI/StandAlone/StandAloneServer.dpr b/samples/ISAPI/StandAlone/StandAloneServer.dpr deleted file mode 100644 index 4477d09f..00000000 --- a/samples/ISAPI/StandAlone/StandAloneServer.dpr +++ /dev/null @@ -1,55 +0,0 @@ -program StandAloneServer; -{$APPTYPE CONSOLE} - - -uses - System.SysUtils, - Winapi.Windows, - IdHTTPWebBrokerBridge, - Web.WebReq, - Web.WebBroker, - WebModuleU in '..\WebModules\WebModuleU.pas' {WebModule1: TWebModule} , - RoutingSampleControllerU in '..\Controllers\RoutingSampleControllerU.pas', - BusinessObjectsU in '..\BO\BusinessObjectsU.pas'; - -{$R *.res} - - -procedure RunServer(APort: Integer); -var - LInputRecord: TInputRecord; - LEvent: DWord; - LHandle: THandle; - LServer: TIdHTTPWebBrokerBridge; -begin - Writeln(Format('Starting HTTP Server or port %d', [APort])); - LServer := TIdHTTPWebBrokerBridge.Create(nil); - try - LServer.DefaultPort := APort; - LServer.Active := True; - Writeln('Press ESC to stop the server'); - LHandle := GetStdHandle(STD_INPUT_HANDLE); - while True do - begin - Win32Check(ReadConsoleInput(LHandle, LInputRecord, 1, LEvent)); - if (LInputRecord.EventType = KEY_EVENT) and - LInputRecord.Event.KeyEvent.bKeyDown and - (LInputRecord.Event.KeyEvent.wVirtualKeyCode = VK_ESCAPE) then - break; - end; - finally - LServer.Free; - end; -end; - -begin - try - if WebRequestHandler <> nil then - WebRequestHandler.WebModuleClass := WebModuleClass; - RunServer(8080); - except - on E: Exception do - Writeln(E.ClassName, ': ', E.Message); - end - -end. diff --git a/samples/ISAPI/bin/.env b/samples/ISAPI/bin/.env new file mode 100644 index 00000000..5d07214b --- /dev/null +++ b/samples/ISAPI/bin/.env @@ -0,0 +1 @@ +database.path = C:\DEV\dmvcframework\samples\WineCellarSample\winecellarserver\WINES_FB30.FDB \ No newline at end of file diff --git a/samples/ISAPI/bin/web.config b/samples/ISAPI/bin/web.config new file mode 100644 index 00000000..d08c7ca0 --- /dev/null +++ b/samples/ISAPI/bin/web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/samples/activerecord_showcase/EntitiesU.pas b/samples/activerecord_showcase/EntitiesU.pas index 59c8bdd2..7750bd1d 100644 --- a/samples/activerecord_showcase/EntitiesU.pas +++ b/samples/activerecord_showcase/EntitiesU.pas @@ -105,6 +105,12 @@ type [MVCNameCase(ncLowerCase)] [MVCTable('customers')] + [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)')] TCustomer = class(TCustomEntity) private {$IFNDEF USE_SEQUENCES} @@ -406,6 +412,35 @@ type property Orders: TObjectList read GetOrders; end; + [MVCNameCase(ncLowerCase)] + [MVCEntityActions([eaRetrieve])] + [MVCNamedSQLQuery('CustomersInTheSameCity', + 'SELECT c.id, c.DESCRIPTION, c.city, c.code, c.rating, (SELECT count(*) - 1 FROM customers c2 WHERE c2.CITY = c.CITY) customers_in_the_same_city ' + + 'FROM CUSTOMERS c WHERE city IS NOT NULL AND city <> '''' ORDER BY customers_in_the_same_city')] + TCustomerStats = class(TCustomEntity) + private + [MVCTableField('id', [foPrimaryKey, foAutoGenerated])] + fID: NullableInt64; + [MVCTableField('code')] + fCode: NullableString; + [MVCTableField('description')] + fCompanyName: NullableString; + [MVCTableField('city')] + fCity: string; + [MVCTableField('rating')] + fRating: NullableInt32; + [MVCTableField('customers_in_the_same_city')] + fCustomersInTheSameCity: Int32; + public + property ID: NullableInt64 read fID write fID; + property Code: NullableString read fCode write fCode; + property CompanyName: NullableString read fCompanyName write fCompanyName; + property City: string read fCity write fCity; + property Rating: NullableInt32 read fRating write fRating; + property CustomersInTheSameCity: Int32 read fCustomersInTheSameCity write fCustomersInTheSameCity; + end; + + [MVCNameCase(ncLowerCase)] [MVCTable('customers')] TCustomerWithLogic = class(TCustomer) diff --git a/samples/activerecord_showcase/MainFormU.dfm b/samples/activerecord_showcase/MainFormU.dfm index 5a2196ec..9b914f49 100644 --- a/samples/activerecord_showcase/MainFormU.dfm +++ b/samples/activerecord_showcase/MainFormU.dfm @@ -2,62 +2,49 @@ object MainForm: TMainForm Left = 0 Top = 0 Caption = 'TMVCActiveRecord - ShowCase' - ClientHeight = 1423 - ClientWidth = 2760 + ClientHeight = 569 + ClientWidth = 1104 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText - Font.Height = -28 + Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] OnDestroy = FormDestroy OnShow = FormShow - PixelsPerInch = 240 DesignSize = ( - 2760 - 1423) - TextHeight = 34 + 1104 + 569) + TextHeight = 13 object btnCRUD: TButton - Left = 20 - Top = 20 - Width = 303 - Height = 83 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 8 + Top = 8 + Width = 121 + Height = 33 Caption = 'CRUD' TabOrder = 0 OnClick = btnCRUDClick end object btnSelect: TButton - Left = 20 - Top = 605 - Width = 303 - Height = 83 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 8 + Top = 242 + Width = 121 + Height = 33 Caption = 'Queries' TabOrder = 1 OnClick = btnSelectClick end object Memo1: TMemo - Left = 700 - Top = 20 - Width = 2040 - Height = 1383 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 280 + Top = 8 + Width = 816 + Height = 553 Anchors = [akLeft, akTop, akRight, akBottom] Ctl3D = True DoubleBuffered = True Font.Charset = ANSI_CHARSET Font.Color = clWindowText - Font.Height = -33 + Font.Height = -13 Font.Name = 'Consolas' Font.Style = [] ParentCtl3D = False @@ -68,310 +55,236 @@ object MainForm: TMainForm TabOrder = 2 WantReturns = False WordWrap = False - ExplicitWidth = 2020 - ExplicitHeight = 1381 + ExplicitWidth = 812 + ExplicitHeight = 552 end object btnRelations: TButton - Left = 20 - Top = 703 - Width = 303 - Height = 87 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 8 + Top = 281 + Width = 121 + Height = 35 Caption = 'Relations' TabOrder = 3 OnClick = btnRelationsClick end object btnInheritance: TButton - Left = 20 - Top = 805 - Width = 303 - Height = 85 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 8 + Top = 322 + Width = 121 + Height = 34 Caption = 'Inheritance' TabOrder = 4 OnClick = btnInheritanceClick end object btnValidation: TButton - Left = 20 - Top = 905 - Width = 303 - Height = 85 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 8 + Top = 362 + Width = 121 + Height = 34 Caption = 'Validation' TabOrder = 5 OnClick = btnValidationClick end object btnMultiThreading: TButton - Left = 360 - Top = 20 - Width = 303 - Height = 83 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 144 + Top = 8 + Width = 121 + Height = 33 Caption = 'Multi Threading' TabOrder = 6 OnClick = btnMultiThreadingClick end object btnRQL: TButton - Left = 20 - Top = 1005 - Width = 303 - Height = 85 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 8 + Top = 402 + Width = 121 + Height = 34 Caption = 'RQL Query' TabOrder = 7 OnClick = btnRQLClick end object btnReadOnlyFields: TButton - Left = 20 - Top = 508 - Width = 303 - Height = 82 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 8 + Top = 203 + Width = 121 + Height = 33 Caption = 'CRUD With R/O Field' TabOrder = 8 OnClick = btnReadOnlyFieldsClick end object btnNullTest: TButton - Left = 360 - Top = 118 - Width = 303 - Height = 82 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 144 + Top = 47 + Width = 121 + Height = 33 Caption = 'Nullables' TabOrder = 9 OnClick = btnNullTestClick end object btnCRUDNoAutoInc: TButton - Left = 20 - Top = 215 - Width = 303 - Height = 83 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 8 + Top = 86 + Width = 121 + Height = 33 Caption = 'CRUD (no autoinc)' TabOrder = 10 OnClick = btnCRUDNoAutoIncClick end object btnCRUDWithStringPKs: TButton - Left = 20 - Top = 313 - Width = 303 - Height = 82 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 8 + Top = 125 + Width = 121 + Height = 33 Caption = 'CRUD (string pks)' TabOrder = 11 OnClick = btnCRUDWithStringPKsClick end object btnWithSpaces: TButton - Left = 20 - Top = 410 - Width = 303 - Height = 83 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 8 + Top = 164 + Width = 121 + Height = 33 Caption = 'CRUD (entity with spaces)' TabOrder = 12 WordWrap = True OnClick = btnWithSpacesClick end object btnCountWithRQL: TButton - Left = 360 - Top = 215 - Width = 303 - Height = 83 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 144 + Top = 86 + Width = 121 + Height = 33 Caption = 'Count with RQL' TabOrder = 13 OnClick = btnCountWithRQLClick end object btnReadAndWriteOnly: TButton - Left = 360 - Top = 313 - Width = 303 - Height = 82 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 144 + Top = 125 + Width = 121 + Height = 33 Caption = 'R/O, R/W' TabOrder = 14 OnClick = btnReadAndWriteOnlyClick end object btnClientGeneratedPK: TButton - Left = 360 - Top = 410 - Width = 303 - Height = 83 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 144 + Top = 164 + Width = 121 + Height = 33 Caption = 'Client Generated PKs' TabOrder = 15 OnClick = btnClientGeneratedPKClick end object btnAttributes: TButton - Left = 360 - Top = 508 - Width = 303 - Height = 82 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 144 + Top = 203 + Width = 121 + Height = 33 Caption = 'Attributes' TabOrder = 16 OnClick = btnAttributesClick end object btnJSON_XML_Types: TButton - Left = 360 - Top = 605 - Width = 303 - Height = 88 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 144 + Top = 242 + Width = 121 + Height = 35 Caption = 'JSON && XML' TabOrder = 17 OnClick = btnJSON_XML_TypesClick end object btnMerge: TButton - Left = 360 - Top = 708 - Width = 303 - Height = 85 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 144 + Top = 283 + Width = 121 + Height = 34 Caption = 'Merge' TabOrder = 18 OnClick = btnMergeClick end object btnTableFilter: TButton - Left = 360 - Top = 808 - Width = 303 - Height = 85 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 144 + Top = 323 + Width = 121 + Height = 34 Caption = 'Table Filter' TabOrder = 19 OnClick = btnTableFilterClick end object btnPartitioning: TButton - Left = 360 - Top = 908 - Width = 303 - Height = 82 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 144 + Top = 363 + Width = 121 + Height = 33 Caption = 'Table Partitioning' TabOrder = 20 OnClick = btnPartitioningClick end object btnCRUDWithGUID: TButton - Left = 20 - Top = 118 - Width = 303 - Height = 82 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 8 + Top = 47 + Width = 121 + Height = 33 Caption = 'CRUD (with GUID PK)' TabOrder = 21 OnClick = btnCRUDWithGUIDClick end object btnOOP: TButton - Left = 360 - Top = 1005 - Width = 303 - Height = 85 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 144 + Top = 402 + Width = 121 + Height = 34 Caption = 'OOP with Partitioning and Filtering' TabOrder = 22 WordWrap = True OnClick = btnOOPClick end object btnReadOnly: TButton - Left = 20 - Top = 1105 - Width = 303 - Height = 85 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 8 + Top = 442 + Width = 121 + Height = 34 Caption = 'Read/Only Entities' TabOrder = 23 OnClick = btnReadOnlyClick end object btnSpeed: TButton - Left = 20 - Top = 1205 - Width = 303 - Height = 85 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 8 + Top = 482 + Width = 121 + Height = 34 Caption = 'Metadata Speed Test' TabOrder = 24 OnClick = btnSpeedClick end object btnRefresh: TButton - Left = 360 - Top = 1105 - Width = 303 - Height = 85 - Margins.Left = 8 - Margins.Top = 8 - Margins.Right = 8 - Margins.Bottom = 8 + Left = 144 + Top = 442 + Width = 121 + Height = 34 Caption = 'Manual Refresh' TabOrder = 25 OnClick = btnRefreshClick end + object btnNamedQuery: TButton + Left = 144 + Top = 482 + Width = 121 + Height = 34 + Caption = 'Named Query' + TabOrder = 26 + OnClick = btnNamedQueryClick + end + object btnVirtualEntities: TButton + Left = 144 + Top = 522 + Width = 121 + Height = 34 + Caption = 'Virtual Entities' + TabOrder = 27 + OnClick = btnVirtualEntitiesClick + end object FDConnection1: TFDConnection Left = 312 Top = 40 diff --git a/samples/activerecord_showcase/MainFormU.pas b/samples/activerecord_showcase/MainFormU.pas index 2dd5fdf2..1bff37e1 100644 --- a/samples/activerecord_showcase/MainFormU.pas +++ b/samples/activerecord_showcase/MainFormU.pas @@ -58,6 +58,8 @@ type btnReadOnly: TButton; btnSpeed: TButton; btnRefresh: TButton; + btnNamedQuery: TButton; + btnVirtualEntities: TButton; procedure btnCRUDClick(Sender: TObject); procedure btnInheritanceClick(Sender: TObject); procedure btnMultiThreadingClick(Sender: TObject); @@ -86,6 +88,8 @@ type procedure btnReadOnlyClick(Sender: TObject); procedure btnSpeedClick(Sender: TObject); procedure btnRefreshClick(Sender: TObject); + procedure btnNamedQueryClick(Sender: TObject); + procedure btnVirtualEntitiesClick(Sender: TObject); private procedure Log(const Value: string); procedure LoadCustomers; @@ -649,6 +653,61 @@ begin 'in(City,["Rome","New York","London","Melbourne","Berlin"])').ToString + ' records'); end; +procedure TMainForm.btnNamedQueryClick(Sender: TObject); +begin + Log('** Named SQL Query'); + Log('QuerySQL: RatingLessThanPar'); + var lCustomers := TMVCActiveRecord.SelectByNamedQuery('RatingLessThanPar', [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: RatingEqualsToPar'); + lCustomers := TMVCActiveRecord.SelectByNamedQuery('RatingEqualsToPar', [3], [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('** Named RQL Query'); + Log('QueryRQL: RatingLessThanPar'); + lCustomers := TMVCActiveRecord.SelectRQLByNamedQuery('RatingLessThanPar', [4], 1000); + 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('QueryRQL: RatingEqualsToPar'); + lCustomers := TMVCActiveRecord.SelectRQLByNamedQuery('RatingEqualsToPar', [3], 1000); + 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; + procedure TMainForm.btnNullablesClick(Sender: TObject); var lCustomer: TCustomer; @@ -1040,6 +1099,7 @@ var lItem: TMVCActiveRecord; lCustomer: TCustomer; lCustList: TObjectList; + lRecCount: Integer; const cRQL1 = 'in(City,["Rome","London"]);sort(+code);limit(0,50)'; cRQL2 = 'and(eq(City,"Rome"),or(contains(CompanyName,"GAS"),contains(CompanyName,"Motors")))'; @@ -1133,6 +1193,114 @@ begin lList.Free; 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.Create; + try + lRecCount := TMVCActiveRecord.SelectRQL(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) - 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) - 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) - 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) - 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) - 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; procedure TMainForm.btnSelectClick(Sender: TObject); @@ -1541,6 +1709,24 @@ begin end; end; +procedure TMainForm.btnVirtualEntitiesClick(Sender: TObject); +begin + var lCustStats := TMVCActiveRecord.SelectByNamedQuery('CustomersInTheSameCity', [], []); + try + for var lCustomer in lCustStats do + begin + Log(Format('%4d - %8.5s - %s - (%d other customers in the same city)', [ + lCustomer.ID.ValueOrDefault, + lCustomer.Code.ValueOrDefault, + lCustomer.CompanyName.ValueOrDefault, + lCustomer.CustomersInTheSameCity + ])); + end; + finally + lCustStats.Free; + end; +end; + procedure TMainForm.btnWithSpacesClick(Sender: TObject); var lCustomer: TCustomerWithSpaces; diff --git a/samples/commons/BusinessObjectsU.pas b/samples/commons/BusinessObjectsU.pas index 4d06c451..61a8505d 100644 --- a/samples/commons/BusinessObjectsU.pas +++ b/samples/commons/BusinessObjectsU.pas @@ -203,7 +203,7 @@ type TInterfacedPerson = class(TInterfacedObject, IPerson) private fName: string; - FDOB: TDate; + fDOB: TDate; fAge: Integer; protected function GetName: string; @@ -213,9 +213,10 @@ type function GetDOB: TDate; procedure SetDOB(const Value: TDate); public - property name: string read GetName write SetName; + property Name: string read GetName write SetName; property Age: Integer read GetAge write SetAge; property DOB: TDate read GetDOB write SetDOB; + constructor Create(Name: String; Age: Integer; DOB: TDate); virtual; end; //TPeople = class(TObjectList); @@ -651,6 +652,14 @@ end; { TInterfacedPerson } +constructor TInterfacedPerson.Create(Name: String; Age: Integer; DOB: TDate); +begin + inherited Create; + fName := Name; + fAge := Age; + fDOB := DOB; +end; + function TInterfacedPerson.GetAge: Integer; begin Result := fAge; diff --git a/samples/data/activerecorddb_firebird_script.sql b/samples/data/activerecorddb_firebird_script.sql index c9daae32..1640d1b2 100644 --- a/samples/data/activerecorddb_firebird_script.sql +++ b/samples/data/activerecorddb_firebird_script.sql @@ -7,7 +7,7 @@ CREATE TABLE articles ( CREATE TABLE customers ( id integer GENERATED BY DEFAULT AS IDENTITY, - code varchar(20) NOT NULL, + code varchar(20), description varchar(200), city varchar(200), rating INTEGER, diff --git a/samples/data/people_dataset.json b/samples/data/people_dataset.json new file mode 100644 index 00000000..5b7bd3ea --- /dev/null +++ b/samples/data/people_dataset.json @@ -0,0 +1 @@ +{"FDBS":{"Version":16,"Manager":{"UpdatesRegistry":true,"TableList":[{"class":"Table","Name":"FDMemTable1","SourceName":"FDMemTable1","TabID":0,"EnforceConstraints":false,"MinimumCapacity":50,"CheckNotNull":false,"ColumnList":[{"class":"Column","Name":"id","SourceName":"id","SourceID":1,"DataType":"Int64","Searchable":true,"AllowNull":true,"Base":true,"OAllowNull":true,"OInUpdate":true,"OInWhere":true,"OInKey":true,"OriginColName":"id"},{"class":"Column","Name":"last_name","SourceName":"last_name","SourceID":2,"DataType":"WideString","Size":100,"Searchable":true,"AllowNull":true,"Base":true,"OAllowNull":true,"OInUpdate":true,"OInWhere":true,"OriginColName":"last_name","SourceSize":100},{"class":"Column","Name":"first_name","SourceName":"first_name","SourceID":3,"DataType":"WideString","Size":100,"Searchable":true,"AllowNull":true,"Base":true,"OAllowNull":true,"OInUpdate":true,"OInWhere":true,"OriginColName":"first_name","SourceSize":100},{"class":"Column","Name":"dob","SourceName":"dob","SourceID":4,"DataType":"Date","Searchable":true,"AllowNull":true,"Base":true,"OAllowNull":true,"OInUpdate":true,"OInWhere":true,"OriginColName":"dob"},{"class":"Column","Name":"full_name","SourceName":"full_name","SourceID":5,"DataType":"WideString","Size":80,"Searchable":true,"AllowNull":true,"Base":true,"OAllowNull":true,"OInUpdate":true,"OInWhere":true,"OriginColName":"full_name","SourceSize":80},{"class":"Column","Name":"is_male","SourceName":"is_male","SourceID":6,"DataType":"Boolean","Searchable":true,"AllowNull":true,"Base":true,"OAllowNull":true,"OInUpdate":true,"OInWhere":true,"OriginColName":"is_male"},{"class":"Column","Name":"note","SourceName":"note","SourceID":7,"DataType":"WideMemo","Searchable":true,"AllowNull":true,"BlobData":true,"Base":true,"OAllowNull":true,"OInUpdate":true,"OInWhere":true,"OriginColName":"note"},{"class":"Column","Name":"photo","SourceName":"photo","SourceID":8,"DataType":"Blob","Searchable":true,"AllowNull":true,"BlobData":true,"Base":true,"OAllowNull":true,"OInUpdate":true,"OInWhere":true,"OriginColName":"photo"},{"class":"Column","Name":"person_type","SourceName":"person_type","SourceID":9,"DataType":"WideString","Size":8190,"Searchable":true,"AllowNull":true,"BlobData":true,"Base":true,"OAllowNull":true,"OInUpdate":true,"OInWhere":true,"OriginColName":"person_type","SourceSize":8190},{"class":"Column","Name":"salary","SourceName":"salary","SourceID":10,"DataType":"Currency","Precision":19,"Scale":4,"Searchable":true,"AllowNull":true,"Base":true,"OAllowNull":true,"OInUpdate":true,"OInWhere":true,"OriginColName":"salary","SourcePrecision":19,"SourceScale":4},{"class":"Column","Name":"annual_bonus","SourceName":"annual_bonus","SourceID":11,"DataType":"Currency","Precision":19,"Scale":4,"Searchable":true,"AllowNull":true,"Base":true,"OAllowNull":true,"OInUpdate":true,"OInWhere":true,"OriginColName":"annual_bonus","SourcePrecision":19,"SourceScale":4}],"ConstraintList":[],"ViewList":[],"RowList":[{"RowID":0,"Original":{"id":235,"last_name":"Richards","first_name":"Reed","dob":"19851104","full_name":"Reed Richards","is_male":true,"person_type":"person","photo":""}},{"RowID":1,"Original":{"id":236,"last_name":"Parker","first_name":"Peter","dob":"19851104","full_name":"Peter Parker","is_male":true,"person_type":"employee","salary":2100,"photo":""}},{"RowID":2,"Original":{"id":237,"last_name":"Storm","first_name":"Sue","dob":"19751014","full_name":"Sue Storm","is_male":false,"person_type":"employee","salary":2200,"photo":""}},{"RowID":3,"Original":{"id":238,"last_name":"Banner","first_name":"Bruce","dob":"19751104","full_name":"Bruce Banner","is_male":true,"person_type":"manager","salary":2800,"annual_bonus":5000,"photo":""}}]}],"RelationList":[],"UpdatesJournal":{"SavePoint":4,"Changes":[]}}}} \ No newline at end of file diff --git a/samples/funcion_actions_showcase/ControllerU.pas b/samples/funcion_actions_showcase/ControllerU.pas new file mode 100644 index 00000000..8fb632d3 --- /dev/null +++ b/samples/funcion_actions_showcase/ControllerU.pas @@ -0,0 +1,246 @@ +unit ControllerU; + +interface + +uses + MVCFramework, MVCFramework.Commons, MVCFramework.Serializer.Commons, + System.Generics.Collections, Data.DB; + +type + [MVCNameCase(ncCamelCase)] + TPersonRec = record + FirstName, LastName: String; + Age: Integer; + class function Create: TPersonRec; static; + end; + + [MVCNameCase(ncCamelCase)] + TPerson = class + private + fAge: Integer; + fFirstName, fLastName: String; + public + property FirstName: String read fFirstName write fFirstName; + property LastName: String read fLastName write fLastName; + property Age: Integer read fAge write fAge; + constructor Create(FirstName, LastName: String; Age: Integer); + end; + + [MVCPath('/api')] + TMyController = class(TMVCController) + public + { actions returning a simple type } + [MVCPath('/sumsasinteger/($A)/($B)')] + function GetSum(const A, B: Integer): Integer; + [MVCPath('/sumsasfloat/($A)/($B)')] + function GetSumAsFloat(const A, B: Extended): Extended; + + { actions returning records } + [MVCPath('/records/single')] + function GetSingleRecord: TPersonRec; + [MVCPath('/records/multiple')] + function GetMultipleRecords: TArray; + + { actions returning objects } + [MVCPath('/objects/single')] + function GetSingleObject: TPerson; + [MVCPath('/objects/multiple')] + function GetMultipleObjects: TObjectList; + + { actions returning datasets } + [MVCPath('/datasets/single')] + function GetSingleDataSet: TDataSet; + [MVCPath('/datasets/multiple')] + function GetMultipleDataSet: TEnumerable; + [MVCPath('/datasets/multiple2')] + function GetMultipleDataSet2: IMVCObjectDictionary; + + { customize response headers } + [MVCPath('/headers')] + function GetWithCustomHeaders: TObjectList; + + { using IMVCResponse } + [MVCPath('/mvcresponse/message')] + function GetMVCResponseSimple: IMVCResponse; + [MVCPath('/mvcresponse/data')] + function GetMVCResponseWithData: IMVCResponse; + [MVCPath('/mvcresponse/list')] + function GetMVCResponseWithObjectList: IMVCResponse; + [MVCPath('/mvcresponse/dictionary')] + function GetMVCResponseWithObjectDictionary: IMVCResponse; + [MVCPath('/mvcresponse/error')] + function GetMVCErrorResponse: IMVCResponse; + end; + +implementation + +uses + System.SysUtils, MVCFramework.Logger, System.StrUtils, System.DateUtils, + MainDMU, FireDAC.Comp.Client, MVCFramework.FireDAC.Utils; + +{ TMyController } + +function TMyController.GetMultipleDataSet: TEnumerable; +begin + var lDM := TdmMain.Create(nil); + try + lDM.dsPeople.Open; + var lList := TObjectList.Create; + lList.Add(TFDMemTable.CloneFrom(lDM.dsPeople)); + lList.Add(TFDMemTable.CloneFrom(lDM.dsPeople)); + Result := lList; + finally + lDM.Free; + end; +end; + +function TMyController.GetMultipleDataSet2: IMVCObjectDictionary; +begin + var lDM := TdmMain.Create(nil); + try + lDM.dsPeople.Open; + Result := ObjectDict() + .Add('people1', TFDMemTable.CloneFrom(lDM.dsPeople)) + .Add('people2', TFDMemTable.CloneFrom(lDM.dsPeople)); + finally + lDM.Free; + end; +end; + +function TMyController.GetMultipleObjects: TObjectList; +begin + Result := TObjectList.Create; + + Result.Add(TPerson.Create('Daniele', 'Teti', YearsBetween(Date, EncodeDateDay(1979, 1)))); + + Result.Add(TPerson.Create('Daniele', 'Teti', Result[0].Age + 10)); + + Result.Add(TPerson.Create('Daniele', 'Teti', Result[0].Age + 20)); +end; + +function TMyController.GetMultipleRecords: TArray; +begin + SetLength(Result, 3); + Result[0] := TPersonRec.Create; + Result[1] := TPersonRec.Create; + Result[2] := TPersonRec.Create; + + Inc(Result[1].Age, 10); + + Inc(Result[2].Age, 20); +end; + +function TMyController.GetMVCErrorResponse: IMVCResponse; +begin + Result := TMVCErrorResponse.Create(500, 'boom'); +end; + +function TMyController.GetMVCResponseSimple: IMVCResponse; +begin + Result := MVCResponse(HTTP_STATUS.OK, 'My Message', 'My Reason String'); +end; + +function TMyController.GetMVCResponseWithData: IMVCResponse; +begin + Result := MVCResponse(HTTP_STATUS.OK, TPerson.Create('Daniele','Teti', 99)); +end; + +function TMyController.GetMVCResponseWithObjectDictionary: IMVCResponse; +begin + Result := MVCResponse( + HTTP_STATUS.OK, + ObjectDict() + .Add('people1', TObjectList.Create([ + TPerson.Create('Daniele','Teti', 99), + TPerson.Create('Peter','Parker', 25), + TPerson.Create('Bruce','Banner', 45) + ]) + ) + .Add('people2', TObjectList.Create([ + TPerson.Create('Daniele','Teti', 99), + TPerson.Create('Peter','Parker', 25), + TPerson.Create('Bruce','Banner', 45) + ]) + ) + ); +end; + +function TMyController.GetMVCResponseWithObjectList: IMVCResponse; +begin + Result := MVCResponse( + HTTP_STATUS.OK, + TObjectList.Create([ + TPerson.Create('Daniele','Teti', 99), + TPerson.Create('Peter','Parker', 25), + TPerson.Create('Bruce','Banner', 45) + ]) + ); +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))); +end; + +function TMyController.GetSingleRecord: TPersonRec; +begin + Result := TPersonRec.Create; +end; + +function TMyController.GetSum(const A, B: Integer): Integer; +begin + Result := A + B; +end; + +function TMyController.GetSumAsFloat(const A, B: Extended): Extended; +begin + Result := A + B; +end; + +function TMyController.GetWithCustomHeaders: TObjectList; +begin + Result := TObjectList.Create; + + Result.Add(TPerson.Create('Daniele', 'Teti', YearsBetween(Date, EncodeDateDay(1979, 1)))); + + Result.Add(TPerson.Create('Daniele', 'Teti', Result[0].Age + 10)); + + Result.Add(TPerson.Create('Daniele', 'Teti', Result[0].Age + 20)); + + { customize headers } + Context.Response.StatusCode := HTTP_STATUS.PartialContent; + Context.Response.ContentType := TMVCMediaType.APPLICATION_JSON; + Context.Response.SetCustomHeader('X-MYHEADER', 'HELLO WORLD'); +end; + +{ TPersonRec } + +class function TPersonRec.Create: TPersonRec; +begin + Result.FirstName := 'Daniele'; + Result.LastName := 'Teti'; + Result.Age := YearsBetween(Date, EncodeDateDay(1979, 1)); +end; + +{ TPerson } + +constructor TPerson.Create(FirstName, LastName: String; Age: Integer); +begin + inherited Create; + fFirstName := FirstName; + fLastName := LastName; + fAge := Age; +end; + +end. diff --git a/samples/funcion_actions_showcase/MainDMU.dfm b/samples/funcion_actions_showcase/MainDMU.dfm new file mode 100644 index 00000000..6a3e36e8 --- /dev/null +++ b/samples/funcion_actions_showcase/MainDMU.dfm @@ -0,0 +1,101 @@ +object dmMain: TdmMain + Height = 162 + Width = 312 + object dsPeople: TFDMemTable + Active = True + FetchOptions.AssignedValues = [evMode] + FetchOptions.Mode = fmAll + ResourceOptions.AssignedValues = [rvPersistent, rvSilentMode] + ResourceOptions.Persistent = True + ResourceOptions.SilentMode = True + UpdateOptions.AssignedValues = [uvCheckRequired, uvAutoCommitUpdates] + UpdateOptions.CheckRequired = False + UpdateOptions.AutoCommitUpdates = True + Left = 176 + Top = 88 + Content = { + 4144425310000000CA060000FF00010001FF02FF03040016000000460044004D + 0065006D005400610062006C0065003100050016000000460044004D0065006D + 005400610062006C0065003100060000000000070000080032000000090000FF + 0AFF0B04000400000069006400050004000000690064000C00010000000E000D + 000F000110000111000112000113000114000115000116000400000069006400 + FEFF0B0400120000006C006100730074005F006E0061006D0065000500120000 + 006C006100730074005F006E0061006D0065000C00020000000E001700180064 + 0000000F00011000011100011200011300011400011600120000006C00610073 + 0074005F006E0061006D006500190064000000FEFF0B04001400000066006900 + 7200730074005F006E0061006D00650005001400000066006900720073007400 + 5F006E0061006D0065000C00030000000E0017001800640000000F0001100001 + 110001120001130001140001160014000000660069007200730074005F006E00 + 61006D006500190064000000FEFF0B04000600000064006F0062000500060000 + 0064006F0062000C00040000000E001A000F0001100001110001120001130001 + 14000116000600000064006F006200FEFF0B040012000000660075006C006C00 + 5F006E0061006D006500050012000000660075006C006C005F006E0061006D00 + 65000C00050000000E0017001800500000000F00011000011100011200011300 + 01140001160012000000660075006C006C005F006E0061006D00650019005000 + 0000FEFF0B04000E000000690073005F006D0061006C00650005000E00000069 + 0073005F006D0061006C0065000C00060000000E001B000F0001100001110001 + 12000113000114000116000E000000690073005F006D0061006C006500FEFF0B + 0400080000006E006F00740065000500080000006E006F00740065000C000700 + 00000E001C000F00011000011D00011100011200011300011400011600080000 + 006E006F0074006500FEFF0B04000A000000700068006F0074006F0005000A00 + 0000700068006F0074006F000C00080000000E001E000F00011000011D000111 + 000112000113000114000116000A000000700068006F0074006F00FEFF0B0400 + 1600000070006500720073006F006E005F007400790070006500050016000000 + 70006500720073006F006E005F0074007900700065000C00090000000E001700 + 1800FE1F00000F00011000011D00011100011200011300011400011600160000 + 0070006500720073006F006E005F0074007900700065001900FE1F0000FEFF0B + 04000C000000730061006C0061007200790005000C000000730061006C006100 + 720079000C000A0000000E001F002000130000002100040000000F0001100001 + 11000112000113000114000116000C000000730061006C006100720079002200 + 13000000230004000000FEFF0B04001800000061006E006E00750061006C005F + 0062006F006E007500730005001800000061006E006E00750061006C005F0062 + 006F006E00750073000C000B0000000E001F002000130000002100040000000F + 000110000111000112000113000114000116001800000061006E006E00750061 + 006C005F0062006F006E0075007300220013000000230004000000FEFEFF24FE + FF25FEFF26FF27280000000000FF290000EB0000000000000001001000000052 + 00690063006800610072006400730002000800000052006500650064000300D5 + 0F0B0004001A0000005200650065006400200052006900630068006100720064 + 0073000500FFFF08000C00000070006500720073006F006E00FEFEFF27280001 + 000000FF290000EC0000000000000001000C0000005000610072006B00650072 + 0002000A000000500065007400650072000300D50F0B00040018000000500065 + 0074006500720020005000610072006B00650072000500FFFF08001000000065 + 006D0070006C006F007900650065000900406F400100000000FEFEFF27280002 + 000000FF290000ED0000000000000001000A000000530074006F0072006D0002 + 000600000053007500650003007B010B00040012000000530075006500200053 + 0074006F0072006D000500000008001000000065006D0070006C006F00790065 + 006500090080B14F0100000000FEFEFF27280003000000FF290000EE00000000 + 00000001000C000000420061006E006E006500720002000A0000004200720075 + 0063006500030090010B00040018000000420072007500630065002000420061 + 006E006E00650072000500FFFF08000E0000006D0061006E0061006700650072 + 000900003FAB01000000000A0080F0FA0200000000FEFEFEFEFEFF2AFEFF2B2C + 0004000000FF2DFEFEFE0E004D0061006E0061006700650072001E0055007000 + 6400610074006500730052006500670069007300740072007900120054006100 + 62006C0065004C006900730074000A005400610062006C00650008004E006100 + 6D006500140053006F0075007200630065004E0061006D0065000A0054006100 + 620049004400240045006E0066006F0072006300650043006F006E0073007400 + 7200610069006E00740073001E004D0069006E0069006D0075006D0043006100 + 700061006300690074007900180043006800650063006B004E006F0074004E00 + 75006C006C00140043006F006C0075006D006E004C006900730074000C004300 + 6F006C0075006D006E00100053006F007500720063006500490044000E006400 + 740049006E007400360034001000440061007400610054007900700065001400 + 530065006100720063006800610062006C006500120041006C006C006F007700 + 4E0075006C006C000800420061007300650014004F0041006C006C006F007700 + 4E0075006C006C0012004F0049006E0055007000640061007400650010004F00 + 49006E00570068006500720065000C004F0049006E004B00650079001A004F00 + 72006900670069006E0043006F006C004E0061006D0065001800640074005700 + 69006400650053007400720069006E0067000800530069007A00650014005300 + 6F007500720063006500530069007A0065000C00640074004400610074006500 + 12006400740042006F006F006C00650061006E00140064007400570069006400 + 65004D0065006D006F00100042006C006F00620044006100740061000C006400 + 740042006C006F006200140064007400430075007200720065006E0063007900 + 120050007200650063006900730069006F006E000A005300630061006C006500 + 1E0053006F00750072006300650050007200650063006900730069006F006E00 + 160053006F0075007200630065005300630061006C0065001C0043006F006E00 + 730074007200610069006E0074004C0069007300740010005600690065007700 + 4C006900730074000E0052006F0077004C00690073007400060052006F007700 + 0A0052006F0077004900440010004F0072006900670069006E0061006C001800 + 520065006C006100740069006F006E004C006900730074001C00550070006400 + 61007400650073004A006F00750072006E0061006C0012005300610076006500 + 50006F0069006E0074000E004300680061006E00670065007300} + end +end diff --git a/samples/funcion_actions_showcase/MainDMU.pas b/samples/funcion_actions_showcase/MainDMU.pas new file mode 100644 index 00000000..cb1384b1 --- /dev/null +++ b/samples/funcion_actions_showcase/MainDMU.pas @@ -0,0 +1,26 @@ +unit MainDMU; + +interface + +uses + System.SysUtils, System.Classes, FireDAC.Stan.Intf, FireDAC.Stan.Option, + FireDAC.Stan.Param, FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, + FireDAC.DApt.Intf, FireDAC.Stan.StorageBin, Data.DB, FireDAC.Comp.DataSet, + FireDAC.Comp.Client; + +type + TdmMain = class(TDataModule) + dsPeople: TFDMemTable; + private + { Private declarations } + public + { Public declarations } + end; + +implementation + +{%CLASSGROUP 'System.Classes.TPersistent'} + +{$R *.dfm} + +end. diff --git a/samples/funcion_actions_showcase/WebModuleU.dfm b/samples/funcion_actions_showcase/WebModuleU.dfm new file mode 100644 index 00000000..02d66b97 --- /dev/null +++ b/samples/funcion_actions_showcase/WebModuleU.dfm @@ -0,0 +1,7 @@ +object MyWebModule: TMyWebModule + OnCreate = WebModuleCreate + OnDestroy = WebModuleDestroy + Actions = <> + Height = 230 + Width = 415 +end diff --git a/samples/funcion_actions_showcase/WebModuleU.pas b/samples/funcion_actions_showcase/WebModuleU.pas new file mode 100644 index 00000000..1bd9f21e --- /dev/null +++ b/samples/funcion_actions_showcase/WebModuleU.pas @@ -0,0 +1,71 @@ +unit WebModuleU; + +interface + +uses + System.SysUtils, + System.Classes, + Web.HTTPApp, + MVCFramework; + +type + TMyWebModule = class(TWebModule) + procedure WebModuleCreate(Sender: TObject); + procedure WebModuleDestroy(Sender: TObject); + private + FMVC: TMVCEngine; + public + { Public declarations } + end; + +var + WebModuleClass: TComponentClass = TMyWebModule; + +implementation + +{$R *.dfm} + +uses + System.IOUtils, + MVCFramework.Commons, + ControllerU; + +procedure TMyWebModule.WebModuleCreate(Sender: TObject); +begin + FMVC := TMVCEngine.Create(Self, + procedure(Config: TMVCConfig) + begin + Config.dotEnv := dotEnv; + // session timeout (0 means session cookie) + Config[TMVCConfigKey.SessionTimeout] := dotEnv.Env('dmvc.session_timeout', '0'); + //default content-type + Config[TMVCConfigKey.DefaultContentType] := dotEnv.Env('dmvc.default.content_type', TMVCConstants.DEFAULT_CONTENT_TYPE); + //default content charset + Config[TMVCConfigKey.DefaultContentCharset] := dotEnv.Env('dmvc.default.content_charset', TMVCConstants.DEFAULT_CONTENT_CHARSET); + //unhandled actions are permitted? + Config[TMVCConfigKey.AllowUnhandledAction] := dotEnv.Env('dmvc.allow_unhandled_actions', 'false'); + //enables or not system controllers loading (available only from localhost requests) + Config[TMVCConfigKey.LoadSystemControllers] := dotEnv.Env('dmvc.load_system_controllers', 'true'); + //default view file extension + Config[TMVCConfigKey.DefaultViewFileExtension] := dotEnv.Env('dmvc.default.view_file_extension', 'html'); + //view path + Config[TMVCConfigKey.ViewPath] := dotEnv.Env('dmvc.view_path', 'templates'); + //Max Record Count for automatic Entities CRUD + Config[TMVCConfigKey.MaxEntitiesRecordCount] := dotEnv.Env('dmvc.max_entities_record_count', IntToStr(TMVCConstants.MAX_RECORD_COUNT)); + //Enable Server Signature in response + Config[TMVCConfigKey.ExposeServerSignature] := dotEnv.Env('dmvc.expose_server_signature', 'false'); + //Enable X-Powered-By Header in response + Config[TMVCConfigKey.ExposeXPoweredBy] := dotEnv.Env('dmvc.expose_x_powered_by', 'true'); + // Max request size in bytes + Config[TMVCConfigKey.MaxRequestSize] := dotEnv.Env('dmvc.max_request_size', IntToStr(TMVCConstants.DEFAULT_MAX_REQUEST_SIZE)); + end); + FMVC.AddController(TMyController); + +end; + +procedure TMyWebModule.WebModuleDestroy(Sender: TObject); +begin + FMVC.Free; +end; + +end. diff --git a/samples/funcion_actions_showcase/function_actions_showcase.dpr b/samples/funcion_actions_showcase/function_actions_showcase.dpr new file mode 100644 index 00000000..5d304a46 --- /dev/null +++ b/samples/funcion_actions_showcase/function_actions_showcase.dpr @@ -0,0 +1,83 @@ +program function_actions_showcase; + +{$APPTYPE CONSOLE} + +uses + System.SysUtils, + MVCFramework, + MVCFramework.Logger, + MVCFramework.DotEnv, + MVCFramework.Commons, + MVCFramework.Signal, + Web.ReqMulti, + Web.WebReq, + Web.WebBroker, + IdContext, + IdHTTPWebBrokerBridge, + ControllerU in 'ControllerU.pas', + WebModuleU in 'WebModuleU.pas' {MyWebModule: TWebModule}, + MainDMU in 'MainDMU.pas' {dmMain: TDataModule}; + +{$R *.res} + + +procedure RunServer(APort: Integer); +var + LServer: TIdHTTPWebBrokerBridge; +begin + Writeln('** DMVCFramework Server ** build ' + DMVCFRAMEWORK_VERSION); + LServer := TIdHTTPWebBrokerBridge.Create(nil); + try + LServer.OnParseAuthentication := TMVCParseAuthentication.OnParseAuthentication; + LServer.DefaultPort := APort; + LServer.KeepAlive := True; + LServer.MaxConnections := dotEnv.Env('dmvc.webbroker.max_connections', 0); + LServer.ListenQueue := dotEnv.Env('dmvc.indy.listen_queue', 500); + + LServer.Active := True; + WriteLn('Listening on port ', APort); + Write('CTRL+C to shutdown the server'); + WaitForTerminationSignal; + EnterInShutdownState; + LServer.Active := False; + finally + LServer.Free; + end; +end; + +begin + { Enable ReportMemoryLeaksOnShutdown during debug } + // ReportMemoryLeaksOnShutdown := True; + IsMultiThread := True; + + // DMVCFramework Specific Configuration + // When MVCSerializeNulls = True empty nullables and nil are serialized as json null. + // When MVCSerializeNulls = False empty nullables and nil are not serialized at all. + MVCSerializeNulls := True; + + try + if WebRequestHandler <> nil then + WebRequestHandler.WebModuleClass := WebModuleClass; + + dotEnvConfigure( + function: IMVCDotEnv + begin + Result := NewDotEnv + .WithStrategy(TMVCDotEnvPriority.FileThenEnv) + //if available, by default, loads default environment (.env) + .UseProfile('test') //if available loads the test environment (.env.test) + .UseProfile('prod') //if available loads the prod environment (.env.prod) + .UseLogger(procedure(LogItem: String) + begin + LogW('dotEnv: ' + LogItem); + end) + .Build(); //uses the executable folder to look for .env* files + end); + + WebRequestHandlerProc.MaxConnections := dotEnv.Env('dmvc.handler.max_connections', 1024); + RunServer(dotEnv.Env('dmvc.server.port', 8080)); + except + on E: Exception do + Writeln(E.ClassName, ': ', E.Message); + end; +end. diff --git a/packages/d111/dmvcframeworkRT.dproj b/samples/funcion_actions_showcase/function_actions_showcase.dproj similarity index 75% rename from packages/d111/dmvcframeworkRT.dproj rename to samples/funcion_actions_showcase/function_actions_showcase.dproj index 78f3dec3..98497095 100644 --- a/packages/d111/dmvcframeworkRT.dproj +++ b/samples/funcion_actions_showcase/function_actions_showcase.dproj @@ -1,14 +1,14 @@  - {96D17257-AF74-48CB-9893-7BCCB56A069D} - dmvcframeworkRT.dpk + {84012097-1BD4-41B3-A479-B831D1147725} 19.5 None True Debug Win32 1 - Package + Console + function_actions_showcase.dpr true @@ -23,6 +23,11 @@ Base true + + true + Base + true + true Base @@ -57,37 +62,34 @@ false false false - true - true System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) - All - dmvcframeworkRT - true - 1040 - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - DMVCFramework - CopyRight (2010-2020) Daniele Teti and the DMVCFramework Team + true + $(BDS)\bin\delphi_PROJECTICON.ico + $(BDS)\bin\delphi_PROJECTICNS.icns + $(DMVC);$(DCC_UnitSearchPath) + VCL;$(DCC_Framework) + function_actions_showcase - package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= - Debug - annotation-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.0.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.0.1.dex.jar;core-runtime-2.0.1.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.0.0.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.0.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.0.0.dex.jar;lifecycle-runtime-2.0.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.0.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar + fmx;DbxCommonDriver;bindengine;IndyIPCommon;emsclient;FireDACCommonDriver;IndyProtocols;Skia.Package.RTL;RadiantShapesFmx_Design;IndyIPClient;dbxcds;FmxTeeUI;bindcompfmx;ibmonitor;FireDACSqliteDriver;DbxClientDriver;soapmidas;fmxFireDAC;dbexpress;Python;inet;DataSnapCommon;fmxase;DzHTMLText_FMX;dbrtl;FireDACDBXDriver;Skia.Package.FMX;CustomIPTransport;DBXInterBaseDriver;IndySystem;RadiantShapesFmx;ibxbindings;bindcomp;FireDACCommon;IndyCore;RESTBackendComponents;bindcompdbx;rtl;RESTComponents;DBXSqliteDriver;IndyIPServer;dsnapxml;DataSnapClient;DataSnapProviderClient;DataSnapFireDAC;emsclientfiredac;FireDAC;FireDACDSDriver;xmlrtl;tethering;ibxpress;dsnap;CloudService;FMXTee;DataSnapNativeClient;PythonFmx;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage) + activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar - package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= - Debug - annotation-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.0.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.0.1.dex.jar;core-runtime-2.0.1.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.0.0.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.0.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.0.0.dex.jar;lifecycle-runtime-2.0.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.0.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar + fmx;DbxCommonDriver;bindengine;IndyIPCommon;emsclient;FireDACCommonDriver;IndyProtocols;Skia.Package.RTL;RadiantShapesFmx_Design;IndyIPClient;dbxcds;FmxTeeUI;bindcompfmx;ibmonitor;FireDACSqliteDriver;DbxClientDriver;soapmidas;fmxFireDAC;dbexpress;Python;inet;DataSnapCommon;DzHTMLText_FMX;dbrtl;FireDACDBXDriver;Skia.Package.FMX;CustomIPTransport;DBXInterBaseDriver;IndySystem;RadiantShapesFmx;ibxbindings;bindcomp;FireDACCommon;IndyCore;RESTBackendComponents;bindcompdbx;rtl;RESTComponents;DBXSqliteDriver;IndyIPServer;dsnapxml;DataSnapClient;DataSnapProviderClient;DataSnapFireDAC;emsclientfiredac;FireDAC;FireDACDSDriver;xmlrtl;tethering;ibxpress;dsnap;CloudService;FMXTee;DataSnapNativeClient;PythonFmx;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage) + activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar + + + DataSnapServer;fmx;emshosting;DbxCommonDriver;bindengine;FireDACCommonODBC;emsclient;FireDACCommonDriver;IndyProtocols;Skia.Package.RTL;RadiantShapesFmx_Design;dbxcds;emsedge;inetdb;FireDACSqliteDriver;DbxClientDriver;FireDACASADriver;soapmidas;dbexpress;FireDACInfxDriver;Python;inet;DataSnapCommon;dbrtl;FireDACOracleDriver;Skia.Package.FMX;CustomIPTransport;FireDACMSSQLDriver;DataSnapIndy10ServerTransport;DataSnapConnectors;FireDACMongoDBDriver;IndySystem;RadiantShapesFmx;FireDACTDataDriver;bindcomp;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;IndyCore;RESTBackendComponents;rtl;FireDACMySQLDriver;FireDACADSDriver;RESTComponents;dsnapxml;DataSnapClient;DataSnapFireDAC;emsclientfiredac;FireDACPgDriver;FireDAC;xmlrtl;dsnap;CloudService;FireDACDb2Driver;DataSnapNativeClient;DatasnapConnectorsFreePascal;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage) + RaizeComponentsVcl;JvNet;vclwinx;DataSnapServer;fmx;emshosting;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;FireDACCommonDriver;appanalytics;IndyProtocols;vclx;Skia.Package.RTL;RadiantShapesFmx_Design;IndyIPClient;dbxcds;vcledge;frxe28;frxTee28;bindcompvclwinx;Prometheus.Client.Core;FmxTeeUI;emsedge;bindcompfmx;DBXFirebirdDriver;JvBands;inetdb;JvAppFrm;ibmonitor;FireDACSqliteDriver;DbxClientDriver;FireDACASADriver;Tee;soapmidas;JclVcl;SVGIconImageListFMX;vclactnband;TeeUI;fmxFireDAC;dbexpress;Jcl;JvManagedThreads;FireDACInfxDriver;Python;DBXMySQLDriver;VclSmp;inet;DataSnapCommon;JvPascalInterpreter;PythonVcl;vcltouch;fmxase;frx28;JvPluginSystem;DBXOdbcDriver;DzHTMLText_FMX;dbrtl;JvDB;FireDACDBXDriver;FireDACOracleDriver;ComPortDrv;fmxdae;TeeDB;Skia.Package.FMX;JvTimeFramework;FireDACMSAccDriver;JvCustom;CustomIPTransport;FireDACMSSQLDriver;JvSystem;SVGIconPackage;DataSnapIndy10ServerTransport;JclDeveloperTools;JvControls;DataSnapConnectors;vcldsnap;DBXInterBaseDriver;JvCrypt;FireDACMongoDBDriver;JvJans;JvMM;IndySystem;JvWizards;frxDB28;RadiantShapesFmx;FireDACTDataDriver;Skia.Package.VCL;JvGlobus;vcldb;ibxbindings;IconFontsImageList;JclContainers;SynEditDR;JvPageComps;vclFireDAC;JvCore;bindcomp;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;IndyCore;RESTBackendComponents;dmvcframeworkDT;bindcompdbx;DzHTMLText_VCL;rtl;FireDACMySQLDriver;FireDACADSDriver;RaizeComponentsVclDb;RESTComponents;DBXSqliteDriver;vcl;IndyIPServer;dsnapxml;dsnapcon;DataSnapClient;DataSnapProviderClient;adortl;JvDotNetCtrls;JvHMI;DBXSybaseASEDriver;JvRuntimeDesign;DBXDb2Driver;JvXPCtrls;vclimg;DataSnapFireDAC;emsclientfiredac;FireDACPgDriver;FireDAC;FireDACDSDriver;inetdbxpress;xmlrtl;tethering;JvStdCtrls;ibxpress;JvDlgs;JvDocking;bindcompvcl;dsnap;JvPrintPreview;JvCmp;dmvcframeworkRT;CloudService;DBXSybaseASADriver;DBXOracleDriver;FireDACDb2Driver;DBXInformixDriver;vclib;IconFontsImageListFMX;fmxobj;bindcompvclsmp;FMXTee;DataSnapNativeClient;PythonFmx;DatasnapConnectorsFreePascal;soaprtl;SVGIconImageList;soapserver;FireDACIBDriver;$(DCC_UsePackage) Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) Debug - true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= 1033 - DMVCFramework - CopyRight (2010-2021) Daniele Teti and the DMVCFramework Team - rtl;dbrtl;IndySystem;IndyProtocols;IndyCore;dmvcframeworkDT;$(DCC_UsePackage) - 110 - rtl;dbrtl;IndySystem;IndyProtocols;IndyCore;$(DCC_UsePackage) + RaizeComponentsVcl;vclwinx;DataSnapServer;fmx;emshosting;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;FireDACCommonDriver;appanalytics;IndyProtocols;vclx;Skia.Package.RTL;RadiantShapesFmx_Design;IndyIPClient;dbxcds;vcledge;bindcompvclwinx;FmxTeeUI;emsedge;bindcompfmx;DBXFirebirdDriver;inetdb;ibmonitor;FireDACSqliteDriver;DbxClientDriver;FireDACASADriver;Tee;soapmidas;SVGIconImageListFMX;vclactnband;TeeUI;fmxFireDAC;dbexpress;FireDACInfxDriver;Python;DBXMySQLDriver;VclSmp;inet;DataSnapCommon;PythonVcl;vcltouch;fmxase;DBXOdbcDriver;DzHTMLText_FMX;dbrtl;FireDACDBXDriver;FireDACOracleDriver;ComPortDrv;fmxdae;TeeDB;Skia.Package.FMX;FireDACMSAccDriver;CustomIPTransport;FireDACMSSQLDriver;SVGIconPackage;DataSnapIndy10ServerTransport;DataSnapConnectors;vcldsnap;DBXInterBaseDriver;FireDACMongoDBDriver;IndySystem;RadiantShapesFmx;FireDACTDataDriver;Skia.Package.VCL;vcldb;ibxbindings;SynEditDR;vclFireDAC;bindcomp;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;IndyCore;RESTBackendComponents;bindcompdbx;DzHTMLText_VCL;rtl;FireDACMySQLDriver;FireDACADSDriver;RaizeComponentsVclDb;RESTComponents;DBXSqliteDriver;vcl;IndyIPServer;dsnapxml;dsnapcon;DataSnapClient;DataSnapProviderClient;adortl;DBXSybaseASEDriver;DBXDb2Driver;vclimg;DataSnapFireDAC;emsclientfiredac;FireDACPgDriver;FireDAC;FireDACDSDriver;inetdbxpress;xmlrtl;tethering;ibxpress;bindcompvcl;dsnap;CloudService;DBXSybaseASADriver;DBXOracleDriver;FireDACDb2Driver;DBXInformixDriver;vclib;fmxobj;bindcompvclsmp;FMXTee;DataSnapNativeClient;PythonFmx;DatasnapConnectorsFreePascal;soaprtl;SVGIconImageList;soapserver;FireDACIBDriver;$(DCC_UsePackage) DEBUG;$(DCC_Define) @@ -96,19 +98,11 @@ true true true + true + true - true - 1033 - 3 - true - false - true - CompanyName=Daniele Teti and the DMVCFramework Team;FileDescription=DelphiMVCFramework 3.2.2-nitrogen;FileVersion=3.2.2.0;InternalName=DelphiMVCFramework 3.2.2-nitrogen;LegalCopyright=Daniele Teti and the DMVCFramework Team - Apache License 2;LegalTrademarks=DelphiMVCFramework;OriginalFilename=$(MSBuildProjectName);ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=DelphiMVCFramework;ProductVersion=3.2.2;Comments= - 3 - 2 - 2 - 111 + false false @@ -120,80 +114,17 @@ MainSource - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +
MyWebModule
+ dfm + TWebModule +
+ +
dmMain
+ dfm + TDataModule +
Base @@ -208,16 +139,12 @@ Delphi.Personality.12 - Package + Console - dmvcframeworkRT.dpk + function_actions_showcase.dpr - - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - @@ -230,14 +157,17 @@ true - true - - + + + function_actions_showcase.exe + true + + 1 @@ -955,7 +885,6 @@ - diff --git a/samples/authenticationauthorization/AppControllerU.pas b/samples/middleware_basicauthentication/AppControllerU.pas similarity index 96% rename from samples/authenticationauthorization/AppControllerU.pas rename to samples/middleware_basicauthentication/AppControllerU.pas index f48a311f..4c9d907d 100644 --- a/samples/authenticationauthorization/AppControllerU.pas +++ b/samples/middleware_basicauthentication/AppControllerU.pas @@ -1,87 +1,87 @@ -unit AppControllerU; - -interface - -uses - MVCFramework, - MVCFramework.Commons, - MVCFramework.Logger, - Web.HTTPApp; - -type - - [MVCPath('/')] - TApp1MainController = class(TMVCController) - public - [MVCPath('/public')] - [MVCHTTPMethod([httpGET])] - procedure PublicSection; - [MVCPath('/')] - [MVCHTTPMethod([httpGET])] - procedure Index; - end; - - [MVCPath('/admin')] - TAdminController = class(TMVCController) - public - [MVCPath('/role1')] - [MVCProduces('text/html')] - [MVCHTTPMethod([httpGET])] - procedure OnlyRole1; - [MVCPath('/role1')] - [MVCProduces('application/json')] - [MVCHTTPMethod([httpGET])] - procedure OnlyRole1EmittingJSON; - [MVCPath('/role2')] - [MVCProduces('text/html')] - [MVCHTTPMethod([httpGET])] - procedure OnlyRole2; - end; - -implementation - -uses - System.SysUtils; - -{ TApp1MainController } - -procedure TApp1MainController.Index; -begin - Redirect('/index.html'); -end; - -procedure TApp1MainController.PublicSection; -begin - Render('This is a public section'); -end; - -{ TAdminController } - -procedure TAdminController.OnlyRole1; -begin - ContentType := TMVCMediaType.TEXT_PLAIN; - ResponseStream.AppendLine('Hey! Hello ' + Context.LoggedUser.UserName + - ', now you are a logged user and this is a protected content!'); - ResponseStream.AppendLine('As logged user you have the following roles: ' + - sLineBreak + string.Join(sLineBreak, Context.LoggedUser.Roles.ToArray)); - RenderResponseStream; -end; - -procedure TAdminController.OnlyRole1EmittingJSON; -begin - ContentType := TMVCMediaType.APPLICATION_JSON; - Render('This is protected content accessible only by user1: parameter = ' + - Context.Request.Params['par1']); -end; - -procedure TAdminController.OnlyRole2; -begin - ContentType := TMVCMediaType.TEXT_PLAIN; - ResponseStream.AppendLine('Hey! Hello ' + Context.LoggedUser.UserName + - ', now you are a logged user and this is a protected content!'); - ResponseStream.AppendLine('As logged user you have the following roles: ' + - sLineBreak + string.Join(sLineBreak, Context.LoggedUser.Roles.ToArray)); - RenderResponseStream; -end; - -end. +unit AppControllerU; + +interface + +uses + MVCFramework, + MVCFramework.Commons, + MVCFramework.Logger, + Web.HTTPApp; + +type + + [MVCPath('/')] + TApp1MainController = class(TMVCController) + public + [MVCPath('/public')] + [MVCHTTPMethod([httpGET])] + procedure PublicSection; + [MVCPath('/')] + [MVCHTTPMethod([httpGET])] + procedure Index; + end; + + [MVCPath('/admin')] + TAdminController = class(TMVCController) + public + [MVCPath('/role1')] + [MVCProduces('text/html')] + [MVCHTTPMethod([httpGET])] + procedure OnlyRole1; + [MVCPath('/role1')] + [MVCProduces('application/json')] + [MVCHTTPMethod([httpGET])] + procedure OnlyRole1EmittingJSON; + [MVCPath('/role2')] + [MVCProduces('text/html')] + [MVCHTTPMethod([httpGET])] + procedure OnlyRole2; + end; + +implementation + +uses + System.SysUtils; + +{ TApp1MainController } + +procedure TApp1MainController.Index; +begin + Redirect('/index.html'); +end; + +procedure TApp1MainController.PublicSection; +begin + Render('This is a public section'); +end; + +{ TAdminController } + +procedure TAdminController.OnlyRole1; +begin + ContentType := TMVCMediaType.TEXT_PLAIN; + ResponseStream.AppendLine('Hey! Hello ' + Context.LoggedUser.UserName + + ', now you are a logged user and this is a protected content!'); + ResponseStream.AppendLine('As logged user you have the following roles: ' + + sLineBreak + string.Join(sLineBreak, Context.LoggedUser.Roles.ToArray)); + RenderResponseStream; +end; + +procedure TAdminController.OnlyRole1EmittingJSON; +begin + ContentType := TMVCMediaType.APPLICATION_JSON; + Render('This is protected content accessible only by user1: parameter = ' + + Context.Request.Params['par1']); +end; + +procedure TAdminController.OnlyRole2; +begin + ContentType := TMVCMediaType.TEXT_PLAIN; + ResponseStream.AppendLine('Hey! Hello ' + Context.LoggedUser.UserName + + ', now you are a logged user and this is a protected content!'); + ResponseStream.AppendLine('As logged user you have the following roles: ' + + sLineBreak + string.Join(sLineBreak, Context.LoggedUser.Roles.ToArray)); + RenderResponseStream; +end; + +end. diff --git a/samples/authenticationauthorization/AuthenticateAuthorize.dpr b/samples/middleware_basicauthentication/AuthenticateAuthorize.dpr similarity index 96% rename from samples/authenticationauthorization/AuthenticateAuthorize.dpr rename to samples/middleware_basicauthentication/AuthenticateAuthorize.dpr index ef11620c..fd538d1e 100644 --- a/samples/authenticationauthorization/AuthenticateAuthorize.dpr +++ b/samples/middleware_basicauthentication/AuthenticateAuthorize.dpr @@ -1,53 +1,53 @@ -program AuthenticateAuthorize; - -{$APPTYPE CONSOLE} - -uses - System.SysUtils, -{$IFDEF MSWINDOWS} - Winapi.Windows, - Winapi.ShellAPI, -{$ENDIF} - Web.WebReq, - Web.WebBroker, - IdHTTPWebBrokerBridge, - WebModuleUnit1 in 'WebModuleUnit1.pas' {WebModule1: TWebModule} , - AppControllerU in 'AppControllerU.pas', - MVCFramework.Middleware.Authentication - in '..\..\sources\MVCFramework.Middleware.Authentication.pas', - AuthenticationU in 'AuthenticationU.pas'; - -{$R *.res} - -procedure RunServer(APort: Integer); -var - LServer: TIdHTTPWebBrokerBridge; -begin - Writeln(Format('Starting HTTP Server or port %d', [APort])); - LServer := TIdHTTPWebBrokerBridge.Create(nil); - try - LServer.DefaultPort := APort; - LServer.Active := True; - Writeln('Press RETURN to stop the server'); - {$IFDEF MSWINDOWS} - ShellExecute(0, 'open', PChar('http://localhost:' + IntToStr(APort) + '/static'), nil, nil, SW_SHOW); - {$ENDIF} - ReadLn; - finally - LServer.Free; - end; -end; - -begin - ReportMemoryLeaksOnShutdown := True; - try - if WebRequestHandler <> nil then - WebRequestHandler.WebModuleClass := WebModuleClass; - WebRequestHandlerProc.MaxConnections := 1024; - RunServer(8080); - except - on E: Exception do - Writeln(E.ClassName, ': ', E.Message); - end - -end. +program AuthenticateAuthorize; + +{$APPTYPE CONSOLE} + +uses + System.SysUtils, +{$IFDEF MSWINDOWS} + Winapi.Windows, + Winapi.ShellAPI, +{$ENDIF} + Web.WebReq, + Web.WebBroker, + IdHTTPWebBrokerBridge, + WebModuleUnit1 in 'WebModuleUnit1.pas' {WebModule1: TWebModule} , + AppControllerU in 'AppControllerU.pas', + MVCFramework.Middleware.Authentication + in '..\..\sources\MVCFramework.Middleware.Authentication.pas', + AuthenticationU in 'AuthenticationU.pas'; + +{$R *.res} + +procedure RunServer(APort: Integer); +var + LServer: TIdHTTPWebBrokerBridge; +begin + Writeln(Format('Starting HTTP Server or port %d', [APort])); + LServer := TIdHTTPWebBrokerBridge.Create(nil); + try + LServer.DefaultPort := APort; + LServer.Active := True; + Writeln('Press RETURN to stop the server'); + {$IFDEF MSWINDOWS} + ShellExecute(0, 'open', PChar('http://localhost:' + IntToStr(APort) + '/static'), nil, nil, SW_SHOW); + {$ENDIF} + ReadLn; + finally + LServer.Free; + end; +end; + +begin + ReportMemoryLeaksOnShutdown := True; + try + if WebRequestHandler <> nil then + WebRequestHandler.WebModuleClass := WebModuleClass; + WebRequestHandlerProc.MaxConnections := 1024; + RunServer(8080); + except + on E: Exception do + Writeln(E.ClassName, ': ', E.Message); + end + +end. diff --git a/samples/authenticationauthorization/AuthenticateAuthorize.dproj b/samples/middleware_basicauthentication/AuthenticateAuthorize.dproj similarity index 75% rename from samples/authenticationauthorization/AuthenticateAuthorize.dproj rename to samples/middleware_basicauthentication/AuthenticateAuthorize.dproj index 30387c68..4d73eccc 100644 --- a/samples/authenticationauthorization/AuthenticateAuthorize.dproj +++ b/samples/middleware_basicauthentication/AuthenticateAuthorize.dproj @@ -1,1180 +1,907 @@ - - - {7B54055A-5749-4136-9FE2-35FDBEEA874C} - 19.1 - VCL - AuthenticateAuthorize.dpr - True - Debug - Win32 - 1 - Console - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_1 - true - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - $(BDS)\bin\delphi_PROJECTICNS.icns - AuthenticateAuthorize - ..\..\sources;..\..\lib\delphistompclient;..\..\lib\loggerpro;..\..\lib\dmustache;$(DCC_UnitSearchPath) - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - None - 1040 - $(BDS)\bin\delphi_PROJECTICON.ico - System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) - .\$(Platform)\$(Config) - .\$(Platform)\$(Config) - false - false - false - false - false - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - 1033 - cxPivotGridChartRS17;JvMM;dxSkinSevenRS17;dxSkinBlueprintRS17;dxSkinHighContrastRS17;dxSkinOffice2007BlackRS17;dxCoreRS17;cxPageControldxBarPopupMenuRS17;dxSkinXmas2008BlueRS17;dxPSDBTeeChartRS17;JvCrypt;dxPSTeeChartRS17;dxSkinSummer2008RS17;dxPScxSchedulerLnkRS17;dxSkinBlueRS17;dxSkinDarkRoomRS17;DBXInterBaseDriver;DataSnapServer;DataSnapCommon;dxPScxTLLnkRS17;JvNet;JvDotNetCtrls;dxRibbonRS17;DbxCommonDriver;cxDataRS17;vclimg;dxSkinsdxBarPainterRS17;dxPSdxDBTVLnkRS17;dbxcds;DatasnapConnectorsFreePascal;NxDBGridDsgn_dxe3;JvXPCtrls;dxSkinMoneyTwinsRS17;vcldb;cxExportRS17;dxPSCoreRS17;dxBarExtItemsRS17;dxGDIPlusRS17;FMXfrx17;dxNavBarRS17;CustomIPTransport;cxLibraryRS17;cxGridRS17;dxSkinOffice2010BlackRS17;dsnap;IndyIPServer;IndyCore;dxSkinMcSkinRS17;CloudService;dxPScxCommonRS17;FmxTeeUI;frxDB17;AnyDAC_PhysDb2_D17;dxSkinsdxDLPainterRS17;dxSkiniMaginaryRS17;JvDB;JvRuntimeDesign;dxPScxVGridLnkRS17;JclDeveloperTools;dxSkinSevenClassicRS17;dxPScxExtCommonRS17;MyFrameTestPackage;dxPScxSSLnkRS17;NxGridRun_dxe3;dxSkinLilianRS17;fs17;dxPSdxLCLnkRS17;dxSkinOffice2010BlueRS17;NxCommonRun_dxe3;bindcompfmx;DataBindingsVCL170;dxSkinOffice2010SilverRS17;vcldbx;cxSchedulerGridRS17;dbrtl;bindcomp;inetdb;JvPluginSystem;dxBarRS17;DataBindings;DBXOdbcDriver;IcsCommonDXE3Run;JvCmp;dxBarDBNavRS17;dxSkinWhiteprintRS17;JvTimeFramework;xmlrtl;dxSkinsdxRibbonPainterRS17;ibxpress;dxDockingRS17;vclactnband;bindengine;soaprtl;FMXTee;dxADOServerModeRS17;bindcompvcl;dxBarExtDBItemsRS17;dxPSPrVwRibbonRS17;Jcl;vclie;dxSkinOffice2007PinkRS17;cxPageControlRS17;dxSkinscxPCPainterRS17;AnyDAC_PhysADS_D17;AnyDAC_PhysIB_D17;dxmdsRS17;dxSkinTheAsphaltWorldRS17;DBXInformixDriver;Intraweb;dxPsPrVwAdvRS17;NxInspectorRun_dxe3;dxSkinSilverRS17;dxdborRS17;dsnapcon;DBXFirebirdDriver;fsDB17;inet;dorm_runtime_xe3;JvPascalInterpreter;vclx;dxSkinStardustRS17;cxEditorsRS17;DBXSybaseASADriver;NxInspectorDsgn_dxe3;dbexpress;IndyIPClient;AnyDAC_PhysMySQL_D17;cxTreeListdxBarPopupMenuRS17;dxSkinVS2010RS17;NxGridDsgn_dxe3;dxThemeRS17;DBXSqliteDriver;dxPScxGridLnkRS17;fmx;JvDlgs;IndySystem;TeeDB;dxSkinValentineRS17;vclib;inetdbbde;DataSnapClient;dxSkinDevExpressStyleRS17;DataSnapProviderClient;DBXSybaseASEDriver;cxBarEditItemRS17;AnyDAC_PhysMSAcc_D17;dxServerModeRS17;cxPivotGridOLAPRS17;cxSchedulerRS17;MetropolisUILiveTile;AnyDAC_PhysSQLITE_D17;dxPSLnksRS17;dxSkinPumpkinRS17;dxPSdxDBOCLnkRS17;cxVerticalGridRS17;dxSkinSpringTimeRS17;vcldsnap;dxSkinDevExpressDarkStyleRS17;DBXDb2Driver;AnyDAC_ComI_D17;DBXOracleDriver;AnyDAC_PhysMSSQL_D17;JvCore;NxDBGridRun_dxe3;vclribbon;AnyDAC_Comp_D17;cxSpreadSheetRS17;dxSkinLiquidSkyRS17;AnyDAC_PhysODBC_D17;fmxase;vcl;dxSkinOffice2007SilverRS17;AnyDAC_PhysPg_D17;IndyIPCommon;DBXMSSQLDriver;CodeSiteExpressPkg;dxPSdxOCLnkRS17;dcldxSkinsCoreRS17;JvAppFrm;AnyDAC_PhysASA_D17;inetdbxpress;webdsnap;NxCollectionRun_dxe3;AnyDAC_PhysOracle_D17;dxSkinCoffeeRS17;JvDocking;adortl;dxSkinscxSchedulerPainterRS17;JvWizards;NxCollectionDsgn_dxe3;frx17;NxCommonDsgn_dxe3;dxtrmdRS17;dxPScxPCProdRS17;AnyDAC_GUIxForms_D17;JvBands;rtl;DbxClientDriver;AnyDAC_PhysTDBX_D17;dxTabbedMDIRS17;dxComnRS17;dxSkinSharpPlusRS17;dxSkinsCoreRS17;dxSkinLondonLiquidSkyRS17;dxdbtrRS17;Tee;JclContainers;NxAddonsRun_dxe3;CPortLibDXE;JvSystem;dxorgcRS17;svnui;dxSkinBlackRS17;JvControls;NxSheetRun_dxe3;IndyProtocols;DBXMySQLDriver;dxLayoutControlRS17;bindcompdbx;TeeUI;JvJans;JvPrintPreview;JvPageComps;JvStdCtrls;JvCustom;dxSkinOffice2007BlueRS17;dxPScxPivotGridLnkRS17;dxSpellCheckerRS17;vcltouch;dxSkinOffice2007GreenRS17;dxSkinSharpRS17;websnap;dxSkinFoggyRS17;dxTileControlRS17;VclSmp;FMXfrxDB17;dxSkinDarkSideRS17;cxPivotGridRS17;DataSnapConnectors;AnyDAC_Phys_D17;fmxobj;SynEdit_RXE3;JclVcl;cxTreeListRS17;dxPSdxFCLnkRS17;dxSkinGlassOceansRS17;frxe17;svn;dxFlowChartRS17;fmxdae;dxSkinsdxNavBarPainterRS17;bdertl;VirtualTreesR;DataSnapIndy10ServerTransport;dxDBXServerModeRS17;dxSkinCaramelRS17;$(DCC_UsePackage) - - - cxPivotGridChartRS17;JvMM;dxSkinSevenRS17;dxSkinBlueprintRS17;dxSkinHighContrastRS17;dxSkinOffice2007BlackRS17;dxCoreRS17;cxPageControldxBarPopupMenuRS17;dxSkinXmas2008BlueRS17;dxPSDBTeeChartRS17;JvCrypt;dxPSTeeChartRS17;dxSkinSummer2008RS17;dxPScxSchedulerLnkRS17;dxSkinBlueRS17;dxSkinDarkRoomRS17;DBXInterBaseDriver;DataSnapServer;DataSnapCommon;dxPScxTLLnkRS17;JvNet;dxRibbonRS17;DbxCommonDriver;cxDataRS17;vclimg;dxSkinsdxBarPainterRS17;dxPSdxDBTVLnkRS17;dbxcds;DatasnapConnectorsFreePascal;NxDBGridDsgn_dxe3;dxSkinMoneyTwinsRS17;vcldb;cxExportRS17;dxPSCoreRS17;dxBarExtItemsRS17;dxGDIPlusRS17;dxNavBarRS17;CustomIPTransport;cxLibraryRS17;cxGridRS17;dxSkinOffice2010BlackRS17;dsnap;IndyIPServer;IndyCore;dxSkinMcSkinRS17;dxPScxCommonRS17;AnyDAC_PhysDb2_D17;dxSkinsdxDLPainterRS17;dxSkiniMaginaryRS17;JvDB;dxPScxVGridLnkRS17;dxSkinSevenClassicRS17;dxPScxExtCommonRS17;dxPScxSSLnkRS17;NxGridRun_dxe3;dxSkinLilianRS17;dxPSdxLCLnkRS17;dxSkinOffice2010BlueRS17;NxCommonRun_dxe3;bindcompfmx;dxSkinOffice2010SilverRS17;cxSchedulerGridRS17;dbrtl;bindcomp;inetdb;JvPluginSystem;dxBarRS17;DBXOdbcDriver;JvCmp;dxBarDBNavRS17;dxSkinWhiteprintRS17;JvTimeFramework;xmlrtl;dxSkinsdxRibbonPainterRS17;ibxpress;dxDockingRS17;vclactnband;bindengine;soaprtl;dxADOServerModeRS17;bindcompvcl;dxBarExtDBItemsRS17;dxPSPrVwRibbonRS17;vclie;dxSkinOffice2007PinkRS17;cxPageControlRS17;dxSkinscxPCPainterRS17;AnyDAC_PhysADS_D17;AnyDAC_PhysIB_D17;dxmdsRS17;dxSkinTheAsphaltWorldRS17;DBXInformixDriver;dxPsPrVwAdvRS17;NxInspectorRun_dxe3;dxSkinSilverRS17;dxdborRS17;dsnapcon;DBXFirebirdDriver;inet;JvPascalInterpreter;vclx;dxSkinStardustRS17;cxEditorsRS17;DBXSybaseASADriver;NxInspectorDsgn_dxe3;dbexpress;IndyIPClient;AnyDAC_PhysMySQL_D17;cxTreeListdxBarPopupMenuRS17;dxSkinVS2010RS17;NxGridDsgn_dxe3;dxThemeRS17;DBXSqliteDriver;dxPScxGridLnkRS17;fmx;JvDlgs;IndySystem;TeeDB;dxSkinValentineRS17;vclib;DataSnapClient;dxSkinDevExpressStyleRS17;DataSnapProviderClient;DBXSybaseASEDriver;cxBarEditItemRS17;AnyDAC_PhysMSAcc_D17;dxServerModeRS17;cxPivotGridOLAPRS17;cxSchedulerRS17;AnyDAC_PhysSQLITE_D17;dxPSLnksRS17;dxSkinPumpkinRS17;dxPSdxDBOCLnkRS17;cxVerticalGridRS17;dxSkinSpringTimeRS17;vcldsnap;dxSkinDevExpressDarkStyleRS17;DBXDb2Driver;AnyDAC_ComI_D17;DBXOracleDriver;AnyDAC_PhysMSSQL_D17;JvCore;NxDBGridRun_dxe3;AnyDAC_Comp_D17;cxSpreadSheetRS17;dxSkinLiquidSkyRS17;AnyDAC_PhysODBC_D17;fmxase;vcl;dxSkinOffice2007SilverRS17;AnyDAC_PhysPg_D17;IndyIPCommon;DBXMSSQLDriver;dxPSdxOCLnkRS17;dcldxSkinsCoreRS17;JvAppFrm;AnyDAC_PhysASA_D17;inetdbxpress;webdsnap;NxCollectionRun_dxe3;AnyDAC_PhysOracle_D17;dxSkinCoffeeRS17;adortl;dxSkinscxSchedulerPainterRS17;JvWizards;NxCollectionDsgn_dxe3;NxCommonDsgn_dxe3;dxtrmdRS17;dxPScxPCProdRS17;AnyDAC_GUIxForms_D17;JvBands;rtl;DbxClientDriver;AnyDAC_PhysTDBX_D17;dxTabbedMDIRS17;dxComnRS17;dxSkinSharpPlusRS17;dxSkinsCoreRS17;dxSkinLondonLiquidSkyRS17;dxdbtrRS17;Tee;NxAddonsRun_dxe3;JvSystem;dxorgcRS17;dxSkinBlackRS17;JvControls;NxSheetRun_dxe3;IndyProtocols;DBXMySQLDriver;dxLayoutControlRS17;bindcompdbx;TeeUI;JvJans;JvPrintPreview;JvPageComps;JvStdCtrls;JvCustom;dxSkinOffice2007BlueRS17;dxPScxPivotGridLnkRS17;dxSpellCheckerRS17;vcltouch;dxSkinOffice2007GreenRS17;dxSkinSharpRS17;websnap;dxSkinFoggyRS17;dxTileControlRS17;VclSmp;dxSkinDarkSideRS17;cxPivotGridRS17;DataSnapConnectors;AnyDAC_Phys_D17;fmxobj;SynEdit_RXE3;cxTreeListRS17;dxPSdxFCLnkRS17;dxSkinGlassOceansRS17;dxFlowChartRS17;fmxdae;dxSkinsdxNavBarPainterRS17;DataSnapIndy10ServerTransport;dxDBXServerModeRS17;dxSkinCaramelRS17;$(DCC_UsePackage) - - - DEBUG;$(DCC_Define) - true - false - true - true - true - - - 3 - true - 1033 - false - - - false - RELEASE;$(DCC_Define) - 0 - 0 - - - 1033 - - - - MainSource - - -
WebModule1
- TWebModule -
- - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - -
- - Delphi.Personality.12 - - - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1040 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - - - - - - - - AuthenticateAuthorize.dpr - - - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - FastReport 6.0 Tee Components - - - - - - AuthenticateAuthorize.exe - true - - - - - 1 - - - 0 - - - - - classes - 1 - - - classes - 1 - - - - - res\xml - 1 - - - res\xml - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - library\lib\armeabi - 1 - - - library\lib\armeabi - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - library\lib\mips - 1 - - - library\lib\mips - 1 - - - - - - library\lib\armeabi-v7a - 1 - - - library\lib\arm64-v8a - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - res\drawable - 1 - - - res\drawable - 1 - - - - - res\values - 1 - - - res\values - 1 - - - - - res\values-v21 - 1 - - - res\values-v21 - 1 - - - - - res\values - 1 - - - res\values - 1 - - - - - res\drawable - 1 - - - res\drawable - 1 - - - - - res\drawable-xxhdpi - 1 - - - res\drawable-xxhdpi - 1 - - - - - res\drawable-ldpi - 1 - - - res\drawable-ldpi - 1 - - - - - res\drawable-mdpi - 1 - - - res\drawable-mdpi - 1 - - - - - res\drawable-hdpi - 1 - - - res\drawable-hdpi - 1 - - - - - res\drawable-xhdpi - 1 - - - res\drawable-xhdpi - 1 - - - - - res\drawable-mdpi - 1 - - - res\drawable-mdpi - 1 - - - - - res\drawable-hdpi - 1 - - - res\drawable-hdpi - 1 - - - - - res\drawable-xhdpi - 1 - - - res\drawable-xhdpi - 1 - - - - - res\drawable-xxhdpi - 1 - - - res\drawable-xxhdpi - 1 - - - - - res\drawable-xxxhdpi - 1 - - - res\drawable-xxxhdpi - 1 - - - - - res\drawable-small - 1 - - - res\drawable-small - 1 - - - - - res\drawable-normal - 1 - - - res\drawable-normal - 1 - - - - - res\drawable-large - 1 - - - res\drawable-large - 1 - - - - - res\drawable-xlarge - 1 - - - res\drawable-xlarge - 1 - - - - - res\values - 1 - - - res\values - 1 - - - - - 1 - - - 1 - - - 0 - - - - - 1 - .framework - - - 1 - .framework - - - 0 - - - - - 1 - .dylib - - - 1 - .dylib - - - 0 - .dll;.bpl - - - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 0 - .bpl - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(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 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(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 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - 1 - - - 1 - - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - - - - - - - 1 - - - 1 - - - 1 - - - - - - - - Contents\Resources - 1 - - - Contents\Resources - 1 - - - - - library\lib\armeabi-v7a - 1 - - - library\lib\arm64-v8a - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 0 - - - - - library\lib\armeabi-v7a - 1 - - - - - 1 - - - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - - - - - - - - - - - True - False - - - 12 - - - - -
+ + + {7B54055A-5749-4136-9FE2-35FDBEEA874C} + 19.5 + VCL + AuthenticateAuthorize.dpr + True + Debug + Win32 + 1 + Console + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + $(BDS)\bin\delphi_PROJECTICNS.icns + AuthenticateAuthorize + ..\..\sources;..\..\lib\delphistompclient;..\..\lib\loggerpro;..\..\lib\dmustache;$(DCC_UnitSearchPath) + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + None + 1040 + $(BDS)\bin\delphi_PROJECTICON.ico + System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) + .\$(Platform)\$(Config) + .\bin + false + false + false + false + false + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + 1033 + cxPivotGridChartRS17;JvMM;dxSkinSevenRS17;dxSkinBlueprintRS17;dxSkinHighContrastRS17;dxSkinOffice2007BlackRS17;dxCoreRS17;cxPageControldxBarPopupMenuRS17;dxSkinXmas2008BlueRS17;dxPSDBTeeChartRS17;JvCrypt;dxPSTeeChartRS17;dxSkinSummer2008RS17;dxPScxSchedulerLnkRS17;dxSkinBlueRS17;dxSkinDarkRoomRS17;DBXInterBaseDriver;DataSnapServer;DataSnapCommon;dxPScxTLLnkRS17;JvNet;JvDotNetCtrls;dxRibbonRS17;DbxCommonDriver;cxDataRS17;vclimg;dxSkinsdxBarPainterRS17;dxPSdxDBTVLnkRS17;dbxcds;DatasnapConnectorsFreePascal;NxDBGridDsgn_dxe3;JvXPCtrls;dxSkinMoneyTwinsRS17;vcldb;cxExportRS17;dxPSCoreRS17;dxBarExtItemsRS17;dxGDIPlusRS17;FMXfrx17;dxNavBarRS17;CustomIPTransport;cxLibraryRS17;cxGridRS17;dxSkinOffice2010BlackRS17;dsnap;IndyIPServer;IndyCore;dxSkinMcSkinRS17;CloudService;dxPScxCommonRS17;FmxTeeUI;frxDB17;AnyDAC_PhysDb2_D17;dxSkinsdxDLPainterRS17;dxSkiniMaginaryRS17;JvDB;JvRuntimeDesign;dxPScxVGridLnkRS17;JclDeveloperTools;dxSkinSevenClassicRS17;dxPScxExtCommonRS17;MyFrameTestPackage;dxPScxSSLnkRS17;NxGridRun_dxe3;dxSkinLilianRS17;fs17;dxPSdxLCLnkRS17;dxSkinOffice2010BlueRS17;NxCommonRun_dxe3;bindcompfmx;DataBindingsVCL170;dxSkinOffice2010SilverRS17;vcldbx;cxSchedulerGridRS17;dbrtl;bindcomp;inetdb;JvPluginSystem;dxBarRS17;DataBindings;DBXOdbcDriver;IcsCommonDXE3Run;JvCmp;dxBarDBNavRS17;dxSkinWhiteprintRS17;JvTimeFramework;xmlrtl;dxSkinsdxRibbonPainterRS17;ibxpress;dxDockingRS17;vclactnband;bindengine;soaprtl;FMXTee;dxADOServerModeRS17;bindcompvcl;dxBarExtDBItemsRS17;dxPSPrVwRibbonRS17;Jcl;vclie;dxSkinOffice2007PinkRS17;cxPageControlRS17;dxSkinscxPCPainterRS17;AnyDAC_PhysADS_D17;AnyDAC_PhysIB_D17;dxmdsRS17;dxSkinTheAsphaltWorldRS17;DBXInformixDriver;Intraweb;dxPsPrVwAdvRS17;NxInspectorRun_dxe3;dxSkinSilverRS17;dxdborRS17;dsnapcon;DBXFirebirdDriver;fsDB17;inet;dorm_runtime_xe3;JvPascalInterpreter;vclx;dxSkinStardustRS17;cxEditorsRS17;DBXSybaseASADriver;NxInspectorDsgn_dxe3;dbexpress;IndyIPClient;AnyDAC_PhysMySQL_D17;cxTreeListdxBarPopupMenuRS17;dxSkinVS2010RS17;NxGridDsgn_dxe3;dxThemeRS17;DBXSqliteDriver;dxPScxGridLnkRS17;fmx;JvDlgs;IndySystem;TeeDB;dxSkinValentineRS17;vclib;inetdbbde;DataSnapClient;dxSkinDevExpressStyleRS17;DataSnapProviderClient;DBXSybaseASEDriver;cxBarEditItemRS17;AnyDAC_PhysMSAcc_D17;dxServerModeRS17;cxPivotGridOLAPRS17;cxSchedulerRS17;MetropolisUILiveTile;AnyDAC_PhysSQLITE_D17;dxPSLnksRS17;dxSkinPumpkinRS17;dxPSdxDBOCLnkRS17;cxVerticalGridRS17;dxSkinSpringTimeRS17;vcldsnap;dxSkinDevExpressDarkStyleRS17;DBXDb2Driver;AnyDAC_ComI_D17;DBXOracleDriver;AnyDAC_PhysMSSQL_D17;JvCore;NxDBGridRun_dxe3;vclribbon;AnyDAC_Comp_D17;cxSpreadSheetRS17;dxSkinLiquidSkyRS17;AnyDAC_PhysODBC_D17;fmxase;vcl;dxSkinOffice2007SilverRS17;AnyDAC_PhysPg_D17;IndyIPCommon;DBXMSSQLDriver;CodeSiteExpressPkg;dxPSdxOCLnkRS17;dcldxSkinsCoreRS17;JvAppFrm;AnyDAC_PhysASA_D17;inetdbxpress;webdsnap;NxCollectionRun_dxe3;AnyDAC_PhysOracle_D17;dxSkinCoffeeRS17;JvDocking;adortl;dxSkinscxSchedulerPainterRS17;JvWizards;NxCollectionDsgn_dxe3;frx17;NxCommonDsgn_dxe3;dxtrmdRS17;dxPScxPCProdRS17;AnyDAC_GUIxForms_D17;JvBands;rtl;DbxClientDriver;AnyDAC_PhysTDBX_D17;dxTabbedMDIRS17;dxComnRS17;dxSkinSharpPlusRS17;dxSkinsCoreRS17;dxSkinLondonLiquidSkyRS17;dxdbtrRS17;Tee;JclContainers;NxAddonsRun_dxe3;CPortLibDXE;JvSystem;dxorgcRS17;svnui;dxSkinBlackRS17;JvControls;NxSheetRun_dxe3;IndyProtocols;DBXMySQLDriver;dxLayoutControlRS17;bindcompdbx;TeeUI;JvJans;JvPrintPreview;JvPageComps;JvStdCtrls;JvCustom;dxSkinOffice2007BlueRS17;dxPScxPivotGridLnkRS17;dxSpellCheckerRS17;vcltouch;dxSkinOffice2007GreenRS17;dxSkinSharpRS17;websnap;dxSkinFoggyRS17;dxTileControlRS17;VclSmp;FMXfrxDB17;dxSkinDarkSideRS17;cxPivotGridRS17;DataSnapConnectors;AnyDAC_Phys_D17;fmxobj;SynEdit_RXE3;JclVcl;cxTreeListRS17;dxPSdxFCLnkRS17;dxSkinGlassOceansRS17;frxe17;svn;dxFlowChartRS17;fmxdae;dxSkinsdxNavBarPainterRS17;bdertl;VirtualTreesR;DataSnapIndy10ServerTransport;dxDBXServerModeRS17;dxSkinCaramelRS17;$(DCC_UsePackage) + + + cxPivotGridChartRS17;JvMM;dxSkinSevenRS17;dxSkinBlueprintRS17;dxSkinHighContrastRS17;dxSkinOffice2007BlackRS17;dxCoreRS17;cxPageControldxBarPopupMenuRS17;dxSkinXmas2008BlueRS17;dxPSDBTeeChartRS17;JvCrypt;dxPSTeeChartRS17;dxSkinSummer2008RS17;dxPScxSchedulerLnkRS17;dxSkinBlueRS17;dxSkinDarkRoomRS17;DBXInterBaseDriver;DataSnapServer;DataSnapCommon;dxPScxTLLnkRS17;JvNet;dxRibbonRS17;DbxCommonDriver;cxDataRS17;vclimg;dxSkinsdxBarPainterRS17;dxPSdxDBTVLnkRS17;dbxcds;DatasnapConnectorsFreePascal;NxDBGridDsgn_dxe3;dxSkinMoneyTwinsRS17;vcldb;cxExportRS17;dxPSCoreRS17;dxBarExtItemsRS17;dxGDIPlusRS17;dxNavBarRS17;CustomIPTransport;cxLibraryRS17;cxGridRS17;dxSkinOffice2010BlackRS17;dsnap;IndyIPServer;IndyCore;dxSkinMcSkinRS17;dxPScxCommonRS17;AnyDAC_PhysDb2_D17;dxSkinsdxDLPainterRS17;dxSkiniMaginaryRS17;JvDB;dxPScxVGridLnkRS17;dxSkinSevenClassicRS17;dxPScxExtCommonRS17;dxPScxSSLnkRS17;NxGridRun_dxe3;dxSkinLilianRS17;dxPSdxLCLnkRS17;dxSkinOffice2010BlueRS17;NxCommonRun_dxe3;bindcompfmx;dxSkinOffice2010SilverRS17;cxSchedulerGridRS17;dbrtl;bindcomp;inetdb;JvPluginSystem;dxBarRS17;DBXOdbcDriver;JvCmp;dxBarDBNavRS17;dxSkinWhiteprintRS17;JvTimeFramework;xmlrtl;dxSkinsdxRibbonPainterRS17;ibxpress;dxDockingRS17;vclactnband;bindengine;soaprtl;dxADOServerModeRS17;bindcompvcl;dxBarExtDBItemsRS17;dxPSPrVwRibbonRS17;vclie;dxSkinOffice2007PinkRS17;cxPageControlRS17;dxSkinscxPCPainterRS17;AnyDAC_PhysADS_D17;AnyDAC_PhysIB_D17;dxmdsRS17;dxSkinTheAsphaltWorldRS17;DBXInformixDriver;dxPsPrVwAdvRS17;NxInspectorRun_dxe3;dxSkinSilverRS17;dxdborRS17;dsnapcon;DBXFirebirdDriver;inet;JvPascalInterpreter;vclx;dxSkinStardustRS17;cxEditorsRS17;DBXSybaseASADriver;NxInspectorDsgn_dxe3;dbexpress;IndyIPClient;AnyDAC_PhysMySQL_D17;cxTreeListdxBarPopupMenuRS17;dxSkinVS2010RS17;NxGridDsgn_dxe3;dxThemeRS17;DBXSqliteDriver;dxPScxGridLnkRS17;fmx;JvDlgs;IndySystem;TeeDB;dxSkinValentineRS17;vclib;DataSnapClient;dxSkinDevExpressStyleRS17;DataSnapProviderClient;DBXSybaseASEDriver;cxBarEditItemRS17;AnyDAC_PhysMSAcc_D17;dxServerModeRS17;cxPivotGridOLAPRS17;cxSchedulerRS17;AnyDAC_PhysSQLITE_D17;dxPSLnksRS17;dxSkinPumpkinRS17;dxPSdxDBOCLnkRS17;cxVerticalGridRS17;dxSkinSpringTimeRS17;vcldsnap;dxSkinDevExpressDarkStyleRS17;DBXDb2Driver;AnyDAC_ComI_D17;DBXOracleDriver;AnyDAC_PhysMSSQL_D17;JvCore;NxDBGridRun_dxe3;AnyDAC_Comp_D17;cxSpreadSheetRS17;dxSkinLiquidSkyRS17;AnyDAC_PhysODBC_D17;fmxase;vcl;dxSkinOffice2007SilverRS17;AnyDAC_PhysPg_D17;IndyIPCommon;DBXMSSQLDriver;dxPSdxOCLnkRS17;dcldxSkinsCoreRS17;JvAppFrm;AnyDAC_PhysASA_D17;inetdbxpress;webdsnap;NxCollectionRun_dxe3;AnyDAC_PhysOracle_D17;dxSkinCoffeeRS17;adortl;dxSkinscxSchedulerPainterRS17;JvWizards;NxCollectionDsgn_dxe3;NxCommonDsgn_dxe3;dxtrmdRS17;dxPScxPCProdRS17;AnyDAC_GUIxForms_D17;JvBands;rtl;DbxClientDriver;AnyDAC_PhysTDBX_D17;dxTabbedMDIRS17;dxComnRS17;dxSkinSharpPlusRS17;dxSkinsCoreRS17;dxSkinLondonLiquidSkyRS17;dxdbtrRS17;Tee;NxAddonsRun_dxe3;JvSystem;dxorgcRS17;dxSkinBlackRS17;JvControls;NxSheetRun_dxe3;IndyProtocols;DBXMySQLDriver;dxLayoutControlRS17;bindcompdbx;TeeUI;JvJans;JvPrintPreview;JvPageComps;JvStdCtrls;JvCustom;dxSkinOffice2007BlueRS17;dxPScxPivotGridLnkRS17;dxSpellCheckerRS17;vcltouch;dxSkinOffice2007GreenRS17;dxSkinSharpRS17;websnap;dxSkinFoggyRS17;dxTileControlRS17;VclSmp;dxSkinDarkSideRS17;cxPivotGridRS17;DataSnapConnectors;AnyDAC_Phys_D17;fmxobj;SynEdit_RXE3;cxTreeListRS17;dxPSdxFCLnkRS17;dxSkinGlassOceansRS17;dxFlowChartRS17;fmxdae;dxSkinsdxNavBarPainterRS17;DataSnapIndy10ServerTransport;dxDBXServerModeRS17;dxSkinCaramelRS17;$(DCC_UsePackage) + + + DEBUG;$(DCC_Define) + true + false + true + true + true + + + 3 + true + 1033 + false + none + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + 1033 + + + + MainSource + + +
WebModule1
+ TWebModule +
+ + + + + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + +
+ + Delphi.Personality.12 + + + + + False + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1040 + 1252 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + + + + + + + + + AuthenticateAuthorize.dpr + + + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + + + + 1 + + + 0 + + + + + classes + 64 + + + classes + 64 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + 1 + + + 1 + + + 0 + + + + + 1 + .framework + + + 1 + .framework + + + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 1 + + + 1 + + + + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 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 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + + + + + + + + + + + + + True + False + + + 12 + + + + +
diff --git a/samples/authenticationauthorization/AuthenticationU.pas b/samples/middleware_basicauthentication/AuthenticationU.pas similarity index 96% rename from samples/authenticationauthorization/AuthenticationU.pas rename to samples/middleware_basicauthentication/AuthenticationU.pas index cc6737d2..0f5f1bf3 100644 --- a/samples/authenticationauthorization/AuthenticationU.pas +++ b/samples/middleware_basicauthentication/AuthenticationU.pas @@ -1,80 +1,80 @@ -unit AuthenticationU; - -interface - -uses - System.SysUtils, MVCFramework.Commons, System.Generics.Collections, - MVCFramework; - -type - TAuthenticationSample = class(TInterfacedObject, IMVCAuthenticationHandler) - protected - procedure OnRequest(const AContext: TWebContext; const ControllerQualifiedClassName: string; - const ActionName: string; var AuthenticationRequired: Boolean); - procedure OnAuthentication(const AContext: TWebContext; const UserName: string; const Password: string; - UserRoles: System.Generics.Collections.TList; - var IsValid: Boolean; const SessionData: TSessionData); - procedure OnAuthorization(const AContext: TWebContext; UserRoles - : System.Generics.Collections.TList; - const ControllerQualifiedClassName: string; const ActionName: string; - var IsAuthorized: Boolean); - end; - -implementation - -{ TMVCAuthorization } - -procedure TAuthenticationSample.OnAuthentication(const AContext: TWebContext; const UserName: string; - const Password: string; - UserRoles: System.Generics.Collections.TList; - var IsValid: Boolean; const SessionData: TSessionData); -begin - IsValid := UserName.Equals(Password); // hey!, this is just a demo!!! - if IsValid then - begin - if UserName = 'user1' then - begin - UserRoles.Add('role1'); - end; - if UserName = 'user2' then - begin - UserRoles.Add('role2'); - end; - if UserName = 'user3' then // all the roles - begin - UserRoles.Add('role1'); - UserRoles.Add('role2'); - end; - end - else - begin - UserRoles.Clear; - end; -end; - -procedure TAuthenticationSample.OnAuthorization - (const AContext: TWebContext; UserRoles - : System.Generics.Collections.TList; - const ControllerQualifiedClassName: string; const ActionName: string; - var IsAuthorized: Boolean); -begin - IsAuthorized := False; - if ActionName = 'Logout' then - IsAuthorized := True; // you can always call logout - if ActionName = 'OnlyRole2' then - IsAuthorized := UserRoles.Contains('role2'); - if ActionName = 'OnlyRole1' then - IsAuthorized := UserRoles.Contains('role1'); - if ActionName = 'OnlyRole1EmittingJSON' then - IsAuthorized := UserRoles.Contains('role1'); -end; - -procedure TAuthenticationSample.OnRequest(const AContext: TWebContext; const ControllerQualifiedClassName: string; - const ActionName: string; var AuthenticationRequired: Boolean); -begin - AuthenticationRequired := ControllerQualifiedClassName = - 'AppControllerU.TAdminController'; - -end; - -end. +unit AuthenticationU; + +interface + +uses + System.SysUtils, MVCFramework.Commons, System.Generics.Collections, + MVCFramework; + +type + TAuthenticationSample = class(TInterfacedObject, IMVCAuthenticationHandler) + protected + procedure OnRequest(const AContext: TWebContext; const ControllerQualifiedClassName: string; + const ActionName: string; var AuthenticationRequired: Boolean); + procedure OnAuthentication(const AContext: TWebContext; const UserName: string; const Password: string; + UserRoles: System.Generics.Collections.TList; + var IsValid: Boolean; const SessionData: TSessionData); + procedure OnAuthorization(const AContext: TWebContext; UserRoles + : System.Generics.Collections.TList; + const ControllerQualifiedClassName: string; const ActionName: string; + var IsAuthorized: Boolean); + end; + +implementation + +{ TMVCAuthorization } + +procedure TAuthenticationSample.OnAuthentication(const AContext: TWebContext; const UserName: string; + const Password: string; + UserRoles: System.Generics.Collections.TList; + var IsValid: Boolean; const SessionData: TSessionData); +begin + IsValid := UserName.Equals(Password); // hey!, this is just a demo!!! + if IsValid then + begin + if UserName = 'user1' then + begin + UserRoles.Add('role1'); + end; + if UserName = 'user2' then + begin + UserRoles.Add('role2'); + end; + if UserName = 'user3' then // all the roles + begin + UserRoles.Add('role1'); + UserRoles.Add('role2'); + end; + end + else + begin + UserRoles.Clear; + end; +end; + +procedure TAuthenticationSample.OnAuthorization + (const AContext: TWebContext; UserRoles + : System.Generics.Collections.TList; + const ControllerQualifiedClassName: string; const ActionName: string; + var IsAuthorized: Boolean); +begin + IsAuthorized := False; + if ActionName = 'Logout' then + IsAuthorized := True; // you can always call logout + if ActionName = 'OnlyRole2' then + IsAuthorized := UserRoles.Contains('role2'); + if ActionName = 'OnlyRole1' then + IsAuthorized := UserRoles.Contains('role1'); + if ActionName = 'OnlyRole1EmittingJSON' then + IsAuthorized := UserRoles.Contains('role1'); +end; + +procedure TAuthenticationSample.OnRequest(const AContext: TWebContext; const ControllerQualifiedClassName: string; + const ActionName: string; var AuthenticationRequired: Boolean); +begin + AuthenticationRequired := ControllerQualifiedClassName = + 'AppControllerU.TAdminController'; + +end; + +end. diff --git a/samples/authenticationauthorization/ProjectGroup1.groupproj b/samples/middleware_basicauthentication/ProjectGroup.groupproj similarity index 100% rename from samples/authenticationauthorization/ProjectGroup1.groupproj rename to samples/middleware_basicauthentication/ProjectGroup.groupproj diff --git a/samples/authenticationauthorization/WebModuleUnit1.dfm b/samples/middleware_basicauthentication/WebModuleUnit1.dfm similarity index 84% rename from samples/authenticationauthorization/WebModuleUnit1.dfm rename to samples/middleware_basicauthentication/WebModuleUnit1.dfm index b43b8558..2c58d387 100644 --- a/samples/authenticationauthorization/WebModuleUnit1.dfm +++ b/samples/middleware_basicauthentication/WebModuleUnit1.dfm @@ -1,12 +1,11 @@ -object WebModule1: TWebModule1 - OldCreateOrder = False - OnCreate = WebModuleCreate - Actions = < - item - Default = True - Name = 'DefaultHandler' - PathInfo = '/' - end> - Height = 230 - Width = 415 -end +object WebModule1: TWebModule1 + OnCreate = WebModuleCreate + Actions = < + item + Default = True + Name = 'DefaultHandler' + PathInfo = '/' + end> + Height = 230 + Width = 415 +end diff --git a/samples/authenticationauthorization/WebModuleUnit1.pas b/samples/middleware_basicauthentication/WebModuleUnit1.pas similarity index 87% rename from samples/authenticationauthorization/WebModuleUnit1.pas rename to samples/middleware_basicauthentication/WebModuleUnit1.pas index 146a9bd1..addec183 100644 --- a/samples/authenticationauthorization/WebModuleUnit1.pas +++ b/samples/middleware_basicauthentication/WebModuleUnit1.pas @@ -1,58 +1,60 @@ -unit WebModuleUnit1; - -interface - -uses - System.SysUtils, - System.Classes, - Web.HTTPApp, - MVCFramework, - MVCFramework.Commons; - -type - TWebModule1 = class(TWebModule) - procedure WebModuleCreate(Sender: TObject); - - private - MVC: TMVCEngine; - - public - { Public declarations } - end; - -var - WebModuleClass: TComponentClass = TWebModule1; - -implementation - -{$R *.dfm} - - -uses - AppControllerU, - System.Generics.Collections, - MVCFramework.Middleware.Authentication, - MVCFramework.Middleware.StaticFiles, - AuthenticationU; - -procedure TWebModule1.WebModuleCreate(Sender: TObject); -begin - MVC := TMVCEngine.Create(Self, - procedure(Config: TMVCConfig) - begin - Config[TMVCConfigKey.SessionTimeout] := '30'; - Config[TMVCConfigKey.DefaultContentType] := 'text/html'; - end); - MVC - .AddController(TApp1MainController) - .AddController(TAdminController) - .AddMiddleware(TMVCBasicAuthenticationMiddleware.Create(TAuthenticationSample.Create)) - .AddMiddleware(TMVCStaticFilesMiddleware.Create( - '/static', { StaticFilesPath } - '..\..\www', { DocumentRoot } - 'index.html', - False { not serving a SPA } - )); -end; - -end. +unit WebModuleUnit1; + +interface + +uses + System.SysUtils, + System.Classes, + Web.HTTPApp, + MVCFramework, + MVCFramework.Commons, FireDAC.Phys.PGDef, FireDAC.Stan.Intf, FireDAC.Phys, + FireDAC.Phys.PG; + +type + TWebModule1 = class(TWebModule) + procedure WebModuleCreate(Sender: TObject); + + private + MVC: TMVCEngine; + + public + { Public declarations } + end; + +var + WebModuleClass: TComponentClass = TWebModule1; + +implementation + +{$R *.dfm} + + +uses + AppControllerU, + System.Generics.Collections, + MVCFramework.Middleware.Authentication, + MVCFramework.Middleware.ActiveRecord, + MVCFramework.Middleware.StaticFiles, + AuthenticationU; + +procedure TWebModule1.WebModuleCreate(Sender: TObject); +begin + MVC := TMVCEngine.Create(Self, + procedure(Config: TMVCConfig) + begin + Config[TMVCConfigKey.SessionTimeout] := '30'; + Config[TMVCConfigKey.DefaultContentType] := 'text/html'; + end); + MVC + .AddController(TApp1MainController) + .AddController(TAdminController) + .AddMiddleware(TMVCBasicAuthenticationMiddleware.Create(TAuthenticationSample.Create)) + .AddMiddleware(TMVCStaticFilesMiddleware.Create( + '/static', { StaticFilesPath } + 'www', { DocumentRoot } + 'index.html', + False { not serving a SPA } + )); +end; + +end. diff --git a/samples/authenticationauthorization/www/index.html b/samples/middleware_basicauthentication/bin/www/index.html similarity index 96% rename from samples/authenticationauthorization/www/index.html rename to samples/middleware_basicauthentication/bin/www/index.html index d95da22f..e79e5c34 100644 --- a/samples/authenticationauthorization/www/index.html +++ b/samples/middleware_basicauthentication/bin/www/index.html @@ -1,18 +1,18 @@ - - -

Here's the public and the private sections on this application server

- -

- The available users are shown below: -

    -
  • user1/user1 (role1)
  • -
  • user2/user2 (role2)
  • -
  • user3/user3 (role1, role2)
  • -
-

- + + +

Here's the public and the private sections on this application server

+ +

+ The available users are shown below: +

    +
  • user1/user1 (role1)
  • +
  • user2/user2 (role2)
  • +
  • user3/user3 (role1, role2)
  • +
+

+ \ No newline at end of file diff --git a/samples/authenticationauthorization/vclclient/AuthenticationAuthorizationClient.dpr b/samples/middleware_basicauthentication/vclclient/AuthenticationAuthorizationClient.dpr similarity index 100% rename from samples/authenticationauthorization/vclclient/AuthenticationAuthorizationClient.dpr rename to samples/middleware_basicauthentication/vclclient/AuthenticationAuthorizationClient.dpr diff --git a/samples/authenticationauthorization/vclclient/AuthenticationAuthorizationClient.dproj b/samples/middleware_basicauthentication/vclclient/AuthenticationAuthorizationClient.dproj similarity index 77% rename from samples/authenticationauthorization/vclclient/AuthenticationAuthorizationClient.dproj rename to samples/middleware_basicauthentication/vclclient/AuthenticationAuthorizationClient.dproj index fda121a9..87a5b116 100644 --- a/samples/authenticationauthorization/vclclient/AuthenticationAuthorizationClient.dproj +++ b/samples/middleware_basicauthentication/vclclient/AuthenticationAuthorizationClient.dproj @@ -1,7 +1,7 @@  {E7317702-64D3-4A65-8734-030F3AE3DBBC} - 19.1 + 19.5 VCL AuthenticationAuthorizationClient.dpr True @@ -68,7 +68,8 @@ Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) 1033 DBXSqliteDriver;DBXDb2Driver;dxCoreRS23;vclactnband;frxe23;vclFireDAC;dxPSLnksRS23;dxPSdxLCLnkRS23;tethering;cxDataRS23;dxPSdxOCLnkRS23;dxTabbedMDIRS23;FireDACADSDriver;dxSkinBlackRS23;dxSkinLondonLiquidSkyRS23;JvPluginSystem;dxDBXServerModeRS23;dxHttpIndyRequestRS23;dxPScxGridLnkRS23;cxSchedulerRS23;FireDACMSSQLDriver;dclRBDBE1723;vcltouch;JvBands;vcldb;rbDB1723;svn;dxWizardControlRS23;dxSkinMcSkinRS23;dxPScxCommonRS23;JvJans;Intraweb;dxSkinOffice2007BlueRS23;rbIBE1723;dxBarRS23;cxSchedulerRibbonStyleEventEditorRS23;dxSkinOffice2013WhiteRS23;JvDotNetCtrls;dxPSTeeChartRS23;cxLibraryRS23;dxSkinVisualStudio2013LightRS23;vclib;cxPivotGridChartRS23;rbDBE1723;dxSkinSummer2008RS23;dxPSdxDBOCLnkRS23;dxGDIPlusRS23;dxSkinDarkSideRS23;FireDACDBXDriver;dxSkinFoggyRS23;dxSkinSevenRS23;vclx;rbCIDE1723;dxSkinOffice2010SilverRS23;dxdborRS23;RESTBackendComponents;dxLayoutControlRS23;dxPSPrVwRibbonRS23;VCLRESTComponents;dxSkinDevExpressStyleRS23;dxSkinWhiteprintRS23;vclie;bindengine;CloudService;rbRAP1723;JvHMI;FireDACMySQLDriver;dxSkinOffice2013DarkGrayRS23;DataSnapClient;dxPScxPCProdRS23;bindcompdbx;DBXSybaseASEDriver;IndyIPServer;dxSkinPumpkinRS23;IndySystem;dsnapcon;cxTreeListdxBarPopupMenuRS23;dclRBIBE1723;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;dxSkinLilianRS23;Jcl;rbADO1723;dxBarDBNavRS23;dxFlowChartRS23;dxSkinOffice2016ColorfulRS23;rbUSER1723;DBXOdbcDriver;FireDACTDataDriver;FMXTee;ipstudiowinclient;soaprtl;DbxCommonDriver;dxSpreadSheetRS23;AsyncProDR;JvManagedThreads;dxSkinOffice2007PinkRS23;dxPSdxSpreadSheetLnkRS23;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;DTKANPRPackage;dxSkinHighContrastRS23;rtl;dxSkinSevenClassicRS23;DbxClientDriver;dxSkinDevExpressDarkStyleRS23;DBXSybaseASADriver;dxNavBarRS23;dxSkinMetropolisDarkRS23;CodeSiteExpressPkg;dxSkinTheAsphaltWorldRS23;JvSystem;SampleListViewMultiDetailAppearancePackage;dxRichEditControlRS23;JvStdCtrls;JvTimeFramework;ipstudiowin;appanalytics;cxPivotGridRS23;rbUSERDesign1723;dxSkinsdxDLPainterRS23;IndyIPClient;dxRibbonRS23;dxPScxVGridLnkRS23;bindcompvcl;frxDB23;vcldbx;dxSkinOffice2007SilverRS23;dxPScxTLLnkRS23;dxMapControlRS23;TeeUI;rbDIDE1723;JvPascalInterpreter;JvDocking;VclSmp;dxPScxSchedulerLnkRS23;cxTreeListRS23;FireDACODBCDriver;JclVcl;DataSnapIndy10ServerTransport;dxRibbonCustomizationFormRS23;dxPSRichEditControlLnkRS23;dxBarExtDBItemsRS23;DataSnapProviderClient;FireDACMongoDBDriver;dxSkiniMaginaryRS23;frx23;dxSpellCheckerRS23;JvControls;dxSkinsdxBarPainterRS23;JvPrintPreview;dxSkinCoffeeRS23;DataSnapServerMidas;RESTComponents;DBXInterBaseDriver;rbRTL1723;dxADOServerModeRS23;emsclientfiredac;DataSnapFireDAC;svnui;dxmdsRS23;dxSkinLiquidSkyRS23;dxdbtrRS23;dxSkinSpringTimeRS23;dxPSDBTeeChartRS23;JvGlobus;dxSkinscxPCPainterRS23;dxPSCoreRS23;DBXMSSQLDriver;JvMM;dxSkinXmas2008BlueRS23;rbDAD1723;DatasnapConnectorsFreePascal;bindcompfmx;JvNet;DBXOracleDriver;dxSkinSilverRS23;dxSkinValentineRS23;inetdb;JvAppFrm;ipstudiowinwordxp;rbTC1723;FmxTeeUI;dxBarExtItemsRS23;FireDACIBDriver;fmx;fmxdae;DelphiCookbookListViewAppearance;dxServerModeRS23;dxPsPrVwAdvRS23;dxSkinOffice2010BlackRS23;JvWizards;cxPageControlRS23;dxSkinStardustRS23;cxSchedulerGridRS23;dbexpress;IndyCore;dxSkinSharpPlusRS23;UIBD21Win32R;JvPageComps;dsnap;DataSnapCommon;emsclient;FireDACCommon;dxSkinOffice2010BlueRS23;bdertl;JvDB;dxSkinVS2010RS23;dxSkinMetropolisRS23;DataSnapConnectors;cxVerticalGridRS23;soapserver;dxSkinCaramelRS23;frxTee23;dxTileControlRS23;JclDeveloperTools;cxGridRS23;CPortLibDXE;FireDACOracleDriver;DBXMySQLDriver;JvCmp;rbFireDAC1723;DBXFirebirdDriver;FireDACCommonDriver;rbTCUI1723;LockBoxDR;inet;IndyIPCommon;JvCustom;dxSkinDarkRoomRS23;dxDockingRS23;vcl;dxSkinOffice2007GreenRS23;dxPScxExtCommonRS23;JvXPCtrls;dxSkinsCoreRS23;FireDACDb2Driver;dxThemeRS23;dxSkinsdxRibbonPainterRS23;dxSkinVisualStudio2013BlueRS23;rbRest1723;TSG5201;dxSkinMoneyTwinsRS23;dxPSdxFCLnkRS23;dxtrmdRS23;TeeDB;FireDAC;cxSchedulerTreeBrowserRS23;JvCore;dxFireDACServerModeRS23;dxSkinBlueRS23;OverbyteIcsD10SRun;JvCrypt;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;FireDACASADriver;cxEditorsRS23;dxSkinGlassOceansRS23;JvDlgs;JvRuntimeDesign;dxSkinsdxNavBarPainterRS23;dxGaugeControlRS23;ibxpress;Tee;dxSkinSharpRS23;DataSnapServer;ibxbindings;cxPivotGridOLAPRS23;rbIDE1723;vclwinx;FireDACDSDriver;dxSkinBlueprintRS23;dxSkinOffice2007BlackRS23;CustomIPTransport;vcldsnap;rbBDE1723;dxSkinOffice2013LightGrayRS23;bindcomp;DBXInformixDriver;officeXPrt;dxPSdxGaugeControlLnkRS23;dxPScxPivotGridLnkRS23;dxorgcRS23;dxPSdxDBTVLnkRS23;dclRBADO1723;vclribbon;dbxcds;KernowSoftwareFMX;adortl;dclRBFireDAC1723;dclRBE1723;dxComnRS23;dsnapxml;dbrtl;inetdbxpress;IndyProtocols;cxExportRS23;dxSkinOffice2016DarkRS23;JclContainers;dxSkinVisualStudio2013DarkRS23;rbRCL1723;dxSkinscxSchedulerPainterRS23;rbRIDE1723;fmxase;$(DCC_UsePackage) - CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName) + ..\bin + none $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png @@ -87,9 +88,7 @@ Debug true 1033 - true false - CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName) PerMonitor @@ -110,10 +109,6 @@
Form5
dfm
- - Cfg_2 - Base - Base @@ -121,6 +116,10 @@ Cfg_1 Base + + Cfg_2 + Base + Delphi.Personality.12 @@ -131,19 +130,14 @@ AuthenticationAuthorizationClient.dpr - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components - - - - AuthenticationAuthorizationClient.exe - true - - + + 1 @@ -156,14 +150,14 @@ 0 - + classes - 1 + 64 classes - 1 + 64 @@ -208,7 +202,6 @@ 1 - library\lib\armeabi-v7a @@ -285,6 +278,16 @@ 1 + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + res\drawable-ldpi @@ -448,6 +451,11 @@ 1 .framework + + Contents\MacOS + 1 + .framework + 0 @@ -461,7 +469,7 @@ 1 .dylib - + 1 .dylib @@ -475,6 +483,11 @@ 1 .dylib + + Contents\MacOS + 1 + .dylib + 0 .dll;.bpl @@ -489,7 +502,7 @@ 1 .dylib - + 1 .dylib @@ -503,6 +516,11 @@ 1 .dylib + + Contents\MacOS + 1 + .dylib + 0 .bpl @@ -521,7 +539,7 @@ 0 - + 0 @@ -532,512 +550,12 @@ Contents\Resources\StartUp\ 0 - + + Contents\Resources\StartUp\ 0 - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(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 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(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 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 + + 0 @@ -1048,71 +566,15 @@ 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - - - 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 + @@ -1123,6 +585,10 @@ ..\ 1 + + ..\ + 1 + @@ -1133,6 +599,10 @@ Contents 1 + + Contents + 1 + @@ -1143,6 +613,10 @@ Contents\Resources 1 + + Contents\Resources + 1 + @@ -1159,7 +633,7 @@ 1 - + 1 @@ -1173,6 +647,10 @@ Contents\MacOS 1 + + Contents\MacOS + 1 + 0 @@ -1191,6 +669,66 @@ 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 @@ -1211,16 +749,218 @@ 1 - - + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + - + + + - - - + + + True diff --git a/samples/authenticationauthorization/vclclient/MainClientFormU.dfm b/samples/middleware_basicauthentication/vclclient/MainClientFormU.dfm similarity index 100% rename from samples/authenticationauthorization/vclclient/MainClientFormU.dfm rename to samples/middleware_basicauthentication/vclclient/MainClientFormU.dfm diff --git a/samples/authenticationauthorization/vclclient/MainClientFormU.pas b/samples/middleware_basicauthentication/vclclient/MainClientFormU.pas similarity index 100% rename from samples/authenticationauthorization/vclclient/MainClientFormU.pas rename to samples/middleware_basicauthentication/vclclient/MainClientFormU.pas diff --git a/samples/middleware_cors/MainControllerU.pas b/samples/middleware_cors/MainControllerU.pas new file mode 100644 index 00000000..f386654f --- /dev/null +++ b/samples/middleware_cors/MainControllerU.pas @@ -0,0 +1,30 @@ +unit MainControllerU; + +interface + +uses + MVCFramework, MVCFramework.Commons, MVCFramework.Serializer.Commons; + +type + + [MVCPath('/api')] + TMyController = class(TMVCController) + public + [MVCPath('/customers')] + [MVCHTTPMethod([httpPOST])] + procedure CreateCustomer(const [MVCFromBody] Dict: TMVCStringDictionary); + end; + +implementation + +uses + System.SysUtils, MVCFramework.Logger, System.StrUtils; + +procedure TMyController.CreateCustomer(const [MVCFromBody] Dict: TMVCStringDictionary); +begin + Render( + ObjectDict().Add('data', StrDict.Add('message', Dict['hello'])) + ) +end; + +end. diff --git a/samples/middleware_cors/ProjectGroup.groupproj b/samples/middleware_cors/ProjectGroup.groupproj new file mode 100644 index 00000000..1b15a52f --- /dev/null +++ b/samples/middleware_cors/ProjectGroup.groupproj @@ -0,0 +1,48 @@ + + + {9F8DA910-24A1-4497-AAB9-7BDE0D4186C2} + + + + + + + + + + + Default.Personality.12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/middleware_cors/SimpleWebServer/SimpleWebServer.dpr b/samples/middleware_cors/SimpleWebServer/SimpleWebServer.dpr new file mode 100644 index 00000000..ecf31502 --- /dev/null +++ b/samples/middleware_cors/SimpleWebServer/SimpleWebServer.dpr @@ -0,0 +1,90 @@ +program SimpleWebServer; + +{$APPTYPE CONSOLE} + +uses + System.SysUtils, + WinAPI.ShellAPI, + MVCFramework, + MVCFramework.Logger, + MVCFramework.DotEnv, + MVCFramework.Commons, + MVCFramework.Signal, + Web.ReqMulti, + Web.WebReq, + Web.WebBroker, + IdContext, + IdHTTPWebBrokerBridge, + WebModuleU in 'WebModuleU.pas', Winapi.Windows {MyWebModule: TWebModule}; + +{$R *.res} + + +procedure RunServer(APort: Integer); +var + LServer: TIdHTTPWebBrokerBridge; +begin + Writeln('** DMVCFramework Server ** build ' + DMVCFRAMEWORK_VERSION); + LServer := TIdHTTPWebBrokerBridge.Create(nil); + try + LServer.OnParseAuthentication := TMVCParseAuthentication.OnParseAuthentication; + LServer.DefaultPort := APort; + LServer.KeepAlive := True; + LServer.MaxConnections := dotEnv.Env('dmvc.webbroker.max_connections', 0); + LServer.ListenQueue := dotEnv.Env('dmvc.indy.listen_queue', 500); + + LServer.Active := True; + + { Comment the next line to avoid the default browser startup } +{$IFDEF MSWINDOWS} + ShellExecute(0, 'open', PChar('http://localhost:' + inttostr(APort)), nil, nil, SW_SHOWMAXIMIZED); +{$ENDIF} + + WriteLn('Simple Web Server'); + WriteLn('Listening on port ', APort); + Write('CTRL+C to shutdown the server'); + WaitForTerminationSignal; + EnterInShutdownState; + LServer.Active := False; + finally + LServer.Free; + end; +end; + +begin + { Enable ReportMemoryLeaksOnShutdown during debug } + // ReportMemoryLeaksOnShutdown := True; + IsMultiThread := True; + + // DMVCFramework Specific Configuration + // When MVCSerializeNulls = True empty nullables and nil are serialized as json null. + // When MVCSerializeNulls = False empty nullables and nil are not serialized at all. + MVCSerializeNulls := True; + + try + if WebRequestHandler <> nil then + WebRequestHandler.WebModuleClass := WebModuleClass; + + dotEnvConfigure( + function: IMVCDotEnv + begin + Result := NewDotEnv + .WithStrategy(TMVCDotEnvPriority.FileThenEnv) + //if available, by default, loads default environment (.env) + .UseProfile('test') //if available loads the test environment (.env.test) + .UseProfile('prod') //if available loads the prod environment (.env.prod) + .UseLogger(procedure(LogItem: String) + begin + LogW('dotEnv: ' + LogItem); + end) + .Build(); //uses the executable folder to look for .env* files + end); + + WebRequestHandlerProc.MaxConnections := dotEnv.Env('dmvc.handler.max_connections', 1024); + + RunServer(dotEnv.Env('dmvc.server.port', 9090)); + except + on E: Exception do + Writeln(E.ClassName, ': ', E.Message); + end; +end. diff --git a/packages/d112/dmvcframeworkRT.dproj b/samples/middleware_cors/SimpleWebServer/SimpleWebServer.dproj similarity index 75% rename from packages/d112/dmvcframeworkRT.dproj rename to samples/middleware_cors/SimpleWebServer/SimpleWebServer.dproj index 835fb310..a91e14bf 100644 --- a/packages/d112/dmvcframeworkRT.dproj +++ b/samples/middleware_cors/SimpleWebServer/SimpleWebServer.dproj @@ -1,14 +1,14 @@  - {96D17257-AF74-48CB-9893-7BCCB56A069D} - dmvcframeworkRT.dpk + {1553C606-62E3-4D67-8E5B-3440886F90A9} 19.5 None True Debug Win32 1 - Package + Console + SimpleWebServer.dpr true @@ -23,6 +23,11 @@ Base true + + true + Base + true + true Base @@ -51,43 +56,42 @@ .\$(Platform)\$(Config) - .\$(Platform)\$(Config) + ..\bin false false false false false - true - true System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) - All - dmvcframeworkRT - true + true + $(BDS)\bin\delphi_PROJECTICON.ico + $(BDS)\bin\delphi_PROJECTICNS.icns + $(DMVC);$(DCC_UnitSearchPath) + VCL;$(DCC_Framework) + SimpleWebServer 1040 CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - DMVCFramework - CopyRight (2010-2020) Daniele Teti and the DMVCFramework Team - package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= - Debug - annotation-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.0.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.0.1.dex.jar;core-runtime-2.0.1.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.0.0.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.0.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.0.0.dex.jar;lifecycle-runtime-2.0.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.0.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar + fmx;DbxCommonDriver;bindengine;IndyIPCommon;emsclient;FireDACCommonDriver;IndyProtocols;Skia.Package.RTL;RadiantShapesFmx_Design;IndyIPClient;dbxcds;FmxTeeUI;bindcompfmx;ibmonitor;FireDACSqliteDriver;DbxClientDriver;soapmidas;fmxFireDAC;dbexpress;Python;inet;DataSnapCommon;fmxase;DzHTMLText_FMX;dbrtl;FireDACDBXDriver;Skia.Package.FMX;CustomIPTransport;DBXInterBaseDriver;IndySystem;RadiantShapesFmx;ibxbindings;bindcomp;FireDACCommon;IndyCore;RESTBackendComponents;bindcompdbx;rtl;RESTComponents;DBXSqliteDriver;IndyIPServer;dsnapxml;DataSnapClient;DataSnapProviderClient;DataSnapFireDAC;emsclientfiredac;FireDAC;FireDACDSDriver;xmlrtl;tethering;ibxpress;dsnap;CloudService;FMXTee;DataSnapNativeClient;PythonFmx;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage) + activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar - package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= - Debug - annotation-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.0.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.0.1.dex.jar;core-runtime-2.0.1.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.0.0.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.0.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.0.0.dex.jar;lifecycle-runtime-2.0.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.0.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar + fmx;DbxCommonDriver;bindengine;IndyIPCommon;emsclient;FireDACCommonDriver;IndyProtocols;Skia.Package.RTL;RadiantShapesFmx_Design;IndyIPClient;dbxcds;FmxTeeUI;bindcompfmx;ibmonitor;FireDACSqliteDriver;DbxClientDriver;soapmidas;fmxFireDAC;dbexpress;Python;inet;DataSnapCommon;DzHTMLText_FMX;dbrtl;FireDACDBXDriver;Skia.Package.FMX;CustomIPTransport;DBXInterBaseDriver;IndySystem;RadiantShapesFmx;ibxbindings;bindcomp;FireDACCommon;IndyCore;RESTBackendComponents;bindcompdbx;rtl;RESTComponents;DBXSqliteDriver;IndyIPServer;dsnapxml;DataSnapClient;DataSnapProviderClient;DataSnapFireDAC;emsclientfiredac;FireDAC;FireDACDSDriver;xmlrtl;tethering;ibxpress;dsnap;CloudService;FMXTee;DataSnapNativeClient;PythonFmx;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage) + activity-1.1.0.dex.jar;annotation-1.2.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;biometric-1.1.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.1.0.dex.jar;core-runtime-2.1.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.2.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.2.0.dex.jar;lifecycle-runtime-2.2.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.2.0.dex.jar;lifecycle-viewmodel-savedstate-2.2.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;savedstate-1.0.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar + + + DataSnapServer;fmx;emshosting;DbxCommonDriver;bindengine;FireDACCommonODBC;emsclient;FireDACCommonDriver;IndyProtocols;Skia.Package.RTL;RadiantShapesFmx_Design;dbxcds;emsedge;inetdb;FireDACSqliteDriver;DbxClientDriver;FireDACASADriver;soapmidas;dbexpress;FireDACInfxDriver;Python;inet;DataSnapCommon;dbrtl;FireDACOracleDriver;Skia.Package.FMX;CustomIPTransport;FireDACMSSQLDriver;DataSnapIndy10ServerTransport;DataSnapConnectors;FireDACMongoDBDriver;IndySystem;RadiantShapesFmx;FireDACTDataDriver;bindcomp;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;IndyCore;RESTBackendComponents;rtl;FireDACMySQLDriver;FireDACADSDriver;RESTComponents;dsnapxml;DataSnapClient;DataSnapFireDAC;emsclientfiredac;FireDACPgDriver;FireDAC;xmlrtl;dsnap;CloudService;FireDACDb2Driver;DataSnapNativeClient;DatasnapConnectorsFreePascal;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage) + RaizeComponentsVcl;JvNet;vclwinx;DataSnapServer;FixInsight_11;fmx;emshosting;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;FireDACCommonDriver;appanalytics;IndyProtocols;vclx;Skia.Package.RTL;RadiantShapesFmx_Design;IndyIPClient;dbxcds;vcledge;frxe28;frxTee28;bindcompvclwinx;Prometheus.Client.Core;FmxTeeUI;emsedge;bindcompfmx;DBXFirebirdDriver;JvBands;inetdb;JvAppFrm;ibmonitor;FireDACSqliteDriver;DbxClientDriver;FireDACASADriver;Tee;soapmidas;JclVcl;SVGIconImageListFMX;vclactnband;TeeUI;fmxFireDAC;dbexpress;Jcl;JvManagedThreads;FireDACInfxDriver;Python;DBXMySQLDriver;VclSmp;inet;DataSnapCommon;JvPascalInterpreter;PythonVcl;vcltouch;fmxase;frx28;JvPluginSystem;DBXOdbcDriver;DzHTMLText_FMX;dbrtl;JvDB;FireDACDBXDriver;FireDACOracleDriver;ComPortDrv;fmxdae;TeeDB;Skia.Package.FMX;JvTimeFramework;FireDACMSAccDriver;JvCustom;CustomIPTransport;FireDACMSSQLDriver;JvSystem;SVGIconPackage;DataSnapIndy10ServerTransport;JclDeveloperTools;JvControls;DataSnapConnectors;vcldsnap;DBXInterBaseDriver;JvCrypt;FireDACMongoDBDriver;JvJans;JvMM;IndySystem;JvWizards;frxDB28;RadiantShapesFmx;FireDACTDataDriver;Skia.Package.VCL;JvGlobus;vcldb;ibxbindings;IconFontsImageList;JclContainers;SynEditDR;JvPageComps;vclFireDAC;JvCore;bindcomp;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;IndyCore;RESTBackendComponents;dmvcframeworkDT;bindcompdbx;DzHTMLText_VCL;rtl;FireDACMySQLDriver;FireDACADSDriver;RaizeComponentsVclDb;RESTComponents;DBXSqliteDriver;vcl;IndyIPServer;dsnapxml;dsnapcon;DataSnapClient;DataSnapProviderClient;adortl;JvDotNetCtrls;JvHMI;DBXSybaseASEDriver;JvRuntimeDesign;DBXDb2Driver;JvXPCtrls;vclimg;DataSnapFireDAC;emsclientfiredac;FireDACPgDriver;FireDAC;FireDACDSDriver;inetdbxpress;xmlrtl;tethering;JvStdCtrls;ibxpress;JvDlgs;JvDocking;bindcompvcl;dsnap;JvPrintPreview;JvCmp;dmvcframeworkRT;CloudService;DBXSybaseASADriver;DBXOracleDriver;FireDACDb2Driver;DBXInformixDriver;vclib;IconFontsImageListFMX;fmxobj;bindcompvclsmp;FMXTee;DataSnapNativeClient;PythonFmx;DatasnapConnectorsFreePascal;soaprtl;SVGIconImageList;soapserver;FireDACIBDriver;$(DCC_UsePackage) Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) Debug - true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= 1033 - DMVCFramework - CopyRight (2010-2021) Daniele Teti and the DMVCFramework Team - rtl;dbrtl;IndySystem;IndyProtocols;IndyCore;dmvcframeworkDT;$(DCC_UsePackage) - 110 - rtl;dbrtl;IndySystem;IndyProtocols;IndyCore;$(DCC_UsePackage) + RaizeComponentsVcl;vclwinx;DataSnapServer;fmx;emshosting;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;FireDACCommonDriver;appanalytics;IndyProtocols;vclx;Skia.Package.RTL;RadiantShapesFmx_Design;IndyIPClient;dbxcds;vcledge;bindcompvclwinx;FmxTeeUI;emsedge;bindcompfmx;DBXFirebirdDriver;inetdb;ibmonitor;FireDACSqliteDriver;DbxClientDriver;FireDACASADriver;Tee;soapmidas;SVGIconImageListFMX;vclactnband;TeeUI;fmxFireDAC;dbexpress;FireDACInfxDriver;Python;DBXMySQLDriver;VclSmp;inet;DataSnapCommon;PythonVcl;vcltouch;fmxase;DBXOdbcDriver;DzHTMLText_FMX;dbrtl;FireDACDBXDriver;FireDACOracleDriver;ComPortDrv;fmxdae;TeeDB;Skia.Package.FMX;FireDACMSAccDriver;CustomIPTransport;FireDACMSSQLDriver;SVGIconPackage;DataSnapIndy10ServerTransport;DataSnapConnectors;vcldsnap;DBXInterBaseDriver;FireDACMongoDBDriver;IndySystem;RadiantShapesFmx;FireDACTDataDriver;Skia.Package.VCL;vcldb;ibxbindings;SynEditDR;vclFireDAC;bindcomp;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;IndyCore;RESTBackendComponents;bindcompdbx;DzHTMLText_VCL;rtl;FireDACMySQLDriver;FireDACADSDriver;RaizeComponentsVclDb;RESTComponents;DBXSqliteDriver;vcl;IndyIPServer;dsnapxml;dsnapcon;DataSnapClient;DataSnapProviderClient;adortl;DBXSybaseASEDriver;DBXDb2Driver;vclimg;DataSnapFireDAC;emsclientfiredac;FireDACPgDriver;FireDAC;FireDACDSDriver;inetdbxpress;xmlrtl;tethering;ibxpress;bindcompvcl;dsnap;CloudService;DBXSybaseASADriver;DBXOracleDriver;FireDACDb2Driver;DBXInformixDriver;vclib;fmxobj;bindcompvclsmp;FMXTee;DataSnapNativeClient;PythonFmx;DatasnapConnectorsFreePascal;soaprtl;SVGIconImageList;soapserver;FireDACIBDriver;$(DCC_UsePackage) DEBUG;$(DCC_Define) @@ -96,20 +100,14 @@ true true true + true + true - true + false 1033 - 3 - true - false - true - CompanyName=Daniele Teti and the DMVCFramework Team;FileDescription=DelphiMVCFramework 3.2.2-nitrogen;FileVersion=3.2.2.0;InternalName=DelphiMVCFramework 3.2.2-nitrogen;LegalCopyright=Daniele Teti and the DMVCFramework Team - Apache License 2;LegalTrademarks=DelphiMVCFramework;OriginalFilename=$(MSBuildProjectName);ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=DelphiMVCFramework;ProductVersion=3.2.2;Comments= - 3 - 2 - 2 - 112 - DMVCFramework - CopyRight (2010-2022) Daniele Teti and the DMVCFramework Team + (None) + none false @@ -121,74 +119,7 @@ MainSource - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Base @@ -203,13 +134,15 @@ Delphi.Personality.12 - Package + Console - dmvcframeworkRT.dpk + SimpleWebServer.dpr + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package Microsoft Office 2000 Sample Automation Server Wrapper Components Microsoft Office XP Sample Automation Server Wrapper Components @@ -225,17 +158,14 @@ true - true - - - + - dmvcframeworkRT.bpl + SimpleWebServer.exe true @@ -630,6 +560,127 @@ 0 + + + 1 + + + 1 + + + + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 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 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset @@ -830,133 +881,11 @@ 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 - - - - - - - - Contents\Resources - 1 - - - Contents\Resources - 1 - - - Contents\Resources - 1 - - - - - library\lib\armeabi-v7a - 1 - - - library\lib\arm64-v8a - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 0 - - - - - library\lib\armeabi-v7a - 1 - - - - - 1 - - - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - Assets - 1 - - - Assets - 1 - - - diff --git a/samples/middleware_cors/SimpleWebServer/WebModuleU.dfm b/samples/middleware_cors/SimpleWebServer/WebModuleU.dfm new file mode 100644 index 00000000..02d66b97 --- /dev/null +++ b/samples/middleware_cors/SimpleWebServer/WebModuleU.dfm @@ -0,0 +1,7 @@ +object MyWebModule: TMyWebModule + OnCreate = WebModuleCreate + OnDestroy = WebModuleDestroy + Actions = <> + Height = 230 + Width = 415 +end diff --git a/samples/middleware_cors/SimpleWebServer/WebModuleU.pas b/samples/middleware_cors/SimpleWebServer/WebModuleU.pas new file mode 100644 index 00000000..90af30be --- /dev/null +++ b/samples/middleware_cors/SimpleWebServer/WebModuleU.pas @@ -0,0 +1,125 @@ +unit WebModuleU; + +interface + +uses + System.SysUtils, + System.Classes, + Web.HTTPApp, + MVCFramework; + +type + TMyWebModule = class(TWebModule) + procedure WebModuleCreate(Sender: TObject); + procedure WebModuleDestroy(Sender: TObject); + private + FMVC: TMVCEngine; + public + { Public declarations } + end; + +var + WebModuleClass: TComponentClass = TMyWebModule; + +implementation + +{$R *.dfm} + +uses + System.IOUtils, + MVCFramework.Commons, + MVCFramework.Middleware.ActiveRecord, + MVCFramework.Middleware.StaticFiles, + MVCFramework.Middleware.Analytics, + MVCFramework.Middleware.Redirect, + MVCFramework.Middleware.Trace, + MVCFramework.Middleware.CORS, + MVCFramework.Middleware.ETag, + MVCFramework.Middleware.Compression; + +procedure TMyWebModule.WebModuleCreate(Sender: TObject); +begin + FMVC := TMVCEngine.Create(Self, + procedure(Config: TMVCConfig) + begin + Config.dotEnv := dotEnv; + // session timeout (0 means session cookie) + Config[TMVCConfigKey.SessionTimeout] := dotEnv.Env('dmvc.session_timeout', '0'); + //default content-type + Config[TMVCConfigKey.DefaultContentType] := dotEnv.Env('dmvc.default.content_type', TMVCConstants.DEFAULT_CONTENT_TYPE); + //default content charset + Config[TMVCConfigKey.DefaultContentCharset] := dotEnv.Env('dmvc.default.content_charset', TMVCConstants.DEFAULT_CONTENT_CHARSET); + //unhandled actions are permitted? + Config[TMVCConfigKey.AllowUnhandledAction] := dotEnv.Env('dmvc.allow_unhandled_actions', 'false'); + //enables or not system controllers loading (available only from localhost requests) + Config[TMVCConfigKey.LoadSystemControllers] := dotEnv.Env('dmvc.load_system_controllers', 'true'); + //default view file extension + Config[TMVCConfigKey.DefaultViewFileExtension] := dotEnv.Env('dmvc.default.view_file_extension', 'html'); + //view path + Config[TMVCConfigKey.ViewPath] := dotEnv.Env('dmvc.view_path', 'templates'); + //Max Record Count for automatic Entities CRUD + Config[TMVCConfigKey.MaxEntitiesRecordCount] := dotEnv.Env('dmvc.max_entities_record_count', IntToStr(TMVCConstants.MAX_RECORD_COUNT)); + //Enable Server Signature in response + Config[TMVCConfigKey.ExposeServerSignature] := dotEnv.Env('dmvc.expose_server_signature', 'false'); + //Enable X-Powered-By Header in response + Config[TMVCConfigKey.ExposeXPoweredBy] := dotEnv.Env('dmvc.expose_x_powered_by', 'true'); + // Max request size in bytes + Config[TMVCConfigKey.MaxRequestSize] := dotEnv.Env('dmvc.max_request_size', IntToStr(TMVCConstants.DEFAULT_MAX_REQUEST_SIZE)); + end); + + // Analytics middleware generates a csv log, useful to do traffic analysis + //FMVC.AddMiddleware(TMVCAnalyticsMiddleware.Create(GetAnalyticsDefaultLogger)); + + // The folder mapped as documentroot for TMVCStaticFilesMiddleware must exists! + FMVC.AddMiddleware( + TMVCStaticFilesMiddleware.Create( + '/static', + TPath.Combine(ExtractFilePath(GetModuleName(HInstance)), 'www'))); + + FMVC.AddMiddleware(TMVCRedirectMiddleware.Create(['/'], '/static')); + + // Trace middlewares produces a much detailed log for debug purposes + //FMVC.AddMiddleware(TMVCTraceMiddleware.Create); + + // CORS middleware handles... well, CORS + //FMVC.AddMiddleware(TMVCCORSMiddleware.Create); + + // Simplifies TMVCActiveRecord connection definition + { + FMVC.AddMiddleware(TMVCActiveRecordMiddleware.Create( + dotEnv.Env('firedac.connection_definition_name', 'MyConnDef'), + dotEnv.Env('firedac.connection_definitions_filename', 'FDConnectionDefs.ini') + )); + } + + + // 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); + + + + { + FMVC.OnWebContextCreate( + procedure(const Context: TWebContext) + begin + // Initialize services to make them accessibile from Context + // Context.CustomIntfObject := TMyService.Create; + end); + + FMVC.OnWebContextDestroy( + procedure(const Context: TWebContext) + begin + //Cleanup services, if needed + end); + } +end; + +procedure TMyWebModule.WebModuleDestroy(Sender: TObject); +begin + FMVC.Free; +end; + +end. diff --git a/samples/middleware_cors/WebModuleU.dfm b/samples/middleware_cors/WebModuleU.dfm new file mode 100644 index 00000000..02d66b97 --- /dev/null +++ b/samples/middleware_cors/WebModuleU.dfm @@ -0,0 +1,7 @@ +object MyWebModule: TMyWebModule + OnCreate = WebModuleCreate + OnDestroy = WebModuleDestroy + Actions = <> + Height = 230 + Width = 415 +end diff --git a/samples/middleware_cors/WebModuleU.pas b/samples/middleware_cors/WebModuleU.pas new file mode 100644 index 00000000..7e18b01d --- /dev/null +++ b/samples/middleware_cors/WebModuleU.pas @@ -0,0 +1,80 @@ +unit WebModuleU; + +interface + +uses + System.SysUtils, + System.Classes, + Web.HTTPApp, + MVCFramework, + MVCFramework.Logger; + +type + TMyWebModule = class(TWebModule) + procedure WebModuleCreate(Sender: TObject); + procedure WebModuleDestroy(Sender: TObject); + private + FMVC: TMVCEngine; + public + { Public declarations } + end; + +var + WebModuleClass: TComponentClass = TMyWebModule; + +implementation + +{$R *.dfm} + + +uses + MainControllerU, + System.IOUtils, + MVCFramework.Commons, + MVCFramework.Middleware.StaticFiles, + MVCFramework.Middleware.Redirect, + MVCFramework.Middleware.Compression, + MVCFramework.Middleware.CORS; + +procedure TMyWebModule.WebModuleCreate(Sender: TObject); +begin + FMVC := TMVCEngine.Create(Self, + procedure(Config: TMVCConfig) + begin + // session timeout (0 means session cookie) + Config[TMVCConfigKey.SessionTimeout] := '0'; + // default content-type + Config[TMVCConfigKey.DefaultContentType] := TMVCConstants.DEFAULT_CONTENT_TYPE; + // default content charset + Config[TMVCConfigKey.DefaultContentCharset] := TMVCConstants.DEFAULT_CONTENT_CHARSET; + // unhandled actions are permitted? + Config[TMVCConfigKey.AllowUnhandledAction] := 'false'; + // default view file extension + Config[TMVCConfigKey.DefaultViewFileExtension] := 'html'; + // view path + Config[TMVCConfigKey.ViewPath] := 'templates'; + // Max Record Count for automatic Entities CRUD + Config[TMVCConfigKey.MaxEntitiesRecordCount] := '20'; + // Enable Server Signature in response + Config[TMVCConfigKey.ExposeServerSignature] := 'true'; + // Max request size in bytes + Config[TMVCConfigKey.MaxRequestSize] := IntToStr(TMVCConstants.DEFAULT_MAX_REQUEST_SIZE); + Config[TMVCConfigKey.LoadSystemControllers] := 'false'; + end); + FMVC + .AddController(TMyController); + + + { // Allows all origins -> * } + //FMVC.AddMiddleware(TMVCCORSMiddleware.Create); + + { // Allows all origins -> * } + FMVC.AddMiddleware(TMVCCORSMiddleware.Create('https://anotherserver.com,http://localhost:9090')); +end; + +procedure TMyWebModule.WebModuleDestroy(Sender: TObject); +begin + FMVC.Free; +end; + +end. diff --git a/samples/middleware_cors/bin/www/index.html b/samples/middleware_cors/bin/www/index.html new file mode 100644 index 00000000..903df5db --- /dev/null +++ b/samples/middleware_cors/bin/www/index.html @@ -0,0 +1,29 @@ + + + + + + + DMVCFramework CORS Sample + + + + + +
+ + + + \ No newline at end of file diff --git a/samples/middleware_cors/middleware_cors.dpr b/samples/middleware_cors/middleware_cors.dpr new file mode 100644 index 00000000..1bbfc40a --- /dev/null +++ b/samples/middleware_cors/middleware_cors.dpr @@ -0,0 +1,67 @@ +program middleware_cors; + +{$APPTYPE CONSOLE} + + +uses + System.SysUtils, + MVCFramework, + MVCFramework.Logger, + MVCFramework.Commons, + {$IFDEF MSWINDOWS} + Winapi.Windows, + Winapi.ShellAPI, + {$ENDIF } + MVCFramework.Signal, + Web.ReqMulti, + Web.WebReq, + Web.WebBroker, + IdContext, + IdHTTPWebBrokerBridge, + MainControllerU in 'MainControllerU.pas', + WebModuleU in 'WebModuleU.pas' {MyWebModule: TWebModule}; + +{$R *.res} + + +procedure RunServer(APort: Integer); +var + LServer: TIdHTTPWebBrokerBridge; +begin + Writeln('** DMVCFramework Server ** build ' + DMVCFRAMEWORK_VERSION); + + LServer := TIdHTTPWebBrokerBridge.Create(nil); + try + LServer.OnParseAuthentication := TMVCParseAuthentication.OnParseAuthentication; + LServer.DefaultPort := APort; + LServer.MaxConnections := 0; + LServer.ListenQueue := 200; + + { required if you use JWT middleware } + LServer.OnParseAuthentication := TMVCParseAuthentication.OnParseAuthentication; + LServer.Active := True; + WriteLn('Middleware CORS Sample'); + WriteLn('Listening on port ', APort); + Write('CTRL+C to shutdown the server'); + WaitForTerminationSignal; + EnterInShutdownState; + LServer.Active := False; + finally + LServer.Free; + end; +end; + +begin + ReportMemoryLeaksOnShutdown := True; + IsMultiThread := True; + try + if WebRequestHandler <> nil then + WebRequestHandler.WebModuleClass := WebModuleClass; + WebRequestHandlerProc.MaxConnections := 1024; + RunServer(8080); + except + on E: Exception do + Writeln(E.ClassName, ': ', E.Message); + end; + +end. diff --git a/packages/d112/dmvcframeworkDT.dproj b/samples/middleware_cors/middleware_cors.dproj similarity index 79% rename from packages/d112/dmvcframeworkDT.dproj rename to samples/middleware_cors/middleware_cors.dproj index aa8c1caf..7e6ad52e 100644 --- a/packages/d112/dmvcframeworkDT.dproj +++ b/samples/middleware_cors/middleware_cors.dproj @@ -1,14 +1,14 @@  - {84344511-1DC2-41BA-8689-9F36C1D475BE} - dmvcframeworkDT.dpk + {A4AB18DC-0F2D-4D2A-94F8-67D871413D88} 19.5 - None + VCL + middleware_cors.dpr True Debug Win32 1 - Package + Console true @@ -23,6 +23,11 @@ Base true + + true + Base + true + true Base @@ -49,12 +54,6 @@ Base true - - true - Cfg_2 - true - true - .\$(Platform)\$(Config) .\$(Platform)\$(Config) @@ -63,37 +62,38 @@ false false false - true - true - System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) - All - dmvcframeworkDT - 1040 - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - DelphiMVCFramework IDE Expert + System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) + true + $(BDS)\bin\delphi_PROJECTICON.ico + $(BDS)\bin\delphi_PROJECTICNS.icns + $(DMVC);$(DCC_UnitSearchPath) + VCL;$(DCC_Framework) + middleware_cors - package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= - Debug - annotation-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.0.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.0.1.dex.jar;core-runtime-2.0.1.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.0.0.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.0.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.0.0.dex.jar;lifecycle-runtime-2.0.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.0.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar + DBXSqliteDriver;RESTComponents;DBXInterBaseDriver;emsclientfiredac;tethering;DataSnapFireDAC;bindcompfmx;fmx;FireDACIBDriver;RadiantShapesFmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;emsclient;DataSnapCommon;FireDACCommon;RESTBackendComponents;soapserver;bindengine;CloudService;FireDACCommonDriver;DataSnapClient;inet;IndyIPCommon;bindcompdbx;IndyIPServer;IndySystem;fmxFireDAC;FireDAC;FireDACSqliteDriver;ibmonitor;soaprtl;DbxCommonDriver;ibxpress;xmlrtl;soapmidas;DataSnapNativeClient;FireDACDSDriver;rtl;DbxClientDriver;ibxbindings;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;RadiantShapesFmx_Design;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;$(DCC_UsePackage) + android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png - package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= - Debug - annotation-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.0.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.0.1.dex.jar;core-runtime-2.0.1.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.0.0.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.0.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.0.0.dex.jar;lifecycle-runtime-2.0.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.0.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar + DBXSqliteDriver;RESTComponents;DBXInterBaseDriver;emsclientfiredac;tethering;DataSnapFireDAC;bindcompfmx;fmx;FireDACIBDriver;RadiantShapesFmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;emsclient;DataSnapCommon;FireDACCommon;RESTBackendComponents;soapserver;bindengine;CloudService;FireDACCommonDriver;DataSnapClient;inet;IndyIPCommon;bindcompdbx;IndyIPServer;IndySystem;fmxFireDAC;FireDAC;FireDACSqliteDriver;ibmonitor;soaprtl;DbxCommonDriver;ibxpress;xmlrtl;soapmidas;DataSnapNativeClient;FireDACDSDriver;rtl;DbxClientDriver;ibxbindings;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;RadiantShapesFmx_Design;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;$(DCC_UsePackage) + android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + + + RESTComponents;emsclientfiredac;DataSnapFireDAC;FireDACADSDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;Spring.Data;inetdb;SMCmpntRX103;emsedge;FireDACIBDriver;dbexpress;IndyCore;dsnap;emsclient;DataSnapCommon;FireDACCommon;RESTBackendComponents;DataSnapConnectors;soapserver;bindengine;CloudService;FireDACOracleDriver;FireDACMySQLDriver;FireDACCommonODBC;FireDACCommonDriver;DataSnapClient;inet;IndySystem;FireDACDb2Driver;FireDACInfxDriver;FireDAC;emshosting;FireDACSqliteDriver;FireDACPgDriver;FireDACASADriver;FireDACTDataDriver;soaprtl;DbxCommonDriver;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;rtl;emsserverresource;DbxClientDriver;CustomIPTransport;bindcomp;dbxcds;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;dbrtl;IndyProtocols;FireDACMongoDBDriver;DataSnapServerMidas;$(DCC_UsePackage) + DBXSqliteDriver;RESTComponents;fmxase;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;emsclientfiredac;tethering;svnui;DataSnapFireDAC;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;IconFontsImageList;vcltouch;vcldb;bindcompfmx;svn;DBXOracleDriver;Spring.Data;inetdb;SMCmpntRX103;RaizeComponentsVcl;emsedge;RaizeComponentsVclDb;fmx;FireDACIBDriver;fmxdae;RadiantShapesFmx;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;Python_D;dsnap;emsclient;DataSnapCommon;FireDACCommon;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;vclie;bindengine;DBXMySQLDriver;CloudService;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;FireDACCommonDriver;DataSnapClient;inet;IndyIPCommon;bindcompdbx;vcl;IndyIPServer;DBXSybaseASEDriver;IconFontsImageListFMX;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;FireDAC;emshosting;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;soaprtl;DbxCommonDriver;ibxpress;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;FireDACDSDriver;rtl;emsserverresource;DbxClientDriver;ibxbindings;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;dmvcframeworkRT;dbxcds;VclSmp;adortl;FireDACODBCDriver;RadiantShapesFmx_Design;DataSnapIndy10ServerTransport;dmvcframeworkDT;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;inetdbxpress;FireDACMongoDBDriver;DataSnapServerMidas;$(DCC_UsePackage) Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) Debug - true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= 1033 - rtl;IndySystem;IndyProtocols;IndyCore;dbrtl;dmvcframeworkRT;$(DCC_UsePackage) - ..\..\sources;$(DCC_UnitSearchPath) - DelphiMVCFramework 3.x - Design Time Support - 110 + .\bin + (None) - rtl;IndySystem;IndyProtocols;IndyCore;dbrtl;$(DCC_UsePackage) + DBXSqliteDriver;RESTComponents;fmxase;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;emsclientfiredac;tethering;DataSnapFireDAC;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;DBXOracleDriver;Spring.Data;inetdb;RaizeComponentsVcl;emsedge;RaizeComponentsVclDb;fmx;FireDACIBDriver;fmxdae;RadiantShapesFmx;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;emsclient;DataSnapCommon;FireDACCommon;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;vclie;bindengine;DBXMySQLDriver;CloudService;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;FireDACCommonDriver;DataSnapClient;inet;IndyIPCommon;bindcompdbx;vcl;IndyIPServer;DBXSybaseASEDriver;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;FireDAC;emshosting;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;soaprtl;DbxCommonDriver;ibxpress;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;FireDACDSDriver;rtl;emsserverresource;DbxClientDriver;ibxbindings;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;dbxcds;VclSmp;adortl;FireDACODBCDriver;RadiantShapesFmx_Design;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;inetdbxpress;FireDACMongoDBDriver;DataSnapServerMidas;$(DCC_UsePackage) DEBUG;$(DCC_Define) @@ -105,11 +105,7 @@ false - true 1033 - false - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=Daniele Teti and the DMVCFramework Team;LegalTrademarks=DelphiMVCFramework;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - 112 false @@ -117,51 +113,15 @@ 0 0 - - true - 1033 - MainSource - - - - - - - - - - - - - - - - -
frmDMVCNewProject
+ + +
MyWebModule
+ TWebModule
- -
frmDMVCNewUnit
-
- - - - - - ICON - DMVCNewProjectIcon - - - ICON - DMVCNewUnitIcon - - - BITMAP - SplashScreen - Base @@ -176,37 +136,30 @@
Delphi.Personality.12 - Package + Console - dmvcframeworkDT.dpk + middleware_cors.dpr - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components - - + + + + + + middleware_cors.exe true - - - - true - - - - - - true - - - - + 1 @@ -598,6 +551,127 @@ 0 + + + 1 + + + 1 + + + + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 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 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset @@ -798,127 +872,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 - - - - - - - - Contents\Resources - 1 - - - Contents\Resources - 1 - - - Contents\Resources - 1 - - - - - library\lib\armeabi-v7a - 1 - - - library\lib\arm64-v8a - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 0 - - - - - library\lib\armeabi-v7a - 1 - - - - - 1 - - - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - Assets - 1 - - - Assets - 1 - - diff --git a/samples/renders/RenderSampleControllerU.pas b/samples/renders/RenderSampleControllerU.pas index d87058fa..ac6f644d 100644 --- a/samples/renders/RenderSampleControllerU.pas +++ b/samples/renders/RenderSampleControllerU.pas @@ -32,7 +32,9 @@ uses MVCFramework, MVCFramework.Commons, MVCFramework.Serializer.Intf, - System.Rtti, BusinessObjectsU; + System.Rtti, + System.Generics.Collections, + BusinessObjectsU, Data.DB; type @@ -42,6 +44,18 @@ type procedure OnBeforeAction(AContext: TWebContext; const AActionName: string; var AHandled: Boolean); override; public + // Result BASED + [MVCHTTPMethod([httpGET])] + [MVCPath('/func/people')] + [MVCProduces('application/json')] + function GetPeople_AsObjectList_AsFunction: TEnumerable; + + [MVCHTTPMethod([httpGET])] + [MVCPath('/func/customers/simple')] + function GetCustomers_AsDataSet_AsFunction: TDataSet; + + + // Render BASED [MVCHTTPMethod([httpGET])] [MVCPath('/customers/simple')] procedure GetCustomers_AsDataSet; @@ -266,10 +280,9 @@ uses InMemoryDataU, JsonDataObjects, MVCFramework.Serializer.JsonDataObjects, - Data.DB, Web.HTTPApp, Graphics, - System.Types; + System.Types, FireDAC.Comp.Client; procedure DrawLogo(const Logo: TBitmap); var @@ -515,6 +528,20 @@ begin end; end; +function TRenderSampleController.GetCustomers_AsDataSet_AsFunction: TDataSet; +var + lDM: TMyDataModule; +begin + lDM := TMyDataModule.Create(nil); + try + lDM.qryCustomers.Open; + Result := TFDMemTable.Create(nil); + TFDMemTable(Result).CloneCursor(lDM.qryCustomers, True); + finally + lDM.Free; + end; +end; + procedure TRenderSampleController.GetCustomersAsDataSetWithRefLinks; var lDM: TMyDataModule; @@ -909,6 +936,14 @@ begin Render(HTTP_STATUS.OK, ObjectDict().Add('data', People)); end; +function TRenderSampleController.GetPeople_AsObjectList_AsFunction: TEnumerable; +begin + Result := TObjectList.Create(True); + TObjectList(Result).Add(TPerson.GetNew('Daniele','Teti', EncodeDate(1979, 11, 4), True)); + TObjectList(Result).Add(TPerson.GetNew('John','Doe', EncodeDate(1879, 10, 2), False)); + TObjectList(Result).Add(TPerson.GetNew('Jane','Doe', EncodeDate(1883, 1, 5), True)); +end; + procedure TRenderSampleController.GetPeople_AsObjectList_HATEOAS; var p: TPerson; diff --git a/samples/renders/renders.dproj b/samples/renders/renders.dproj index a8839b78..1ddbd51b 100644 --- a/samples/renders/renders.dproj +++ b/samples/renders/renders.dproj @@ -215,12 +215,12 @@
+ true - true @@ -627,6 +627,127 @@ 0 + + + 1 + + + 1 + + + + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 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 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset @@ -827,127 +948,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 - - - - - - - - Contents\Resources - 1 - - - Contents\Resources - 1 - - - Contents\Resources - 1 - - - - - library\lib\armeabi-v7a - 1 - - - library\lib\arm64-v8a - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 0 - - - - - library\lib\armeabi-v7a - 1 - - - - - 1 - - - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - Assets - 1 - - - Assets - 1 - - diff --git a/samples/session_file_based/AppControllerU.pas b/samples/session_file_based/AppControllerU.pas new file mode 100644 index 00000000..bdac9165 --- /dev/null +++ b/samples/session_file_based/AppControllerU.pas @@ -0,0 +1,102 @@ +unit AppControllerU; + +interface + +uses + MVCFramework, + MVCFramework.Commons, + MVCFramework.Logger; + +type + [MVCPath('/')] + TApp1MainController = class(TMVCController) + public + [MVCPath('/name')] + [MVCHTTPMethod([httpGET])] + procedure Index; + + [MVCPath('/list')] + [MVCHTTPMethod([httpGET])] + procedure GetCustomSessionData; + + [MVCPath('/login/($username)')] + [MVCHTTPMethod([httpGET])] + procedure DoLogin(username: String); + + [MVCPath('/fruit/($nameOfFruit)')] + [MVCHTTPMethod([httpGET])] + procedure RegisterFruit(nameOfFruit: String); + + [MVCPath('/logout')] + [MVCHTTPMethod([httpGET])] + procedure DoLogout; + + end; + +implementation + +uses + System.SysUtils, + System.Classes; + +{ TApp1MainController } + +procedure TApp1MainController.DoLogin(username: String); +begin + Session['username'] := username; + ResponseStream + .AppendLine('Logged as ' + username) + .AppendLine + .AppendLine('in address of browser type: ') + .AppendLine('http://localhost:8080/list to check the current values in session ') + .AppendLine('http://localhost:8080/fruit/apple to register apple ') + .AppendLine('http://localhost:8080/fruit/banana to register banana ') + .AppendLine('http://localhost:8080/logout to end session ') + .AppendLine('http://localhost:8080/login/johndoe to login as johndoe'); + RenderResponseStream; +end; + +procedure TApp1MainController.RegisterFruit(nameOfFruit: String); +begin + Session[nameOfFruit] := nameOfFruit; + Redirect('/list'); +end; + +procedure TApp1MainController.DoLogout; +begin + Context.SessionStop(false); + Render('Logout'); +end; + +procedure TApp1MainController.GetCustomSessionData; +var + I: Integer; + lList: TArray; +begin + lList := Session.Keys; + ResponseStream.AppendLine('List of fruits:'); + for I := 0 to Length(lList) - 1 do + begin + ResponseStream.AppendLine(IntToStr(I + 1) + '-' + Session[lList[I]]); + end; + RenderResponseStream; +end; + +procedure TApp1MainController.Index; +begin + ContentType := TMVCMediaType.TEXT_PLAIN; + + // do not create session if not already created + if Context.SessionStarted then + begin + // automaticaly create the session + Render('Session[''username''] = ' + Session['username']); + end + else + begin + Render(400, 'Session not created. Do login first'); + end; +end; + +end. + diff --git a/samples/session_file_based/FileBasedSessionSample.dpr b/samples/session_file_based/FileBasedSessionSample.dpr new file mode 100644 index 00000000..bf342dbd --- /dev/null +++ b/samples/session_file_based/FileBasedSessionSample.dpr @@ -0,0 +1,55 @@ +program FileBasedSessionSample; + +{$APPTYPE CONSOLE} + + +uses + System.SysUtils, + MVCFramework, + MVCFramework.Signal, + {$IFDEF MSWINDOWS} + Winapi.Windows, + Winapi.ShellAPI, + {$ENDIF } + Web.WebReq, + Web.WebBroker, + IdHTTPWebBrokerBridge, + WebModuleUnit1 in 'WebModuleUnit1.pas' {WebModule1: TWebModule}, + AppControllerU in 'AppControllerU.pas'; + +{$R *.res} + + +procedure RunServer(APort: Integer); +var + LServer: TIdHTTPWebBrokerBridge; +begin + Writeln(Format('Starting HTTP Server or port %d', [APort])); + LServer := TIdHTTPWebBrokerBridge.Create(nil); + try + LServer.DefaultPort := APort; + LServer.Active := True; + {$IFDEF MSWINDOWS} + //ShellExecute(0, 'open', PChar('http://localhost:' + IntToStr(APort) + '/login/john'), nil, nil, SW_SHOW); + {$ENDIF} + Writeln('CTRL+C to stop the server'); + WaitForTerminationSignal; + EnterInShutdownState; + finally + LServer.Free; + end; +end; + +begin + ReportMemoryLeaksOnShutdown := True; + try + if WebRequestHandler <> nil then + WebRequestHandler.WebModuleClass := WebModuleClass; + WebRequestHandlerProc.MaxConnections := 1024; + RunServer(8080); + except + on E: Exception do + Writeln(E.ClassName, ': ', E.Message); + end + +end. diff --git a/packages/d111/dmvcframeworkDT.dproj b/samples/session_file_based/FileBasedSessionSample.dproj similarity index 77% rename from packages/d111/dmvcframeworkDT.dproj rename to samples/session_file_based/FileBasedSessionSample.dproj index 4690f54f..4e9c4a3c 100644 --- a/packages/d111/dmvcframeworkDT.dproj +++ b/samples/session_file_based/FileBasedSessionSample.dproj @@ -1,28 +1,18 @@  - {84344511-1DC2-41BA-8689-9F36C1D475BE} - dmvcframeworkDT.dpk + {F9CBCE21-869A-478F-992C-88FCAC97BC8B} 19.5 - None + VCL + FileBasedSessionSample.dpr True Debug Win32 1 - Package + Console true - - true - Base - true - - - true - Base - true - true Base @@ -49,13 +39,15 @@ Base true - - true - Cfg_2 - true - true - + $(BDS)\bin\delphi_PROJECTICNS.icns + FileBasedSessionSample + ..\..\sources;..\..\lib\delphistompclient;..\..\lib\loggerpro;..\..\lib\dmustache;$(DCC_UnitSearchPath) + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + None + 1040 + $(BDS)\bin\delphi_PROJECTICON.ico + System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) .\$(Platform)\$(Config) .\$(Platform)\$(Config) false @@ -63,37 +55,14 @@ false false false - true - true - System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) - All - dmvcframeworkDT - 1040 - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - DelphiMVCFramework IDE Expert - - - package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= - Debug - annotation-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.0.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.0.1.dex.jar;core-runtime-2.0.1.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.0.0.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.0.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.0.0.dex.jar;lifecycle-runtime-2.0.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.0.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar - - - package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= - Debug - annotation-1.2.0.dex.jar;asynclayoutinflater-1.0.0.dex.jar;billing-4.0.0.dex.jar;browser-1.0.0.dex.jar;cloud-messaging.dex.jar;collection-1.0.0.dex.jar;coordinatorlayout-1.0.0.dex.jar;core-1.5.0-rc02.dex.jar;core-common-2.0.1.dex.jar;core-runtime-2.0.1.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;firebase-annotations-16.0.0.dex.jar;firebase-common-20.0.0.dex.jar;firebase-components-17.0.0.dex.jar;firebase-datatransport-18.0.0.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.0.0.dex.jar;firebase-installations-interop-17.0.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-22.0.0.dex.jar;fmx.dex.jar;fragment-1.0.0.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;legacy-support-core-ui-1.0.0.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.0.0.dex.jar;lifecycle-livedata-2.0.0.dex.jar;lifecycle-livedata-core-2.0.0.dex.jar;lifecycle-runtime-2.0.0.dex.jar;lifecycle-service-2.0.0.dex.jar;lifecycle-viewmodel-2.0.0.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;play-services-ads-20.1.0.dex.jar;play-services-ads-base-20.1.0.dex.jar;play-services-ads-identifier-17.0.0.dex.jar;play-services-ads-lite-20.1.0.dex.jar;play-services-base-17.5.0.dex.jar;play-services-basement-17.6.0.dex.jar;play-services-cloud-messaging-16.0.0.dex.jar;play-services-drive-17.0.0.dex.jar;play-services-games-21.0.0.dex.jar;play-services-location-18.0.0.dex.jar;play-services-maps-17.0.1.dex.jar;play-services-measurement-base-18.0.0.dex.jar;play-services-measurement-sdk-api-18.0.0.dex.jar;play-services-places-placereport-17.0.0.dex.jar;play-services-stats-17.0.0.dex.jar;play-services-tasks-17.2.0.dex.jar;print-1.0.0.dex.jar;room-common-2.1.0.dex.jar;room-runtime-2.1.0.dex.jar;slidingpanelayout-1.0.0.dex.jar;sqlite-2.0.1.dex.jar;sqlite-framework-2.0.1.dex.jar;swiperefreshlayout-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.0.0.dex.jar;transport-runtime-3.0.0.dex.jar;user-messaging-platform-1.0.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.1.0.dex.jar Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - Debug - true 1033 - rtl;IndySystem;IndyProtocols;IndyCore;dbrtl;dmvcframeworkRT;$(DCC_UsePackage) - ..\..\sources;$(DCC_UnitSearchPath) - DelphiMVCFramework 3.x - Design Time Support - 110 + cxPivotGridChartRS17;JvMM;dxSkinSevenRS17;dxSkinBlueprintRS17;dxSkinHighContrastRS17;dxSkinOffice2007BlackRS17;dxCoreRS17;cxPageControldxBarPopupMenuRS17;dxSkinXmas2008BlueRS17;dxPSDBTeeChartRS17;JvCrypt;dxPSTeeChartRS17;dxSkinSummer2008RS17;dxPScxSchedulerLnkRS17;dxSkinBlueRS17;dxSkinDarkRoomRS17;DBXInterBaseDriver;DataSnapServer;DataSnapCommon;dxPScxTLLnkRS17;JvNet;JvDotNetCtrls;dxRibbonRS17;DbxCommonDriver;cxDataRS17;vclimg;dxSkinsdxBarPainterRS17;dxPSdxDBTVLnkRS17;dbxcds;DatasnapConnectorsFreePascal;NxDBGridDsgn_dxe3;JvXPCtrls;dxSkinMoneyTwinsRS17;vcldb;cxExportRS17;dxPSCoreRS17;dxBarExtItemsRS17;dxGDIPlusRS17;FMXfrx17;dxNavBarRS17;CustomIPTransport;cxLibraryRS17;cxGridRS17;dxSkinOffice2010BlackRS17;dsnap;IndyIPServer;IndyCore;dxSkinMcSkinRS17;CloudService;dxPScxCommonRS17;FmxTeeUI;frxDB17;AnyDAC_PhysDb2_D17;dxSkinsdxDLPainterRS17;dxSkiniMaginaryRS17;JvDB;JvRuntimeDesign;dxPScxVGridLnkRS17;JclDeveloperTools;dxSkinSevenClassicRS17;dxPScxExtCommonRS17;MyFrameTestPackage;dxPScxSSLnkRS17;NxGridRun_dxe3;dxSkinLilianRS17;fs17;dxPSdxLCLnkRS17;dxSkinOffice2010BlueRS17;NxCommonRun_dxe3;bindcompfmx;DataBindingsVCL170;dxSkinOffice2010SilverRS17;vcldbx;cxSchedulerGridRS17;dbrtl;bindcomp;inetdb;JvPluginSystem;dxBarRS17;DataBindings;DBXOdbcDriver;IcsCommonDXE3Run;JvCmp;dxBarDBNavRS17;dxSkinWhiteprintRS17;JvTimeFramework;xmlrtl;dxSkinsdxRibbonPainterRS17;ibxpress;dxDockingRS17;vclactnband;bindengine;soaprtl;FMXTee;dxADOServerModeRS17;bindcompvcl;dxBarExtDBItemsRS17;dxPSPrVwRibbonRS17;Jcl;vclie;dxSkinOffice2007PinkRS17;cxPageControlRS17;dxSkinscxPCPainterRS17;AnyDAC_PhysADS_D17;AnyDAC_PhysIB_D17;dxmdsRS17;dxSkinTheAsphaltWorldRS17;DBXInformixDriver;Intraweb;dxPsPrVwAdvRS17;NxInspectorRun_dxe3;dxSkinSilverRS17;dxdborRS17;dsnapcon;DBXFirebirdDriver;fsDB17;inet;dorm_runtime_xe3;JvPascalInterpreter;vclx;dxSkinStardustRS17;cxEditorsRS17;DBXSybaseASADriver;NxInspectorDsgn_dxe3;dbexpress;IndyIPClient;AnyDAC_PhysMySQL_D17;cxTreeListdxBarPopupMenuRS17;dxSkinVS2010RS17;NxGridDsgn_dxe3;dxThemeRS17;DBXSqliteDriver;dxPScxGridLnkRS17;fmx;JvDlgs;IndySystem;TeeDB;dxSkinValentineRS17;vclib;inetdbbde;DataSnapClient;dxSkinDevExpressStyleRS17;DataSnapProviderClient;DBXSybaseASEDriver;cxBarEditItemRS17;AnyDAC_PhysMSAcc_D17;dxServerModeRS17;cxPivotGridOLAPRS17;cxSchedulerRS17;MetropolisUILiveTile;AnyDAC_PhysSQLITE_D17;dxPSLnksRS17;dxSkinPumpkinRS17;dxPSdxDBOCLnkRS17;cxVerticalGridRS17;dxSkinSpringTimeRS17;vcldsnap;dxSkinDevExpressDarkStyleRS17;DBXDb2Driver;AnyDAC_ComI_D17;DBXOracleDriver;AnyDAC_PhysMSSQL_D17;JvCore;NxDBGridRun_dxe3;vclribbon;AnyDAC_Comp_D17;cxSpreadSheetRS17;dxSkinLiquidSkyRS17;AnyDAC_PhysODBC_D17;fmxase;vcl;dxSkinOffice2007SilverRS17;AnyDAC_PhysPg_D17;IndyIPCommon;DBXMSSQLDriver;CodeSiteExpressPkg;dxPSdxOCLnkRS17;dcldxSkinsCoreRS17;JvAppFrm;AnyDAC_PhysASA_D17;inetdbxpress;webdsnap;NxCollectionRun_dxe3;AnyDAC_PhysOracle_D17;dxSkinCoffeeRS17;JvDocking;adortl;dxSkinscxSchedulerPainterRS17;JvWizards;NxCollectionDsgn_dxe3;frx17;NxCommonDsgn_dxe3;dxtrmdRS17;dxPScxPCProdRS17;AnyDAC_GUIxForms_D17;JvBands;rtl;DbxClientDriver;AnyDAC_PhysTDBX_D17;dxTabbedMDIRS17;dxComnRS17;dxSkinSharpPlusRS17;dxSkinsCoreRS17;dxSkinLondonLiquidSkyRS17;dxdbtrRS17;Tee;JclContainers;NxAddonsRun_dxe3;CPortLibDXE;JvSystem;dxorgcRS17;svnui;dxSkinBlackRS17;JvControls;NxSheetRun_dxe3;IndyProtocols;DBXMySQLDriver;dxLayoutControlRS17;bindcompdbx;TeeUI;JvJans;JvPrintPreview;JvPageComps;JvStdCtrls;JvCustom;dxSkinOffice2007BlueRS17;dxPScxPivotGridLnkRS17;dxSpellCheckerRS17;vcltouch;dxSkinOffice2007GreenRS17;dxSkinSharpRS17;websnap;dxSkinFoggyRS17;dxTileControlRS17;VclSmp;FMXfrxDB17;dxSkinDarkSideRS17;cxPivotGridRS17;DataSnapConnectors;AnyDAC_Phys_D17;fmxobj;SynEdit_RXE3;JclVcl;cxTreeListRS17;dxPSdxFCLnkRS17;dxSkinGlassOceansRS17;frxe17;svn;dxFlowChartRS17;fmxdae;dxSkinsdxNavBarPainterRS17;bdertl;VirtualTreesR;DataSnapIndy10ServerTransport;dxDBXServerModeRS17;dxSkinCaramelRS17;$(DCC_UsePackage) - rtl;IndySystem;IndyProtocols;IndyCore;dbrtl;$(DCC_UsePackage) + cxPivotGridChartRS17;JvMM;dxSkinSevenRS17;dxSkinBlueprintRS17;dxSkinHighContrastRS17;dxSkinOffice2007BlackRS17;dxCoreRS17;cxPageControldxBarPopupMenuRS17;dxSkinXmas2008BlueRS17;dxPSDBTeeChartRS17;JvCrypt;dxPSTeeChartRS17;dxSkinSummer2008RS17;dxPScxSchedulerLnkRS17;dxSkinBlueRS17;dxSkinDarkRoomRS17;DBXInterBaseDriver;DataSnapServer;DataSnapCommon;dxPScxTLLnkRS17;JvNet;dxRibbonRS17;DbxCommonDriver;cxDataRS17;vclimg;dxSkinsdxBarPainterRS17;dxPSdxDBTVLnkRS17;dbxcds;DatasnapConnectorsFreePascal;NxDBGridDsgn_dxe3;dxSkinMoneyTwinsRS17;vcldb;cxExportRS17;dxPSCoreRS17;dxBarExtItemsRS17;dxGDIPlusRS17;dxNavBarRS17;CustomIPTransport;cxLibraryRS17;cxGridRS17;dxSkinOffice2010BlackRS17;dsnap;IndyIPServer;IndyCore;dxSkinMcSkinRS17;dxPScxCommonRS17;AnyDAC_PhysDb2_D17;dxSkinsdxDLPainterRS17;dxSkiniMaginaryRS17;JvDB;dxPScxVGridLnkRS17;dxSkinSevenClassicRS17;dxPScxExtCommonRS17;dxPScxSSLnkRS17;NxGridRun_dxe3;dxSkinLilianRS17;dxPSdxLCLnkRS17;dxSkinOffice2010BlueRS17;NxCommonRun_dxe3;bindcompfmx;dxSkinOffice2010SilverRS17;cxSchedulerGridRS17;dbrtl;bindcomp;inetdb;JvPluginSystem;dxBarRS17;DBXOdbcDriver;JvCmp;dxBarDBNavRS17;dxSkinWhiteprintRS17;JvTimeFramework;xmlrtl;dxSkinsdxRibbonPainterRS17;ibxpress;dxDockingRS17;vclactnband;bindengine;soaprtl;dxADOServerModeRS17;bindcompvcl;dxBarExtDBItemsRS17;dxPSPrVwRibbonRS17;vclie;dxSkinOffice2007PinkRS17;cxPageControlRS17;dxSkinscxPCPainterRS17;AnyDAC_PhysADS_D17;AnyDAC_PhysIB_D17;dxmdsRS17;dxSkinTheAsphaltWorldRS17;DBXInformixDriver;dxPsPrVwAdvRS17;NxInspectorRun_dxe3;dxSkinSilverRS17;dxdborRS17;dsnapcon;DBXFirebirdDriver;inet;JvPascalInterpreter;vclx;dxSkinStardustRS17;cxEditorsRS17;DBXSybaseASADriver;NxInspectorDsgn_dxe3;dbexpress;IndyIPClient;AnyDAC_PhysMySQL_D17;cxTreeListdxBarPopupMenuRS17;dxSkinVS2010RS17;NxGridDsgn_dxe3;dxThemeRS17;DBXSqliteDriver;dxPScxGridLnkRS17;fmx;JvDlgs;IndySystem;TeeDB;dxSkinValentineRS17;vclib;DataSnapClient;dxSkinDevExpressStyleRS17;DataSnapProviderClient;DBXSybaseASEDriver;cxBarEditItemRS17;AnyDAC_PhysMSAcc_D17;dxServerModeRS17;cxPivotGridOLAPRS17;cxSchedulerRS17;AnyDAC_PhysSQLITE_D17;dxPSLnksRS17;dxSkinPumpkinRS17;dxPSdxDBOCLnkRS17;cxVerticalGridRS17;dxSkinSpringTimeRS17;vcldsnap;dxSkinDevExpressDarkStyleRS17;DBXDb2Driver;AnyDAC_ComI_D17;DBXOracleDriver;AnyDAC_PhysMSSQL_D17;JvCore;NxDBGridRun_dxe3;AnyDAC_Comp_D17;cxSpreadSheetRS17;dxSkinLiquidSkyRS17;AnyDAC_PhysODBC_D17;fmxase;vcl;dxSkinOffice2007SilverRS17;AnyDAC_PhysPg_D17;IndyIPCommon;DBXMSSQLDriver;dxPSdxOCLnkRS17;dcldxSkinsCoreRS17;JvAppFrm;AnyDAC_PhysASA_D17;inetdbxpress;webdsnap;NxCollectionRun_dxe3;AnyDAC_PhysOracle_D17;dxSkinCoffeeRS17;adortl;dxSkinscxSchedulerPainterRS17;JvWizards;NxCollectionDsgn_dxe3;NxCommonDsgn_dxe3;dxtrmdRS17;dxPScxPCProdRS17;AnyDAC_GUIxForms_D17;JvBands;rtl;DbxClientDriver;AnyDAC_PhysTDBX_D17;dxTabbedMDIRS17;dxComnRS17;dxSkinSharpPlusRS17;dxSkinsCoreRS17;dxSkinLondonLiquidSkyRS17;dxdbtrRS17;Tee;NxAddonsRun_dxe3;JvSystem;dxorgcRS17;dxSkinBlackRS17;JvControls;NxSheetRun_dxe3;IndyProtocols;DBXMySQLDriver;dxLayoutControlRS17;bindcompdbx;TeeUI;JvJans;JvPrintPreview;JvPageComps;JvStdCtrls;JvCustom;dxSkinOffice2007BlueRS17;dxPScxPivotGridLnkRS17;dxSpellCheckerRS17;vcltouch;dxSkinOffice2007GreenRS17;dxSkinSharpRS17;websnap;dxSkinFoggyRS17;dxTileControlRS17;VclSmp;dxSkinDarkSideRS17;cxPivotGridRS17;DataSnapConnectors;AnyDAC_Phys_D17;fmxobj;SynEdit_RXE3;cxTreeListRS17;dxPSdxFCLnkRS17;dxSkinGlassOceansRS17;dxFlowChartRS17;fmxdae;dxSkinsdxNavBarPainterRS17;DataSnapIndy10ServerTransport;dxDBXServerModeRS17;dxSkinCaramelRS17;$(DCC_UsePackage) DEBUG;$(DCC_Define) @@ -104,12 +73,10 @@ true - false - true + 3 + true 1033 - false - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=Daniele Teti and the DMVCFramework Team;LegalTrademarks=DelphiMVCFramework;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - 111 + false false @@ -117,51 +84,15 @@ 0 0 - - true - 1033 - MainSource - - - - - - - - - - - - - - - - -
frmDMVCNewProject
+ +
WebModule1
+ TWebModule
- -
frmDMVCNewUnit
-
- - - - - - ICON - DMVCNewProjectIcon - - - ICON - DMVCNewUnitIcon - - - BITMAP - SplashScreen - + Base @@ -176,37 +107,60 @@
Delphi.Personality.12 - Package + + + False + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1040 + 1252 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + + + + + + + - dmvcframeworkDT.dpk + FileBasedSessionSample.dpr - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components + Microsoft Office 2000 Beispiele für gekapselte Komponenten für Automatisierungsserver + Microsoft Office XP Beispiele für gekapselte Komponenten für Automation Server - - - + + + FileBasedSessionSample.exe true - - - true - - - - - - true - - - - + 1 @@ -933,9 +887,6 @@ - False - False - False True False diff --git a/samples/session_file_based/WebModuleUnit1.dfm b/samples/session_file_based/WebModuleUnit1.dfm new file mode 100644 index 00000000..2c58d387 --- /dev/null +++ b/samples/session_file_based/WebModuleUnit1.dfm @@ -0,0 +1,11 @@ +object WebModule1: TWebModule1 + OnCreate = WebModuleCreate + Actions = < + item + Default = True + Name = 'DefaultHandler' + PathInfo = '/' + end> + Height = 230 + Width = 415 +end diff --git a/samples/session_file_based/WebModuleUnit1.pas b/samples/session_file_based/WebModuleUnit1.pas new file mode 100644 index 00000000..b7d8a556 --- /dev/null +++ b/samples/session_file_based/WebModuleUnit1.pas @@ -0,0 +1,44 @@ +unit WebModuleUnit1; + +interface + +uses + System.SysUtils, + System.Classes, + Web.HTTPApp, + MVCFramework; + +type + TWebModule1 = class(TWebModule) + procedure WebModuleCreate(Sender: TObject); + + private + MVC: TMVCEngine; + + public + { Public declarations } + end; + +var + WebModuleClass: TComponentClass = TWebModule1; + +implementation + +{$R *.dfm} + + +uses AppControllerU, MVCFramework.Commons; + +procedure TWebModule1.WebModuleCreate(Sender: TObject); +begin + MVC := TMVCEngine.Create(Self, + procedure(Config: TMVCConfig) + begin + Config[TMVCConfigKey.SessionTimeout] := '10'; // 10minutes + Config[TMVCConfigKey.DefaultContentType] := 'text/plain'; + Config[TMVCConfigKey.SessionType] := 'file'; + end); + MVC.AddController(TApp1MainController); +end; + +end. diff --git a/sources/MVCFramework.ActiveRecord.pas b/sources/MVCFramework.ActiveRecord.pas index 877b7a76..d46ed803 100644 --- a/sources/MVCFramework.ActiveRecord.pas +++ b/sources/MVCFramework.ActiveRecord.pas @@ -103,6 +103,18 @@ type procedure EndUpdates; end; + TSQLQueryWithName = record + Name: String; + SQLText: String; + BackEnd: String; //TMVCActiveRecordBackEnd + end; + + TRQLQueryWithName = record + Name: String; + RQLText: String; + end; + + TFieldsMap = class(TObjectDictionary) private fWritableFieldsCount: Integer; @@ -133,6 +145,22 @@ type constructor Create(const PartitionClause: String); end; + MVCNamedSQLQueryAttribute = class(MVCActiveRecordCustomAttribute) + public + Name: string; + SQLQuery: String; + Backend: String; //TMVCActiveRecordBackEnd + constructor Create(aName: string; aSQLSelect: String); overload; + constructor Create(aName: string; aSQLSelect: String; aBackEnd: String); overload; + end; + + MVCNamedRQLQueryAttribute = class(MVCActiveRecordCustomAttribute) + public + Name: string; + RQLQuery: String; + constructor Create(aName: string; aRQL: String); + end; + MVCTableFieldAttribute = class(MVCActiveRecordCustomAttribute) public FieldName: string; @@ -202,6 +230,8 @@ type fPrimaryKeyOptions: TMVCActiveRecordFieldOptions; fPrimaryKeySequenceName: string; fPrimaryKeyFieldType: TFieldType; + fNamedSQLQueries: TArray; + fNamedRQLQueries: TArray; public constructor Create; destructor Destroy; override; @@ -226,7 +256,6 @@ type fBackendDriver: string; fTableMap: TMVCTableMap; function GetPartitionInfo: TPartitionInfo; - function GetBackEnd: string; function GetConnection: TFDConnection; procedure InitTableInfo; class function ExecQuery( @@ -256,7 +285,7 @@ type const Unidirectional: Boolean; const DirectExecute: Boolean): TDataSet; overload; procedure FillPrimaryKey(const SequenceName: string); - function ExecNonQuery(const SQL: string; RefreshAutoGenerated: Boolean = false): int64; + function ExecNonQuery(const SQL: string; RefreshAutoGenerated: Boolean = false): Int64; overload; class function GetByPK(aActiveRecord: TMVCActiveRecord; const aValue: string; const aFieldType: TFieldType; const RaiseExceptionIfNotFound: Boolean): TMVCActiveRecord; overload; @@ -330,10 +359,11 @@ type function GenerateSelectSQL: string; function SQLGenerator: TMVCSQLGenerator; - - function InternalCount(const RQL: string): int64; + function InternalCount(const RQL: string): Int64; 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 constructor Create(aLazyLoadConnection: Boolean); overload; { cannot be virtual! } @@ -342,6 +372,7 @@ type procedure EnsureConnection; procedure Assign(ActiveRecord: TMVCActiveRecord); virtual; procedure InvalidateConnection(const ReacquireAfterInvalidate: Boolean = false); + function GetBackEnd: string; /// /// Executes an Insert (pk is null) or an Update (pk is not null) /// @@ -354,7 +385,7 @@ type const aRaiseException: Boolean = True): Boolean; procedure Insert; function GetMapping: TMVCFieldsMapping; - function LoadByPK(const id: int64): Boolean; overload; virtual; + function LoadByPK(const id: Int64): Boolean; overload; virtual; function LoadByPK(const id: string): Boolean; overload; virtual; function LoadByPK(const id: TGuid): Boolean; overload; virtual; function LoadByPK(const id: string; const aFieldType: TFieldType): Boolean; overload; virtual; @@ -372,51 +403,25 @@ type procedure AddChildren(const ChildObject: TObject); procedure RemoveChildren(const ChildObject: TObject); function GetPrimaryKeyFieldType: TFieldType; - // dynamic access - property Attributes[const AttrName: string]: TValue read GetAttributes write SetAttributes; + + function FindSQLQueryByName(const QueryName: String; out NamedSQLQuery: TSQLQueryWithName): Boolean; + function FindRQLQueryByName(const QueryName: String; out NamedRQLQuery: TRQLQueryWithName): Boolean; + + property Attributes[const AttrName: string]: TValue + read GetAttributes + write SetAttributes; + [MVCDoNotSerialize] - property TableName: string read GetTableName write SetTableName; + property TableName: string + read GetTableName + write SetTableName; + [MVCDoNotSerialize] - property PrimaryKeyIsAutogenerated: Boolean read GetPrimaryKeyIsAutogenerated + property PrimaryKeyIsAutogenerated: Boolean + read GetPrimaryKeyIsAutogenerated write SetPrimaryKeyIsAutogenerated; - class function GetByPK(const aClass: TMVCActiveRecordClass; const aValue: int64; - const RaiseExceptionIfNotFound: Boolean = True): TMVCActiveRecord; overload; - class function GetByPK(const aClass: TMVCActiveRecordClass; const aValue: string; - const RaiseExceptionIfNotFound: Boolean = True): TMVCActiveRecord; overload; - class function GetByPK(const aClass: TMVCActiveRecordClass; const aValue: TGuid; - const RaiseExceptionIfNotFound: Boolean = True): TMVCActiveRecord; overload; + class function GetScalar(const SQL: string; const Params: array of Variant): Variant; - class function Select(const aClass: TMVCActiveRecordClass; const SQL: string; - const Params: array of Variant) - : TMVCActiveRecordList; overload; - class function Select(const aClass: TMVCActiveRecordClass; const SQL: string; - const Params: array of Variant; - const Connection: TFDConnection): TMVCActiveRecordList; overload; - class function SelectRQL(const aClass: TMVCActiveRecordClass; const RQL: string; - const MaxRecordCount: Integer) - : TMVCActiveRecordList; overload; - class function DeleteRQL(const aClass: TMVCActiveRecordClass; const RQL: string): int64; - function SelectRQL(const RQL: string; const MaxRecordCount: Integer) - : TMVCActiveRecordList; overload; - class function Where(const aClass: TMVCActiveRecordClass; const SQLWhere: string; - const Params: array of Variant) - : TMVCActiveRecordList; overload; - class function Where(const aClass: TMVCActiveRecordClass; const SQLWhere: string; - const Params: array of Variant; - const Connection: TFDConnection): TMVCActiveRecordList; overload; - class function All(const aClass: TMVCActiveRecordClass): TObjectList; - overload; - class function DeleteAll(const aClass: TMVCActiveRecordClass): int64; overload; - function Count(const RQL: string = ''): int64; overload; - class function Count(const aClass: TMVCActiveRecordClass; const RQL: string = '') - : int64; overload; - class function SelectDataSet(const SQL: string; const Params: array of Variant; - const Unidirectional: Boolean = False; - const DirectExecute: Boolean = False): TDataSet; overload; - class function SelectDataSet(const SQL: string; const Params: array of Variant; - const ParamTypes: array of TFieldType; - const Unidirectional: Boolean = False; - const DirectExecute: Boolean = False): TDataSet; overload; class function CurrentConnection: TFDConnection; end; @@ -443,21 +448,55 @@ type end; TMVCActiveRecordHelper = class helper for TMVCActiveRecord + { GetByPK } + class function GetByPK(const aClass: TMVCActiveRecordClass; const aValue: Int64; + const RaiseExceptionIfNotFound: Boolean = True): TMVCActiveRecord; overload; + class function GetByPK(const aClass: TMVCActiveRecordClass; const aValue: string; + const RaiseExceptionIfNotFound: Boolean = True): TMVCActiveRecord; overload; + class function GetByPK(const aClass: TMVCActiveRecordClass; const aValue: TGuid; + const RaiseExceptionIfNotFound: Boolean = True): TMVCActiveRecord; overload; class function GetByPK(const aValue: string; const aFieldType: TFieldType; const RaiseExceptionIfNotFound: Boolean): T; overload; - class function GetByPK(const aValue: int64; + class function GetByPK(const aValue: Int64; const RaiseExceptionIfNotFound: Boolean = True): T; overload; class function GetByPK(const aValue: string; const RaiseExceptionIfNotFound: Boolean = True): T; overload; class function GetByPK(const aValue: TGuid; const RaiseExceptionIfNotFound: Boolean = True): T; overload; + + { Select } + /// + /// Returns a TObjectList from a SQL using variant params + /// class function Select(const SQL: string; const Params: array of Variant; const Options: TMVCActiveRecordLoadOptions = []): TObjectList; overload; + /// + /// Returns a TObjectList from a SQL using typed params + /// class function Select(const SQL: string; const Params: array of Variant; const ParamTypes: array of TFieldType; const Options: TMVCActiveRecordLoadOptions = []) : TObjectList; overload; + /// + /// Fills a TObjectList 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) + /// + class function Select(const SQL: string; const Params: array of Variant; + const ParamTypes: array of TFieldType; const Options: TMVCActiveRecordLoadOptions; + const OutList: TObjectList): UInt32; overload; + + class function Select(const aClass: TMVCActiveRecordClass; const SQL: string; + const Params: array of Variant) + : TMVCActiveRecordList; overload; + class function Select(const aClass: TMVCActiveRecordClass; const SQL: string; + const Params: array of Variant; + 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; + + { SelectOne } class function SelectOne(const SQL: string; const Params: array of Variant; const ParamTypes: array of TFieldType; const Options: TMVCActiveRecordLoadOptions = []; @@ -465,14 +504,30 @@ type class function SelectOne(const SQL: string; const Params: array of Variant; const RaiseExceptionIfNotFound: Boolean = True): T; overload; + + + { SelectRQL } + function SelectRQL(const RQL: string; const MaxRecordCount: Integer) + : TMVCActiveRecordList; overload; class function SelectRQL(const RQL: string; const MaxRecordCount: Integer) : TObjectList; overload; + class function SelectRQL(const RQL: string; + const MaxRecordCount: Integer; const OutList: TObjectList): UInt32; overload; class function SelectOneByRQL(const RQL: string; const RaiseExceptionIfNotFound: Boolean = True): T; overload; + class function SelectRQL(const aClass: TMVCActiveRecordClass; const RQL: string; + const MaxRecordCount: Integer) + : TMVCActiveRecordList; overload; + class function SelectRQL(const aClass: TMVCActiveRecordClass; const RQL: string; + const MaxRecordCount: Integer; const OutList: TMVCActiveRecordList): UInt32; overload; + + { Misc } class function All: TObjectList; overload; - class function DeleteRQL(const RQL: string = ''): int64; overload; - class function Count(const RQL: string = ''): int64; overload; + class function DeleteRQL(const RQL: string = ''): Int64; overload; + class function Count(const RQL: string = ''): Int64; overload; + + { Where } class function Where(const SQLWhere: string; const Params: array of Variant) : TObjectList; overload; @@ -483,6 +538,28 @@ type class function Where(const SQLWhere: string; const Params: array of Variant; const ParamTypes: array of TFieldType): TObjectList; overload; + class function Where(const SQLWhere: string; + const Params: array of Variant; + const ParamTypes: array of TFieldType; + const OutList: TObjectList): UInt32; overload; + class function Where( + const aClass: TMVCActiveRecordClass; + const SQLWhere: string; + const Params: array of Variant) + : TMVCActiveRecordList; overload; + class function Where( + const aClass: TMVCActiveRecordClass; + const SQLWhere: string; + const Params: array of Variant; + 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; + + { GetXXXByWhere } class function GetOneByWhere(const SQLWhere: string; const Params: array of Variant; const RaiseExceptionIfNotFound: Boolean = True): T; overload; class function GetOneByWhere(const SQLWhere: string; @@ -493,8 +570,45 @@ type class function GetFirstByWhere(const SQLWhere: string; const Params: array of Variant; const ParamTypes: array of TFieldType; const RaiseExceptionIfNotFound: Boolean = True): T; overload; + + { Merge } class function Merge(CurrentList, NewList: TObjectList; const MergeMode: TMergeMode = [mmInsert, mmUpdate, mmDelete]): IMVCMultiExecutor; + + { Misc } + class function All(const aClass: TMVCActiveRecordClass): TObjectList; + overload; + class function DeleteAll(const aClass: TMVCActiveRecordClass): Int64; overload; + class function DeleteRQL(const aClass: TMVCActiveRecordClass; const RQL: string): Int64; overload; + function Count(const RQL: string = ''): Int64; overload; + class function Count(const aClass: TMVCActiveRecordClass; const RQL: string = '') + : int64; overload; + + { SelectDataSet } + class function SelectDataSet(const SQL: string; const Params: array of Variant; + const Unidirectional: Boolean = False; + const DirectExecute: Boolean = False): TDataSet; overload; + class function SelectDataSet(const SQL: string; const Params: array of Variant; + const ParamTypes: array of TFieldType; + const Unidirectional: Boolean = False; + const DirectExecute: Boolean = False): TDataSet; overload; + + { NamedQuery} + class function SelectByNamedQuery( + const QueryName: String; + const Params: array of Variant; + const ParamTypes: array of TFieldType; + const Options: TMVCActiveRecordLoadOptions = []): TObjectList; + class function SelectRQLByNamedQuery( + const QueryName: String; + const Params: array of const; + const MaxRecordCount: Integer): TObjectList; + class function DeleteRQLByNamedQuery( + const QueryName: String; + const Params: array of const): Int64; + class function CountRQLByNamedQuery( + const QueryName: string; + const Params: array of const): Int64; end; IMVCEntitiesRegistry = interface @@ -1234,6 +1348,43 @@ begin end; end; +function TMVCActiveRecord.FindRQLQueryByName(const QueryName: String; + out NamedRQLQuery: TRQLQueryWithName): Boolean; +var + I: Integer; +begin + for I := Low(fTableMap.fNamedRQLQueries) to High(fTableMap.fNamedRQLQueries) do + begin + if SameText(QueryName, fTableMap.fNamedRQLQueries[I].Name) then + begin + NamedRQLQuery := fTableMap.fNamedRQLQueries[I]; + Exit(True); + end; + end; + Result := False; +end; + +function TMVCActiveRecord.FindSQLQueryByName(const QueryName: String; + out NamedSQLQuery: TSQLQueryWithName): Boolean; +var + I: Integer; + lBackEnd: String; +begin + for I := Low(fTableMap.fNamedSQLQueries) to High(fTableMap.fNamedSQLQueries) do + begin + if SameText(QueryName, fTableMap.fNamedSQLQueries[I].Name) then + begin + lBackEnd := fTableMap.fNamedSQLQueries[I].BackEnd; + if lBackEnd.IsEmpty or (lBackEnd = GetBackEnd) then + begin + NamedSQLQuery := fTableMap.fNamedSQLQueries[I]; + Exit(True); + end; + end; + end; + Result := False; +end; + class function TMVCActiveRecord.ExecQuery(const SQL: string; const Values: array of Variant; const Unidirectional: Boolean; const DirectExecute: Boolean): TDataSet; begin @@ -1248,6 +1399,8 @@ var lPrimaryFieldTypeAsStr: string; lTableMap: TMVCTableMap; lPKCount: Integer; + lNamedSQLQueryCount: Integer; + lNamedRQLQueryCount: Integer; begin if ActiveRecordTableMapRegistry.TryGetValue(Self, fTableMap) then begin @@ -1269,6 +1422,8 @@ begin lTableMap.fRTTIType := gCtx.GetType(Self.ClassInfo) as TRttiInstanceType; lTableMap.fObjAttributes := lTableMap.fRTTIType.GetAttributes; lPKCount := 0; + lNamedSQLQueryCount := Length(lTableMap.fNamedSQLQueries); + lNamedRQLQueryCount := Length(lTableMap.fNamedRQLQueries); for lAttribute in lTableMap.fObjAttributes do begin if lAttribute is MVCTableAttribute then @@ -1287,13 +1442,30 @@ begin lTableMap.fPartitionClause := MVCPartitionAttribute(lAttribute).PartitionClause; Continue; end; + if lAttribute is MVCNamedSQLQueryAttribute then + begin + Inc(lNamedSQLQueryCount); + SetLength(lTableMap.fNamedSQLQueries, lNamedSQLQueryCount); + lTableMap.fNamedSQLQueries[lNamedSQLQueryCount - 1].Name := MVCNamedSQLQueryAttribute(lAttribute).Name; + lTableMap.fNamedSQLQueries[lNamedSQLQueryCount - 1].SQLText := MVCNamedSQLQueryAttribute(lAttribute).SQLQuery; + lTableMap.fNamedSQLQueries[lNamedSQLQueryCount - 1].BackEnd := MVCNamedSQLQueryAttribute(lAttribute).Backend; + Continue; + end; + if lAttribute is MVCNamedRQLQueryAttribute then + begin + Inc(lNamedRQLQueryCount); + SetLength(lTableMap.fNamedRQLQueries, lNamedRQLQueryCount); + lTableMap.fNamedRQLQueries[lNamedRQLQueryCount - 1].Name := MVCNamedRQLQueryAttribute(lAttribute).Name; + lTableMap.fNamedRQLQueries[lNamedRQLQueryCount - 1].RQLText := MVCNamedRQLQueryAttribute(lAttribute).RQLQuery; + Continue; + end; end; if lTableMap.fTableName = '' then begin if [eaCreate, eaUpdate, eaDelete] * lTableMap.fEntityAllowedActions <> [] then begin - raise Exception.Create('Cannot find TableNameAttribute'); + raise Exception.Create('Cannot find TableNameAttribute on class ' + ClassName + ' - [HINT] Is this class decorated with MVCTable and its fields with MVCTableField?'); end; end; @@ -1353,7 +1525,7 @@ begin lTableMap.fMap.EndUpdates; if (lPKCount + lTableMap.fMap.WritableFieldsCount + lTableMap.fMap.ReadableFieldsCount) = 0 then raise EMVCActiveRecord.Create( - 'No fields nor PKs defined. [HINT] Use MVCTableField in private fields'); + 'No fields nor PKs defined in class ' + ClassName + '. [HINT] Use MVCTableField in private fields'); lTableMap.fPartitionInfoInternal := nil; ActiveRecordTableMapRegistry.AddTableMap(Self, lTableMap); @@ -1419,6 +1591,16 @@ begin Result := GetScalar(lSQL, []); 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; var lSQL: string; @@ -1494,19 +1676,19 @@ begin end; end; -class function TMVCActiveRecord.GetByPK(const aClass: TMVCActiveRecordClass; const aValue: string; +class function TMVCActiveRecordHelper.GetByPK(const aClass: TMVCActiveRecordClass; const aValue: string; const RaiseExceptionIfNotFound: Boolean): TMVCActiveRecord; begin Result := GetByPK(aClass.Create, aValue, ftString, RaiseExceptionIfNotFound); end; -class function TMVCActiveRecord.GetByPK(const aClass: TMVCActiveRecordClass; const aValue: int64; +class function TMVCActiveRecordHelper.GetByPK(const aClass: TMVCActiveRecordClass; const aValue: int64; const RaiseExceptionIfNotFound: Boolean): TMVCActiveRecord; begin Result := GetByPK(aClass.Create, aValue.ToString, ftInteger, RaiseExceptionIfNotFound); end; -class function TMVCActiveRecord.GetByPK(const aClass: TMVCActiveRecordClass; const aValue: TGuid; +class function TMVCActiveRecordHelper.GetByPK(const aClass: TMVCActiveRecordClass; const aValue: TGuid; const RaiseExceptionIfNotFound: Boolean): TMVCActiveRecord; begin Result := GetByPK(aClass.Create, aValue.ToString, ftGuid, RaiseExceptionIfNotFound); @@ -1657,6 +1839,72 @@ begin end; end; +class function TMVCActiveRecordHelper.SelectRQL(const RQL: string; + const MaxRecordCount: Integer; const OutList: TObjectList): 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(lSQL, [], [], OutList); + finally + lAR.Free; + end; +end; + +class function TMVCActiveRecordHelper.SelectRQLByNamedQuery( + const QueryName: string; + const Params: array of const; + const MaxRecordCount: Integer): TObjectList; +var + lT: T; + lRQLQuery: TRQLQueryWithName; +begin + lT := T.Create; + try + if not lT.FindRQLQueryByName(QueryName, lRQLQuery) then + begin + raise EMVCActiveRecord.CreateFmt('NamedRQLQuery not found: %s', [QueryName]); + end; + Result := SelectRQL(Format(lRQLQuery.RQLText, Params), MaxRecordCount); + finally + lT.Free; + end; +end; + +class function TMVCActiveRecordHelper.Where(const SQLWhere: string; + const Params: array of Variant; const ParamTypes: array of TFieldType; + const OutList: TObjectList): 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(lAR.GenerateSelectSQL + lFilter + SQLWhere, Params, ParamTypes, [], OutList); + end + else + begin + if lFilter.IsEmpty then + begin + Result := Select(lAR.GenerateSelectSQL + ' WHERE ' + SQLWhere, Params, ParamTypes, [], OutList); + end + else + begin + Result := Select(lAR.GenerateSelectSQL + lFilter + ' AND ' + SQLWhere, Params, ParamTypes, [], OutList); + end; + end; + finally + lAR.Free; + end; +end; + function TMVCActiveRecord.GetPartitionInfo: TPartitionInfo; var lRQLCompilerClass: TRQLCompilerClass; @@ -1733,7 +1981,7 @@ begin [GetEnumName(TypeInfo(TMVCEntityAction), Ord(aEntityAction)), ClassName]) at ReturnAddress; end; -class function TMVCActiveRecord.Count(const aClass: TMVCActiveRecordClass; const RQL: string): int64; +class function TMVCActiveRecordHelper.Count(const aClass: TMVCActiveRecordClass; const RQL: string): int64; var lAR: TMVCActiveRecord; begin @@ -1747,7 +1995,7 @@ begin end; end; -function TMVCActiveRecord.Count(const RQL: string = ''): int64; +function TMVCActiveRecordHelper.Count(const RQL: string = ''): int64; begin Result := InternalCount(RQL); end; @@ -1757,11 +2005,49 @@ begin Result := TMVCActiveRecord.Count(TMVCActiveRecordClass(T), RQL); end; +class function TMVCActiveRecordHelper.CountRQLByNamedQuery( + const QueryName: string; + const Params: array of const): Int64; +var + lRQLQuery: TRQLQueryWithName; + lT: T; +begin + lT := T.Create; + try + if not lT.FindRQLQueryByName(QueryName, lRQLQuery) then + begin + raise EMVCActiveRecord.CreateFmt('NamedRQLQuery not found: %s', [QueryName]); + end; + Result := Count(Format(lRQLQuery.RQLText, Params)); + finally + lT.Free; + end; +end; + class function TMVCActiveRecordHelper.DeleteRQL(const RQL: string): int64; begin Result := TMVCActiveRecord.DeleteRQL(TMVCActiveRecordClass(T), RQL); end; +class function TMVCActiveRecordHelper.DeleteRQLByNamedQuery( + const QueryName: String; + const Params: array of const): Int64; +var + lRQLQuery: TRQLQueryWithName; + lT: T; +begin + lT := T.Create; + try + if not lT.FindRQLQueryByName(QueryName, lRQLQuery) then + begin + raise EMVCActiveRecord.CreateFmt('NamedRQLQuery not found: %s', [QueryName]); + end; + Result := DeleteRQL(Format(lRQLQuery.RQLText, Params)); + finally + lT.Free; + end; +end; + class function TMVCActiveRecord.CurrentConnection: TFDConnection; begin Result := ActiveRecordConnectionsRegistry.GetCurrent; @@ -1802,7 +2088,7 @@ begin OnAfterDelete; end; -class function TMVCActiveRecord.DeleteAll(const aClass: TMVCActiveRecordClass): int64; +class function TMVCActiveRecordHelper.DeleteAll(const aClass: TMVCActiveRecordClass): int64; var lAR: TMVCActiveRecord; begin @@ -1815,7 +2101,7 @@ begin end; end; -class function TMVCActiveRecord.DeleteRQL(const aClass: TMVCActiveRecordClass; const RQL: string): int64; +class function TMVCActiveRecordHelper.DeleteRQL(const aClass: TMVCActiveRecordClass; const RQL: string): int64; var lAR: TMVCActiveRecord; begin @@ -2446,40 +2732,25 @@ begin end; end; -class function TMVCActiveRecord.Select(const aClass: TMVCActiveRecordClass; const SQL: string; +class function TMVCActiveRecordHelper.Select(const aClass: TMVCActiveRecordClass; const SQL: string; const Params: array of Variant): TMVCActiveRecordList; begin Result := Select(aClass, SQL, Params, nil); end; -class function TMVCActiveRecord.Select(const aClass: TMVCActiveRecordClass; const SQL: string; +class function TMVCActiveRecordHelper.Select(const aClass: TMVCActiveRecordClass; const SQL: string; const Params: array of Variant; const Connection: TFDConnection): TMVCActiveRecordList; -var - lDataSet: TDataSet; - lAR: TMVCActiveRecord; begin Result := TMVCActiveRecordList.Create; try - lDataSet := ExecQuery(SQL, Params, Connection, True, False); - try - while not lDataSet.Eof do - begin - lAR := aClass.Create; - Result.Add(lAR); - lAR.LoadByDataset(lDataSet); - lDataSet.Next; - end; - finally - lDataSet.Free; - end; + Select(aClass, SQL, Params, Connection, Result); except Result.Free; raise; end; - end; -class function TMVCActiveRecord.SelectDataSet(const SQL: string; const Params: array of Variant; +class function TMVCActiveRecordHelper.SelectDataSet(const SQL: string; const Params: array of Variant; const ParamTypes: array of TFieldType; const Unidirectional: Boolean; const DirectExecute: Boolean): TDataSet; begin Result := TMVCActiveRecord.ExecQuery(SQL, Params, ParamTypes, Unidirectional, DirectExecute); @@ -2491,17 +2762,72 @@ begin Result := Select(SQL, Params, [], Options); end; -class function TMVCActiveRecord.SelectDataSet(const SQL: string; const Params: array of Variant; +class function TMVCActiveRecordHelper.SelectDataSet(const SQL: string; const Params: array of Variant; const Unidirectional: Boolean; const DirectExecute: Boolean): TDataSet; begin Result := TMVCActiveRecord.ExecQuery(SQL, Params, Unidirectional, DirectExecute); end; -function TMVCActiveRecord.SelectRQL(const RQL: string; const MaxRecordCount: Integer): TMVCActiveRecordList; +function TMVCActiveRecordHelper.SelectRQL(const RQL: string; const MaxRecordCount: Integer): TMVCActiveRecordList; begin Result := InternalSelectRQL(RQL, MaxRecordCount); end; +class function TMVCActiveRecordHelper.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(const SQL: string; const Params: array of Variant; + const ParamTypes: array of TFieldType; const Options: TMVCActiveRecordLoadOptions; const OutList: TObjectList): 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.SelectByNamedQuery( + const QueryName: String; const Params: array of Variant; + const ParamTypes: array of TFieldType; + const Options: TMVCActiveRecordLoadOptions): TObjectList; +var + lT: T; + lSQLQuery: TSQLQueryWithName; +begin + lT := T.Create; + try + if not lT.FindSQLQueryByName(QueryName, lSQLQuery) then + begin + raise EMVCActiveRecord.CreateFmt('NamedSQLQuery not found: %s', [QueryName]); + end; + Result := Select(lSQLQuery.SQLText, Params, ParamTypes, Options); + finally + lT.Free; + end; +end; + class function TMVCActiveRecordHelper.Select(const SQL: string; const Params: array of Variant; const ParamTypes: array of TFieldType; const Options: TMVCActiveRecordLoadOptions): TObjectList; var @@ -2511,18 +2837,7 @@ var begin Result := TObjectList.Create(True); try - lDataSet := ExecQuery(SQL, Params, ParamTypes, True, False); - try - while not lDataSet.Eof do - begin - lAR := T.Create; - Result.Add(lAR); - lAR.LoadByDataset(lDataSet, Options); - lDataSet.Next; - end; - finally - lDataSet.Free; - end; + Select(SQL, Params, ParamTypes, Options, Result); except Result.Free; raise; @@ -2581,32 +2896,17 @@ end; class function TMVCActiveRecordHelper.Where(const SQLWhere: string; const Params: array of Variant; const ParamTypes: array of TFieldType): TObjectList; -var - lAR: TMVCActiveRecord; - lFilter: string; begin - lAR := T.Create; + Result := TObjectList.Create(True); try - lFilter := lAR.SQLGenerator.GetDefaultSQLFilter(True); - if SQLWhere.Trim.IsEmpty() or SQLWhere.Trim.StartsWith('/*limit*/') or SQLWhere.Trim.StartsWith('/*sort*/') then - begin - Result := Select(lAR.GenerateSelectSQL + lFilter + SQLWhere, Params, ParamTypes) - end - else - begin - if lFilter.IsEmpty then - Result := Select(lAR.GenerateSelectSQL + ' WHERE ' + SQLWhere, Params, ParamTypes) - else - begin - Result := Select(lAR.GenerateSelectSQL + lFilter + ' AND ' + SQLWhere, Params, ParamTypes); - end; - end; - finally - lAR.Free; + Where(SQLWhere, Params, ParamTypes, Result); + except + Result.Free; + raise; end; end; -class function TMVCActiveRecord.SelectRQL(const aClass: TMVCActiveRecordClass; const RQL: string; +class function TMVCActiveRecordHelper.SelectRQL(const aClass: TMVCActiveRecordClass; const RQL: string; const MaxRecordCount: Integer): TMVCActiveRecordList; var lAR: TMVCActiveRecord; @@ -3000,6 +3300,20 @@ begin OnAfterInsertOrUpdate; end; +class function TMVCActiveRecordHelper.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); begin if fChildren = nil then @@ -3012,7 +3326,7 @@ begin end; end; -class function TMVCActiveRecord.All(const aClass: TMVCActiveRecordClass): TObjectList; +class function TMVCActiveRecordHelper.All(const aClass: TMVCActiveRecordClass): TObjectList; var lAR: TMVCActiveRecord; begin @@ -3043,22 +3357,21 @@ begin end; end; -class function TMVCActiveRecord.Where(const aClass: TMVCActiveRecordClass; const SQLWhere: string; +class function TMVCActiveRecordHelper.Where(const aClass: TMVCActiveRecordClass; const SQLWhere: string; const Params: array of Variant): TMVCActiveRecordList; begin Result := Where(aClass, SQLWhere, Params, nil); end; -class function TMVCActiveRecord.Where(const aClass: TMVCActiveRecordClass; const SQLWhere: string; +class function TMVCActiveRecordHelper.Where(const aClass: TMVCActiveRecordClass; const SQLWhere: string; const Params: array of Variant; const Connection: TFDConnection): TMVCActiveRecordList; -var - lAR: TMVCActiveRecord; begin - lAR := aClass.Create; + Result := TMVCActiveRecordList.Create; try - Result := Select(aClass, lAR.GenerateSelectSQL + SQLWhere, Params, Connection); - finally - lAR.Free; + Where(aClass, SQLWhere, Params, Connection, Result); + except + Result.Free; + raise; end; end; @@ -4063,6 +4376,53 @@ begin inherited; end; +class function TMVCActiveRecordHelper.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; + +{ MVCNamedSQLQueryAttribute } + +constructor MVCNamedSQLQueryAttribute.Create(aName, aSQLSelect: String); +begin + Create(aName, aSQLSelect, ''); +end; + +constructor MVCNamedSQLQueryAttribute.Create(aName, aSQLSelect, + aBackEnd: String); +begin + inherited Create; + Name := aName; + SQLQuery := aSQLSelect; + BackEnd := aBackEnd; +end; + +{ MVCNamedRQLQueryAttribute } + +constructor MVCNamedRQLQueryAttribute.Create(aName, aRQL: String); +begin + inherited Create; + Name := aName; + RQLQuery := aRQL; +end; + initialization gConnectionsLock := TObject.Create; diff --git a/sources/MVCFramework.DotEnv.pas b/sources/MVCFramework.DotEnv.pas index e8882ff0..f9c19f2f 100644 --- a/sources/MVCFramework.DotEnv.pas +++ b/sources/MVCFramework.DotEnv.pas @@ -204,7 +204,7 @@ begin begin fEnvPath := TPath.Combine(fEnvPath, DotEnvDirectory); end; - DoLog('Path = ' + DotEnvDirectory); + DoLog('Path = ' + fEnvPath); fEnvDict.Clear; lAllProfiles := ['default'] + fProfiles.ToArray(); DoLog('Active profile/s priority = [' + String.Join(',', lAllProfiles) + ']'); diff --git a/sources/MVCFramework.FireDAC.Utils.pas b/sources/MVCFramework.FireDAC.Utils.pas index d2136f1d..570225f6 100644 --- a/sources/MVCFramework.FireDAC.Utils.pas +++ b/sources/MVCFramework.FireDAC.Utils.pas @@ -29,7 +29,8 @@ unit MVCFramework.FireDAC.Utils; interface uses - FireDAC.Comp.Client, FireDAC.Stan.Param, System.Rtti, JsonDataObjects; + FireDAC.Comp.Client, FireDAC.Stan.Param, System.Rtti, JsonDataObjects, + Data.DB, FireDAC.Comp.DataSet; type TFireDACUtils = class sealed @@ -51,13 +52,13 @@ type TFDCustomMemTableHelper = class helper for TFDCustomMemTable public procedure InitFromMetadata(const AJSONMetadata: TJSONObject); + class function CloneFrom(const FDDataSet: TFDDataSet): TFDMemTable; static; end; implementation uses System.Generics.Collections, - Data.DB, System.Classes, MVCFramework.Serializer.Commons, System.SysUtils; @@ -222,6 +223,12 @@ begin end; end; +class function TFDCustomMemTableHelper.CloneFrom(const FDDataSet: TFDDataSet): TFDMemTable; +begin + Result := TFDMemTable.Create(nil); + TFDMemTable(Result).CloneCursor(FDDataSet); +end; + procedure TFDCustomMemTableHelper.InitFromMetadata(const AJSONMetadata: TJSONObject); begin TFireDACUtils.CreateDatasetFromMetadata(Self, AJSONMetadata); diff --git a/sources/MVCFramework.JWT.pas b/sources/MVCFramework.JWT.pas index 376447ab..6606bcb9 100644 --- a/sources/MVCFramework.JWT.pas +++ b/sources/MVCFramework.JWT.pas @@ -516,7 +516,7 @@ begin FSecretKey := SecretKey; FRegisteredClaims := TJWTRegisteredClaims.Create; FCustomClaims := TJWTCustomClaims.Create; - FHMACAlgorithm := HMAC_HS512; + FHMACAlgorithm := HMACAlgorithm; FLeewaySeconds := ALeewaySeconds; FRegClaimsToChecks := [TJWTCheckableClaim.ExpirationTime, TJWTCheckableClaim.NotBefore, TJWTCheckableClaim.IssuedAt]; end; diff --git a/sources/MVCFramework.Logger.pas b/sources/MVCFramework.Logger.pas index c3ef8813..a5355c19 100644 --- a/sources/MVCFramework.Logger.pas +++ b/sources/MVCFramework.Logger.pas @@ -194,14 +194,6 @@ begin LogE(E.ClassName + ': ' + AMessage); end; -// procedure LogException( -// const AException: Exception; -// const AMessage: string); -// begin -// Log.Error(Format('[%s] %s (Custom message: "%s")', [AException.ClassName, -// AException.Message, AMessage]), LOGGERPRO_TAG); -// end; - procedure LogEnterMethod(const AMethodName: string); begin LogI('>> ' + AMethodName); @@ -266,27 +258,27 @@ end; procedure SetDefaultLogger(const aLogWriter: ILogWriter); begin - if gDefaultLogger = nil then - begin - TMonitor.Enter(gLock); // double check here - try - if gDefaultLogger = nil then + if gDefaultLogger = nil then + begin + TMonitor.Enter(gLock); // double check here + try + if gDefaultLogger = nil then + begin + if aLogWriter <> nil then begin - if aLogWriter <> nil then - begin - gDefaultLogger := aLogWriter; - Log.Info('Custom Logger initialized', LOGGERPRO_TAG); - end - else - begin - InitializeDefaultLogger; - Log.Info('Default Logger initialized', LOGGERPRO_TAG); - end; + gDefaultLogger := aLogWriter; + Log.Info('Custom Logger initialized', LOGGERPRO_TAG); + end + else + begin + InitializeDefaultLogger; + Log.Info('Default Logger initialized', LOGGERPRO_TAG); end; - finally - TMonitor.Exit(gLock); end; + finally + TMonitor.Exit(gLock); end; + end; end; procedure InitializeDefaultLogger; diff --git a/sources/MVCFramework.RESTClient.Commons.pas b/sources/MVCFramework.RESTClient.Commons.pas index c6fa5bb1..747970e5 100644 --- a/sources/MVCFramework.RESTClient.Commons.pas +++ b/sources/MVCFramework.RESTClient.Commons.pas @@ -179,6 +179,9 @@ var begin lDecompressed := TMemoryStream.Create; try +{$IF defined(MACOS) or defined(IOS)} + lDecompressed.CopyFrom(aContentStream, 0); // MACOS automatically decompresses response body +{$ELSE} if SameText(aContentEncoding, 'gzip') or SameText(aContentEncoding, 'deflate') then begin /// Certain types of deflate compression cannot be decompressed by the standard Zlib, @@ -202,6 +205,7 @@ begin begin raise EMVCRESTClientException.CreateFmt('Content-Encoding not supported [%s]', [aContentEncoding]); end; +{$ENDIF} SetLength(Result, lDecompressed.Size); lDecompressed.Position := 0; diff --git a/sources/MVCFramework.Router.pas b/sources/MVCFramework.Router.pas index 8974f51c..01d0fb79 100644 --- a/sources/MVCFramework.Router.pas +++ b/sources/MVCFramework.Router.pas @@ -250,7 +250,7 @@ begin begin if LMethod.Visibility <> mvPublic then // 2020-08-08 Continue; - if (LMethod.MethodKind <> mkProcedure) { or LMethod.IsClassMethod } then + if not (LMethod.MethodKind in [mkProcedure, mkFunction]) then Continue; LAttributes := LMethod.GetAttributes; diff --git a/sources/MVCFramework.Serializer.Commons.pas b/sources/MVCFramework.Serializer.Commons.pas index 4dd392f0..d1095fe3 100644 --- a/sources/MVCFramework.Serializer.Commons.pas +++ b/sources/MVCFramework.Serializer.Commons.pas @@ -1141,7 +1141,7 @@ begin begin // sqlite doesn't support boolean, so are identified as integers // so we need to do some more checks... - if (aRTTIField.FieldType.TypeKind = tkEnumeration) and (aRTTIField.Name.ToLower.Contains('bool')) then + if (aRTTIField.FieldType.TypeKind = tkEnumeration) and (aRTTIField.FieldType.Handle = TypeInfo(Boolean)) then begin aRTTIField.SetValue(AObject, AField.AsInteger = 1); end diff --git a/sources/MVCFramework.Serializer.HTML.pas b/sources/MVCFramework.Serializer.HTML.pas index 4b8eb36e..3492bba5 100644 --- a/sources/MVCFramework.Serializer.HTML.pas +++ b/sources/MVCFramework.Serializer.HTML.pas @@ -77,7 +77,6 @@ type const ASerializationAction: TMVCSerializationAction = nil ): string; overload; - function SerializeCollection( const AList: TObject; const AType: TMVCSerializationType = stDefault; @@ -151,6 +150,12 @@ type const AIgnoredFields: TMVCIgnoredList = []; const ANameCase: TMVCNameCase = ncAsIs ); + + function SerializeArrayOfRecord( + var ATValueContainingAnArray: TValue; + const AType: TMVCSerializationType = stDefault; + const AIgnoredAttributes: TMVCIgnoredList = nil; + const ASerializationAction: TMVCSerializationAction = nil): string; end; implementation @@ -274,6 +279,14 @@ begin RaiseNotImplemented; end; +function TMVCHTMLSerializer.SerializeArrayOfRecord( + var ATValueContainingAnArray: TValue; const AType: TMVCSerializationType; + const AIgnoredAttributes: TMVCIgnoredList; + const ASerializationAction: TMVCSerializationAction): string; +begin + RaiseNotImplemented; +end; + function TMVCHTMLSerializer.SerializeCollection(const AList: IInterface; const AType: TMVCSerializationType; const AIgnoredAttributes: TMVCIgnoredList; const ASerializationAction: TMVCSerializationAction): string; diff --git a/sources/MVCFramework.Serializer.Intf.pas b/sources/MVCFramework.Serializer.Intf.pas index 0a07a79f..b4bd50d5 100644 --- a/sources/MVCFramework.Serializer.Intf.pas +++ b/sources/MVCFramework.Serializer.Intf.pas @@ -94,6 +94,13 @@ type const ASerializationAction: TMVCSerializationAction = nil ): string; overload; + function SerializeArrayOfRecord( + var ATValueContainingAnArray: TValue; + const AType: TMVCSerializationType = stDefault; + const AIgnoredAttributes: TMVCIgnoredList = nil; + const ASerializationAction: TMVCSerializationAction = nil + ): string; overload; + function SerializeCollection( const AList: TObject; const AType: TMVCSerializationType = stDefault; diff --git a/sources/MVCFramework.Serializer.JsonDataObjects.CustomTypes.pas b/sources/MVCFramework.Serializer.JsonDataObjects.CustomTypes.pas index 1b7a97d8..f55fab67 100644 --- a/sources/MVCFramework.Serializer.JsonDataObjects.CustomTypes.pas +++ b/sources/MVCFramework.Serializer.JsonDataObjects.CustomTypes.pas @@ -72,6 +72,11 @@ type end; TMVCObjectDictionarySerializer = class(TInterfacedObject, IMVCTypeSerializer) + private + procedure InternalSerializeIMVCObjectDictionary( + lObjDict: TMVCObjectDictionary; + var lOutObject: TJsonObject; + const ASerializationAction: TMVCSerializationAction); protected fCurrentSerializer: TMVCJsonDataObjectsSerializer; public @@ -469,27 +474,28 @@ procedure TMVCObjectDictionarySerializer.SerializeAttribute( const AElementValue: TValue; const APropertyName: string; const ASerializerObject: TObject; const AAttributes: TArray); -begin - raise EMVCDeserializationException.Create('Serialization as attribute not supported for this type'); -end; - -procedure TMVCObjectDictionarySerializer.SerializeRoot(const AObject: TObject; - out ASerializerObject: TObject; const AAttributes: TArray; - const ASerializationAction: TMVCSerializationAction); var lObjDict: TMVCObjectDictionary; - lOutObject, lOutCustom: TJsonObject; + lOutObject: TJsonObject; +begin + lObjDict := TMVCObjectDictionary(AElementValue.AsInterface); + lOutObject := TJsonObject(ASerializerObject); + InternalSerializeIMVCObjectDictionary(lObjDict, lOutObject, nil); +end; + +procedure TMVCObjectDictionarySerializer.InternalSerializeIMVCObjectDictionary( + lObjDict: TMVCObjectDictionary; + var lOutObject: TJsonObject; + const ASerializationAction: TMVCSerializationAction); +var + lOutCustom: TJsonObject; lName: string; lObj: TMVCObjectDictionary.TMVCObjectDictionaryValueItem; lList: IMVCList; lLinks: IMVCLinks; lJSONType: TJsonDataType; lJSONValue: TJsonBaseObject; - begin - lObjDict := TMVCObjectDictionary(AObject); - lOutObject := TJsonObject.Create; - try for lName in lObjDict.Keys do begin lObj := lObjDict.Items[lName]; @@ -585,10 +591,22 @@ begin RaiseSerializationError('Invalid JSON'); end; end; - // fCurrentSerializer.InternalObjectToJsonObject(lObj.Data, lOutObject.O[lName], - // TMVCSerializationType.stDefault, [], lObj.SerializationAction, lLinks, nil); end; end + +end; + +procedure TMVCObjectDictionarySerializer.SerializeRoot(const AObject: TObject; + out ASerializerObject: TObject; const AAttributes: TArray; + const ASerializationAction: TMVCSerializationAction); +var + lObjDict: TMVCObjectDictionary; + lOutObject: TJsonObject; +begin + lObjDict := TMVCObjectDictionary(AObject); + lOutObject := TJsonObject.Create; + try + InternalSerializeIMVCObjectDictionary(lObjDict, lOutObject, ASerializationAction); except lOutObject.Free; raise; diff --git a/sources/MVCFramework.Serializer.JsonDataObjects.pas b/sources/MVCFramework.Serializer.JsonDataObjects.pas index 792dec80..6c6ec09c 100644 --- a/sources/MVCFramework.Serializer.JsonDataObjects.pas +++ b/sources/MVCFramework.Serializer.JsonDataObjects.pas @@ -174,6 +174,13 @@ type const AType: TMVCSerializationType = stDefault; const AIgnoredAttributes: TMVCIgnoredList = nil; const ASerializationAction: TMVCSerializationAction = nil): string; overload; + function SerializeArrayOfRecord( + var ATValueContainingAnArray: TValue; + const AType: TMVCSerializationType = stDefault; + const AIgnoredAttributes: TMVCIgnoredList = nil; + const ASerializationAction: TMVCSerializationAction = nil + ): string; overload; + procedure RecordToJsonObject(const ARecord: Pointer; const ARecordTypeInfo: PTypeInfo; const AJSONObject: TJDOJsonObject; const AType: TMVCSerializationType; const AIgnoredAttributes: TMVCIgnoredList); @@ -3027,7 +3034,14 @@ begin begin if Obj <> nil then begin - ObjectToJsonObject(Obj, JSONArray.AddObject, GetSerializationType(Obj, AType), AIgnoredAttributes) + if Obj is TDataSet then + begin + DataSetToJsonArray(TDataSet(Obj), JSONArray.AddArray, TMVCNameCase.ncLowerCase, nil,nil,); + end + else + begin + ObjectToJsonObject(Obj, JSONArray.AddObject, GetSerializationType(Obj, AType), AIgnoredAttributes) + end; end else begin @@ -3042,6 +3056,55 @@ begin end; end; +function TMVCJsonDataObjectsSerializer.SerializeArrayOfRecord( + var ATValueContainingAnArray: TValue; const AType: TMVCSerializationType; + const AIgnoredAttributes: TMVCIgnoredList; + const ASerializationAction: TMVCSerializationAction): string; +var + I: Integer; + lCurrentArrayItem: TValue; + lJSONArr: TJsonArray; + lJObj: TJsonObject; +begin + if not ATValueContainingAnArray.IsArray then + begin + raise EMVCSerializationException.Create(String(ATValueContainingAnArray.TypeInfo^.Name) + ' is not an array'); + end; + if ATValueContainingAnArray.GetArrayLength = 0 then + begin + Result := '[]'; + end; + + lJSONArr := TJsonArray.Create; + try + for I := 0 to ATValueContainingAnArray.GetArrayLength - 1 do + begin + lJObj := lJSONArr.AddObject; + lCurrentArrayItem := ATValueContainingAnArray.GetArrayElement(I); + if lCurrentArrayItem.IsObjectInstance then + begin + raise EMVCSerializationException.CreateFmt('Found a "%s" while serializing array. Instance types not allowed in arrays - [HINT] Use list of objects instead of array', [lCurrentArrayItem.AsObject.ClassName]); + end + else + begin + InternalRecordToJsonObject( + lCurrentArrayItem.GetReferenceToRawData, + lCurrentArrayItem.TypeInfo, + lJObj, + TMVCSerializationType.stFields, + nil, + nil, + nil, + nil + ); + end; + end; + Result := lJSONArr.ToJSON(); + finally + lJSONArr.free; + end; +end; + function TMVCJsonDataObjectsSerializer.SerializeCollection(const AList: IInterface; const AType: TMVCSerializationType; const AIgnoredAttributes: TMVCIgnoredList; const ASerializationAction: TMVCSerializationAction): string; begin @@ -3731,7 +3794,6 @@ begin raise; end; end; - // lSer.JsonArrayToList(AJsonArray, AList, AClazz, AType, AIgnoredAttributes); finally lSer.Free; end; diff --git a/sources/MVCFramework.Session.pas b/sources/MVCFramework.Session.pas index 18cbc8f7..075afca7 100644 --- a/sources/MVCFramework.Session.pas +++ b/sources/MVCFramework.Session.pas @@ -32,15 +32,18 @@ uses System.SyncObjs, System.SysUtils, System.DateUtils, - System.Generics.Collections; + System.Generics.Collections, MVCFramework.Commons; const - DEFAULT_SESSION_INACTIVITY = 60; // in minutes type + EMVCSession = class(EMVCException) - TWebSession = class abstract + end; + + + TMVCWebSession = class abstract private FSessionId: string; FLastAccess: TDateTime; @@ -48,22 +51,25 @@ type protected function GetItems(const AKey: string): string; virtual; abstract; procedure SetItems(const AKey, AValue: string); virtual; abstract; + procedure SetLastAccess(Value: TDateTime); public constructor Create(const ASessionId: string; const ATimeout: UInt64); virtual; destructor Destroy; override; procedure MarkAsUsed; virtual; function ToString: string; override; function IsExpired: Boolean; virtual; - + function Keys: TArray; virtual; abstract; + class function TryFindSessionID(const ASessionID: String): Boolean; virtual; + class procedure TryDeleteSessionID(const ASessionID: String); virtual; property Items[const AKey: string]: string read GetItems write SetItems; default; property SessionId: string read FSessionId; property LastAccess: TDateTime read FLastAccess; property Timeout: UInt64 read FTimeout; end; - TWebSessionClass = class of TWebSession; + TMVCWebSessionClass = class of TMVCWebSession; - TWebSessionMemory = class(TWebSession) + TMVCWebSessionMemory = class(TMVCWebSession) private FData: TDictionary; protected @@ -72,37 +78,61 @@ type public constructor Create(const ASessionId: string; const ATimeout: UInt64); override; destructor Destroy; override; - function ToString: string; override; - property Data: TDictionary read FData; end; + + TMVCWebSessionFile = class(TMVCWebSessionMemory) + private + fSessionFolder: String; + protected + procedure StartLoading; + procedure EndLoading; + function GetFileName: String; overload; + class function GetFileName(const SessionFolder, SessionID: String): String; overload; + procedure LoadFromFile; + procedure SaveToFile; + procedure OnValueNotify(Sender: TObject; const Item: String; Action: TCollectionNotification); + public + constructor Create(const SessionID: string; const Timeout: UInt64); override; + destructor Destroy; override; + function Keys: System.TArray; override; + class function TryFindSessionID(const ASessionID: String): Boolean; override; + class procedure TryDeleteSessionID(const ASessionID: String); override; + end; + TMVCSessionFactory = class sealed private - FRegisteredSessionTypes: TDictionary; + FRegisteredSessionTypes: TDictionary; protected class var cInstance: TMVCSessionFactory; constructor Create; public destructor Destroy; override; - procedure RegisterSessionType(const AName: string; AWebSessionClass: TWebSessionClass); - function CreateNewByType(const AName, ASessionId: string; const ATimeout: UInt64): TWebSession; - + procedure RegisterSessionType(const AName: string; AWebSessionClass: TMVCWebSessionClass); + function CreateNewByType(const AName, ASessionId: string; const ATimeout: UInt64): TMVCWebSession; + function TryFindSessionID(const AName: string; const ASessionID: String): Boolean; + procedure TryDeleteSessionID(const AName: string; const ASessionID: String); class function GetInstance: TMVCSessionFactory; static; // class procedure DestroyInstance; static; end; -function GlobalSessionList: TObjectDictionary; +function GlobalSessionList: TObjectDictionary; implementation +uses + System.IOUtils, + System.Classes, + MVCFramework.Serializer.Commons; + var - GlSessionList: TObjectDictionary = nil; + GlSessionList: TObjectDictionary = nil; GlLastSessionListClear: TDateTime; GlCriticalSection: TCriticalSection; -function GlobalSessionList: TObjectDictionary; +function GlobalSessionList: TObjectDictionary; var S: string; begin @@ -111,7 +141,9 @@ begin GlCriticalSection.Enter; try if not Assigned(GlSessionList) then - GlSessionList := TObjectDictionary.Create([doOwnsValues]); + begin + GlSessionList := TObjectDictionary.Create([doOwnsValues]); + end; finally GlCriticalSection.Leave; end; @@ -122,7 +154,7 @@ begin TMonitor.Enter(GlSessionList); try for S in GlSessionList.Keys do - if TWebSession(GlSessionList.Items[S]).IsExpired then + if TMVCWebSession(GlSessionList.Items[S]).IsExpired then GlSessionList.Remove(S); GlLastSessionListClear := Now; finally @@ -135,19 +167,19 @@ end; { TWebSession } -constructor TWebSession.Create(const ASessionId: string; const ATimeout: UInt64); +constructor TMVCWebSession.Create(const ASessionId: string; const ATimeout: UInt64); begin inherited Create; FSessionId := ASessionId; FTimeout := ATimeout; end; -destructor TWebSession.Destroy; +destructor TMVCWebSession.Destroy; begin inherited Destroy; end; -function TWebSession.IsExpired: Boolean; +function TMVCWebSession.IsExpired: Boolean; begin if (FTimeout = 0) then Result := MinutesBetween(Now, LastAccess) > DEFAULT_SESSION_INACTIVITY @@ -155,31 +187,46 @@ begin Result := MinutesBetween(Now, LastAccess) > FTimeout; end; -procedure TWebSession.MarkAsUsed; +procedure TMVCWebSession.MarkAsUsed; begin FLastAccess := Now; end; -function TWebSession.ToString: string; +procedure TMVCWebSession.SetLastAccess(Value: TDateTime); +begin + FLastAccess := Value; +end; + +function TMVCWebSession.ToString: string; begin Result := ''; end; +class procedure TMVCWebSession.TryDeleteSessionID(const ASessionID: String); +begin + //do nothing +end; + +class function TMVCWebSession.TryFindSessionID(const ASessionID: String): Boolean; +begin + Result := False; +end; + { TWebSessionMemory } -constructor TWebSessionMemory.Create(const ASessionId: string; const ATimeout: UInt64); +constructor TMVCWebSessionMemory.Create(const ASessionId: string; const ATimeout: UInt64); begin inherited Create(ASessionId, ATimeout); FData := TDictionary.Create; end; -destructor TWebSessionMemory.Destroy; +destructor TMVCWebSessionMemory.Destroy; begin FData.Free; inherited Destroy; end; -function TWebSessionMemory.GetItems(const AKey: string): string; +function TMVCWebSessionMemory.GetItems(const AKey: string): string; begin TMonitor.Enter(Self); try @@ -190,7 +237,7 @@ begin end; end; -procedure TWebSessionMemory.SetItems(const AKey, AValue: string); +procedure TMVCWebSessionMemory.SetItems(const AKey, AValue: string); begin TMonitor.Enter(Self); try @@ -200,7 +247,7 @@ begin end; end; -function TWebSessionMemory.ToString: string; +function TMVCWebSessionMemory.ToString: string; var LKey: string; begin @@ -214,15 +261,15 @@ end; constructor TMVCSessionFactory.Create; begin inherited Create; - FRegisteredSessionTypes := TDictionary.Create; + FRegisteredSessionTypes := TDictionary.Create; end; -function TMVCSessionFactory.CreateNewByType(const AName, ASessionId: string; const ATimeout: UInt64): TWebSession; +function TMVCSessionFactory.CreateNewByType(const AName, ASessionId: string; const ATimeout: UInt64): TMVCWebSession; var - Clazz: TWebSessionClass; + Clazz: TMVCWebSessionClass; begin if not FRegisteredSessionTypes.TryGetValue(AName, Clazz) then - raise Exception.Create('Unknown application session type'); + raise EMVCSession.Create('Unknown application session type: ' + AName); Result := Clazz.Create(ASessionId, ATimeout); end; @@ -241,14 +288,164 @@ begin Result := cInstance; end; -procedure TMVCSessionFactory.RegisterSessionType(const AName: string; AWebSessionClass: TWebSessionClass); +procedure TMVCSessionFactory.RegisterSessionType(const AName: string; AWebSessionClass: TMVCWebSessionClass); begin FRegisteredSessionTypes.AddOrSetValue(AName, AWebSessionClass); end; +procedure TMVCSessionFactory.TryDeleteSessionID(const AName, ASessionID: String); +var + Clazz: TMVCWebSessionClass; +begin + if not FRegisteredSessionTypes.TryGetValue(AName, Clazz) then + raise EMVCSession.Create('Unknown application session type: ' + AName); + Clazz.TryDeleteSessionID(ASessionID); +end; + +function TMVCSessionFactory.TryFindSessionID(const AName: string; const ASessionID: String): Boolean; +var + Clazz: TMVCWebSessionClass; +begin + if not FRegisteredSessionTypes.TryGetValue(AName, Clazz) then + raise EMVCSession.Create('Unknown application session type: ' + AName); + Result := Clazz.TryFindSessionID(ASessionID); +end; + +{ TWebSessionMemoryController } + +constructor TMVCWebSessionFile.Create(const SessionID: string; const Timeout: UInt64); +begin + inherited Create(SessionID, Timeout); + Data.OnValueNotify := OnValueNotify; + fSessionFolder := TPath.Combine(AppPath, 'sessions'); + TDirectory.CreateDirectory(fSessionFolder); + LoadFromFile; + MarkAsUsed; + SaveToFile; +end; + +destructor TMVCWebSessionFile.Destroy; +begin + inherited; +end; + +procedure TMVCWebSessionFile.EndLoading; +begin + Data.OnValueNotify := OnValueNotify; +end; + +class function TMVCWebSessionFile.GetFileName(const SessionFolder, + SessionID: String): String; +begin + Result := TPath.Combine(SessionFolder, SessionId); +end; + +function TMVCWebSessionFile.GetFileName: String; +begin + Result := GetFileName(fSessionFolder, SessionId); +end; + +function TMVCWebSessionFile.Keys: System.TArray; +begin + Result := Data.Keys.ToArray; +end; + +procedure TMVCWebSessionFile.LoadFromFile; +var + lFileName: String; + lFile: TStreamReader; + lLine: string; + lPieces: TArray; +begin + lFileName := GetFileName; + if not TFile.Exists(lFileName) then + begin + Exit; + end; + //Log.Info('Loading session %s from %s', [SessionId, lFileName], 'file_session_events'); + lFile := TFile.OpenText(lFileName); + try + StartLoading; + try + SetLastAccess(ISOTimeStampToDateTime(lFile.ReadLine)); + while not lFile.EndOfStream do + begin + lLine := lFile.ReadLine; + lPieces := lLine.Split(['=']); + Data.Add(lPieces[0], lPieces[1]); + end; + finally + EndLoading; + end; + finally + lFile.Free; + end; +end; + +procedure TMVCWebSessionFile.OnValueNotify(Sender: TObject; const Item: String; + Action: TCollectionNotification); +begin + if Action in [cnAdded, cnExtracted, cnRemoved] then + begin + //Log.Info('Saving session %s because item changed [%s]', [SessionId, Item], 'file_session_events'); + SaveToFile; + end; +end; + +procedure TMVCWebSessionFile.SaveToFile; +var + lFileName: String; + lPair: TPair; + lFile: TStreamWriter; +begin + MarkAsUsed; + lFileName := GetFileName; + lFile := TFile.CreateText(lFileName); + try + lFile.WriteLine(DateTimeToISOTimeStamp(LastAccess)); + for lPair in Data do + begin + lFile.WriteLine(String.Join('=', [lPair.Key, lPair.Value])); + end; + lFile.Close; + finally + lFile.Free; + end; +end; + +procedure TMVCWebSessionFile.StartLoading; +begin + Data.OnValueNotify := nil; +end; + +class procedure TMVCWebSessionFile.TryDeleteSessionID(const ASessionID: String); +var + lSessionFolder: string; +begin + inherited; + lSessionFolder := TPath.Combine(AppPath, 'sessions'); + if TFile.Exists(GetFileName(lSessionFolder, ASessionID)) then + begin + TFile.Delete(GetFileName(lSessionFolder, ASessionID)); + end; +end; + +class function TMVCWebSessionFile.TryFindSessionID( + const ASessionID: String): Boolean; +var + lSessionFolder: string; +begin + inherited; + lSessionFolder := TPath.Combine(AppPath, 'sessions'); + Result := TFile.Exists(GetFileName(lSessionFolder, ASessionID)); +end; + + initialization -TMVCSessionFactory.GetInstance.RegisterSessionType('memory', TWebSessionMemory); +TMVCSessionFactory.GetInstance.RegisterSessionType('memory', TMVCWebSessionMemory); +TMVCSessionFactory.GetInstance.RegisterSessionType('file', TMVCWebSessionFile); + GlCriticalSection := TCriticalSection.Create; finalization diff --git a/sources/MVCFramework.pas b/sources/MVCFramework.pas index 439997ac..5083835a 100644 --- a/sources/MVCFramework.pas +++ b/sources/MVCFramework.pas @@ -506,8 +506,8 @@ type function IsValid: Boolean; procedure Clear; - procedure SaveToSession(const AWebSession: TWebSession); - function LoadFromSession(const AWebSession: TWebSession): Boolean; + procedure SaveToSession(const AWebSession: TMVCWebSession); + function LoadFromSession(const AWebSession: TMVCWebSession): Boolean; property UserName: string read FUserName write FUserName; property Roles: TList read FRoles; @@ -525,10 +525,10 @@ type FIsSessionStarted: Boolean; FSessionMustBeClose: Boolean; FLoggedUser: TUser; - FWebSession: TWebSession; + FWebSession: TMVCWebSession; FData: TMVCStringDictionary; - FIntfObject: IInterface; - function GetWebSession: TWebSession; + fIntfObject: IInterface; + function GetWebSession: TMVCWebSession; function GetLoggedUser: TUser; function GetParamsTable: TMVCRequestParamsTable; procedure SetParamsTable(const AValue: TMVCRequestParamsTable); @@ -541,14 +541,14 @@ type procedure BindToSession(const ASessionId: string); function SendSessionCookie(const AContext: TWebContext): string; function AddSessionToTheSessionList(const ASessionType, ASessionId: string; - const ASessionTimeout: Integer): TWebSession; + const ASessionTimeout: Integer): TMVCWebSession; function GetData: TMVCStringDictionary; public constructor Create(const ARequest: TWebRequest; const AResponse: TWebResponse; const AConfig: TMVCConfig; const ASerializers: TDictionary); destructor Destroy; override; - procedure SessionStart; virtual; + procedure SessionStart(const SessionType: String); virtual; procedure SessionStop(const ARaiseExceptionIfExpired: Boolean = True); virtual; function SessionStarted: Boolean; @@ -560,7 +560,7 @@ type property LoggedUser: TUser read GetLoggedUser; property Request: TMVCWebRequest read FRequest; property Response: TMVCWebResponse read FResponse; - property Session: TWebSession read GetWebSession; + property Session: TMVCWebSession read GetWebSession; property Config: TMVCConfig read FConfig; property Data: TMVCStringDictionary read GetData; property CustomIntfObject: IInterface read GetIntfObject write SetIntfObject; @@ -772,7 +772,7 @@ type private FViewModel: TMVCViewDataObject; FViewDataSets: TMVCViewDataSet; - function GetSession: TWebSession; + function GetSession: TMVCWebSession; function GetViewData(const aModelName: string): TObject; function GetViewDataset(const aDataSetName: string): TDataSet; procedure SetViewData(const aModelName: string; const Value: TObject); @@ -808,7 +808,7 @@ type /// procedure LoadViewFragment(const AViewFragment: string); - function SessionAs: T; + function SessionAs: T; procedure RaiseSessionExpired; virtual; // Avoiding mid-air collisions - support @@ -819,7 +819,7 @@ type // Properties property Context: TWebContext read GetContext write FContext; - property Session: TWebSession read GetSession; + property Session: TMVCWebSession read GetSession; property ContentType: string read GetContentType write SetContentType; property StatusCode: Integer read GetStatusCode write SetStatusCode; procedure PushObjectToView(const aModelName: string; const AModel: TObject); @@ -1089,7 +1089,7 @@ type function CustomExceptionHandling(const Ex: Exception; const AController: TMVCController; const AContext: TWebContext): Boolean; class function GetCurrentSession(const ASessionId: string; - const ARaiseExceptionIfExpired: Boolean = True): TWebSession; static; + const ARaiseExceptionIfExpired: Boolean = True): TMVCWebSession; static; class function ExtractSessionIdFromWebRequest(const AWebRequest: TWebRequest): string; static; class function SendSessionCookie(const AContext: TWebContext): string; overload; static; class function SendSessionCookie(const AContext: TWebContext; const ASessionId: string): string; @@ -1101,9 +1101,8 @@ type constructor Create(const AWebModule: TWebModule; const AConfigAction: TProc = nil; const ACustomLogger: ILogWriter = nil); reintroduce; destructor Destroy; override; - - function GetSessionBySessionId(const ASessionId: string): TWebSession; function TryGetProtocolFilter(var ProtocolFilter: T): Boolean; + function GetSessionBySessionId(const ASessionId: string): TMVCWebSession; { webcontext events} procedure OnWebContextCreate(const WebContextCreateEvent: TWebContextCreateEvent); @@ -1153,43 +1152,77 @@ type property message: string read FMessage write FMessage; end; + + // std responses + + IMVCResponse = interface + ['{9DFEC741-EE38-4AC9-9C2C-9EA0D15D08D5}'] + function GetData: TObject; + function GetMessage: string; + function GetReasonString: string; + function GetStatusCode: Integer; + function GetIgnoredList: TMVCIgnoredList; + property StatusCode: Integer read GetStatusCode; + property ReasonString: string read GetReasonString; + property Message: string read GetMessage; + property Data: TObject read GetData; + end; + [MVCNameCase(ncLowerCase)] - TMVCResponse = class + TMVCResponse = class(TInterfacedObject, IMVCResponse) private - FStatusCode: Integer; - FReasonString: string; - FMessage: string; + fStatusCode: Integer; + fReasonString: string; + fMessage: string; fDataObject: TObject; + fIgnoredList: TMVCIgnoredList; + fObjectDictionary: IMVCObjectDictionary; + function GetData: TObject; + function GetMessage: string; + function GetReasonString: string; + function GetStatusCode: Integer; + procedure SetData(const Value: TObject); + procedure SetMessage(const Value: string); + procedure SetReasonString(const Value: string); + procedure SetStatusCode(const Value: Integer); + function GetObjectDictionary: IMVCObjectDictionary; + procedure SetObjectDictionary(const Value: IMVCObjectDictionary); protected - { protected declarations } - public constructor Create; overload; virtual; - constructor Create(AStatusCode: Integer; AReasonString: string; AMessage: string); overload; + public + constructor Create(AStatusCode: Integer; AMessage: string; AReasonString: string = ''); overload; + constructor Create(AStatusCode: Integer; AData: TObject; AReasonString: string = ''); overload; + constructor Create(AStatusCode: Integer; AObjectDictionary: IMVCObjectDictionary; AReasonString: 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; - property Data: TObject read fDataObject write fDataObject; + function GetIgnoredList: TMVCIgnoredList; + [MVCDoNotSerialize] + property StatusCode: Integer read GetStatusCode write SetStatusCode; + [MVCDoNotSerialize] + property ReasonString: string read GetReasonString write SetReasonString; + property Message: string read GetMessage write SetMessage; + property Data: TObject read GetData write SetData; + property ObjectDictionary: IMVCObjectDictionary read GetObjectDictionary write SetObjectDictionary; end; [MVCNameCase(ncLowerCase)] TMVCErrorResponse = class(TMVCResponse) private - FClassname: string; - FItems: TObjectList; - FAppErrorCode: Integer; - FDetailedMessage: string; + fClassname: string; + fItems: TObjectList; + fAppErrorCode: Integer; + fDetailedMessage: string; procedure SetAppErrorCode(const Value: Integer); public constructor Create; override; destructor Destroy; override; - property Classname: string read FClassname write FClassname; - property DetailedMessage: string read FDetailedMessage write FDetailedMessage; - property AppErrorCode: Integer read FAppErrorCode write SetAppErrorCode; + property Classname: string read fClassname write fClassname; + property DetailedMessage: string read fDetailedMessage write fDetailedMessage; + property AppErrorCode: Integer read fAppErrorCode write SetAppErrorCode; [MVCListOf(TMVCErrorResponseItem)] - property Items: TObjectList read FItems; + property Items: TObjectList read fItems; end; + // end - std responses TMVCBaseViewEngine = class(TMVCBase) @@ -1224,7 +1257,13 @@ type function IsShuttingDown: Boolean; procedure EnterInShutdownState; function CreateResponse(const StatusCode: UInt16; const ReasonString: string; - const Message: string = ''): TMVCResponse; + const Message: string = ''): TMVCResponse; deprecated 'Use MVCResponse()'; + +// std responses +function MVCResponse(AStatusCode: Integer; AMessage: string = ''; AReasonString: string = ''): IMVCResponse; overload; +function MVCResponse(AStatusCode: Integer; AData: TObject; AReasonString: string = ''): IMVCResponse; overload; +function MVCResponse(AStatusCode: Integer; AObjectDictionary: IMVCObjectDictionary; AReasonString: string = ''): IMVCResponse; overload; +// end - std responses implementation @@ -1992,7 +2031,7 @@ begin Result := (not UserName.IsEmpty) and (LoggedSince > 0); end; -function TUser.LoadFromSession(const AWebSession: TWebSession): Boolean; +function TUser.LoadFromSession(const AWebSession: TMVCWebSession): Boolean; var SerObj: string; Pieces: TArray; @@ -2016,7 +2055,7 @@ begin end; end; -procedure TUser.SaveToSession(const AWebSession: TWebSession); +procedure TUser.SaveToSession(const AWebSession: TMVCWebSession); var LRoles: string; begin @@ -2044,9 +2083,9 @@ end; { TWebContext } function TWebContext.AddSessionToTheSessionList(const ASessionType, ASessionId: string; - const ASessionTimeout: Integer): TWebSession; + const ASessionTimeout: Integer): TMVCWebSession; var - Session: TWebSession; + Session: TMVCWebSession; begin if (Trim(ASessionType) = EmptyStr) then raise EMVCException.Create('Empty Session Type'); @@ -2218,16 +2257,35 @@ begin Result := FRequest.ParamsTable; end; -function TWebContext.GetWebSession: TWebSession; +function TWebContext.GetWebSession: TMVCWebSession; +var + lSessionIDFromRequest: string; + lSessionType: String; begin if not Assigned(FWebSession) then begin - FWebSession := TMVCEngine.GetCurrentSession( - TMVCEngine.ExtractSessionIdFromWebRequest(FRequest.RawWebRequest), False); + lSessionIDFromRequest := TMVCEngine.ExtractSessionIdFromWebRequest(FRequest.RawWebRequest); + FWebSession := TMVCEngine.GetCurrentSession(lSessionIDFromRequest, False); if not Assigned(FWebSession) then - SessionStart + begin + lSessionType := Config[TMVCConfigKey.SessionType]; + if not TMVCSessionFactory.GetInstance.TryFindSessionID(lSessionType, lSessionIDFromRequest) then + begin + SessionStart(lSessionType); + end + else + begin + FWebSession := AddSessionToTheSessionList( + lSessionType, + lSessionIDFromRequest, + StrToInt(Config[TMVCConfigKey.SessionTimeout])); + TMVCEngine.SendSessionCookie(Self, FWebSession.SessionId); + end; + end else + begin TMVCEngine.SendSessionCookie(Self, FWebSession.SessionId); + end; end; Result := FWebSession; Result.MarkAsUsed; @@ -2255,14 +2313,14 @@ begin Result := FSessionMustBeClose; end; -procedure TWebContext.SessionStart; +procedure TWebContext.SessionStart(const SessionType: String); var ID: string; begin if not Assigned(FWebSession) then begin ID := TMVCEngine.SendSessionCookie(Self); - FWebSession := AddSessionToTheSessionList(Config[TMVCConfigKey.SessionType], ID, + FWebSession := AddSessionToTheSessionList(SessionType, ID, StrToInt64(Config[TMVCConfigKey.SessionTimeout])); FIsSessionStarted := True; FSessionMustBeClose := False; @@ -2305,10 +2363,20 @@ begin begin raise EMVCSessionExpiredException.Create('Session not started'); end; + GlobalSessionList.Remove(SId); + if SId <> '' then begin FWebSession := nil; + try + TMVCSessionFactory.GetInstance.TryDeleteSessionID(Config[TMVCConfigKey.SessionType], SId); + except + on E: Exception do + begin + LogException(E, 'Cannot delete session file for sessionid: ' + SId); + end; + end; end; finally TMonitor.Exit(GlobalSessionList); @@ -2446,7 +2514,6 @@ begin {end - filters} FControllers := TObjectList.Create(True); FSavedOnBeforeDispatch := nil; - WebRequestHandler.CacheConnections := True; WebRequestHandler.MaxConnections := 4096; @@ -2569,66 +2636,6 @@ begin end; end; -//procedure TMVCEngine.ExecuteAfterControllerActionMiddleware(const AContext: TWebContext; -// const AControllerQualifiedClassName: string; const AActionName: string; -// const AHandled: Boolean); -//var -// I: Integer; -//begin -// for I := 0 to FMiddlewares.Count - 1 do -// begin -// FMiddlewares[I].OnAfterControllerAction(AContext, AControllerQualifiedClassName, AActionName, AHandled); -// end; -//end; - -//procedure TMVCEngine.ExecuteAfterRoutingMiddleware(const AContext: TWebContext; -// const AHandled: Boolean); -//var -// I: Integer; -//begin -// for I := 0 to FMiddlewares.Count - 1 do -// begin -// FMiddlewares[I].OnAfterRouting(AContext, AHandled); -// end; -//end; - -//procedure TMVCEngine.ExecuteBeforeControllerActionMiddleware(const AContext: TWebContext; -// const AControllerQualifiedClassName: string; const AActionName: string; var AHandled: Boolean); -//var -// Middleware: IMVCMiddleware; -//begin -// if not AHandled then -// begin -// for Middleware in FMiddlewares do -// begin -// Middleware.OnBeforeControllerAction(AContext, AControllerQualifiedClassName, AActionName, -// AHandled); -// if AHandled then -// begin -// Break; -// end; -// end; -// end; -//end; - -//procedure TMVCEngine.ExecuteBeforeRoutingMiddleware(const AContext: TWebContext; -// var AHandled: Boolean); -//var -// Middleware: IMVCMiddleware; -//begin -// if not AHandled then -// begin -// for Middleware in FMiddlewares do -// begin -// Middleware.OnBeforeRouting(AContext, AHandled); -// if AHandled then -// begin -// Break; -// end; -// end; -// end; -//end; - class function TMVCEngine.ExtractSessionIdFromWebRequest(const AWebRequest: TWebRequest): string; begin Result := AWebRequest.CookieFields.Values[TMVCConstants.SESSION_TOKEN_NAME]; @@ -2642,8 +2649,11 @@ begin FWebModule.BeforeDispatch := OnBeforeDispatch; end; -class function TMVCEngine.GetCurrentSession(const ASessionId: string; const ARaiseExceptionIfExpired: Boolean): TWebSession; -var lSessionList: TObjectDictionary; +class function TMVCEngine.GetCurrentSession( + const ASessionId: string; + const ARaiseExceptionIfExpired: Boolean): TMVCWebSession; +var + lSessionList: TObjectDictionary; begin Result := nil; lSessionList := GlobalSessionList; @@ -2677,7 +2687,7 @@ begin end; end; -function TMVCEngine.GetSessionBySessionId(const ASessionId: string): TWebSession; +function TMVCEngine.GetSessionBySessionId(const ASessionId: string): TMVCWebSession; begin Result := TMVCEngine.GetCurrentSession(ASessionId, False); if Assigned(Result) then @@ -2866,10 +2876,14 @@ begin end; class function TMVCEngine.SendSessionCookie(const AContext: TWebContext): string; -var SId: string; +var + SId: string; begin - SId := StringReplace(StringReplace(StringReplace('DT' + GUIDToString(TGUID.NewGuid), '}', '', []), - '{', '', []), '-', '', [rfReplaceAll]); + SId := StringReplace(StringReplace(StringReplace( + 'DT' + GUIDToString(TGUID.NewGuid) + GUIDToString(TGUID.NewGuid), + '}', '', [rfReplaceAll]), + '{', '', [rfReplaceAll]), + '-', '', [rfReplaceAll]); Result := SendSessionCookie(AContext, SId); end; @@ -3126,7 +3140,7 @@ begin Result := Context.Request.GetHeader('If-Match'); end; -function TMVCController.GetSession: TWebSession; +function TMVCController.GetSession: TMVCWebSession; begin Result := GetContext.Session; end; @@ -3372,8 +3386,9 @@ begin GetContext.Response.RawWebResponse.FreeContentStream := True; end; -function TMVCRenderer.Serializer(const AContentType: string; -const ARaiseExceptionIfNotExists: Boolean): IMVCSerializer; +function TMVCRenderer.Serializer( + const AContentType: string; + const ARaiseExceptionIfNotExists: Boolean): IMVCSerializer; var lContentMediaType: string; lContentCharSet: string; begin @@ -3530,6 +3545,7 @@ procedure TMVCRenderer.Render( const AObject: IInterface; const ASerializationAction: TMVCSerializationAction); begin + {TODO -oDanieleT -cGeneral : Handle StatusCode} Render(TObject(AObject), False, ASerializationAction); end; @@ -3759,8 +3775,8 @@ begin begin try GetContext.Response.StatusCode := AResponse.StatusCode; - GetContext.Response.ReasonString := HTTP_STATUS.ReasonStringFor(AResponse.StatusCode); - Render(AResponse, False, stProperties); + GetContext.Response.ReasonString := AResponse.ReasonString; + Render(AResponse, False, stProperties, nil, AResponse.GetIgnoredList); finally if AOwns then AResponse.Free; @@ -3810,6 +3826,7 @@ constructor TMVCResponse.Create; begin inherited Create; fDataObject := nil; + fMessage := ''; end; constructor TMVCErrorResponse.Create; @@ -3818,12 +3835,32 @@ begin FItems := TObjectList.Create(True); end; -constructor TMVCResponse.Create(AStatusCode: Integer; AReasonString, AMessage: string); +constructor TMVCResponse.Create(AStatusCode: Integer; AMessage: string; AReasonString: string); begin Create; - StatusCode := AStatusCode; - ReasonString := AReasonString; - message := AMessage; + fStatusCode := AStatusCode; + fMessage := AMessage; + fReasonString := AReasonString; + fIgnoredList := ['Data', 'ObjectDictionary']; +end; + +constructor TMVCResponse.Create(AStatusCode: Integer; AData: TObject; AReasonString: string); +begin + Create; + fStatusCode := AStatusCode; + fDataObject := AData; + fReasonString := AReasonString; + fIgnoredList := ['Message', 'ObjectDictionary']; +end; + +constructor TMVCResponse.Create(AStatusCode: Integer; + AObjectDictionary: IMVCObjectDictionary; AReasonString: string); +begin + Create; + fStatusCode := AStatusCode; + fObjectDictionary := AObjectDictionary; + fReasonString := AReasonString; + fIgnoredList := ['Message', 'Data']; end; destructor TMVCResponse.Destroy; @@ -3832,6 +3869,64 @@ begin inherited; end; +function TMVCResponse.GetData: TObject; +begin + Result := fDataObject; +end; + +function TMVCResponse.GetIgnoredList: TMVCIgnoredList; +begin + Result := fIgnoredList; +end; + +function TMVCResponse.GetMessage: string; +begin + Result := fMessage; +end; + +function TMVCResponse.GetObjectDictionary: IMVCObjectDictionary; +begin + Result := fObjectDictionary; +end; + +function TMVCResponse.GetReasonString: string; +begin + if fReasonString.IsEmpty then + Result := HTTP_STATUS.ReasonStringFor(fStatusCode) + else + Result := fReasonString; +end; + +function TMVCResponse.GetStatusCode: Integer; +begin + Result := fStatusCode; +end; + +procedure TMVCResponse.SetData(const Value: TObject); +begin + fDataObject := Value; +end; + +procedure TMVCResponse.SetMessage(const Value: string); +begin + fMessage := Value; +end; + +procedure TMVCResponse.SetObjectDictionary(const Value: IMVCObjectDictionary); +begin + fObjectDictionary := Value; +end; + +procedure TMVCResponse.SetReasonString(const Value: string); +begin + fReasonString := Value; +end; + +procedure TMVCResponse.SetStatusCode(const Value: Integer); +begin + fStatusCode := Value; +end; + destructor TMVCErrorResponse.Destroy; begin FItems.Free; @@ -4054,6 +4149,24 @@ procedure TCustomControllerFilter.SetNext(NextFilter: IControllerFilter); begin fNext := NextFilter; end; +//======= +// std responses +function MVCResponse(AStatusCode: Integer; AMessage: string; AReasonString: string): IMVCResponse; overload; +begin + Result := TMVCResponse.Create(AStatusCode, AMessage, AReasonString); +end; + +function MVCResponse(AStatusCode: Integer; AData: TObject; AReasonString: string): IMVCResponse; overload; +begin + Result := TMVCResponse.Create(AStatusCode, AData, AReasonString); +end; + +function MVCResponse(AStatusCode: Integer; AObjectDictionary: IMVCObjectDictionary; AReasonString: string): IMVCResponse; overload; +begin + Result := TMVCResponse.Create(AStatusCode, AObjectDictionary, AReasonString); +end; + +// end - std responses initialization diff --git a/unittests/general/Several/ActiveRecordTestsU.pas b/unittests/general/Several/ActiveRecordTestsU.pas index d72553e7..4a2aecc1 100644 --- a/unittests/general/Several/ActiveRecordTestsU.pas +++ b/unittests/general/Several/ActiveRecordTestsU.pas @@ -70,12 +70,20 @@ type [Test] procedure TestSelectWithExceptions; [Test] + procedure TestNamedQuerySQL; + [Test] + procedure TestNamedQuerySQLByBackEnd; + [Test] procedure TestStore; [Test] procedure TestLifeCycle; [Test] procedure TestRQL; [Test] + procedure TestNamedQueryRQL; + [Test] + procedure TestNamedQueryRQLWithExceptions; + [Test] procedure TestRQLWithMVCNameAsAttribute; [Test] procedure TestRQLWithBoolean; @@ -1170,6 +1178,68 @@ begin Assert.AreEqual(Trunc(20 * 30), TMVCActiveRecord.Count(TCustomerWithLF)); end; +procedure TTestActiveRecordBase.TestNamedQueryRQL; +var + lCustomers: TObjectList; +begin + Assert.AreEqual(Int64(0), TMVCActiveRecord.Count(TCustomer)); + LoadData; + lCustomers := TMVCActiveRecord.SelectRQLByNamedQuery('CityRomeOrLondon', [], MAXINT); + try + Assert.AreEqual(240, lCustomers.Count); + for var lCustomer in lCustomers do + begin + Assert.IsMatch('^(Rome|London)$', lCustomer.City); + end; + finally + lCustomers.Free; + end; + TMVCActiveRecord.DeleteRQLByNamedQuery('CityRomeOrLondon', []); + Assert.AreEqual(Int64(0), TMVCActiveRecord.CountRQLByNamedQuery('CityRomeOrLondon', [])); +end; + +procedure TTestActiveRecordBase.TestNamedQueryRQLWithExceptions; +begin + Assert.WillRaiseWithMessage( + procedure + begin + TMVCActiveRecord.SelectRQLByNamedQuery('WrongQueryName', [1,2,3], MAXINT); + end, nil, 'NamedRQLQuery not found: WrongQueryName'); + + Assert.WillRaiseWithMessage( + procedure + begin + TMVCActiveRecord.DeleteRQLByNamedQuery('WrongQueryName', []); + end, nil, 'NamedRQLQuery not found: WrongQueryName'); +end; + +procedure TTestActiveRecordBase.TestNamedQuerySQL; +begin + Assert.AreEqual(Int64(0), TMVCActiveRecord.Count(TCustomer)); + LoadData; + var lCustomers := TMVCActiveRecord.SelectByNamedQuery('ByTwoCities', ['Rome', 'London'], [ftString, ftString]); + try + Assert.AreEqual(240, lCustomers.Count); + for var lCustomer in lCustomers do + begin + Assert.IsMatch('^(Rome|London)$', lCustomer.City); + end; + finally + lCustomers.Free; + end; +end; + +procedure TTestActiveRecordBase.TestNamedQuerySQLByBackEnd; +begin + var lList := TMVCActiveRecord.SelectByNamedQuery('get_backend_name', [],[]); + try + Assert.AreEqual(1, lList.Count); + Assert.AreEqual(lList.First.GetBackEnd, lList.First.BackEndName); + finally + lList.Free; + end; +end; + procedure TTestActiveRecordBase.TestNullables; var lTest: TNullablesTest; diff --git a/unittests/general/Several/BOs.pas b/unittests/general/Several/BOs.pas index 10aceae4..88ce22bb 100644 --- a/unittests/general/Several/BOs.pas +++ b/unittests/general/Several/BOs.pas @@ -101,6 +101,8 @@ const type [MVCTable('customers')] + [MVCNamedRQLQuery('CityRomeOrLondon','or(eq(City, "Rome"),eq(City, "London"))')] + [MVCNamedSQLQuery('ByTwoCities','select * from customers where city = ? or city = ?')] TCustomer = class(TMVCActiveRecord) private [MVCTableField('id', [foPrimaryKey, foAutoGenerated])] @@ -661,6 +663,19 @@ type destructor Destroy; override; end; + [MVCEntityActions([eaRetrieve])] + [MVCNamedSQLQuery('get_backend_name', 'select ''firebird'' backendname from rdb$database', TMVCActiveRecordBackEnd.FirebirdSQL)] + [MVCNamedSQLQuery('get_backend_name', 'select ''postgresql'' backendname', TMVCActiveRecordBackEnd.PostgreSQL)] + [MVCNamedSQLQuery('get_backend_name', 'select ''sqlite'' backendname', TMVCActiveRecordBackEnd.SQLite)] + TDummyEntity = class(TMVCActiveRecord) + private + [MVCTableField('backendname')] + FBackEndName: String; + procedure SetBackEndName(const Value: String); + public + property BackEndName: String read FBackEndName write SetBackEndName; + end; + function GetMyObject: TMyObject; function GetMyObjectWithTValue: TMyObjectWithTValue; function GetMyObjectWithStream: TMyStreamObject; @@ -1432,6 +1447,13 @@ begin end; +{ TDummyEntity } + +procedure TDummyEntity.SetBackEndName(const Value: String); +begin + FBackEndName := Value; +end; + initialization ActiveRecordMappingRegistry.AddEntity('customers', TCustomer); diff --git a/unittests/general/Several/FrameworkTestsU.pas b/unittests/general/Several/FrameworkTestsU.pas index 7d2d3629..e96c9a44 100644 --- a/unittests/general/Several/FrameworkTestsU.pas +++ b/unittests/general/Several/FrameworkTestsU.pas @@ -38,43 +38,6 @@ uses type - [TestFixture] - TTestMappers = class(TObject) - protected - [Test] - procedure SameFishesDataSet(ds, ds2: TDataSet); - - public - // procedure TestObjectToJSONObject; - // procedure TestObjectListToJSONArray; - // procedure TestObjectToJSONObject_Generics; - // procedure TestWrappedListToJSONArray; - // procedure TestJSONObjectToObjectAndBack; - // procedure TestLoadJSONObjectToObjectAndBack; - // procedure TestSerializeUsingProperties; - // procedure TestSerializeUsingFields; - // procedure TestSerializeUsingFieldsComplexObject; - // procedure TestSerializeUsingFieldsComplexObject2; - // procedure TestSerializeUsingFieldsWithNotExixtentPropetyInJSONObject; - // procedure TestComplexObjectToJSONObjectAndBack; - // procedure TestComplexObjectToJSONObjectAndBackWithNilReference; - // procedure TestDataSetToJSONObject; - // procedure TestDataSetToJSONObjectWithNulls; - // procedure TestDataSetToJSONObjectFieldPolicyLowerCase; - // procedure TestDataSetToJSONObjectFieldPolicyUpperCase; - // procedure TestDataSetToJSONObjectFieldPolicyAsIsCase; - // procedure TestDataSetToJSONArray; - // procedure TestObjectToJSONObjectAndBackWithStringStreamUTF16; - // procedure TestObjectToJSONObjectAndBackWithStringStreamUTF8; - // procedure TestObjectToJSONObjectAndBackWithStream; - // procedure TestJSONArrayToObjectListNoGenerics; - // procedure TestJSONArrayToObjectListNoGenericsWrappedList; - // procedure TestCheckMapperSerializeAsStringIsEmptyStrIfObjIsNil; - // procedure TestJSONObjectToObjectWithNullInJSONString; - // procedure TestJSONObjectStringToObject; - // procedure TestJSONObjectStringToObjectWithWrongJSON; - end; - [TestFixture] TTestRouting = class(TObject) private @@ -381,18 +344,6 @@ begin end; end; -procedure TTestMappers.SameFishesDataSet(ds, ds2: TDataSet); -begin - Assert.areEqual(ds.FieldByName('Species No').AsInteger, ds2.FieldByName('Species No').AsInteger); - Assert.areEqual(ds.FieldByName('Category').AsString, ds2.FieldByName('Category').AsString); - Assert.areEqual(ds.FieldByName('Common_Name').AsString, ds2.FieldByName('Common_Name').AsString); - Assert.areEqual(ds.FieldByName('Species Name').AsString, ds2.FieldByName('Species Name').AsString); - Assert.areEqual(ds.FieldByName('Length (cm)').AsString, ds2.FieldByName('Length (cm)').AsString); - Assert.areEqual(ds.FieldByName('Length_In').AsInteger, ds2.FieldByName('Length_In').AsInteger); - Assert.areEqual(ds.FieldByName('Notes').AsString, ds2.FieldByName('Notes').AsString); - Assert.areEqual(ds.FieldByName('Graphic').AsString, ds2.FieldByName('Graphic').AsString); -end; - procedure TTestRouting.SetUp; begin FControllers := TObjectList.Create; diff --git a/unittests/general/Several/LiveServerTestU.pas b/unittests/general/Several/LiveServerTestU.pas index 1169cf19..773b63d2 100644 --- a/unittests/general/Several/LiveServerTestU.pas +++ b/unittests/general/Several/LiveServerTestU.pas @@ -298,6 +298,22 @@ type [Test] procedure TestViewDataViewDataSet; + // test functional actions + [Test] + procedure TestFuncActionGetSingleRecord; + + [Test] + procedure TestFuncActionGetMultipleRecords; + + [Test] + procedure TestFuncActionGetDatasetSingle; + + [Test] + procedure TestFuncActionGetDatasetMultiple; + + [Test] + procedure TestFuncActionGetComplexObject; + // test issues [Test] [Category('renders')] @@ -1068,12 +1084,11 @@ var begin res := RESTClient.Get('/exception/emvcexception1'); Assert.areEqual(HTTP_STATUS.InternalServerError, res.StatusCode); + Assert.areEqual('Internal Server Error', res.StatusText); lJSON := StrToJSONObject(res.Content); try 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('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 @@ -1089,12 +1104,11 @@ var begin res := RESTClient.Get('/exception/emvcexception2'); Assert.areEqual(HTTP_STATUS.BadRequest, res.StatusCode); + Assert.areEqual('Bad Request', res.StatusText); lJSON := StrToJSONObject(res.Content); try 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('Bad Request', lJSON.S['reasonstring'], lJSON.ToJSON()); Assert.areEqual(0, lJSON.A['items'].Count, lJSON.ToJSON()); Assert.isTrue(lJSON.IsNull('data'), lJSON.ToJSON()); finally @@ -1109,12 +1123,11 @@ var begin res := RESTClient.Get('/exception/emvcexception3'); Assert.areEqual(HTTP_STATUS.Created, res.StatusCode); + Assert.areEqual('Created', res.StatusText); lJSON := StrToJSONObject(res.Content); try 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('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()); @@ -1130,13 +1143,12 @@ var begin res := RESTClient.Get('/exception/emvcexception4'); Assert.areEqual(HTTP_STATUS.Created, res.StatusCode); + Assert.areEqual('Created', res.StatusText); lJSON := StrToJSONObject(res.Content); try Assert.areEqual('message', lJSON.S['message'], lJSON.ToJSON()); 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('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()); @@ -1443,6 +1455,118 @@ begin Assert.areEqual('This is a TEXT file', lRes.Content, '/static/folder1.html'); end; +procedure TServerTest.TestFuncActionGetComplexObject; +var + c1: IMVCRESTClient; + lRes: IMVCRESTResponse; +begin + c1 := TMVCRESTClient.New.BaseURL(TEST_SERVER_ADDRESS, 9999); + lRes := c1.Get('/api/v1/actionresult/complex'); + Assert.areEqual(200, lRes.StatusCode); + var lJSON := lRes.ToJSONObject; + try + Assert.AreEqual(3, lJSON.Count); + Assert.IsTrue(lJSON.Types['value'] = jdtInt); + Assert.IsTrue(lJSON.Types['person'] = jdtObject); + Assert.IsTrue(lJSON.Types['people'] = jdtArray); + Assert.AreEqual(6, lJSON.O['person'].Count); + Assert.AreEqual(3, lJSON.A['people'].Count); + Assert.AreEqual(6, lJSON.A['people'][0].ObjectValue.Count); + Assert.AreEqual(6, lJSON.A['people'][1].ObjectValue.Count); + Assert.AreEqual(6, lJSON.A['people'][2].ObjectValue.Count); + finally + lJSON.Free; + end; +end; + +procedure TServerTest.TestFuncActionGetDatasetMultiple; +var + c1: IMVCRESTClient; + lRes: IMVCRESTResponse; +begin + c1 := TMVCRESTClient.New.BaseURL(TEST_SERVER_ADDRESS, 9999); + lRes := c1.Get('/api/v1/actionresult/dataset/multiple'); + Assert.areEqual(200, lRes.StatusCode); + var lJSON := lRes.ToJSONObject; + try + Assert.AreEqual(2, lJSON.Count); + Assert.IsTrue(lJSON.Contains('ds1')); + Assert.IsTrue(lJSON.Contains('ds2')); + Assert.AreEqual(15, lJSON.A['ds1'].Count); + Assert.AreEqual(15, lJSON.A['ds2'].Count); + finally + lJSON.Free; + end; +end; + +procedure TServerTest.TestFuncActionGetDatasetSingle; +var + c1: IMVCRESTClient; + lRes: IMVCRESTResponse; +begin + c1 := TMVCRESTClient.New.BaseURL(TEST_SERVER_ADDRESS, 9999); + lRes := c1.Get('/api/v1/actionresult/dataset/single'); + Assert.areEqual(200, lRes.StatusCode); + var lJSON := lRes.ToJSONArray; + try + Assert.AreEqual(15, lJSON.Count); + for var I := 0 to lJSON.Count - 1 do + begin + Assert.IsTrue(lJSON[I].Typ = jdtObject); + Assert.AreEqual(12, lJSON[I].ObjectValue.Count); + end; + finally + lJSON.Free; + end; +end; + +procedure TServerTest.TestFuncActionGetMultipleRecords; +var + c1: IMVCRESTClient; + lRes: IMVCRESTResponse; +begin + c1 := TMVCRESTClient.New.BaseURL(TEST_SERVER_ADDRESS, 9999); + lRes := c1.Get('/api/v1/actionresult/records/multiple'); + Assert.areEqual(200, lRes.StatusCode); + var lJSON := lRes.ToJSONArray; + try + Assert.AreEqual(3, lJSON.Count); + + Assert.AreEqual('Daniele', lJSON[0].S['firstName']); + Assert.AreEqual('Teti', lJSON[0].S['lastName']); + Assert.AreEqual(20, lJSON[0].I['age']); + + Assert.AreEqual('Daniele', lJSON[1].S['firstName']); + Assert.AreEqual('Teti', lJSON[1].S['lastName']); + Assert.AreEqual(30, lJSON[1].I['age']); + + Assert.AreEqual('Daniele', lJSON[2].S['firstName']); + Assert.AreEqual('Teti', lJSON[2].S['lastName']); + Assert.AreEqual(40, lJSON[2].I['age']); + finally + lJSON.Free; + end; +end; + +procedure TServerTest.TestFuncActionGetSingleRecord; +var + c1: IMVCRESTClient; + lRes: IMVCRESTResponse; +begin + c1 := TMVCRESTClient.New.BaseURL(TEST_SERVER_ADDRESS, 9999); + lRes := c1.Get('/api/v1/actionresult/records/single'); + Assert.areEqual(200, lRes.StatusCode); + var lJSON := lRes.ToJSONObject; + try + Assert.AreEqual(3, lJSON.Count); + Assert.AreEqual('Daniele', lJSON.S['firstName']); + Assert.AreEqual('Teti', lJSON.S['lastName']); + Assert.AreEqual(99, lJSON.I['age']); + finally + lJSON.Free; + end; +end; + procedure TServerTest.TestGetImagePng; var c1: IMVCRESTClient; diff --git a/unittests/general/TestServer/TestServerControllerU.pas b/unittests/general/TestServer/TestServerControllerU.pas index b4b8812b..fd7195dd 100644 --- a/unittests/general/TestServer/TestServerControllerU.pas +++ b/unittests/general/TestServer/TestServerControllerU.pas @@ -34,7 +34,8 @@ uses FireDAC.Comp.Client, System.Generics.Collections, Data.DB, - BusinessObjectsU; + BusinessObjectsU, MVCFramework.Serializer.Commons, System.Classes, + System.UITypes; type @@ -46,9 +47,10 @@ type fDataSet: TFDMemTable; protected procedure MVCControllerAfterCreate; override; - function GetDataSet: TDataSet; procedure MVCControllerBeforeDestroy; override; public + class function GetDataSet: TDataSet; + [MVCPath('/req/with/params/($par1)/($par2)/($par3)')] [MVCHTTPMethod([httpGET, httpDELETE])] procedure ReqWithParams; @@ -412,6 +414,117 @@ type procedure Action1or2; end; + +// action result types + [MVCNameCase(ncLowerCase)] + TSum = class + private + fValue: Integer; + public + property Value: Integer read fValue write fValue; + end; + + [MVCNameCase(ncLowerCase)] + TComplexObject = class + private + fValue: Integer; + FPeople: TPeople; + FPerson: TPerson; + procedure SetPeople(const Value: TPeople); + procedure SetPerson(const Value: TPerson); + public + destructor Destroy; override; + property Value: Integer read fValue write fValue; + property Person: TPerson read FPerson write SetPerson; + property People: TPeople read FPeople write SetPeople; + end; + + [MVCNameCase(ncCamelCase)] + TPersonRec = record + FirstName, LastName: String; + Age: Integer; + class function Create: TPersonRec; static; + end; +// action result types - end + + [MVCPath('/api/v1/actionresult')] + TTestActionResultController = class(TMVCController) + public + { actions returning records } + [MVCPath('/sums/($a)/($b)')] + [MVCHTTPMethod([httpGET])] + function GetObject(a,b: Integer): TSum; + + [MVCPath('/records/single')] + function GetSingleRecord: TPersonRec; + + [MVCPath('/records/multiple')] + function GetMultipleRecords: TArray; + + [MVCPath('/complex')] + [MVCHTTPMethod([httpGET])] + function GetComplexObject: TComplexObject; + + [MVCPath('/people')] + [MVCHTTPMethod([httpGET])] + function GetPeople: TObjectList; + + [MVCPath('/people/($id)')] + [MVCHTTPMethod([httpGET])] + function GetPerson(id: Integer): IPerson; + + [MVCPath('/photo')] + [MVCHTTPMethod([httpGET])] + function GetPhoto: TStream; + + [MVCPath('/string')] + [MVCHTTPMethod([httpGET])] + function GetString: String; + + [MVCPath('/enum')] + [MVCHTTPMethod([httpGET])] + function GetEnum: TFontStyle; + + [MVCPath('/bool')] + [MVCHTTPMethod([httpGET])] + function GetBool: Boolean; + + [MVCPath('/float')] + [MVCHTTPMethod([httpGET])] + function GetFloat: Double; + + [MVCPath('/strdict')] + [MVCHTTPMethod([httpGET])] + function GetStrDict: TMVCStringDictionary; + + [MVCPath('/TSimpleRecord')] + [MVCHTTPMethod([httpGET])] + function GetTSimpleRecord: TSimpleRecord; + + [MVCPath('/ArrayOf/TSimpleRecord')] + [MVCHTTPMethod([httpGET])] + function GetArrayOfTSimpleRecord: TArray; + + [MVCPath('/TComplexRecord')] + [MVCHTTPMethod([httpGET])] + function GetTComplexRecord: TComplexRecord; + + [MVCPath('/ArrayOf/TComplexRecord')] + [MVCHTTPMethod([httpGET])] + function GetArrayOfTComplexRecord: TComplexRecordArray; + + [MVCPath('/dataset/single')] + [MVCHTTPMethod([httpGET])] + function GetDataSetSingle: TDataSet; + + [MVCPath('/dataset/multiple')] + [MVCHTTPMethod([httpGET])] + function GetDataSetMultiple: IMVCObjectDictionary; + + end; + + + implementation uses @@ -419,11 +532,9 @@ uses System.JSON, Web.HTTPApp, Generics.Collections, - MVCFramework.Serializer.Commons, MVCFramework.Serializer.Defaults, MVCFramework.DuckTyping, - System.IOUtils, - System.Classes, MVCFramework.Tests.Serializer.Entities; + System.IOUtils, MVCFramework.Tests.Serializer.Entities, System.DateUtils; { TTestServerController } @@ -512,7 +623,7 @@ begin end; -function TTestServerController.GetDataSet: TDataSet; +class function TTestServerController.GetDataSet: TDataSet; begin Result := TFDMemTable.Create(nil); TFDMemTable(Result).LoadFromFile(TPath.Combine(AppPath, 'customers.json')); @@ -1226,4 +1337,150 @@ begin Render(HTTP_STATUS.OK); end; +{ TTestActionResultController } + +function TTestActionResultController.GetArrayOfTComplexRecord: TComplexRecordArray; +begin + SetLength(Result,3); + Result[0] := TComplexRecord.Create; + Result[1] := TComplexRecord.Create; + Result[2] := TComplexRecord.Create; + + Result[0].StringProperty := 'item 0'; + Result[1].StringProperty := 'item 1'; + Result[2].StringProperty := 'item 2'; +end; + +function TTestActionResultController.GetArrayOfTSimpleRecord: TArray; +begin + SetLength(Result, 3); + Result[0] := TSimpleRecord.Create; + Result[1] := TSimpleRecord.Create; + Result[2] := TSimpleRecord.Create; +end; + +function TTestActionResultController.GetBool: Boolean; +begin + Result := True; +end; + +function TTestActionResultController.GetComplexObject: TComplexObject; +begin + Result := TComplexObject.Create; + Result.Value := 1234; + Result.Person := TPerson.GetNew('Danielem', 'Teti', EncodeDate(1920,12,23), True); + Result.People := TPerson.GetList(); +end; + +function TTestActionResultController.GetDataSetMultiple: IMVCObjectDictionary; +begin + Result := + ObjectDict() + .Add('ds1', TTestServerController.GetDataSet) + .Add('ds2', TTestServerController.GetDataSet); +end; + +function TTestActionResultController.GetDataSetSingle: TDataSet; +begin + Result := TTestServerController.GetDataSet; +end; + +function TTestActionResultController.GetEnum: TFontStyle; +begin + Result := TFontStyle.fsBold; +end; + +function TTestActionResultController.GetFloat: Double; +begin + Result := 3.1415; +end; + +function TTestActionResultController.GetMultipleRecords: TArray; +begin + SetLength(Result, 3); + Result[0] := TPersonRec.Create; + Result[1] := TPersonRec.Create; + Result[2] := TPersonRec.Create; + Result[0].Age := 20; + Result[1].Age := 30; + Result[2].Age := 40; +end; + +function TTestActionResultController.GetPeople: TObjectList; +begin + Result := TPerson.GetList(); +end; + +function TTestActionResultController.GetPerson(id: Integer): IPerson; +begin + Result := TInterfacedPerson.Create('Daniele Teti', 20, 2010); +end; + +function TTestActionResultController.GetPhoto: TStream; +begin + Context.Response.ContentType := TMVCMediaType.IMAGE_X_PNG; + Result := TFileStream.Create('sample.png', fmOpenRead or fmShareDenyNone); +end; + +function TTestActionResultController.GetSingleRecord: TPersonRec; +begin + Result := TPersonRec.Create; +end; + +function TTestActionResultController.GetStrDict: TMVCStringDictionary; +begin + Result := StrDict.Add('first_name','Daniele').Add('last_name','Teti'); +end; + +function TTestActionResultController.GetString: String; +begin + Result := 'Hello World'; +end; + +function TTestActionResultController.GetTComplexRecord: TComplexRecord; +begin + Result := TComplexRecord.Create; +end; + +function TTestActionResultController.GetTSimpleRecord: TSimpleRecord; +begin + Result := TSimpleRecord.Create; +end; + +function TTestActionResultController.GetObject(a, b: Integer): TSum; +begin + StatusCode := 201; + Context.Response.SetCustomHeader('X-CUSTOM-HEADER','CARBONARA'); + Result := TSum.Create; + Result.Value := a + b; +end; + +{ TComplexObject } + +destructor TComplexObject.Destroy; +begin + FPerson.Free; + FPeople.Free; + inherited; +end; + +procedure TComplexObject.SetPeople(const Value: TPeople); +begin + FPeople := Value; +end; + +procedure TComplexObject.SetPerson(const Value: TPerson); +begin + FPerson := Value; +end; + +{ TPersonRec } + +class function TPersonRec.Create: TPersonRec; +begin + Result.FirstName := 'Daniele'; + Result.LastName := 'Teti'; + Result.Age := 99; +end; + end. diff --git a/unittests/general/TestServer/WebModuleUnit.pas b/unittests/general/TestServer/WebModuleUnit.pas index 4c2f72a8..a746a3a4 100644 --- a/unittests/general/TestServer/WebModuleUnit.pas +++ b/unittests/general/TestServer/WebModuleUnit.pas @@ -93,6 +93,7 @@ begin .AddController(TTestServerControllerActionFilters) .AddController(TTestPrivateServerControllerCustomAuth) .AddController(TTestMultiPathController) + .AddController(TTestActionResultController) .AddController(TTestJSONRPCController, '/jsonrpc') .AddController(TTestJSONRPCControllerWithGet, '/jsonrpcwithget') .AddController(TMVCActiveRecordController, diff --git a/unittests/general/UnitTestReports/dmvcframework_nunit_win32.xml b/unittests/general/UnitTestReports/dmvcframework_nunit_win32.xml index dcb80048..32086969 100644 --- a/unittests/general/UnitTestReports/dmvcframework_nunit_win32.xml +++ b/unittests/general/UnitTestReports/dmvcframework_nunit_win32.xml @@ -1,407 +1,232 @@  - + - + - + - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - + + + - + - - - - - - - - - - + - - + + @@ -409,10 +234,10 @@ - + - - + + @@ -422,19 +247,19 @@ - - - + + + - - + + - + @@ -493,127 +318,282 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -623,387 +603,438 @@ + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - + - + + + + + + + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/unittests/general/UnitTestReports/dmvcframework_nunit_win64.xml b/unittests/general/UnitTestReports/dmvcframework_nunit_win64.xml index df651f92..4575f70e 100644 --- a/unittests/general/UnitTestReports/dmvcframework_nunit_win64.xml +++ b/unittests/general/UnitTestReports/dmvcframework_nunit_win64.xml @@ -1,192 +1,358 @@  - + - + - + - - - - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -199,26 +365,332 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -230,15 +702,211 @@ - + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + - - + + @@ -248,8 +916,8 @@ - - + + @@ -259,17 +927,17 @@ - - + + - + - + @@ -330,212 +998,15 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - + + + @@ -555,453 +1026,17 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -