In Delphi, datasets are the most common way of accessing data. Therefore, we must establish the relationship between JSON and Tdataset, and realize the communication and transformation between the data. It is important to note that this is only the normal conversion between Tdataset and JSON, since CDs contains delta packets, whose data formats are far more complex than ordinary tdataset.
The dataset field information is a complete dictionary information. Therefore, we must also establish the dictionary information in JSON in order to create the field information of the dataset. We set its JSON information as follows:
cols:[field List information], such as:
"Cols": [{"Jsontype": "Integer", "Fieldindex": 0, "FieldType": "Integer", "FieldSize": 0, "FieldName": "ID", "Required": false},{"Jsontype": "string", "Fieldindex": 1, "FieldType": "string", "FieldSize": +, "FieldName": "Title", "Required" : false},{"Jsontype": "Variant", "Fieldindex": 2, "FieldType": "Blob", "FieldSize": 0, "FieldName": "Picture", "Required" : false}]
The data information is the node of the database, and it is also an array nesting record information:
"Data": [Recordset information]
Say less nonsense, directly on the code:
- Unit Udbjson;
- Interface
- Uses
- Sysutils,classes,variants,db,dbclient,superobject;
- Type
- Ttablejson = Class
- Private
- Const CSTFIELDTYPE = ' FieldType ';
- Const CSTFIELDNAME = ' FieldName ';
- Const CSTFIELDSIZE = ' FieldSize ';
- Const CSTJSONTYPE = ' Jsontype ';
- Const cstrequired = ' Required ';
- Const CSTFIELDINDEX = ' Fieldindex ';
- Const cstcols= ' Cols ';
- Const cstdata= ' Data ';
- Public
- class function Jsonfromdataset (Dataset:tdataset): string;
- class function Createfieldbyjson (fields:tfielddefs; Colsjson:isuperobject): Boolean;
- class function Importdatafromjson (dataset:tdataset;datajson:isuperobject): Integer;
- class function Cdsfromjson (Cds:tclientdataset; Json:isuperobject): Boolean;
- class function GetValue (Json:isuperobject;const name:string): Variant;
- class function Createjsonvalue (Json:isuperobject;const name:string;const value:variant): Boolean;
- class function Createjsonvaluebyfield (Json:isuperobject; Field:tfield): Boolean;
- class function Getvalue2field (Field:tfield; Jsonvalue:isuperobject): Variant;
- End
- Implementation
- Uses TYPINFO,ENCDDECD;
- {Ttablejson}
- class function Ttablejson.cdsfromjson (Cds:tclientdataset;
- Json:isuperobject): Boolean;
- Var
- Colsjson:isuperobject;
- Begin
- Result: = False;
- If Json = Nil Then
- Exit;
- Cds. Close;
- Cds. Data: = Null;
- Create a field
- Colsjson: = Json.o[cstcols];
- Createfieldbyjson (CDS. Fielddefs,colsjson);
- If CDS. Fielddefs.count >0 Then
- Cds. CreateDataSet;
- Importdatafromjson (Cds,json.o[cstdata]);
- Result: = True;
- End
- class function Ttablejson.createfieldbyjson (fields:tfielddefs;
- Colsjson:isuperobject): Boolean;
- Var
- Subjson:isuperobject;
- Ft:tfieldtype;
- Begin
- Result: = False;
- Fields.DataSet.Close;
- Fields.clear;
- For Subjson in Colsjson do
- Begin
- FT: = Tfieldtype (GetEnumValue (TypeInfo (Tfieldtype), ' ft ' +subjson.s[cstfieldtype]);
- If ft= ftautoinc then//increment field cannot be entered and must be changed
- FT: = Ftinteger;
- Fields.Add (subjson.s[cstfieldname],ft,subjson.i[cstfieldsize],subjson.b[cstrequired]);
- End
- Result: = True;
- End
- class function Ttablejson.createjsonvalue (Json:isuperobject;
- Const name:string; Const value:variant): Boolean;
- Begin
- Result: = False;
- Json.o[name]: = SO (Value);
- Result: = True;
- End
- class function Ttablejson.createjsonvaluebyfield (Json:isuperobject;
- Field:tfield): Boolean;
- Begin
- Result: = False;
- If Field is Tdatetimefield then
- Json.o[field.fieldname]: = SO (field.asdatetime)
- else if Field is Tblobfield then
- Json.s[field.fieldname]: = encodestring (field.asstring)
- Else
- Json.o[field.fieldname]: = SO (Field.value);
- Result: = True;
- End
- class function Ttablejson.getvalue (
- Json:isuperobject;const name:string): Variant;
- Begin
- Case Json.datatype of
- Stnull:result: = Null;
- Stboolean:result: = Json.b[name];
- Stdouble:result: = Json.d[name];
- Stcurrency:result: = Json.c[name];
- Stint:result: = Json.i[name];
- Ststring:result: = Json.s[name];
- End
- End
- class function Ttablejson.getvalue2field (Field:tfield; Jsonvalue:isuperobject): Variant;
- Begin
- If Jsonvalue.datatype = Stnull Then
- Result: = Null
- else if Field is Tdatetimefield then
- Result: = Javatodelphidatetime (Jsonvalue.asinteger)
- else if (field is Tintegerfield) or (field was Tlargeintfield) then
- Result: = Jsonvalue.asinteger
- else if Field is Tnumericfield then
- Result: = jsonvalue.asdouble
- else if Field is Tbooleanfield then
- Result: = Jsonvalue.asboolean
- else if Field is Tstringfield then
- Result: = jsonvalue.asstring
- else if Field is Tblobfield then
- Result: = decodestring (jsonvalue.asstring)
- End
- class function Ttablejson.importdatafromjson (Dataset:tdataset;
- Datajson:isuperobject): Integer;
- Var
- Subjson:isuperobject;
- I:integer;
- Iter:tsuperobjectiter;
- Begin
- If not dataset.active then
- Dataset.open;
- Dataset.disablecontrols;
- Try
- For Subjson in Datajson do
- Begin
- Dataset.append;
- If Objectfindfirst (Subjson,iter) Then
- Begin
- Repeat
- If Dataset.findfield (ITER). Ite.Current.Name) <>nil Then
- Dataset.findfield (ITER). Ite.Current.Name). Value: =
- Getvalue2field (
- Dataset.findfield (ITER). Ite.Current.Name),
- Iter. Ite.Current.Value);
- Until not Objectfindnext (ITER);
- End
- Dataset.post;
- End
- Finally
- Dataset.enablecontrols;
- End
- End
- class function Ttablejson.jsonfromdataset (Dataset:tdataset): string;
- Procedure Getfieldtypeinfo (Field:tfield;var fieldtyp,jsontyp:string);
- Begin
- Fieldtyp: = Getenumname (TypeInfo (Tfieldtype), Ord (Field.datatype));
- Delete (fieldtyp,1,2);
- If Field is Tstringfield then
- Jsontyp: = ' string '
- else if Field is Tdatetimefield then
- Jsontyp: = ' integer '
- else if (field is Tintegerfield) or (field was Tlargeintfield) then
- Jsontyp: = ' integer '
- else if Field is Tcurrencyfield then
- Jsontyp: = ' Currency '
- else if Field is Tnumericfield then
- Jsontyp: = ' Double '
- else if Field is Tbooleanfield then
- Jsontyp: = ' Boolean '
- Else
- Jsontyp: = ' variant ';
- End
- Var
- Sj,aj,sj2:isuperobject;
- I:integer;
- fieldtyp,jsontyp:string;
- List:tstringlist;
- Begin
- SJ: = SO ();
- Create columns
- AJ: = SA ([]);
- List: = tstringlist.create;
- Try
- list.sorted: = True;
- For I: = 0 to Dataset.fieldcount-1 do
- Begin
- SJ2: = SO ();
- Getfieldtypeinfo (Dataset.fields[i],fieldtyp,jsontyp);
- Sj2. S[cstfieldname]: = Dataset.fields[i]. FieldName;
- Sj2. S[cstfieldtype]: = Fieldtyp;
- Sj2. S[cstjsontype]: = Jsontyp;
- Sj2. I[cstfieldsize]: = Dataset.fields[i]. Size;
- Sj2. B[cstrequired]: = Dataset.fields[i]. Required;
- Sj2. I[cstfieldindex]: = Dataset.fields[i]. Index;
- Aj. Asarray.add (SJ2);
- List.add (Dataset.fields[i]. fieldname+ ' = ' +jsontyp);
- End
- Sj. o[' Cols ']: = AJ;
- To create data for a dataset
- Dataset.disablecontrols;
- Dataset.first;
- AJ: = SA ([]);
- While not dataset.eof do
- Begin
- SJ2: = SO ();
- For I: = 0 to Dataset.fieldcount-1 do
- Begin
- Sj2. S[inttostr (Dataset.fields[i]. Index)]: = Vartostrdef (Dataset.fields[i]. Value, ');
- If Varisnull (Dataset.fields[i]. Value) Then
- Sj2. O[dataset.fields[i]. FieldName]: = SO (Null)
- Else
- Begin
- Createjsonvaluebyfield (Sj2,dataset.fields[i]);
- End
- End
- Aj. Asarray.add (SJ2);
- Dataset.next;
- End
- Sj. o[' Data ': = AJ;
- Result: = SJ. asstring;
- Finally
- List.free;
- Dataset.enablecontrols;
- End
- End
- End.
- Invocation Example:
- DataSet to JSON object or JSON text
- Var
- Json:ttablejson;
- s:string;
- Begin
- S: = json. Jsonfromdataset (ADODATASET1);
- Read the string s in Tstringstream, save it as text, and look at its format.
- End
- JSON object or text, loading to the dataset
- Var
- Json:isuperobject;
- Begin
- JSON: = Tsuperobject.parsefile (' json.txt ', False);
- Ttablejson.cdsfromjson (Cdsjson,json);
- End
http://blog.csdn.net/diligentcatrich/article/details/6913512
Delphi JSON (CDs contains delta packets)