10
10
#include " td/db/SqliteStatement.h"
11
11
12
12
#include " td/utils/logging.h"
13
- #include " td/utils/ScopeGuard.h"
14
13
#include " td/utils/Slice.h"
15
14
#include " td/utils/Status.h"
16
15
@@ -20,106 +19,43 @@ namespace td {
20
19
21
20
class SqliteKeyValue {
22
21
public:
23
- static Status drop (SqliteDb &connection, Slice kv_name ) TD_WARN_UNUSED_RESULT {
24
- return connection.exec (PSLICE () << " DROP TABLE IF EXISTS " << kv_name );
22
+ static Status drop (SqliteDb &connection, Slice table_name ) TD_WARN_UNUSED_RESULT {
23
+ return connection.exec (PSLICE () << " DROP TABLE IF EXISTS " << table_name );
25
24
}
26
25
27
- static Status init (SqliteDb &connection, Slice kv_name ) TD_WARN_UNUSED_RESULT {
28
- return connection.exec (PSLICE () << " CREATE TABLE IF NOT EXISTS " << kv_name << " (k BLOB PRIMARY KEY, v BLOB)" );
26
+ static Status init (SqliteDb &connection, Slice table_name ) TD_WARN_UNUSED_RESULT {
27
+ return connection.exec (PSLICE () << " CREATE TABLE IF NOT EXISTS " << table_name << " (k BLOB PRIMARY KEY, v BLOB)" );
29
28
}
30
29
31
30
using SeqNo = uint64;
32
- Result<bool > init (string name) TD_WARN_UNUSED_RESULT {
33
- name_ = std::move (name);
34
- bool is_created = false ;
35
- SqliteDb db;
36
- TRY_STATUS (db.init (name, &is_created));
37
- TRY_STATUS (db.exec (" PRAGMA encoding=\" UTF-8\" " ));
38
- TRY_STATUS (db.exec (" PRAGMA synchronous=NORMAL" ));
39
- TRY_STATUS (db.exec (" PRAGMA journal_mode=WAL" ));
40
- TRY_STATUS (db.exec (" PRAGMA temp_store=MEMORY" ));
41
- TRY_STATUS (init_with_connection (std::move (db), " KV" ));
42
- return is_created;
43
- }
44
31
45
- Status init_with_connection (SqliteDb connection, string kv_name) TD_WARN_UNUSED_RESULT {
46
- db_ = std::move (connection);
47
- kv_name_ = std::move (kv_name);
48
- TRY_STATUS (init (db_, kv_name_));
49
-
50
- TRY_RESULT (set_stmt, db_.get_statement (PSLICE () << " REPLACE INTO " << kv_name_ << " (k, v) VALUES (?1, ?2)" ));
51
- set_stmt_ = std::move (set_stmt);
52
- TRY_RESULT (get_stmt, db_.get_statement (PSLICE () << " SELECT v FROM " << kv_name_ << " WHERE k = ?1" ));
53
- get_stmt_ = std::move (get_stmt);
54
- TRY_RESULT (erase_stmt, db_.get_statement (PSLICE () << " DELETE FROM " << kv_name_ << " WHERE k = ?1" ));
55
- erase_stmt_ = std::move (erase_stmt);
56
- TRY_RESULT (get_all_stmt, db_.get_statement (PSLICE () << " SELECT k, v FROM " << kv_name_ << " " ));
57
-
58
- TRY_RESULT (erase_by_prefix_stmt,
59
- db_.get_statement (PSLICE () << " DELETE FROM " << kv_name_ << " WHERE ?1 <= k AND k < ?2" ));
60
- erase_by_prefix_stmt_ = std::move (erase_by_prefix_stmt);
61
-
62
- TRY_RESULT (erase_by_prefix_rare_stmt,
63
- db_.get_statement (PSLICE () << " DELETE FROM " << kv_name_ << " WHERE ?1 <= k" ));
64
- erase_by_prefix_rare_stmt_ = std::move (erase_by_prefix_rare_stmt);
65
-
66
- TRY_RESULT (get_by_prefix_stmt,
67
- db_.get_statement (PSLICE () << " SELECT k, v FROM " << kv_name_ << " WHERE ?1 <= k AND k < ?2" ));
68
- get_by_prefix_stmt_ = std::move (get_by_prefix_stmt);
69
-
70
- TRY_RESULT (get_by_prefix_rare_stmt,
71
- db_.get_statement (PSLICE () << " SELECT k, v FROM " << kv_name_ << " WHERE ?1 <= k" ));
72
- get_by_prefix_rare_stmt_ = std::move (get_by_prefix_rare_stmt);
73
-
74
- get_all_stmt_ = std::move (get_all_stmt);
75
- return Status::OK ();
32
+ bool empty () const {
33
+ return db_.empty ();
76
34
}
77
35
36
+ Result<bool > init (string path) TD_WARN_UNUSED_RESULT;
37
+
38
+ Status init_with_connection (SqliteDb connection, string table_name) TD_WARN_UNUSED_RESULT;
39
+
78
40
Result<bool > try_regenerate_index () TD_WARN_UNUSED_RESULT {
79
41
return false ;
80
42
}
43
+
81
44
void close () {
82
45
clear ();
83
46
}
84
- static Status destroy (Slice name) TD_WARN_UNUSED_RESULT {
85
- return SqliteDb::destroy (name);
86
- }
87
- void close_and_destroy () {
88
- drop (db_, kv_name_).ensure ();
89
- auto name = std::move (name_);
90
- clear ();
91
- if (!name.empty ()) {
92
- SqliteDb::destroy (name).ignore ();
93
- }
94
- }
95
47
96
- SeqNo set (Slice key, Slice value) {
97
- set_stmt_.bind_blob (1 , key).ensure ();
98
- set_stmt_.bind_blob (2 , value).ensure ();
99
- set_stmt_.step ().ensure ();
100
- set_stmt_.reset ();
101
- return 0 ;
48
+ static Status destroy (Slice path) TD_WARN_UNUSED_RESULT {
49
+ return SqliteDb::destroy (path);
102
50
}
103
51
104
- SeqNo erase (Slice key) {
105
- erase_stmt_.bind_blob (1 , key).ensure ();
106
- erase_stmt_.step ().ensure ();
107
- erase_stmt_.reset ();
108
- return 0 ;
109
- }
110
- string get (Slice key) {
111
- SCOPE_EXIT {
112
- get_stmt_.reset ();
113
- };
114
- get_stmt_.bind_blob (1 , key).ensure ();
115
- get_stmt_.step ().ensure ();
116
- if (!get_stmt_.has_row ()) {
117
- return " " ;
118
- }
119
- auto data = get_stmt_.view_blob (0 ).str ();
120
- get_stmt_.step ().ignore ();
121
- return data;
122
- }
52
+ void close_and_destroy ();
53
+
54
+ SeqNo set (Slice key, Slice value);
55
+
56
+ string get (Slice key);
57
+
58
+ SeqNo erase (Slice key);
123
59
124
60
Status begin_transaction () TD_WARN_UNUSED_RESULT {
125
61
return db_.begin_transaction ();
@@ -128,23 +64,7 @@ class SqliteKeyValue {
128
64
return db_.commit_transaction ();
129
65
}
130
66
131
- void erase_by_prefix (Slice prefix) {
132
- auto next = next_prefix (prefix);
133
- if (next.empty ()) {
134
- SCOPE_EXIT {
135
- erase_by_prefix_rare_stmt_.reset ();
136
- };
137
- erase_by_prefix_rare_stmt_.bind_blob (1 , prefix).ensure ();
138
- erase_by_prefix_rare_stmt_.step ().ensure ();
139
- } else {
140
- SCOPE_EXIT {
141
- erase_by_prefix_stmt_.reset ();
142
- };
143
- erase_by_prefix_stmt_.bind_blob (1 , prefix).ensure ();
144
- erase_by_prefix_stmt_.bind_blob (2 , next).ensure ();
145
- erase_by_prefix_stmt_.step ().ensure ();
146
- }
147
- };
67
+ void erase_by_prefix (Slice prefix);
148
68
149
69
std::unordered_map<string, string> get_all () {
150
70
std::unordered_map<string, string> res;
@@ -160,6 +80,7 @@ class SqliteKeyValue {
160
80
}
161
81
get_by_range (prefix, next, callback);
162
82
}
83
+
163
84
template <class CallbackT >
164
85
void get_by_range (Slice from, Slice till, CallbackT &&callback) {
165
86
SqliteStatement *stmt = nullptr ;
@@ -183,16 +104,13 @@ class SqliteKeyValue {
183
104
}
184
105
}
185
106
186
- bool empty () const {
187
- return db_.empty ();
188
- }
189
107
void clear () {
190
108
*this = SqliteKeyValue ();
191
109
}
192
110
193
111
private:
194
- string name_; // deprecated
195
- string kv_name_ ;
112
+ string path_;
113
+ string table_name_ ;
196
114
SqliteDb db_;
197
115
SqliteStatement get_stmt_;
198
116
SqliteStatement set_stmt_;
@@ -203,20 +121,7 @@ class SqliteKeyValue {
203
121
SqliteStatement get_by_prefix_stmt_;
204
122
SqliteStatement get_by_prefix_rare_stmt_;
205
123
206
- string next_prefix (Slice prefix) {
207
- string next = prefix.str ();
208
- size_t pos = next.size ();
209
- while (pos) {
210
- pos--;
211
- auto value = static_cast <uint8>(next[pos]);
212
- value++;
213
- next[pos] = static_cast <char >(value);
214
- if (value != 0 ) {
215
- return next;
216
- }
217
- }
218
- return string{};
219
- }
124
+ string next_prefix (Slice prefix);
220
125
};
221
126
222
127
} // namespace td
0 commit comments