您的位置:首页 > 移动开发 > Objective-C

JsonDataObjects序列和还原

2018-01-14 21:36 489 查看
JsonDataObjects序列和还原

JsonDataObjects号称DELPHI最快的JSON库,且支持跨平台。

// cxg 2017-9-12

// Use JsonDataObjects(cross platform json library)

// Use delphi 10.2.1

unit ujson;

interface

uses

System.SysUtils, soap.EncdDecd, Web.HTTPApp, System.NetEncoding, Data.DB,

System.Classes, JsonDataObjects;

// {"data":[{"field1":value1,"field2":value2}]};

function datasetToJson(dataset: TDataSet): string;

// {"data":[{"field1":value1,"field2":value2}]};

procedure jsonToDataset(const json: string; dataset: TDataSet);

// {"cols":[{"name":"field1","size":0,"type":"int"}]"data":[{"field1":value1}]};

function datasetToJsonCols(dataset: TDataSet): string;

// {

// "update":[{"table":"表1","where":"字段1=1","字段1":"1","字段2":0}]

// ,"insert":[{"table":"表1","字段1":"1","字段2":0}]

// ,"delete":[{"table":"表1","where":"字段1=1"}]

// };

procedure parseJsonSql(const json: string; outsql: TStrings);

implementation

procedure parseJsonSql(const json: string; outsql: TStrings);

// {

// "update":[{"table":"表1","where":"字段1=1","字段1":"1","字段2":0}]

// ,"insert":[{"table":"表1","字段1":"1","字段2":0}]

// ,"delete":[{"table":"表1","where":"字段1=1"}]

// };

var

obj, childobj: TJsonObject;

tablename, sql, lname, lvalue, where: string;

i, j: Integer;

function _getValue(value: PJsonDataValue): string;

{

TJsonDataType = (

jdtNone, jdtString, jdtInt, jdtLong, jdtULong, jdtFloat, jdtDateTime

, jdtBool, jdtArray, jdtObject

);

}

begin

case Value.Typ of

jdtString: Result := QuotedStr(UTF8ToString(rawbytestring(TNetEncoding.URL.Decode(value.Value)))); // 解码

jdtBool: Result := BoolToStr(value.BoolValue);

jdtFloat: Result := FloatToStr(value.FloatValue);

jdtInt, jdtLong, jdtULong: Result := IntToStr(value.IntValue);

jdtDateTime: Result := DateTimeToStr(value.DateTimeValue);

end;

end;

begin

if outsql = nil then

Exit;

outsql.Clear;

obj := TJsonObject.Parse(json) as TJsonObject;

try

// 解析并生成insert sql begin-----------------------------------

for i := 0 to obj.A['insert'].Count - 1 do

begin

childobj := obj.A['insert'].O[i];

lname := '';

lvalue := '';

for j := 0 to childobj.Count - 1 do

begin

if childobj.Names[j] = 'table' then

begin

tablename := childobj.Items[j].Value;

Continue;

end;

if lname = '' then

lname := childobj.Names[j]

else

lname := lname + ',' + childobj.Names[j];

if lvalue = '' then

lvalue := _getValue(childobj.Items[j])

else

lvalue := lvalue + ',' + _getValue(childobj.Items[j]);

end;

sql := 'insert into ' + tablename + ' (' + lname + ') values (' + lvalue + ')';

outsql.Add(sql);

end;

// 解析并生成insert sql end----------------------------------------

// 解析并生成update sql begin---------------------------------------

for i := 0 to obj.A['update'].Count - 1 do

begin

childobj := obj.A['update'].O[i];

lname := '';

lvalue := '';

for j := 0 to childobj.Count - 1 do

begin

if childobj.Names[j] = 'table' then

begin

tablename := childobj.Items[j].Value;

Continue;

end

else

if childobj.Names[j] = 'where' then

begin

where := childobj.Items[j].Value;

Continue;

end;

if lname = '' then

lname := childobj.Names[j] + '=' + _getValue(childobj.Items[j])

else

lname := lname + ',' + childobj.Names[j] + '=' + _getValue(childobj.Items[j]);

end;

sql := 'update ' + tablename + ' set ' + lname + ' where ' + where;

outsql.Add(sql);

end;

// 解析并生成update sql end--------------------------------------------

// 解析并生成delete sql begin--------------------------------------------

for i := 0 to obj.A['delete'].Count - 1 do

begin

childobj := obj.A['delete'].O[i];

lname := '';

lvalue := '';

for j := 0 to childobj.Count - 1 do

begin

if childobj.Names[j] = 'table' then

begin

tablename := childobj.Items[j].Value;

Continue;

end

else

if childobj.Names[j] = 'where' then

begin

where := childobj.Items[j].Value;

Continue;

end;

end;

sql := 'delete from ' + tablename + ' where ' + where;

outsql.Add(sql);

end;

// 解析并生成delete sql end-------------------------------------------

finally

obj.free;

end;

end;

function datasetToJsonCols(dataset: TDataSet): string;

// {"cols":[{"name":"field1","size":0,"type":"int"}]"data":[{"field1":value1}]};

var

i: Integer;

obj, childobj: TJsonObject;

field: TField;

blob: TStringStream;

function _getFieldType(fld: TField): string;

begin

case fld.DataType of

ftBoolean:

Result := 'bool';

ftSmallint, ftInteger, ftWord, ftAutoInc:

Result := 'int';

ftLargeint:

Result := 'int64';

ftFloat, ftBCD, ftCurrency:

Result := 'float';

ftTimeStamp, ftDate, ftTime, ftDateTime:

Result := 'datetime';

ftString, ftFixedChar, ftMemo, ftWideString:

Result := 'string';

ftBytes, ftVarBytes, ftBlob, ftGraphic, ftOraBlob, ftOraClob:

Result := 'blob';

end;

end;

begin

// {"cols":[{"name":"c1","size":0,"type":"int"}]"data":[{"c1":1}]};

Result := '{"result":"false"}';

if (dataset = nil) or (not dataset.Active) then

Exit;

obj := TJsonObject.Create;

obj.A['cols'];

obj.A['data'];

dataset.First;

for i := 0 to dataset.FieldCount - 1 do // fill cols array

begin

field := dataset.Fields[i];

childobj := obj.A['cols'].AddObject;

childobj.S['name'] := field.FieldName;

childobj.I['size'] := field.Size;

childobj.S['type'] := _getFieldType(field);

childobj.B['required'] := field.Required;

childobj.B['readonly'] := field.ReadOnly;

end;

// fill data array

dataset.First;

while not dataset.Eof do

begin

childobj := obj.A['data'].AddObject;

for i := 0 to dataset.FieldCount - 1 do

begin

field := dataset.Fields[i];

if field.IsNull then

childobj.S[field.FieldName] := ''

else

begin

case field.DataType of

ftBoolean:

childobj.B[field.FieldName] := field.AsBoolean;

ftSmallint, ftInteger, ftWord, ftAutoInc:

childobj.I[field.FieldName] := field.AsInteger;

ftLargeint:

childobj.L[field.FieldName] := TLargeintField(field).AsLargeInt;

ftFloat, ftBCD, ftCurrency:

childobj.F[field.FieldName] := field.AsFloat;

ftTimeStamp, ftDate, ftTime, ftDateTime:

childobj.D[field.FieldName] := field.AsDateTime;

ftString, ftFixedChar, ftMemo, ftWideString:

childobj.S[field.FieldName] := TNetEncoding.URL.Encode(string(UTF8Encode(field.AsString))); // 编码

ftBytes, ftVarBytes, ftBlob, ftGraphic, ftOraBlob, ftOraClob:

begin

blob := TStringStream.Create('');

try

TBlobField(field).SaveToStream(blob);

childobj.S[field.FieldName] := EncodeString(blob.DataString); // base64 编码

finally

blob.Free;

end;

end;

end;

end;

end; // end for

dataset.Next;

end; // end while

Result := obj.ToString;

end;

procedure jsonToDataset(const json: string; dataset: TDataSet);

// {"data":[{"field1":value1,"field2":value2}]};

var

obj, childobj: TJsonObject;

i, j: Integer;

field: TField;

blob: TStringStream;

begin

if (dataset = nil) or (not dataset.Active) or (json = '{"result":"false"}') then

Exit;

obj := TJsonObject.Parse(json) as TJsonObject;

dataset.DisableControls;

try

for i := 0 to obj.A['data'].Count - 1 do

begin

dataset.Append;

childobj := obj.A['data'].O[i];

if childobj = nil then

continue;

for j := 0 to dataset.FieldCount - 1 do

begin

field := dataset.Fields[j];

if field = nil then

Continue;

case field.datatype of

ftBoolean:

field.AsBoolean := childobj.B[field.FieldName];

ftFloat, ftBCD, ftCurrency:

field.AsFloat := childobj.F[field.FieldName];

ftSmallint, ftInteger, ftWord, ftAutoInc:

field.AsInteger := childobj.I[field.FieldName];

ftString, ftFixedChar, ftMemo, ftWideString:

field.AsString :=UTF8ToString(rawbyte
4000
string( TNetEncoding.URL.Decode(childobj.S[field.FieldName]))); // 解码

ftTimeStamp, ftDate, ftTime, ftDateTime:

field.AsDateTime := childobj.D[field.FieldName];

ftLargeint:

TLargeintField(field).AsLargeInt := childobj.L[field.FieldName];

ftBytes, ftVarBytes, ftBlob, ftGraphic, ftOraBlob, ftOraClob:

begin

blob := TStringStream.Create(DecodeString(childobj.S[field.FieldName]));

try

TBlobField(field).LoadFromStream(blob);

finally

blob.Free;

end;

end;

end;

end;

dataset.Post;

end;

finally

dataset.EnableControls;

obj.free;

end;

end;

function datasetToJson(dataset: TDataSet): string;

// {"data":[{"field1":value1,"field2":value2}]};

var

i: Integer;

obj, childobj: TJsonObject;

field: TField;

blob: TStringStream;

begin

Result := '{"result":"false"}';

if (dataset = nil) or (not dataset.Active) then

Exit;

obj := TJsonObject.Create;

try

obj.A['data'];

dataset.First;

while not dataset.Eof do

begin

childobj := obj.A['data'].AddObject;

for i := 0 to dataset.FieldCount - 1 do

begin

field := dataset.Fields[i];

if field.IsNull then

childobj.S[field.FieldName] := ''

else

begin

case field.datatype of

ftBoolean:

childobj.B[field.FieldName] := field.AsBoolean;

ftSmallint, ftInteger, ftWord, ftAutoInc:

childobj.I[field.FieldName] := field.AsInteger;

ftLargeint:

childobj.L[field.FieldName] := TLargeintField(field).AsLargeInt;

ftCurrency, ftFloat, ftBCD:

childobj.F[field.FieldName] := field.AsFloat;

ftTimeStamp, ftDate, ftTime, ftDateTime:

childobj.D[field.FieldName] := field.AsDateTime;

ftString, ftFixedChar, ftMemo, ftWideString:

childobj.S[field.FieldName] := TNetEncoding.URL.Encode(string(UTF8Encode(field.AsString)));

ftBytes, ftVarBytes, ftBlob, ftGraphic, ftOraBlob, ftOraClob:

begin

blob := TStringStream.Create('');

try

TBlobField(field).SaveToStream(blob);

childobj.S[field.FieldName] := EncodeString(blob.DataString); // base64 编码

finally

blob.Free;

end;

end;

end;

end;

end; // end for

dataset.Next;

end; // end while

Result := obj.ToString;

finally

obj.Free;

end;

end;

end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: