Encapsulating rapid JSON for database and network data transmission

background I want to complete json as the dat...
background
design idea
Specific implementation
Use example
Project address
Series article planning
feel

background

I want to complete json as the data medium to operate the database and network transmission. Looking up the data, we found that rapid json is a popular json library, and it is fast. But in my way of use, it's very cumbersome to use, and my purpose is data exchange. Rapid json is very common. It seems that it should be a value transfer operation. In fact, it is a memory move. Although this can achieve the goal of high efficiency, it will make mistakes if you are not careful, and it looks ugly when you write it, so I wrote a proxy class to meet my needs.

design idea

Just add some convenient operation methods, provide a variety of constructors to easily create objects, provide a copy constructor, provide a convenient interface to add elements, provide object traversal methods and so on. In fact, it's a rapidjson object. All the actual operations are based on rapidjson. Rjson is just a proxy. It changes the way of use and provides value transmission, which will cause some performance degradation, but it's a necessary change to meet my needs.

Specific implementation

Class structure

Document * json is the actual json object. I encapsulate it to provide a new access interface without exposing other details, such as the value object. Therefore, the traversal design of Rjson objects is rather cumbersome. Finally, I chose a way similar to ES6, providing a GetAllKeys method first, and then accessing each value one by one for traversal.

class Rjson { private: Document* json; public: Rjson(); Rjson(const char* jstr); Rjson ExtendObject(Rjson& obj); void AddValueInt(string k, int v); void AddValueString(string k, string v) ; ... }

Default constructor

Rjson() { json = new Document(); //After a Document object is created by rapidjosn, you must add Value or call SetObject() to form an empty json, otherwise an error will be reported json->SetObject(); //I merge two operations to create an empty json }

Constructor, accepts char * parameter

Rjson(const char* jstr) { //Note that this is const char *, otherwise from string.c_str() will be forced to transfer when it is passed, otherwise it will be matched with the overloaded constructor of string parameter. json = new Document(); //The combination of two-step operation, simple processing, can facilitate a lot of code creation json->Parse(jstr); }

Constructor, accepts string parameter

Rjson(string jstr) { //Notice the way to call the overloaded constructor in the constructor. new (this)Rjson(jstr.c_str()); }

copy constructor

Rjson(const Rjson& origin) { json = new Document(); //Copy from json->CopyFrom(*(origin.json), json->GetAllocator()); }

Assignment operation

Rjson& operator = (const Rjson& origin) { new (this)Rjson(origin); //Using copy constructor to implement return(*this); }

Overload [] operator

string operator[](string key) { //Values are returned as strings string rs = ""; if (json->HasMember(key.c_str())) { int vType; GetValueAndTypeByKey(key.c_str(), &rs, &vType); } return rs; }

Add value type

void AddValueInt(string k, int v) { string* newK = new string(k); //New must be created Value aInt(kNumberType); aInt.SetInt(v); json->AddMember(StringRef(newK->c_str()), aInt, json->GetAllocator()); //The addMember method is address passing }

Add string type

void AddValueString(string k, string v) { string* newK = new string(k); Value aStr(kStringType); //New must be created aStr.SetString(v.c_str(), json->GetAllocator()); json->AddMember(StringRef(newK->c_str()), aStr, json->GetAllocator()); }

Add object array

void AddValueArray(string k, vector<string>& arr) { string* newK = new string(k); int len = arr.size(); Value rows(kArrayType); for (int i = 0; i < len; i++) { Value al(kStringType); //New must be created al.SetString(arr.at(i).c_str(),json->GetAllocator()); rows.PushBack(al, json->GetAllocator()); } json->AddMember(StringRef(newK->c_str()), rows, json->GetAllocator()); }

Get all keys

vector<string> GetAllKeys() { //Do not want to expose the Value object, use this interface plus the [] operator to complete the traversal. If you need a Value type, use the GetValueAndTypeByKey method. vector<string> keys; for (auto iter = json->MemberBegin(); iter != json->MemberEnd(); ++iter) { keys.push_back((iter->name).GetString()); } return keys; }

Gets the specified value and its type

There are seven value types defined by rapidjson, which need to be handled one by one

enum Type { kNullType = 0, //!< null kFalseType = 1, //!< false kTrueType = 2, //!< true kObjectType = 3, //!< object kArrayType = 4, //!< array kStringType = 5, //!< string kNumberType = 6 //!< number };

Only numeric value, string and array type are processed temporarily

void GetValueAndTypeByKey(string key, string* v, int* vType) { Value::ConstMemberIterator iter = json->FindMember(key.c_str()); if (iter != json->MemberEnd()) { *vType = (int)(iter->value.GetType()); if (iter->value.IsInt()) { std::stringstream s; s << iter->value.GetInt(); *v = s.str(); } else if (iter->value.IsString()) { *v = iter->value.GetString(); } else if (iter->value.IsArray()) { *v = GetJsonString((Value&)iter->value); } else { *v = ""; } } else { *vType = kStringType; *v = ""; } }

Get json string

string GetJsonString() { StringBuffer strBuffer; Writer<StringBuffer> writer(strBuffer); json->Accept(writer); return strBuffer.GetString(); }

Extending json objects

Rjson ExtendObject(Rjson& obj) { Document* src = obj.GetOriginRapidJson(); for (auto iter = src->MemberBegin(); iter != src->MemberEnd(); ++iter) { if (json->HasMember(iter->name)) { //Key exists, update Value& v = (*json)[iter->name]; v.CopyFrom(iter->value, json->GetAllocator()); //v = (Value&)std::move(vTmp); } else { //Key does not exist, new string* newK = new string(iter->name.GetString()); Value vTmp; vTmp.CopyFrom(iter->value, json->GetAllocator()); json->AddMember(StringRef(newK->c_str()), vTmp, json->GetAllocator()); } } return *(this); }

Use example

Rjson obj; obj.AddValueString("username", "Insert test"); obj.AddValueInt("password", 3245); cout << obj.GetJsonString() << endl; Rjson obj2(obj); Rjson obj3("{\"user\":\"bill\",\"age\":12}");

Project address

https://github.com/zhoutk/Jorm

Series article planning

  • Design of general interface for c + + operational relational database (JSON ORM version c + +)
  • Design and implementation of rjson -- rapid JSON agent
  • Implementation and analysis of SQL it 3 database operation
  • Implementation and analysis of mysql database operation
  • Implementation and analysis of postgres database operation
  • Implementation and analysis of oracle database operation
  • Implementation and analysis of mssql database operation
  • Summary (if required)

feel

This is the first step to encapsulate the database universal access interface, providing convenient json object operation, or writing a json object will be depressing. I miss the feeling of operating json in javascript, silky lubrication

27 June 2020, 21:28 | Views: 1764

Add new comment

For adding a comment, please log in
or create account

0 comments