unit uDBJson;
interface
{$HINTS OFF}
uses
SysUtils, Classes, Variants, DB, DBClient, SuperObject;type
TTableJSon = classprivate const
cstFieldType = 'FieldType';const
cstFieldName = 'FieldName';const
cstFieldSize = 'FieldSize';const
cstJsonType = 'JsonType';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.