superobject 序列數據集ui
unit uDBJson;code
interfacestring
{$HINTS OFF}it
uses SysUtils, Classes, Variants, DB, DBClient, SuperObject;io
type TTableJSon = classfunction
private const cstFieldType = 'FieldType';class
const cstFieldName = 'FieldName';object
const cstFieldSize = 'FieldSize';List
const cstJsonType = 'JsonType';im
const cstRequired = 'Required';
const cstFieldIndex = 'FieldIndex';
const cstCols = 'Cols';
const cstData = 'Data';
public class function DataSetToJson(DataSet: TDataSet): ISuperObject; class function DataSetToJson2(DataSet: TDataSet): string; class function CreateFieldByJson(Fields: TFieldDefs; ColsJson: ISuperObject): Boolean; class procedure ImportDataFromJSon(DataSet: TDataSet; DataJson: ISuperObject); class function JSonToClientDataset(CDS: TClientDataSet; Json: ISuperObject) : Boolean; class function GetValue(Json: ISuperObject; const Name: string): Variant;
class function CreateJsonValue(Json: ISuperObject; const Name: string; const Value: Variant): Boolean; class function CreateJsonValueByField(Json: ISuperObject; Field: TField): Boolean; class function GetValue2Field(Field: TField; JsonValue: ISuperObject): Variant;
end;
implementation
uses TypInfo, encddecd;
{ TTableJSon }
class function TTableJSon.JSonToClientDataset(CDS: TClientDataSet; Json: ISuperObject): Boolean; var ColsJson: ISuperObject; begin Result := False; if Json = nil then Exit; CDS.Close; CDS.Data := Null; // 建立字段 ColsJson := Json.O[cstCols]; CreateFieldByJson(CDS.FieldDefs, ColsJson); if CDS.FieldDefs.Count > 0 then CDS.CreateDataSet; ImportDataFromJSon(CDS, Json.O[cstData]); Result := True; end;
class function TTableJSon.CreateFieldByJson(Fields: TFieldDefs; ColsJson: ISuperObject): Boolean; var SubJson: ISuperObject; ft: TFieldType; begin Result := False; Fields.DataSet.Close; Fields.Clear; for SubJson in ColsJson do begin ft := TFieldType(GetEnumValue(TypeInfo(TFieldType), 'ft' + SubJson.S[cstFieldType])); if ft = ftAutoInc then // 自增字段不能錄入,必須更改 ft := ftInteger; Fields.Add(SubJson.S[cstFieldName], ft, SubJson.I[cstFieldSize], SubJson.B[cstRequired]); end; Result := True; end;
class function TTableJSon.CreateJsonValue(Json: ISuperObject; const Name: string; const Value: Variant): Boolean; begin Result := False; Json.O[Name] := SO(Value); Result := True; end;
class function TTableJSon.CreateJsonValueByField(Json: ISuperObject; Field: TField): Boolean; begin Result := False; if Field Is TDateTimeField then Json.O[Field.FieldName] := SO(Field.AsDateTime) else if Field is TBlobField then Json.S[Field.FieldName] := EncodeString(Field.AsString) else Json.O[Field.FieldName] := SO(Field.Value); Result := True; end;
class function TTableJSon.GetValue(Json: ISuperObject; const Name: string): Variant; begin case Json.DataType of stNull: Result := Null; stBoolean: Result := Json.B[Name]; stDouble: Result := Json.D[Name]; stCurrency: Result := Json.C[Name]; stInt: Result := Json.I[Name]; stString: Result := Json.S[Name]; end; end;
class function TTableJSon.GetValue2Field(Field: TField; JsonValue: ISuperObject): Variant; begin if JsonValue.DataType = stNull then Result := Null else if Field is TDateTimeField then Result := JavaToDelphiDateTime(JsonValue.AsInteger) else if (Field is TIntegerField) or (Field is TLargeintField) then Result := JsonValue.AsInteger else if Field is TNumericField then Result := JsonValue.AsDouble else if Field is TBooleanField then Result := JsonValue.AsBoolean else if Field is TStringField then Result := JsonValue.AsString else if Field is TBlobField then Result := DecodeString(JsonValue.AsString) end;
class procedure TTableJSon.ImportDataFromJSon(DataSet: TDataSet; DataJson: ISuperObject); var SubJson: ISuperObject; iter: TSuperObjectIter; begin if not DataSet.Active then DataSet.Open; DataSet.DisableControls; try for SubJson in DataJson do begin DataSet.Append; if ObjectFindFirst(SubJson, iter) then begin repeat if DataSet.FindField(iter.Ite.Current.Name) <> nil then DataSet.FindField(iter.Ite.Current.Name).Value := GetValue2Field(DataSet.FindField(iter.Ite.Current.Name), iter.Ite.Current.Value); until not ObjectFindNext(iter); end; DataSet.Post; end; finally DataSet.EnableControls; end; end;
class function TTableJSon.DataSetToJson(DataSet: TDataSet): ISuperObject; procedure GetFieldTypeInfo(Field: TField; var Fieldtyp, JsonTyp: string); begin Fieldtyp := GetEnumName(TypeInfo(TFieldType), ord(Field.DataType)); Delete(Fieldtyp, 1, 2); if Field is TStringField then JsonTyp := 'string' else if Field is TDateTimeField then JsonTyp := 'integer' else if (Field is TIntegerField) or (Field is TLargeintField) then JsonTyp := 'integer' else if Field is TCurrencyField then JsonTyp := 'currency' else if Field is TNumericField then JsonTyp := 'double' else if Field is TBooleanField then JsonTyp := 'boolean' else JsonTyp := 'variant'; end;
var sj, aj, sj2: ISuperObject; I: Integer; Fieldtyp, JsonTyp: string; List: TStringList; begin sj := SO(); // 建立列 aj := SA([]); List := TStringList.Create; try List.Sorted := True;
for I := 0 to DataSet.FieldCount - 1 do begin sj2 := SO(); GetFieldTypeInfo(DataSet.Fields[I], Fieldtyp, JsonTyp); sj2.S[cstFieldName] := DataSet.Fields[I].FieldName; sj2.S[cstFieldType] := Fieldtyp; sj2.S[cstJsonType] := JsonTyp; sj2.I[cstFieldSize] := DataSet.Fields[I].Size; sj2.B[cstRequired] := DataSet.Fields[I].Required; sj2.I[cstFieldIndex] := DataSet.Fields[I].Index; aj.AsArray.Add(sj2); List.Add(DataSet.Fields[I].FieldName + '=' + JsonTyp); end; sj.O['Cols'] := aj; // 建立數據集的數據 DataSet.DisableControls; DataSet.First; aj := SA([]); while not DataSet.Eof do begin sj2 := SO(); for I := 0 to DataSet.FieldCount - 1 do begin if VarIsNull(DataSet.Fields[I].Value) then sj2.O[DataSet.Fields[I].FieldName] := SO(Null) else begin CreateJsonValueByField(sj2, DataSet.Fields[I]); end; end; aj.AsArray.Add(sj2); DataSet.Next; end; sj.O['Data'] := aj; Result := sj;
finally List.Free; DataSet.EnableControls; end; end;
class function TTableJSon.DataSetToJson2(DataSet: TDataSet): string; procedure GetFieldTypeInfo(Field: TField; var Fieldtyp, JsonTyp: string); begin Fieldtyp := GetEnumName(TypeInfo(TFieldType), ord(Field.DataType)); Delete(Fieldtyp, 1, 2); if Field is TStringField then JsonTyp := 'string' else if Field is TDateTimeField then JsonTyp := 'integer' else if (Field is TIntegerField) or (Field is TLargeintField) then JsonTyp := 'integer' else if Field is TCurrencyField then JsonTyp := 'currency' else if Field is TNumericField then JsonTyp := 'double' else if Field is TBooleanField then JsonTyp := 'boolean' else JsonTyp := 'variant'; end;
var sj, aj, sj2: ISuperObject; I: Integer; Fieldtyp, JsonTyp: string; List: TStringList; begin sj := SO(); // 建立列 aj := SA([]); List := TStringList.Create; try List.Sorted := True;
for I := 0 to DataSet.FieldCount - 1 do begin sj2 := SO(); GetFieldTypeInfo(DataSet.Fields[I], Fieldtyp, JsonTyp); sj2.S[cstFieldName] := DataSet.Fields[I].FieldName; sj2.S[cstFieldType] := Fieldtyp; sj2.S[cstJsonType] := JsonTyp; sj2.I[cstFieldSize] := DataSet.Fields[I].Size; sj2.B[cstRequired] := DataSet.Fields[I].Required; sj2.I[cstFieldIndex] := DataSet.Fields[I].Index; aj.AsArray.Add(sj2); List.Add(DataSet.Fields[I].FieldName + '=' + JsonTyp); end; sj.O['Cols'] := aj; // 建立數據集的數據 DataSet.DisableControls; DataSet.First; aj := SA([]); while not DataSet.Eof do begin sj2 := SO(); for I := 0 to DataSet.FieldCount - 1 do begin if VarIsNull(DataSet.Fields[I].Value) then sj2.O[DataSet.Fields[I].FieldName] := SO(Null) else begin CreateJsonValueByField(sj2, DataSet.Fields[I]); end; end; aj.AsArray.Add(sj2); DataSet.Next; end; sj.O['Data'] := aj; Result := sj.AsString;
finally List.Free; DataSet.EnableControls; end; end;
end.