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 ...
随机推荐
- HDU 3775 Chain Code pick定理
pick定理:一个计算点阵中顶点在格点上的多边形面积公式:S=a+b÷2-1,其中a表示多边形内部的点数,b表示多边形边界上的点数,s表示多边形的面积. 思路:http://blog.csdn.net ...
- 错误error: Exception at 0x613baa14, code: 0xc0000005: read access violation at: 0x0, flags=0x0 (first chance)的解决办法
一.错误原因 出现这个错误的原因多半是由于指针出现错误,即出现了空指针,也有说是变量没有初始化,笔者碰到的情况是发生了内存溢出. 二.定位方法 一般这种问题直接导致程序崩溃,直接调试,就能找到对应的问 ...
- oracle存储过程粗解
存储过程创建的语法: create or replace procedure 存储过程名(param1 in type,param2 out type) as 变量1 类型(值范围);变量2 类型(值 ...
- group_load,weight_load,group_capacity, group_weight大致都是啥数值
[ 113.180820] sgs->group_load:2039,sum_nr_running:2,sum_weighted_load:2039,sgs->group_capacity ...
- Dubbo基础介绍
基础知识 Dubbo是什么:Dubbo是一个分布式的服务框架,提供高性能和透明化的RPC远程调用方案,以及SOA服务治理方案 Dubbo涉及的知识: 远程调用:RMI.hassion.webservi ...
- 染色 color
染色 color 题目描述 有一块矩阵平板,分成n*m个格子,一开始全是白色.在这上面进行k次染色,每次染色按照如下步骤:1. 随机选择一个格子,称为A.2. 随机选择一个格子,称为B.3. 将由A ...
- 让JS帮你决定午餐吃什么吧
最愁就是每天中午吃什么了,有空就做了个 JavaScript 轮播随机选择.会轮播预先自定义的菜单中,然后点选定的时候确定一款.代码可以查看本页源代码获得,你可以自定义修改菜单数组. 效果演示 准备选 ...
- Lesson9 some interesting things in C#
1.关键帧动画 1)xml 界面 <Page x:Class="Test.MainPage" xmlns="http://schemas.microsoft.com ...
- Windows Server 2008允许多用户登录远程桌面
远程桌面是windows管理员对服务器进行管理最常用的方式,默认情况下windows server服务器是只允许单个远程链接的,如何开启多个用户远程桌面,下面就来介绍. 工具/原料 windo ...
- linux 安装 pip
# wget https://bootstrap.pypa.io/get-pip.py # python get-pip.py