Mongodb.h
1 #ifndef MONGODB_H 2 #define MONGODB_H 3 4 #include <bsoncxx/builder/stream/document.hpp> 5 #include <bsoncxx/types.hpp> 6 #include <mongocxx/client.hpp> 7 #include <mongocxx/instance.hpp> 8 #include <mongocxx/uri.hpp> 9 #include <bsoncxx/json.hpp> 10 #include <QString> 11 12 using bsoncxx::builder::stream::document; 13 using bsoncxx::builder::stream::open_document; 14 using bsoncxx::builder::stream::close_document; 15 using bsoncxx::builder::stream::open_array; 16 using bsoncxx::builder::stream::close_array; 17 using bsoncxx::builder::stream::finalize; 18 using namespace mongocxx; 19 using namespace mongocxx::options; 20 using bsoncxx::builder::basic::kvp; 21 using bsoncxx::builder::basic::make_document; 22 using bsoncxx::to_json; 23 24 class Mongodb 25 { 26 protected: 27 mongocxx::instance* m_dbInstance = nullptr; 28 mongocxx::client* m_client = nullptr; 29 30 QString m_hostName; 31 QString m_port; 32 33 public: 34 stdx::optional<bsoncxx::document::value> find_One(QString db,QString coll,document& filter,const mongocxx::v_noabi::options::find& options = mongocxx::v_noabi::options::find()); 35 cursor* find(QString db,QString coll,document& filter,const mongocxx::v_noabi::options::find& options = mongocxx::v_noabi::options::find()); 36 stdx::optional<result::insert_one> insert_One(QString db,QString coll,document& doc,const mongocxx::v_noabi::options::insert& options = {}); 37 stdx::optional<result::update> update_One(QString db,QString coll,document& filter,document& value,const mongocxx::v_noabi::options::update& options = mongocxx::v_noabi::options::update()); 38 stdx::optional<result::update> update_Many(QString db,QString coll,document& filter,document& value,const mongocxx::v_noabi::options::update& options = mongocxx::v_noabi::options::update()); 39 stdx::optional<result::delete_result> delete_One(QString db,QString coll,document& filter,const mongocxx::v_noabi::options::delete_options& options = mongocxx::v_noabi::options::delete_options()); 40 stdx::optional<result::delete_result> delete_Many(QString db,QString coll,document& filter,const mongocxx::v_noabi::options::delete_options& options = mongocxx::v_noabi::options::delete_options()); 41 std::int64_t countDocument(QString db,QString coll,document& filter,const options::count& option = options::count()); 42 43 public: 44 Mongodb(); 45 Mongodb(QString hostName,QString port); 46 void setHostName(QString hostName); 47 void setPort(QString port); 48 void connectToHost(); 49 mongocxx::client* client(); 50 ~Mongodb(); 51 52 static QString getIDInView(const bsoncxx::v_noabi::document::view& view); 53 }; 54 55 #endif // MONGODB_H
Mongodb.cpp
1 #include "Mongodb.h" 2 #include "tinyjson.hpp" 3 4 using namespace tiny; 5 6 Mongodb::Mongodb() 7 { 8 9 } 10 11 Mongodb::Mongodb(QString hostName,QString port) 12 { 13 m_hostName = hostName; 14 m_port = port; 15 } 16 17 void Mongodb::setHostName(QString hostName) 18 { 19 m_hostName = hostName; 20 } 21 22 void Mongodb::setPort(QString port) 23 { 24 m_port = port; 25 } 26 27 void Mongodb::connectToHost() 28 { 29 if((m_hostName != "") && (m_port != "")) 30 { 31 if(m_dbInstance) 32 { 33 delete m_dbInstance; 34 m_dbInstance = nullptr; 35 } 36 37 if(m_client) 38 { 39 delete m_client; 40 m_client = nullptr; 41 } 42 43 m_dbInstance = new(std::nothrow) mongocxx::instance(); 44 m_client = new(std::nothrow) mongocxx::client(mongocxx::uri{("mongodb://" + m_hostName + ":" + m_port).toStdString().c_str()}); 45 } 46 } 47 48 mongocxx::client* Mongodb::client() 49 { 50 return m_client; 51 } 52 53 stdx::optional<bsoncxx::document::value> Mongodb::find_One(QString db,QString coll,document& filter,const mongocxx::v_noabi::options::find& options) 54 { 55 stdx::optional<bsoncxx::document::value> ret; 56 57 if(m_dbInstance && m_client) 58 { 59 return (*m_client)[db.toStdString().c_str()][coll.toStdString().c_str()].find_one(filter.view(),options); 60 } 61 62 return ret; 63 } 64 65 cursor* Mongodb::find(QString db,QString coll,document& filter,const mongocxx::v_noabi::options::find& options) 66 { 67 if(m_dbInstance && m_client) 68 { 69 auto c = (*m_client)[db.toStdString().c_str()][coll.toStdString().c_str()].find(filter.view(),options); 70 return new(std::nothrow) cursor(std::move(c)); 71 } 72 73 return nullptr; 74 } 75 76 stdx::optional<result::insert_one> Mongodb::insert_One(QString db,QString coll,document& doc,const mongocxx::v_noabi::options::insert& options) 77 { 78 stdx::optional<result::insert_one> ret; 79 80 if(m_dbInstance && m_client) 81 { 82 ret = (*m_client)[db.toStdString().c_str()][coll.toStdString().c_str()].insert_one(doc.view(),options); 83 } 84 85 return ret; 86 } 87 88 stdx::optional<result::update> Mongodb::update_One(QString db,QString coll,document& filter,document& value,const mongocxx::v_noabi::options::update& options) 89 { 90 stdx::optional<result::update> ret; 91 if(m_dbInstance && m_client) 92 { 93 ret = (*m_client)[db.toStdString().c_str()][coll.toStdString().c_str()].update_one( 94 filter.view(), 95 make_document(kvp("$set",value)), 96 options 97 ); 98 } 99 100 return ret; 101 } 102 103 stdx::optional<result::update> Mongodb::update_Many(QString db,QString coll,document& filter,document& value,const mongocxx::v_noabi::options::update& options) 104 { 105 stdx::optional<result::update> ret; 106 if(m_dbInstance && m_client) 107 { 108 ret = (*m_client)[db.toStdString().c_str()][coll.toStdString().c_str()].update_many( 109 filter.view(), 110 make_document(kvp("$set",value)), 111 options 112 ); 113 } 114 115 return ret; 116 } 117 118 stdx::optional<result::delete_result> Mongodb::delete_One(QString db,QString coll,document& filter,const mongocxx::v_noabi::options::delete_options& options) 119 { 120 stdx::optional<result::delete_result> ret; 121 122 if(m_dbInstance && m_client) 123 { 124 ret = (*m_client)[db.toStdString().c_str()][coll.toStdString().c_str()].delete_one(filter.view(),options); 125 } 126 127 return ret; 128 } 129 130 stdx::optional<result::delete_result> Mongodb::delete_Many(QString db,QString coll,document& filter,const mongocxx::v_noabi::options::delete_options& options) 131 { 132 stdx::optional<result::delete_result> ret; 133 134 if(m_dbInstance && m_client) 135 { 136 ret = (*m_client)[db.toStdString().c_str()][coll.toStdString().c_str()].delete_many(filter.view(),options); 137 } 138 139 return ret; 140 } 141 142 std::int64_t Mongodb::countDocument(QString db,QString coll,document& filter,const options::count& option) 143 { 144 return (*m_client)[db.toStdString().c_str()][coll.toStdString().c_str()].count_documents(filter.view(),option); 145 } 146 147 Mongodb::~Mongodb() 148 { 149 delete m_dbInstance; 150 delete m_client; 151 } 152 153 QString Mongodb::getIDInView(const bsoncxx::v_noabi::document::view& view) 154 { 155 QString ret = ""; 156 157 auto str = bsoncxx::to_json(view); 158 TinyJson json; 159 json.ReadJson(str); 160 161 auto id = json.Get<std::string>("_id"); 162 TinyJson id_json; 163 id_json.ReadJson(id); 164 ret = id_json.Get<std::string>("$oid").c_str(); 165 166 return ret; 167 }
tinyjson.hpp(来自github)
https://github.com/button-chen/tinyjson
1 /** 2 * 3 * tiny::TinyJson library 4 * Copyright 2017 Button 5 * 6 */ 7 8 #ifndef TINY_JSON_H_ 9 #define TINY_JSON_H_ 10 11 #include <string> 12 #include <sstream> 13 #include <map> 14 #include <vector> 15 #include <algorithm> 16 #include <iostream> 17 18 namespace tiny { 19 20 /** 21 * 无类型,解析时确认 22 * 23 */ 24 class Value 25 { 26 public: 27 Value() { 28 value_.clear(); 29 nokey_ = false; 30 } 31 Value(std::string val) : value_(val) { 32 if (value_ == "") { 33 value_.clear(); 34 nokey_ = true; 35 } 36 else { 37 nokey_ = false; 38 } 39 } 40 ~Value() {} 41 42 public: 43 std::string value() { return value_; } 44 template<typename R> 45 R GetAs() { 46 std::istringstream iss(value_); 47 R v; 48 iss >> v; 49 return v; 50 } 51 52 53 template<typename V> 54 void Set(V v) { 55 std::ostringstream oss; 56 if (nokey_) { 57 oss << v; 58 } 59 else { 60 oss << """ << value_ << """ << ":" << v; 61 } 62 value_ = oss.str(); 63 } 64 65 template<typename T> 66 void Push(T& v) { 67 std::ostringstream oss; 68 if (v.get_nokey()) { 69 oss << v.WriteJson(0); 70 } 71 else { 72 oss << v.WriteJson(1); 73 } 74 value_ = oss.str(); 75 } 76 77 private: 78 std::string value_; 79 bool nokey_; 80 }; 81 82 template<> inline bool Value::GetAs() { return value_ == "true" ? true : false; } 83 template<> inline std::string Value::GetAs() { return value_; } 84 template<> 85 inline void Value::Set(std::string v) { 86 std::ostringstream oss; 87 if (nokey_) { 88 oss << """ << v << """; 89 } 90 else { 91 oss << """ << value_ << """ << ":" << """ << v << """; 92 } 93 value_ = oss.str(); 94 } 95 96 template<> 97 inline void Value::Set(const char* v) { 98 Set(std::string(v)); 99 } 100 101 template<> 102 inline void Value::Set(bool v) { 103 std::ostringstream oss; 104 std::string val = v == true ? "true" : "false"; 105 if (nokey_) { 106 oss << val; 107 } 108 else { 109 oss << """ << value_ << """ << ":" << val; 110 } 111 value_ = oss.str(); 112 } 113 114 /** 115 * 此模板类处理json键对应的值是一个嵌套对象或者数组的情况 116 * 117 */ 118 template<typename T> 119 class ValueArray : public T 120 { 121 public: 122 ValueArray() {} 123 ValueArray(std::vector<std::string> vo) { vo_ = vo; } 124 125 bool Enter(int i) { 126 std::string obj = vo_[i]; 127 return this->ReadJson(obj); 128 } 129 130 int Count() { return vo_.size(); } 131 132 private: 133 std::vector<std::string> vo_; 134 }; 135 136 /** 137 * 解析json字符串保存为键值的顺序存储,解析是按一层一层的进行 138 * 解析时把json看做是对象'{}' 与 数组'[]' 的组合 139 * 140 */ 141 class ParseJson 142 { 143 public: 144 ParseJson() {} 145 ~ParseJson() {} 146 147 public: 148 bool ParseArray(std::string json, std::vector<std::string>& vo); 149 bool ParseObj(std::string json); 150 std::vector<std::string> GetKeyVal() { 151 return keyval_; 152 } 153 154 protected: 155 std::string Trims(std::string s, char lc, char rc); 156 int GetFirstNotSpaceChar(std::string& s, int cur); 157 std::string FetchArrayStr(std::string inputstr, int inpos, int& offset); 158 std::string FetchObjStr(std::string inputstr, int inpos, int& offset); 159 std::string FetchStrStr(std::string inputstr, int inpos, int& offset); 160 std::string FetchNumStr(std::string inputstr, int inpos, int& offset); 161 162 private: 163 std::vector<char> token_; 164 std::vector<std::string> keyval_; 165 }; 166 167 inline bool ParseJson::ParseArray(std::string json, std::vector<std::string>& vo) { 168 json = Trims(json, '[', ']'); 169 std::string tokens; 170 size_t i = 0; 171 for (; i < json.size(); ++i) { 172 char c = json[i]; 173 if (isspace(c) || c == '"') continue; 174 if (c == ':' || c == ',' || c == '{') { 175 if (!tokens.empty()) { 176 vo.push_back(tokens); 177 tokens.clear(); 178 } 179 if (c == ',') continue; 180 int offset = 0; 181 char nextc = c; 182 for (; c != '{';) { 183 nextc = json[++i]; 184 if (isspace(nextc)) continue; 185 break; 186 } 187 if (nextc == '{') { 188 tokens = FetchObjStr(json, i, offset); 189 } 190 else if (nextc == '[') { 191 tokens = FetchArrayStr(json, i, offset); 192 } 193 i += offset; 194 continue; 195 } 196 tokens.push_back(c); 197 } 198 if (!tokens.empty()) { 199 vo.push_back(tokens); 200 } 201 return true; 202 } 203 204 // 解析为 key-value 调用一次解析一个层次 205 inline bool ParseJson::ParseObj(std::string json) { 206 auto LastValidChar = [&](int index)->char{ 207 for (int i = index-1; i >= 0; --i){ 208 if (isspace(json[i])) continue; 209 char tmp = json[i]; 210 return tmp; 211 } 212 return '