unit uJSONDB;

interface
uses
SysUtils, Classes, Variants, DB, DBClient, SuperObject, Dialogs;
type
TJSONDB = class

private
class function getJsonFieldNames(res: ISuperObject):TStringList ;
class function getJsonFieldValues(res: ISuperObject):TStringList ;
public
class procedure JsonToClientDataSet(jsonArr: TSuperArray; dstCDS: TClientDataSet);
//class procedure JsonToClientDataSetF(jsonArr: TSuperArray; dstCDS: TClientDataSet;fs:String);
class function ClientDataSetToJSON(srcCDS: TClientDataSet):UTF8String;
end;
//type
// TArrayDim = Array of ShortString;

implementation

function GetToken(var astring: string;const fmt:array of char): string;
var
i,j:integer;
Found:Boolean;
begin
found:=false;
result:='';
aString := TrimLeft(aString);

if length(astring)=0 then exit;

I:=1;
while I<=length(Astring) do
begin
found:=false;
if aString[i]<=#128 then
begin
for j:=Low(Fmt) to High(Fmt) do
begin
if (astring[i]<>Fmt[j]) then continue;
found:=true;
break;
end;
if Not found then I:=I+1;
end
else I:=I+2;

if found then break;
end;

if found then
begin
result:=copy(astring,1,i-1);
delete(astring,1,i);
end
else
begin
result:=astring;
astring:='';
end;
end;

function GetFieldParams(PropName, Source:string): string;
var
S1, S2: string;
TmpParam: string;
AChar: string;
aValue, aPropName, aSource: string;
begin
Result:='';
if Source='' then Exit;
aSource := Source;
while aSource <> '' do
begin
aValue := GetToken(aSource,[',']);
aPropName := GetToken(aValue,[':']);
if CompareText(PropName,aPropName) <> 0 then continue;
Result := aValue;
break;
end;
end;
//從json取得欄位名稱
class function TJSONDB.getJsonFieldNames(res: ISuperObject):TStringList ;
var
i: Integer;
fieldList : TStringList;
fieldNames :String;

begin
try
fieldList := TStringList.Create;
fieldNames := res.AsObject.getNames.AsString;

fieldNames := StringReplace(fieldNames, '[', '', [rfReplaceAll, rfIgnoreCase]);
fieldNames := StringReplace(fieldNames, ']', '', [rfReplaceAll, rfIgnoreCase]);
fieldNames := StringReplace(fieldNames, '"', '', [rfReplaceAll, rfIgnoreCase]);

fieldList.Delimiter := ',';
fieldList.DelimitedText := fieldNames;
Result:= fieldList;
finally
//fieldList.Free;
end;
end;

//從json取得欄位值
class function TJSONDB.getJsonFieldValues(res: ISuperObject):TStringList ;
var
i: Integer;
fieldList : TStringList;
fieldValues :String;
begin
try
fieldList := TStringList.Create;
fieldValues := res.AsObject.getValues.AsString;
fieldValues := StringReplace(fieldValues, '[', '', [rfReplaceAll, rfIgnoreCase]);
fieldValues := StringReplace(fieldValues, ']', '', [rfReplaceAll, rfIgnoreCase]);
fieldValues := StringReplace(fieldValues, '"', '', [rfReplaceAll, rfIgnoreCase]);

fieldList.Delimiter := ',';
fieldList.DelimitedText := fieldValues;
Result:= fieldList;
finally
//fieldList.Free;
end;
end;
//json轉CDS
class procedure TJSONDB.JsonToClientDataSet(jsonArr: TSuperArray; dstCDS: TClientDataSet);
var
fieldList: TStringList;
valuesList: TStringList;
jsonSrc: string;
i, j: Integer;
jo: ISuperObject;

jts: TSuperTableString;
ja: TSuperArray;

iter: TSuperObjectIter;
ss,s1:String;
dps:TSupertype;
ft:TFieldType;
len:integer;
// XJSon :TlkJSONobject;
begin

fieldList:= getJsonFieldNames(SO[jsonArr[0].AsJson(False,False)]);
if (dstCDS.FieldCount = 0) then
begin
jo:= so(jsonArr[0].AsString);
// iter:=jo.AsObject.GetEnumerator;
// xjson:= TlkJSON.ParseText(jsonArr[0]);
for i := 0 to fieldList.Count -1 do
begin

if ObjectFindFirst(jo, iter) then
begin
repeat
dps:=iter.Ite.Current.Value.DataType;
ss:=iter.Ite.Current.Name;
if trim(ss)= trim(fieldList[i]) then
break;
until not ObjectFindNext(iter);
end;
ObjectFindClose(iter);
ft := ftString;
case dps of
stNull: ft := ftString;
stBoolean: ft := ftString;
stDouble: ft := ftFloat;
stCurrency: ft := ftFloat;
stInt: ft := ftFloat;
stString: ft := ftString;
end;
if (ft=ftFloat) then
begin
dstCDS.FieldDefs.Add(fieldList[i],ft);
// s1:=s1+fieldList[i]+',';
end;
if (ft=ftString) then
begin
len:=100; //默认字段长度为100
s1:=copy(fieldList[i],1,3);//判断是否属于需要特殊设置长度的字段
if s1='AAA' then //根据设置的特殊字段名称AAA开始的字段,_开始后面的数字为字段长度
begin
len:=pos('_',fieldList[i]) ;
len:=strtointdef(copy(fieldList[i],len+1,length(fieldList[i])-len),100); //获取特殊字段的长度设置
end;
dstCDS.FieldDefs.Add(fieldList[i],ft,len,false); // ftVarBytes ftString
end;
end;
dstCDS.CreateDataSet;
dstCDS.Close;
dstCDS.Open;
end;
try
dstCDS.DisableControls;
for i := 0 to jsonArr.Length -1 do
begin

jts:=jsonArr[i].AsObject;
ja:=jts.GetValues.AsArray;

// jsonSrc:= SO[jsonArr[i].AsJson(False,False)].AsString;
// jsonSrc := StringReplace(jsonSrc, '[', '', [rfReplaceAll, rfIgnoreCase]);
// jsonSrc := StringReplace(jsonSrc, ']', '', [rfReplaceAll, rfIgnoreCase]);
// jsonSrc := StringReplace(jsonSrc, '"', '', [rfReplaceAll, rfIgnoreCase]);
// jsonSrc := StringReplace(jsonSrc, '{', '', [rfReplaceAll, rfIgnoreCase]);
// jsonSrc := StringReplace(jsonSrc, '}', '', [rfReplaceAll, rfIgnoreCase]);

dstCDS.Append;
for j:= 0 to fieldList.Count -1 do
begin
{ss:= GetFieldParams(fieldList[j], jsonSrc);

}
ss:=ja[j].AsString;
if trim(ss)='null' then
ss:='';
dstCDS.FieldByName(fieldList[j]).AsString:=ss;
end;
dstCDS.Post;
end;

finally
dstCDS.EnableControls;
end;
end;

//ClientDataSet轉JSON
class function TJSONDB.ClientDataSetToJSON(srcCDS: TClientDataSet): UTF8String;
var
i, j: Integer;
keyValue:String;
jsonList:TStringList;
jsonResult:String;
begin
if not srcCDS.Active then srcCDS.Open;

try
jsonList := TStringList.Create;
srcCDS.DisableControls;
srcCDS.First;
while not srcCDS.Eof do
begin
keyValue:= '';
for i := 0 to srcCDS.FieldDefs.Count -1 do
begin
keyValue:= keyValue + Format('"%s":"%s",',[srcCDS.Fields[i].FieldName, srcCDS.Fields[i].AsString]);

end;
jsonList.Add(Format('{%s}',[Copy(keyValue, 0, Length(keyValue)-1)]));
srcCDS.Next;
end;
for i := 0 to jsonList.Count -1 do
begin
jsonResult := jsonResult + jsonList[i] + ',';
end;
Result:= Utf8Encode(Format('[%s]', [Copy(jsonResult, 0, Length(jsonResult)-1)]));
finally
srcCDS.EnableControls;
jsonList.Free;
end;
end;

end.

delphi中json转dataset的更多相关文章

  1. Delphi中JSon SuperObject 使用:数据集与JSON对象互转

    在delphi中,数据集是最常用数据存取方式.因此,必须建立JSON与TDataSet之间的互转关系,实现数据之间通讯与转换.值得注意的是,这只是普通的TDataset与JSON之间转换,由于CDS包 ...

  2. Delphi中Json格式读写

    Json是一种轻量级传输数据格式,广泛应用互联网和各应用中.json主要採用键值对来表示数据项.多个数据项之间用逗号分隔,也能够用于数组.以下注重介绍一下在delphi中使用json,在delphi中 ...

  3. Delphi中使用ISuperObject解析Json数据

    Java.Php等语言中都有成熟的框架来解析Json数据,可以让我们使用很少的代码就把格式化好的json数据转换成程序可识别的对象或者属性,同时delphi中也有这样的组件来实现此功能,即Isuper ...

  4. delphi中midas是什么

    Delphi中MIDAS到底是什么呢?和他相关组件是什么呢?   MIDAS(Multitiered Distributed Application Services)多层分布式应用服务.   Del ...

  5. ActiveX数据对象之事务控制在VB和DELPHI中的应用

            本文发表在中国人民解放军"信息工程大学"学报 2001年第3期.        ActiveX数据对象之事务控制在VB和DELPHI中的应用             ...

  6. Delphi中带缓存的数据更新技术

    一. 概念 在网络环境下,数据库应用程序是c/s或者是多层结构的模式.在这种环境下,数据库应用程序的开发应当尽可能考虑减少网络数据传输量,并且尽量提高并发度.基于这个目的,带缓存的数据更新技术应运而生 ...

  7. Delphi中封装ADO之我重学习记录

    delphi adodataset ctstatic 数据是缓存在服务器端还是客户端 答:客户端,开启本地缓存功能后,就能数据在本地批量修改后,再批量提交,减少了网络传送   原创,专业,图文 Del ...

  8. Delphi中根据分类数据生成树形结构的最优方法

    一. 引言:    TreeView控件适合于表示具有多层次关系的数据.它以简洁的界面,表现形式清晰.形象,操作简单而深受用户喜爱.而且用它可以实现ListView.ListBox所无法实现的很多功能 ...

  9. kbmmw 中JSON 操作入门

    现在各种系统中JSON 用的越来越多.delphi 也自身支持JSON 处理. 今天简要说一下kbmmw 内部如何使用和操作JSON. kbmmw 中json的操作是以TkbmMWJSONStream ...

随机推荐

  1. 5 HTML脚本&字符实体&URL

    HTML脚本: 用<script>标签定义客户端脚本,比如JavaScript script元素即可包含脚本语句,也可以通过src属性指向外部脚本文件 JavaScript常用于图片操作. ...

  2. ES5-json对象和字符串互转

    JSON.stringify();和JSON.parse();是在ES5中提出并使用的:JSON.stringify();将一个对象转化为json字符串,JSON.parse();将一个对象转化为对象 ...

  3. npm安装包时报错:Error: EPERM: operation not permitted, rename

    解决方法:先执行 npm cache clean -force在安装需要的包.

  4. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 显示代码

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  5. exp之shellcode的理解

    原题请见 https://www.jarvisoj.com/challenges from pwn import * io = remote("pwn2.jarvisoj.com" ...

  6. USN日志

    转载:https://www.iteye.com/blog/univasity-805234    https://blog.51cto.com/velika/1440105 源码:https://f ...

  7. 【PAT甲级】1035 Password (20 分)

    题意: 输入一个正整数N(<=1000),接着输入N行数据,每行包括一个ID和一个密码,长度不超过10的字符串,如果有歧义字符就将其修改.输出修改过多少组密码并按输入顺序输出ID和修改后的密码, ...

  8. 【PAT甲级】1022 Digital Library (30 分)(模拟)

    题意: 输入一个正整数N(<=10000),接下来输入N组数据,ID,书名,作者,关键词,出版社,出版年份. 然后输入一个正整数M(<=1000),接下来输入查询的数据,递增输出ID,若没 ...

  9. ATT&CK实战系列——红队实战(一)

    一.环境搭建 1.环境搭建测试 最近想要开始学习内网渗透,搜集了一些教程,准备先实验一个vulnstack靶机,熟悉一下内网渗透操作再学习基础知识. 靶场下载地址:http://vulnstack.q ...

  10. LeetCode 101.对称二叉树 - JavaScript

    题目描述:给定一个二叉树,检查它是否是镜像对称的. 题目分析 下面这种二叉树就是镜像对称的,符合题目要求: 1 / \ 2 2 / \ / \ 3 4 4 3 解法 1:递归检查 根据题目" ...