diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-10-16 14:55:20 +0200 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-10-21 09:02:21 +0200 |
commit | 237b9ae4113e7a9f489632296941becb71afdb45 (patch) | |
tree | 01cde58f495944f01cad9d282391d4efd2897141 /common/storage_common.cpp | |
parent | 95d11bf0be98a4e3c08502fe23417b800233ce14 (diff) | |
download | sink-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.cpp | 50 |
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 @@ | |||
27 | SINK_DEBUG_AREA("storage") | 27 | SINK_DEBUG_AREA("storage") |
28 | 28 | ||
29 | namespace Sink { | 29 | namespace Sink { |
30 | namespace Storage { | ||
30 | 31 | ||
31 | static const char *s_internalPrefix = "__internal"; | 32 | static const char *s_internalPrefix = "__internal"; |
32 | static const int s_internalPrefixSize = strlen(s_internalPrefix); | 33 | static const int s_internalPrefixSize = strlen(s_internalPrefix); |
33 | 34 | ||
34 | void errorHandler(const Storage::Error &error) | 35 | void 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 | ||
39 | std::function<void(const Storage::Error &error)> Storage::basicErrorHandler() | 40 | std::function<void(const DataStore::Error &error)> DataStore::basicErrorHandler() |
40 | { | 41 | { |
41 | return errorHandler; | 42 | return errorHandler; |
42 | } | 43 | } |
43 | 44 | ||
44 | void Storage::setDefaultErrorHandler(const std::function<void(const Storage::Error &error)> &errorHandler) | 45 | void DataStore::setDefaultErrorHandler(const std::function<void(const DataStore::Error &error)> &errorHandler) |
45 | { | 46 | { |
46 | mErrorHandler = errorHandler; | 47 | mErrorHandler = errorHandler; |
47 | } | 48 | } |
48 | 49 | ||
49 | std::function<void(const Storage::Error &error)> Storage::defaultErrorHandler() const | 50 | std::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 | ||
57 | void Storage::setMaxRevision(Sink::Storage::Transaction &transaction, qint64 revision) | 58 | void 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 | ||
62 | qint64 Storage::maxRevision(const Sink::Storage::Transaction &transaction) | 63 | qint64 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 | ||
78 | void Storage::setCleanedUpRevision(Sink::Storage::Transaction &transaction, qint64 revision) | 79 | void 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 | ||
83 | qint64 Storage::cleanedUpRevision(const Sink::Storage::Transaction &transaction) | 84 | qint64 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 | ||
99 | QByteArray Storage::getUidFromRevision(const Sink::Storage::Transaction &transaction, qint64 revision) | 100 | QByteArray 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 | ||
112 | QByteArray Storage::getTypeFromRevision(const Sink::Storage::Transaction &transaction, qint64 revision) | 113 | QByteArray 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 | ||
125 | void Storage::recordRevision(Sink::Storage::Transaction &transaction, qint64 revision, const QByteArray &uid, const QByteArray &type) | 126 | void 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 | ||
132 | void Storage::removeRevision(Sink::Storage::Transaction &transaction, qint64 revision) | 133 | void 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 | ||
138 | bool Storage::isInternalKey(const char *key) | 139 | bool 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 | ||
143 | bool Storage::isInternalKey(void *key, int size) | 144 | bool 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 | ||
152 | bool Storage::isInternalKey(const QByteArray &key) | 153 | bool DataStore::isInternalKey(const QByteArray &key) |
153 | { | 154 | { |
154 | return key.startsWith(s_internalPrefix); | 155 | return key.startsWith(s_internalPrefix); |
155 | } | 156 | } |
156 | 157 | ||
157 | QByteArray Storage::assembleKey(const QByteArray &key, qint64 revision) | 158 | QByteArray 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 | ||
164 | QByteArray Storage::uidFromKey(const QByteArray &key) | 165 | QByteArray DataStore::uidFromKey(const QByteArray &key) |
165 | { | 166 | { |
166 | return key.mid(0, 38); | 167 | return key.mid(0, 38); |
167 | } | 168 | } |
168 | 169 | ||
169 | qint64 Storage::revisionFromKey(const QByteArray &key) | 170 | qint64 DataStore::revisionFromKey(const QByteArray &key) |
170 | { | 171 | { |
171 | return key.mid(39).toLongLong(); | 172 | return key.mid(39).toLongLong(); |
172 | } | 173 | } |
173 | 174 | ||
174 | QByteArray Storage::generateUid() | 175 | QByteArray DataStore::generateUid() |
175 | { | 176 | { |
176 | return QUuid::createUuid().toByteArray(); | 177 | return QUuid::createUuid().toByteArray(); |
177 | } | 178 | } |
178 | 179 | ||
179 | Storage::NamedDatabase Storage::mainDatabase(const Sink::Storage::Transaction &t, const QByteArray &type) | 180 | DataStore::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 | ||
184 | bool Storage::NamedDatabase::contains(const QByteArray &uid) | 185 | bool 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 |