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