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 ...
随机推荐
- Android事件分发机制详解(2)----分析ViewGruop的事件分发
首先,我们需要 知道什么是ViewGroup,它和普通的View有什么区别? ViewGroup就是一组View的集合,它包含很多子View和ViewGroup,是Android 所有布局的父类或间接 ...
- KindleEditor insertfile初始化多个
KindEditor.ready(function (K) { var editor = K.editor({ allowFileManager: true }); K('#insertfile'). ...
- 【bzoj3670】[Noi2014]动物园 KMP-next数组
题目描述 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅,只会卖萌向游客要吃的.为了整治动物园的不良风气,让动物们凭自己的真才实学向游客要吃的,园长决定开设算法班,让动物们学习算法. 某天, ...
- [洛谷P1972][SDOI2009]HH的项链
题目大意:给你一串数字,多次询问区间内数字的种类数 题解:莫队 卡点:洛谷数据加强,开了个$O(2)$ C++ Code: #include <cstdio> #include <a ...
- BZOJ3609 [Heoi2014]人人尽说江南好 【博弈】
题目链接 BZOJ3609 题解 我们假设最后合成若干个\(m\),和\(n \mod m\),此时合成次数是最多的,也唯一确定胜利者 可以发现,在轮流操作的情况下,胜利者一定可以将终态变为这个状态 ...
- 白白的(baibaide)
白白的(baibaide) 有一个长度为 $n$ 的序列 $a_1, a_2, \dots, a_n$,一开始每个位置都是白色.如果一个区间中每个位置都是白色,则称这是一个白白的区间.如果一个白白的区 ...
- html li css选中状态切换
思路:点击当前li元素后是用removeClass()删除所有兄弟元素(使用siblings()获取)的class样式,然后使用addClass()为当前li添加class. 具体演示如下: 1.HT ...
- hihocoder 后缀自动机二·重复旋律5
求不同子串个数 裸的后缀自动机 #include<cstring> #include<cmath> #include<iostream> #include<a ...
- MAC中如何配置两套android-sdk环境
1 背景介绍 随着android studio的完善和普及,越来越多Android app开发者从Eclipse+ADT环境转到Android Studio(后文统一用AS表示).但是,AS往往需要较 ...
- Python学习笔记(Django篇)——2、创建第一个django应用
在helloworld工程的基础上,我们准备创建第一个基于web的django应用,把这个应用名字命名为demo 首先,是如何创建这个应用包,当然第一选择我们可以进入到cmd中,执行如下命令 py ...