1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef OMIT_MULTI_VER
17 #include "sqlite_multi_ver_transaction.h"
18
19 #include <climits>
20 #include <string>
21 #include <vector>
22 #include <algorithm>
23
24 #include "securec.h"
25
26 #include "db_common.h"
27 #include "db_constant.h"
28 #include "db_types.h"
29 #include "log_print.h"
30 #include "sqlite_utils.h"
31 #include "multi_ver_kv_entry.h"
32 #include "multi_ver_value_object.h"
33 #include "value_hash_calc.h"
34 #include "time_helper.h"
35
36 namespace DistributedDB {
37 const std::string SQLiteMultiVerTransaction::CREATE_TABLE_SQL =
38 "CREATE TABLE IF NOT EXISTS version_data(key BLOB, value BLOB, oper_flag INTEGER, version INTEGER, " \
39 "timestamp INTEGER, ori_timestamp INTEGER, hash_key BLOB, " \
40 "PRIMARY key(hash_key, version));";
41
42 const std::string SQLiteMultiVerTransaction::CREATE_TABLE_VERSION_INDEX_SQL =
43 "CREATE INDEX IF NOT EXISTS version_index ON version_data (version);";
44
45 const std::string SQLiteMultiVerTransaction::CREATE_TABLE_FLAG_INDEX_SQL =
46 "CREATE INDEX IF NOT EXISTS flag_index ON version_data (oper_flag);";
47
48 const std::string SQLiteMultiVerTransaction::SELECT_ONE_SQL =
49 "SELECT oper_flag, key, value FROM version_data WHERE hash_key=? AND (timestamp>? OR (timestamp=? AND rowid>=?)) " \
50 "AND version<=? AND (oper_flag&0x08=0x08) ORDER BY version DESC LIMIT 1;";
51 const std::string SQLiteMultiVerTransaction::SELECT_BY_HASHKEY_VER_SQL =
52 "SELECT oper_flag, value FROM version_data WHERE hash_key=? AND version=? ";
53 const std::string SQLiteMultiVerTransaction::SELECT_BATCH_SQL =
54 "SELECT oper_flag, key, value, version FROM version_data WHERE key>=? AND key<=?" \
55 "AND (timestamp>? OR (timestamp=? AND rowid>=?)) AND version<=? AND (oper_flag&0x08=0x08) " \
56 "ORDER BY key ASC, version DESC;";
57 // select the data whose hash key is same to the current data.
58 const std::string SQLiteMultiVerTransaction::SELECT_HASH_ENTRY_SQL =
59 "SELECT oper_flag FROM version_data WHERE hash_key=? AND version>? AND version<=? AND (oper_flag&0x08=0x08) " \
60 "ORDER BY version DESC LIMIT 1;";
61 const std::string SQLiteMultiVerTransaction::SELECT_ONE_VER_RAW_SQL =
62 "SELECT key, value, oper_flag, timestamp, ori_timestamp, hash_key FROM version_data " \
63 "WHERE version=? ORDER BY rowid ASC;";
64 const std::string SQLiteMultiVerTransaction::INSERT_SQL =
65 "INSERT OR REPLACE INTO version_data VALUES(?,?,?,?,?,?,?);";
66 const std::string SQLiteMultiVerTransaction::DELETE_VER_SQL =
67 "DELETE FROM version_data WHERE version=?;";
68 const std::string SQLiteMultiVerTransaction::DELETE_BY_VER_HASHKEY_SQL =
69 "DELETE FROM version_data WHERE version=? and hash_key=?;";
70 const std::string SQLiteMultiVerTransaction::SELECT_PRE_PUT_VER_DATA_SQL =
71 "SELECT value FROM version_data WHERE version=? AND timestamp<=?;";
72 const std::string SQLiteMultiVerTransaction::DELETE_PRE_PUT_VER_DATA_SQL =
73 "DELETE FROM version_data WHERE version=? AND timestamp<=?;";
74
75 const std::string SQLiteMultiVerTransaction::SELECT_ONE_BY_KEY_TIMESTAMP_SQL =
76 "SELECT timestamp, ori_timestamp, version, value FROM version_data WHERE hash_key=? AND (oper_flag&0x08=0x08) " \
77 "ORDER BY version DESC LIMIT 1;";
78
79 const std::string SQLiteMultiVerTransaction::SELECT_LATEST_CLEAR_ID =
80 "SELECT rowid, timestamp FROM version_data WHERE (oper_flag&0x07=0x03) AND (oper_flag&0x08=0x08) " \
81 "ORDER BY rowid DESC LIMIT 1;"; // clear flag and the local flag.
82
83 const std::string SQLiteMultiVerTransaction::SELECT_MAX_LOCAL_VERSION =
84 "SELECT MAX(version) FROM version_data WHERE (oper_flag&0x08=0x08);";
85
86 const std::string SQLiteMultiVerTransaction::SELECT_MAX_VERSION =
87 "SELECT MAX(version) FROM version_data;";
88
89 const std::string SQLiteMultiVerTransaction::SELECT_MAX_TIMESTAMP =
90 "SELECT MAX(timestamp) FROM version_data;";
91
92 const std::string SQLiteMultiVerTransaction::UPDATE_VERSION_TIMESTAMP =
93 "UPDATE version_data SET timestamp=? WHERE version=?;";
94
95 const std::string SQLiteMultiVerTransaction::SELECT_OVERWRITTEN_CLEAR_TYPE =
96 "SELECT hash_key, oper_flag, version FROM version_data WHERE version <? AND (oper_flag&0x08=0x08) " \
97 "AND timestamp < (SELECT timestamp FROM version_data WHERE version =? AND (oper_flag&0x07=0x03) );";
98
99 const std::string SQLiteMultiVerTransaction::SELECT_OVERWRITTEN_NO_CLEAR_TYPE =
100 "SELECT hash_key, oper_flag, version FROM version_data WHERE version <? AND (oper_flag&0x08=0x08) " \
101 "AND hash_key =?;";
102
103 namespace {
104 // just for the insert sql argument index.
105 const int BIND_INSERT_KEY_INDEX = 1;
106 const int BIND_INSERT_VAL_INDEX = 2;
107 const int BIND_INSERT_OPER_FLG_INDEX = 3;
108 const int BIND_INSERT_VER_INDEX = 4;
109 const int BIND_INSERT_TIME_INDEX = 5;
110 const int BIND_INSERT_ORI_TIME_INDEX = 6;
111 const int BIND_INSERT_HASH_KEY_INDEX = 7;
112
113 // just for query entries.
114 const int STEP_SUCCESS = 0; // result OK, and put the data into the result set.
115 const int STEP_CONTINUE = 1; // the current key has been put into the result set, discard this one.
116 const int STEP_NEXTKEY = 2; // the current key has been deleted or abandoned.
117 const int STEP_ERROR = 3; // errors occur while executing the query.
118
119 const uint64_t NO_TIMESTAMP = 0;
120 }
121
SQLiteMultiVerTransaction()122 SQLiteMultiVerTransaction::SQLiteMultiVerTransaction()
123 : clearId_(0),
124 clearTime_(0),
125 currentMaxTimestamp_(NO_TIMESTAMP),
126 version_(0),
127 db_(nullptr),
128 isReadOnly_(false),
129 isDataChanged_(false)
130 {}
131
~SQLiteMultiVerTransaction()132 SQLiteMultiVerTransaction::~SQLiteMultiVerTransaction()
133 {
134 if (db_ != nullptr) {
135 (void)sqlite3_close_v2(db_);
136 db_ = nullptr;
137 }
138 }
139
Initialize(const std::string & uri,bool isReadOnly,CipherType type,const CipherPassword & passwd)140 int SQLiteMultiVerTransaction::Initialize(const std::string &uri,
141 bool isReadOnly, CipherType type, const CipherPassword &passwd)
142 {
143 std::vector<std::string> tableVect;
144 tableVect.push_back(CREATE_TABLE_SQL);
145 tableVect.push_back(CREATE_TABLE_VERSION_INDEX_SQL);
146 tableVect.push_back(CREATE_TABLE_FLAG_INDEX_SQL);
147 OpenDbProperties option = {uri, true, false, tableVect, type, passwd};
148 int errCode = SQLiteUtils::OpenDatabase(option, db_);
149 if (errCode != E_OK) {
150 LOGE("Init db error:%d", errCode);
151 return errCode;
152 }
153
154 uri_ = uri;
155 isReadOnly_ = isReadOnly;
156 return E_OK;
157 }
158
SetVersion(const Version & versionInfo)159 void SQLiteMultiVerTransaction::SetVersion(const Version &versionInfo)
160 {
161 version_ = versionInfo;
162 }
163
Put(const Key & key,const Value & value)164 int SQLiteMultiVerTransaction::Put(const Key &key, const Value &value)
165 {
166 // for only read transaction, not support for writing.
167 if (isReadOnly_) {
168 return -E_NOT_SUPPORT;
169 }
170
171 uint64_t flag = ADD_FLAG | LOCAL_FLAG;
172 MultiVerEntryAuxData data = {flag, NO_TIMESTAMP, NO_TIMESTAMP};
173 return AddRecord(key, value, data);
174 }
175
Delete(const Key & key)176 int SQLiteMultiVerTransaction::Delete(const Key &key)
177 {
178 if (key.empty() || key.size() > DBConstant::MAX_VALUE_SIZE) {
179 return -E_INVALID_ARGS;
180 }
181 Value valueRead;
182 int errCode = Get(key, valueRead);
183 if (errCode != E_OK) {
184 return errCode;
185 }
186
187 valueRead.clear();
188 MultiVerValueObject valueObject;
189 errCode = valueObject.SetValue(valueRead);
190 if (errCode != E_OK) {
191 return errCode;
192 }
193
194 Value value;
195 errCode = valueObject.GetSerialData(value);
196 if (errCode != E_OK) {
197 return errCode;
198 }
199
200 Key hashKey;
201 errCode = DBCommon::CalcValueHash(key, hashKey);
202 if (errCode != E_OK) {
203 return errCode;
204 }
205
206 MultiVerEntryAuxData data = {DEL_FLAG | LOCAL_FLAG, NO_TIMESTAMP, NO_TIMESTAMP};
207 return AddRecord(hashKey, value, data);
208 }
209
Clear()210 int SQLiteMultiVerTransaction::Clear()
211 {
212 if (isReadOnly_) {
213 return -E_NOT_SUPPORT;
214 }
215
216 Key key = {'c', 'l', 'e', 'a', 'r'};
217 Value emptyValue;
218 MultiVerValueObject valueObject;
219 int errCode = valueObject.SetValue(emptyValue);
220 if (errCode != E_OK) {
221 return errCode;
222 }
223
224 Value value;
225 errCode = valueObject.GetSerialData(value);
226 if (errCode != E_OK) {
227 return errCode;
228 }
229
230 MultiVerEntryAuxData data = {LOCAL_FLAG | CLEAR_FLAG, NO_TIMESTAMP, NO_TIMESTAMP};
231 errCode = AddRecord(key, value, data);
232
233 clearId_ = 0;
234 GetClearId();
235 return errCode;
236 }
237
Get(const Key & key,Value & value) const238 int SQLiteMultiVerTransaction::Get(const Key &key, Value &value) const
239 {
240 sqlite3_stmt *statement = nullptr;
241 std::lock_guard<std::mutex> lock(readMutex_);
242 int errCode = SQLiteUtils::GetStatement(db_, SELECT_ONE_SQL, statement);
243 if (errCode != E_OK) {
244 return errCode;
245 }
246
247 GetClearId(); // query the clear rowid, and only concern the later entry.
248 Key readKey;
249 Key hashKey;
250 errCode = DBCommon::CalcValueHash(key, hashKey);
251 if (errCode != E_OK) {
252 goto END;
253 }
254 errCode = GetKeyAndValueByHashKey(statement, hashKey, readKey, value, false);
255 END:
256 SQLiteUtils::ResetStatement(statement, true, errCode);
257 return errCode;
258 }
259
GetValueForTrimSlice(const Key & hashKey,const Version version,Value & value) const260 int SQLiteMultiVerTransaction::GetValueForTrimSlice(const Key &hashKey, const Version version, Value &value) const
261 {
262 sqlite3_stmt *statement = nullptr;
263 std::lock_guard<std::mutex> lock(readMutex_);
264 int errCode = SQLiteUtils::GetStatement(db_, SELECT_BY_HASHKEY_VER_SQL, statement);
265 if (errCode != E_OK) {
266 return errCode;
267 }
268
269 uint64_t operFlag;
270 errCode = SQLiteUtils::BindBlobToStatement(statement, 1, hashKey, false); // bind the 1st para for hash key
271 if (errCode != E_OK) {
272 goto END;
273 }
274
275 errCode = sqlite3_bind_int64(statement, 2, version); // bind the 2nd para for version
276 if (errCode != SQLITE_OK) {
277 LOGE("Bind the clear id for query error:%d", errCode);
278 goto END;
279 }
280
281 errCode = SQLiteUtils::StepWithRetry(statement);
282 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
283 errCode = -E_NOT_FOUND;
284 goto END;
285 } else if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
286 goto END;
287 }
288
289 errCode = E_OK;
290 operFlag = static_cast<uint64_t>(sqlite3_column_int64(statement, 0));
291 // only the added data should be operated.
292 if ((OPERATE_MASK & operFlag) == ADD_FLAG) {
293 errCode = SQLiteUtils::GetColumnBlobValue(statement, 1, value); // Get the value.
294 }
295
296 END:
297 SQLiteUtils::ResetStatement(statement, true, errCode);
298 return errCode;
299 }
300
GetEntries(const Key & keyPrefix,std::vector<Entry> & entries) const301 int SQLiteMultiVerTransaction::GetEntries(const Key &keyPrefix, std::vector<Entry> &entries) const
302 {
303 GetEntriesStatements statements;
304 std::lock_guard<std::mutex> lock(readMutex_);
305 int errCode = PrepareForGetEntries(keyPrefix, statements);
306 if (errCode != E_OK) {
307 return errCode;
308 }
309
310 Entry entry;
311 Key lastKey;
312 int stepResult;
313 int innerCode;
314
315 entries.clear();
316 entries.shrink_to_fit();
317 do {
318 errCode = SQLiteUtils::StepWithRetry(statements.getEntriesStatement);
319 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
320 stepResult = GetOneEntry(statements, lastKey, entry, errCode);
321 SQLiteUtils::ResetStatement(statements.hashFilterStatement, false, errCode);
322 if (stepResult == STEP_SUCCESS) {
323 lastKey = entry.key;
324 entries.push_back(std::move(entry));
325 } else if (stepResult == STEP_NEXTKEY) { // this key would be dispatched
326 lastKey = entry.key;
327 } else if (stepResult == STEP_CONTINUE) {
328 continue;
329 } else {
330 goto END;
331 }
332 } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
333 break;
334 } else {
335 LOGE("SQLite step failed:%d", errCode);
336 goto END;
337 }
338 } while (true);
339
340 // if select no result, return -E_NOT_FOUND.
341 if (entries.empty()) {
342 errCode = -E_NOT_FOUND;
343 } else {
344 errCode = E_OK;
345 }
346 END:
347 innerCode = ReleaseGetEntriesStatements(statements);
348 if (innerCode != E_OK) {
349 errCode = innerCode;
350 }
351 return errCode;
352 }
353
CheckToSaveRecord(const MultiVerKvEntry * entry,bool & isNeedSave,std::vector<Value> & values)354 int SQLiteMultiVerTransaction::CheckToSaveRecord(const MultiVerKvEntry *entry, bool &isNeedSave,
355 std::vector<Value> &values)
356 {
357 Value disVal;
358 int errCode = CheckIfNeedSaveRecord(entry, isNeedSave, disVal);
359 if (errCode != E_OK) {
360 return errCode;
361 }
362
363 if (!isNeedSave) {
364 static_cast<const GenericMultiVerKvEntry *>(entry)->GetValue(disVal);
365 return E_OK;
366 }
367 // Should erase the data inserted before the clear operation.
368 uint64_t operFlag = 0;
369 uint64_t timestamp = 0;
370 (static_cast<const GenericMultiVerKvEntry *>(entry))->GetOperFlag(operFlag);
371 entry->GetTimestamp(timestamp);
372 if ((operFlag & OPERATE_MASK) == CLEAR_FLAG && version_ != 0) {
373 LOGD("Erase one version:%" PRIu64, version_);
374 errCode = GetPrePutValues(version_, timestamp, values);
375 if (errCode != E_OK) {
376 return errCode;
377 }
378 errCode = RemovePrePutEntries(version_, timestamp);
379 if (errCode != E_OK) {
380 LOGE("Delete version data before clear oper failed:%d", errCode);
381 return errCode;
382 }
383 clearId_ = 0; // Clear the clear id.
384 }
385
386 return E_OK;
387 }
388
PutBatch(const std::vector<Entry> & entries)389 int SQLiteMultiVerTransaction::PutBatch(const std::vector<Entry> &entries)
390 {
391 for (auto iter = entries.begin(); iter != entries.end(); iter++) {
392 int errCode = Put(iter->key, iter->value);
393 if (errCode != E_OK) {
394 LOGE("put failed:%d!", errCode);
395 return errCode;
396 }
397 }
398 return E_OK;
399 }
400
PutBatch(const std::vector<MultiVerKvEntry * > & entries,bool isLocal,std::vector<Value> & values)401 int SQLiteMultiVerTransaction::PutBatch(const std::vector<MultiVerKvEntry *> &entries, bool isLocal,
402 std::vector<Value> &values)
403 {
404 for (const auto &item : entries) {
405 if (item == nullptr) {
406 continue;
407 }
408
409 auto entry = static_cast<GenericMultiVerKvEntry *>(item);
410 MultiVerEntryAuxData data;
411 entry->GetOperFlag(data.operFlag);
412 entry->GetTimestamp(data.timestamp);
413 entry->GetOriTimestamp(data.oriTimestamp);
414 data.operFlag &= OPERATE_MASK;
415
416 // isLocal means that the entries need merge.
417 if (isLocal) {
418 data.operFlag |= LOCAL_FLAG; // set to local
419 }
420
421 bool isNeedSave = false;
422 int errCode = CheckToSaveRecord(item, isNeedSave, values);
423 if (errCode != E_OK) {
424 return errCode;
425 }
426 // already add to the values.
427 if (!isNeedSave) {
428 continue;
429 }
430
431 Key key;
432 Value value;
433 (void)entry->GetKey(key);
434 errCode = entry->GetValue(value);
435 if (errCode != E_OK) {
436 return errCode;
437 }
438
439 values.push_back(value);
440 errCode = AddRecord(key, value, data);
441 if (errCode != E_OK) {
442 LOGE("Put batch data failed:%d", errCode);
443 return errCode;
444 }
445 }
446 return E_OK;
447 }
448
GetDiffEntries(const Version & begin,const Version & end,MultiVerDiffData & data) const449 int SQLiteMultiVerTransaction::GetDiffEntries(const Version &begin, const Version &end, MultiVerDiffData &data) const
450 {
451 sqlite3_stmt *statement = nullptr;
452 int errCode = SQLiteUtils::GetStatement(db_, SELECT_ONE_VER_RAW_SQL, statement);
453 if (errCode != E_OK) {
454 LOGE("Fail to get the version raw data statement:%d", errCode);
455 return errCode;
456 }
457
458 Value value;
459 std::vector<MultiVerEntryData> savedEntries;
460 errCode = GetRawDataByVersion(statement, end, savedEntries); // Get all the data of the end version.
461 if (errCode != E_OK) {
462 LOGE("Get raw data for diff version failed:%d", errCode);
463 goto ERROR;
464 }
465
466 for (auto &item : savedEntries) {
467 if ((item.auxData.operFlag & OPERATE_MASK) == CLEAR_FLAG) {
468 data.Reset();
469 data.isCleared = true;
470 continue;
471 }
472 value.clear();
473 if (begin == 0) { // no begin version, means no value
474 errCode = -E_NOT_FOUND;
475 } else {
476 // Need get the origin key of the deleted data.
477 if ((item.auxData.operFlag & OPERATE_MASK) == ADD_FLAG) {
478 errCode = Get(item.key, value);
479 } else {
480 errCode = GetOriginKeyValueByHash(item, value);
481 }
482 }
483
484 if (errCode == E_OK || errCode == -E_NOT_FOUND) {
485 ClassifyDiffEntries(errCode, (item.auxData.operFlag & OPERATE_MASK), value, item, data);
486 errCode = E_OK;
487 } else {
488 break;
489 }
490 }
491
492 ERROR:
493 if (errCode != E_OK) {
494 data.Reset();
495 }
496
497 SQLiteUtils::ResetStatement(statement, true, errCode);
498 return errCode;
499 }
500
GetMaxVersion(MultiVerDataType type,Version & maxVersion) const501 int SQLiteMultiVerTransaction::GetMaxVersion(MultiVerDataType type, Version &maxVersion) const
502 {
503 std::string sql = SELECT_MAX_VERSION;
504 if (type == MultiVerDataType::NATIVE_TYPE) {
505 sql = SELECT_MAX_LOCAL_VERSION;
506 }
507 sqlite3_stmt *statement = nullptr;
508 int errCode = SQLiteUtils::GetStatement(db_, sql, statement);
509 if (errCode != E_OK) {
510 return errCode;
511 }
512
513 // Step for getting the latest version
514 errCode = SQLiteUtils::StepWithRetry(statement);
515 if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
516 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
517 LOGI("Initial the new max local version");
518 maxVersion = 0;
519 errCode = E_OK;
520 } else {
521 LOGE("Execute max version failed:%d", errCode);
522 }
523 } else {
524 maxVersion = static_cast<Version>(sqlite3_column_int64(statement, 0)); // only select the first result.
525 errCode = E_OK;
526 }
527
528 SQLiteUtils::ResetStatement(statement, true, errCode);
529 return errCode;
530 }
531
ClearEntriesByVersion(const Version & versionInfo)532 int SQLiteMultiVerTransaction::ClearEntriesByVersion(const Version &versionInfo)
533 {
534 // consider to get the statement.
535 sqlite3_stmt *statement = nullptr;
536 int errCode = SQLiteUtils::GetStatement(db_, DELETE_VER_SQL, statement);
537 if (errCode != E_OK) {
538 LOGE("Get delete version statement error:%d", errCode);
539 return errCode;
540 }
541
542 // bind the version info.
543 errCode = sqlite3_bind_int64(statement, 1, versionInfo); // bind the first argument;
544 if (errCode != SQLITE_OK) {
545 LOGE("bind the delete version statement error:%d", errCode);
546 errCode = SQLiteUtils::MapSQLiteErrno(errCode);
547 goto END;
548 }
549
550 // Step for getting the latest version
551 errCode = SQLiteUtils::StepWithRetry(statement);
552 if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
553 LOGE("Delete records error:%d", errCode);
554 } else {
555 errCode = E_OK;
556 }
557
558 END:
559 SQLiteUtils::ResetStatement(statement, true, errCode);
560 return errCode;
561 }
562
GetPrePutValues(const Version & versionInfo,Timestamp timestamp,std::vector<Value> & values) const563 int SQLiteMultiVerTransaction::GetPrePutValues(const Version &versionInfo, Timestamp timestamp,
564 std::vector<Value> &values) const
565 {
566 sqlite3_stmt *statement = nullptr;
567 int errCode = SQLiteUtils::GetStatement(db_, SELECT_PRE_PUT_VER_DATA_SQL, statement);
568 if (errCode != E_OK) {
569 LOGE("get delete version statement for clear error:%d", errCode);
570 return errCode;
571 }
572
573 // bind the versioninfo
574 errCode = sqlite3_bind_int64(statement, 1, versionInfo); // bind the first argument;
575 if (errCode != SQLITE_OK) {
576 LOGE("bind the delete version statement for clear error:%d", errCode);
577 errCode = SQLiteUtils::MapSQLiteErrno(errCode);
578 goto ERROR;
579 }
580
581 // bind the clear timestamp
582 errCode = sqlite3_bind_int64(statement, 2, timestamp); // 2 is timestamp; bind the second argument for timestamp;
583 if (errCode != SQLITE_OK) {
584 LOGE("bind the clear timestamp for delete ver data error:%d", errCode);
585 errCode = SQLiteUtils::MapSQLiteErrno(errCode);
586 goto ERROR;
587 }
588
589 do {
590 errCode = SQLiteUtils::StepWithRetry(statement);
591 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
592 Value value;
593 errCode = SQLiteUtils::GetColumnBlobValue(statement, 0, value); // get the 1st for value.
594 if (errCode != E_OK) {
595 goto ERROR;
596 }
597 values.push_back(std::move(value));
598 } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
599 errCode = E_OK;
600 goto ERROR;
601 } else {
602 goto ERROR;
603 }
604 } while (true);
605
606 ERROR:
607 SQLiteUtils::ResetStatement(statement, true, errCode);
608 return errCode;
609 }
610
RemovePrePutEntries(const Version & versionInfo,Timestamp timestamp)611 int SQLiteMultiVerTransaction::RemovePrePutEntries(const Version &versionInfo, Timestamp timestamp)
612 {
613 sqlite3_stmt *statement = nullptr;
614 int errCode = SQLiteUtils::GetStatement(db_, DELETE_PRE_PUT_VER_DATA_SQL, statement);
615 if (errCode != E_OK) {
616 LOGE("get delete version statement for clear error:%d", errCode);
617 return errCode;
618 }
619
620 // bind the versioninfo
621 errCode = sqlite3_bind_int64(statement, 1, versionInfo); // bind the first argument;
622 if (errCode != SQLITE_OK) {
623 LOGE("bind the delete version statement for clear error:%d", errCode);
624 errCode = SQLiteUtils::MapSQLiteErrno(errCode);
625 goto ERROR;
626 }
627
628 // bind the clear timestamp
629 errCode = sqlite3_bind_int64(statement, 2, timestamp); // 2 is timestamp; bind the 2nd argument for timestamp;
630 if (errCode != SQLITE_OK) {
631 LOGE("bind the clear timestamp for delete ver data error:%d", errCode);
632 errCode = SQLiteUtils::MapSQLiteErrno(errCode);
633 goto ERROR;
634 }
635
636 // Step for getting the latest version
637 errCode = SQLiteUtils::StepWithRetry(statement);
638 if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
639 LOGE("Delete records for clear error:%d", errCode);
640 } else {
641 errCode = E_OK;
642 }
643
644 ERROR:
645 SQLiteUtils::ResetStatement(statement, true, errCode);
646 return errCode;
647 }
648
StartTransaction()649 int SQLiteMultiVerTransaction::StartTransaction()
650 {
651 return SQLiteUtils::BeginTransaction(db_);
652 }
653
RollBackTransaction()654 int SQLiteMultiVerTransaction::RollBackTransaction()
655 {
656 return SQLiteUtils::RollbackTransaction(db_);
657 }
658
CommitTransaction()659 int SQLiteMultiVerTransaction::CommitTransaction()
660 {
661 return SQLiteUtils::CommitTransaction(db_);
662 }
663
GetEntriesByVersion(Version version,std::list<MultiVerTrimedVersionData> & data) const664 int SQLiteMultiVerTransaction::GetEntriesByVersion(Version version, std::list<MultiVerTrimedVersionData> &data) const
665 {
666 std::lock_guard<std::mutex> lock(readMutex_);
667 sqlite3_stmt *statement = nullptr;
668 int errCode = SQLiteUtils::GetStatement(db_, SELECT_ONE_VER_RAW_SQL, statement);
669 if (errCode != E_OK) {
670 return errCode;
671 }
672
673 std::vector<MultiVerEntryData> savedEntries;
674 errCode = GetRawDataByVersion(statement, version, savedEntries);
675 if (errCode != E_OK) {
676 LOGE("get raw data failed:%d", errCode);
677 goto ERROR;
678 }
679
680 for (auto &item : savedEntries) {
681 MultiVerTrimedVersionData versionData;
682 versionData.operFlag = item.auxData.operFlag;
683 if ((versionData.operFlag & OPERATE_MASK) == ADD_FLAG) {
684 (void)DBCommon::CalcValueHash(item.key, versionData.key);
685 } else {
686 versionData.key = item.key;
687 }
688 versionData.version = version;
689 data.push_front(versionData);
690 }
691
692 ERROR:
693 SQLiteUtils::ResetStatement(statement, true, errCode);
694 return errCode;
695 }
696
GetEntriesByVersion(const Version & versionInfo,std::vector<MultiVerKvEntry * > & entries) const697 int SQLiteMultiVerTransaction::GetEntriesByVersion(const Version &versionInfo,
698 std::vector<MultiVerKvEntry *> &entries) const
699 {
700 std::lock_guard<std::mutex> lock(readMutex_);
701 sqlite3_stmt *statement = nullptr;
702 int errCode = SQLiteUtils::GetStatement(db_, SELECT_ONE_VER_RAW_SQL, statement);
703 if (errCode != E_OK) {
704 return errCode;
705 }
706
707 std::vector<MultiVerEntryData> savedEntries;
708 errCode = GetRawDataByVersion(statement, versionInfo, savedEntries);
709 if (errCode != E_OK) {
710 LOGE("get raw data failed:%d", errCode);
711 goto ERROR;
712 }
713
714 for (auto &item : savedEntries) {
715 GenericMultiVerKvEntry *entry = new (std::nothrow) GenericMultiVerKvEntry;
716 if (entry == nullptr) {
717 errCode = -E_OUT_OF_MEMORY;
718 break;
719 }
720 entry->SetOperFlag(item.auxData.operFlag);
721 entry->SetKey(item.key);
722 entry->SetValue(item.value);
723 entry->SetTimestamp(item.auxData.timestamp);
724 entry->SetOriTimestamp(item.auxData.oriTimestamp);
725 entries.push_back(entry);
726 }
727
728 ERROR:
729 if (errCode != E_OK) {
730 for (auto &entry : entries) {
731 delete entry;
732 entry = nullptr;
733 }
734
735 entries.clear();
736 entries.shrink_to_fit();
737 }
738
739 SQLiteUtils::ResetStatement(statement, true, errCode);
740 return errCode;
741 }
742
GetCurrentMaxTimestamp() const743 Timestamp SQLiteMultiVerTransaction::GetCurrentMaxTimestamp() const
744 {
745 // consider to get the statement.
746 sqlite3_stmt *statement = nullptr;
747 int errCode = SQLiteUtils::GetStatement(db_, SELECT_MAX_TIMESTAMP, statement);
748 if (errCode != E_OK) {
749 LOGE("Get current max timestamp statement error:%d", errCode);
750 return 0;
751 }
752 Timestamp timestamp = 0;
753 // Step for getting the latest version
754 errCode = SQLiteUtils::StepWithRetry(statement);
755 if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
756 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
757 LOGI("Initial the current max timestamp");
758 }
759 } else {
760 timestamp = static_cast<Timestamp>(sqlite3_column_int64(statement, 0)); // the first result.
761 }
762 SQLiteUtils::ResetStatement(statement, true, errCode);
763 return timestamp;
764 }
765
UpdateTimestampByVersion(const Version & version,Timestamp stamp) const766 int SQLiteMultiVerTransaction::UpdateTimestampByVersion(const Version &version,
767 Timestamp stamp) const
768 {
769 if (isReadOnly_) {
770 return -E_NOT_SUPPORT;
771 }
772
773 sqlite3_stmt *statement = nullptr;
774 int errCode = SQLiteUtils::GetStatement(db_, UPDATE_VERSION_TIMESTAMP, statement);
775 if (errCode != E_OK) {
776 LOGE("Get update timestamp statement error:%d", errCode);
777 return errCode;
778 }
779
780 // bind the timestamp
781 errCode = sqlite3_bind_int64(statement, 1, static_cast<int64_t>(stamp)); // bind the 1st for timestamp;
782 if (errCode != SQLITE_OK) {
783 LOGE("bind the updated timestamp error:%d", errCode);
784 errCode = SQLiteUtils::MapSQLiteErrno(errCode);
785 goto END;
786 }
787
788 // bind the versioninfo
789 errCode = sqlite3_bind_int64(statement, 2, static_cast<int64_t>(version)); // bind the 2nd for version;
790 if (errCode != SQLITE_OK) {
791 LOGE("bind the updated version error:%d", errCode);
792 errCode = SQLiteUtils::MapSQLiteErrno(errCode);
793 goto END;
794 }
795
796 // Step for getting the latest version
797 errCode = SQLiteUtils::StepWithRetry(statement);
798 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
799 errCode = E_OK;
800 currentMaxTimestamp_ = (stamp > currentMaxTimestamp_) ? stamp : currentMaxTimestamp_;
801 LOGD("Update the timestamp of version:%" PRIu64 " - %" PRIu64, version, stamp);
802 } else {
803 LOGE("Failed to update the timestamp of the version:%d", errCode);
804 }
805
806 END:
807 SQLiteUtils::ResetStatement(statement, true, errCode);
808 return errCode;
809 }
810
IsDataChanged() const811 bool SQLiteMultiVerTransaction::IsDataChanged() const
812 {
813 if (isReadOnly_) {
814 return false;
815 }
816
817 return isDataChanged_;
818 }
819
ResetVersion()820 void SQLiteMultiVerTransaction::ResetVersion()
821 {
822 if (db_ != nullptr) {
823 sqlite3_db_release_memory(db_);
824 }
825
826 version_ = 0;
827 clearId_ = 0;
828 isDataChanged_ = false;
829 }
830
Reset(CipherType type,const CipherPassword & passwd)831 int SQLiteMultiVerTransaction::Reset(CipherType type, const CipherPassword &passwd)
832 {
833 std::lock_guard<std::mutex> lock(resetMutex_);
834 std::vector<std::string> tableVect = {CREATE_TABLE_SQL};
835 OpenDbProperties option = {uri_, true, false, tableVect, type, passwd};
836 sqlite3 *newConnection = nullptr;
837 int errCode = SQLiteUtils::OpenDatabase(option, newConnection);
838 if (errCode != E_OK) {
839 LOGE("Reset the transaction error:%d", errCode);
840 return errCode;
841 }
842 if (db_ != nullptr) {
843 (void)sqlite3_close_v2(db_);
844 }
845 db_ = newConnection;
846 return E_OK;
847 }
848
GetVersion() const849 Version SQLiteMultiVerTransaction::GetVersion() const
850 {
851 return version_;
852 }
853
GetOverwrittenClearTypeEntries(Version clearVersion,std::list<MultiVerTrimedVersionData> & data) const854 int SQLiteMultiVerTransaction::GetOverwrittenClearTypeEntries(Version clearVersion,
855 std::list<MultiVerTrimedVersionData> &data) const
856 {
857 sqlite3_stmt *statement = nullptr;
858 std::lock_guard<std::mutex> lock(readMutex_);
859 int errCode = SQLiteUtils::GetStatement(db_, SELECT_OVERWRITTEN_CLEAR_TYPE, statement);
860 if (errCode != E_OK) {
861 return errCode;
862 }
863
864 errCode = sqlite3_bind_int64(statement, 1, clearVersion); // bind the 1st for the clear version
865 if (errCode != SQLITE_OK) {
866 LOGE("Bind the clear id for query error:%d", errCode);
867 goto END;
868 }
869
870 errCode = sqlite3_bind_int64(statement, 2, clearVersion); // bind the 2nd for the clear version to get timestamp
871 if (errCode != SQLITE_OK) {
872 LOGE("Bind the clear id for query error:%d", errCode);
873 goto END;
874 }
875
876 do {
877 errCode = SQLiteUtils::StepWithRetry(statement);
878 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
879 uint64_t operFlag = static_cast<uint64_t>(sqlite3_column_int64(statement, 1)); // get the 2nd for opr
880
881 MultiVerTrimedVersionData trimedVerData;
882 errCode = SQLiteUtils::GetColumnBlobValue(statement, 0, trimedVerData.key); // get the 1st for key.
883 if (errCode != E_OK) {
884 goto END;
885 }
886 trimedVerData.operFlag = operFlag & OPERATE_MASK;
887 trimedVerData.version = static_cast<uint64_t>(sqlite3_column_int64(statement, 2)); // 2 is ver for getting
888 data.push_front(trimedVerData);
889 } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
890 errCode = E_OK;
891 goto END;
892 } else {
893 goto END;
894 }
895 } while (true);
896 END:
897 SQLiteUtils::ResetStatement(statement, true, errCode);
898 return errCode;
899 }
900
GetOverwrittenNonClearTypeEntries(Version version,const Key & hashKey,std::list<MultiVerTrimedVersionData> & data) const901 int SQLiteMultiVerTransaction::GetOverwrittenNonClearTypeEntries(Version version, const Key &hashKey,
902 std::list<MultiVerTrimedVersionData> &data) const
903 {
904 sqlite3_stmt *statement = nullptr;
905 std::lock_guard<std::mutex> lock(readMutex_);
906 int errCode = SQLiteUtils::GetStatement(db_, SELECT_OVERWRITTEN_NO_CLEAR_TYPE, statement);
907 if (errCode != E_OK) {
908 return errCode;
909 }
910
911 errCode = sqlite3_bind_int64(statement, 1, version); // bind the 1st for the version
912 if (errCode != SQLITE_OK) {
913 LOGE("Bind the clear id for query error:%d", errCode);
914 goto END;
915 }
916
917 errCode = SQLiteUtils::BindBlobToStatement(statement, 2, hashKey, false); // 2nd argument is hashKey
918 if (errCode != E_OK) {
919 goto END;
920 }
921
922 do {
923 errCode = SQLiteUtils::StepWithRetry(statement);
924 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
925 uint64_t operFlag = static_cast<uint64_t>(sqlite3_column_int64(statement, 1)); // 2nd for oper flag.
926 MultiVerTrimedVersionData trimedVerData;
927 errCode = SQLiteUtils::GetColumnBlobValue(statement, 0, trimedVerData.key); // column result is key.
928 if (errCode != E_OK) {
929 goto END;
930 }
931
932 trimedVerData.operFlag = operFlag & OPERATE_MASK; // get the meta flag
933 trimedVerData.version = static_cast<uint64_t>(sqlite3_column_int64(statement, 2)); // 2 is ver for getting
934 data.push_front(trimedVerData);
935 } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
936 errCode = E_OK;
937 goto END;
938 } else {
939 goto END;
940 }
941 } while (true);
942
943 END:
944 SQLiteUtils::ResetStatement(statement, true, errCode);
945 return errCode;
946 }
947
DeleteEntriesByHashKey(Version version,const Key & hashKey)948 int SQLiteMultiVerTransaction::DeleteEntriesByHashKey(Version version, const Key &hashKey)
949 {
950 // consider to get the statement.
951 sqlite3_stmt *statement = nullptr;
952 int errCode = SQLiteUtils::GetStatement(db_, DELETE_BY_VER_HASHKEY_SQL, statement);
953 if (errCode != E_OK) {
954 LOGE("Get delete version statement error:%d", errCode);
955 return errCode;
956 }
957
958 // bind the version info.
959 errCode = sqlite3_bind_int64(statement, 1, version); // bind the first argument;
960 if (errCode != SQLITE_OK) {
961 LOGE("bind the delete version statement error:%d", errCode);
962 errCode = SQLiteUtils::MapSQLiteErrno(errCode);
963 goto END;
964 }
965
966 errCode = SQLiteUtils::BindBlobToStatement(statement, 2, hashKey, false); // 2nd argument is hashKey
967 if (errCode != E_OK) {
968 goto END;
969 }
970
971 // Step for getting the latest version
972 errCode = SQLiteUtils::StepWithRetry(statement);
973 if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
974 LOGE("Delete records error:%d", errCode);
975 } else {
976 errCode = E_OK;
977 }
978
979 END:
980 SQLiteUtils::ResetStatement(statement, true, errCode);
981 return errCode;
982 }
983
GetRawMultiVerEntry(sqlite3_stmt * statement,MultiVerEntryData & keyEntry)984 int SQLiteMultiVerTransaction::GetRawMultiVerEntry(sqlite3_stmt *statement, MultiVerEntryData &keyEntry)
985 {
986 int errCode = SQLiteUtils::GetColumnBlobValue(statement, 1, keyEntry.value);
987 if (errCode != E_OK) {
988 return errCode;
989 }
990
991 uint64_t flag = static_cast<uint64_t>(sqlite3_column_int64(statement, 2)); // 2 is oper flag index
992 keyEntry.auxData.operFlag = flag & OPERATE_MASK; // remove the local flag.
993
994 keyEntry.auxData.timestamp = static_cast<uint64_t>(sqlite3_column_int64(statement, 3)); // 3 is timestamp index
995 keyEntry.auxData.oriTimestamp = static_cast<uint64_t>(sqlite3_column_int64(statement, 4)); // 4 is ori timestamp
996
997 // if the data is deleted data, just use the hash key.
998 if ((flag & OPERATE_MASK) != ADD_FLAG) {
999 errCode = SQLiteUtils::GetColumnBlobValue(statement, 5, keyEntry.key); // 5 is the hash key index.
1000 if (errCode != E_OK) {
1001 return errCode;
1002 }
1003 } else {
1004 errCode = SQLiteUtils::GetColumnBlobValue(statement, 0, keyEntry.key); // the key index.
1005 if (errCode != E_OK) {
1006 return errCode;
1007 }
1008 }
1009 if (keyEntry.key.empty()) {
1010 return -E_INVALID_DATA;
1011 }
1012 return E_OK;
1013 }
1014
GetRawDataByVersion(sqlite3_stmt * & statement,const Version & version,std::vector<MultiVerEntryData> & entries)1015 int SQLiteMultiVerTransaction::GetRawDataByVersion(sqlite3_stmt *&statement,
1016 const Version &version, std::vector<MultiVerEntryData> &entries)
1017 {
1018 // Bind the version
1019 int errCode = sqlite3_bind_int64(statement, 1, static_cast<int64_t>(version)); // only one parameter.
1020 if (errCode != SQLITE_OK) {
1021 LOGE("Bind the ver for getting raw ver data error:%d", errCode);
1022 return SQLiteUtils::MapSQLiteErrno(errCode);
1023 }
1024
1025 do {
1026 errCode = SQLiteUtils::StepWithRetry(statement);
1027 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1028 MultiVerEntryData entry;
1029 errCode = GetRawMultiVerEntry(statement, entry);
1030 if (errCode == E_OK) {
1031 entries.push_back(std::move(entry));
1032 } else {
1033 break;
1034 }
1035 } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1036 // if select no result, return the E_OK.
1037 errCode = E_OK;
1038 break;
1039 } else {
1040 LOGE("SQLite step failed:%d", errCode);
1041 break;
1042 }
1043 } while (true);
1044
1045 SQLiteUtils::ResetStatement(statement, false, errCode);
1046 return errCode;
1047 }
1048
GetDiffOperator(int errCode,uint64_t flag)1049 int SQLiteMultiVerTransaction::GetDiffOperator(int errCode, uint64_t flag)
1050 {
1051 int oper = EntryOperator::FAIL;
1052 if (errCode == -E_NOT_FOUND) {
1053 if (flag == ADD_FLAG) {
1054 oper = EntryOperator::INSERT;
1055 }
1056 } else if (errCode == E_OK) {
1057 if (flag == DEL_FLAG) {
1058 oper = EntryOperator::DELETE;
1059 } else if (flag == ADD_FLAG) {
1060 oper = EntryOperator::UPDATE;
1061 }
1062 }
1063
1064 return oper;
1065 }
1066
AddRecord(const Key & key,const Value & value,const MultiVerEntryAuxData & data)1067 int SQLiteMultiVerTransaction::AddRecord(const Key &key, const Value &value,
1068 const MultiVerEntryAuxData &data)
1069 {
1070 if (isReadOnly_) {
1071 return -E_NOT_SUPPORT;
1072 }
1073 sqlite3_stmt *statement = nullptr;
1074 int errCode = SQLiteUtils::GetStatement(db_, INSERT_SQL, statement);
1075 if (errCode != E_OK) {
1076 return errCode;
1077 }
1078
1079 // If the record has timestamp, it means the record is foreign.
1080 MultiVerEntryAuxData dataCopy = data;
1081 if (data.timestamp == NO_TIMESTAMP) {
1082 if (currentMaxTimestamp_ == NO_TIMESTAMP) {
1083 currentMaxTimestamp_ = std::max(GetCurrentMaxTimestamp(), currentMaxTimestamp_);
1084 }
1085 dataCopy.timestamp = currentMaxTimestamp_++;
1086 if ((dataCopy.operFlag & LOCAL_FLAG) != 0) {
1087 dataCopy.oriTimestamp = currentMaxTimestamp_;
1088 LOGD("Origin timestamp:%" PRIu64, currentMaxTimestamp_);
1089 }
1090 }
1091
1092 errCode = BindAddRecordArgs(statement, key, value, dataCopy);
1093 if (errCode != E_OK) {
1094 goto END;
1095 }
1096
1097 // Step for put the result.
1098 errCode = SQLiteUtils::StepWithRetry(statement);
1099 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1100 currentMaxTimestamp_ = (dataCopy.timestamp > currentMaxTimestamp_) ? dataCopy.timestamp : currentMaxTimestamp_;
1101 errCode = E_OK;
1102 isDataChanged_ = true;
1103 } else {
1104 LOGE("SQLite step error: %d", errCode);
1105 errCode = SQLiteUtils::MapSQLiteErrno(errCode);
1106 }
1107
1108 END:
1109 SQLiteUtils::ResetStatement(statement, true, errCode);
1110 return errCode;
1111 }
1112
ClassifyDiffEntries(int errCode,uint64_t flag,const Value & value,MultiVerEntryData & item,MultiVerDiffData & data) const1113 void SQLiteMultiVerTransaction::ClassifyDiffEntries(int errCode, uint64_t flag,
1114 const Value &value, MultiVerEntryData &item, MultiVerDiffData &data) const
1115 {
1116 int oper = GetDiffOperator(errCode, flag);
1117 Entry entry;
1118 entry.key.swap(item.key);
1119 if (oper == EntryOperator::DELETE) {
1120 if (value.empty()) {
1121 MultiVerValueObject valueObject;
1122 valueObject.SetValue(value);
1123 Value newValue;
1124 int returnCode = valueObject.GetSerialData(newValue);
1125 if (returnCode != E_OK) {
1126 entry.value.clear();
1127 } else {
1128 entry.value.swap(newValue);
1129 }
1130 } else {
1131 entry.value = value;
1132 }
1133 data.deleted.push_back(std::move(entry));
1134 } else if (oper == EntryOperator::INSERT) {
1135 entry.value.swap(item.value);
1136 data.inserted.push_back(std::move(entry));
1137 } else if (oper == EntryOperator::UPDATE) {
1138 entry.value.swap(item.value);
1139 data.updated.push_back(std::move(entry));
1140 }
1141 }
1142
GetClearId() const1143 void SQLiteMultiVerTransaction::GetClearId() const
1144 {
1145 if (clearId_ > 0) { // only changes at the begin or after clear operation.
1146 return;
1147 }
1148
1149 // consider to get the statement.
1150 sqlite3_stmt *statement = nullptr;
1151 int errCode = SQLiteUtils::GetStatement(db_, SELECT_LATEST_CLEAR_ID, statement);
1152 if (errCode != E_OK) {
1153 LOGE("Get latest clear id error:%d", errCode);
1154 clearId_ = 1;
1155 clearTime_ = 0;
1156 return;
1157 }
1158
1159 // Step for getting the latest version
1160 errCode = SQLiteUtils::StepWithRetry(statement);
1161 if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1162 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1163 LOGI("Initial the new version for clear");
1164 }
1165 clearId_ = 1;
1166 clearTime_ = 0;
1167 } else {
1168 clearId_ = sqlite3_column_int64(statement, 0); // Get the max rowid from the 1st column.
1169 clearTime_ = sqlite3_column_int64(statement, 1); // Get the max timestamp from the 2nd column.
1170 }
1171 SQLiteUtils::ResetStatement(statement, true, errCode);
1172 }
1173
BindClearIdAndVersion(sqlite3_stmt * statement,int index) const1174 int SQLiteMultiVerTransaction::BindClearIdAndVersion(sqlite3_stmt *statement, int index) const
1175 {
1176 int errCode = sqlite3_bind_int64(statement, index, clearTime_); // bind the 1st for the clear time
1177 if (errCode != SQLITE_OK) {
1178 LOGE("Bind the clear id for query error:%d", errCode);
1179 goto END;
1180 }
1181
1182 // bind the next argument for the clear time in the same transact
1183 errCode = sqlite3_bind_int64(statement, index + 1, clearTime_);
1184 if (errCode != SQLITE_OK) {
1185 LOGE("Bind the clear id for query error:%d", errCode);
1186 goto END;
1187 }
1188
1189 errCode = sqlite3_bind_int64(statement, index + 2, clearId_); // 2 is clearId combination using with the clear time.
1190 if (errCode != SQLITE_OK) {
1191 LOGE("Bind the clear id for query error:%d", errCode);
1192 goto END;
1193 }
1194
1195 errCode = sqlite3_bind_int64(statement, index + 3, version_); // 3 is version after the clear rowid.
1196 if (errCode != SQLITE_OK) {
1197 LOGE("Bind the version for query error:%d", errCode);
1198 goto END;
1199 }
1200 END:
1201 return SQLiteUtils::MapSQLiteErrno(errCode);
1202 }
1203
BindQueryEntryArgs(sqlite3_stmt * statement,const Key & key) const1204 int SQLiteMultiVerTransaction::BindQueryEntryArgs(sqlite3_stmt *statement,
1205 const Key &key) const
1206 {
1207 int errCode = SQLiteUtils::BindBlobToStatement(statement, 1, key, false); // first argument is key
1208 if (errCode != E_OK) {
1209 return errCode;
1210 }
1211
1212 return BindClearIdAndVersion(statement, 2); // 2 is clear id.
1213 }
1214
BindQueryEntriesArgs(sqlite3_stmt * statement,const Key & key) const1215 int SQLiteMultiVerTransaction::BindQueryEntriesArgs(sqlite3_stmt *statement,
1216 const Key &key) const
1217 {
1218 // bind the prefix key for the first and second args.
1219 int errCode = SQLiteUtils::BindPrefixKey(statement, 1, key); // first argument is key
1220 if (errCode != E_OK) {
1221 return errCode;
1222 }
1223
1224 return BindClearIdAndVersion(statement, 3); // 3 is clear id.
1225 }
1226
BindAddRecordKeysToStatement(sqlite3_stmt * statement,const Key & key,const MultiVerEntryAuxData & data)1227 int SQLiteMultiVerTransaction::BindAddRecordKeysToStatement(sqlite3_stmt *statement, const Key &key,
1228 const MultiVerEntryAuxData &data)
1229 {
1230 if ((data.operFlag & OPERATE_MASK) != ADD_FLAG) {
1231 Key emptyKey;
1232 int errCode = SQLiteUtils::BindBlobToStatement(statement, BIND_INSERT_KEY_INDEX, emptyKey, true);
1233 if (errCode != E_OK) {
1234 return errCode;
1235 }
1236
1237 errCode = SQLiteUtils::BindBlobToStatement(statement, BIND_INSERT_HASH_KEY_INDEX, key, false);
1238 if (errCode != E_OK) {
1239 return errCode;
1240 }
1241 return errCode;
1242 }
1243 int errCode = SQLiteUtils::BindBlobToStatement(statement, BIND_INSERT_KEY_INDEX, key, false);
1244 if (errCode != E_OK) {
1245 return errCode;
1246 }
1247 Key hashKey;
1248 errCode = DBCommon::CalcValueHash(key, hashKey);
1249 if (errCode != E_OK) {
1250 return errCode;
1251 }
1252
1253 errCode = SQLiteUtils::BindBlobToStatement(statement, BIND_INSERT_HASH_KEY_INDEX, hashKey, false);
1254 if (errCode != E_OK) {
1255 return errCode;
1256 }
1257 return errCode;
1258 }
1259
BindAddRecordArgs(sqlite3_stmt * statement,const Key & key,const Value & value,const MultiVerEntryAuxData & data) const1260 int SQLiteMultiVerTransaction::BindAddRecordArgs(sqlite3_stmt *statement,
1261 const Key &key, const Value &value, const MultiVerEntryAuxData &data) const
1262 {
1263 int errCode = BindAddRecordKeysToStatement(statement, key, data);
1264 if (errCode != E_OK) {
1265 LOGE("Failed to bind the keys:%d", errCode);
1266 return errCode;
1267 }
1268
1269 errCode = SQLiteUtils::BindBlobToStatement(statement, BIND_INSERT_VAL_INDEX, value, true);
1270 if (errCode != E_OK) {
1271 return errCode;
1272 }
1273
1274 errCode = sqlite3_bind_int64(statement, BIND_INSERT_OPER_FLG_INDEX, static_cast<int64_t>(data.operFlag));
1275 if (errCode != SQLITE_OK) {
1276 goto END;
1277 }
1278
1279 errCode = sqlite3_bind_int64(statement, BIND_INSERT_VER_INDEX, static_cast<int64_t>(version_));
1280 if (errCode != SQLITE_OK) {
1281 goto END;
1282 }
1283
1284 errCode = sqlite3_bind_int64(statement, BIND_INSERT_TIME_INDEX, static_cast<int64_t>(data.timestamp));
1285 if (errCode != SQLITE_OK) {
1286 goto END;
1287 }
1288
1289 errCode = sqlite3_bind_int64(statement, BIND_INSERT_ORI_TIME_INDEX, static_cast<int64_t>(data.oriTimestamp));
1290 if (errCode != SQLITE_OK) {
1291 goto END;
1292 }
1293
1294 END:
1295 if (errCode != SQLITE_OK) {
1296 LOGE("Failed to bind the value:%d", errCode);
1297 }
1298 return SQLiteUtils::MapSQLiteErrno(errCode);
1299 }
1300
GetOneEntry(const GetEntriesStatements & statements,const Key & lastKey,Entry & entry,int & errCode) const1301 int SQLiteMultiVerTransaction::GetOneEntry(const GetEntriesStatements &statements,
1302 const Key &lastKey, Entry &entry, int &errCode) const
1303 {
1304 // SQL: "select oper_flag, key, value, version from data;"
1305 errCode = SQLiteUtils::GetColumnBlobValue(statements.getEntriesStatement, 1, entry.key); // 2th is key
1306 if (errCode != E_OK) {
1307 return STEP_ERROR;
1308 }
1309
1310 // if equal to the last key, just step to the next one.
1311 if (lastKey == entry.key) {
1312 entry.key.clear();
1313 return STEP_CONTINUE;
1314 }
1315 uint64_t flag = static_cast<uint64_t>(sqlite3_column_int64(statements.getEntriesStatement, 0)); // 1th is flag
1316 if ((flag & OPERATE_MASK) != ADD_FLAG) {
1317 return STEP_NEXTKEY;
1318 }
1319
1320 errCode = SQLiteUtils::GetColumnBlobValue(statements.getEntriesStatement, 2, entry.value); // 2 is value
1321 if (errCode != E_OK) {
1322 return STEP_ERROR;
1323 }
1324
1325 Version curVer = static_cast<uint64_t>(sqlite3_column_int64(statements.getEntriesStatement, 3)); // 3 is ver
1326 // select the version that is greater than the curEntryVer;
1327 Key hashKey;
1328 errCode = DBCommon::CalcValueHash(entry.key, hashKey);
1329 if (errCode != E_OK) {
1330 return STEP_ERROR;
1331 }
1332 errCode = SQLiteUtils::BindBlobToStatement(statements.hashFilterStatement, 1, hashKey, false);
1333 if (errCode != E_OK) {
1334 return STEP_ERROR;
1335 }
1336
1337 errCode = sqlite3_bind_int64(statements.hashFilterStatement, 2, static_cast<int64_t>(curVer)); // 2 is curVer
1338 if (errCode != E_OK) {
1339 return STEP_ERROR;
1340 }
1341 errCode = sqlite3_bind_int64(statements.hashFilterStatement, 3, static_cast<int64_t>(version_)); // 3 is version
1342 if (errCode != E_OK) {
1343 return STEP_ERROR;
1344 }
1345 errCode = SQLiteUtils::StepWithRetry(statements.hashFilterStatement);
1346 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1347 return STEP_NEXTKEY;
1348 } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1349 return STEP_SUCCESS;
1350 } else {
1351 LOGE("Filter the entries hash key error:%d", errCode);
1352 return STEP_ERROR;
1353 }
1354 }
1355
IsRecordCleared(const Timestamp timestamp) const1356 bool SQLiteMultiVerTransaction::IsRecordCleared(const Timestamp timestamp) const
1357 {
1358 GetClearId();
1359 if (clearTime_ < 0) {
1360 return true;
1361 }
1362 if (timestamp <= static_cast<uint64_t>(clearTime_)) {
1363 return true;
1364 }
1365 return false;
1366 }
1367
CheckIfNeedSaveRecord(sqlite3_stmt * statement,const MultiVerKvEntry * multiVerKvEntry,bool & isNeedSave,Value & origVal) const1368 int SQLiteMultiVerTransaction::CheckIfNeedSaveRecord(sqlite3_stmt *statement, const MultiVerKvEntry *multiVerKvEntry,
1369 bool &isNeedSave, Value &origVal) const
1370 {
1371 // Bind the input args for sql
1372 int errCode;
1373 Key key;
1374 Value value;
1375 uint64_t operFlag = 0;
1376 static_cast<const GenericMultiVerKvEntry *>(multiVerKvEntry)->GetKey(key);
1377 static_cast<const GenericMultiVerKvEntry *>(multiVerKvEntry)->GetOperFlag(operFlag);
1378 static_cast<const GenericMultiVerKvEntry *>(multiVerKvEntry)->GetValue(value);
1379 if ((operFlag & OPERATE_MASK) == ADD_FLAG) {
1380 Key hashKey;
1381 errCode = DBCommon::CalcValueHash(key, hashKey);
1382 if (errCode != E_OK) {
1383 return errCode;
1384 }
1385 errCode = SQLiteUtils::BindBlobToStatement(statement, 1, hashKey, false); // key is the first arg
1386 } else {
1387 errCode = SQLiteUtils::BindBlobToStatement(statement, 1, key, false); // key is the first arg
1388 }
1389
1390 if (errCode != E_OK) {
1391 return errCode;
1392 }
1393
1394 // ori_stamp should diff from timstamp
1395 errCode = SQLiteUtils::StepWithRetry(statement);
1396 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1397 errCode = E_OK;
1398 isNeedSave = true;
1399 } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1400 auto readTime = static_cast<Timestamp>(sqlite3_column_int64(statement, 0)); // the first for time
1401 auto readOriTime = static_cast<Timestamp>(sqlite3_column_int64(statement, 1)); // the second for orig time.
1402 auto readVersion = static_cast<Version>(sqlite3_column_int64(statement, 2)); // 2 is version.
1403 errCode = SQLiteUtils::GetColumnBlobValue(statement, 3, origVal); // 3 is origin value.
1404 if (errCode != E_OK) {
1405 return errCode;
1406 }
1407 Timestamp timestamp = NO_TIMESTAMP;
1408 static_cast<const GenericMultiVerKvEntry *>(multiVerKvEntry)->GetTimestamp(timestamp);
1409 Timestamp oriTimestamp = NO_TIMESTAMP;
1410 static_cast<const GenericMultiVerKvEntry *>(multiVerKvEntry)->GetOriTimestamp(oriTimestamp);
1411 // Only the latest origin time is same or the reading time is bigger than putting time.
1412 isNeedSave = ((readTime < timestamp) && (readOriTime != oriTimestamp || value != origVal));
1413 LOGD("Timestamp :%" PRIu64 " vs %" PRIu64 ", %" PRIu64 " vs %" PRIu64 ", readVersion:%" PRIu64 ", version:"
1414 "%" PRIu64 ", %d", readOriTime, oriTimestamp, readTime, timestamp, readVersion, version_, isNeedSave);
1415 // if the version of the data to be saved is same to the original, you should notify the caller.
1416 if (readVersion != version_) {
1417 origVal.resize(0);
1418 }
1419 } else {
1420 LOGE("Check if need store sync entry failed:%d", errCode);
1421 }
1422
1423 return errCode;
1424 }
1425
CheckIfNeedSaveRecord(const MultiVerKvEntry * multiVerKvEntry,bool & isNeedSave,Value & value) const1426 int SQLiteMultiVerTransaction::CheckIfNeedSaveRecord(const MultiVerKvEntry *multiVerKvEntry, bool &isNeedSave,
1427 Value &value) const
1428 {
1429 auto entry = static_cast<const GenericMultiVerKvEntry *>(multiVerKvEntry);
1430 Timestamp timestamp = NO_TIMESTAMP;
1431 entry->GetTimestamp(timestamp);
1432 if (IsRecordCleared(timestamp)) {
1433 isNeedSave = false;
1434 entry->GetValue(value);
1435 return E_OK;
1436 }
1437
1438 sqlite3_stmt *statement = nullptr;
1439 int errCode = SQLiteUtils::GetStatement(db_, SELECT_ONE_BY_KEY_TIMESTAMP_SQL, statement);
1440 if (errCode != E_OK) {
1441 return errCode;
1442 }
1443
1444 errCode = CheckIfNeedSaveRecord(statement, entry, isNeedSave, value);
1445 SQLiteUtils::ResetStatement(statement, true, errCode);
1446 return errCode;
1447 }
1448
PrepareForGetEntries(const Key & keyPrefix,GetEntriesStatements & statements) const1449 int SQLiteMultiVerTransaction::PrepareForGetEntries(const Key &keyPrefix, GetEntriesStatements &statements) const
1450 {
1451 int innerCode;
1452 int errCode = SQLiteUtils::GetStatement(db_, SELECT_BATCH_SQL, statements.getEntriesStatement);
1453 if (errCode != E_OK) {
1454 goto END;
1455 }
1456 errCode = SQLiteUtils::GetStatement(db_, SELECT_HASH_ENTRY_SQL, statements.hashFilterStatement);
1457 if (errCode != E_OK) {
1458 goto END;
1459 }
1460
1461 GetClearId(); // for read data.
1462 errCode = BindQueryEntriesArgs(statements.getEntriesStatement, keyPrefix);
1463 if (errCode != E_OK) {
1464 goto END;
1465 }
1466 return E_OK;
1467 END:
1468 innerCode = ReleaseGetEntriesStatements(statements);
1469 if (errCode == E_OK) {
1470 errCode = innerCode;
1471 }
1472 return errCode;
1473 }
1474
ReleaseGetEntriesStatements(GetEntriesStatements & statements) const1475 int SQLiteMultiVerTransaction::ReleaseGetEntriesStatements(GetEntriesStatements &statements) const
1476 {
1477 int errCode = E_OK;
1478 SQLiteUtils::ResetStatement(statements.getEntriesStatement, true, errCode);
1479 SQLiteUtils::ResetStatement(statements.hashFilterStatement, true, errCode);
1480 return errCode;
1481 }
1482
GetKeyAndValueByHashKey(sqlite3_stmt * statement,const Key & hashKey,Key & key,Value & value,bool isNeedReadKey) const1483 int SQLiteMultiVerTransaction::GetKeyAndValueByHashKey(sqlite3_stmt *statement, const Key &hashKey,
1484 Key &key, Value &value, bool isNeedReadKey) const
1485 {
1486 int errCode = BindQueryEntryArgs(statement, hashKey);
1487 if (errCode != E_OK) {
1488 return errCode;
1489 }
1490
1491 errCode = SQLiteUtils::StepWithRetry(statement);
1492 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1493 return -E_NOT_FOUND;
1494 } else if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1495 return errCode;
1496 }
1497
1498 uint64_t flag = static_cast<uint64_t>(sqlite3_column_int64(statement, 0)); // get the flag
1499 if ((flag & OPERATE_MASK) != ADD_FLAG) { // if not add or replace,
1500 return -E_NOT_FOUND;
1501 }
1502 if (isNeedReadKey) {
1503 errCode = SQLiteUtils::GetColumnBlobValue(statement, 1, key); // 2nd column result is key.
1504 if (errCode != E_OK) {
1505 return errCode;
1506 }
1507 }
1508
1509 return SQLiteUtils::GetColumnBlobValue(statement, 2, value); // 2 is value.
1510 }
1511
GetOriginKeyValueByHash(MultiVerEntryData & item,Value & value) const1512 int SQLiteMultiVerTransaction::GetOriginKeyValueByHash(MultiVerEntryData &item, Value &value) const
1513 {
1514 sqlite3_stmt *statement = nullptr;
1515 int errCode = SQLiteUtils::GetStatement(db_, SELECT_ONE_SQL, statement);
1516 if (errCode != E_OK) {
1517 return errCode;
1518 }
1519 Key origKey;
1520 errCode = GetKeyAndValueByHashKey(statement, item.key, origKey, value, true);
1521 if (errCode != E_OK) {
1522 goto END;
1523 }
1524 item.key = origKey;
1525 END:
1526 SQLiteUtils::ResetStatement(statement, true, errCode);
1527 return errCode;
1528 }
1529 } // namespace DistributedDB
1530 #endif