Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XE5+ changes #39

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/DataSetUtils.pas
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ interface
type
TDataSetUtils = class
public
class function CreateField(DataSet: TDataSet; FieldType: TFieldType; const FieldName: string = '';ASize: Integer=0): TField;
class function CreateField(DataSet: TDataSet; FieldType: TFieldType; const FieldName: string = '';ASize: Integer=0; const displayName: string=''): TField;
class function CreateDataSetField(DataSet: TDataSet; const FieldName: string): TDataSetField;
end;

Expand All @@ -21,19 +21,21 @@ class function TDataSetUtils.CreateDataSetField(DataSet: TDataSet;const FieldNam
end;

class function TDataSetUtils.CreateField(DataSet: TDataSet;
FieldType: TFieldType; const FieldName: string; ASize: Integer): TField;
FieldType: TFieldType; const FieldName: string; ASize: Integer; const displayName: string): TField;
begin
Result:= DefaultFieldClasses[FieldType].Create(DataSet);
Result.FieldName:= FieldName;
if Result.FieldName = '' then
Result.FieldName:= 'Field' + IntToStr(DataSet.FieldCount +1);
if(displayName <> '') then
result.DisplayLabel := displayName;
Result.FieldKind := fkData;
Result.DataSet:= DataSet;
Result.Name:= DataSet.Name + Result.FieldName;
Result.Size := ASize;

if (FieldType = ftString) and (ASize <= 0) then
raise Exception.CreateFmt('Size n�o definido para o campo "%s".',[FieldName]);
raise Exception.CreateFmt('Size não definido para o campo "%s".',[FieldName]);
end;

end.
110 changes: 89 additions & 21 deletions src/JsonToDataSetConverter.pas
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@ TJsonToDataSetConverter = class
class procedure SetFieldValue(AField: TField; AValue: ISuperObject);

class procedure ExtractFields(ADataSet: TDataSet; AObject: ISuperObject);
class procedure ExtractStructure(ADataSet: TDataSet; AObject: ISuperObject; tableNode, titleNode: string);

class function SuperTypeToFieldType(ASuperType: TSuperType): TFieldType;
class function SuperTypeToFieldSize(ASuperType: TSuperType): Integer;
public
class procedure UnMarshalToDataSet(ADataSet: TDataSet; AJson: string);overload;
class procedure UnMarshalToDataSet(ADataSet: TDataSet; AObject: ISuperObject);overload;
class procedure UnMarshalToDataSet(ADataSet: TClientDataSet; AJson: string);
class procedure ToDataSet(ADataSet: TClientDataSet; AObject: ISuperObject);

class function CreateDataSetMetadata(AJson: string): TClientDataSet; overload;
class function CreateDataSetMetadata(AObject: ISuperObject): TClientDataSet; overload;
class function CreateDataSetMetadata(AObject: ISuperObject; table, structure: string): TClientDataSet; overload;
end;

implementation
Expand Down Expand Up @@ -83,6 +85,26 @@ class function TJsonToDataSetConverter.CreateDataSetMetadata(AObject: ISuperObje
Result.CreateDataSet;
end;

class function TJsonToDataSetConverter.CreateDataSetMetadata(AObject: ISuperObject; table, structure: string): TClientDataSet;
var
vArray: TSuperArray;
begin
Result := TClientDataSet.Create(nil);

if AObject.IsType(stArray) then
begin
vArray := AObject.O[table].AsArray;

ExtractStructure(Result, AObject, table, structure);
end
else
begin
ExtractStructure(Result, AObject, table, structure);
end;
if Result.Fields.Count > 0 then
Result.CreateDataSet;
end;

class procedure TJsonToDataSetConverter.ExtractFields(ADataSet: TDataSet;AObject: ISuperObject);
var
vIterator: TSuperObjectIter;
Expand Down Expand Up @@ -114,32 +136,75 @@ class procedure TJsonToDataSetConverter.ExtractFields(ADataSet: TDataSet;AObject
end;
end;

class procedure TJsonToDataSetConverter.ExtractStructure(ADataSet: TDataSet; AObject: ISuperObject; tableNode, titleNode: string);

var
vIterator: TSuperObjectIter;
vNestedField: TDataSetField;
vArray: TSuperArray;
table: TSuperArray;
I: Integer;
begin
i:= 0;
table:= AObject.o[tableNode].AsArray;
if SuperObject.ObjectFindFirst(table[0], vIterator) then
begin
try
repeat
if (vIterator.val.IsType(stArray)) then
begin
vNestedField := TDataSetUtils.CreateDataSetField(ADataSet, vIterator.key);

vArray := vIterator.val.AsArray;
if (vArray.Length > 0) then
begin
ExtractFields(vNestedField.NestedDataSet, vArray[0]);
end;
end
else
begin
TDataSetUtils.CreateField(ADataSet, SuperTypeToFieldType(vIterator.val.DataType), vIterator.key,
SuperTypeToFieldSize(vIterator.val.DataType), AObject.o[titleNode].S[vIterator.key]);
end;
until not SuperObject.ObjectFindNext(vIterator);
finally
SuperObject.ObjectFindClose(vIterator);
end;
end;

end;

class procedure TJsonToDataSetConverter.SetFieldValue(AField: TField;AValue: ISuperObject);
var
vFieldName: string;
vNestedDataSet: TDataSet;
vNestedDataSet: TClientDataSet;
begin
vFieldName := AField.FieldName;
case AField.DataType of
ftSmallint, ftInteger, ftWord, ftLargeint: AField.AsInteger := AValue.AsInteger;
ftFloat, ftCurrency, ftBCD, ftFMTBcd: AField.AsFloat := AValue.AsDouble;
ftBoolean: AField.AsBoolean := AValue.AsBoolean;
ftDate, ftTime, ftDateTime, ftTimeStamp: AField.AsDateTime := AValue.AsDouble;
ftDataSet: begin
vNestedDataSet := TDataSetField(AField).NestedDataSet;

UnMarshalToDataSet(vNestedDataSet, AValue);
end;
else
AField.AsString := AValue.AsString;
end;
vFieldName := AField.FieldName;
if (AValue.IsType(stNull)) then
begin
vNestedDataSet := nil;
exit;
end;
case AField.DataType of
ftSmallint, ftInteger, ftWord, ftLargeint: AField.AsInteger := AValue.AsInteger;
ftFloat, ftCurrency, ftBCD, ftFMTBcd: AField.AsFloat := AValue.AsDouble;
ftBoolean: AField.AsBoolean := AValue.AsBoolean;
ftDate, ftTime, ftDateTime, ftTimeStamp: AField.AsDateTime := AValue.AsDouble;
ftDataSet: begin
vNestedDataSet := TClientDataSet( TDataSetField(AField).NestedDataSet);

ToDataSet(vNestedDataSet, AValue);
end;
else
AField.AsString := AValue.AsString;
end;
end;

class function TJsonToDataSetConverter.SuperTypeToFieldSize(ASuperType: TSuperType): Integer;
begin
Result := 0;

if (ASuperType = stString) then
if (ASuperType = stNull) or (ASuperType = stString) then // Some fields return as null
begin
Result := 255;
end;
Expand All @@ -155,16 +220,19 @@ class function TJsonToDataSetConverter.SuperTypeToFieldType(ASuperType: TSuperTy
stObject: Result := ftDataSet;
stArray: Result := ftDataSet;
stString: Result := ftString;
stNull: Result:= ftstring; // Rather than fail with an unknown type
else
Result := ftUnknown;
end;
end;

class procedure TJsonToDataSetConverter.UnMarshalToDataSet(ADataSet: TDataSet;AObject: ISuperObject);
class procedure TJsonToDataSetConverter.ToDataSet(ADataSet: TClientDataSet; AObject: ISuperObject);
var
i: Integer;
vArray: TSuperArray;
begin
if (ADataSet.FieldDefs.Count = 0) then // Check for whether any data is returned
EXIT;
ADataSet.DisableControls;
try
if AObject.IsType(stArray) then
Expand All @@ -187,13 +255,13 @@ class procedure TJsonToDataSetConverter.UnMarshalToDataSet(ADataSet: TDataSet;AO
ADataSet.First;
end;

class procedure TJsonToDataSetConverter.UnMarshalToDataSet(ADataSet: TDataSet; AJson: string);
class procedure TJsonToDataSetConverter.UnMarshalToDataSet(ADataSet: TClientDataSet; AJson: string);
var
AObject: ISuperObject;
begin
AObject := SuperObject.SO(AJson);

UnMarshalToDataSet(ADataSet, AObject);
ToDataSet(ADataSet, AObject);
end;

end.
Loading