From 349f43a5092b5c60ebd65cea9fb0a92d132bb278 Mon Sep 17 00:00:00 2001 From: mateusvicente100 Date: Tue, 20 Aug 2019 10:48:10 -0300 Subject: [PATCH] Validade Child Modifications --- src/core/DataSet.Serialize.DS.Impl.pas | 53 ++++++++++++--- src/core/DataSet.Serialize.JSON.Impl.pas | 86 +++++++++++++----------- 2 files changed, 88 insertions(+), 51 deletions(-) diff --git a/src/core/DataSet.Serialize.DS.Impl.pas b/src/core/DataSet.Serialize.DS.Impl.pas index d847b1a..10cd19d 100644 --- a/src/core/DataSet.Serialize.DS.Impl.pas +++ b/src/core/DataSet.Serialize.DS.Impl.pas @@ -35,7 +35,7 @@ TDataSetSerialize = class /// /// Invisible or null fields will not be exported. /// - function DataSetToJSONArray(const ADataSet: TDataSet): TJSONArray; + function DataSetToJSONArray(const ADataSet: TDataSet; const IsChild: Boolean = False): TJSONArray; /// /// Encrypts a blob field in Base64. /// @@ -46,6 +46,10 @@ TDataSetSerialize = class /// Returns a string with the cryptogrammed content in Base64. /// function EncodingBlobField(const AField: TField): string; + /// + /// Verifiy if a DataSet has detail dataset and if has child modification. + /// + function HasChildModification(const ADataSet: TDataSet): Boolean; public /// /// Responsible for creating a new isntāncia of TDataSetSerialize class. @@ -96,7 +100,7 @@ function TDataSetSerialize.ToJSONObject: TJSONObject; Result := DataSetToJSONObject(FDataSet); end; -function TDataSetSerialize.DataSetToJSONArray(const ADataSet: TDataSet): TJSONArray; +function TDataSetSerialize.DataSetToJSONArray(const ADataSet: TDataSet; const IsChild: Boolean): TJSONArray; var LBookMark: TBookmark; begin @@ -108,6 +112,12 @@ function TDataSetSerialize.DataSetToJSONArray(const ADataSet: TDataSet): TJSONAr ADataSet.First; while not ADataSet.Eof do begin + if IsChild and FOnlyUpdatedRecords then + if (ADataSet.UpdateStatus = TUpdateStatus.usUnmodified) and not(HasChildModification(ADataSet)) then + begin + ADataSet.Next; + Continue; + end; Result.AddElement(DataSetToJSONObject(ADataSet)); ADataSet.Next; end; @@ -179,16 +189,10 @@ function TDataSetSerialize.DataSetToJSONObject(const ADataSet: TDataSet): TJSONO begin LDataSetDetails := TList.Create; try - ADataSet.GetDetailDataSets(LDataSetDetails); + ADataSet.GetDetailDataSets(LDataSetDetails); for LNestedDataSet in LDataSetDetails do - begin - if (FOnlyUpdatedRecords) and (LNestedDataSet is TFDDataSet) then - TFDDataSet(LNestedDataSet).FilterChanges := [rtInserted, rtModified, rtDeleted]; if (LNestedDataSet.RecordCount > 0) then - Result.AddPair(LowerCase(TDataSetSerializeUtils.FormatDataSetName(LNestedDataSet.Name)), DataSetToJSONArray(LNestedDataSet)); - if (FOnlyUpdatedRecords) and (LNestedDataSet is TFDDataSet) then - TFDDataSet(LNestedDataSet).FilterChanges := [rtInserted, rtModified, rtUnmodified]; - end; + Result.AddPair(LowerCase(TDataSetSerializeUtils.FormatDataSetName(LNestedDataSet.Name)), DataSetToJSONArray(LNestedDataSet, True)); finally LDataSetDetails.Free; end; @@ -216,6 +220,35 @@ function TDataSetSerialize.EncodingBlobField(const AField: TField): string; end; end; +function TDataSetSerialize.HasChildModification(const ADataSet: TDataSet): Boolean; +var + LDataSetDetails: TList; + LNestedDataSet: TDataSet; +begin + Result := False; + LDataSetDetails := TList.Create; + try + ADataSet.GetDetailDataSets(LDataSetDetails); + for LNestedDataSet in LDataSetDetails do + begin + if not (LNestedDataSet is TFDDataSet) then + Continue; + try + TFDDataSet(LNestedDataSet).FilterChanges := [rtInserted, rtModified, rtDeleted]; + if (TFDDataSet(LNestedDataSet).RecordCount > 0) or HasChildModification(LNestedDataSet) then + begin + Result := True; + Break; + end; + finally + TFDDataSet(LNestedDataSet).FilterChanges := [rtInserted, rtModified, rtUnmodified]; + end; + end; + finally + LDataSetDetails.Free; + end; +end; + function TDataSetSerialize.SaveStructure: TJSONArray; var LField: TField; diff --git a/src/core/DataSet.Serialize.JSON.Impl.pas b/src/core/DataSet.Serialize.JSON.Impl.pas index 9695ed7..c38832d 100644 --- a/src/core/DataSet.Serialize.JSON.Impl.pas +++ b/src/core/DataSet.Serialize.JSON.Impl.pas @@ -199,7 +199,7 @@ procedure TJSONSerialize.JSONObjectToDataSet(const AJSONObject: TJSONObject; con begin if TUpdateStatus.usInserted.ToString.Equals(LObjectState) then ADataSet.Append - else + else if not TUpdateStatus.usUnmodified.ToString.Equals(LObjectState) then begin if not ADataSet.Locate(GetKeyFieldsDataSet(ADataSet), VarArrayOf(GetKeyValuesDataSet(ADataSet, AJSONObject)), []) then Exit; @@ -216,51 +216,55 @@ procedure TJSONSerialize.JSONObjectToDataSet(const AJSONObject: TJSONObject; con ADataSet.Edit else ADataSet.Append; - for LField in ADataSet.Fields do + + if (ADataSet.State in dsEditModes) then begin - if LField.ReadOnly then - Continue; - if not (AJSONObject.TryGetValue(LField.FieldName, LJSONValue) or AJSONObject.TryGetValue(LowerCase(LField.FieldName), LJSONValue)) then - Continue; - if LJSONValue is TJSONNull then + for LField in ADataSet.Fields do begin - LField.Clear; - Continue; - end; - case LField.DataType of - TFieldType.ftBoolean: - if LJSONValue.TryGetValue(LBooleanValue) then - LField.AsBoolean := LBooleanValue; - TFieldType.ftInteger, TFieldType.ftSmallint, TFieldType.ftShortint, TFieldType.ftLongWord: - LField.AsInteger := StrToIntDef(LJSONValue.Value, 0); - TFieldType.ftLargeint, TFieldType.ftAutoInc: - LField.AsLargeInt := StrToInt64Def(LJSONValue.Value, 0); - TFieldType.ftCurrency: - LField.AsCurrency := StrToCurr(LJSONValue.Value); - TFieldType.ftFloat, TFieldType.ftFMTBcd, TFieldType.ftBCD, TFieldType.ftSingle: - LField.AsFloat := StrToFloat(LJSONValue.Value); - TFieldType.ftString, TFieldType.ftWideString, TFieldType.ftMemo, TFieldType.ftWideMemo: - LField.AsString := LJSONValue.Value; - TFieldType.ftDate, TFieldType.ftTimeStamp, TFieldType.ftDateTime, TFieldType.ftTime: - LField.AsDateTime := ISO8601ToDate(LJSONValue.Value); - TFieldType.ftDataSet: - begin - LNestedDataSet := TDataSetField(LField).NestedDataSet; - if LJSONValue is TJSONObject then - JSONObjectToDataSet(LJSONValue as TJSONObject, LNestedDataSet, False) - else if LJSONValue is TJSONArray then + if LField.ReadOnly then + Continue; + if not (AJSONObject.TryGetValue(LField.FieldName, LJSONValue) or AJSONObject.TryGetValue(LowerCase(LField.FieldName), LJSONValue)) then + Continue; + if LJSONValue is TJSONNull then + begin + LField.Clear; + Continue; + end; + case LField.DataType of + TFieldType.ftBoolean: + if LJSONValue.TryGetValue(LBooleanValue) then + LField.AsBoolean := LBooleanValue; + TFieldType.ftInteger, TFieldType.ftSmallint, TFieldType.ftShortint, TFieldType.ftLongWord: + LField.AsInteger := StrToIntDef(LJSONValue.Value, 0); + TFieldType.ftLargeint, TFieldType.ftAutoInc: + LField.AsLargeInt := StrToInt64Def(LJSONValue.Value, 0); + TFieldType.ftCurrency: + LField.AsCurrency := StrToCurr(LJSONValue.Value); + TFieldType.ftFloat, TFieldType.ftFMTBcd, TFieldType.ftBCD, TFieldType.ftSingle: + LField.AsFloat := StrToFloat(LJSONValue.Value); + TFieldType.ftString, TFieldType.ftWideString, TFieldType.ftMemo, TFieldType.ftWideMemo: + LField.AsString := LJSONValue.Value; + TFieldType.ftDate, TFieldType.ftTimeStamp, TFieldType.ftDateTime, TFieldType.ftTime: + LField.AsDateTime := ISO8601ToDate(LJSONValue.Value); + TFieldType.ftDataSet: begin - ClearDataSet(LNestedDataSet); - JSONArrayToDataSet(LJSONValue as TJSONArray, LNestedDataSet); + LNestedDataSet := TDataSetField(LField).NestedDataSet; + if LJSONValue is TJSONObject then + JSONObjectToDataSet(LJSONValue as TJSONObject, LNestedDataSet, False) + else if LJSONValue is TJSONArray then + begin + ClearDataSet(LNestedDataSet); + JSONArrayToDataSet(LJSONValue as TJSONArray, LNestedDataSet); + end; end; - end; - TFieldType.ftGraphic, TFieldType.ftBlob, TFieldType.ftStream: - LoadBlobFieldFromStream(LField, LJSONValue); - else - raise EDataSetSerializeException.CreateFmt(FIELD_TYPE_NOT_FOUND, [LField.FieldName]); + TFieldType.ftGraphic, TFieldType.ftBlob, TFieldType.ftStream: + LoadBlobFieldFromStream(LField, LJSONValue); + else + raise EDataSetSerializeException.CreateFmt(FIELD_TYPE_NOT_FOUND, [LField.FieldName]); + end; end; - end; - ADataSet.Post; + ADataSet.Post; + end; LDataSetDetails := TList.Create; try ADataSet.GetDetailDataSets(LDataSetDetails);