! 4 space instead of tab & remove global std
[scx.git] / include / SqliteKV.hpp
blob17139a5465a242e77f563e987c2540e35a5a8fb8
1 #ifndef SCX_SQLITEKV_HPP
2 #define SCX_SQLITEKV_HPP
4 #include <sqlite3.h>
5 #include <zlib.h>
6 #include <string>
7 #include <cstdio>
8 #include <cstring>
10 namespace scx {
12 class SqliteKV
14 public:
15 SqliteKV(const std::string& dbName = ""):
16 BEGIN_TRANSACTION("BEGIN;"),
17 COMMIT_TRANSACTION("COMMIT;"),
18 CREATE_TABLE("create table if not exists %s(KEY text primary key, VALUE blob);"),
19 DROP_TABLE("drop table if exists %s;"),
20 INSERT_PAIR("insert into %s values('%s', ?);"),
21 SELECT_VALUE("select VALUE from %s where KEY='%s';"),
22 UPDATE_VALUE("update %s set VALUE=? where KEY='%s';"),
23 DROP_PAIR("drop from %s where KEY='%s';"),
24 COUNT_PAIRS("select count(key) from %s;"),
25 COUNT_RESULTS("select count(key) from %s where KEY='%s';"),
26 mDbName(dbName),
27 mTableName(""),
28 mDb(NULL),
29 mSqlBufLen(200),
30 mSqlBuf(new char[200])
32 if (!mDbName.empty())
33 OpenDb(mDbName);
36 ~SqliteKV()
38 if (!mDbName.empty())
39 CloseDb();
40 if (mSqlBuf != NULL)
41 delete mSqlBuf;
44 void OpenDb(const std::string& dbName)
46 mDbName = dbName;
47 sqlite3_open(mDbName.c_str(), &mDb);
49 sqlite3_exec(mDb, "PRAGMA journal_mode=off;", NULL, 0, 0);
50 sqlite3_exec(mDb, "PRAGMA synchronous=off;", NULL, 0, 0);
51 sqlite3_exec(mDb, "PRAGMA cache_size=8000;", NULL, 0, 0);
52 //sqlite3_exec(mDb, "PRAGMA page_size=2048;", NULL, 0, 0);
53 //sqlite3_exec(mDb, "PRAGMA page_count=200;", NULL, 0, 0);
56 void CloseDb()
58 mDbName.clear();
59 sqlite3_finalize(mStmt);
60 sqlite3_close(mDb);
63 // switch table (if the targe table doesn't exist, I'll create it before switch)
64 void SwitchTable(const std::string& tableName)
66 mTableName = tableName;
67 CheckSqlBuf(CREATE_TABLE.size() + mTableName.size());
68 snprintf(mSqlBuf, mSqlBufLen, CREATE_TABLE.c_str(), tableName.c_str());
69 sqlite3_exec(mDb, mSqlBuf, NULL, 0, 0);
72 // drop the current table
73 void DropTable()
75 CheckSqlBuf(DROP_TABLE.size() + mTableName.size());
76 snprintf(mSqlBuf, mSqlBufLen, DROP_TABLE.c_str(), mTableName.c_str());
77 sqlite3_exec(mDb, mSqlBuf, NULL, 0, 0);
80 void Begin()
82 sqlite3_exec(mDb, BEGIN_TRANSACTION.c_str(), NULL, 0, 0);
85 void Commit()
87 sqlite3_exec(mDb, COMMIT_TRANSACTION.c_str(), NULL, 0, 0);
90 /* put family */
92 // put fixed-size data, by sizeof(T)
93 template<typename T>
94 bool PutData(const std::string& key, const T& data)
96 return PutRaw(key, (char*)&data, sizeof(T));
99 // put string data
100 bool PutString(const std::string& key, const std::string& text)
102 return PutRaw(key, text.c_str(), text.size());
105 // put raw data
106 bool PutRaw(const std::string& key, const char* raw, int size)
108 CheckSqlBuf(INSERT_PAIR.size() + mTableName.size() + key.size());
109 snprintf(mSqlBuf, mSqlBufLen, INSERT_PAIR.c_str(), mTableName.c_str(), key.c_str());
110 sqlite3_prepare_v2(mDb, mSqlBuf, -1, &mStmt, 0);
111 sqlite3_bind_blob(mStmt, 1, raw, size, SQLITE_STATIC);
112 sqlite3_step(mStmt);
113 sqlite3_finalize(mStmt);
114 return sqlite3_changes(mDb) == 0;
117 /* get family */
119 // get type data
120 template<class T>
121 bool GetData(const std::string& key, T& data)
123 const void* blob;
124 int size;
125 if (GetBlob(key, blob, size))
127 memcpy(&data, blob, size);
128 return true;
130 else
132 return false;
136 // get string data
137 bool GetString(const std::string& key, std::string& text)
139 const void* blob;
140 int size;
141 if (GetBlob(key, blob, size))
143 text.assign((const char*)blob, size);
144 return true;
146 else
148 return false;
152 // get raw data, false if null or not found
153 bool GetRaw(const std::string& key, char*& raw, int& size)
155 const void* blob;
156 if (GetBlob(key, blob, size))
158 raw = new char[size];
159 memcpy(raw, blob, size);
160 return true;
162 else
164 return false;
168 /* update family */
170 template<typename T>
171 bool UpdateData(const std::string& key, const T& data)
173 return UpdateRaw(key, (char*)&data, sizeof(T));
176 bool UpdateString(const std::string& key, const std::string& text)
178 return UpdateRaw(key, text.c_str(), text.size());
181 bool UpdateRaw(const std::string& key, const char* raw, int size)
183 //CheckSqlBuf(UPDATE_VALUE.size() + mTableName.size() + key.size());
184 snprintf(mSqlBuf, mSqlBufLen, UPDATE_VALUE.c_str(), mTableName.c_str(), key.c_str());
185 sqlite3_prepare_v2(mDb, mSqlBuf, -1, &mStmt, 0);
186 sqlite3_bind_blob(mStmt, 1, raw, size, SQLITE_STATIC);
187 sqlite3_step(mStmt);
188 return true;
191 // delete pair by key
192 bool Delete(const std::string& key)
194 CheckSqlBuf(DROP_TABLE.size() + mTableName.size());
195 snprintf(mSqlBuf, mSqlBufLen, DROP_TABLE.c_str(), mTableName.c_str());
196 sqlite3_exec(mDb, mSqlBuf, NULL, 0, 0);
197 return true;
200 // number of pairs in table
201 int Count()
203 CheckSqlBuf(COUNT_PAIRS.size() + mTableName.size());
204 snprintf(mSqlBuf, mSqlBufLen, COUNT_PAIRS.c_str(), mTableName.c_str());
205 sqlite3_prepare_v2(mDb, mSqlBuf, -1, &mStmt, 0);
206 sqlite3_step(mStmt);
207 return sqlite3_column_int(mStmt, 0);
210 private:
211 void CheckSqlBuf(size_t len)
214 if (mSqlBufLen < len)
216 delete mSqlBuf;
217 mSqlBuf = new char[len];
218 mSqlBufLen = len;
223 bool GetBlob(const std::string& key, const void*& blob, int& size)
225 CheckSqlBuf(SELECT_VALUE.size() + mTableName.size() + key.size());
226 snprintf(mSqlBuf, mSqlBufLen, SELECT_VALUE.c_str(), mTableName.c_str(), key.c_str());
227 sqlite3_prepare_v2(mDb, mSqlBuf, -1, &mStmt, 0);
228 sqlite3_step(mStmt);
229 blob = sqlite3_column_blob(mStmt, 0);
230 size = sqlite3_column_bytes(mStmt, 0);
231 return (blob != NULL);
234 private:
235 static int OnRow(void*, int argc, char** argv, char** colName)
237 return 0;
240 private:
241 const std::string BEGIN_TRANSACTION;
242 const std::string COMMIT_TRANSACTION;
243 const std::string CREATE_TABLE;
244 const std::string DROP_TABLE;
245 const std::string INSERT_PAIR;
246 const std::string SELECT_VALUE;
247 const std::string UPDATE_VALUE;
248 const std::string DROP_PAIR;
249 const std::string COUNT_PAIRS;
250 const std::string COUNT_RESULTS;
252 private:
253 std::string mDbName;
254 std::string mTableName;
255 sqlite3* mDb;
256 sqlite3_stmt* mStmt;
257 size_t mSqlBufLen;
258 char* mSqlBuf;
263 #endif