summaryrefslogtreecommitdiffstats
path: root/common/storage_common.cpp
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2016-10-16 14:55:20 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2016-10-21 09:02:21 +0200
commit237b9ae4113e7a9f489632296941becb71afdb45 (patch)
tree01cde58f495944f01cad9d282391d4efd2897141 /common/storage_common.cpp
parent95d11bf0be98a4e3c08502fe23417b800233ce14 (diff)
downloadsink-237b9ae4113e7a9f489632296941becb71afdb45.tar.gz
sink-237b9ae4113e7a9f489632296941becb71afdb45.zip
Refactor how the storage is used.
This is the initial refactoring to improve how we deal with the storage. It does a couple of things: * Rename Sink::Storage to Sink::Storage::DataStore to free up the Sink::Storage namespace * Introduce a Sink::ResourceContext to have a single object that can be passed around containing everything that is necessary to operate on a resource. This is a lot better than the multiple separate parameters that we used to pass around all over the place, while still allowing for dependency injection for tests. * Tie storage access together using the new EntityStore that directly works with ApplicationDomainTypes. This gives us a central place where main storage, indexes and buffer adaptors are tied together, which will also give us a place to implement external indexes, such as a fulltextindex using xapian. * Use ApplicationDomainTypes as the default way to pass around entities. Instead of using various ways to pass around entities (buffers, buffer adaptors, ApplicationDomainTypes), only use a single way. The old approach was confusing, and was only done as: * optimization; really shouldn't be necessary and otherwise I'm sure we can find better ways to optimize ApplicationDomainType itself. * a way to account for entities that have multiple buffers, a concept that I no longer deem relevant. While this commit does the bulk of the work to get there, the following commits will refactor more stuff to get things back to normal.
Diffstat (limited to 'common/storage_common.cpp')
-rw-r--r--common/storage_common.cpp50
1 files changed, 26 insertions, 24 deletions
diff --git a/common/storage_common.cpp b/common/storage_common.cpp
index 1f2594e..60ef83d 100644
--- a/common/storage_common.cpp
+++ b/common/storage_common.cpp
@@ -27,26 +27,27 @@
27SINK_DEBUG_AREA("storage") 27SINK_DEBUG_AREA("storage")
28 28
29namespace Sink { 29namespace Sink {
30namespace Storage {
30 31
31static const char *s_internalPrefix = "__internal"; 32static const char *s_internalPrefix = "__internal";
32static const int s_internalPrefixSize = strlen(s_internalPrefix); 33static const int s_internalPrefixSize = strlen(s_internalPrefix);
33 34
34void errorHandler(const Storage::Error &error) 35void errorHandler(const DataStore::Error &error)
35{ 36{
36 SinkWarning() << "Database error in " << error.store << ", code " << error.code << ", message: " << error.message; 37 SinkWarning() << "Database error in " << error.store << ", code " << error.code << ", message: " << error.message;
37} 38}
38 39
39std::function<void(const Storage::Error &error)> Storage::basicErrorHandler() 40std::function<void(const DataStore::Error &error)> DataStore::basicErrorHandler()
40{ 41{
41 return errorHandler; 42 return errorHandler;
42} 43}
43 44
44void Storage::setDefaultErrorHandler(const std::function<void(const Storage::Error &error)> &errorHandler) 45void DataStore::setDefaultErrorHandler(const std::function<void(const DataStore::Error &error)> &errorHandler)
45{ 46{
46 mErrorHandler = errorHandler; 47 mErrorHandler = errorHandler;
47} 48}
48 49
49std::function<void(const Storage::Error &error)> Storage::defaultErrorHandler() const 50std::function<void(const DataStore::Error &error)> DataStore::defaultErrorHandler() const
50{ 51{
51 if (mErrorHandler) { 52 if (mErrorHandler) {
52 return mErrorHandler; 53 return mErrorHandler;
@@ -54,12 +55,12 @@ std::function<void(const Storage::Error &error)> Storage::defaultErrorHandler()
54 return basicErrorHandler(); 55 return basicErrorHandler();
55} 56}
56 57
57void Storage::setMaxRevision(Sink::Storage::Transaction &transaction, qint64 revision) 58void DataStore::setMaxRevision(DataStore::Transaction &transaction, qint64 revision)
58{ 59{
59 transaction.openDatabase().write("__internal_maxRevision", QByteArray::number(revision)); 60 transaction.openDatabase().write("__internal_maxRevision", QByteArray::number(revision));
60} 61}
61 62
62qint64 Storage::maxRevision(const Sink::Storage::Transaction &transaction) 63qint64 DataStore::maxRevision(const DataStore::Transaction &transaction)
63{ 64{
64 qint64 r = 0; 65 qint64 r = 0;
65 transaction.openDatabase().scan("__internal_maxRevision", 66 transaction.openDatabase().scan("__internal_maxRevision",
@@ -68,19 +69,19 @@ qint64 Storage::maxRevision(const Sink::Storage::Transaction &transaction)
68 return false; 69 return false;
69 }, 70 },
70 [](const Error &error) { 71 [](const Error &error) {
71 if (error.code != Sink::Storage::NotFound) { 72 if (error.code != DataStore::NotFound) {
72 SinkWarning() << "Coultn'd find the maximum revision."; 73 SinkWarning() << "Coultn'd find the maximum revision.";
73 } 74 }
74 }); 75 });
75 return r; 76 return r;
76} 77}
77 78
78void Storage::setCleanedUpRevision(Sink::Storage::Transaction &transaction, qint64 revision) 79void DataStore::setCleanedUpRevision(DataStore::Transaction &transaction, qint64 revision)
79{ 80{
80 transaction.openDatabase().write("__internal_cleanedUpRevision", QByteArray::number(revision)); 81 transaction.openDatabase().write("__internal_cleanedUpRevision", QByteArray::number(revision));
81} 82}
82 83
83qint64 Storage::cleanedUpRevision(const Sink::Storage::Transaction &transaction) 84qint64 DataStore::cleanedUpRevision(const DataStore::Transaction &transaction)
84{ 85{
85 qint64 r = 0; 86 qint64 r = 0;
86 transaction.openDatabase().scan("__internal_cleanedUpRevision", 87 transaction.openDatabase().scan("__internal_cleanedUpRevision",
@@ -89,14 +90,14 @@ qint64 Storage::cleanedUpRevision(const Sink::Storage::Transaction &transaction)
89 return false; 90 return false;
90 }, 91 },
91 [](const Error &error) { 92 [](const Error &error) {
92 if (error.code != Sink::Storage::NotFound) { 93 if (error.code != DataStore::NotFound) {
93 SinkWarning() << "Coultn'd find the maximum revision."; 94 SinkWarning() << "Coultn'd find the maximum revision.";
94 } 95 }
95 }); 96 });
96 return r; 97 return r;
97} 98}
98 99
99QByteArray Storage::getUidFromRevision(const Sink::Storage::Transaction &transaction, qint64 revision) 100QByteArray DataStore::getUidFromRevision(const DataStore::Transaction &transaction, qint64 revision)
100{ 101{
101 QByteArray uid; 102 QByteArray uid;
102 transaction.openDatabase("revisions") 103 transaction.openDatabase("revisions")
@@ -109,7 +110,7 @@ QByteArray Storage::getUidFromRevision(const Sink::Storage::Transaction &transac
109 return uid; 110 return uid;
110} 111}
111 112
112QByteArray Storage::getTypeFromRevision(const Sink::Storage::Transaction &transaction, qint64 revision) 113QByteArray DataStore::getTypeFromRevision(const DataStore::Transaction &transaction, qint64 revision)
113{ 114{
114 QByteArray type; 115 QByteArray type;
115 transaction.openDatabase("revisionType") 116 transaction.openDatabase("revisionType")
@@ -122,25 +123,25 @@ QByteArray Storage::getTypeFromRevision(const Sink::Storage::Transaction &transa
122 return type; 123 return type;
123} 124}
124 125
125void Storage::recordRevision(Sink::Storage::Transaction &transaction, qint64 revision, const QByteArray &uid, const QByteArray &type) 126void DataStore::recordRevision(DataStore::Transaction &transaction, qint64 revision, const QByteArray &uid, const QByteArray &type)
126{ 127{
127 // TODO use integerkeys 128 // TODO use integerkeys
128 transaction.openDatabase("revisions").write(QByteArray::number(revision), uid); 129 transaction.openDatabase("revisions").write(QByteArray::number(revision), uid);
129 transaction.openDatabase("revisionType").write(QByteArray::number(revision), type); 130 transaction.openDatabase("revisionType").write(QByteArray::number(revision), type);
130} 131}
131 132
132void Storage::removeRevision(Sink::Storage::Transaction &transaction, qint64 revision) 133void DataStore::removeRevision(DataStore::Transaction &transaction, qint64 revision)
133{ 134{
134 transaction.openDatabase("revisions").remove(QByteArray::number(revision)); 135 transaction.openDatabase("revisions").remove(QByteArray::number(revision));
135 transaction.openDatabase("revisionType").remove(QByteArray::number(revision)); 136 transaction.openDatabase("revisionType").remove(QByteArray::number(revision));
136} 137}
137 138
138bool Storage::isInternalKey(const char *key) 139bool DataStore::isInternalKey(const char *key)
139{ 140{
140 return key && strncmp(key, s_internalPrefix, s_internalPrefixSize) == 0; 141 return key && strncmp(key, s_internalPrefix, s_internalPrefixSize) == 0;
141} 142}
142 143
143bool Storage::isInternalKey(void *key, int size) 144bool DataStore::isInternalKey(void *key, int size)
144{ 145{
145 if (size < 1) { 146 if (size < 1) {
146 return false; 147 return false;
@@ -149,39 +150,39 @@ bool Storage::isInternalKey(void *key, int size)
149 return key && strncmp(static_cast<char *>(key), s_internalPrefix, (size > s_internalPrefixSize ? s_internalPrefixSize : size)) == 0; 150 return key && strncmp(static_cast<char *>(key), s_internalPrefix, (size > s_internalPrefixSize ? s_internalPrefixSize : size)) == 0;
150} 151}
151 152
152bool Storage::isInternalKey(const QByteArray &key) 153bool DataStore::isInternalKey(const QByteArray &key)
153{ 154{
154 return key.startsWith(s_internalPrefix); 155 return key.startsWith(s_internalPrefix);
155} 156}
156 157
157QByteArray Storage::assembleKey(const QByteArray &key, qint64 revision) 158QByteArray DataStore::assembleKey(const QByteArray &key, qint64 revision)
158{ 159{
159 Q_ASSERT(revision <= 9223372036854775807); 160 Q_ASSERT(revision <= 9223372036854775807);
160 Q_ASSERT(key.size() == 38); 161 Q_ASSERT(key.size() == 38);
161 return key + QByteArray::number(revision).rightJustified(19, '0', false); 162 return key + QByteArray::number(revision).rightJustified(19, '0', false);
162} 163}
163 164
164QByteArray Storage::uidFromKey(const QByteArray &key) 165QByteArray DataStore::uidFromKey(const QByteArray &key)
165{ 166{
166 return key.mid(0, 38); 167 return key.mid(0, 38);
167} 168}
168 169
169qint64 Storage::revisionFromKey(const QByteArray &key) 170qint64 DataStore::revisionFromKey(const QByteArray &key)
170{ 171{
171 return key.mid(39).toLongLong(); 172 return key.mid(39).toLongLong();
172} 173}
173 174
174QByteArray Storage::generateUid() 175QByteArray DataStore::generateUid()
175{ 176{
176 return QUuid::createUuid().toByteArray(); 177 return QUuid::createUuid().toByteArray();
177} 178}
178 179
179Storage::NamedDatabase Storage::mainDatabase(const Sink::Storage::Transaction &t, const QByteArray &type) 180DataStore::NamedDatabase DataStore::mainDatabase(const DataStore::Transaction &t, const QByteArray &type)
180{ 181{
181 return t.openDatabase(type + ".main"); 182 return t.openDatabase(type + ".main");
182} 183}
183 184
184bool Storage::NamedDatabase::contains(const QByteArray &uid) 185bool DataStore::NamedDatabase::contains(const QByteArray &uid)
185{ 186{
186 bool found = false; 187 bool found = false;
187 scan(uid, 188 scan(uid,
@@ -189,8 +190,9 @@ bool Storage::NamedDatabase::contains(const QByteArray &uid)
189 found = true; 190 found = true;
190 return false; 191 return false;
191 }, 192 },
192 [this](const Sink::Storage::Error &error) {}, true); 193 [this](const DataStore::Error &error) {}, true);
193 return found; 194 return found;
194} 195}
195 196
197}
196} // namespace Sink 198} // namespace Sink