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 int ret = E_OK;
257 SQLiteUtils::ResetStatement(statement, true, ret);
258 return errCode != E_OK ? errCode : ret;
259 }
260
GetValueForTrimSlice(const Key & hashKey,const Version version,Value & value) const261 int SQLiteMultiVerTransaction::GetValueForTrimSlice(const Key &hashKey, const Version version, Value &value) const
262 {
263 sqlite3_stmt *statement = nullptr;
264 std::lock_guard<std::mutex> lock(readMutex_);
265 int errCode = SQLiteUtils::GetStatement(db_, SELECT_BY_HASHKEY_VER_SQL, statement);
266 if (errCode != E_OK) {
267 return errCode;
268 }
269
270 uint64_t operFlag;
271 errCode = SQLiteUtils::BindBlobToStatement(statement, 1, hashKey, false); // bind the 1st para for hash key
272 if (errCode != E_OK) {
273 goto END;
274 }
275
276 errCode = sqlite3_bind_int64(statement, 2, version); // bind the 2nd para for version
277 if (errCode != SQLITE_OK) {
278 LOGE("Bind the clear id for query error:%d", errCode);
279 goto END;
280 }
281
282 errCode = SQLiteUtils::StepWithRetry(statement);
283 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
284 errCode = -E_NOT_FOUND;
285 goto END;
286 } else if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
287 goto END;
288 }
289
290 errCode = E_OK;
291 operFlag = static_cast<uint64_t>(sqlite3_column_int64(statement, 0));
292 // only the added data should be operated.
293 if ((OPERATE_MASK & operFlag) == ADD_FLAG) {
294 errCode = SQLiteUtils::GetColumnBlobValue(statement, 1, value); // Get the value.
295 }
296
297 END:
298 int ret = E_OK;
299 SQLiteUtils::ResetStatement(statement, true, ret);
300 return errCode != E_OK ? errCode : ret;
301 }
302
GetEntries(const Key & keyPrefix,std::vector<Entry> & entries) const303 int SQLiteMultiVerTransaction::GetEntries(const Key &keyPrefix, std::vector<Entry> &entries) const
304 {
305 GetEntriesStatements statements;
306 std::lock_guard<std::mutex> lock(readMutex_);
307 int errCode = PrepareForGetEntries(keyPrefix, statements);
308 if (errCode != E_OK) {
309 return errCode;
310 }
311
312 Entry entry;
313 Key lastKey;
314 int stepResult;
315 int innerCode;
316
317 entries.clear();
318 entries.shrink_to_fit();
319 do {
320 errCode = SQLiteUtils::StepWithRetry(statements.getEntriesStatement);
321 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
322 stepResult = GetOneEntry(statements, lastKey, entry, errCode);
323 SQLiteUtils::ResetStatement(statements.hashFilterStatement, false, innerCode);
324 if (stepResult == STEP_SUCCESS) {
325 lastKey = entry.key;
326 entries.push_back(std::move(entry));
327 } else if (stepResult == STEP_NEXTKEY) { // this key would be dispatched
328 lastKey = entry.key;
329 } else if (stepResult == STEP_CONTINUE) {
330 continue;
331 } else {
332 goto END;
333 }
334 } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
335 break;
336 } else {
337 LOGE("SQLite step failed:%d", errCode);
338 goto END;
339 }
340 } while (true);
341
342 // if select no result, return -E_NOT_FOUND.
343 if (entries.empty()) {
344 errCode = -E_NOT_FOUND;
345 } else {
346 errCode = E_OK;
347 }
348 END:
349 innerCode = ReleaseGetEntriesStatements(statements);
350 if (innerCode != E_OK) {
351 errCode = innerCode;
352 }
353 return errCode;
354 }
355
CheckToSaveRecord(const MultiVerKvEntry * entry,bool & isNeedSave,std::vector<Value> & values)356 int SQLiteMultiVerTransaction::CheckToSaveRecord(const MultiVerKvEntry *entry, bool &isNeedSave,
357 std::vector<Value> &values)
358 {
359 Value disVal;
360 int errCode = CheckIfNeedSaveRecord(entry, isNeedSave, disVal);
361 if (errCode != E_OK) {
362 return errCode;
363 }
364
365 if (!isNeedSave) {
366 static_cast<const GenericMultiVerKvEntry *>(entry)->GetValue(disVal);
367 return E_OK;
368 }
369 // Should erase the data inserted before the clear operation.
370 uint64_t operFlag = 0;
371 uint64_t timestamp = 0;
372 (static_cast<const GenericMultiVerKvEntry *>(entry))->GetOperFlag(operFlag);
373 entry->GetTimestamp(timestamp);
374 if ((operFlag & OPERATE_MASK) == CLEAR_FLAG && version_ != 0) {
375 LOGD("Erase one version:%" PRIu64, version_);
376 errCode = GetPrePutValues(version_, timestamp, values);
377 if (errCode != E_OK) {
378 return errCode;
379 }
380 errCode = RemovePrePutEntries(version_, timestamp);
381 if (errCode != E_OK) {
382 LOGE("Delete version data before clear oper failed:%d", errCode);
383 return errCode;
384 }
385 clearId_ = 0; // Clear the clear id.
386 }
387
388 return E_OK;
389 }
390
PutBatch(const std::vector<Entry> & entries)391 int SQLiteMultiVerTransaction::PutBatch(const std::vector<Entry> &entries)
392 {
393 for (auto iter = entries.begin(); iter != entries.end(); iter++) {
394 int errCode = Put(iter->key, iter->value);
395 if (errCode != E_OK) {
396 LOGE("put failed:%d!", errCode);
397 return errCode;
398 }
399 }
400 return E_OK;
401 }
402
PutBatch(const std::vector<MultiVerKvEntry * > & entries,bool isLocal,std::vector<Value> & values)403 int SQLiteMultiVerTransaction::PutBatch(const std::vector<MultiVerKvEntry *> &entries, bool isLocal,
404 std::vector<Value> &values)
405 {
406 for (const auto &item : entries) {
407 if (item == nullptr) {
408 continue;
409 }
410
411 auto entry = static_cast<GenericMultiVerKvEntry *>(item);
412 MultiVerEntryAuxData data;
413 entry->GetOperFlag(data.operFlag);
414 entry->GetTimestamp(data.timestamp);
415 entry->GetOriTimestamp(data.oriTimestamp);
416 data.operFlag &= OPERATE_MASK;
417
418 // isLocal means that the entries need merge.
419 if (isLocal) {
420 data.operFlag |= LOCAL_FLAG; // set to local
421 }
422
423 bool isNeedSave = false;
424 int errCode = CheckToSaveRecord(item, isNeedSave, values);
425 if (errCode != E_OK) {
426 return errCode;
427 }
428 // already add to the values.
429 if (!isNeedSave) {
430 continue;
431 }
432
433 Key key;
434 Value value;
435 (void)entry->GetKey(key);
436 errCode = entry->GetValue(value);
437 if (errCode != E_OK) {
438 return errCode;
439 }
440
441 values.push_back(value);
442 errCode = AddRecord(key, value, data);
443 if (errCode != E_OK) {
444 LOGE("Put batch data failed:%d", errCode);
445 return errCode;
446 }
447 }
448 return E_OK;
449 }
450
GetDiffEntries(const Version & begin,const Version & end,MultiVerDiffData & data) const451 int SQLiteMultiVerTransaction::GetDiffEntries(const Version &begin, const Version &end, MultiVerDiffData &data) const
452 {
453 sqlite3_stmt *statement = nullptr;
454 int errCode = SQLiteUtils::GetStatement(db_, SELECT_ONE_VER_RAW_SQL, statement);
455 if (errCode != E_OK) {
456 LOGE("Fail to get the version raw data statement:%d", errCode);
457 return errCode;
458 }
459
460 Value value;
461 std::vector<MultiVerEntryData> savedEntries;
462 errCode = GetRawDataByVersion(statement, end, savedEntries); // Get all the data of the end version.
463 if (errCode != E_OK) {
464 LOGE("Get raw data for diff version failed:%d", errCode);
465 goto ERROR;
466 }
467
468 for (auto &item : savedEntries) {
469 if ((item.auxData.operFlag & OPERATE_MASK) == CLEAR_FLAG) {
470 data.Reset();
471 data.isCleared = true;
472 continue;
473 }
474 value.clear();
475 if (begin == 0) { // no begin version, means no value
476 errCode = -E_NOT_FOUND;
477 } else {
478 // Need get the origin key of the deleted data.
479 if ((item.auxData.operFlag & OPERATE_MASK) == ADD_FLAG) {
480 errCode = Get(item.key, value);
481 } else {
482 errCode = GetOriginKeyValueByHash(item, value);
483 }
484 }
485
486 if (errCode == E_OK || errCode == -E_NOT_FOUND) {
487 ClassifyDiffEntries(errCode, (item.auxData.operFlag & OPERATE_MASK), value, item, data);
488 errCode = E_OK;
489 } else {
490 break;
491 }
492 }
493
494 ERROR:
495 if (errCode != E_OK) {
496 data.Reset();
497 }
498
499 int ret = E_OK;
500 SQLiteUtils::ResetStatement(statement, true, ret);
501 return errCode != E_OK ? errCode : ret;
502 }
503
GetMaxVersion(MultiVerDataType type,Version & maxVersion) const504 int SQLiteMultiVerTransaction::GetMaxVersion(MultiVerDataType type, Version &maxVersion) const
505 {
506 std::string sql = SELECT_MAX_VERSION;
507 if (type == MultiVerDataType::NATIVE_TYPE) {
508 sql = SELECT_MAX_LOCAL_VERSION;
509 }
510 sqlite3_stmt *statement = nullptr;
511 int errCode = SQLiteUtils::GetStatement(db_, sql, statement);
512 if (errCode != E_OK) {
513 return errCode;
514 }
515
516 // Step for getting the latest version
517 errCode = SQLiteUtils::StepWithRetry(statement);
518 if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
519 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
520 LOGI("Initial the new max local version");
521 maxVersion = 0;
522 errCode = E_OK;
523 } else {
524 LOGE("Execute max version failed:%d", errCode);
525 }
526 } else {
527 maxVersion = static_cast<Version>(sqlite3_column_int64(statement, 0)); // only select the first result.
528 errCode = E_OK;
529 }
530
531 int ret = E_OK;
532 SQLiteUtils::ResetStatement(statement, true, ret);
533 return errCode != E_OK ? errCode : ret;
534 }
535
ClearEntriesByVersion(const Version & versionInfo)536 int SQLiteMultiVerTransaction::ClearEntriesByVersion(const Version &versionInfo)
537 {
538 // consider to get the statement.
539 sqlite3_stmt *statement = nullptr;
540 int errCode = SQLiteUtils::GetStatement(db_, DELETE_VER_SQL, statement);
541 if (errCode != E_OK) {
542 LOGE("Get delete version statement error:%d", errCode);
543 return errCode;
544 }
545
546 // bind the version info.
547 errCode = sqlite3_bind_int64(statement, 1, versionInfo); // bind the first argument;
548 if (errCode != SQLITE_OK) {
549 LOGE("bind the delete version statement error:%d", errCode);
550 errCode = SQLiteUtils::MapSQLiteErrno(errCode);
551 goto END;
552 }
553
554 // Step for getting the latest version
555 errCode = SQLiteUtils::StepWithRetry(statement);
556 if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
557 LOGE("Delete records error:%d", errCode);
558 } else {
559 errCode = E_OK;
560 }
561
562 END:
563 int ret = E_OK;
564 SQLiteUtils::ResetStatement(statement, true, ret);
565 return errCode != E_OK ? errCode : ret;
566 }
567
GetPrePutValues(const Version & versionInfo,Timestamp timestamp,std::vector<Value> & values) const568 int SQLiteMultiVerTransaction::GetPrePutValues(const Version &versionInfo, Timestamp timestamp,
569 std::vector<Value> &values) const
570 {
571 sqlite3_stmt *statement = nullptr;
572 int errCode = SQLiteUtils::GetStatement(db_, SELECT_PRE_PUT_VER_DATA_SQL, statement);
573 if (errCode != E_OK) {
574 LOGE("get delete version statement for clear error:%d", errCode);
575 return errCode;
576 }
577
578 // bind the versioninfo
579 errCode = sqlite3_bind_int64(statement, 1, versionInfo); // bind the first argument;
580 if (errCode != SQLITE_OK) {
581 LOGE("bind the delete version statement for clear error:%d", errCode);
582 errCode = SQLiteUtils::MapSQLiteErrno(errCode);
583 goto ERROR;
584 }
585
586 // bind the clear timestamp
587 errCode = sqlite3_bind_int64(statement, 2, timestamp); // 2 is timestamp; bind the 2nd argument for timestamp;
588 if (errCode != SQLITE_OK) {
589 LOGE("bind the clear timestamp for delete ver data error:%d", errCode);
590 errCode = SQLiteUtils::MapSQLiteErrno(errCode);
591 goto ERROR;
592 }
593
594 do {
595 errCode = SQLiteUtils::StepWithRetry(statement);
596 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
597 Value value;
598 errCode = SQLiteUtils::GetColumnBlobValue(statement, 0, value); // get the 1st for value.
599 if (errCode != E_OK) {
600 goto ERROR;
601 }
602 values.push_back(std::move(value));
603 } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
604 errCode = E_OK;
605 goto ERROR;
606 } else {
607 goto ERROR;
608 }
609 } while (true);
610
611 ERROR:
612 int ret = E_OK;
613 SQLiteUtils::ResetStatement(statement, true, ret);
614 return errCode != E_OK ? errCode : ret;
615 }
616
RemovePrePutEntries(const Version & versionInfo,Timestamp timestamp)617 int SQLiteMultiVerTransaction::RemovePrePutEntries(const Version &versionInfo, Timestamp timestamp)
618 {
619 sqlite3_stmt *statement = nullptr;
620 int errCode = SQLiteUtils::GetStatement(db_, DELETE_PRE_PUT_VER_DATA_SQL, statement);
621 if (errCode != E_OK) {
622 LOGE("get delete version statement for clear error:%d", errCode);
623 return errCode;
624 }
625
626 // bind the versioninfo
627 errCode = sqlite3_bind_int64(statement, 1, versionInfo); // bind the first argument;
628 if (errCode != SQLITE_OK) {
629 LOGE("bind the delete version statement for clear error:%d", errCode);
630 errCode = SQLiteUtils::MapSQLiteErrno(errCode);
631 goto ERROR;
632 }
633
634 // bind the clear timestamp
635 errCode = sqlite3_bind_int64(statement, 2, timestamp); // 2 is timestamp; bind the 2nd argument for timestamp;
636 if (errCode != SQLITE_OK) {
637 LOGE("bind the clear timestamp for delete ver data error:%d", errCode);
638 errCode = SQLiteUtils::MapSQLiteErrno(errCode);
639 goto ERROR;
640 }
641
642 // Step for getting the latest version
643 errCode = SQLiteUtils::StepWithRetry(statement);
644 if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
645 LOGE("Delete records for clear error:%d", errCode);
646 } else {
647 errCode = E_OK;
648 }
649
650 ERROR:
651 int ret = E_OK;
652 SQLiteUtils::ResetStatement(statement, true, ret);
653 return errCode != E_OK ? errCode : ret;
654 }
655
StartTransaction()656 int SQLiteMultiVerTransaction::StartTransaction()
657 {
658 return SQLiteUtils::BeginTransaction(db_);
659 }
660
RollBackTransaction()661 int SQLiteMultiVerTransaction::RollBackTransaction()
662 {
663 return SQLiteUtils::RollbackTransaction(db_);
664 }
665
CommitTransaction()666 int SQLiteMultiVerTransaction::CommitTransaction()
667 {
668 return SQLiteUtils::CommitTransaction(db_);
669 }
670
GetEntriesByVersion(Version version,std::list<MultiVerTrimedVersionData> & data) const671 int SQLiteMultiVerTransaction::GetEntriesByVersion(Version version, std::list<MultiVerTrimedVersionData> &data) const
672 {
673 std::lock_guard<std::mutex> lock(readMutex_);
674 sqlite3_stmt *statement = nullptr;
675 int errCode = SQLiteUtils::GetStatement(db_, SELECT_ONE_VER_RAW_SQL, statement);
676 if (errCode != E_OK) {
677 return errCode;
678 }
679
680 std::vector<MultiVerEntryData> savedEntries;
681 errCode = GetRawDataByVersion(statement, version, savedEntries);
682 if (errCode != E_OK) {
683 LOGE("get raw data failed:%d", errCode);
684 goto ERROR;
685 }
686
687 for (auto &item : savedEntries) {
688 MultiVerTrimedVersionData versionData;
689 versionData.operFlag = item.auxData.operFlag;
690 if ((versionData.operFlag & OPERATE_MASK) == ADD_FLAG) {
691 (void)DBCommon::CalcValueHash(item.key, versionData.key);
692 } else {
693 versionData.key = item.key;
694 }
695 versionData.version = version;
696 data.push_front(versionData);
697 }
698
699 ERROR:
700 int ret = E_OK;
701 SQLiteUtils::ResetStatement(statement, true, ret);
702 return errCode != E_OK ? errCode : ret;
703 }
704
GetEntriesByVersion(const Version & versionInfo,std::vector<MultiVerKvEntry * > & entries) const705 int SQLiteMultiVerTransaction::GetEntriesByVersion(const Version &versionInfo,
706 std::vector<MultiVerKvEntry *> &entries) const
707 {
708 std::lock_guard<std::mutex> lock(readMutex_);
709 sqlite3_stmt *statement = nullptr;
710 int errCode = SQLiteUtils::GetStatement(db_, SELECT_ONE_VER_RAW_SQL, statement);
711 if (errCode != E_OK) {
712 return errCode;
713 }
714
715 std::vector<MultiVerEntryData> savedEntries;
716 errCode = GetRawDataByVersion(statement, versionInfo, savedEntries);
717 if (errCode != E_OK) {
718 LOGE("get raw data failed:%d", errCode);
719 goto ERROR;
720 }
721
722 for (auto &item : savedEntries) {
723 GenericMultiVerKvEntry *entry = new (std::nothrow) GenericMultiVerKvEntry;
724 if (entry == nullptr) {
725 errCode = -E_OUT_OF_MEMORY;
726 break;
727 }
728 entry->SetOperFlag(item.auxData.operFlag);
729 entry->SetKey(item.key);
730 entry->SetValue(item.value);
731 entry->SetTimestamp(item.auxData.timestamp);
732 entry->SetOriTimestamp(item.auxData.oriTimestamp);
733 entries.push_back(entry);
734 }
735
736 ERROR:
737 if (errCode != E_OK) {
738 for (auto &entry : entries) {
739 delete entry;
740 entry = nullptr;
741 }
742
743 entries.clear();
744 entries.shrink_to_fit();
745 }
746
747 int ret = E_OK;
748 SQLiteUtils::ResetStatement(statement, true, ret);
749 return errCode != E_OK ? errCode : ret;
750 }
751
GetCurrentMaxTimestamp() const752 Timestamp SQLiteMultiVerTransaction::GetCurrentMaxTimestamp() const
753 {
754 // consider to get the statement.
755 sqlite3_stmt *statement = nullptr;
756 int errCode = SQLiteUtils::GetStatement(db_, SELECT_MAX_TIMESTAMP, statement);
757 if (errCode != E_OK) {
758 LOGE("Get current max timestamp statement error:%d", errCode);
759 return 0;
760 }
761 Timestamp timestamp = 0;
762 // Step for getting the latest version
763 errCode = SQLiteUtils::StepWithRetry(statement);
764 if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
765 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
766 LOGI("Initial the current max timestamp");
767 }
768 } else {
769 timestamp = static_cast<Timestamp>(sqlite3_column_int64(statement, 0)); // the first result.
770 }
771 SQLiteUtils::ResetStatement(statement, true, errCode);
772 return timestamp;
773 }
774
UpdateTimestampByVersion(const Version & version,Timestamp stamp) const775 int SQLiteMultiVerTransaction::UpdateTimestampByVersion(const Version &version,
776 Timestamp stamp) const
777 {
778 if (isReadOnly_) {
779 return -E_NOT_SUPPORT;
780 }
781
782 sqlite3_stmt *statement = nullptr;
783 int errCode = SQLiteUtils::GetStatement(db_, UPDATE_VERSION_TIMESTAMP, statement);
784 if (errCode != E_OK) {
785 LOGE("Get update timestamp statement error:%d", errCode);
786 return errCode;
787 }
788
789 // bind the timestamp
790 errCode = sqlite3_bind_int64(statement, 1, static_cast<int64_t>(stamp)); // bind the 1st for timestamp;
791 if (errCode != SQLITE_OK) {
792 LOGE("bind the updated timestamp error:%d", errCode);
793 errCode = SQLiteUtils::MapSQLiteErrno(errCode);
794 goto END;
795 }
796
797 // bind the versioninfo
798 errCode = sqlite3_bind_int64(statement, 2, static_cast<int64_t>(version)); // bind the 2nd for version;
799 if (errCode != SQLITE_OK) {
800 LOGE("bind the updated version error:%d", errCode);
801 errCode = SQLiteUtils::MapSQLiteErrno(errCode);
802 goto END;
803 }
804
805 // Step for getting the latest version
806 errCode = SQLiteUtils::StepWithRetry(statement);
807 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
808 errCode = E_OK;
809 currentMaxTimestamp_ = (stamp > currentMaxTimestamp_) ? stamp : currentMaxTimestamp_;
810 LOGD("Update the timestamp of version:%" PRIu64 " - %" PRIu64, version, stamp);
811 } else {
812 LOGE("Failed to update the timestamp of the version:%d", errCode);
813 }
814
815 END:
816 int ret = E_OK;
817 SQLiteUtils::ResetStatement(statement, true, ret);
818 return errCode != E_OK ? errCode : ret;
819 }
820
IsDataChanged() const821 bool SQLiteMultiVerTransaction::IsDataChanged() const
822 {
823 if (isReadOnly_) {
824 return false;
825 }
826
827 return isDataChanged_;
828 }
829
ResetVersion()830 void SQLiteMultiVerTransaction::ResetVersion()
831 {
832 if (db_ != nullptr) {
833 sqlite3_db_release_memory(db_);
834 }
835
836 version_ = 0;
837 clearId_ = 0;
838 isDataChanged_ = false;
839 }
840
Reset(CipherType type,const CipherPassword & passwd)841 int SQLiteMultiVerTransaction::Reset(CipherType type, const CipherPassword &passwd)
842 {
843 std::lock_guard<std::mutex> lock(resetMutex_);
844 std::vector<std::string> tableVect = {CREATE_TABLE_SQL};
845 OpenDbProperties option = {uri_, true, false, tableVect, type, passwd};
846 sqlite3 *newConnection = nullptr;
847 int errCode = SQLiteUtils::OpenDatabase(option, newConnection);
848 if (errCode != E_OK) {
849 LOGE("Reset the transaction error:%d", errCode);
850 return errCode;
851 }
852 if (db_ != nullptr) {
853 (void)sqlite3_close_v2(db_);
854 }
855 db_ = newConnection;
856 return E_OK;
857 }
858
GetVersion() const859 Version SQLiteMultiVerTransaction::GetVersion() const
860 {
861 return version_;
862 }
863
GetOverwrittenClearTypeEntries(Version clearVersion,std::list<MultiVerTrimedVersionData> & data) const864 int SQLiteMultiVerTransaction::GetOverwrittenClearTypeEntries(Version clearVersion,
865 std::list<MultiVerTrimedVersionData> &data) const
866 {
867 sqlite3_stmt *statement = nullptr;
868 std::lock_guard<std::mutex> lock(readMutex_);
869 int errCode = SQLiteUtils::GetStatement(db_, SELECT_OVERWRITTEN_CLEAR_TYPE, statement);
870 if (errCode != E_OK) {
871 return errCode;
872 }
873
874 errCode = sqlite3_bind_int64(statement, 1, clearVersion); // bind the 1st for the clear version
875 if (errCode != SQLITE_OK) {
876 LOGE("Bind the clear id for query error:%d", errCode);
877 goto END;
878 }
879
880 errCode = sqlite3_bind_int64(statement, 2, clearVersion); // bind the 2nd for the clear version to get timestamp
881 if (errCode != SQLITE_OK) {
882 LOGE("Bind the clear id for query error:%d", errCode);
883 goto END;
884 }
885
886 do {
887 errCode = SQLiteUtils::StepWithRetry(statement);
888 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
889 uint64_t operFlag = static_cast<uint64_t>(sqlite3_column_int64(statement, 1)); // get the 2nd for opr
890
891 MultiVerTrimedVersionData trimedVerData;
892 errCode = SQLiteUtils::GetColumnBlobValue(statement, 0, trimedVerData.key); // get the 1st for key.
893 if (errCode != E_OK) {
894 goto END;
895 }
896 trimedVerData.operFlag = operFlag & OPERATE_MASK;
897 trimedVerData.version = static_cast<uint64_t>(sqlite3_column_int64(statement, 2)); // 2 is ver for getting
898 data.push_front(trimedVerData);
899 } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
900 errCode = E_OK;
901 goto END;
902 } else {
903 goto END;
904 }
905 } while (true);
906 END:
907 int ret = E_OK;
908 SQLiteUtils::ResetStatement(statement, true, ret);
909 return errCode != E_OK ? errCode : ret;
910 }
911
GetOverwrittenNonClearTypeEntries(Version version,const Key & hashKey,std::list<MultiVerTrimedVersionData> & data) const912 int SQLiteMultiVerTransaction::GetOverwrittenNonClearTypeEntries(Version version, const Key &hashKey,
913 std::list<MultiVerTrimedVersionData> &data) const
914 {
915 sqlite3_stmt *statement = nullptr;
916 std::lock_guard<std::mutex> lock(readMutex_);
917 int errCode = SQLiteUtils::GetStatement(db_, SELECT_OVERWRITTEN_NO_CLEAR_TYPE, statement);
918 if (errCode != E_OK) {
919 return errCode;
920 }
921
922 errCode = sqlite3_bind_int64(statement, 1, version); // bind the 1st for the version
923 if (errCode != SQLITE_OK) {
924 LOGE("Bind the clear id for query error:%d", errCode);
925 goto END;
926 }
927
928 errCode = SQLiteUtils::BindBlobToStatement(statement, 2, hashKey, false); // 2nd argument is hashKey
929 if (errCode != E_OK) {
930 goto END;
931 }
932
933 do {
934 errCode = SQLiteUtils::StepWithRetry(statement);
935 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
936 uint64_t operFlag = static_cast<uint64_t>(sqlite3_column_int64(statement, 1)); // 2nd for oper flag.
937 MultiVerTrimedVersionData trimedVerData;
938 errCode = SQLiteUtils::GetColumnBlobValue(statement, 0, trimedVerData.key); // column result is key.
939 if (errCode != E_OK) {
940 goto END;
941 }
942
943 trimedVerData.operFlag = operFlag & OPERATE_MASK; // get the meta flag
944 trimedVerData.version = static_cast<uint64_t>(sqlite3_column_int64(statement, 2)); // 2 is ver for getting
945 data.push_front(trimedVerData);
946 } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
947 errCode = E_OK;
948 goto END;
949 } else {
950 goto END;
951 }
952 } while (true);
953
954 END:
955 int ret = E_OK;
956 SQLiteUtils::ResetStatement(statement, true, ret);
957 return errCode != E_OK ? errCode : ret;
958 }
959
DeleteEntriesByHashKey(Version version,const Key & hashKey)960 int SQLiteMultiVerTransaction::DeleteEntriesByHashKey(Version version, const Key &hashKey)
961 {
962 // consider to get the statement.
963 sqlite3_stmt *statement = nullptr;
964 int errCode = SQLiteUtils::GetStatement(db_, DELETE_BY_VER_HASHKEY_SQL, statement);
965 if (errCode != E_OK) {
966 LOGE("Get delete version statement error:%d", errCode);
967 return errCode;
968 }
969
970 // bind the version info.
971 errCode = sqlite3_bind_int64(statement, 1, version); // bind the first argument;
972 if (errCode != SQLITE_OK) {
973 LOGE("bind the delete version statement error:%d", errCode);
974 errCode = SQLiteUtils::MapSQLiteErrno(errCode);
975 goto END;
976 }
977
978 errCode = SQLiteUtils::BindBlobToStatement(statement, 2, hashKey, false); // 2nd argument is hashKey
979 if (errCode != E_OK) {
980 goto END;
981 }
982
983 // Step for getting the latest version
984 errCode = SQLiteUtils::StepWithRetry(statement);
985 if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
986 LOGE("Delete records error:%d", errCode);
987 } else {
988 errCode = E_OK;
989 }
990
991 END:
992 int ret = E_OK;
993 SQLiteUtils::ResetStatement(statement, true, ret);
994 return errCode != E_OK ? errCode : ret;
995 }
996
GetRawMultiVerEntry(sqlite3_stmt * statement,MultiVerEntryData & keyEntry)997 int SQLiteMultiVerTransaction::GetRawMultiVerEntry(sqlite3_stmt *statement, MultiVerEntryData &keyEntry)
998 {
999 int errCode = SQLiteUtils::GetColumnBlobValue(statement, 1, keyEntry.value);
1000 if (errCode != E_OK) {
1001 return errCode;
1002 }
1003
1004 uint64_t flag = static_cast<uint64_t>(sqlite3_column_int64(statement, 2)); // 2 is oper flag index
1005 keyEntry.auxData.operFlag = flag & OPERATE_MASK; // remove the local flag.
1006
1007 keyEntry.auxData.timestamp = static_cast<uint64_t>(sqlite3_column_int64(statement, 3)); // 3 is timestamp index
1008 keyEntry.auxData.oriTimestamp = static_cast<uint64_t>(sqlite3_column_int64(statement, 4)); // 4 is ori timestamp
1009
1010 // if the data is deleted data, just use the hash key.
1011 if ((flag & OPERATE_MASK) != ADD_FLAG) {
1012 errCode = SQLiteUtils::GetColumnBlobValue(statement, 5, keyEntry.key); // 5 is the hash key index.
1013 if (errCode != E_OK) {
1014 return errCode;
1015 }
1016 } else {
1017 errCode = SQLiteUtils::GetColumnBlobValue(statement, 0, keyEntry.key); // the key index.
1018 if (errCode != E_OK) {
1019 return errCode;
1020 }
1021 }
1022 if (keyEntry.key.empty()) {
1023 return -E_INVALID_DATA;
1024 }
1025 return E_OK;
1026 }
1027
GetRawDataByVersion(sqlite3_stmt * & statement,const Version & version,std::vector<MultiVerEntryData> & entries)1028 int SQLiteMultiVerTransaction::GetRawDataByVersion(sqlite3_stmt *&statement,
1029 const Version &version, std::vector<MultiVerEntryData> &entries)
1030 {
1031 // Bind the version
1032 int errCode = sqlite3_bind_int64(statement, 1, static_cast<int64_t>(version)); // only one parameter.
1033 if (errCode != SQLITE_OK) {
1034 LOGE("Bind the ver for getting raw ver data error:%d", errCode);
1035 return SQLiteUtils::MapSQLiteErrno(errCode);
1036 }
1037
1038 do {
1039 errCode = SQLiteUtils::StepWithRetry(statement);
1040 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1041 MultiVerEntryData entry;
1042 errCode = GetRawMultiVerEntry(statement, entry);
1043 if (errCode == E_OK) {
1044 entries.push_back(std::move(entry));
1045 } else {
1046 break;
1047 }
1048 } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1049 // if select no result, return the E_OK.
1050 errCode = E_OK;
1051 break;
1052 } else {
1053 LOGE("SQLite step failed:%d", errCode);
1054 break;
1055 }
1056 } while (true);
1057
1058 int ret = E_OK;
1059 SQLiteUtils::ResetStatement(statement, false, ret);
1060 return errCode != E_OK ? errCode : ret;
1061 }
1062
GetDiffOperator(int errCode,uint64_t flag)1063 int SQLiteMultiVerTransaction::GetDiffOperator(int errCode, uint64_t flag)
1064 {
1065 int oper = EntryOperator::FAIL;
1066 if (errCode == -E_NOT_FOUND) {
1067 if (flag == ADD_FLAG) {
1068 oper = EntryOperator::INSERT;
1069 }
1070 } else if (errCode == E_OK) {
1071 if (flag == DEL_FLAG) {
1072 oper = EntryOperator::DELETE;
1073 } else if (flag == ADD_FLAG) {
1074 oper = EntryOperator::UPDATE;
1075 }
1076 }
1077
1078 return oper;
1079 }
1080
AddRecord(const Key & key,const Value & value,const MultiVerEntryAuxData & data)1081 int SQLiteMultiVerTransaction::AddRecord(const Key &key, const Value &value,
1082 const MultiVerEntryAuxData &data)
1083 {
1084 if (isReadOnly_) {
1085 return -E_NOT_SUPPORT;
1086 }
1087 sqlite3_stmt *statement = nullptr;
1088 int errCode = SQLiteUtils::GetStatement(db_, INSERT_SQL, statement);
1089 if (errCode != E_OK) {
1090 return errCode;
1091 }
1092
1093 // If the record has timestamp, it means the record is foreign.
1094 MultiVerEntryAuxData dataCopy = data;
1095 if (data.timestamp == NO_TIMESTAMP) {
1096 if (currentMaxTimestamp_ == NO_TIMESTAMP) {
1097 currentMaxTimestamp_ = std::max(GetCurrentMaxTimestamp(), currentMaxTimestamp_);
1098 }
1099 dataCopy.timestamp = currentMaxTimestamp_++;
1100 if ((dataCopy.operFlag & LOCAL_FLAG) != 0) {
1101 dataCopy.oriTimestamp = currentMaxTimestamp_;
1102 LOGD("Origin timestamp:%" PRIu64, currentMaxTimestamp_);
1103 }
1104 }
1105
1106 errCode = BindAddRecordArgs(statement, key, value, dataCopy);
1107 if (errCode != E_OK) {
1108 goto END;
1109 }
1110
1111 // Step for put the result.
1112 errCode = SQLiteUtils::StepWithRetry(statement);
1113 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1114 currentMaxTimestamp_ = (dataCopy.timestamp > currentMaxTimestamp_) ? dataCopy.timestamp : currentMaxTimestamp_;
1115 errCode = E_OK;
1116 isDataChanged_ = true;
1117 } else {
1118 LOGE("SQLite step error: %d", errCode);
1119 errCode = SQLiteUtils::MapSQLiteErrno(errCode);
1120 }
1121
1122 END:
1123 int ret = E_OK;
1124 SQLiteUtils::ResetStatement(statement, true, ret);
1125 return errCode != E_OK ? errCode : ret;
1126 }
1127
ClassifyDiffEntries(int errCode,uint64_t flag,const Value & value,MultiVerEntryData & item,MultiVerDiffData & data) const1128 void SQLiteMultiVerTransaction::ClassifyDiffEntries(int errCode, uint64_t flag,
1129 const Value &value, MultiVerEntryData &item, MultiVerDiffData &data) const
1130 {
1131 int oper = GetDiffOperator(errCode, flag);
1132 Entry entry;
1133 entry.key.swap(item.key);
1134 if (oper == EntryOperator::DELETE) {
1135 if (value.empty()) {
1136 MultiVerValueObject valueObject;
1137 valueObject.SetValue(value);
1138 Value newValue;
1139 int returnCode = valueObject.GetSerialData(newValue);
1140 if (returnCode != E_OK) {
1141 entry.value.clear();
1142 } else {
1143 entry.value.swap(newValue);
1144 }
1145 } else {
1146 entry.value = value;
1147 }
1148 data.deleted.push_back(std::move(entry));
1149 } else if (oper == EntryOperator::INSERT) {
1150 entry.value.swap(item.value);
1151 data.inserted.push_back(std::move(entry));
1152 } else if (oper == EntryOperator::UPDATE) {
1153 entry.value.swap(item.value);
1154 data.updated.push_back(std::move(entry));
1155 }
1156 }
1157
GetClearId() const1158 void SQLiteMultiVerTransaction::GetClearId() const
1159 {
1160 if (clearId_ > 0) { // only changes at the begin or after clear operation.
1161 return;
1162 }
1163
1164 // consider to get the statement.
1165 sqlite3_stmt *statement = nullptr;
1166 int errCode = SQLiteUtils::GetStatement(db_, SELECT_LATEST_CLEAR_ID, statement);
1167 if (errCode != E_OK) {
1168 LOGE("Get latest clear id error:%d", errCode);
1169 clearId_ = 1;
1170 clearTime_ = 0;
1171 return;
1172 }
1173
1174 // Step for getting the latest version
1175 errCode = SQLiteUtils::StepWithRetry(statement);
1176 if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1177 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1178 LOGI("Initial the new version for clear");
1179 }
1180 clearId_ = 1;
1181 clearTime_ = 0;
1182 } else {
1183 clearId_ = sqlite3_column_int64(statement, 0); // Get the max rowid from the 1st column.
1184 clearTime_ = sqlite3_column_int64(statement, 1); // Get the max timestamp from the 2nd column.
1185 }
1186 SQLiteUtils::ResetStatement(statement, true, errCode);
1187 }
1188
BindClearIdAndVersion(sqlite3_stmt * statement,int index) const1189 int SQLiteMultiVerTransaction::BindClearIdAndVersion(sqlite3_stmt *statement, int index) const
1190 {
1191 int errCode = sqlite3_bind_int64(statement, index, clearTime_); // bind the 1st for the clear time
1192 if (errCode != SQLITE_OK) {
1193 LOGE("Bind the clear id for query error:%d", errCode);
1194 goto END;
1195 }
1196
1197 // bind the next argument for the clear time in the same transact
1198 errCode = sqlite3_bind_int64(statement, index + 1, clearTime_);
1199 if (errCode != SQLITE_OK) {
1200 LOGE("Bind the clear id for query error:%d", errCode);
1201 goto END;
1202 }
1203
1204 errCode = sqlite3_bind_int64(statement, index + 2, clearId_); // 2 is clearId combination using with the clear time.
1205 if (errCode != SQLITE_OK) {
1206 LOGE("Bind the clear id for query error:%d", errCode);
1207 goto END;
1208 }
1209
1210 errCode = sqlite3_bind_int64(statement, index + 3, version_); // 3 is version after the clear rowid.
1211 if (errCode != SQLITE_OK) {
1212 LOGE("Bind the version for query error:%d", errCode);
1213 goto END;
1214 }
1215 END:
1216 return SQLiteUtils::MapSQLiteErrno(errCode);
1217 }
1218
BindQueryEntryArgs(sqlite3_stmt * statement,const Key & key) const1219 int SQLiteMultiVerTransaction::BindQueryEntryArgs(sqlite3_stmt *statement,
1220 const Key &key) const
1221 {
1222 int errCode = SQLiteUtils::BindBlobToStatement(statement, 1, key, false); // first argument is key
1223 if (errCode != E_OK) {
1224 return errCode;
1225 }
1226
1227 return BindClearIdAndVersion(statement, 2); // 2 is clear id.
1228 }
1229
BindQueryEntriesArgs(sqlite3_stmt * statement,const Key & key) const1230 int SQLiteMultiVerTransaction::BindQueryEntriesArgs(sqlite3_stmt *statement,
1231 const Key &key) const
1232 {
1233 // bind the prefix key for the first and second args.
1234 int errCode = SQLiteUtils::BindPrefixKey(statement, 1, key); // first argument is key
1235 if (errCode != E_OK) {
1236 return errCode;
1237 }
1238
1239 return BindClearIdAndVersion(statement, 3); // 3 is clear id.
1240 }
1241
BindAddRecordKeysToStatement(sqlite3_stmt * statement,const Key & key,const MultiVerEntryAuxData & data)1242 int SQLiteMultiVerTransaction::BindAddRecordKeysToStatement(sqlite3_stmt *statement, const Key &key,
1243 const MultiVerEntryAuxData &data)
1244 {
1245 if ((data.operFlag & OPERATE_MASK) != ADD_FLAG) {
1246 Key emptyKey;
1247 int errCode = SQLiteUtils::BindBlobToStatement(statement, BIND_INSERT_KEY_INDEX, emptyKey, true);
1248 if (errCode != E_OK) {
1249 return errCode;
1250 }
1251
1252 errCode = SQLiteUtils::BindBlobToStatement(statement, BIND_INSERT_HASH_KEY_INDEX, key, false);
1253 if (errCode != E_OK) {
1254 return errCode;
1255 }
1256 return errCode;
1257 }
1258 int errCode = SQLiteUtils::BindBlobToStatement(statement, BIND_INSERT_KEY_INDEX, key, false);
1259 if (errCode != E_OK) {
1260 return errCode;
1261 }
1262 Key hashKey;
1263 errCode = DBCommon::CalcValueHash(key, hashKey);
1264 if (errCode != E_OK) {
1265 return errCode;
1266 }
1267
1268 errCode = SQLiteUtils::BindBlobToStatement(statement, BIND_INSERT_HASH_KEY_INDEX, hashKey, false);
1269 if (errCode != E_OK) {
1270 return errCode;
1271 }
1272 return errCode;
1273 }
1274
BindAddRecordArgs(sqlite3_stmt * statement,const Key & key,const Value & value,const MultiVerEntryAuxData & data) const1275 int SQLiteMultiVerTransaction::BindAddRecordArgs(sqlite3_stmt *statement,
1276 const Key &key, const Value &value, const MultiVerEntryAuxData &data) const
1277 {
1278 int errCode = BindAddRecordKeysToStatement(statement, key, data);
1279 if (errCode != E_OK) {
1280 LOGE("Failed to bind the keys:%d", errCode);
1281 return errCode;
1282 }
1283
1284 errCode = SQLiteUtils::BindBlobToStatement(statement, BIND_INSERT_VAL_INDEX, value, true);
1285 if (errCode != E_OK) {
1286 return errCode;
1287 }
1288
1289 errCode = sqlite3_bind_int64(statement, BIND_INSERT_OPER_FLG_INDEX, static_cast<int64_t>(data.operFlag));
1290 if (errCode != SQLITE_OK) {
1291 goto END;
1292 }
1293
1294 errCode = sqlite3_bind_int64(statement, BIND_INSERT_VER_INDEX, static_cast<int64_t>(version_));
1295 if (errCode != SQLITE_OK) {
1296 goto END;
1297 }
1298
1299 errCode = sqlite3_bind_int64(statement, BIND_INSERT_TIME_INDEX, static_cast<int64_t>(data.timestamp));
1300 if (errCode != SQLITE_OK) {
1301 goto END;
1302 }
1303
1304 errCode = sqlite3_bind_int64(statement, BIND_INSERT_ORI_TIME_INDEX, static_cast<int64_t>(data.oriTimestamp));
1305 if (errCode != SQLITE_OK) {
1306 goto END;
1307 }
1308
1309 END:
1310 if (errCode != SQLITE_OK) {
1311 LOGE("Failed to bind the value:%d", errCode);
1312 }
1313 return SQLiteUtils::MapSQLiteErrno(errCode);
1314 }
1315
GetOneEntry(const GetEntriesStatements & statements,const Key & lastKey,Entry & entry,int & errCode) const1316 int SQLiteMultiVerTransaction::GetOneEntry(const GetEntriesStatements &statements,
1317 const Key &lastKey, Entry &entry, int &errCode) const
1318 {
1319 // SQL: "select oper_flag, key, value, version from data;"
1320 errCode = SQLiteUtils::GetColumnBlobValue(statements.getEntriesStatement, 1, entry.key); // 2th is key
1321 if (errCode != E_OK) {
1322 return STEP_ERROR;
1323 }
1324
1325 // if equal to the last key, just step to the next one.
1326 if (lastKey == entry.key) {
1327 entry.key.clear();
1328 return STEP_CONTINUE;
1329 }
1330 uint64_t flag = static_cast<uint64_t>(sqlite3_column_int64(statements.getEntriesStatement, 0)); // 1th is flag
1331 if ((flag & OPERATE_MASK) != ADD_FLAG) {
1332 return STEP_NEXTKEY;
1333 }
1334
1335 errCode = SQLiteUtils::GetColumnBlobValue(statements.getEntriesStatement, 2, entry.value); // 2 is value
1336 if (errCode != E_OK) {
1337 return STEP_ERROR;
1338 }
1339
1340 Version curVer = static_cast<uint64_t>(sqlite3_column_int64(statements.getEntriesStatement, 3)); // 3 is ver
1341 // select the version that is greater than the curEntryVer;
1342 Key hashKey;
1343 errCode = DBCommon::CalcValueHash(entry.key, hashKey);
1344 if (errCode != E_OK) {
1345 return STEP_ERROR;
1346 }
1347 errCode = SQLiteUtils::BindBlobToStatement(statements.hashFilterStatement, 1, hashKey, false);
1348 if (errCode != E_OK) {
1349 return STEP_ERROR;
1350 }
1351
1352 errCode = sqlite3_bind_int64(statements.hashFilterStatement, 2, static_cast<int64_t>(curVer)); // 2 is curVer
1353 if (errCode != E_OK) {
1354 return STEP_ERROR;
1355 }
1356 errCode = sqlite3_bind_int64(statements.hashFilterStatement, 3, static_cast<int64_t>(version_)); // 3 is version
1357 if (errCode != E_OK) {
1358 return STEP_ERROR;
1359 }
1360 errCode = SQLiteUtils::StepWithRetry(statements.hashFilterStatement);
1361 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1362 return STEP_NEXTKEY;
1363 } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1364 return STEP_SUCCESS;
1365 } else {
1366 LOGE("Filter the entries hash key error:%d", errCode);
1367 return STEP_ERROR;
1368 }
1369 }
1370
IsRecordCleared(const Timestamp timestamp) const1371 bool SQLiteMultiVerTransaction::IsRecordCleared(const Timestamp timestamp) const
1372 {
1373 GetClearId();
1374 if (clearTime_ < 0) {
1375 return true;
1376 }
1377 if (timestamp <= static_cast<uint64_t>(clearTime_)) {
1378 return true;
1379 }
1380 return false;
1381 }
1382
CheckIfNeedSaveRecord(sqlite3_stmt * statement,const MultiVerKvEntry * multiVerKvEntry,bool & isNeedSave,Value & origVal) const1383 int SQLiteMultiVerTransaction::CheckIfNeedSaveRecord(sqlite3_stmt *statement, const MultiVerKvEntry *multiVerKvEntry,
1384 bool &isNeedSave, Value &origVal) const
1385 {
1386 // Bind the input args for sql
1387 int errCode;
1388 Key key;
1389 Value value;
1390 uint64_t operFlag = 0;
1391 static_cast<const GenericMultiVerKvEntry *>(multiVerKvEntry)->GetKey(key);
1392 static_cast<const GenericMultiVerKvEntry *>(multiVerKvEntry)->GetOperFlag(operFlag);
1393 static_cast<const GenericMultiVerKvEntry *>(multiVerKvEntry)->GetValue(value);
1394 if ((operFlag & OPERATE_MASK) == ADD_FLAG) {
1395 Key hashKey;
1396 errCode = DBCommon::CalcValueHash(key, hashKey);
1397 if (errCode != E_OK) {
1398 return errCode;
1399 }
1400 errCode = SQLiteUtils::BindBlobToStatement(statement, 1, hashKey, false); // key is the first arg
1401 } else {
1402 errCode = SQLiteUtils::BindBlobToStatement(statement, 1, key, false); // key is the first arg
1403 }
1404
1405 if (errCode != E_OK) {
1406 return errCode;
1407 }
1408
1409 // ori_stamp should diff from timstamp
1410 errCode = SQLiteUtils::StepWithRetry(statement);
1411 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1412 errCode = E_OK;
1413 isNeedSave = true;
1414 } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1415 auto readTime = static_cast<Timestamp>(sqlite3_column_int64(statement, 0)); // the first for time
1416 auto readOriTime = static_cast<Timestamp>(sqlite3_column_int64(statement, 1)); // the second for orig time.
1417 auto readVersion = static_cast<Version>(sqlite3_column_int64(statement, 2)); // 2 is version.
1418 errCode = SQLiteUtils::GetColumnBlobValue(statement, 3, origVal); // 3 is origin value.
1419 if (errCode != E_OK) {
1420 return errCode;
1421 }
1422 Timestamp timestamp = NO_TIMESTAMP;
1423 static_cast<const GenericMultiVerKvEntry *>(multiVerKvEntry)->GetTimestamp(timestamp);
1424 Timestamp oriTimestamp = NO_TIMESTAMP;
1425 static_cast<const GenericMultiVerKvEntry *>(multiVerKvEntry)->GetOriTimestamp(oriTimestamp);
1426 // Only the latest origin time is same or the reading time is bigger than putting time.
1427 isNeedSave = ((readTime < timestamp) && (readOriTime != oriTimestamp || value != origVal));
1428 LOGD("Timestamp :%" PRIu64 " vs %" PRIu64 ", %" PRIu64 " vs %" PRIu64 ", readVersion:%" PRIu64 ", version:"
1429 "%" PRIu64 ", %d", readOriTime, oriTimestamp, readTime, timestamp, readVersion, version_, isNeedSave);
1430 // if the version of the data to be saved is same to the original, you should notify the caller.
1431 if (readVersion != version_) {
1432 origVal.resize(0);
1433 }
1434 } else {
1435 LOGE("Check if need store sync entry failed:%d", errCode);
1436 }
1437
1438 return errCode;
1439 }
1440
CheckIfNeedSaveRecord(const MultiVerKvEntry * multiVerKvEntry,bool & isNeedSave,Value & value) const1441 int SQLiteMultiVerTransaction::CheckIfNeedSaveRecord(const MultiVerKvEntry *multiVerKvEntry, bool &isNeedSave,
1442 Value &value) const
1443 {
1444 auto entry = static_cast<const GenericMultiVerKvEntry *>(multiVerKvEntry);
1445 Timestamp timestamp = NO_TIMESTAMP;
1446 entry->GetTimestamp(timestamp);
1447 if (IsRecordCleared(timestamp)) {
1448 isNeedSave = false;
1449 entry->GetValue(value);
1450 return E_OK;
1451 }
1452
1453 sqlite3_stmt *statement = nullptr;
1454 int errCode = SQLiteUtils::GetStatement(db_, SELECT_ONE_BY_KEY_TIMESTAMP_SQL, statement);
1455 if (errCode != E_OK) {
1456 return errCode;
1457 }
1458
1459 errCode = CheckIfNeedSaveRecord(statement, entry, isNeedSave, value);
1460 int ret = E_OK;
1461 SQLiteUtils::ResetStatement(statement, true, ret);
1462 return errCode != E_OK ? errCode : ret;
1463 }
1464
PrepareForGetEntries(const Key & keyPrefix,GetEntriesStatements & statements) const1465 int SQLiteMultiVerTransaction::PrepareForGetEntries(const Key &keyPrefix, GetEntriesStatements &statements) const
1466 {
1467 int innerCode;
1468 int errCode = SQLiteUtils::GetStatement(db_, SELECT_BATCH_SQL, statements.getEntriesStatement);
1469 if (errCode != E_OK) {
1470 goto END;
1471 }
1472 errCode = SQLiteUtils::GetStatement(db_, SELECT_HASH_ENTRY_SQL, statements.hashFilterStatement);
1473 if (errCode != E_OK) {
1474 goto END;
1475 }
1476
1477 GetClearId(); // for read data.
1478 errCode = BindQueryEntriesArgs(statements.getEntriesStatement, keyPrefix);
1479 if (errCode != E_OK) {
1480 goto END;
1481 }
1482 return E_OK;
1483 END:
1484 innerCode = ReleaseGetEntriesStatements(statements);
1485 if (errCode == E_OK) {
1486 errCode = innerCode;
1487 }
1488 return errCode;
1489 }
1490
ReleaseGetEntriesStatements(GetEntriesStatements & statements) const1491 int SQLiteMultiVerTransaction::ReleaseGetEntriesStatements(GetEntriesStatements &statements) const
1492 {
1493 int errCode = E_OK;
1494 SQLiteUtils::ResetStatement(statements.getEntriesStatement, true, errCode);
1495 SQLiteUtils::ResetStatement(statements.hashFilterStatement, true, errCode);
1496 return errCode;
1497 }
1498
GetKeyAndValueByHashKey(sqlite3_stmt * statement,const Key & hashKey,Key & key,Value & value,bool isNeedReadKey) const1499 int SQLiteMultiVerTransaction::GetKeyAndValueByHashKey(sqlite3_stmt *statement, const Key &hashKey,
1500 Key &key, Value &value, bool isNeedReadKey) const
1501 {
1502 int errCode = BindQueryEntryArgs(statement, hashKey);
1503 if (errCode != E_OK) {
1504 return errCode;
1505 }
1506
1507 errCode = SQLiteUtils::StepWithRetry(statement);
1508 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1509 return -E_NOT_FOUND;
1510 } else if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1511 return errCode;
1512 }
1513
1514 uint64_t flag = static_cast<uint64_t>(sqlite3_column_int64(statement, 0)); // get the flag
1515 if ((flag & OPERATE_MASK) != ADD_FLAG) { // if not add or replace,
1516 return -E_NOT_FOUND;
1517 }
1518 if (isNeedReadKey) {
1519 errCode = SQLiteUtils::GetColumnBlobValue(statement, 1, key); // 2nd column result is key.
1520 if (errCode != E_OK) {
1521 return errCode;
1522 }
1523 }
1524
1525 return SQLiteUtils::GetColumnBlobValue(statement, 2, value); // 2 is value.
1526 }
1527
GetOriginKeyValueByHash(MultiVerEntryData & item,Value & value) const1528 int SQLiteMultiVerTransaction::GetOriginKeyValueByHash(MultiVerEntryData &item, Value &value) const
1529 {
1530 sqlite3_stmt *statement = nullptr;
1531 int errCode = SQLiteUtils::GetStatement(db_, SELECT_ONE_SQL, statement);
1532 if (errCode != E_OK) {
1533 return errCode;
1534 }
1535 Key origKey;
1536 errCode = GetKeyAndValueByHashKey(statement, item.key, origKey, value, true);
1537 if (errCode != E_OK) {
1538 goto END;
1539 }
1540 item.key = origKey;
1541 END:
1542 int ret = E_OK;
1543 SQLiteUtils::ResetStatement(statement, true, ret);
1544 return errCode != E_OK ? errCode : ret;
1545 }
1546 } // namespace DistributedDB
1547 #endif