From a42b2c0488b0ec2aeb3b2435e48a320576ec1024 Mon Sep 17 00:00:00 2001 From: viniciussanchez Date: Thu, 5 Sep 2019 22:18:19 -0300 Subject: [PATCH] Issue #24 --- samples/src/DataSet.Serialize.Samples.dfm | 568 ++++++++++++------ samples/src/DataSet.Serialize.Samples.pas | 23 + src/core/DataSet.Serialize.JSON.Impl.pas | 23 +- .../Providers.DataSet.Serialize.Constants.pas | 1 + 4 files changed, 425 insertions(+), 190 deletions(-) diff --git a/samples/src/DataSet.Serialize.Samples.dfm b/samples/src/DataSet.Serialize.Samples.dfm index c1f685f..01ec9d8 100644 --- a/samples/src/DataSet.Serialize.Samples.dfm +++ b/samples/src/DataSet.Serialize.Samples.dfm @@ -484,203 +484,348 @@ object FrmSamples: TFrmSamples object tabJSONNested: TTabSheet Caption = 'JSON Nested Object' ImageIndex = 2 - object Panel11: TPanel - Left = 241 + object PageControl1: TPageControl + Left = 0 Top = 0 - Width = 504 + Width = 986 Height = 543 + ActivePage = TabSheet1 Align = alClient - BevelOuter = bvNone TabOrder = 0 - object DBGrid2: TDBGrid - Left = 0 - Top = 0 - Width = 504 - Height = 112 - Align = alTop - DataSource = dsJSONNested - TabOrder = 0 - TitleFont.Charset = DEFAULT_CHARSET - TitleFont.Color = clWindowText - TitleFont.Height = -11 - TitleFont.Name = 'Tahoma' - TitleFont.Style = [] - Columns = < - item - Expanded = False - FieldName = 'PAIS' - Title.Caption = 'Pa'#237's' - Width = 406 - Visible = True + object TabSheet1: TTabSheet + Caption = 'TDataSetField - Samples 1' + ExplicitWidth = 281 + ExplicitHeight = 165 + object Panel11: TPanel + Left = 241 + Top = 0 + Width = 496 + Height = 515 + Align = alClient + BevelOuter = bvNone + TabOrder = 0 + ExplicitWidth = 504 + ExplicitHeight = 543 + object DBGrid2: TDBGrid + Left = 0 + Top = 0 + Width = 496 + Height = 112 + Align = alTop + DataSource = dsJSONNested + TabOrder = 0 + TitleFont.Charset = DEFAULT_CHARSET + TitleFont.Color = clWindowText + TitleFont.Height = -11 + TitleFont.Name = 'Tahoma' + TitleFont.Style = [] + Columns = < + item + Expanded = False + FieldName = 'PAIS' + Title.Caption = 'Pa'#237's' + Width = 406 + Visible = True + end + item + Expanded = False + FieldName = 'SIGLA' + Title.Caption = 'Sigla' + Width = 38 + Visible = True + end> end - item - Expanded = False - FieldName = 'SIGLA' - Title.Caption = 'Sigla' - Width = 38 - Visible = True - end> - end - object DBGrid3: TDBGrid - Left = 0 - Top = 112 - Width = 504 - Height = 209 - Align = alTop - DataSource = dsJSONNestedUF - TabOrder = 1 - TitleFont.Charset = DEFAULT_CHARSET - TitleFont.Color = clWindowText - TitleFont.Height = -11 - TitleFont.Name = 'Tahoma' - TitleFont.Style = [] - Columns = < - item - Expanded = False - FieldName = 'NOME' - Title.Caption = 'Nome' - Width = 406 - Visible = True + object DBGrid3: TDBGrid + Left = 0 + Top = 112 + Width = 496 + Height = 209 + Align = alTop + DataSource = dsJSONNestedUF + TabOrder = 1 + TitleFont.Charset = DEFAULT_CHARSET + TitleFont.Color = clWindowText + TitleFont.Height = -11 + TitleFont.Name = 'Tahoma' + TitleFont.Style = [] + Columns = < + item + Expanded = False + FieldName = 'NOME' + Title.Caption = 'Nome' + Width = 406 + Visible = True + end + item + Expanded = False + FieldName = 'SIGLA' + Title.Caption = 'UF' + Width = 38 + Visible = True + end> end - item - Expanded = False - FieldName = 'SIGLA' - Title.Caption = 'UF' - Width = 38 - Visible = True - end> - end - object DBGrid4: TDBGrid - Left = 0 - Top = 321 - Width = 504 - Height = 222 - Align = alClient - DataSource = dsJSONNEstedCity - TabOrder = 2 - TitleFont.Charset = DEFAULT_CHARSET - TitleFont.Color = clWindowText - TitleFont.Height = -11 - TitleFont.Name = 'Tahoma' - TitleFont.Style = [] - Columns = < - item - Expanded = False - FieldName = 'NOME' - Title.Caption = 'Nome' - Width = 300 - Visible = True + object DBGrid4: TDBGrid + Left = 0 + Top = 321 + Width = 496 + Height = 194 + Align = alClient + DataSource = dsJSONNEstedCity + TabOrder = 2 + TitleFont.Charset = DEFAULT_CHARSET + TitleFont.Color = clWindowText + TitleFont.Height = -11 + TitleFont.Name = 'Tahoma' + TitleFont.Style = [] + Columns = < + item + Expanded = False + FieldName = 'NOME' + Title.Caption = 'Nome' + Width = 300 + Visible = True + end + item + Expanded = False + FieldName = 'CEP' + Width = 144 + Visible = True + end> end - item - Expanded = False - FieldName = 'CEP' - Width = 144 - Visible = True - end> - end - end - object Panel14: TPanel - Left = 0 - Top = 0 - Width = 241 - Height = 543 - Align = alLeft - BevelOuter = bvNone - TabOrder = 1 - object mmJSONNested: TMemo - Left = 0 - Top = 33 - Width = 241 - Height = 510 - Align = alClient - Lines.Strings = ( - '{' - ' "pais": "Brasil",' - ' "sigla": "BRL",' - ' "estados": [' - ' {' - ' "nome": "S'#227'o Paulo",' - ' "sigla": "SP",' - ' "cidades": [' - ' {' - ' "nome": "Fernand'#243'polis",' - ' "cep": "15600-000"' - ' },' - ' {' - ' "nome": "Votuporanga",' - ' "cep": "12600-100"' - ' },' - ' {' - ' "nome": "Jales",' - ' "cep": "14859-000"' - ' },' - ' {' - ' "nome": "S'#227'o Jos'#233' do Rio Preto",' - ' "cep": "18450-450"' - ' },' - ' {' - ' "nome": "B'#225'lsamo",' - ' "cep": "15140-000"' - ' }' - ' ]' - ' },' - ' {' - ' "nome": "Paran'#225'",' - ' "sigla": "PR",' - ' "cidades": [' - ' {' - ' "nome": "Maring'#225'",' - ' "cep": "87050-000"' - ' },' - ' {' - ' "nome": "Londrina",' - ' "cep": "86010-190"' - ' }' - ' ]' - ' }' - ' ]' - '}') - ScrollBars = ssVertical - TabOrder = 0 - end - object Button10: TButton - Left = 0 - Top = 0 - Width = 241 - Height = 33 - Align = alTop - Caption = 'Load from JSON Array' - TabOrder = 1 - OnClick = Button10Click - end - end - object Panel15: TPanel - Left = 745 - Top = 0 - Width = 241 - Height = 543 - Align = alRight - BevelOuter = bvNone - TabOrder = 2 - object mmExportDataSetNested: TMemo - Left = 0 - Top = 33 - Width = 241 - Height = 510 - Align = alClient - ReadOnly = True - ScrollBars = ssVertical - TabOrder = 0 + end + object Panel14: TPanel + Left = 0 + Top = 0 + Width = 241 + Height = 515 + Align = alLeft + BevelOuter = bvNone + TabOrder = 1 + ExplicitHeight = 543 + object mmJSONNested: TMemo + Left = 0 + Top = 33 + Width = 241 + Height = 482 + Align = alClient + Lines.Strings = ( + '{' + ' "pais": "Brasil",' + ' "sigla": "BRL",' + ' "estados": [' + ' {' + ' "nome": "S'#227'o Paulo",' + ' "sigla": "SP",' + ' "cidades": [' + ' {' + ' "nome": "Fernand'#243'polis",' + ' "cep": "15600-000"' + ' },' + ' {' + ' "nome": "Votuporanga",' + ' "cep": "12600-100"' + ' },' + ' {' + ' "nome": "Jales",' + ' "cep": "14859-000"' + ' },' + ' {' + ' "nome": "S'#227'o Jos'#233' do Rio Preto",' + ' "cep": "18450-450"' + ' },' + ' {' + ' "nome": "B'#225'lsamo",' + ' "cep": "15140-000"' + ' }' + ' ]' + ' },' + ' {' + ' "nome": "Paran'#225'",' + ' "sigla": "PR",' + ' "cidades": [' + ' {' + ' "nome": "Maring'#225'",' + ' "cep": "87050-000"' + ' },' + ' {' + ' "nome": "Londrina",' + ' "cep": "86010-190"' + ' }' + ' ]' + ' }' + ' ]' + '}') + ScrollBars = ssVertical + TabOrder = 0 + ExplicitHeight = 510 + end + object Button10: TButton + Left = 0 + Top = 0 + Width = 241 + Height = 33 + Align = alTop + Caption = 'Load from JSON' + TabOrder = 1 + OnClick = Button10Click + end + end + object Panel15: TPanel + Left = 737 + Top = 0 + Width = 241 + Height = 515 + Align = alRight + BevelOuter = bvNone + TabOrder = 2 + ExplicitLeft = 745 + ExplicitHeight = 543 + object mmExportDataSetNested: TMemo + Left = 0 + Top = 33 + Width = 241 + Height = 482 + Align = alClient + ReadOnly = True + ScrollBars = ssVertical + TabOrder = 0 + ExplicitHeight = 510 + end + object Button11: TButton + Left = 0 + Top = 0 + Width = 241 + Height = 33 + Align = alTop + Caption = 'Export to JSON' + TabOrder = 1 + OnClick = Button11Click + end + end end - object Button11: TButton - Left = 0 - Top = 0 - Width = 241 - Height = 33 - Align = alTop - Caption = 'Export to JSON' - TabOrder = 1 - OnClick = Button11Click + object TabSheet2: TTabSheet + Caption = 'TDataSetField - Samples 2' + ImageIndex = 1 + ExplicitLeft = 0 + object Panel16: TPanel + Left = 0 + Top = 0 + Width = 241 + Height = 515 + Align = alLeft + BevelOuter = bvNone + TabOrder = 0 + ExplicitLeft = 8 + object mmDataSetField: TMemo + Left = 0 + Top = 33 + Width = 241 + Height = 482 + Align = alClient + Lines.Strings = ( + '[' + ' {' + ' "id": 1,' + ' "name": "Vinicius Sanchez",' + ' "array": [' + ' 1,' + ' 2,' + ' 3,' + ' 4' + ' ]' + ' },' + ' {' + ' "id": 2,' + ' "name": "Julio Cesar Senha",' + ' "array": [' + ' 1,' + ' 2' + ' ]' + ' },' + ' {' + ' "id": 3,' + ' "name": "Mateus Vicente",' + ' "array": [' + ' 1,' + ' 2,' + ' 3,' + ' 4,' + ' 5,' + ' 6' + ' ]' + ' }' + ']') + ScrollBars = ssVertical + TabOrder = 0 + end + object Button12: TButton + Left = 0 + Top = 0 + Width = 241 + Height = 33 + Align = alTop + Caption = 'Load from JSON' + TabOrder = 1 + OnClick = Button12Click + end + end + object Panel17: TPanel + Left = 241 + Top = 0 + Width = 737 + Height = 515 + Align = alClient + BevelOuter = bvNone + TabOrder = 1 + ExplicitTop = -3 + object DBGrid5: TDBGrid + Left = 0 + Top = 0 + Width = 737 + Height = 112 + Align = alTop + DataSource = dsNested + TabOrder = 0 + TitleFont.Charset = DEFAULT_CHARSET + TitleFont.Color = clWindowText + TitleFont.Height = -11 + TitleFont.Name = 'Tahoma' + TitleFont.Style = [] + Columns = < + item + Expanded = False + FieldName = 'ID' + Visible = True + end + item + Expanded = False + FieldName = 'NAME' + Width = 388 + Visible = True + end> + end + object DBGrid6: TDBGrid + Left = 0 + Top = 112 + Width = 737 + Height = 403 + Align = alClient + DataSource = dsChieldsArray + TabOrder = 1 + TitleFont.Charset = DEFAULT_CHARSET + TitleFont.Color = clWindowText + TitleFont.Height = -11 + TitleFont.Name = 'Tahoma' + TitleFont.Style = [] + Columns = < + item + Expanded = False + FieldName = 'VALUE' + Width = 102 + Visible = True + end> + end + end end end end @@ -816,4 +961,49 @@ object FrmSamples: TFrmSamples Left = 568 Top = 384 end + object dsChieldsArray: TDataSource + DataSet = mtChieldsArray + Left = 568 + Top = 320 + end + object mtChieldsArray: TFDMemTable + DataSetField = mtNestedARRAY + FetchOptions.AssignedValues = [evMode] + FetchOptions.Mode = fmAll + ResourceOptions.AssignedValues = [rvSilentMode] + ResourceOptions.SilentMode = True + UpdateOptions.AssignedValues = [uvCheckRequired, uvAutoCommitUpdates] + UpdateOptions.CheckRequired = False + UpdateOptions.AutoCommitUpdates = True + Left = 600 + Top = 320 + object mtChieldsArrayVALUE: TIntegerField + FieldName = 'VALUE' + end + end + object mtNested: TFDMemTable + FetchOptions.AssignedValues = [evMode] + FetchOptions.Mode = fmAll + ResourceOptions.AssignedValues = [rvSilentMode] + ResourceOptions.SilentMode = True + UpdateOptions.AssignedValues = [uvCheckRequired, uvAutoCommitUpdates] + UpdateOptions.CheckRequired = False + UpdateOptions.AutoCommitUpdates = True + Left = 600 + Top = 264 + object mtNestedID: TIntegerField + FieldName = 'ID' + end + object mtNestedNAME: TStringField + FieldName = 'NAME' + end + object mtNestedARRAY: TDataSetField + FieldName = 'ARRAY' + end + end + object dsNested: TDataSource + DataSet = mtNested + Left = 568 + Top = 264 + end end diff --git a/samples/src/DataSet.Serialize.Samples.pas b/samples/src/DataSet.Serialize.Samples.pas index f57a791..096535d 100644 --- a/samples/src/DataSet.Serialize.Samples.pas +++ b/samples/src/DataSet.Serialize.Samples.pas @@ -80,6 +80,23 @@ TFrmSamples = class(TForm) mtJSONNestedUFCIDADES: TDataSetField; mtJSONNestedCityNOME: TStringField; mtJSONNestedCityCEP: TStringField; + PageControl1: TPageControl; + TabSheet1: TTabSheet; + TabSheet2: TTabSheet; + Panel16: TPanel; + mmDataSetField: TMemo; + Button12: TButton; + dsChieldsArray: TDataSource; + mtChieldsArray: TFDMemTable; + mtNested: TFDMemTable; + dsNested: TDataSource; + mtNestedID: TIntegerField; + mtNestedNAME: TStringField; + mtNestedARRAY: TDataSetField; + Panel17: TPanel; + DBGrid5: TDBGrid; + DBGrid6: TDBGrid; + mtChieldsArrayVALUE: TIntegerField; procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure Button2Click(Sender: TObject); @@ -94,6 +111,7 @@ TFrmSamples = class(TForm) procedure Button9Click(Sender: TObject); procedure Button10Click(Sender: TObject); procedure Button11Click(Sender: TObject); + procedure Button12Click(Sender: TObject); private procedure Append; procedure ClearFields; @@ -137,6 +155,11 @@ procedure TFrmSamples.Button11Click(Sender: TObject); end; end; +procedure TFrmSamples.Button12Click(Sender: TObject); +begin + mtNested.LoadFromJSON(mmDataSetField.Lines.Text); +end; + procedure TFrmSamples.Button1Click(Sender: TObject); var LJSONArray: TJSONArray; diff --git a/src/core/DataSet.Serialize.JSON.Impl.pas b/src/core/DataSet.Serialize.JSON.Impl.pas index 3327ed0..2d2640c 100644 --- a/src/core/DataSet.Serialize.JSON.Impl.pas +++ b/src/core/DataSet.Serialize.JSON.Impl.pas @@ -57,6 +57,16 @@ TJSONSerialize = class /// procedure JSONObjectToDataSet(const AJSONObject: TJSONObject; const ADataSet: TDataSet; const AMerging: Boolean); /// + /// Loads a DataSet with a JSONOValue. + /// + /// + /// Refers to the JSON value that must be loaded in the DataSet. + /// + /// + /// Refers to the DataSet which must be loaded with the JSON value. + /// + procedure JSONValueToDataSet(const AJSONValue: TJSONValue; const ADataSet: TDataSet); + /// /// Loads a DataSet with a JSONArray. /// /// @@ -284,6 +294,15 @@ procedure TJSONSerialize.JSONObjectToDataSet(const AJSONObject: TJSONObject; con end; end; +procedure TJSONSerialize.JSONValueToDataSet(const AJSONValue: TJSONValue; const ADataSet: TDataSet); +begin + if ADataSet.Fields.Count <> 1 then + raise EDataSetSerializeException.Create(Format(INVALID_FIELD_COUNT, [ADataSet.Name])); + ADataSet.Append; + ADataSet.Fields.Fields[0].AsString := AJSONValue.Value; + ADataSet.Post; +end; + procedure TJSONSerialize.ToDataSet(const ADataSet: TDataSet); begin if Assigned(FJSONObject) then @@ -417,8 +436,10 @@ procedure TJSONSerialize.JSONArrayToDataSet(const AJSONArray: TJSONArray; const begin if (LJSONValue is TJSONArray) then JSONArrayToDataSet(LJSONValue as TJSONArray, ADataSet) + else if (LJSONValue is TJSONObject) then + JSONObjectToDataSet(LJSONValue as TJSONObject, ADataSet, False) else - JSONObjectToDataSet(LJSONValue as TJSONObject, ADataSet, False); + JSONValueToDataSet(LJSONValue, ADataSet); end; if ADataSet.Active then ADataSet.First; diff --git a/src/providers/Providers.DataSet.Serialize.Constants.pas b/src/providers/Providers.DataSet.Serialize.Constants.pas index 910cdea..8e67137 100644 --- a/src/providers/Providers.DataSet.Serialize.Constants.pas +++ b/src/providers/Providers.DataSet.Serialize.Constants.pas @@ -11,6 +11,7 @@ interface SIZE_NOT_DEFINED_FOR_FIELD = 'Size not defined for field "%s".'; TO_CONVERT_STRUCTURE_ONLY_JSON_ARRAY_ALLOWED = 'To convert a structure only JSONArray is allowed'; OBJECT_STATE = 'object_state'; + INVALID_FIELD_COUNT = '[%s] Invalid field count'; implementation