JsonDataObjects序列和还原
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(rawbytestring( 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.
JsonDataObjects序列和还原的更多相关文章
- msgpack的数据序列和还原
msgpack的数据序列和还原 msgpack不仅可以序列一些常规的数据类型的数据,比如:string.datetime.integer...... 还能序列olevariant.stream 这就非 ...
- QJSON封装好的序列和还原方法
QJSON封装好的序列和还原方法 {*******************************************************}{ }{ QJSON与数据集互转 }{ }{ 版权所 ...
- MSGPACK序列和还原TFDParams
MSGPACK序列和还原TFDParams unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, S ...
- 优秀的数据序列和还原类----TSimpleMsgPack
优秀的数据序列和还原类----TSimpleMsgPack TSimpleMsgPack是D10天地弦的作品. 优点:至简,就一个单元文件实现,不需要引用其他单元. 缺点:不是标准的MSGPACK实现 ...
- cross socket和msgpack的数据序列和还原
cross socket和msgpack的数据序列和还原 procedure TForm1.Button1Click(Sender: TObject); begin var pack: TSimple ...
- TynSerial流的序列(还原)
TynSerial流的序列(还原) procedure TForm1.ToolButton18Click(Sender: TObject); var serial: TynSerial; ms, ms ...
- TynSerial基本数据类型序列(还原)
TynSerial基本数据类型序列(还原) procedure TForm1.ToolButton17Click(Sender: TObject); var serial: TynSerial; be ...
- TynSerial序列(还原)TFDMemTable
TynSerial序列(还原)TFDMemTable 1)TFDMemTable查询数据 procedure TForm1.Qrys(accountno, sql, sql2: string; Dat ...
- TynSerial图片序列(还原)
TynSerial图片序列(还原) 笔者以生成图形验证码为例. function TForm1.VerifyCode(image: TImage): string; // 生成验证码和图像 var u ...
随机推荐
- Linq学习(一)
与LINQ有关的语言特性 1.隐式类型 var 2.匿名类型 如:var obj = new {Guid.Empty, myTitle = "匿名类型", myOtherParam ...
- reinterpret_cast and const_cast
reinterpret_cast reinterpret意为“重新解释” reinterpret_cast是C++中与C风格类型转换最接近的类型转换运算符.它让程序员能够将一种对象类型转换为另一种,不 ...
- nyoj 题目21 三个水杯
三个水杯 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互倒水,并且水杯没有 ...
- [bzoj2038] [2009国家集训队]小Z的袜子
Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把这N只 ...
- 【普通の惨败】GDOI2015卖萌记
前记:这次可真的全程卖萌了.... Day 0 早早坐上前往广州的火车,然后转车到韶关 然后就到了偏远郊区的(准)四星酒店 周围连路灯都没有,极其僻静极其荒凉 大家都极其安静地回到自己房间复习 这一天 ...
- POJ 3177 Redundant Paths 无向图边双联通基础题
题意: 给一个无向图,保证任意两个点之间有两条完全不相同的路径 求至少加多少边才能实现 题解: 得先学会一波tarjan无向图 桥的定义是:删除这条边之后该图不联通 一条无向边(u,v)是桥,当且仅当 ...
- ZOJ Bizarre Routine 2013杭州网赛B题
题目意思: 给定n, expect, a, b 要求你构造一组array[],存放一个1..n的排列,使的下面的程序能输出YES 题目所示代码: bool less_than(x, y) { T++; ...
- 转:Mysql explain
转自:http://blog.csdn.net/zhuxineli/article/details/14455029(单纯学习而转) explain显示了MySQL如何使用索引来处理select语句以 ...
- Aspose.Cells 基础用法
最近使用Aspose.Cells做Excel,在怎么添加批注和添加内部导航链接上耗费了一些时间,最后在官网上找到相关用法,记录一下. 代码不用过多介绍,看看即可明白. 测试代码下载 Workbook ...
- odp.net 读写oracle blob字段
DEVELOPER: ODP.NET Serving Winning LOBs: http://www.oracle.com/technetwork/issue-archive/2005/05-nov ...