superobject 序列数据集

unit uDBJson;

interface

{$HINTS OFF}

uses
  SysUtils, Classes, Variants, DB, DBClient, SuperObject;

type
  TTableJSon = class

  private 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.

posted @ 2012-05-22 10:52  delphi中间件  阅读(1543)  评论(0编辑  收藏  举报