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. Django 中的select_related函数优化查询

    参考链接: https://blog.csdn.net/secretx/article/details/43964607 在数据库有外键的时候,使用select_related()和prefech_r ...

  2. HTTP协议中常用相应的状态码总结

    HTTP协议与我们的生活息息相关,尤其对于我们后端开发人员,工作之余我整理了一些HTTP协议响应的一些常见的状态码,希望能帮助大家 HTTP状态码列表 消息(1字头)服务器收到请求,需要请求者继续执行 ...

  3. C++11常用特性介绍——nullptr关键字及用法

    一.nullptr关键字及用法 1)NULL的二义性 void func(int) {} void func(int*) {} 当函数调用func(NULL)时会执行哪个函数呢? 先看C++对NULL ...

  4. Dynamic Programming(动态规划)

    钢材分段问题 #include<iostream> #include<vector> using namespace std; class Solution { public: ...

  5. webpack的配置文件[webpack.config.js]

    如果项目里没有webpack.config.js这个文件,webpack会使用它本身内置在源码里的配置项. webpack.config.js这个配置名称可以通过指令修改 npx webpack -- ...

  6. 在ng-repeat 中使用 ng-click

    angular 中使用 ng-repeat  过程中,有时需要绑定 事件 click ,使用ng-click ,但是并没有效果,此时应该使用 data-ng-click 替代 ng-click ,并且 ...

  7. Day1-A-POJ-3295

    由题意知,有5种操作,5个未知数,可0可1,一串操作问是否恒为1,最多100个字符,直接栈模拟所有情况即可 代码如下: int p, q, r, s, t; bool calculate(string ...

  8. uniGUI之TUniHiddenPanel(14)

    TUniHiddenPanel是将不在界面上显示的  容器  控件.  只有uniDBGrid实际列才有对应的编辑控件,如果是外键列则无法设置 编辑控件. 里面的控件将不会 显示.将控件放入其中即可. ...

  9. 使用 JvisualVM 监控 spark executor

    使用 JvisualVM,需要先配置 java 的启动参数 jmx 正常情况下,如下配置 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmx ...

  10. JAVA关于回文判断的实现

    (一). 设计思想: 首先输入字符串,然后判断长度若长度为0或1则输出TRUE若长度大于一则进行判断, 若符合条件则输出TRUE反之输出FALSE. (二)程序源代码 import java.util ...