refactored some ObjectsMappers responsibilities

Client part of Unit test doesn't compile
This commit is contained in:
Daniele Teti 2017-04-24 00:19:53 +02:00
parent 06ccd68540
commit 52e15c4eca
21 changed files with 1559 additions and 1334 deletions

View File

@ -3,7 +3,7 @@ unit BusinessObjects;
interface
uses
ObjectsMappers;
MVCFramework.Serializer.Commons;
type
TBaseBO = class
@ -17,7 +17,7 @@ type
property ID: Integer read FID write SetID;
end;
[MapperJSONNaming(JSONNameLowerCase)]
[MVCNameCase(ncLowerCase)]
TArticle = class(TBaseBO)
private
FPrice: Currency;
@ -30,11 +30,11 @@ type
procedure CheckInsert; override;
procedure CheckUpdate; override;
procedure CheckDelete; override;
[MapperColumn('CODICE')]
[MVCColumn('CODICE')]
property Code: string read FCode write SetCode;
[MapperColumn('DESCRIZIONE')]
[MVCColumn('DESCRIZIONE')]
property Description: string read FDescription write SetDescription;
[MapperColumn('PREZZO')]
[MVCColumn('PREZZO')]
property Price: Currency read FPrice write SetPrice;
end;

View File

@ -9,14 +9,12 @@ object dmMain: TdmMain
'Password=masterkey'
'DriverID=FB')
ConnectedStoredUsage = []
Connected = True
LoginPrompt = False
BeforeConnect = ConnectionBeforeConnect
Left = 64
Top = 48
end
object dsArticles: TFDQuery
Active = True
Connection = Connection
UpdateOptions.AssignedValues = [uvFetchGeneratorsPoint, uvGeneratorName]
UpdateOptions.FetchGeneratorsPoint = gpImmediate

View File

@ -7,7 +7,7 @@ uses
FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def,
FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys, FireDAC.Phys.FB, Data.DB,
FireDAC.Comp.Client, FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf,
FireDAC.DApt, FireDAC.Comp.DataSet;
FireDAC.DApt, FireDAC.Comp.DataSet, FireDAC.Phys.FBDef, FireDAC.VCLUI.Wait;
type
TdmMain = class(TDataModule)

View File

@ -29,7 +29,9 @@ type
implementation
uses
ObjectsMappers, FireDAC.Stan.Option, FireDAC.Comp.Client, FireDAC.Stan.Param;
FireDAC.Stan.Option, FireDAC.Comp.Client, FireDAC.Stan.Param,
MVCFramework.FireDAC.Utils, MVCFramework.DataSet.Utils,
MVCFramework.Serializer.Commons;
{ TArticoliService }
@ -39,7 +41,7 @@ var
begin
AArticolo.CheckInsert;
Cmd := FDM.updArticles.Commands[arInsert];
Mapper.ObjectToFDParameters(Cmd.Params, AArticolo, 'NEW_');
TFireDACUtils.ObjectToParameters(Cmd.Params, AArticolo, 'NEW_');
Cmd.OpenOrExecute;
end;
@ -49,7 +51,7 @@ var
begin
AArticolo.CheckDelete;
Cmd := FDM.updArticles.Commands[arDelete];
Mapper.ObjectToFDParameters(Cmd.Params, AArticolo, 'OLD_');
TFireDACUtils.ObjectToParameters(Cmd.Params, AArticolo, 'OLD_');
Cmd.Execute;
end;
@ -80,7 +82,7 @@ var
begin
AArticolo.CheckUpdate;
Cmd := FDM.updArticles.Commands[arUpdate];
Mapper.ObjectToFDParameters(Cmd.Params, AArticolo, 'NEW_');
TFireDACUtils.ObjectToParameters(Cmd.Params, AArticolo, 'NEW_');
Cmd.ParamByName('OLD_ID').AsInteger := AArticolo.ID;
Cmd.Execute;
if Cmd.RowsAffected <> 1 then

View File

@ -8,17 +8,19 @@ uses
IdHTTPWebBrokerBridge,
Web.WebReq,
Web.WebBroker,
WebModuleUnit1 in 'WebModuleUnit1.pas' {WebModule1: TWebModule} ,
WebModuleUnit1 in 'WebModuleUnit1.pas' {WebModule1: TWebModule},
Controllers.Base in 'Controllers.Base.pas',
Controllers.Articles in 'Controllers.Articles.pas',
Services in 'Services.pas',
BusinessObjects in 'BusinessObjects.pas',
MainDM in 'MainDM.pas' {dmMain: TDataModule} ,
MainDM in 'MainDM.pas' {dmMain: TDataModule},
Commons in 'Commons.pas',
MVCFramework.Serializer.JSON in '..\..\sources\MVCFramework.Serializer.JSON.pas',
ObjectsMappers in '..\..\sources\ObjectsMappers.pas',
MVCFramework.Commons in '..\..\sources\MVCFramework.Commons.pas',
MVCFramework.Serializer.Intf in '..\..\sources\MVCFramework.Serializer.Intf.pas';
MVCFramework.Serializer.Intf in '..\..\sources\MVCFramework.Serializer.Intf.pas',
MVCFramework.FireDAC.Utils in '..\..\sources\MVCFramework.FireDAC.Utils.pas',
ObjectsMappers in '..\..\sources\ObjectsMappers.pas',
MVCFramework.DataSet.Utils in '..\..\sources\MVCFramework.DataSet.Utils.pas';
{$R *.res}

View File

@ -105,9 +105,11 @@
</DCCReference>
<DCCReference Include="Commons.pas"/>
<DCCReference Include="..\..\sources\MVCFramework.Serializer.JSON.pas"/>
<DCCReference Include="..\..\sources\ObjectsMappers.pas"/>
<DCCReference Include="..\..\sources\MVCFramework.Commons.pas"/>
<DCCReference Include="..\..\sources\MVCFramework.Serializer.Intf.pas"/>
<DCCReference Include="..\..\sources\MVCFramework.FireDAC.Utils.pas"/>
<DCCReference Include="..\..\sources\ObjectsMappers.pas"/>
<DCCReference Include="..\..\sources\MVCFramework.DataSet.Utils.pas"/>
<None Include="ModelSupport_ordersmanager\default.txvpck"/>
<None Include="ModelSupport_ordersmanager\Services\default.txvpck"/>
<None Include="ModelSupport_ordersmanager\ordersmanager\default.txvpck"/>
@ -135,6 +137,7 @@
<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"/>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
@ -301,6 +304,12 @@
<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_ordersmanager\default.txvpck" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
@ -331,12 +340,14 @@
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployClass Name="ProjectiOSDeviceResourceRules"/>
<DeployClass Name="ProjectOSXResource">
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="OSX32">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClassesDexFile">
<Platform Name="Android">
@ -344,18 +355,15 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon144">
<DeployClass Name="AndroidGDBServer">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="Win32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<DeployClass Name="AndroidLibnativeArmeabiFile">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
@ -365,49 +373,294 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch768">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<DeployClass Name="AndroidLibnativeX86File"/>
<DeployClass Name="AndroidServiceOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="iOSDevice64">
<DeployClass Name="AndroidSplashImageDef">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
</DeployClass>
<DeployClass Name="AndroidSplashStyles">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon144">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage426">
<Platform Name="Android">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage470">
<Platform Name="Android">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage640">
<Platform Name="Android">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage960">
<Platform Name="Android">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyFramework">
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyModule">
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="DependencyPackage">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="File">
<Platform Name="Android">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>0</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1024">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1536">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch768">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch320">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640x1136">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectAndroidManifest">
<Platform Name="Android">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice32">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceResourceRules"/>
<DeployClass Name="ProjectiOSEntitlements"/>
<DeployClass Name="ProjectiOSInfoPList"/>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXEntitlements"/>
<DeployClass Name="ProjectOSXInfoPList"/>
<DeployClass Name="ProjectOSXResource">
<Platform Name="OSX32">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="Linux64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyFramework">
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="ProjectUWPManifest">
<Platform Name="Win32">
@ -417,105 +670,13 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeX86File"/>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1024">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch320">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSInfoPList"/>
<DeployClass Name="AndroidLibnativeArmeabiFile">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<DeployClass Name="UWP_DelphiLogo150">
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1536">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage470">
<Platform Name="Android">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage640">
<Platform Name="Android">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640x1136">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
@ -529,158 +690,6 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSEntitlements"/>
<DeployClass Name="AndroidGDBServer">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXInfoPList"/>
<DeployClass Name="ProjectOSXEntitlements"/>
<DeployClass Name="UWP_DelphiLogo150">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStyles">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage426">
<Platform Name="Android">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashImageDef">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectAndroidManifest">
<Platform Name="Android">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="File">
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>0</Operation>
</Platform>
<Platform Name="Android">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="DependencyPackage">
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage960">
<Platform Name="Android">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyModule">
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
</Platform>
<Platform Name="OSX32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
</DeployClass>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>

View File

@ -22,7 +22,6 @@ object MainForm: TMainForm
Height = 39
Align = alTop
TabOrder = 0
ExplicitWidth = 592
object DBNavigator1: TDBNavigator
AlignWithMargins = True
Left = 378
@ -32,7 +31,6 @@ object MainForm: TMainForm
DataSource = dsrcArticles
Align = alRight
TabOrder = 0
ExplicitLeft = 301
end
object btnOpen: TButton
AlignWithMargins = True

View File

@ -47,7 +47,7 @@ var
implementation
uses
ObjectsMappers, System.UITypes;
System.UITypes, MVCFramework.DataSet.Utils;
{$R *.dfm}
@ -76,7 +76,7 @@ begin
DataSet.DisableControls;
try
FLoading := true;
dsArticles.AppendFromJSONArrayString(Res.BodyAsString);
dsArticles.LoadFromJSONArrayString(Res.BodyAsString);
FLoading := false;
dsArticles.First;
finally
@ -129,9 +129,7 @@ var
begin
Res := Clt.doGET('/articles', [DataSet.FieldByName('id').AsString]);
FLoading := true;
DataSet.Edit;
DataSet.LoadFromJSONObjectString(Res.BodyAsString);
DataSet.Post;
FLoading := false;
end;
@ -149,7 +147,7 @@ procedure TMainForm.ShowError(const AResponse: IRESTResponse);
begin
MessageDlg(
AResponse.ResponseCode.ToString + ': ' + AResponse.ResponseText + sLineBreak +
AResponse.BodyAsJsonObject.Get('message').JsonValue.Value,
AResponse.BodyAsString,
mtError, [mbOK], 0);
end;

View File

@ -2,7 +2,8 @@ program articles_crud_vcl_client;
uses
Vcl.Forms,
MainFormU in 'MainFormU.pas' {MainForm};
MainFormU in 'MainFormU.pas' {MainForm},
MVCFramework.Serializer.Defaults in '..\..\sources\MVCFramework.Serializer.Defaults.pas';
{$R *.res}

View File

@ -100,6 +100,7 @@
<Form>MainForm</Form>
<FormType>dfm</FormType>
</DCCReference>
<DCCReference Include="..\..\sources\MVCFramework.Serializer.Defaults.pas"/>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
@ -128,19 +129,24 @@
</Excluded_Packages>
</Delphi.Personality>
<Deployment Version="3">
<DeployClass Name="ProjectiOSDeviceResourceRules">
<Platform Name="iOSDevice64">
<DeployFile LocalName="Win32\Debug\articles_crud_vcl_client.exe" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>articles_crud_vcl_client.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXResource">
<Platform Name="OSX32">
<RemoteDir>Contents\Resources</RemoteDir>
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClassesDexFile">
<Platform Name="Android">
@ -148,239 +154,372 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon144">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="Win32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeMipsFile">
<Platform Name="Android">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch768">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
<Platform Name="Linux64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyFramework">
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="ProjectUWPManifest">
<Platform Name="Win32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeX86File"/>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1024">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch320">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSInfoPList">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiFile">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1536">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage470">
<Platform Name="Android">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage640">
<Platform Name="Android">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640x1136">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo44">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSEntitlements">
<Platform Name="iOSDevice64">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidGDBServer">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiFile">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeMipsFile">
<Platform Name="Android">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeX86File"/>
<DeployClass Name="AndroidServiceOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashImageDef">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStyles">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon144">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage426">
<Platform Name="Android">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage470">
<Platform Name="Android">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage640">
<Platform Name="Android">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage960">
<Platform Name="Android">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyFramework">
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyModule">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="DependencyPackage">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="File">
<Platform Name="Android">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\Resources\StartUp\</RemoteDir>
<Operation>0</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1024">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1536">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch768">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch320">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640x1136">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectAndroidManifest">
<Platform Name="Android">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice32">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceResourceRules">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSEntitlements">
<Platform Name="iOSDevice32">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSInfoPList">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXEntitlements">
<Platform Name="OSX32">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXInfoPList">
<Platform Name="OSX32">
<RemoteDir>Contents</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXEntitlements">
<DeployClass Name="ProjectOSXResource">
<Platform Name="OSX32">
<RemoteDir>..\</RemoteDir>
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="Linux64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectUWPManifest">
<Platform Name="Win32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<Operation>1</Operation>
</Platform>
</DeployClass>
@ -394,146 +533,14 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStyles">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage426">
<Platform Name="Android">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashImageDef">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectAndroidManifest">
<Platform Name="Android">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="File">
<DeployClass Name="UWP_DelphiLogo44">
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\Resources\StartUp\</RemoteDir>
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>0</Operation>
</Platform>
<Platform Name="Android">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="DependencyPackage">
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage960">
<Platform Name="Android">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyModule">
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
</DeployClass>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>

View File

@ -0,0 +1,354 @@
unit MVCFramework.DataSet.Utils;
interface
uses System.SysUtils, Data.DB, System.Generics.Collections, System.JSON,
System.Rtti, JsonDataObjects;
type
TFieldNamePolicy = (fpLowerCase, fpUpperCase, fpAsIs);
TDataSetHelper = class helper for TDataSet
public
function AsJSONArray: String;
function AsJSONArrayString: string; deprecated 'Use AsJSONArray';
function AsJSONObject(AFieldNamePolicy: TFieldNamePolicy = fpLowerCase): String;
function AsJSONObjectString: string; deprecated 'Use AsJSONObject';
procedure LoadFromJSONObject(AJSONObject: TJSONObject;
AFieldNamePolicy: TFieldNamePolicy = fpLowerCase); overload;
procedure LoadFromJSONObject(AJSONObject: TJSONObject;
AIgnoredFields: TArray<string>;
AFieldNamePolicy: TFieldNamePolicy = fpLowerCase); overload;
procedure LoadFromJSONArray(AJSONArray: String;
AFieldNamePolicy: TFieldNamePolicy = TFieldNamePolicy.
fpLowerCase); overload;
procedure LoadFromJSONArrayString(AJSONArrayString: string;
AIgnoredFields: TArray<string>; AFieldNamePolicy: TFieldNamePolicy = TFieldNamePolicy.fpLowerCase); overload;
procedure LoadFromJSONArrayString(AJSONArrayString: string;
AFieldNamePolicy: TFieldNamePolicy = TFieldNamePolicy.fpLowerCase); overload;
procedure LoadFromJSONArray(AJSONArray: TJSONArray;
AIgnoredFields: TArray<string>; AFieldNamePolicy: TFieldNamePolicy = TFieldNamePolicy.fpLowerCase); overload;
procedure LoadFromJSONObjectString(AJSONObjectString: string); overload;
procedure LoadFromJSONObjectString(AJSONObjectString: string;
AIgnoredFields: TArray<string>); overload;
procedure AppendFromJSONArrayString(AJSONArrayString: string); overload;
procedure AppendFromJSONArrayString(AJSONArrayString: string;
AIgnoredFields: TArray<string>; AFieldNamePolicy: TFieldNamePolicy = TFieldNamePolicy.fpLowerCase); overload;
function AsObjectList<T: class, constructor>(CloseAfterScroll
: boolean = false): TObjectList<T>;
function AsObject<T: class, constructor>(CloseAfterScroll
: boolean = false): T;
end;
TDataSetUtils = class sealed
private
class var CTX: TRttiContext;
public
class constructor Create;
class destructor Destroy;
class procedure DataSetToObject(ADataSet: TDataSet; AObject: TObject);
class procedure DataSetToObjectList<T: class, constructor>
(ADataSet: TDataSet; AObjectList: TObjectList<T>;
ACloseDataSetAfterScroll: boolean = True);
end;
implementation
uses
MVCFramework.Serializer.Commons,
MVCFramework.Serializer.JSONDataObjects,
MVCFramework.Serializer.Intf;
{ TDataSetHelper }
function TDataSetHelper.AsJSONArray: String;
var
lSerializer: IMVCSerializer;
begin
Result := '[]';
if not Eof then
begin
lSerializer := TMVCJsonDataObjectsSerializer.Create;
Result := lSerializer.SerializeDataSet(Self, [], ncLowerCase);
// TDataSetUtils.DataSetToJSONArray(Self, JArr, false);
end;
end;
function TDataSetHelper.AsJSONArrayString: string;
begin
Result := AsJSONArray;
end;
function TDataSetHelper.AsJSONObject(AFieldNamePolicy: TFieldNamePolicy): String;
var
lSerializer: IMVCSerializer;
begin
lSerializer := TMVCJsonDataObjectsSerializer.Create;
Result := lSerializer.SerializeDataSetRecord(Self, [], ncAsIs);
// Mapper.DataSetToJSONObject(Self, JObj, false);
end;
function TDataSetHelper.AsJSONObjectString: string;
begin
Result := AsJSONObject(fpLowerCase);
end;
function TDataSetHelper.AsObject<T>(CloseAfterScroll: boolean): T;
var
Obj: T;
begin
if not Self.Eof then
begin
Obj := T.Create;
try
TDataSetUtils.DataSetToObject(Self, Obj);
Result := Obj;
except
FreeAndNil(Obj);
raise;
end;
end
else
Result := nil;
end;
function TDataSetHelper.AsObjectList<T>(CloseAfterScroll: boolean): TObjectList<T>;
var
Objs: TObjectList<T>;
begin
Objs := TObjectList<T>.Create(True);
try
TDataSetUtils.DataSetToObjectList<T>(Self, Objs, CloseAfterScroll);
Result := Objs;
except
FreeAndNil(Objs);
raise;
end;
end;
procedure TDataSetHelper.LoadFromJSONArray(AJSONArray: String;
AFieldNamePolicy: TFieldNamePolicy);
var
lSerializer: IMVCSerializer;
begin
Self.DisableControls;
try
lSerializer := TMVCJsonDataObjectsSerializer.Create;
lSerializer.DeserializeDataSet(AJSONArray, Self, nil, ncAsIs);
// Mapper.JSONArrayToDataSet(AJSONArray, Self, TArray<string>.Create(), false,
// AFieldNamePolicy);
finally
Self.EnableControls;
end;
end;
procedure TDataSetHelper.LoadFromJSONArray(AJSONArray: TJSONArray;
AIgnoredFields: TArray<string>; AFieldNamePolicy: TFieldNamePolicy);
begin
Self.DisableControls;
try
raise Exception.Create('Not Implemented');
// Mapper.JSONArrayToDataSet(AJSONArray, Self, AIgnoredFields, false, AFieldNamePolicy);
finally
Self.EnableControls;
end;
end;
procedure TDataSetHelper.LoadFromJSONArrayString(AJSONArrayString: string;
AIgnoredFields: TArray<string>; AFieldNamePolicy: TFieldNamePolicy);
begin
AppendFromJSONArrayString(AJSONArrayString, AIgnoredFields, AFieldNamePolicy);
end;
procedure TDataSetHelper.LoadFromJSONArrayString(AJSONArrayString: string; AFieldNamePolicy: TFieldNamePolicy);
begin
AppendFromJSONArrayString(AJSONArrayString, TArray<String>.Create(), AFieldNamePolicy);
end;
procedure TDataSetHelper.AppendFromJSONArrayString(AJSONArrayString: string;
AIgnoredFields: TArray<string>; AFieldNamePolicy: TFieldNamePolicy);
// var
// JV: TJSONValue;
// lJArr: TJDOJsonArray;
begin
// raise Exception.Create('Not Implemented');
// lJArr := TJsonBaseObject.Parse(AJSONArrayString) as TJDOJsonArray;
LoadFromJSONArray(AJSONArrayString, AFieldNamePolicy);
// JV := TJSONObject.ParseJSONValue(AJSONArrayString);
// try
// if JV is TJSONArray then
// LoadFromJSONArray(TJSONArray(JV), AIgnoredFields, AFieldNamePolicy)
// else
// raise Exception.Create('Expected JSONArray in LoadFromJSONArrayString');
// finally
// JV.Free;
// end;
end;
procedure TDataSetHelper.AppendFromJSONArrayString(AJSONArrayString: string);
begin
AppendFromJSONArrayString(AJSONArrayString, TArray<string>.Create());
end;
procedure TDataSetHelper.LoadFromJSONObject(AJSONObject: TJSONObject;
AIgnoredFields: TArray<string>; AFieldNamePolicy: TFieldNamePolicy);
begin
raise Exception.Create('Not Implemented');
// Mapper.JSONObjectToDataSet(AJSONObject, Self, AIgnoredFields, false,
// AFieldNamePolicy);
end;
procedure TDataSetHelper.LoadFromJSONObjectString(AJSONObjectString: string;
AIgnoredFields: TArray<string>);
var
lSerializer: IMVCSerializer;
begin
lSerializer := TMVCJsonDataObjectsSerializer.Create;
lSerializer.DeserializeDataSetRecord(AJSONObjectString, Self, nil, ncAsIs);
// JV := TJSONObject.ParseJSONValue(AJSONObjectString);
// try
// if JV is TJSONObject then
// LoadFromJSONObject(TJSONObject(JV), AIgnoredFields)
// else
// raise EMapperException.Create
// ('Extected JSONObject in LoadFromJSONObjectString');
// finally
// JV.Free;
// end;
end;
procedure TDataSetHelper.LoadFromJSONObject(AJSONObject: TJSONObject;
AFieldNamePolicy: TFieldNamePolicy);
begin
LoadFromJSONObject(AJSONObject, TArray<string>.Create());
end;
procedure TDataSetHelper.LoadFromJSONObjectString(AJSONObjectString: string);
begin
LoadFromJSONObjectString(AJSONObjectString, TArray<string>.Create());
end;
{ TDataSetUtils }
class constructor TDataSetUtils.Create;
begin
TDataSetUtils.CTX := TRttiContext.Create;
end;
class procedure TDataSetUtils.DataSetToObject(ADataSet: TDataSet;
AObject: TObject);
var
_type: TRttiType;
_fields: TArray<TRttiProperty>;
_field: TRttiProperty;
_attribute: TCustomAttribute;
_dict: TDictionary<string, string>;
_keys: TDictionary<string, boolean>;
mf: MVCColumnAttribute;
field_name: string;
Value: TValue;
FoundAttribute: boolean;
FoundTransientAttribute: boolean;
begin
_dict := TDictionary<string, string>.Create();
_keys := TDictionary<string, boolean>.Create();
_type := CTX.GetType(AObject.ClassInfo);
_fields := _type.GetProperties;
for _field in _fields do
begin
FoundAttribute := false;
FoundTransientAttribute := false;
for _attribute in _field.GetAttributes do
begin
if _attribute is MVCColumnAttribute then
begin
FoundAttribute := True;
mf := MVCColumnAttribute(_attribute);
_dict.Add(_field.Name, mf.FieldName);
_keys.Add(_field.Name, mf.IsPK);
end
else if _attribute is MVCDoNotSerializeAttribute then
FoundTransientAttribute := True;
end;
if ((not FoundAttribute) and (not FoundTransientAttribute)) then
begin
_dict.Add(_field.Name, _field.Name);
_keys.Add(_field.Name, false);
end;
end;
for _field in _fields do
begin
if not _dict.TryGetValue(_field.Name, field_name) then
Continue;
case _field.PropertyType.TypeKind of
tkEnumeration: // tristan
begin
if _field.PropertyType.Handle = TypeInfo(boolean) then
begin
case ADataSet.FieldByName(field_name).DataType of
ftInteger, ftSmallint, ftLargeint:
begin
Value := (ADataSet.FieldByName(field_name).AsInteger = 1);
end;
ftBoolean:
begin
Value := ADataSet.FieldByName(field_name).AsBoolean;
end;
else
Continue;
end;
end;
end;
tkInteger:
Value := ADataSet.FieldByName(field_name).AsInteger;
tkInt64:
Value := ADataSet.FieldByName(field_name).AsLargeInt;
tkFloat:
Value := ADataSet.FieldByName(field_name).AsFloat;
tkString:
Value := ADataSet.FieldByName(field_name).AsString;
tkUString, tkWChar, tkLString, tkWString:
Value := ADataSet.FieldByName(field_name).AsWideString;
else
Continue;
end;
_field.SetValue(AObject, Value);
end;
_dict.Free;
_keys.Free;
end;
class procedure TDataSetUtils.DataSetToObjectList<T>(ADataSet: TDataSet;
AObjectList: TObjectList<T>; ACloseDataSetAfterScroll: boolean);
var
Obj: T;
SavedPosition: TArray<Byte>;
begin
ADataSet.DisableControls;
try
SavedPosition := ADataSet.Bookmark;
while not ADataSet.Eof do
begin
Obj := T.Create;
DataSetToObject(ADataSet, Obj);
AObjectList.Add(Obj);
ADataSet.Next;
end;
if ADataSet.BookmarkValid(SavedPosition) then
ADataSet.Bookmark := SavedPosition;
finally
ADataSet.EnableControls;
end;
if ACloseDataSetAfterScroll then
ADataSet.Close;
end;
class destructor TDataSetUtils.Destroy;
begin
CTX.Free;
end;
end.

View File

@ -0,0 +1,159 @@
unit MVCFramework.FireDAC.Utils;
interface
uses
FireDAC.Comp.Client, FireDAC.Stan.Param, System.Rtti;
type
TFireDACUtils = class sealed
private
class var CTX: TRttiContext;
class function InternalExecuteQuery(AQuery: TFDQuery; AObject: TObject;
WithResult: boolean): Int64;
public
class constructor Create;
class destructor Destroy;
class function ExecuteQueryNoResult(AQuery: TFDQuery;
AObject: TObject): Int64;
class procedure ExecuteQuery(AQuery: TFDQuery; AObject: TObject);
class procedure ObjectToParameters(AFDParams: TFDParams; AObject: TObject; AParamPrefix: string = '');
end;
implementation
uses
System.Generics.Collections,
Data.DB,
System.Classes,
MVCFramework.Serializer.Commons,
System.SysUtils;
{ TFireDACUtils }
class constructor TFireDACUtils.Create;
begin
TFireDACUtils.CTX := TRttiContext.Create;
end;
class destructor TFireDACUtils.Destroy;
begin
TFireDACUtils.CTX.Free;
end;
class procedure TFireDACUtils.ExecuteQuery(AQuery: TFDQuery; AObject: TObject);
begin
InternalExecuteQuery(AQuery, AObject, True);
end;
class function TFireDACUtils.ExecuteQueryNoResult(AQuery: TFDQuery;
AObject: TObject): Int64;
begin
Result := InternalExecuteQuery(AQuery, AObject, false);
end;
class procedure TFireDACUtils.ObjectToParameters(AFDParams: TFDParams;
AObject: TObject; AParamPrefix: string);
var
I: Integer;
pname: string;
_rttiType: TRttiType;
obj_fields: TArray<TRttiProperty>;
obj_field: TRttiProperty;
obj_field_attr: MVCColumnAttribute;
Map: TObjectDictionary<string, TRttiProperty>;
f: TRttiProperty;
fv: TValue;
PrefixLength: Integer;
function KindToFieldType(AKind: TTypeKind; AProp: TRttiProperty): TFieldType;
begin
case AKind of
tkInteger:
Result := ftInteger;
tkFloat:
begin // daniele teti 2014-05-23
if AProp.PropertyType.QualifiedName = 'System.TDate' then
Result := ftDate
else if AProp.PropertyType.QualifiedName = 'System.TDateTime' then
Result := ftDateTime
else if AProp.PropertyType.QualifiedName = 'System.TTime' then
Result := ftTime
else
Result := ftFloat;
end;
tkChar, tkString:
Result := ftString;
tkWChar, tkUString, tkLString, tkWString:
Result := ftWideString;
tkVariant:
Result := ftVariant;
tkArray:
Result := ftArray;
tkInterface:
Result := ftInterface;
tkInt64:
Result := ftLongWord;
else
Result := ftUnknown;
end;
end;
begin
PrefixLength := Length(AParamPrefix);
Map := TObjectDictionary<string, TRttiProperty>.Create;
try
if Assigned(AObject) then
begin
_rttiType := ctx.GetType(AObject.ClassType);
obj_fields := _rttiType.GetProperties;
for obj_field in obj_fields do
begin
if TMVCSerializerHelpful.HasAttribute<MVCColumnAttribute>(obj_field, obj_field_attr) then
begin
Map.Add(MVCColumnAttribute(obj_field_attr).FieldName.ToLower,
obj_field);
end
else
begin
Map.Add(obj_field.Name.ToLower, obj_field);
end
end;
end;
for I := 0 to AFDParams.Count - 1 do
begin
pname := AFDParams[I].Name.ToLower;
if pname.StartsWith(AParamPrefix, True) then
Delete(pname, 1, PrefixLength);
if Map.TryGetValue(pname, f) then
begin
fv := f.GetValue(AObject);
AFDParams[I].DataType := KindToFieldType(fv.Kind, f);
// DmitryG - 2014-03-28
AFDParams[I].Value := fv.AsVariant;
end
else
begin
AFDParams[I].Clear;
end;
end;
finally
Map.Free;
end
end;
class function TFireDACUtils.InternalExecuteQuery(AQuery: TFDQuery; AObject: TObject;
WithResult: boolean): Int64;
begin
ObjectToParameters(AQuery.Params, AObject);
Result := 0;
if WithResult then
AQuery.Open
else
begin
AQuery.ExecSQL;
Result := AQuery.RowsAffected;
end;
end;
end.

View File

@ -32,16 +32,9 @@ uses
System.Classes,
IdHTTP,
IdURI,
ObjectsMappers,
MVCFramework.Commons,
{$IF CompilerVersion < 27}
Data.DBXJSON,
{$ELSE}
System.JSON,
{$ENDIF}
MVCFramework.Serializer.Commons,
MVCFramework.DataSet.Utils,
IdMultipartFormData,
System.SysUtils,
Data.DB,
@ -49,7 +42,7 @@ uses
IdCompressorZLib,
IdSSLOpenSSL,
System.Generics.Collections,
System.StrUtils, Web.HTTPApp, IdCookie;
System.StrUtils, Web.HTTPApp, IdCookie, MVCFramework.Serializer.Intf;
type
ERESTClientException = class(Exception);
@ -91,9 +84,9 @@ type
function Body: TStream;
function BodyAsString: string;
function BodyAsJSONValue: TJSONValue;
function BodyAsJSONObject: TJSONObject;
function BodyAsJSONArray: TJSONArray;
// function BodyAsJSONValue: TJSONValue;
// function BodyAsJSONObject: TJSONObject;
// function BodyAsJSONArray: TJSONArray;
procedure UpdateResponseCode(const AResponseCode: Word);
procedure UpdateResponseText(const AResponseText: string);
@ -120,15 +113,15 @@ type
property HasError: Boolean read GetHasError write SetHasError;
end;
TJSONObjectResponseHelper = class helper for TJSONObject
public
function AsObject<T: class, constructor>(): T;
end;
// TJSONObjectResponseHelper = class helper for TJSONObject
// public
// function AsObject<T: class, constructor>(): T;
// end;
TJSONArrayResponseHelper = class helper for TJSONArray
public
function AsObjectList<T: class, constructor>(): TObjectList<T>;
end;
// TJSONArrayResponseHelper = class helper for TJSONArray
// public
// function AsObjectList<T: class, constructor>(): TObjectList<T>;
// end;
TRESTClient = class(TInterfacedObject)
strict private
@ -167,6 +160,8 @@ type
procedure SetSessionID(const AValue: string);
procedure SetProxyServer(const AValue: string);
procedure SetProxyPort(const AValue: Integer);
private
FSerializer: IMVCSerializer;
strict protected
procedure HandleRequestCookies();
procedure HandleCookies(aCookies: TIdCookies;
@ -229,45 +224,33 @@ type
: IRESTResponse; overload;
function doPOST(const ABody: string): IRESTResponse; overload;
function doPOST(ABody: TJSONValue; const AOwnsBody: Boolean = True)
: IRESTResponse; overload;
function doPOST<TBodyType: class>(ABody: TBodyType;
const AOwnsBody: Boolean = True): IRESTResponse; overload;
function doPOST<TBodyType: class>(ABody: TObjectList<TBodyType>;
const AOwnsBody: Boolean = True): IRESTResponse; overload;
function doPOST(const AResource: string; const AParams: array of string)
: IRESTResponse; overload;
function doPOST(const AResource: string; const AParams: array of string;
ABody: TJSONValue; const AOwnsBody: Boolean = True)
: IRESTResponse; overload;
function doPOST(const AResource: string; const AParams: array of string;
function doPOST(
const AResource: string;
const AParams: array of string): IRESTResponse; overload;
function doPOST(
const AResource: string;
const AParams: array of string;
const ABody: string): IRESTResponse; overload;
function doPATCH(const ABody: string): IRESTResponse; overload;
function doPATCH(ABody: TJSONValue; const AOwnsBody: Boolean = True)
: IRESTResponse; overload;
function doPATCH<TBodyType: class>(ABody: TBodyType;
const AOwnsBody: Boolean = True): IRESTResponse; overload;
function doPATCH<TBodyType: class>(ABody: TObjectList<TBodyType>;
const AOwnsBody: Boolean = True): IRESTResponse; overload;
function doPATCH(const AResource: string; const AParams: array of string;
ABody: TJSONValue; const AOwnsBody: Boolean = True)
: IRESTResponse; overload;
function doPATCH(const AResource: string; const AParams: array of string;
const ABody: string): IRESTResponse; overload;
function doPUT(const ABody: string): IRESTResponse; overload;
function doPUT(ABody: TJSONValue; const AOwnsBody: Boolean = True)
: IRESTResponse; overload;
function doPUT<TBodyType: class>(ABody: TBodyType;
const AOwnsBody: Boolean = True): IRESTResponse; overload;
function doPUT<TBodyType: class>(ABody: TObjectList<TBodyType>;
const AOwnsBody: Boolean = True): IRESTResponse; overload;
function doPUT(const AResource: string; const AParams: array of string)
: IRESTResponse; overload;
function doPUT(const AResource: string; const AParams: array of string;
ABody: TJSONValue; const AOwnsBody: Boolean = True)
: IRESTResponse; overload;
function doPUT(const AResource: string; const AParams: array of string;
const ABody: string): IRESTResponse; overload;
@ -315,16 +298,18 @@ type
implementation
{$IFNDEF ANDROID OR IOS}
{$IF CompilerVersion > 30}
uses
System.AnsiStrings;
{$ENDIF}
{$ENDIF}
MVCFramework.Serializer.Defaults
{$IFNDEF ANDROID OR IOS}
{$IF CompilerVersion > 30}
, System.AnsiStrings
{$ENDIF}
{$ENDIF}
;
type
TRESTResponse = class(TInterfacedObject, IRESTResponse)
@ -333,7 +318,7 @@ type
FResponseCode: Word;
FResponseText: string;
FHeaders: TStringlist;
FBodyAsJSONValue: TJSONValue;
// FBodyAsJSONValue: TJSONValue;
FContentType: string;
FContentEncoding: string;
function GetHeader(const AValue: string): string;
@ -358,9 +343,9 @@ type
function Body(): TStream;
function BodyAsString(): string;
function BodyAsJSONValue(): TJSONValue;
function BodyAsJSONObject(): TJSONObject;
function BodyAsJSONArray(): TJSONArray;
// function BodyAsJSONValue(): TJSONValue;
// function BodyAsJSONObject(): TJSONObject;
// function BodyAsJSONArray(): TJSONArray;
procedure UpdateResponseCode(const AResponseCode: Word);
procedure UpdateResponseText(const AResponseText: string);
@ -389,39 +374,6 @@ begin
Result := FBody;
end;
function TRESTResponse.BodyAsJSONArray: TJSONArray;
begin
Result := BodyAsJSONValue as TJSONArray;
end;
function TRESTResponse.BodyAsJSONObject: TJSONObject;
begin
Result := BodyAsJSONValue as TJSONObject;
end;
function TRESTResponse.BodyAsJSONValue: TJSONValue;
begin
try
if not Assigned(FBodyAsJSONValue) then
begin
if (BodyAsString = '') then
FBodyAsJSONValue := nil
else
begin
try
FBodyAsJSONValue := TJSONObject.ParseJSONValue(BodyAsString);
except
FBodyAsJSONValue := nil;
end;
end;
end;
Result := FBodyAsJSONValue;
except
on E: Exception do
raise ERESTClientException.Create(E.Message);
end;
end;
function TRESTResponse.BodyAsString: string;
var
ss: TStringStream;
@ -453,14 +405,14 @@ begin
FHeaders := TStringlist.Create;
FCookies := TIdCookies.Create(nil);
FBody := TStringStream.Create('', TEncoding.UTF8);
FBodyAsJSONValue := nil;
// FBodyAsJSONValue := nil;
FHasError := False;
end;
destructor TRESTResponse.Destroy;
begin
if Assigned(FBodyAsJSONValue) then
FreeAndNil(FBodyAsJSONValue);
// if Assigned(FBodyAsJSONValue) then
// FreeAndNil(FBodyAsJSONValue);
FreeAndNil(FHeaders);
FreeAndNil(FBody);
FreeAndNil(FCookies);
@ -469,12 +421,16 @@ begin
end;
function TRESTResponse.Error: TMVCExceptionObj;
var
lSerializer: IMVCSerializer;
begin
if not FHasError then
Exit(nil);
if not Assigned(FErrorObject) then
begin
FErrorObject := Mapper.JSONObjectToObject<TMVCExceptionObj>(self.BodyAsJSONObject);
FErrorObject := TMVCExceptionObj.Create;
lSerializer := GetDefaultSerializer;
lSerializer.DeserializeObject(Self.BodyAsString, FErrorObject);
end;
Result := FErrorObject;
end;
@ -613,17 +569,28 @@ end;
{ TJSONObjectResponseHelper }
function TJSONObjectResponseHelper.AsObject<T>: T;
begin
Result := Mapper.JSONObjectToObject<T>(self);
end;
//function TJSONObjectResponseHelper.AsObject<T>: T;
//var
// lSerializer: IMVCSerializer;
//begin
// lSerializer := GetDefaultSerializer;
// Result := T.Create;
// try
// lSerializer.DeserializeObject(Self.ToJSON, Result);
// except
// FreeAndNil(Result);
// raise;
// end;
// // Result := Mapper.JSONObjectToObject<T>(self);
//end;
{ TJSONArrayResponseHelper }
function TJSONArrayResponseHelper.AsObjectList<T>: TObjectList<T>;
begin
Result := Mapper.JSONArrayToObjectList<T>(self, False, True);
end;
//function TJSONArrayResponseHelper.AsObjectList<T>: TObjectList<T>;
//begin
// raise Exception.Create('Not Implemented');
// // Result := Mapper.JSONArrayToObjectList<T>(self, False, True);
//end;
{ TRESTClient }
@ -716,10 +683,14 @@ begin
begin
if (FHTTP.Compressor <> nil) then
begin
{$HINTS OFF}
{$HINTS OFF}
FHTTP.Compressor.Free;
FHTTP.Compressor := nil;
{$HINTS ON}
{$HINTS ON}
end;
end;
Result := self;
@ -819,6 +790,8 @@ begin
FHTTP.HandleRedirects := True;
FHTTP.Request.CustomHeaders.FoldLines := False;
FHTTP.Request.BasicAuthentication := True;
FSerializer := GetDefaultSerializer;
end;
function TRESTClient.DataSetDelete(const AResource, AKeyValue: string)
@ -827,16 +800,15 @@ begin
Result := doDELETE(AResource, [AKeyValue]);
end;
function TRESTClient.DataSetInsert(const AResource: string; ADataSet: TDataSet)
: IRESTResponse;
function TRESTClient.DataSetInsert(const AResource: string; ADataSet: TDataSet): IRESTResponse;
begin
Result := doPOST(AResource, [], ADataSet.AsJSONObjectString);
Result := doPOST(AResource, [], ADataSet.AsJSONObject);
end;
function TRESTClient.DataSetUpdate(const AResource: string; ADataSet: TDataSet;
const AKeyValue: string): IRESTResponse;
begin
Result := doPUT(AResource, [AKeyValue], ADataSet.AsJSONObjectString);
Result := doPUT(AResource, [AKeyValue], ADataSet.AsJSONObject);
end;
destructor TRESTClient.Destroy;
@ -935,52 +907,6 @@ begin
ClearAllParams;
end;
function TRESTClient.doPOST(const AResource: string;
const AParams: array of string; ABody: TJSONValue; const AOwnsBody: Boolean)
: IRESTResponse;
begin
if not Assigned(ABody) then
raise ERESTClientException.Create('ABody is nil JSONValue');
try
Result := doPOST(AResource, AParams,
{$IF CompilerVersion >= 28}
ABody.ToJSON
{$ELSE}
ABody.ToString
{$ENDIF});
finally
if AOwnsBody then
FreeAndNil(ABody);
end;
end;
function TRESTClient.doPATCH(const AResource: string;
const AParams: array of string; ABody: TJSONValue; const AOwnsBody: Boolean)
: IRESTResponse;
begin
if not Assigned(ABody) then
raise ERESTClientException.Create('ABody is nil JSONValue');
try
Result := doPATCH(AResource, AParams,
{$IF CompilerVersion >= 28}
ABody.ToJSON
{$ELSE}
ABody.ToString
{$ENDIF});
finally
if AOwnsBody then
FreeAndNil(ABody);
end;
end;
function TRESTClient.doPATCH(const AResource: string;
const AParams: array of string; const ABody: string): IRESTResponse;
var
@ -1013,18 +939,6 @@ begin
Result := doPATCH(FResource, FParams, ABody);
end;
function TRESTClient.doPATCH(ABody: TJSONValue; const AOwnsBody: Boolean)
: IRESTResponse;
begin
if (FResource = '') then
raise ERESTClientException.Create('You must enter the Resource!');
if not Assigned(ABody) then
raise ERESTClientException.Create('You must enter the Body!');
Result := doPATCH(FResource, FParams, ABody, AOwnsBody);
end;
function TRESTClient.doPATCH<TBodyType>(ABody: TBodyType;
const AOwnsBody: Boolean): IRESTResponse;
begin
@ -1034,8 +948,7 @@ begin
if not Assigned(ABody) then
raise ERESTClientException.Create('You must enter the Body!');
Result := doPATCH(FResource, FParams, Mapper.ObjectToJSONObject(ABody)
as TJSONValue, True);
Result := doPATCH(FResource, FParams, FSerializer.SerializeObject(ABody));
if AOwnsBody then
TObject(ABody).Free;
@ -1051,9 +964,7 @@ begin
raise ERESTClientException.Create('You must enter the Body!');
ABody.OwnsObjects := AOwnsBody;
Result := doPATCH(FResource, FParams, Mapper.ObjectListToJSONArray<TBodyType>
(ABody, AOwnsBody) as TJSONValue, True);
Result := doPATCH(FResource, FParams, FSerializer.SerializeCollection(ABody));
end;
function TRESTClient.doPOST(const AResource: string;
@ -1093,18 +1004,6 @@ begin
Result := doPOST(FResource, FParams, ABody);
end;
function TRESTClient.doPOST(ABody: TJSONValue; const AOwnsBody: Boolean)
: IRESTResponse;
begin
if (FResource = '') then
raise ERESTClientException.Create('You must enter the Resource!');
if not Assigned(ABody) then
raise ERESTClientException.Create('You must enter the Body!');
Result := doPOST(FResource, FParams, ABody, AOwnsBody);
end;
function TRESTClient.doPOST<TBodyType>(ABody: TBodyType;
const AOwnsBody: Boolean): IRESTResponse;
begin
@ -1114,8 +1013,7 @@ begin
if not Assigned(ABody) then
raise ERESTClientException.Create('You must enter the Body!');
Result := doPOST(FResource, FParams, Mapper.ObjectToJSONObject(ABody)
as TJSONValue, True);
Result := doPOST(FResource, FParams, FSerializer.SerializeObject(ABody));
if AOwnsBody then
TObject(ABody).Free;
@ -1132,8 +1030,7 @@ begin
ABody.OwnsObjects := AOwnsBody;
Result := doPOST(FResource, FParams, Mapper.ObjectListToJSONArray<TBodyType>
(ABody, AOwnsBody) as TJSONValue, True);
Result := doPOST(FResource, FParams, FSerializer.SerializeCollection(ABody));
end;
function TRESTClient.doPUT(const AResource: string;
@ -1146,29 +1043,6 @@ begin
ClearAllParams;
end;
function TRESTClient.doPUT(const AResource: string;
const AParams: array of string; ABody: TJSONValue; const AOwnsBody: Boolean)
: IRESTResponse;
begin
if not Assigned(ABody) then
raise ERESTClientException.Create('ABody is nil JSONValue');
try
Result := doPUT(AResource, AParams,
{$IF CompilerVersion >= 28}
ABody.ToJSON
{$ELSE}
ABody.ToString
{$ENDIF});
finally
if AOwnsBody then
FreeAndNil(ABody);
end;
end;
function TRESTClient.doPUT(const AResource: string;
const AParams: array of string; const ABody: string): IRESTResponse;
var
@ -1201,18 +1075,6 @@ begin
Result := doPUT(FResource, FParams, ABody);
end;
function TRESTClient.doPUT(ABody: TJSONValue; const AOwnsBody: Boolean)
: IRESTResponse;
begin
if (FResource = '') then
raise ERESTClientException.Create('You must enter the Resource!');
if not Assigned(ABody) then
raise ERESTClientException.Create('You must enter the Body!');
Result := doPUT(FResource, FParams, ABody, AOwnsBody);
end;
function TRESTClient.doPUT<TBodyType>(ABody: TBodyType;
const AOwnsBody: Boolean): IRESTResponse;
begin
@ -1222,8 +1084,7 @@ begin
if not Assigned(ABody) then
raise ERESTClientException.Create('You must enter the Body!');
Result := doPUT(FResource, FParams, Mapper.ObjectToJSONObject(ABody)
as TJSONValue, True);
Result := doPUT(FResource, FParams, FSerializer.SerializeObject(ABody));
if AOwnsBody then
TObject(ABody).Free;
@ -1240,8 +1101,7 @@ begin
ABody.OwnsObjects := AOwnsBody;
Result := doPUT(FResource, FParams, Mapper.ObjectListToJSONArray<TBodyType>
(ABody, AOwnsBody) as TJSONValue, True);
Result := doPUT(FResource, FParams, FSerializer.SerializeCollection(ABody));
end;
function TRESTClient.DSDelete(const AResource, AKeyValue: string)
@ -1529,11 +1389,17 @@ begin
begin
Result.HasError := True;
Result.Body.Write(UTF8Encode(E.ErrorMessage)[1],
{$IF CompilerVersion > 30}
{$IF CompilerVersion > 30}
ElementToCharLen(string(UTF8Encode(E.ErrorMessage)),
{$ELSE}
{$ELSE}
ElementToCharLen(UTF8Encode(E.ErrorMessage),
{$ENDIF}
{$ENDIF}
Length(E.ErrorMessage) * 2));
end
else
@ -1637,11 +1503,17 @@ begin
begin
Result.HasError := True;
Result.Body.Write(UTF8Encode(E.ErrorMessage)[1],
{$IF CompilerVersion > 30}
{$IF CompilerVersion > 30}
ElementToCharLen(string(UTF8Encode(E.ErrorMessage)),
{$ELSE}
{$ELSE}
ElementToCharLen(UTF8Encode(E.ErrorMessage),
{$ENDIF}
{$ENDIF}
Length(E.ErrorMessage) * 2));
end
else
@ -1698,10 +1570,14 @@ begin
begin
if (FHTTP.IOHandler <> nil) then
begin
{$HINTS OFF}
{$HINTS OFF}
FHTTP.IOHandler.Free;
FHTTP.IOHandler := nil;
{$HINTS ON}
{$HINTS ON}
end;
end;
Result := self;

View File

@ -161,6 +161,18 @@ type
property SerializationType: TMVCSerializationType read FSerializationType;
end;
MVCColumnAttribute = class(TCustomAttribute)
private
FFieldName: string;
FIsPK: boolean;
procedure SetFieldName(const Value: string);
procedure SetIsPK(const Value: boolean);
public
constructor Create(AFieldName: string; AIsPK: boolean = false);
property FieldName: string read FFieldName write SetFieldName;
property IsPK: boolean read FIsPK write SetIsPK;
end;
TMVCSerializerHelpful = record
private
{ private declarations }
@ -560,4 +572,23 @@ begin
FSerializationType := ASerializationType;
end;
{ MVCColumnAttribute }
constructor MVCColumnAttribute.Create(AFieldName: string; AIsPK: boolean);
begin
inherited Create;
FFieldName := AFieldName;
FIsPK := AIsPK;
end;
procedure MVCColumnAttribute.SetFieldName(const Value: string);
begin
FFieldName := Value;
end;
procedure MVCColumnAttribute.SetIsPK(const Value: boolean);
begin
FIsPK := Value;
end;
end.

View File

@ -0,0 +1,20 @@
unit MVCFramework.Serializer.Defaults;
interface
uses
MVCFramework.Serializer.Intf;
function GetDefaultSerializer: IMVCSerializer;
implementation
uses
MVCFramework.Serializer.JsonDataObjects;
function GetDefaultSerializer: IMVCSerializer;
begin
Result := TMVCJsonDataObjectsSerializer.Create;
end;
end.

View File

@ -272,40 +272,6 @@ type
PropertyName: string): boolean;
end;
TDataSetHelper = class helper for TDataSet
public
function AsJSONArray: TJSONArray;
function AsJSONArrayString: string;
function AsJSONObject(AReturnNilIfEOF: boolean = false;
AFieldNamePolicy: TFieldNamePolicy = fpLowerCase): TJSONObject;
function AsJSONObjectString(AReturnEmptyStringIfEOF
: boolean = false): string;
procedure LoadFromJSONObject(AJSONObject: TJSONObject;
AFieldNamePolicy: TFieldNamePolicy = fpLowerCase); overload;
procedure LoadFromJSONObject(AJSONObject: TJSONObject;
AIgnoredFields: TArray<string>;
AFieldNamePolicy: TFieldNamePolicy = fpLowerCase); overload;
procedure LoadFromJSONArray(AJSONArray: TJSONArray;
AFieldNamePolicy: TFieldNamePolicy = TFieldNamePolicy.
fpLowerCase); overload;
procedure LoadFromJSONArrayString(AJSONArrayString: string;
AIgnoredFields: TArray<string>; AFieldNamePolicy: TFieldNamePolicy = TFieldNamePolicy.fpLowerCase); overload;
procedure LoadFromJSONArrayString(AJSONArrayString: string;
AFieldNamePolicy: TFieldNamePolicy = TFieldNamePolicy.fpLowerCase); overload;
procedure LoadFromJSONArray(AJSONArray: TJSONArray;
AIgnoredFields: TArray<string>; AFieldNamePolicy: TFieldNamePolicy = TFieldNamePolicy.fpLowerCase); overload;
procedure LoadFromJSONObjectString(AJSONObjectString: string); overload;
procedure LoadFromJSONObjectString(AJSONObjectString: string;
AIgnoredFields: TArray<string>); overload;
procedure AppendFromJSONArrayString(AJSONArrayString: string); overload;
procedure AppendFromJSONArrayString(AJSONArrayString: string;
AIgnoredFields: TArray<string>; AFieldNamePolicy: TFieldNamePolicy = TFieldNamePolicy.fpLowerCase); overload;
function AsObjectList<T: class, constructor>(CloseAfterScroll
: boolean = false): TObjectList<T>;
function AsObject<T: class, constructor>(CloseAfterScroll
: boolean = false): T;
end;
MapperTransientAttribute = class(TCustomAttribute)
end;
@ -382,7 +348,7 @@ type
property name: string read GetName;
end;
MapperColumnAttribute = class(TCustomAttribute)
MapperColumnAttribute_DEPRECATED = class(TCustomAttribute)
private
FFieldName: string;
FIsPK: boolean;
@ -522,7 +488,7 @@ var
_rttiType: TRttiType;
obj_fields: TArray<TRttiProperty>;
obj_field: TRttiProperty;
obj_field_attr: MapperColumnAttribute;
obj_field_attr: MapperColumnAttribute_DEPRECATED;
Map: TObjectDictionary<string, TRttiProperty>;
f: TRttiProperty;
fv: TValue;
@ -535,9 +501,9 @@ begin
obj_fields := _rttiType.GetProperties;
for obj_field in obj_fields do
begin
if HasAttribute<MapperColumnAttribute>(obj_field, obj_field_attr) then
if HasAttribute<MapperColumnAttribute_DEPRECATED>(obj_field, obj_field_attr) then
begin
Map.Add(MapperColumnAttribute(obj_field_attr).FieldName, obj_field);
Map.Add(MapperColumnAttribute_DEPRECATED(obj_field_attr).FieldName, obj_field);
end
else
begin
@ -660,10 +626,10 @@ var
_type: TRttiType;
_fields: TArray<TRttiProperty>;
_field: TRttiProperty;
_attribute: MapperColumnAttribute;
_attribute: MapperColumnAttribute_DEPRECATED;
_dict: TDictionary<string, string>;
_keys: TDictionary<string, boolean>;
mf: MapperColumnAttribute;
mf: MapperColumnAttribute_DEPRECATED;
field_name: string;
Value: TValue;
ts: TTimeStamp;
@ -674,7 +640,7 @@ begin
_type := ctx.GetType(AObject.ClassInfo);
_fields := _type.GetProperties;
for _field in _fields do
if HasAttribute<MapperColumnAttribute>(_field, _attribute) then
if HasAttribute<MapperColumnAttribute_DEPRECATED>(_field, _attribute) then
begin
mf := _attribute;
_dict.Add(_field.Name, mf.FieldName);
@ -903,7 +869,7 @@ var
_attribute: TCustomAttribute;
_dict: TDictionary<string, string>;
_keys: TDictionary<string, boolean>;
mf: MapperColumnAttribute;
mf: MapperColumnAttribute_DEPRECATED;
field_name: string;
Value: TValue;
FoundAttribute: boolean;
@ -919,10 +885,10 @@ begin
FoundTransientAttribute := false;
for _attribute in _field.GetAttributes do
begin
if _attribute is MapperColumnAttribute then
if _attribute is MapperColumnAttribute_DEPRECATED then
begin
FoundAttribute := True;
mf := MapperColumnAttribute(_attribute);
mf := MapperColumnAttribute_DEPRECATED(_attribute);
_dict.Add(_field.Name, mf.FieldName);
_keys.Add(_field.Name, mf.IsPK);
end
@ -2835,7 +2801,7 @@ var
_rttiType: TRttiType;
obj_fields: TArray<TRttiProperty>;
obj_field: TRttiProperty;
obj_field_attr: MapperColumnAttribute;
obj_field_attr: MapperColumnAttribute_DEPRECATED;
Map: TObjectDictionary<string, TRttiProperty>;
f: TRttiProperty;
fv: TValue;
@ -2884,9 +2850,9 @@ begin
obj_fields := _rttiType.GetProperties;
for obj_field in obj_fields do
begin
if HasAttribute<MapperColumnAttribute>(obj_field, obj_field_attr) then
if HasAttribute<MapperColumnAttribute_DEPRECATED>(obj_field, obj_field_attr) then
begin
Map.Add(MapperColumnAttribute(obj_field_attr).FieldName.ToLower,
Map.Add(MapperColumnAttribute_DEPRECATED(obj_field_attr).FieldName.ToLower,
obj_field);
end
else
@ -2968,19 +2934,19 @@ end;
{ MappedField }
constructor MapperColumnAttribute.Create(AFieldName: string; AIsPK: boolean);
constructor MapperColumnAttribute_DEPRECATED.Create(AFieldName: string; AIsPK: boolean);
begin
inherited Create;
FFieldName := AFieldName;
FIsPK := AIsPK;
end;
procedure MapperColumnAttribute.SetFieldName(const Value: string);
procedure MapperColumnAttribute_DEPRECATED.SetFieldName(const Value: string);
begin
FFieldName := Value;
end;
procedure MapperColumnAttribute.SetIsPK(const Value: boolean);
procedure MapperColumnAttribute_DEPRECATED.SetIsPK(const Value: boolean);
begin
FIsPK := Value;
end;
@ -3038,207 +3004,7 @@ begin
end;
{ TDataSetHelper }
function TDataSetHelper.AsJSONArray: TJSONArray;
var
JArr: TJSONArray;
begin
JArr := TJSONArray.Create;
try
if not Eof then
Mapper.DataSetToJSONArray(Self, JArr, false);
Result := JArr;
except
FreeAndNil(JArr);
raise;
end;
end;
function TDataSetHelper.AsJSONArrayString: string;
var
Arr: TJSONArray;
begin
Arr := AsJSONArray;
try
{ .$IFDEF TOJSON }
Result := Arr.ToJSON;
{ .$ELSE }
// Result := Arr.ToString;
{ .$IFEND }
finally
Arr.Free;
end;
end;
function TDataSetHelper.AsJSONObject(AReturnNilIfEOF: boolean;
AFieldNamePolicy: TFieldNamePolicy): TJSONObject;
var
JObj: TJSONObject;
begin
JObj := TJSONObject.Create;
try
Mapper.DataSetToJSONObject(Self, JObj, false);
if AReturnNilIfEOF and (JObj.Size = 0) then
FreeAndNil(JObj);
Result := JObj;
except
FreeAndNil(JObj);
raise;
end;
end;
function TDataSetHelper.AsJSONObjectString(AReturnEmptyStringIfEOF
: boolean): string;
var
JObj: TJSONObject;
begin
JObj := AsJSONObject(True);
if not Assigned(JObj) then
begin
if AReturnEmptyStringIfEOF then
Result := ''
else
Result := '{}';
end
else
try
{ .$IFDEF TOJSON }
Result := JObj.ToJSON;
{ .$ELSE }
// Result := JObj.ToString
{ .$IFEND }
finally
JObj.Free;
end;
end;
function TDataSetHelper.AsObject<T>(CloseAfterScroll: boolean): T;
var
Obj: T;
begin
if not Self.Eof then
begin
Obj := T.Create;
try
Mapper.DataSetToObject(Self, Obj);
Result := Obj;
except
FreeAndNil(Obj);
raise;
end;
end
else
Result := nil;
end;
function TDataSetHelper.AsObjectList<T>(CloseAfterScroll: boolean)
: TObjectList<T>;
var
Objs: TObjectList<T>;
begin
Objs := TObjectList<T>.Create(True);
try
Mapper.DataSetToObjectList<T>(Self, Objs, CloseAfterScroll);
Result := Objs;
except
FreeAndNil(Objs);
raise;
end;
end;
procedure TDataSetHelper.LoadFromJSONArray(AJSONArray: TJSONArray;
AFieldNamePolicy: TFieldNamePolicy);
begin
Self.DisableControls;
try
Mapper.JSONArrayToDataSet(AJSONArray, Self, TArray<string>.Create(), false,
AFieldNamePolicy);
finally
Self.EnableControls;
end;
end;
procedure TDataSetHelper.LoadFromJSONArray(AJSONArray: TJSONArray;
AIgnoredFields: TArray<string>; AFieldNamePolicy: TFieldNamePolicy);
begin
Self.DisableControls;
try
Mapper.JSONArrayToDataSet(AJSONArray, Self, AIgnoredFields, false, AFieldNamePolicy);
finally
Self.EnableControls;
end;
end;
procedure TDataSetHelper.LoadFromJSONArrayString(AJSONArrayString: string;
AIgnoredFields: TArray<string>; AFieldNamePolicy: TFieldNamePolicy);
begin
AppendFromJSONArrayString(AJSONArrayString, AIgnoredFields, AFieldNamePolicy);
end;
procedure TDataSetHelper.LoadFromJSONArrayString(AJSONArrayString: string; AFieldNamePolicy: TFieldNamePolicy);
begin
AppendFromJSONArrayString(AJSONArrayString, TArray<String>.Create(), AFieldNamePolicy);
end;
procedure TDataSetHelper.AppendFromJSONArrayString(AJSONArrayString: string;
AIgnoredFields: TArray<string>; AFieldNamePolicy: TFieldNamePolicy);
var
JV: TJSONValue;
begin
JV := TJSONObject.ParseJSONValue(AJSONArrayString);
try
if JV is TJSONArray then
LoadFromJSONArray(TJSONArray(JV), AIgnoredFields, AFieldNamePolicy)
else
raise EMapperException.Create
('Expected JSONArray in LoadFromJSONArrayString');
finally
JV.Free;
end;
end;
procedure TDataSetHelper.AppendFromJSONArrayString(AJSONArrayString: string);
begin
AppendFromJSONArrayString(AJSONArrayString, TArray<string>.Create());
end;
procedure TDataSetHelper.LoadFromJSONObject(AJSONObject: TJSONObject;
AIgnoredFields: TArray<string>; AFieldNamePolicy: TFieldNamePolicy);
begin
Mapper.JSONObjectToDataSet(AJSONObject, Self, AIgnoredFields, false,
AFieldNamePolicy);
end;
procedure TDataSetHelper.LoadFromJSONObjectString(AJSONObjectString: string;
AIgnoredFields: TArray<string>);
var
JV: TJSONValue;
begin
JV := TJSONObject.ParseJSONValue(AJSONObjectString);
try
if JV is TJSONObject then
LoadFromJSONObject(TJSONObject(JV), AIgnoredFields)
else
raise EMapperException.Create
('Extected JSONObject in LoadFromJSONObjectString');
finally
JV.Free;
end;
end;
procedure TDataSetHelper.LoadFromJSONObject(AJSONObject: TJSONObject;
AFieldNamePolicy: TFieldNamePolicy);
begin
LoadFromJSONObject(AJSONObject, TArray<string>.Create());
end;
procedure TDataSetHelper.LoadFromJSONObjectString(AJSONObjectString: string);
begin
LoadFromJSONObjectString(AJSONObjectString, TArray<string>.Create());
end;
{ MapperSerializeAsString }
{ MapperSerializeAsString }
constructor MapperSerializeAsString.Create(aEncoding: string);
begin

View File

@ -4,7 +4,7 @@
<ProjectVersion>18.2</ProjectVersion>
<FrameworkType>VCL</FrameworkType>
<Base>True</Base>
<Config Condition="'$(Config)'==''">SERVER_ON_LINUX</Config>
<Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>

View File

@ -53,12 +53,12 @@ type
procedure TestSerializeUsingFieldsWithNotExixtentPropetyInJSONObject;
procedure TestComplexObjectToJSONObjectAndBack;
procedure TestComplexObjectToJSONObjectAndBackWithNilReference;
procedure TestDataSetToJSONObject;
procedure TestDataSetToJSONObjectWithNulls;
procedure TestDataSetToJSONObjectFieldPolicyLowerCase;
procedure TestDataSetToJSONObjectFieldPolicyUpperCase;
procedure TestDataSetToJSONObjectFieldPolicyAsIsCase;
procedure TestDataSetToJSONArray;
// procedure TestDataSetToJSONObject;
// procedure TestDataSetToJSONObjectWithNulls;
// procedure TestDataSetToJSONObjectFieldPolicyLowerCase;
// procedure TestDataSetToJSONObjectFieldPolicyUpperCase;
// procedure TestDataSetToJSONObjectFieldPolicyAsIsCase;
// procedure TestDataSetToJSONArray;
procedure TestObjectToJSONObjectAndBackWithStringStreamUTF16;
procedure TestObjectToJSONObjectAndBackWithStringStreamUTF8;
procedure TestObjectToJSONObjectAndBackWithStream;
@ -379,191 +379,191 @@ begin
end;
end;
procedure TTestMappers.TestDataSetToJSONArray;
var
ds: TClientDataSet;
JObj: TJSONObject;
ds2: TClientDataSet;
JArr: TJSONArray;
begin
ds := TClientDataSet.Create(nil);
ds2 := TClientDataSet.Create(nil);
try
ds.LoadFromFile('..\..\fishes.xml');
ds.First;
// JArr := TJSONArray.Create;
JArr := ds.AsJSONArray;
try
// Mapper.DataSetToJSONArray(ds, JArr, false);
ds2.LoadFromFile('..\..\fishes.xml');
ds2.EmptyDataSet;
ds.First;
while not ds.Eof do
begin
ds2.Insert;
JObj := JArr.Get(ds.RecNo - 1) as TJSONObject;
ds2.LoadFromJSONObject(JObj);
// Mapper.JSONObjectToDataSet(JObj, ds2, false);
ds2.Post;
SameFishesDataSet(ds, ds2);
ds.Next;
end;
finally
JArr.Free;
end;
finally
ds.Free;
ds2.Free;
end;
end;
//procedure TTestMappers.TestDataSetToJSONArray;
//var
// ds: TClientDataSet;
// JObj: TJSONObject;
// ds2: TClientDataSet;
// JArr: TJSONArray;
//begin
// ds := TClientDataSet.Create(nil);
// ds2 := TClientDataSet.Create(nil);
// try
// ds.LoadFromFile('..\..\fishes.xml');
// ds.First;
// // JArr := TJSONArray.Create;
// JArr := ds.AsJSONArray;
// try
// // Mapper.DataSetToJSONArray(ds, JArr, false);
// ds2.LoadFromFile('..\..\fishes.xml');
// ds2.EmptyDataSet;
// ds.First;
// while not ds.Eof do
// begin
// ds2.Insert;
// JObj := JArr.Get(ds.RecNo - 1) as TJSONObject;
// ds2.LoadFromJSONObject(JObj);
// // Mapper.JSONObjectToDataSet(JObj, ds2, false);
// ds2.Post;
// SameFishesDataSet(ds, ds2);
// ds.Next;
// end;
// finally
// JArr.Free;
// end;
// finally
// ds.Free;
// ds2.Free;
// end;
//end;
procedure TTestMappers.TestDataSetToJSONObject;
var
ds: TClientDataSet;
JObj: TJSONObject;
ds2: TClientDataSet;
begin
ds := TClientDataSet.Create(nil);
ds2 := TClientDataSet.Create(nil);
try
ds.LoadFromFile('..\..\fishes.xml');
JObj := ds.AsJSONObject;
try
ds2.LoadFromFile('..\..\fishes.xml');
ds2.EmptyDataSet;
ds2.Insert;
ds2.LoadFromJSONObject(JObj);
ds2.Post;
SameFishesDataSet(ds, ds2);
finally
JObj.Free;
end;
finally
ds.Free;
ds2.Free;
end;
end;
//procedure TTestMappers.TestDataSetToJSONObject;
//var
// ds: TClientDataSet;
// JObj: TJSONObject;
// ds2: TClientDataSet;
//begin
// ds := TClientDataSet.Create(nil);
// ds2 := TClientDataSet.Create(nil);
// try
// ds.LoadFromFile('..\..\fishes.xml');
// JObj := ds.AsJSONObject;
// try
// ds2.LoadFromFile('..\..\fishes.xml');
// ds2.EmptyDataSet;
// ds2.Insert;
// ds2.LoadFromJSONObject(JObj);
// ds2.Post;
// SameFishesDataSet(ds, ds2);
// finally
// JObj.Free;
// end;
// finally
// ds.Free;
// ds2.Free;
// end;
//end;
procedure TTestMappers.TestDataSetToJSONObjectFieldPolicyAsIsCase;
var
ds: TClientDataSet;
JObj: TJSONObject;
ds2: TClientDataSet;
begin
ds := TClientDataSet.Create(nil);
ds2 := TClientDataSet.Create(nil);
try
ds.LoadFromFile('..\..\fishes.xml');
JObj := ds.AsJSONObject(false, fpAsIs);
try
ds2.LoadFromFile('..\..\fishes.xml');
ds2.EmptyDataSet;
ds2.Insert;
ds2.LoadFromJSONObject(JObj, fpAsIs);
ds2.Post;
SameFishesDataSet(ds, ds2);
finally
JObj.Free;
end;
finally
ds.Free;
ds2.Free;
end;
end;
//procedure TTestMappers.TestDataSetToJSONObjectFieldPolicyAsIsCase;
//var
// ds: TClientDataSet;
// JObj: TJSONObject;
// ds2: TClientDataSet;
//begin
// ds := TClientDataSet.Create(nil);
// ds2 := TClientDataSet.Create(nil);
// try
// ds.LoadFromFile('..\..\fishes.xml');
// JObj := ds.AsJSONObject(false, fpAsIs);
// try
// ds2.LoadFromFile('..\..\fishes.xml');
// ds2.EmptyDataSet;
// ds2.Insert;
// ds2.LoadFromJSONObject(JObj, fpAsIs);
// ds2.Post;
// SameFishesDataSet(ds, ds2);
// finally
// JObj.Free;
// end;
// finally
// ds.Free;
// ds2.Free;
// end;
//end;
procedure TTestMappers.TestDataSetToJSONObjectFieldPolicyLowerCase;
var
ds: TClientDataSet;
JObj: TJSONObject;
ds2: TClientDataSet;
begin
ds := TClientDataSet.Create(nil);
ds2 := TClientDataSet.Create(nil);
try
ds.LoadFromFile('..\..\fishes.xml');
JObj := ds.AsJSONObject(false, fpLowerCase);
try
ds2.LoadFromFile('..\..\fishes.xml');
ds2.EmptyDataSet;
ds2.Insert;
ds2.LoadFromJSONObject(JObj, fpLowerCase);
ds2.Post;
SameFishesDataSet(ds, ds2);
finally
JObj.Free;
end;
finally
ds.Free;
ds2.Free;
end;
end;
//procedure TTestMappers.TestDataSetToJSONObjectFieldPolicyLowerCase;
//var
// ds: TClientDataSet;
// JObj: TJSONObject;
// ds2: TClientDataSet;
//begin
// ds := TClientDataSet.Create(nil);
// ds2 := TClientDataSet.Create(nil);
// try
// ds.LoadFromFile('..\..\fishes.xml');
// JObj := ds.AsJSONObject(false, fpLowerCase);
// try
// ds2.LoadFromFile('..\..\fishes.xml');
// ds2.EmptyDataSet;
// ds2.Insert;
// ds2.LoadFromJSONObject(JObj, fpLowerCase);
// ds2.Post;
// SameFishesDataSet(ds, ds2);
// finally
// JObj.Free;
// end;
// finally
// ds.Free;
// ds2.Free;
// end;
//end;
//
//procedure TTestMappers.TestDataSetToJSONObjectFieldPolicyUpperCase;
//var
// ds: TClientDataSet;
// JObj: TJSONObject;
// ds2: TClientDataSet;
//begin
// ds := TClientDataSet.Create(nil);
// ds2 := TClientDataSet.Create(nil);
// try
// ds.LoadFromFile('..\..\fishes.xml');
// JObj := ds.AsJSONObject(false, fpUpperCase);
// try
// ds2.LoadFromFile('..\..\fishes.xml');
// ds2.EmptyDataSet;
// ds2.Insert;
// ds2.LoadFromJSONObject(JObj, fpUpperCase);
// ds2.Post;
// SameFishesDataSet(ds, ds2);
// finally
// JObj.Free;
// end;
// finally
// ds.Free;
// ds2.Free;
// end;
//end;
procedure TTestMappers.TestDataSetToJSONObjectFieldPolicyUpperCase;
var
ds: TClientDataSet;
JObj: TJSONObject;
ds2: TClientDataSet;
begin
ds := TClientDataSet.Create(nil);
ds2 := TClientDataSet.Create(nil);
try
ds.LoadFromFile('..\..\fishes.xml');
JObj := ds.AsJSONObject(false, fpUpperCase);
try
ds2.LoadFromFile('..\..\fishes.xml');
ds2.EmptyDataSet;
ds2.Insert;
ds2.LoadFromJSONObject(JObj, fpUpperCase);
ds2.Post;
SameFishesDataSet(ds, ds2);
finally
JObj.Free;
end;
finally
ds.Free;
ds2.Free;
end;
end;
procedure TTestMappers.TestDataSetToJSONObjectWithNulls;
var
ds: TClientDataSet;
JObj: TJSONObject;
begin
ds := TClientDataSet.Create(nil);
try
ds.FieldDefs.Add('string_value', ftString, 50);
ds.FieldDefs.Add('integer_value', ftInteger);
ds.FieldDefs.Add('float_value', ftFloat);
ds.FieldDefs.Add('null_value', ftString, 50);
ds.FieldDefs.Add('boolean_value', ftBoolean);
ds.CreateDataSet;
ds.Insert;
ds.FieldByName('string_value').AsString := 'myStringValue';
ds.FieldByName('integer_value').AsInteger := 123;
ds.FieldByName('float_value').AsFloat := 123.456;
ds.FieldByName('null_value').Clear;
ds.FieldByName('boolean_value').AsBoolean := true;
ds.Post;
JObj := ds.AsJSONObject;
try
CheckEquals('myStringValue', JObj.Values['string_value'].Value);
CheckEquals(123, JObj.Values['integer_value'].GetValue<TJSONNumber>().AsInt);
CheckEquals(123.456, JObj.Values['float_value'].GetValue<TJSONNumber>().AsDouble, 0.0009);
CheckTrue(JObj.Values['null_value'].GetValue<TJSONNull>().Null);
CheckEquals(true, JObj.Values['boolean_value'].GetValue<TJSONBool>().AsBoolean);
CheckTrue(JObj.ToJSON.Replace(' ', '').Contains('"null_value":null'));
ds.Insert;
ds.LoadFromJSONObject(JObj);
ds.Post;
CheckTrue(ds.FieldByName('null_value').IsNull);
finally
JObj.Free;
end;
finally
ds.Free;
end;
end;
//procedure TTestMappers.TestDataSetToJSONObjectWithNulls;
//var
// ds: TClientDataSet;
// JObj: TJSONObject;
//begin
// ds := TClientDataSet.Create(nil);
// try
// ds.FieldDefs.Add('string_value', ftString, 50);
// ds.FieldDefs.Add('integer_value', ftInteger);
// ds.FieldDefs.Add('float_value', ftFloat);
// ds.FieldDefs.Add('null_value', ftString, 50);
// ds.FieldDefs.Add('boolean_value', ftBoolean);
// ds.CreateDataSet;
// ds.Insert;
// ds.FieldByName('string_value').AsString := 'myStringValue';
// ds.FieldByName('integer_value').AsInteger := 123;
// ds.FieldByName('float_value').AsFloat := 123.456;
// ds.FieldByName('null_value').Clear;
// ds.FieldByName('boolean_value').AsBoolean := true;
// ds.Post;
// JObj := ds.AsJSONObject;
// try
// CheckEquals('myStringValue', JObj.Values['string_value'].Value);
// CheckEquals(123, JObj.Values['integer_value'].GetValue<TJSONNumber>().AsInt);
// CheckEquals(123.456, JObj.Values['float_value'].GetValue<TJSONNumber>().AsDouble, 0.0009);
// CheckTrue(JObj.Values['null_value'].GetValue<TJSONNull>().Null);
// CheckEquals(true, JObj.Values['boolean_value'].GetValue<TJSONBool>().AsBoolean);
// CheckTrue(JObj.ToJSON.Replace(' ', '').Contains('"null_value":null'));
// ds.Insert;
// ds.LoadFromJSONObject(JObj);
// ds.Post;
// CheckTrue(ds.FieldByName('null_value').IsNull);
// finally
// JObj.Free;
// end;
// finally
// ds.Free;
// end;
//end;
procedure TTestMappers.TestJSONArrayToObjectListNoGenerics;
var

View File

@ -212,6 +212,7 @@ begin
procedure(Response: IRESTResponse)
begin
try
{ TODO -oDaniele -cGeneral : Crea una unit con i metodi che mancano }
j := Response.BodyAsJsonObject.Clone as TJSONObject;
except
// test should not block...never!

View File

@ -7,6 +7,9 @@ uses
System.SysUtils,
IdHTTPWebBrokerBridge,
Web.WebReq,
{$IFNDEF LINUX}
Winapi.Windows,
{$ENDIF}
Web.WebBroker,
MVCFramework.Commons,
WebModuleUnit in 'WebModuleUnit.pas' {bas: TWebModule} ,

View File

@ -6,7 +6,7 @@
<MainSource>TestServer.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Linux64</Platform>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>129</TargetedPlatforms>
<AppType>Console</AppType>
</PropertyGroup>