summaryrefslogtreecommitdiffstats
path: root/common/storage_unqlite.cpp
diff options
context:
space:
mode:
authorAaron Seigo <aseigo@kde.org>2014-12-07 10:08:07 +0100
committerAaron Seigo <aseigo@kde.org>2014-12-11 01:07:08 +0100
commit9ee8378d393778ac67314be7ea8d5bcbaeee9ee0 (patch)
treecf93471a69f9f4bbb4940de55ae134106fcd8380 /common/storage_unqlite.cpp
parentee6f068dff6b15441e553ffbfb2bf8aa97b26f57 (diff)
downloadsink-9ee8378d393778ac67314be7ea8d5bcbaeee9ee0.tar.gz
sink-9ee8378d393778ac67314be7ea8d5bcbaeee9ee0.zip
try out unqlite
Diffstat (limited to 'common/storage_unqlite.cpp')
-rw-r--r--common/storage_unqlite.cpp221
1 files changed, 221 insertions, 0 deletions
diff --git a/common/storage_unqlite.cpp b/common/storage_unqlite.cpp
new file mode 100644
index 0000000..d0eaa38
--- /dev/null
+++ b/common/storage_unqlite.cpp
@@ -0,0 +1,221 @@
1#include "storage.h"
2
3#include <iostream>
4
5#include <QAtomicInt>
6#include <QDebug>
7#include <QDir>
8#include <QFileInfo>
9#include <QReadWriteLock>
10#include <QString>
11#include <QTime>
12
13#include <unqlite/unqlite.h>
14
15class Storage::Private
16{
17public:
18 Private(const QString &storageRoot, const QString &name, AccessMode m);
19 ~Private();
20
21 QString name;
22 kyotocabinet::TreeDB db;
23 AccessMode mode;
24 bool dbOpen;
25 bool inTransaction;
26};
27
28Storage::Private::Private(const QString &storageRoot, const QString &n, AccessMode m)
29 : name(n),
30 mode(m),
31 dbOpen(false),
32 inTransaction(false)
33{
34 QDir dir;
35 dir.mkdir(storageRoot);
36
37 //create file
38 uint32_t openMode = kyotocabinet::BasicDB::OCREATE |
39 (mode == ReadOnly ? kyotocabinet::BasicDB::OREADER
40 : kyotocabinet::BasicDB::OWRITER);
41 dbOpen = db.open((storageRoot + "/" + name + ".kch").toStdString(), openMode);
42 if (!dbOpen) {
43 std::cerr << "Could not open database: " << db.error().codename(db.error().code()) << " " << db.error().message() << std::endl;
44 // TODO: handle error
45 }
46}
47
48Storage::Private::~Private()
49{
50 if (dbOpen && inTransaction) {
51 db.end_transaction(false);
52 }
53}
54
55Storage::Storage(const QString &storageRoot, const QString &name, AccessMode mode)
56 : d(new Private(storageRoot, name, mode))
57{
58}
59
60Storage::~Storage()
61{
62 delete d;
63}
64
65bool Storage::isInTransaction() const
66{
67 return d->inTransaction;
68}
69
70bool Storage::startTransaction(AccessMode type)
71{
72 if (!d->dbOpen) {
73 return false;
74 }
75
76 if (type == ReadWrite && d->mode != ReadWrite) {
77 return false;
78 }
79
80 if (d->inTransaction) {
81 return true;
82 }
83
84 //TODO handle errors
85 d->inTransaction = d->db.begin_transaction();
86 return d->inTransaction;
87}
88
89bool Storage::commitTransaction()
90{
91 if (!d->dbOpen) {
92 return false;
93 }
94
95 if (!d->inTransaction) {
96 return false;
97 }
98
99 bool success = d->db.end_transaction(true);
100 d->inTransaction = false;
101 return success;
102}
103
104void Storage::abortTransaction()
105{
106 if (!d->dbOpen || !d->inTransaction) {
107 return;
108 }
109
110 d->db.end_transaction(false);
111 d->inTransaction = false;
112}
113
114bool Storage::write(const char *key, size_t keySize, const char *value, size_t valueSize)
115{
116 if (!d->dbOpen) {
117 return false;
118 }
119
120 bool success = d->db.set(key, keySize, value, valueSize);
121 return success;
122}
123
124bool Storage::write(const std::string &sKey, const std::string &sValue)
125{
126 if (!d->dbOpen) {
127 return false;
128 }
129
130 bool success = d->db.set(sKey, sValue);
131 return success;
132}
133
134void Storage::read(const std::string &sKey,
135 const std::function<bool(const std::string &value)> &resultHandler,
136 const std::function<void(const Storage::Error &error)> &errorHandler)
137{
138 if (!d->dbOpen) {
139 Error error(d->name.toStdString(), -1, "Not open");
140 errorHandler(error);
141 return;
142 }
143
144 std::string value;
145 if (sKey.empty()) {
146 kyotocabinet::DB::Cursor *cursor = d->db.cursor();
147 cursor->jump();
148
149 std::string key, value;
150 while (cursor->get_value(&value, true) && resultHandler(value)) {}
151
152 delete cursor;
153 return;
154 } else {
155 if (d->db.get(sKey, &value)) {
156 resultHandler(value);
157 return;
158 }
159 }
160
161 Error error(d->name.toStdString(), d->db.error().code(), d->db.error().message());
162 errorHandler(error);
163}
164
165void Storage::read(const std::string &sKey,
166 const std::function<bool(void *ptr, int size)> &resultHandler,
167 const std::function<void(const Storage::Error &error)> &errorHandler)
168{
169 if (!d->dbOpen) {
170 Error error(d->name.toStdString(), -1, "Not open");
171 errorHandler(error);
172 return;
173 }
174
175 size_t valueSize;
176 char *valueBuffer;
177 if (sKey.empty()) {
178 kyotocabinet::DB::Cursor *cursor = d->db.cursor();
179 cursor->jump();
180
181 while ((valueBuffer = cursor->get_value(&valueSize, true))) {
182 bool ok = resultHandler(valueBuffer, valueSize);
183 delete[] valueBuffer;
184 if (!ok) {
185 break;
186 }
187 }
188
189 delete cursor;
190 } else {
191 valueBuffer = d->db.get(sKey.data(), sKey.size(), &valueSize);
192 if (valueBuffer) {
193 resultHandler(valueBuffer, valueSize);
194 } else {
195 Error error(d->name.toStdString(), d->db.error().code(), d->db.error().message());
196 errorHandler(error);
197 }
198 delete[] valueBuffer;
199 }
200}
201
202qint64 Storage::diskUsage() const
203{
204 if (!d->dbOpen) {
205 return 0;
206 }
207
208 QFileInfo info(QString::fromStdString(d->db.path()));
209 return info.size();
210}
211
212void Storage::removeFromDisk() const
213{
214 if (!d->dbOpen) {
215 return;
216 }
217
218 QFileInfo info(QString::fromStdString(d->db.path()));
219 QDir dir = info.dir();
220 dir.remove(info.fileName());
221}