unidac增加json支持

unidac增加json支持

unidac从10.4开发支持json。

UniQuery1.SaveToJSON();
UniQuery1.SaveToXML();

这样,unidac数据集的数据既可以保存为XML,又可以保存为JSON。

生成的JSON数据样例:

{
    "meta":{
        "fields":[
            {"name":"s","type":"string","maxLength":9,"dbtype":"str","maybenull":false},
            {"name":"i","type":"int","maxLength":4,"precision":10},
            {"name":"f","type":"float","maxLength":8,"precision":0},
            {"name":"money","type":"number","dbtype":"currency","maxLength":8,"precision":0},
            {"name":"b","type":"boolean","maxLength":2},
            {"name":"time","type":"datetime","dbtype":"variantdate","maxLength":8,"scale":0,"precision":0},
            {"name":"blob","type":"bin.hex","maxLength":2147483647,"long":true}
        ]
    },
    "data":{
        "rows":[
            {"s":"str","i":8,"f":0.89,"money":12.8,"b":true,"time":"2025-04-11T08:35:33"}
        ]
    }
} 

 生成的XML数据样例:

<xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882' xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882' xmlns:rs='urn:schemas-microsoft-com:rowset' xmlns:z='#RowsetSchema'>
  <s:Schema id='RowsetSchema'>
    <s:ElementType name='row' content='eltOnly' rs:updatable='true'>
      <s:AttributeType name='unitid' rs:basecolumn='unitid' rs:number='1' rs:writeunknown='true' rs:keycolumn='true' rs:basetable='tunit' rs:basecatalog='yndb'>
        <s:datatype dt:type='string' dt:maxLength='4' rs:maybenull='false' />
      </s:AttributeType>
      <s:AttributeType name='unitname' rs:basecolumn='unitname' rs:number='2' rs:nullable='true' rs:writeunknown='true' rs:basetable='tunit' rs:basecatalog='yndb'>
        <s:datatype dt:type='string' dt:maxLength='6' />
      </s:AttributeType>
      <s:extends type='rs:rowbase' />
    </s:ElementType>
  </s:Schema>
  <rs:data>
    <z:row unitid='10' unitname='2' />
    <z:row unitid='2' unitname='' />
    <z:row unitid='3' unitname='' />
    <z:row unitid='4' unitname='' />
    <z:row unitid='5' unitname='' />
    <z:row unitid='6' unitname='' />
    <z:row unitid='7' unitname='' />
    <z:row unitid='8' unitname='' />
    <z:row unitid='9' unitname='测试' />
  </rs:data>
</xml>

 

var vt: TVirtualTable;
  ms: TMemoryStream;

procedure TForm1.Button1Click(Sender: TObject);
begin
  //marshal dataset to json
  UniQuery1.SaveToJSON(ms);
  //unmarshal dataset from json
  vt.LoadFromStream(ms);
  vt.Open;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  vt := tvirtualtable.Create(Self);
  DataSource1.DataSet := vt;
  ms := TMemoryStream.Create;
end;

 

procedure TDataSetService.WriteFieldXMLDataType(Field: TField; FieldDesc: TFieldDesc;
  const FieldAlias: string; XmlWriter: XMLTextWriter);
begin
  case FieldDesc.DataType of
    dtBlob, dtBytes, dtVarBytes, dtExtVarBytes: begin
      XmlWriter.WriteAttributeString('dt:type', 'bin.hex');
      if (FieldDesc.DataType = dtBlob) then
        XmlWriter.WriteAttributeString('dt:maxLength', '2147483647')
      else
        XmlWriter.WriteAttributeString('dt:maxLength', IntToStr(FieldDesc.Length));
      if Field.IsBlob and not FieldDesc.Fixed then
        XmlWriter.WriteAttributeString('rs:long', 'true');
    end;
    dtBoolean: begin
      XmlWriter.WriteAttributeString('dt:type', 'boolean');
      XmlWriter.WriteAttributeString('dt:maxLength', IntToStr(FieldDesc.Size));
    end;
    dtString, dtExtString, dtMemo, dtWideString, dtExtWideString, dtWideMemo: begin
      XmlWriter.WriteAttributeString('dt:type', 'string');
      if FieldDesc.DataType in [dtMemo, dtWideMemo] then
        XmlWriter.WriteAttributeString('dt:maxLength', '2147483647')
      else
        XmlWriter.WriteAttributeString('dt:maxLength', IntToStr(FieldDesc.Length));
      if not (FieldDesc.DataType in [dtWideString, dtExtWideString, dtWideMemo]) then
        XmlWriter.WriteAttributeString('rs:dbtype', 'str');
      if Field.IsBlob and not FieldDesc.Fixed then
        XmlWriter.WriteAttributeString('rs:long', 'true');
    end;
    dtCurrency, dtBCD: begin
      XmlWriter.WriteAttributeString('dt:type', 'number');
      XmlWriter.WriteAttributeString('rs:dbtype', 'currency');
      XmlWriter.WriteAttributeString('dt:maxLength', IntToStr(FieldDesc.Size));
      XmlWriter.WriteAttributeString('rs:precision', IntToStr(FieldDesc.Length));
    end;
    dtDateTime: begin
      XmlWriter.WriteAttributeString('dt:type', 'datetime');
      XmlWriter.WriteAttributeString('rs:dbtype', 'variantdate');
      XmlWriter.WriteAttributeString('dt:maxLength', IntToStr(FieldDesc.Size));
      XmlWriter.WriteAttributeString('rs:scale', IntToStr(FieldDesc.Scale));
      XmlWriter.WriteAttributeString('rs:precision', IntToStr(FieldDesc.Length));
    end;
    dtDate: begin
      XmlWriter.WriteAttributeString('dt:type', 'date');
      XmlWriter.WriteAttributeString('dt:maxLength', IntToStr(FieldDesc.Size));
      XmlWriter.WriteAttributeString('rs:scale', IntToStr(FieldDesc.Scale));
      XmlWriter.WriteAttributeString('rs:precision', IntToStr(FieldDesc.Length));
    end;
    dtTime: begin
      XmlWriter.WriteAttributeString('dt:type', 'time');
      XmlWriter.WriteAttributeString('dt:maxLength', IntToStr(FieldDesc.Size));
      XmlWriter.WriteAttributeString('rs:scale', IntToStr(FieldDesc.Scale));
      XmlWriter.WriteAttributeString('rs:precision', IntToStr(FieldDesc.Length));
    end;
  {$IFNDEF FPC}
    dtSQLTimeStamp: begin
      XmlWriter.WriteAttributeString('dt:type', 'datetime');
      XmlWriter.WriteAttributeString('rs:dbtype', 'timestamp');
      XmlWriter.WriteAttributeString('dt:maxLength', IntToStr(FieldDesc.Size));
      XmlWriter.WriteAttributeString('rs:scale', IntToStr(FieldDesc.Scale));
      XmlWriter.WriteAttributeString('rs:precision', IntToStr(FieldDesc.Length));
    end;
  {$ENDIF}
    dtFloat, dtSingle, dtExtended: begin
      if (FieldDesc.Length <= 7) and (FieldDesc.Size <= 4) then begin
        XmlWriter.WriteAttributeString('dt:type', 'r4');
        XmlWriter.WriteAttributeString('dt:maxLength', '4');
      end
      else begin
        XmlWriter.WriteAttributeString('dt:type', 'float');
        XmlWriter.WriteAttributeString('dt:maxLength', IntToStr(FieldDesc.Size));
      end;
      XmlWriter.WriteAttributeString('rs:precision', IntToStr(FieldDesc.Length));
    end;
    dtGuid: begin
      XmlWriter.WriteAttributeString('dt:type', 'uuid');
      XmlWriter.WriteAttributeString('dt:maxLength', '38');
    end;
    dtInt32: begin
      XmlWriter.WriteAttributeString('dt:type', 'int');
      XmlWriter.WriteAttributeString('dt:maxLength', IntToStr(FieldDesc.Size));
      XmlWriter.WriteAttributeString('rs:precision', '10');
    end;
    dtFmtBCD: begin
      XmlWriter.WriteAttributeString('dt:type', 'number');
      XmlWriter.WriteAttributeString('rs:dbtype', 'numeric');
      XmlWriter.WriteAttributeString('dt:maxLength', IntToStr(FieldDesc.Size));
      XmlWriter.WriteAttributeString('rs:scale', IntToStr(FieldDesc.Scale));
      XmlWriter.WriteAttributeString('rs:precision', IntToStr(FieldDesc.Length));
    end;
    dtInt16: begin
      XmlWriter.WriteAttributeString('dt:type', 'i2');
      XmlWriter.WriteAttributeString('dt:maxLength', IntToStr(FieldDesc.Size));
      XmlWriter.WriteAttributeString('rs:precision', '5');
    end;
    dtWord: begin
      XmlWriter.WriteAttributeString('dt:type', 'ui2');
      XmlWriter.WriteAttributeString('dt:maxLength', IntToStr(FieldDesc.Size));
      XmlWriter.WriteAttributeString('rs:precision', IntToStr(FieldDesc.Length));
    end;
    dtInt8: begin
      XmlWriter.WriteAttributeString('dt:type', 'i1');
      XmlWriter.WriteAttributeString('dt:maxLength', IntToStr(FieldDesc.Size));
      XmlWriter.WriteAttributeString('rs:precision', IntToStr(FieldDesc.Length));
    end;
    dtUInt8: begin
      XmlWriter.WriteAttributeString('dt:type', 'ui1');
      XmlWriter.WriteAttributeString('dt:maxLength', IntToStr(FieldDesc.Size));
      XmlWriter.WriteAttributeString('rs:precision', IntToStr(FieldDesc.Length));
    end;
    dtLongword: begin
      XmlWriter.WriteAttributeString('dt:type', 'ui4');
      XmlWriter.WriteAttributeString('dt:maxLength', IntToStr(FieldDesc.Size));
      XmlWriter.WriteAttributeString('rs:precision', IntToStr(FieldDesc.Length));
    end;
    dtInt64: begin
      XmlWriter.WriteAttributeString('dt:type', 'i8');
      XmlWriter.WriteAttributeString('dt:maxLength', IntToStr(FieldDesc.Size));
      XmlWriter.WriteAttributeString('rs:precision', '19');
    end;
    dtUInt64: begin
      XmlWriter.WriteAttributeString('dt:type', 'ui8');
      XmlWriter.WriteAttributeString('dt:maxLength', IntToStr(FieldDesc.Size));
      XmlWriter.WriteAttributeString('rs:precision', '19');
    end;
    dtUnknown, dtVariant:
      XmlWriter.WriteAttributeString('dt:type', 'string')
    else
      DatabaseError(SDataTypeNotSupported, FDataSet);
  end;

  if FieldDesc.Fixed and not (FieldDesc.DataType in [dtUnknown, dtVariant]) then
    XmlWriter.WriteAttributeString('rs:fixedlength', 'true');

  if Field.Required and not Field.ReadOnly then
    XmlWriter.WriteAttributeString('rs:maybenull', 'false');
end;

 

posted @ 2025-04-10 20:41  delphi中间件  阅读(99)  评论(0)    收藏  举报