• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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