+ Improved TMVCActiveRecord Interbase support

This commit is contained in:
Daniele Teti 2022-01-26 23:00:32 +01:00
parent 7a2b6458fd
commit 07bd70c5ed
20 changed files with 343 additions and 547 deletions

View File

@ -67,7 +67,12 @@ type
[MVCTable('articles')]
TArticleWithWriteOnlyFields = class(TCustomEntity)
private
[MVCTableField('ID', [foPrimaryKey, foAutoGenerated, foReadOnly])]
{$IFNDEF USE_SEQUENCES}
[MVCTableField('id', [foPrimaryKey, foAutoGenerated, foReadOnly])]
{$ELSE}
[MVCTableField('id', [foPrimaryKey, foAutoGenerated],
'SEQ_ARTICLES_ID' { required for interbase } )]
{$ENDIF}
fID: NullableInt32;
[MVCTableField('description', [foWriteOnly])]
fDescrizione: string;
@ -137,7 +142,12 @@ type
[MVCTable('customers')]
TPartitionedCustomer = class(TCustomEntity)
private
{$IFNDEF USE_SEQUENCES}
[MVCTableField('id', [foPrimaryKey, foAutoGenerated])]
{$ELSE}
[MVCTableField('id', [foPrimaryKey, foAutoGenerated],
'SEQ_CUSTOMERS_ID' { required for interbase } )]
{$ENDIF}
fID: NullableInt64;
[MVCTableField('code')]
fCode: NullableString;

View File

@ -1,7 +1,7 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{1576AA4D-0623-40AC-97D3-AA4BB4381A0A}</ProjectGuid>
<ProjectVersion>19.2</ProjectVersion>
<ProjectVersion>19.3</ProjectVersion>
<FrameworkType>VCL</FrameworkType>
<MainSource>articles_crud_with_injectable_parameters.dpr</MainSource>
<Base>True</Base>
@ -106,61 +106,6 @@
<DCCReference Include="Commons.pas"/>
<DCCReference Include="..\..\sources\MVCFramework.ActiveRecord.pas"/>
<DCCReference Include="..\..\sources\MVCFramework.Serializer.JsonDataObjects.pas"/>
<None Include="ModelSupport_ordersmanager\default.txvpck"/>
<None Include="ModelSupport_ordersmanager\Services\default.txvpck"/>
<None Include="ModelSupport_ordersmanager\ordersmanager\default.txvpck"/>
<None Include="ModelSupport_ordersmanager\Services\default.txaPackage"/>
<None Include="ModelSupport_ordersmanager\BusinessObjects\default.txaPackage"/>
<None Include="ModelSupport_ordersmanager\BusinessObjects\default.txvpck"/>
<None Include="ModelSupport_ordersmanager\Controllers\Articoli\default.txaPackage"/>
<None Include="ModelSupport_articles_crud\default.txvpck"/>
<None Include="ModelSupport_articles_crud\Commons\default.txvpck"/>
<None Include="ModelSupport_articles_crud\MainDM\default.txvpck"/>
<None Include="ModelSupport_articles_crud\BusinessObjects\default.txvpck"/>
<None Include="ModelSupport_articles_crud\Services\default.txvpck"/>
<None Include="ModelSupport_articles_crud\articles_crud\default.txvpck"/>
<None Include="ModelSupport_articles_crud\WebModuleUnit1\default.txvpck"/>
<None Include="ModelSupport_articles_crud\Controllers\default.txvpck"/>
<None Include="ModelSupport_articles_crud\Controllers\Articoli\default.txvpck"/>
<None Include="ModelSupport_articles_crud\Controllers\Base\default.txvpck"/>
<None Include="ModelSupport_articles_crud\MainDM\default.txaPackage"/>
<None Include="ModelSupport_articles_crud\Controllers\Base\default.txaPackage"/>
<None Include="ModelSupport_articles_crud\Services\default.txaPackage"/>
<None Include="ModelSupport_articles_crud\Controllers\default.txaPackage"/>
<None Include="ModelSupport_articles_crud\WebModuleUnit1\default.txaPackage"/>
<None Include="ModelSupport_articles_crud\articles_crud\default.txaPackage"/>
<None Include="ModelSupport_articles_crud\Commons\default.txaPackage"/>
<None Include="ModelSupport_articles_crud\BusinessObjects\default.txaPackage"/>
<None Include="ModelSupport_articles_crud\Controllers\Articoli\default.txaPackage"/>
<None Include="ModelSupport_articles_crud\MVCFramework\default.txaPackage"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\default.txaPackage"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\default.txvpck"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\Services\default.txvpck"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\articles_crud_with_injectable_parameters\default.txvpck"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\BusinessObjects\default.txvpck"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\Controllers\default.txvpck"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\Controllers\Articles\default.txvpck"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\Controllers\Base\default.txvpck"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\MainDM\default.txvpck"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\MVCFramework\default.txvpck"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\MVCFramework\ActiveRecord\default.txvpck"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\Commons\default.txvpck"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\WebModuleUnit1\default.txvpck"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\MVCFramework\default.txaPackage"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\articles_crud_with_injectable_parameters\default.txaPackage"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\WebModuleUnit1\default.txaPackage"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\Controllers\Articles\default.txaPackage"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\MVCFramework\ActiveRecord\default.txaPackage"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\BusinessObjects\default.txaPackage"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\Controllers\Base\default.txaPackage"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\Services\default.txaPackage"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\Commons\default.txaPackage"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\Controllers\default.txaPackage"/>
<None Include="ModelSupport_articles_crud_with_injectable_parameters\MainDM\default.txaPackage"/>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
@ -168,6 +113,10 @@
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
@ -185,318 +134,12 @@
</Excluded_Packages>
</Delphi.Personality>
<Deployment Version="3">
<DeployFile LocalName="ModelSupport_articles_crud\MainDM\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\MVCFramework\ActiveRecord\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="bin\articles_crud_with_injectable_parameters.exe" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>articles_crud_with_injectable_parameters.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\Controllers\Base\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud\Services\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud\Controllers\Articoli\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\Commons\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud\WebModuleUnit1\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud\BusinessObjects\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud\Controllers\Articoli\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\Controllers\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud\Services\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\Services\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud\articles_crud\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\MainDM\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\BusinessObjects\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\Controllers\Base\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud\Commons\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\WebModuleUnit1\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_ordersmanager\Services\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\articles_crud_with_injectable_parameters\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud\Controllers\Base\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud\WebModuleUnit1\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud\Controllers\Base\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\articles_crud_with_injectable_parameters\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_ordersmanager\BusinessObjects\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_ordersmanager\BusinessObjects\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud\MainDM\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_ordersmanager\Services\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\WebModuleUnit1\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud\Controllers\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\MainDM\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_ordersmanager\ordersmanager\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\Controllers\Articles\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud\BusinessObjects\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud\articles_crud\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\MVCFramework\ActiveRecord\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\Services\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud\Commons\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\Controllers\Articles\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\BusinessObjects\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud\Controllers\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud\MVCFramework\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\MVCFramework\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_ordersmanager\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\Controllers\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\MVCFramework\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_ordersmanager\Controllers\Articoli\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="ModelSupport_articles_crud_with_injectable_parameters\Commons\default.txaPackage" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="OSX32">
<Operation>1</Operation>
@ -505,6 +148,16 @@
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClasses">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
<Operation>64</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>classes</RemoteDir>
<Operation>64</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClassesDexFile">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
@ -804,6 +457,10 @@
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
@ -817,6 +474,10 @@
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
@ -843,6 +504,10 @@
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
@ -870,6 +535,9 @@
<Platform Name="OSX64">
<Operation>0</Operation>
</Platform>
<Platform Name="OSXARM64">
<Operation>0</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
@ -1423,6 +1091,10 @@
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSXARM64">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="Android">
@ -1451,6 +1123,9 @@
<Platform Name="OSX64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
@ -1489,16 +1164,17 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Android64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSXARM64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
</Deployment>
<Platforms>
<Platform value="Win32">True</Platform>

Binary file not shown.

Binary file not shown.

View File

@ -65,7 +65,7 @@ begin
if Context.Request.Headers['User-Agent'].Contains('Android') then
begin
Context.Response.Location := 'http://play.google.com';
Context.Response.StatusCode := 307; // temporary redirect
Context.Response.StatusCode := HTTP_STATUS.TemporaryRedirect; // 307 - temporary redirect
Handled := True;
end;
end;

View File

@ -586,20 +586,21 @@ begin
lDM.qryCustomers.Open;
lDict := ObjectDict(False { data are not freed after ObjectDict if freed } )
.Add('customers', lDM.qryCustomers,
procedure(const DS: TDataset; const Links: IMVCLinks)
begin
Links.AddRefLink.Add(HATEOAS.HREF, '/customers/' + DS.FieldByName('cust_no').AsString)
.Add(HATEOAS.REL, 'self').Add(HATEOAS._TYPE, 'application/json');
Links.AddRefLink.Add(HATEOAS.HREF, '/customers/' + DS.FieldByName('cust_no').AsString +
'/orders').Add(HATEOAS.REL, 'orders').Add(HATEOAS._TYPE, 'application/json');
end).Add('singleCustomer', lDM.qryCustomers,
procedure(const DS: TDataset; const Links: IMVCLinks)
begin
Links.AddRefLink.Add(HATEOAS.HREF, '/customers/' + DS.FieldByName('cust_no').AsString)
.Add(HATEOAS.REL, 'self').Add(HATEOAS._TYPE, 'application/json');
Links.AddRefLink.Add(HATEOAS.HREF, '/customers/' + DS.FieldByName('cust_no').AsString +
'/orders').Add(HATEOAS.REL, 'orders').Add(HATEOAS._TYPE, 'application/json');
end, dstSingleRecord, ncPascalCase);
procedure(const DS: TDataset; const Links: IMVCLinks)
begin
Links.AddRefLink.Add(HATEOAS.HREF, '/customers/' + DS.FieldByName('cust_no').AsString)
.Add(HATEOAS.REL, 'self').Add(HATEOAS._TYPE, 'application/json');
Links.AddRefLink.Add(HATEOAS.HREF, '/customers/' + DS.FieldByName('cust_no').AsString +
'/orders').Add(HATEOAS.REL, 'orders').Add(HATEOAS._TYPE, 'application/json');
end)
.Add('singleCustomer', lDM.qryCustomers,
procedure(const DS: TDataset; const Links: IMVCLinks)
begin
Links.AddRefLink.Add(HATEOAS.HREF, '/customers/' + DS.FieldByName('cust_no').AsString)
.Add(HATEOAS.REL, 'self').Add(HATEOAS._TYPE, 'application/json');
Links.AddRefLink.Add(HATEOAS.HREF, '/customers/' + DS.FieldByName('cust_no').AsString +
'/orders').Add(HATEOAS.REL, 'orders').Add(HATEOAS._TYPE, 'application/json');
end, dstSingleRecord, ncPascalCase);
Render(lDict);
finally
lDM.Free;
@ -748,8 +749,11 @@ end;
procedure TRenderSampleController.GetPerson_AsText(const ID: Integer);
begin
ResponseStream.AppendLine('ID : ' + ID.ToString).AppendLine('FirstName : Daniele')
.AppendLine('LastName : Teti').AppendLine('DOB : ' + DateToStr(EncodeDate(1979, 5, 2)))
ResponseStream
.AppendLine('ID : ' + ID.ToString)
.AppendLine('FirstName : Daniele')
.AppendLine('LastName : Teti')
.AppendLine('DOB : ' + DateToStr(EncodeDate(1979, 5, 2)))
.AppendLine('Married : yes');
RenderResponseStream;
end;
@ -875,7 +879,7 @@ begin
{$ENDREGION}
{ classic approach }
// Render<TPerson>(HTTP_STATUS.OK, People, True);
//Render<TPerson>(HTTP_STATUS.OK, People, True);
{ new approach with ObjectDict }
Render(HTTP_STATUS.OK, ObjectDict().Add('data', People));
end;

View File

@ -2,7 +2,7 @@
//
// Delphi MVC Framework
//
// Copyright (c) 2010-2021 Daniele Teti and the DMVCFramework Team
// Copyright (c) 2010-2022 Daniele Teti and the DMVCFramework Team
//
// https://github.com/danieleteti/delphimvcframework
//

View File

@ -8,6 +8,7 @@ uses
type
[MVCPath('/')]
[MVCPath('/api')]
TRoutingSampleController = class(TMVCController)
public
[MVCPath]
@ -133,8 +134,13 @@ begin
if Context.Request.QueryStringParamExists('order') then
orderby := Context.Request.QueryStringParam('order');
S := Format('SEARCHTEXT: "%s" - PAGE: %d - ORDER BY FIELD: "%s"', [search, Page, orderby]);
ResponseStream.AppendLine(S).AppendLine(StringOfChar('*', 30)).AppendLine('1. Daniele Teti')
.AppendLine('2. John Doe').AppendLine('3. Mark Rossi').AppendLine('4. Jack Verdi')
ResponseStream
.AppendLine(S)
.AppendLine(StringOfChar('*', 30))
.AppendLine('1. Daniele Teti')
.AppendLine('2. John Doe')
.AppendLine('3. Mark Rossi')
.AppendLine('4. Jack Verdi')
.AppendLine(StringOfChar('*', 30));
RenderResponseStream;
end;

View File

@ -1,7 +1,7 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{E3725756-A58C-46BB-9708-ADE38AF9523C}</ProjectGuid>
<ProjectVersion>19.2</ProjectVersion>
<ProjectVersion>19.3</ProjectVersion>
<FrameworkType>None</FrameworkType>
<MainSource>routingsample.dpr</MainSource>
<Base>True</Base>
@ -23,16 +23,6 @@
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='iOSDevice64' and '$(Base)'=='true') or '$(Base_iOSDevice64)'!=''">
<Base_iOSDevice64>true</Base_iOSDevice64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='iOSSimulator' and '$(Base)'=='true') or '$(Base_iOSSimulator)'!=''">
<Base_iOSSimulator>true</Base_iOSSimulator>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
@ -116,19 +106,6 @@
<VerInfo_Keys>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=</VerInfo_Keys>
<Android_LauncherIcon192>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png</Android_LauncherIcon192>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_iOSDevice64)'!=''">
<iOS_AppStore1024>$(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_1024x1024.png</iOS_AppStore1024>
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone &amp; iPad;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSCameraUsageDescription=The reason for accessing the camera;NSFaceIDUsageDescription=The reason for accessing the face id;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing bluetooth;NSBluetoothPeripheralUsageDescription=The reason for accessing bluetooth peripherals;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSMotionUsageDescription=The reason for accessing the accelerometer;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple&apos;s speech recognition servers</VerInfo_Keys>
<VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_BundleId>$(MSBuildProjectName)</VerInfo_BundleId>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_iOSSimulator)'!=''">
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone &amp; iPad;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSCameraUsageDescription=The reason for accessing the camera;NSFaceIDUsageDescription=The reason for accessing the face id;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing bluetooth;NSBluetoothPeripheralUsageDescription=The reason for accessing bluetooth peripherals;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSMotionUsageDescription=The reason for accessing the accelerometer;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple&apos;s speech recognition servers</VerInfo_Keys>
<VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<VerInfo_Locale>1033</VerInfo_Locale>
<DCC_UsePackage>FireDACSqliteDriver;DBXSqliteDriver;FireDACPgDriver;fmx;IndySystem;TeeDB;frx19;inetdbbde;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;CodeSiteExpressPkg;FireDACDBXDriver;inetdbxpress;webdsnap;frxe19;FireDACDb2Driver;adortl;frxDB19;FireDACASADriver;bindcompfmx;ADVLikeComponents;vcldbx;FireDACODBCDriver;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;inetdb;Tee;DBXOdbcDriver;vclFireDAC;xmlrtl;svnui;ibxpress;IndyProtocols;DBXMySQLDriver;FireDACCommonDriver;vclactnband;bindengine;soaprtl;bindcompdbx;FMXTee;TeeUI;bindcompvcl;vclie;FireDACADSDriver;vcltouch;VclSmp;FireDACMSSQLDriver;FireDAC;VCLRESTComponents;Intraweb;DBXInformixDriver;DataSnapConnectors;FireDACDataSnapDriver;dsnapcon;DBXFirebirdDriver;inet;fmxobj;FireDACMySQLDriver;vclx;svn;DBXSybaseASADriver;FireDACOracleDriver;fmxdae;RESTComponents;bdertl;FireDACMSAccDriver;DataSnapIndy10ServerTransport;dbexpress;IndyIPClient;$(DCC_UsePackage)</DCC_UsePackage>
@ -169,10 +146,6 @@
</DCCReference>
<DCCReference Include="RoutingSampleControllerU.pas"/>
<DCCReference Include="BusinessObjectsU.pas"/>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
@ -180,6 +153,10 @@
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
@ -245,11 +222,6 @@
</Excluded_Packages>
</Delphi.Personality>
<Deployment Version="3">
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="OSX32">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="Linux64\Debug\routingsample" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Linux64">
<RemoteName>routingsample</RemoteName>
@ -261,21 +233,26 @@
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="iOSSimulator">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libpcre.dylib" Class="DependencyModule">
<Platform Name="iOSSimulator">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="OSX32">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgsqlite3.dylib" Class="DependencyModule">
<Platform Name="OSX32">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="iOSSimulator">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\osx64\libcgsqlite3.dylib" Class="DependencyModule">
<Platform Name="OSX64">
<Overwrite>true</Overwrite>
@ -289,6 +266,16 @@
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClasses">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
<Operation>64</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>classes</RemoteDir>
<Operation>64</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClassesDexFile">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
@ -587,6 +574,10 @@
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
@ -600,6 +591,10 @@
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
@ -626,6 +621,10 @@
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
@ -653,6 +652,9 @@
<Platform Name="OSX64">
<Operation>0</Operation>
</Platform>
<Platform Name="OSXARM64">
<Operation>0</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
@ -1206,6 +1208,10 @@
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSXARM64">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="Android">
@ -1234,6 +1240,9 @@
<Platform Name="OSX64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSXARM64">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
@ -1272,22 +1281,21 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Android64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSXARM64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
</Deployment>
<Platforms>
<Platform value="Android">False</Platform>
<Platform value="Android64">False</Platform>
<Platform value="iOSDevice64">False</Platform>
<Platform value="iOSSimulator">False</Platform>
<Platform value="Linux64">True</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>

View File

@ -1245,6 +1245,10 @@ begin
GetBackEnd +
' requires it');
end;
if foReadOnly in fPrimaryKeyOptions then
begin
raise EMVCActiveRecord.Create('Cannot define a read-only primary key when a sequence is used for the class ' + ClassName);
end;
FillPrimaryKey(fPrimaryKeySequenceName);
end;
end;

View File

@ -45,7 +45,12 @@ type
class procedure ExecuteQuery(AQuery: TFDQuery; AObject: TObject);
class procedure ObjectToParameters(AFDParams: TFDParams; AObject: TObject; AParamPrefix: string = '';
ASetParamTypes: boolean = True);
class procedure CreateDatasetFromMetadata(AFDMemTable: TFDMemTable; AMeta: TJSONObject);
class procedure CreateDatasetFromMetadata(AFDMemTable: TFDCustomMemTable; AMeta: TJSONObject);
end;
TFDCustomMemTableHelper = class helper for TFDCustomMemTable
public
procedure InitFromMetadata(const AJSONMetadata: TJSONObject);
end;
implementation
@ -65,7 +70,7 @@ begin
end;
class procedure TFireDACUtils.CreateDatasetFromMetadata(
AFDMemTable: TFDMemTable; AMeta: TJSONObject);
AFDMemTable: TFDCustomMemTable; AMeta: TJSONObject);
var
lJArr: TJSONArray;
I: Integer;
@ -217,4 +222,9 @@ begin
end;
end;
procedure TFDCustomMemTableHelper.InitFromMetadata(const AJSONMetadata: TJSONObject);
begin
TFireDACUtils.CreateDatasetFromMetadata(Self, AJSONMetadata);
end;
end.

View File

@ -37,7 +37,7 @@ uses
System.RegularExpressions,
MVCFramework,
MVCFramework.Commons,
IdURI;
IdURI, System.Classes;
type
TMVCActionParamCacheItem = class
@ -82,9 +82,10 @@ type
var aParams: TMVCRequestParamsTable): Boolean;
function GetParametersNames(const V: string): TList<string>;
protected
function GetControllerMappedPath(
procedure FillControllerMappedPaths(
const aControllerName: string;
const aControllerAttributes: TArray<TCustomAttribute>): string;
const aControllerAttributes: TArray<TCustomAttribute>;
const aControllerMappedPaths: TStringList);
public
class function StringMethodToHTTPMetod(const aValue: string): TMVCHTTPMethodType; static;
constructor Create(const aConfig: TMVCConfig;
@ -148,6 +149,7 @@ var
LRequestAccept: string;
LRequestContentType: string;
LControllerMappedPath: string;
LControllerMappedPaths: TStringList;
LControllerDelegate: TMVCControllerDelegate;
LAttributes: TArray<TCustomAttribute>;
LAtt: TCustomAttribute;
@ -157,6 +159,7 @@ var
LMethodPath: string;
LProduceAttribute: MVCProducesAttribute;
lURLSegment: string;
LItem: String;
// JUST FOR DEBUG
// lMethodCompatible: Boolean;
// lContentTypeCompatible: Boolean;
@ -185,93 +188,108 @@ begin
TMonitor.Enter(gLock);
try
LControllerMappedPath := EmptyStr;
for LControllerDelegate in AControllers do
begin
SetLength(LAttributes, 0);
LRttiType := FRttiContext.GetType(LControllerDelegate.Clazz.ClassInfo);
lURLSegment := LControllerDelegate.URLSegment;
if lURLSegment.IsEmpty then
//LControllerMappedPaths := TArray<string>.Create();
LControllerMappedPaths := TStringList.Create;
try
for LControllerDelegate in AControllers do
begin
LAttributes := LRttiType.GetAttributes;
if (LAttributes = nil) then
Continue;
LControllerMappedPath := GetControllerMappedPath(LRttiType.Name, LAttributes);
end
else
begin
LControllerMappedPath := lURLSegment;
end;
LControllerMappedPaths.Clear;
SetLength(LAttributes, 0);
LRttiType := FRttiContext.GetType(LControllerDelegate.Clazz.ClassInfo);
if (LControllerMappedPath = '/') then
begin
LControllerMappedPath := '';
end;
{$IF defined(TOKYOORBETTER)}
if not LRequestPathInfo.StartsWith(APathPrefix + LControllerMappedPath, True) then
{$ELSE}
if not TMVCStringHelper.StartsWith(APathPrefix + LControllerMappedPath, LRequestPathInfo, True) then
{$ENDIF}
begin
Continue;
end;
LMethods := LRttiType.GetMethods; { do not use GetDeclaredMethods because JSON-RPC rely on this!! }
for LMethod in LMethods do
begin
if LMethod.Visibility <> mvPublic then // 2020-08-08
Continue;
if (LMethod.MethodKind <> mkProcedure) { or LMethod.IsClassMethod } then
Continue;
LAttributes := LMethod.GetAttributes;
if Length(LAttributes) = 0 then
Continue;
for LAtt in LAttributes do
lURLSegment := LControllerDelegate.URLSegment;
if lURLSegment.IsEmpty then
begin
if LAtt is MVCPathAttribute then
begin
// THIS BLOCK IS HERE JUST FOR DEBUG
// if LMethod.Name.Contains('GetProject') then
// begin
// lMethodCompatible := True; //debug here
// end;
// lMethodCompatible := IsHTTPMethodCompatible(ARequestMethodType, LAttributes);
// lContentTypeCompatible := IsHTTPContentTypeCompatible(ARequestMethodType, LRequestContentType, LAttributes);
// lAcceptCompatible := IsHTTPAcceptCompatible(ARequestMethodType, LRequestAccept, LAttributes);
LAttributes := LRttiType.GetAttributes;
if (LAttributes = nil) then
Continue;
//LControllerMappedPaths := GetControllerMappedPath(LRttiType.Name, LAttributes);
FillControllerMappedPaths(LRttiType.Name, LAttributes, LControllerMappedPaths);
end
else
begin
LControllerMappedPaths.Add(lURLSegment);
end;
if IsHTTPMethodCompatible(ARequestMethodType, LAttributes) and
IsHTTPContentTypeCompatible(ARequestMethodType, LRequestContentType, LAttributes) and
IsHTTPAcceptCompatible(ARequestMethodType, LRequestAccept, LAttributes) then
for LItem in LControllerMappedPaths do
begin
LControllerMappedPath := LItem;
if (LControllerMappedPath = '/') then
begin
LControllerMappedPath := '';
end;
{$IF defined(TOKYOORBETTER)}
if not LRequestPathInfo.StartsWith(APathPrefix + LControllerMappedPath, True) then
{$ELSE}
if not TMVCStringHelper.StartsWith(APathPrefix + LControllerMappedPath, LRequestPathInfo, True) then
{$ENDIF}
begin
Continue;
end;
// end;
// if (not LControllerMappedPathFound) then
// continue;
LMethods := LRttiType.GetMethods; { do not use GetDeclaredMethods because JSON-RPC rely on this!! }
for LMethod in LMethods do
begin
if LMethod.Visibility <> mvPublic then // 2020-08-08
Continue;
if (LMethod.MethodKind <> mkProcedure) { or LMethod.IsClassMethod } then
Continue;
LAttributes := LMethod.GetAttributes;
if Length(LAttributes) = 0 then
Continue;
for LAtt in LAttributes do
begin
LMethodPath := MVCPathAttribute(LAtt).Path;
if IsCompatiblePath(APathPrefix + LControllerMappedPath + LMethodPath,
LRequestPathInfo, ARequestParams) then
if LAtt is MVCPathAttribute then
begin
FMethodToCall := LMethod;
FControllerClazz := LControllerDelegate.Clazz;
FControllerCreateAction := LControllerDelegate.CreateAction;
LProduceAttribute := GetAttribute<MVCProducesAttribute>(LAttributes);
if LProduceAttribute <> nil then
// THIS BLOCK IS HERE JUST FOR DEBUG
// if LMethod.Name.Contains('GetProject') then
// begin
// lMethodCompatible := True; //debug here
// end;
// lMethodCompatible := IsHTTPMethodCompatible(ARequestMethodType, LAttributes);
// lContentTypeCompatible := IsHTTPContentTypeCompatible(ARequestMethodType, LRequestContentType, LAttributes);
// lAcceptCompatible := IsHTTPAcceptCompatible(ARequestMethodType, LRequestAccept, LAttributes);
if IsHTTPMethodCompatible(ARequestMethodType, LAttributes) and
IsHTTPContentTypeCompatible(ARequestMethodType, LRequestContentType, LAttributes) and
IsHTTPAcceptCompatible(ARequestMethodType, LRequestAccept, LAttributes) then
begin
AResponseContentMediaType := LProduceAttribute.Value;
AResponseContentCharset := LProduceAttribute.Charset;
end
else
begin
AResponseContentMediaType := ADefaultContentType;
AResponseContentCharset := ADefaultContentCharset;
LMethodPath := MVCPathAttribute(LAtt).Path;
if IsCompatiblePath(APathPrefix + LControllerMappedPath + LMethodPath,
LRequestPathInfo, ARequestParams) then
begin
FMethodToCall := LMethod;
FControllerClazz := LControllerDelegate.Clazz;
FControllerCreateAction := LControllerDelegate.CreateAction;
LProduceAttribute := GetAttribute<MVCProducesAttribute>(LAttributes);
if LProduceAttribute <> nil then
begin
AResponseContentMediaType := LProduceAttribute.Value;
AResponseContentCharset := LProduceAttribute.Charset;
end
else
begin
AResponseContentMediaType := ADefaultContentType;
AResponseContentCharset := ADefaultContentCharset;
end;
Exit(True);
end;
end;
Exit(True);
end;
end;
end; // if MVCPathAttribute
end; // for in Attributes
end; // for in Methods
end; // for in Controllers
end; // if MVCPathAttribute
end; // for in Attributes
end; // for in Methods
end;
end; // for in Controllers
finally
LControllerMappedPaths.Free;
end;
finally
TMonitor.Exit(gLock);
end;
@ -287,9 +305,10 @@ begin
Exit(T(Att));
end;
function TMVCRouter.GetControllerMappedPath(
const aControllerName: string;
const aControllerAttributes: TArray<TCustomAttribute>): string;
procedure TMVCRouter.FillControllerMappedPaths(
const aControllerName: string;
const aControllerAttributes: TArray<TCustomAttribute>;
const aControllerMappedPaths: TStringList);
var
LFound: Boolean;
LAtt: TCustomAttribute;
@ -300,13 +319,13 @@ begin
if LAtt is MVCPathAttribute then
begin
LFound := True;
Result := MVCPathAttribute(LAtt).Path;
Break;
aControllerMappedPaths.Add(MVCPathAttribute(LAtt).Path);
end;
end;
if not LFound then
begin
raise EMVCException.CreateFmt('Controller %s does not have MVCPath attribute', [aControllerName]);
end;
end;
function TMVCRouter.GetFirstMediaType(const AContentType: string): string;
@ -349,7 +368,7 @@ begin
FActionParamsCache.Add(AMVCPath, lCacheItem);
end;
if (APath = AMVCPath) then
if (APath = AMVCPath) or ((APath = '/') and (AMVCPath = '')) then
Exit(True)
else
begin

View File

@ -109,7 +109,7 @@ begin
begin
if lKeyValue.Value.Writeable then
begin
lSB.Append(':' + GetParamNameForSQL(lKeyValue.Value.FieldName) + ',');
lSB.Append(':' + GetParamNameForSQL(lKeyValue.Value.FieldName) + ',');
end;
end;
@ -140,11 +140,9 @@ end;
initialization
TMVCSQLGeneratorRegistry.Instance.RegisterSQLGenerator('firebird', TMVCSQLGeneratorFirebird);
TMVCSQLGeneratorRegistry.Instance.RegisterSQLGenerator('interbase', TMVCSQLGeneratorFirebird);
finalization
TMVCSQLGeneratorRegistry.Instance.UnRegisterSQLGenerator('firebird');
TMVCSQLGeneratorRegistry.Instance.UnRegisterSQLGenerator('interbase');
end.

View File

@ -61,21 +61,30 @@ var
lKeyValue: TPair<TRttiField, TFieldInfo>;
lSB: TStringBuilder;
lPKInInsert: Boolean;
lFieldName: String;
begin
lPKInInsert := (not PKFieldName.IsEmpty); // and (not(TMVCActiveRecordFieldOption.foAutoGenerated in PKOptions));
lPKInInsert := lPKInInsert and (not(TMVCActiveRecordFieldOption.foReadOnly in PKOptions));
lSB := TStringBuilder.Create;
try
lSB.Append('INSERT INTO ' + TableName + '(');
lSB.Append('INSERT INTO ' + GetTableNameForSQL(TableName) + '(');
if lPKInInsert then
begin
lSB.Append(PKFieldName + ',');
lSB.Append(GetFieldNameForSQL(PKFieldName) + ',');
end;
{partition}
for lFieldName in fPartitionInfo.FieldNames do
begin
lSB.Append(GetFieldNameForSQL(lFieldName) + ',');
end;
{end-partition}
for lKeyValue in Map do
begin
if lKeyValue.Value.Writeable then
begin
lSB.Append(lKeyValue.Value.FieldName + ',');
lSB.Append(GetFieldNameForSQL(lKeyValue.Value.FieldName) + ',');
end;
end;
@ -83,13 +92,21 @@ begin
lSB.Append(') values (');
if lPKInInsert then
begin
lSB.Append(':' + PKFieldName + ',');
lSB.Append(':' + GetParamNameForSQL(PKFieldName) + ',');
end;
{partition}
for lFieldName in fPartitionInfo.FieldNames do
begin
lSB.Append(':' + GetParamNameForSQL(lFieldName) + ',');
end;
{end-partition}
for lKeyValue in Map do
begin
if lKeyValue.Value.Writeable then
begin
lSB.Append(':' + lKeyValue.Value.FieldName + ',');
lSB.Append(':' + GetParamNameForSQL(lKeyValue.Value.FieldName) + ',');
end;
end;

View File

@ -57,6 +57,18 @@ type
[TestCase('request url /fault2', '/exception/fault2')]
procedure TestControllerWithExceptionInCreate(const URLSegment: string);
[Test]
[TestCase('url "/"', '/')]
[TestCase('url "/action1"', '/action1')]
[TestCase('url "/action2"', '/action2')]
[TestCase('url "/api/v1"', '/api/v1')]
[TestCase('url "/api/v1/action1"', '/api/v1/action1')]
[TestCase('url "/api/v1/action2"', '/api/v1/action2')]
[TestCase('url "/api/v2"', '/api/v2')]
[TestCase('url "/api/v2/action1"', '/api/v2/action1')]
[TestCase('url "/api/v2/action2"', '/api/v2/action2')]
procedure TestMultiMVCPathOnControllerAndAction(const URLSegment: string);
[Test]
procedure TestReqWithParams;
@ -1149,7 +1161,7 @@ procedure TServerTest.TestFileWithFolderName;
var
lRes: IMVCRESTResponse;
begin
lRes := RESTClient.Accept(TMVCMediaType.TEXT_HTML).Get('');
lRes := RESTClient.Accept(TMVCMediaType.TEXT_HTML).Get('doesn''t exist');
Assert.areEqual(404, lRes.StatusCode, '<empty>');
lRes := RESTClient.Accept(TMVCMediaType.TEXT_HTML).Get('/static/index.html');
@ -1302,6 +1314,15 @@ begin
Assert.AreNotEqual('', r.HeaderValue('request_gen_time'));
end;
procedure TServerTest.TestMultiMVCPathOnControllerAndAction(
const URLSegment: string);
var
lRes: IMVCRESTResponse;
begin
lRes := RESTClient.Get(URLSegment);
Assert.areEqual(HTTP_STATUS.OK, lRes.StatusCode);
end;
procedure TServerTest.TestObjectDict;
var
lRes: IMVCRESTResponse;

View File

@ -24,7 +24,8 @@ uses
MVCFramework.JSONRPC in '..\..\..\sources\MVCFramework.JSONRPC.pas',
RandomUtilsU in '..\..\..\samples\commons\RandomUtilsU.pas',
MVCFramework.Serializer.HTML in '..\..\..\sources\MVCFramework.Serializer.HTML.pas',
MVCFramework.Tests.Serializer.Entities in '..\..\common\MVCFramework.Tests.Serializer.Entities.pas';
MVCFramework.Tests.Serializer.Entities in '..\..\common\MVCFramework.Tests.Serializer.Entities.pas',
MVCFramework.Router in '..\..\..\sources\MVCFramework.Router.pas';
{$R *.res}

View File

@ -120,6 +120,7 @@
<DCCReference Include="..\..\..\samples\commons\RandomUtilsU.pas"/>
<DCCReference Include="..\..\..\sources\MVCFramework.Serializer.HTML.pas"/>
<DCCReference Include="..\..\common\MVCFramework.Tests.Serializer.Entities.pas"/>
<DCCReference Include="..\..\..\sources\MVCFramework.Router.pas"/>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
@ -169,6 +170,11 @@
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="OSX32">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="iOSSimulator">
<Overwrite>true</Overwrite>
@ -180,11 +186,6 @@
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib" Class="DependencyModule">
<Platform Name="OSX32">
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="TestServer" Configuration="CI" Class="ProjectOutput">
<Platform Name="Linux64">
<RemoteName>TestServer</RemoteName>

View File

@ -38,7 +38,8 @@ uses
type
[MVCPath('/')]
[MVCPath]
[MVCPath('/donotusethis')]
TTestServerController = class(TMVCController)
private
FFormatSettings: TFormatSettings;
@ -359,6 +360,17 @@ type
constructor Create; override;
end;
[MVCPath]
[MVCPath('/api/v1')]
[MVCPath('/api/v2')]
TTestMultiPathController = class(TMVCController)
public
[MVCPath]
[MVCPath('/action1')]
[MVCPath('/action2')]
procedure Action1or2;
end;
implementation
uses
@ -1049,4 +1061,11 @@ begin
// do nothing
end;
{ TTestMultiPathController }
procedure TTestMultiPathController.Action1or2;
begin
Render(HTTP_STATUS.OK);
end;
end.

View File

@ -1,9 +1,9 @@
object MainWebModule: TMainWebModule
OldCreateOrder = False
OnCreate = WebModuleCreate
Actions = <>
Height = 230
Width = 415
PixelsPerInch = 96
object FDStanStorageJSONLink1: TFDStanStorageJSONLink
Left = 192
Top = 96

View File

@ -80,12 +80,14 @@ begin
Config[TMVCConfigKey.ViewPath] := '..\templates';
Config[TMVCConfigKey.DefaultViewFileExtension] := 'html';
end, nil);
MVCEngine.AddController(TTestServerController)
MVCEngine
.AddController(TTestServerController)
.AddController(TTestPrivateServerController)
.AddController(TTestServerControllerExceptionAfterCreate)
.AddController(TTestServerControllerExceptionBeforeDestroy)
.AddController(TTestServerControllerActionFilters)
.AddController(TTestPrivateServerControllerCustomAuth)
.AddController(TTestMultiPathController)
.AddController(TTestJSONRPCController, '/jsonrpc')
.AddController(TTestJSONRPCControllerWithGet, '/jsonrpcwithget')
.PublishObject(