• 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 #ifdef RELATIONAL_STORE
16 #include "sqlite_single_ver_relational_storage_executor.h"
17 
18 #include <algorithm>
19 #include <optional>
20 
21 #include "data_transformer.h"
22 #include "db_common.h"
23 #include "log_table_manager_factory.h"
24 #include "relational_row_data_impl.h"
25 #include "res_finalizer.h"
26 #include "sqlite_relational_utils.h"
27 
28 namespace DistributedDB {
29 namespace {
PermitSelect(void * a,int b,const char * c,const char * d,const char * e,const char * f)30 int PermitSelect(void *a, int b, const char *c, const char *d, const char *e, const char *f)
31 {
32     if (b != SQLITE_SELECT && b != SQLITE_READ && b != SQLITE_FUNCTION) {
33         return SQLITE_DENY;
34     }
35     return SQLITE_OK;
36 }
37 }
SQLiteSingleVerRelationalStorageExecutor(sqlite3 * dbHandle,bool writable,DistributedTableMode mode)38 SQLiteSingleVerRelationalStorageExecutor::SQLiteSingleVerRelationalStorageExecutor(sqlite3 *dbHandle, bool writable,
39     DistributedTableMode mode)
40     : SQLiteStorageExecutor(dbHandle, writable, false), mode_(mode)
41 {}
42 
43 
CheckTableConstraint(const TableInfo & table,DistributedTableMode mode)44 int CheckTableConstraint(const TableInfo &table, DistributedTableMode mode)
45 {
46     std::string trimedSql = DBCommon::TrimSpace(table.GetCreateTableSql());
47     if (DBCommon::HasConstraint(trimedSql, "WITHOUT ROWID", " ),", " ,;")) {
48         LOGE("[CreateDistributedTable] Not support create distributed table without rowid.");
49         return -E_NOT_SUPPORT;
50     }
51 
52     if (mode == DistributedTableMode::COLLABORATION) {
53         if (DBCommon::HasConstraint(trimedSql, "CHECK", " ,", " (")) {
54             LOGE("[CreateDistributedTable] Not support create distributed table with 'CHECK' constraint.");
55             return -E_NOT_SUPPORT;
56         }
57 
58         if (DBCommon::HasConstraint(trimedSql, "ON CONFLICT", " )", " ")) {
59             LOGE("[CreateDistributedTable] Not support create distributed table with 'ON CONFLICT' constraint.");
60             return -E_NOT_SUPPORT;
61         }
62 
63         if (DBCommon::HasConstraint(trimedSql, "REFERENCES", " )", " ")) {
64             LOGE("[CreateDistributedTable] Not support create distributed table with 'FOREIGN KEY' constraint.");
65             return -E_NOT_SUPPORT;
66         }
67     }
68 
69     if (mode == DistributedTableMode::SPLIT_BY_DEVICE) {
70         if (table.GetPrimaryKey().size() > 1) {
71             LOGE("[CreateDistributedTable] Not support create distributed table with composite primary keys.");
72             return -E_NOT_SUPPORT;
73         }
74     }
75 
76     return E_OK;
77 }
78 
79 namespace {
GetExistedDataTimeOffset(sqlite3 * db,const std::string & tableName,bool isMem,int64_t & timeOffset)80 int GetExistedDataTimeOffset(sqlite3 *db, const std::string &tableName, bool isMem, int64_t &timeOffset)
81 {
82     std::string sql = "SELECT get_sys_time(0) - max(rowid) - 1 FROM " + tableName;
83     sqlite3_stmt *stmt = nullptr;
84     int errCode = SQLiteUtils::GetStatement(db, sql, stmt);
85     if (errCode != E_OK) {
86         return errCode;
87     }
88     errCode = SQLiteUtils::StepWithRetry(stmt, isMem);
89     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
90         timeOffset = static_cast<int64_t>(sqlite3_column_int64(stmt, 0));
91         errCode = E_OK;
92     }
93     SQLiteUtils::ResetStatement(stmt, true, errCode);
94     return errCode;
95 }
96 }
97 
GeneLogInfoForExistedData(sqlite3 * db,const std::string & tableName,const TableInfo & table,const std::string & calPrimaryKeyHash)98 int SQLiteSingleVerRelationalStorageExecutor::GeneLogInfoForExistedData(sqlite3 *db, const std::string &tableName,
99     const TableInfo &table, const std::string &calPrimaryKeyHash)
100 {
101     int64_t timeOffset = 0;
102     int errCode = GetExistedDataTimeOffset(db, tableName, isMemDb_, timeOffset);
103     if (errCode != E_OK) {
104         return errCode;
105     }
106     std::string timeOffsetStr = std::to_string(timeOffset);
107     std::string logTable = DBConstant::RELATIONAL_PREFIX + tableName + "_log";
108     std::string sql = "INSERT INTO " + logTable +
109         " SELECT rowid, '', '', " + timeOffsetStr + " + rowid, " + timeOffsetStr + " + rowid, 0x2, " +
110         calPrimaryKeyHash + " FROM " + tableName + " WHERE 1=1;";
111     return SQLiteUtils::ExecuteRawSQL(db, sql);
112 }
113 
CreateDistributedTable(const std::string & tableName,DistributedTableMode mode,bool isUpgraded,const std::string & identity,TableInfo & table)114 int SQLiteSingleVerRelationalStorageExecutor::CreateDistributedTable(const std::string &tableName,
115     DistributedTableMode mode, bool isUpgraded, const std::string &identity, TableInfo &table)
116 {
117     if (dbHandle_ == nullptr) {
118         return -E_INVALID_DB;
119     }
120 
121     if (mode == DistributedTableMode::SPLIT_BY_DEVICE && !isUpgraded) {
122         bool isEmpty = false;
123         int errCode = SQLiteUtils::CheckTableEmpty(dbHandle_, tableName, isEmpty);
124         if (errCode != E_OK || !isEmpty) {
125             LOGE("[CreateDistributedTable] check table empty failed. error=%d, isEmpty=%d", errCode, isEmpty);
126             return -E_NOT_SUPPORT;
127         }
128     }
129 
130     int errCode = SQLiteUtils::AnalysisSchema(dbHandle_, tableName, table);
131     if (errCode != E_OK) {
132         LOGE("[CreateDistributedTable] analysis table schema failed. %d", errCode);
133         return errCode;
134     }
135 
136     errCode = CheckTableConstraint(table, mode);
137     if (errCode != E_OK) {
138         LOGE("[CreateDistributedTable] check table constraint failed.");
139         return errCode;
140     }
141 
142     // create log table
143     auto tableManager = LogTableManagerFactory::GetTableManager(mode);
144     errCode = tableManager->CreateRelationalLogTable(dbHandle_, table);
145     if (errCode != E_OK) {
146         LOGE("[CreateDistributedTable] create log table failed");
147         return errCode;
148     }
149 
150     if (!isUpgraded) {
151         std::string calPrimaryKeyHash = tableManager->CalcPrimaryKeyHash("", table, identity);
152         errCode = GeneLogInfoForExistedData(dbHandle_, tableName, table, calPrimaryKeyHash);
153         if (errCode != E_OK) {
154             return errCode;
155         }
156     }
157 
158     // add trigger
159     errCode = tableManager->AddRelationalLogTableTrigger(dbHandle_, table, identity);
160     if (errCode != E_OK) {
161         LOGE("[CreateDistributedTable] Add relational log table trigger failed.");
162         return errCode;
163     }
164     return SetLogTriggerStatus(true);
165 }
166 
UpgradeDistributedTable(const std::string & tableName,DistributedTableMode mode,bool & schemaChanged,RelationalSchemaObject & schema)167 int SQLiteSingleVerRelationalStorageExecutor::UpgradeDistributedTable(const std::string &tableName,
168     DistributedTableMode mode, bool &schemaChanged, RelationalSchemaObject &schema)
169 {
170     if (dbHandle_ == nullptr) {
171         return -E_INVALID_DB;
172     }
173     TableInfo newTableInfo;
174     int errCode = SQLiteUtils::AnalysisSchema(dbHandle_, tableName, newTableInfo);
175     if (errCode != E_OK) {
176         LOGE("[UpgradeDistributedTable] analysis table schema failed. %d", errCode);
177         return errCode;
178     }
179 
180     if (CheckTableConstraint(newTableInfo, mode)) {
181         LOGE("[UpgradeDistributedTable] Not support create distributed table without rowid.");
182         return -E_NOT_SUPPORT;
183     }
184 
185     // new table should has same or compatible upgrade
186     TableInfo tableInfo = schema.GetTable(tableName);
187     errCode = tableInfo.CompareWithTable(newTableInfo, schema.GetSchemaVersion());
188     if (errCode == -E_RELATIONAL_TABLE_INCOMPATIBLE) {
189         LOGE("[UpgradeDistributedTable] Not support with incompatible upgrade.");
190         return -E_SCHEMA_MISMATCH;
191     } else if (errCode == -E_RELATIONAL_TABLE_EQUAL) {
192         LOGD("[UpgradeDistributedTable] schema has not changed.");
193         return E_OK;
194     }
195 
196     schemaChanged = true;
197     errCode = AlterAuxTableForUpgrade(tableInfo, newTableInfo);
198     if (errCode != E_OK) {
199         LOGE("[UpgradeDistributedTable] Alter aux table for upgrade failed. %d", errCode);
200     }
201 
202     schema.AddRelationalTable(newTableInfo);
203     return errCode;
204 }
205 
206 namespace {
GetDeviceTableName(sqlite3 * handle,const std::string & tableName,const std::string & device,std::vector<std::string> & deviceTables)207 int GetDeviceTableName(sqlite3 *handle, const std::string &tableName, const std::string &device,
208     std::vector<std::string> &deviceTables)
209 {
210     if (device.empty() && tableName.empty()) { // device and table name should not both be empty
211         return -E_INVALID_ARGS;
212     }
213     std::string deviceHash = DBCommon::TransferStringToHex(DBCommon::TransferHashString(device));
214     std::string devicePattern = device.empty() ? "%" : deviceHash;
215     std::string tablePattern = tableName.empty() ? "%" : tableName;
216     std::string deviceTableName = DBConstant::RELATIONAL_PREFIX + tablePattern + "_" + devicePattern;
217 
218     const std::string checkSql = "SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '" +
219         deviceTableName + "';";
220     sqlite3_stmt *stmt = nullptr;
221     int errCode = SQLiteUtils::GetStatement(handle, checkSql, stmt);
222     if (errCode != E_OK) {
223         SQLiteUtils::ResetStatement(stmt, true, errCode);
224         return errCode;
225     }
226 
227     do {
228         errCode = SQLiteUtils::StepWithRetry(stmt, false);
229         if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
230             errCode = E_OK;
231             break;
232         } else if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
233             LOGE("Get table name failed. %d", errCode);
234             break;
235         }
236         std::string realTableName;
237         errCode = SQLiteUtils::GetColumnTextValue(stmt, 0, realTableName); // 0: table name result column index
238         if (errCode != E_OK || realTableName.empty()) { // sqlite might return a row with NULL
239             continue;
240         }
241         if (realTableName.rfind("_log") == (realTableName.length() - 4)) { // 4:suffix length of "_log"
242             continue;
243         }
244         deviceTables.emplace_back(realTableName);
245     } while (true);
246 
247     SQLiteUtils::ResetStatement(stmt, true, errCode);
248     return errCode;
249 }
250 
GetUpgradeFields(const TableInfo & oldTableInfo,const TableInfo & newTableInfo)251 std::vector<FieldInfo> GetUpgradeFields(const TableInfo &oldTableInfo, const TableInfo &newTableInfo)
252 {
253     std::vector<FieldInfo> fields;
254     auto itOld = oldTableInfo.GetFields().begin();
255     auto itNew = newTableInfo.GetFields().begin();
256     for (; itNew != newTableInfo.GetFields().end(); itNew++) {
257         if (itOld == oldTableInfo.GetFields().end() || itOld->first != itNew->first) {
258             fields.emplace_back(itNew->second);
259             continue;
260         }
261         itOld++;
262     }
263     return fields;
264 }
265 
UpgradeFields(sqlite3 * db,const std::vector<std::string> & tables,std::vector<FieldInfo> & fields)266 int UpgradeFields(sqlite3 *db, const std::vector<std::string> &tables, std::vector<FieldInfo> &fields)
267 {
268     if (db == nullptr) {
269         return -E_INVALID_ARGS;
270     }
271 
272     std::sort(fields.begin(), fields.end(), [] (const FieldInfo &a, const FieldInfo &b) {
273         return a.GetColumnId()< b.GetColumnId();
274     });
275     int errCode = E_OK;
276     for (const auto &table : tables) {
277         for (const auto &field : fields) {
278             std::string alterSql = "ALTER TABLE " + table + " ADD " + field.GetFieldName() + " " + field.GetDataType();
279             alterSql += field.IsNotNull() ? " NOT NULL" : "";
280             alterSql += field.HasDefaultValue() ? " DEFAULT " + field.GetDefaultValue() : "";
281             alterSql += ";";
282             errCode = SQLiteUtils::ExecuteRawSQL(db, alterSql);
283             if (errCode != E_OK) {
284                 LOGE("Alter table failed. %d", errCode);
285                 break;
286             }
287         }
288     }
289     return errCode;
290 }
291 
GetChangedIndexes(const TableInfo & oldTableInfo,const TableInfo & newTableInfo)292 std::map<std::string, CompositeFields> GetChangedIndexes(const TableInfo &oldTableInfo, const TableInfo &newTableInfo)
293 {
294     std::map<std::string, CompositeFields> indexes;
295     auto itOld = oldTableInfo.GetIndexDefine().begin();
296     auto itNew = newTableInfo.GetIndexDefine().begin();
297     auto itOldEnd = oldTableInfo.GetIndexDefine().end();
298     auto itNewEnd = newTableInfo.GetIndexDefine().end();
299 
300     while (itOld != itOldEnd && itNew != itNewEnd) {
301         if (itOld->first == itNew->first) {
302             if (itOld->second != itNew->second) {
303                 indexes.insert({itNew->first, itNew->second});
304             }
305             itOld++;
306             itNew++;
307         } else if (itOld->first < itNew->first) {
308             indexes.insert({itOld->first, {}});
309             itOld++;
310         } else if (itOld->first > itNew->first) {
311             indexes.insert({itNew->first, itNew->second});
312             itNew++;
313         }
314     }
315 
316     while (itOld != itOldEnd) {
317         indexes.insert({itOld->first, {}});
318         itOld++;
319     }
320 
321     while (itNew != itNewEnd) {
322         indexes.insert({itNew->first, itNew->second});
323         itNew++;
324     }
325 
326     return indexes;
327 }
328 
Upgradeindexes(sqlite3 * db,const std::vector<std::string> & tables,const std::map<std::string,CompositeFields> & indexes)329 int Upgradeindexes(sqlite3 *db, const std::vector<std::string> &tables,
330     const std::map<std::string, CompositeFields> &indexes)
331 {
332     if (db == nullptr) {
333         return -E_INVALID_ARGS;
334     }
335 
336     int errCode = E_OK;
337     for (const auto &table : tables) {
338         for (const auto &index : indexes) {
339             if (index.first.empty()) {
340                 continue;
341             }
342             std::string realIndexName = table + "_" + index.first;
343             std::string deleteIndexSql = "DROP INDEX IF EXISTS " + realIndexName;
344             errCode = SQLiteUtils::ExecuteRawSQL(db, deleteIndexSql);
345             if (errCode != E_OK) {
346                 LOGE("Drop index failed. %d", errCode);
347                 return errCode;
348             }
349 
350             if (index.second.empty()) { // empty means drop index only
351                 continue;
352             }
353 
354             auto it = index.second.begin();
355             std::string indexDefine = *it++;
356             while (it != index.second.end()) {
357                 indexDefine += ", " + *it++;
358             }
359             std::string createIndexSql = "CREATE INDEX IF NOT EXISTS " + realIndexName + " ON " + table +
360                 "(" + indexDefine + ");";
361             errCode = SQLiteUtils::ExecuteRawSQL(db, createIndexSql);
362             if (errCode != E_OK) {
363                 LOGE("Create index failed. %d", errCode);
364                 break;
365             }
366         }
367     }
368     return errCode;
369 }
370 }
371 
AlterAuxTableForUpgrade(const TableInfo & oldTableInfo,const TableInfo & newTableInfo)372 int SQLiteSingleVerRelationalStorageExecutor::AlterAuxTableForUpgrade(const TableInfo &oldTableInfo,
373     const TableInfo &newTableInfo)
374 {
375     std::vector<FieldInfo> upgradeFields = GetUpgradeFields(oldTableInfo, newTableInfo);
376     std::map<std::string, CompositeFields> upgradeIndexces = GetChangedIndexes(oldTableInfo, newTableInfo);
377     std::vector<std::string> deviceTables;
378     int errCode = GetDeviceTableName(dbHandle_, oldTableInfo.GetTableName(), {}, deviceTables);
379     if (errCode != E_OK) {
380         LOGE("Get device table name for alter table failed. %d", errCode);
381         return errCode;
382     }
383 
384     LOGD("Begin to alter table: upgrade fields[%zu], indexces[%zu], deviceTable[%zu]", upgradeFields.size(),
385         upgradeIndexces.size(), deviceTables.size());
386     errCode = UpgradeFields(dbHandle_, deviceTables, upgradeFields);
387     if (errCode != E_OK) {
388         LOGE("upgrade fields failed. %d", errCode);
389         return errCode;
390     }
391 
392     errCode = Upgradeindexes(dbHandle_, deviceTables, upgradeIndexces);
393     if (errCode != E_OK) {
394         LOGE("upgrade indexes failed. %d", errCode);
395     }
396 
397     return E_OK;
398 }
399 
StartTransaction(TransactType type)400 int SQLiteSingleVerRelationalStorageExecutor::StartTransaction(TransactType type)
401 {
402     if (dbHandle_ == nullptr) {
403         LOGE("Begin transaction failed, dbHandle is null.");
404         return -E_INVALID_DB;
405     }
406     int errCode = SQLiteUtils::BeginTransaction(dbHandle_, type);
407     if (errCode != E_OK) {
408         LOGE("Begin transaction failed, errCode = %d", errCode);
409     }
410     return errCode;
411 }
412 
Commit()413 int SQLiteSingleVerRelationalStorageExecutor::Commit()
414 {
415     if (dbHandle_ == nullptr) {
416         return -E_INVALID_DB;
417     }
418 
419     return SQLiteUtils::CommitTransaction(dbHandle_);
420 }
421 
Rollback()422 int SQLiteSingleVerRelationalStorageExecutor::Rollback()
423 {
424     if (dbHandle_ == nullptr) {
425         return -E_INVALID_DB;
426     }
427     int errCode = SQLiteUtils::RollbackTransaction(dbHandle_);
428     if (errCode != E_OK) {
429         LOGE("sqlite single ver storage executor rollback fail! errCode = [%d]", errCode);
430     }
431     return errCode;
432 }
433 
SetTableInfo(const TableInfo & tableInfo)434 void SQLiteSingleVerRelationalStorageExecutor::SetTableInfo(const TableInfo &tableInfo)
435 {
436     table_ = tableInfo;
437 }
438 
BindDataValueByType(sqlite3_stmt * statement,const std::optional<DataValue> & data,int cid)439 static int BindDataValueByType(sqlite3_stmt *statement, const std::optional<DataValue> &data, int cid)
440 {
441     int errCode = E_OK;
442     StorageType type = data.value().GetType();
443     switch (type) {
444         case StorageType::STORAGE_TYPE_INTEGER: {
445             int64_t intData = 0;
446             (void)data.value().GetInt64(intData);
447             errCode = SQLiteUtils::MapSQLiteErrno(sqlite3_bind_int64(statement, cid, intData));
448             break;
449         }
450 
451         case StorageType::STORAGE_TYPE_REAL: {
452             double doubleData = 0;
453             (void)data.value().GetDouble(doubleData);
454             errCode = SQLiteUtils::MapSQLiteErrno(sqlite3_bind_double(statement, cid, doubleData));
455             break;
456         }
457 
458         case StorageType::STORAGE_TYPE_TEXT: {
459             std::string strData;
460             (void)data.value().GetText(strData);
461             errCode = SQLiteUtils::BindTextToStatement(statement, cid, strData);
462             break;
463         }
464 
465         case StorageType::STORAGE_TYPE_BLOB: {
466             Blob blob;
467             (void)data.value().GetBlob(blob);
468             std::vector<uint8_t> blobData(blob.GetData(), blob.GetData() + blob.GetSize());
469             errCode = SQLiteUtils::BindBlobToStatement(statement, cid, blobData, true);
470             break;
471         }
472 
473         case StorageType::STORAGE_TYPE_NULL: {
474             errCode = SQLiteUtils::MapSQLiteErrno(sqlite3_bind_null(statement, cid));
475             break;
476         }
477 
478         default:
479             break;
480     }
481     return errCode;
482 }
483 
GetLogData(sqlite3_stmt * logStatement,LogInfo & logInfo)484 static int GetLogData(sqlite3_stmt *logStatement, LogInfo &logInfo)
485 {
486     logInfo.dataKey = sqlite3_column_int64(logStatement, 0);  // 0 means dataKey index
487 
488     std::vector<uint8_t> dev;
489     int errCode = SQLiteUtils::GetColumnBlobValue(logStatement, 1, dev);  // 1 means dev index
490     if (errCode != E_OK) {
491         return errCode;
492     }
493     logInfo.device = std::string(dev.begin(), dev.end());
494 
495     std::vector<uint8_t> oriDev;
496     errCode = SQLiteUtils::GetColumnBlobValue(logStatement, 2, oriDev);  // 2 means ori_dev index
497     if (errCode != E_OK) {
498         return errCode;
499     }
500     logInfo.originDev = std::string(oriDev.begin(), oriDev.end());
501     logInfo.timestamp = static_cast<uint64_t>(sqlite3_column_int64(logStatement, 3));  // 3 means timestamp index
502     logInfo.wTimestamp = static_cast<uint64_t>(sqlite3_column_int64(logStatement, 4));  // 4 means w_timestamp index
503     logInfo.flag = static_cast<uint64_t>(sqlite3_column_int64(logStatement, 5));  // 5 means flag index
504     logInfo.flag &= (~DataItem::LOCAL_FLAG);
505     logInfo.flag &= (~DataItem::UPDATE_FLAG);
506     return SQLiteUtils::GetColumnBlobValue(logStatement, 6, logInfo.hashKey);  // 6 means hashKey index
507 }
508 
GetDataItemSerialSize(DataItem & item,size_t appendLen)509 static size_t GetDataItemSerialSize(DataItem &item, size_t appendLen)
510 {
511     // timestamp and local flag: 3 * uint64_t, version(uint32_t), key, value, origin dev and the padding size.
512     // the size would not be very large.
513     static const size_t maxOrigDevLength = 40;
514     size_t devLength = std::max(maxOrigDevLength, item.origDev.size());
515     size_t dataSize = (Parcel::GetUInt64Len() * 3 + Parcel::GetUInt32Len() + Parcel::GetVectorCharLen(item.key) +
516         Parcel::GetVectorCharLen(item.value) + devLength + appendLen);
517     return dataSize;
518 }
519 
GetKvData(const Key & key,Value & value) const520 int SQLiteSingleVerRelationalStorageExecutor::GetKvData(const Key &key, Value &value) const
521 {
522     static const std::string SELECT_META_VALUE_SQL = "SELECT value FROM " + DBConstant::RELATIONAL_PREFIX +
523         "metadata WHERE key=?;";
524     sqlite3_stmt *statement = nullptr;
525     int errCode = SQLiteUtils::GetStatement(dbHandle_, SELECT_META_VALUE_SQL, statement);
526     if (errCode != E_OK) {
527         goto END;
528     }
529 
530     errCode = SQLiteUtils::BindBlobToStatement(statement, 1, key, false); // first arg.
531     if (errCode != E_OK) {
532         goto END;
533     }
534 
535     errCode = SQLiteUtils::StepWithRetry(statement, isMemDb_);
536     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
537         errCode = -E_NOT_FOUND;
538         goto END;
539     } else if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
540         goto END;
541     }
542 
543     errCode = SQLiteUtils::GetColumnBlobValue(statement, 0, value); // only one result.
544     END:
545     SQLiteUtils::ResetStatement(statement, true, errCode);
546     return errCode;
547 }
548 
PutKvData(const Key & key,const Value & value) const549 int SQLiteSingleVerRelationalStorageExecutor::PutKvData(const Key &key, const Value &value) const
550 {
551     static const std::string INSERT_META_SQL = "INSERT OR REPLACE INTO " + DBConstant::RELATIONAL_PREFIX +
552         "metadata VALUES(?,?);";
553     sqlite3_stmt *statement = nullptr;
554     int errCode = SQLiteUtils::GetStatement(dbHandle_, INSERT_META_SQL, statement);
555     if (errCode != E_OK) {
556         goto ERROR;
557     }
558 
559     errCode = SQLiteUtils::BindBlobToStatement(statement, 1, key, false);  // 1 means key index
560     if (errCode != E_OK) {
561         LOGE("[SingleVerExe][BindPutKv]Bind key error:%d", errCode);
562         goto ERROR;
563     }
564 
565     errCode = SQLiteUtils::BindBlobToStatement(statement, 2, value, true);  // 2 means value index
566     if (errCode != E_OK) {
567         LOGE("[SingleVerExe][BindPutKv]Bind value error:%d", errCode);
568         goto ERROR;
569     }
570     errCode = SQLiteUtils::StepWithRetry(statement, isMemDb_);
571     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
572         errCode = E_OK;
573     }
574 ERROR:
575     SQLiteUtils::ResetStatement(statement, true, errCode);
576     return errCode;
577 }
578 
DeleteMetaData(const std::vector<Key> & keys) const579 int SQLiteSingleVerRelationalStorageExecutor::DeleteMetaData(const std::vector<Key> &keys) const
580 {
581     static const std::string REMOVE_META_VALUE_SQL = "DELETE FROM " + DBConstant::RELATIONAL_PREFIX +
582         "metadata WHERE key=?;";
583     sqlite3_stmt *statement = nullptr;
584     int errCode = SQLiteUtils::GetStatement(dbHandle_, REMOVE_META_VALUE_SQL, statement);
585     if (errCode != E_OK) {
586         return errCode;
587     }
588 
589     for (const auto &key : keys) {
590         errCode = SQLiteUtils::BindBlobToStatement(statement, 1, key, false); // first arg.
591         if (errCode != E_OK) {
592             break;
593         }
594 
595         errCode = SQLiteUtils::StepWithRetry(statement, isMemDb_);
596         if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
597             break;
598         }
599         errCode = E_OK;
600         SQLiteUtils::ResetStatement(statement, false, errCode);
601     }
602     SQLiteUtils::ResetStatement(statement, true, errCode);
603     return CheckCorruptedStatus(errCode);
604 }
605 
DeleteMetaDataByPrefixKey(const Key & keyPrefix) const606 int SQLiteSingleVerRelationalStorageExecutor::DeleteMetaDataByPrefixKey(const Key &keyPrefix) const
607 {
608     static const std::string REMOVE_META_VALUE_BY_KEY_PREFIX_SQL = "DELETE FROM " + DBConstant::RELATIONAL_PREFIX +
609         "metadata WHERE key>=? AND key<=?;";
610     sqlite3_stmt *statement = nullptr;
611     int errCode = SQLiteUtils::GetStatement(dbHandle_, REMOVE_META_VALUE_BY_KEY_PREFIX_SQL, statement);
612     if (errCode != E_OK) {
613         return errCode;
614     }
615 
616     errCode = SQLiteUtils::BindPrefixKey(statement, 1, keyPrefix); // 1 is first arg.
617     if (errCode == E_OK) {
618         errCode = SQLiteUtils::StepWithRetry(statement, isMemDb_);
619         if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
620             errCode = E_OK;
621         }
622     }
623     SQLiteUtils::ResetStatement(statement, true, errCode);
624     return CheckCorruptedStatus(errCode);
625 }
626 
GetAllKeys(sqlite3_stmt * statement,std::vector<Key> & keys)627 static int GetAllKeys(sqlite3_stmt *statement, std::vector<Key> &keys)
628 {
629     if (statement == nullptr) {
630         return -E_INVALID_DB;
631     }
632     int errCode;
633     do {
634         errCode = SQLiteUtils::StepWithRetry(statement, false);
635         if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
636             Key key;
637             errCode = SQLiteUtils::GetColumnBlobValue(statement, 0, key);
638             if (errCode != E_OK) {
639                 break;
640             }
641 
642             keys.push_back(std::move(key));
643         } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
644             errCode = E_OK;
645             break;
646         } else {
647             LOGE("SQLite step for getting all keys failed:%d", errCode);
648             break;
649         }
650     } while (true);
651     return errCode;
652 }
653 
GetAllMetaKeys(std::vector<Key> & keys) const654 int SQLiteSingleVerRelationalStorageExecutor::GetAllMetaKeys(std::vector<Key> &keys) const
655 {
656     static const std::string SELECT_ALL_META_KEYS = "SELECT key FROM " + DBConstant::RELATIONAL_PREFIX + "metadata;";
657     sqlite3_stmt *statement = nullptr;
658     int errCode = SQLiteUtils::GetStatement(dbHandle_, SELECT_ALL_META_KEYS, statement);
659     if (errCode != E_OK) {
660         LOGE("[Relational][GetAllKey] Get statement failed:%d", errCode);
661         return errCode;
662     }
663     errCode = GetAllKeys(statement, keys);
664     SQLiteUtils::ResetStatement(statement, true, errCode);
665     return errCode;
666 }
667 
PrepareForSavingLog(const QueryObject & object,const std::string & deviceName,sqlite3_stmt * & logStmt,sqlite3_stmt * & queryStmt) const668 int SQLiteSingleVerRelationalStorageExecutor::PrepareForSavingLog(const QueryObject &object,
669     const std::string &deviceName, sqlite3_stmt *&logStmt, sqlite3_stmt *&queryStmt) const
670 {
671     std::string devName = DBCommon::TransferHashString(deviceName);
672     const std::string tableName = DBConstant::RELATIONAL_PREFIX + object.GetTableName() + "_log";
673     std::string dataFormat = "?, '" + deviceName + "', ?, ?, ?, ?, ?";
674     std::string columnList = "data_key, device, ori_device, timestamp, wtimestamp, flag, hash_key";
675     std::string sql = "INSERT OR REPLACE INTO " + tableName +
676         " (" + columnList + ") VALUES (" + dataFormat + ");";
677     int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, logStmt);
678     if (errCode != E_OK) {
679         LOGE("[info statement] Get log statement fail! errCode:%d", errCode);
680         return errCode;
681     }
682     std::string selectSql = "select " + columnList + " from " + tableName;
683     if (mode_ == DistributedTableMode::COLLABORATION) {
684         selectSql += " where hash_key = ?;";
685     } else {
686         selectSql += " where hash_key = ? and device = ?;";
687     }
688     errCode = SQLiteUtils::GetStatement(dbHandle_, selectSql, queryStmt);
689     if (errCode != E_OK) {
690         SQLiteUtils::ResetStatement(logStmt, true, errCode);
691         LOGE("[info statement] Get query statement fail! errCode:%d", errCode);
692     }
693     return errCode;
694 }
695 
PrepareForSavingData(const QueryObject & object,sqlite3_stmt * & statement) const696 int SQLiteSingleVerRelationalStorageExecutor::PrepareForSavingData(const QueryObject &object,
697     sqlite3_stmt *&statement) const
698 {
699     std::string colName;
700     std::string dataFormat;
701     for (size_t colId = 0; colId < table_.GetFields().size(); ++colId) {
702         colName += table_.GetFieldName(colId) + ",";
703         dataFormat += "?,";
704     }
705     colName.pop_back();
706     dataFormat.pop_back();
707 
708     const std::string sql = "INSERT OR REPLACE INTO " + table_.GetTableName() +
709         " (" + colName + ") VALUES (" + dataFormat + ");";
710     int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, statement);
711     if (errCode != E_OK) {
712         LOGE("[info statement] Get saving data statement fail! errCode:%d", errCode);
713     }
714     return errCode;
715 }
716 
SaveSyncLog(sqlite3_stmt * statement,sqlite3_stmt * queryStmt,const DataItem & dataItem,int64_t rowid)717 int SQLiteSingleVerRelationalStorageExecutor::SaveSyncLog(sqlite3_stmt *statement, sqlite3_stmt *queryStmt,
718     const DataItem &dataItem, int64_t rowid)
719 {
720     int errCode = SQLiteUtils::BindBlobToStatement(queryStmt, 1, dataItem.hashKey);  // 1 means hashkey index.
721     if (errCode != E_OK) {
722         return errCode;
723     }
724     if (mode_ != DistributedTableMode::COLLABORATION) {
725         errCode = SQLiteUtils::BindTextToStatement(queryStmt, 2, dataItem.dev);  // 2 means device index.
726         if (errCode != E_OK) {
727             return errCode;
728         }
729     }
730     LogInfo logInfoGet;
731     errCode = SQLiteUtils::StepWithRetry(queryStmt, isMemDb_);
732     if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
733         errCode = -E_NOT_FOUND;
734     } else {
735         errCode = GetLogData(queryStmt, logInfoGet);
736     }
737 
738     LogInfo logInfoBind;
739     logInfoBind.hashKey = dataItem.hashKey;
740     logInfoBind.device = dataItem.dev;
741     logInfoBind.timestamp = dataItem.timestamp;
742     logInfoBind.flag = dataItem.flag;
743 
744     if (errCode == -E_NOT_FOUND) { // insert
745         logInfoBind.wTimestamp = dataItem.writeTimestamp;
746         logInfoBind.originDev = dataItem.dev;
747     } else if (errCode == E_OK) { // update
748         logInfoBind.wTimestamp = logInfoGet.wTimestamp;
749         logInfoBind.originDev = logInfoGet.originDev;
750     } else {
751         return errCode;
752     }
753 
754     // bind
755     SQLiteUtils::BindInt64ToStatement(statement, 1, rowid);  // 1 means dataKey index
756     std::vector<uint8_t> originDev(logInfoBind.originDev.begin(), logInfoBind.originDev.end());
757     SQLiteUtils::BindBlobToStatement(statement, 2, originDev);  // 2 means ori_dev index
758     SQLiteUtils::BindInt64ToStatement(statement, 3, logInfoBind.timestamp);  // 3 means timestamp index
759     SQLiteUtils::BindInt64ToStatement(statement, 4, logInfoBind.wTimestamp);  // 4 means w_timestamp index
760     SQLiteUtils::BindInt64ToStatement(statement, 5, logInfoBind.flag);  // 5 means flag index
761     SQLiteUtils::BindBlobToStatement(statement, 6, logInfoBind.hashKey);  // 6 means hashKey index
762     errCode = SQLiteUtils::StepWithRetry(statement, isMemDb_);
763     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
764         return E_OK;
765     }
766     return errCode;
767 }
768 
DeleteSyncDataItem(const DataItem & dataItem,sqlite3_stmt * & stmt)769 int SQLiteSingleVerRelationalStorageExecutor::DeleteSyncDataItem(const DataItem &dataItem, sqlite3_stmt *&stmt)
770 {
771     if (stmt == nullptr) {
772         std::string sql = "DELETE FROM " + table_.GetTableName() + " WHERE rowid IN ("
773             "SELECT data_key FROM " + DBConstant::RELATIONAL_PREFIX + baseTblName_ + "_log ";
774         if (mode_ == DistributedTableMode::COLLABORATION) {
775             sql += "WHERE hash_key=?);";
776         } else {
777             sql += "WHERE hash_key=? AND device=? AND flag&0x01=0);";
778         }
779         int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, stmt);
780         if (errCode != E_OK) {
781             LOGE("[DeleteSyncDataItem] Get statement fail!, errCode:%d", errCode);
782             return errCode;
783         }
784     }
785 
786     int errCode = SQLiteUtils::BindBlobToStatement(stmt, 1, dataItem.hashKey); // 1 means hash_key index
787     if (errCode != E_OK) {
788         SQLiteUtils::ResetStatement(stmt, true, errCode);
789         return errCode;
790     }
791     if (mode_ != DistributedTableMode::COLLABORATION) {
792         errCode = SQLiteUtils::BindTextToStatement(stmt, 2, dataItem.dev); // 2 means device index
793         if (errCode != E_OK) {
794             SQLiteUtils::ResetStatement(stmt, true, errCode);
795             return errCode;
796         }
797     }
798     errCode = SQLiteUtils::StepWithRetry(stmt, isMemDb_);
799     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
800         errCode = E_OK;
801     }
802     SQLiteUtils::ResetStatement(stmt, false, errCode);  // Finalize outside.
803     return errCode;
804 }
805 
SaveSyncDataItem(const DataItem & dataItem,sqlite3_stmt * & saveDataStmt,sqlite3_stmt * & rmDataStmt,const std::vector<FieldInfo> & fieldInfos,int64_t & rowid)806 int SQLiteSingleVerRelationalStorageExecutor::SaveSyncDataItem(const DataItem &dataItem, sqlite3_stmt *&saveDataStmt,
807     sqlite3_stmt *&rmDataStmt, const std::vector<FieldInfo> &fieldInfos, int64_t &rowid)
808 {
809     if ((dataItem.flag & DataItem::DELETE_FLAG) != 0) {
810         return DeleteSyncDataItem(dataItem, rmDataStmt);
811     }
812     if ((mode_ == DistributedTableMode::COLLABORATION &&
813          table_.GetIdentifyKey().size() == 1u && table_.GetIdentifyKey().at(0) == "rowid") ||
814         (mode_ == DistributedTableMode::SPLIT_BY_DEVICE &&
815          table_.GetPrimaryKey().size() == 1u && table_.GetPrimaryKey().at(0) == "rowid") ||
816         table_.GetAutoIncrement()) {  // No primary key of auto increment
817         int errCode = DeleteSyncDataItem(dataItem, rmDataStmt);
818         if (errCode != E_OK) {
819             LOGE("Delete no pk data before insert failed, errCode=%d.", errCode);
820             return errCode;
821         }
822     }
823     OptRowDataWithLog data;
824     int errCode = DataTransformer::DeSerializeDataItem(dataItem, data, fieldInfos);
825     if (errCode != E_OK) {
826         LOGE("[RelationalStorageExecutor] DeSerialize dataItem failed! errCode = [%d]", errCode);
827         return errCode;
828     }
829 
830     if (data.optionalData.size() != table_.GetFields().size()) {
831         LOGW("Remote data has different fields with local data. Remote size:%zu, local size:%zu",
832             data.optionalData.size(), table_.GetFields().size());
833     }
834 
835     auto putSize = std::min(data.optionalData.size(), table_.GetFields().size());
836     for (size_t cid = 0; cid < putSize; ++cid) {
837         const auto &fieldData = data.optionalData[cid];
838         errCode = BindDataValueByType(saveDataStmt, fieldData, cid + 1);
839         if (errCode != E_OK) {
840             LOGE("Bind data failed, errCode:%d, cid:%zu.", errCode, cid + 1);
841             return errCode;
842         }
843     }
844 
845     errCode = SQLiteUtils::StepWithRetry(saveDataStmt, isMemDb_);
846     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
847         rowid = SQLiteUtils::GetLastRowId(dbHandle_);
848         errCode = E_OK;
849     }
850     return errCode;
851 }
852 
DeleteSyncLog(const DataItem & dataItem,sqlite3_stmt * & stmt)853 int SQLiteSingleVerRelationalStorageExecutor::DeleteSyncLog(const DataItem &dataItem, sqlite3_stmt *&stmt)
854 {
855     if (stmt == nullptr) {
856         std::string sql = "DELETE FROM " + DBConstant::RELATIONAL_PREFIX + baseTblName_ + "_log ";
857         if (mode_ == DistributedTableMode::COLLABORATION) {
858             sql += "WHERE hash_key=?";
859         } else {
860             sql += "WHERE hash_key=? AND device=?";
861         }
862 
863         int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, stmt);
864         if (errCode != E_OK) {
865             LOGE("[DeleteSyncLog] Get statement fail!");
866             return errCode;
867         }
868     }
869 
870     int errCode = SQLiteUtils::BindBlobToStatement(stmt, 1, dataItem.hashKey); // 1 means hashkey index
871     if (errCode != E_OK) {
872         SQLiteUtils::ResetStatement(stmt, true, errCode);
873         return errCode;
874     }
875     if (mode_ != DistributedTableMode::COLLABORATION) {
876         errCode = SQLiteUtils::BindTextToStatement(stmt, 2, dataItem.dev); // 2 means device index
877         if (errCode != E_OK) {
878             SQLiteUtils::ResetStatement(stmt, true, errCode);
879             return errCode;
880         }
881     }
882     errCode = SQLiteUtils::StepWithRetry(stmt, isMemDb_);
883     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
884         errCode = E_OK;
885     }
886     SQLiteUtils::ResetStatement(stmt, false, errCode);  // Finalize outside.
887     return errCode;
888 }
889 
ProcessMissQueryData(const DataItem & item,sqlite3_stmt * & rmDataStmt,sqlite3_stmt * & rmLogStmt)890 int SQLiteSingleVerRelationalStorageExecutor::ProcessMissQueryData(const DataItem &item, sqlite3_stmt *&rmDataStmt,
891     sqlite3_stmt *&rmLogStmt)
892 {
893     int errCode = DeleteSyncDataItem(item, rmDataStmt);
894     if (errCode != E_OK) {
895         return errCode;
896     }
897     return DeleteSyncLog(item, rmLogStmt);
898 }
899 
GetSyncDataPre(const DataItem & dataItem,DataItem & itemGet)900 int SQLiteSingleVerRelationalStorageExecutor::GetSyncDataPre(const DataItem &dataItem, DataItem &itemGet)
901 {
902     if (saveStmt_.queryStmt == nullptr) {
903         return -E_INVALID_ARGS;
904     }
905     int errCode = SQLiteUtils::BindBlobToStatement(saveStmt_.queryStmt, 1, dataItem.hashKey); // 1 index for hashkey
906     if (errCode != E_OK) {
907         return errCode;
908     }
909     if (mode_ != DistributedTableMode::COLLABORATION) {
910         errCode = SQLiteUtils::BindTextToStatement(saveStmt_.queryStmt, 2, dataItem.dev); // 2 index for devices
911         if (errCode != E_OK) {
912             return errCode;
913         }
914     }
915 
916     LogInfo logInfoGet;
917     errCode = SQLiteUtils::StepWithRetry(saveStmt_.queryStmt, isMemDb_);
918     if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
919         errCode = -E_NOT_FOUND;
920     } else {
921         errCode = GetLogData(saveStmt_.queryStmt, logInfoGet);
922     }
923     itemGet.timestamp = logInfoGet.timestamp;
924     SQLiteUtils::ResetStatement(saveStmt_.queryStmt, false, errCode);
925     return errCode;
926 }
927 
CheckDataConflictDefeated(const DataItem & dataItem,bool & isDefeated)928 int SQLiteSingleVerRelationalStorageExecutor::CheckDataConflictDefeated(const DataItem &dataItem, bool &isDefeated)
929 {
930     if ((dataItem.flag & DataItem::REMOTE_DEVICE_DATA_MISS_QUERY) != DataItem::REMOTE_DEVICE_DATA_MISS_QUERY &&
931         mode_ == DistributedTableMode::SPLIT_BY_DEVICE) {
932         isDefeated = false; // no need to solve conflict except miss query data
933         return E_OK;
934     }
935 
936     DataItem itemGet;
937     int errCode = GetSyncDataPre(dataItem, itemGet);
938     if (errCode != E_OK && errCode != -E_NOT_FOUND) {
939         LOGE("Failed to get raw data. %d", errCode);
940         return errCode;
941     }
942     isDefeated = (dataItem.timestamp <= itemGet.timestamp); // defeated if item timestamp is earlier then raw data
943     return E_OK;
944 }
945 
SaveSyncDataItem(const std::vector<FieldInfo> & fieldInfos,const std::string & deviceName,DataItem & item)946 int SQLiteSingleVerRelationalStorageExecutor::SaveSyncDataItem(const std::vector<FieldInfo> &fieldInfos,
947     const std::string &deviceName, DataItem &item)
948 {
949     item.dev = deviceName;
950     bool isDefeated = false;
951     int errCode = CheckDataConflictDefeated(item, isDefeated);
952     if (errCode != E_OK) {
953         LOGE("check data conflict failed. %d", errCode);
954         return errCode;
955     }
956 
957     if (isDefeated) {
958         LOGD("Data was defeated.");
959         return E_OK;
960     }
961     if ((item.flag & DataItem::REMOTE_DEVICE_DATA_MISS_QUERY) != 0) {
962         return ProcessMissQueryData(item, saveStmt_.rmDataStmt, saveStmt_.rmLogStmt);
963     }
964     int64_t rowid = -1;
965     errCode = SaveSyncDataItem(item, saveStmt_.saveDataStmt, saveStmt_.rmDataStmt, fieldInfos, rowid);
966     if (errCode == E_OK || errCode == -E_NOT_FOUND) {
967         errCode = SaveSyncLog(saveStmt_.saveLogStmt, saveStmt_.queryStmt, item, rowid);
968     }
969     return errCode;
970 }
971 
SaveSyncDataItems(const QueryObject & object,std::vector<DataItem> & dataItems,const std::string & deviceName)972 int SQLiteSingleVerRelationalStorageExecutor::SaveSyncDataItems(const QueryObject &object,
973     std::vector<DataItem> &dataItems, const std::string &deviceName)
974 {
975     int errCode = PrepareForSavingData(object, saveStmt_.saveDataStmt);
976     if (errCode != E_OK) {
977         return errCode;
978     }
979     errCode = PrepareForSavingLog(object, deviceName, saveStmt_.saveLogStmt, saveStmt_.queryStmt);
980     if (errCode != E_OK) {
981         SQLiteUtils::ResetStatement(saveStmt_.saveDataStmt, true, errCode);
982         return errCode;
983     }
984     std::vector<FieldInfo> fieldInfos;
985     for (const auto &col: table_.GetFields()) {
986         fieldInfos.push_back(col.second);
987     }
988 
989     for (auto &item : dataItems) {
990         if (item.neglect) { // Do not save this record if it is neglected
991             continue;
992         }
993         errCode = SaveSyncDataItem(fieldInfos, deviceName, item);
994         if (errCode != E_OK) {
995             break;
996         }
997         // Need not reset rmDataStmt and rmLogStmt here.
998         saveStmt_.ResetStatements(false);
999     }
1000     if (errCode == -E_NOT_FOUND) {
1001         errCode = E_OK;
1002     }
1003     saveStmt_.ResetStatements(true);
1004     return errCode;
1005 }
1006 
SaveSyncItems(const QueryObject & object,std::vector<DataItem> & dataItems,const std::string & deviceName,const TableInfo & table,bool useTrans)1007 int SQLiteSingleVerRelationalStorageExecutor::SaveSyncItems(const QueryObject &object, std::vector<DataItem> &dataItems,
1008     const std::string &deviceName, const TableInfo &table, bool useTrans)
1009 {
1010     if (useTrans) {
1011         int errCode = StartTransaction(TransactType::IMMEDIATE);
1012         if (errCode != E_OK) {
1013             return errCode;
1014         }
1015     }
1016 
1017     int errCode = SetLogTriggerStatus(false);
1018     if (errCode != E_OK) {
1019         goto END;
1020     }
1021 
1022     baseTblName_ = object.GetTableName();
1023     SetTableInfo(table);
1024     errCode = SaveSyncDataItems(object, dataItems, deviceName);
1025     if (errCode != E_OK) {
1026         LOGE("Save sync data items failed. errCode=%d", errCode);
1027         goto END;
1028     }
1029 
1030     errCode = SetLogTriggerStatus(true);
1031 END:
1032     if (useTrans) {
1033         if (errCode == E_OK) {
1034             errCode = Commit();
1035         } else {
1036             (void)Rollback(); // Keep the error code of the first scene
1037         }
1038     }
1039     return errCode;
1040 }
1041 
GetDataItemForSync(sqlite3_stmt * stmt,DataItem & dataItem,bool isGettingDeletedData) const1042 int SQLiteSingleVerRelationalStorageExecutor::GetDataItemForSync(sqlite3_stmt *stmt, DataItem &dataItem,
1043     bool isGettingDeletedData) const
1044 {
1045     RowDataWithLog data;
1046     int errCode = GetLogData(stmt, data.logInfo);
1047     if (errCode != E_OK) {
1048         LOGE("relational data value transfer to kv fail");
1049         return errCode;
1050     }
1051 
1052     if (!isGettingDeletedData) {
1053         for (size_t cid = 0; cid < table_.GetFields().size(); ++cid) {
1054             DataValue value;
1055             errCode = SQLiteRelationalUtils::GetDataValueByType(stmt, cid + DBConstant::RELATIONAL_LOG_TABLE_FIELD_NUM,
1056                 value);
1057             if (errCode != E_OK) {
1058                 return errCode;
1059             }
1060             data.rowData.push_back(std::move(value));
1061         }
1062     }
1063 
1064     errCode = DataTransformer::SerializeDataItem(data,
1065         isGettingDeletedData ? std::vector<FieldInfo>() : table_.GetFieldInfos(), dataItem);
1066     if (errCode != E_OK) {
1067         LOGE("relational data value transfer to kv fail");
1068     }
1069     return errCode;
1070 }
1071 
GetMissQueryData(sqlite3_stmt * fullStmt,DataItem & item)1072 int SQLiteSingleVerRelationalStorageExecutor::GetMissQueryData(sqlite3_stmt *fullStmt, DataItem &item)
1073 {
1074     int errCode = GetDataItemForSync(fullStmt, item, false);
1075     if (errCode != E_OK) {
1076         return errCode;
1077     }
1078     item.value = {};
1079     item.flag |= DataItem::REMOTE_DEVICE_DATA_MISS_QUERY;
1080     return errCode;
1081 }
1082 
1083 namespace {
StepNext(bool isMemDB,sqlite3_stmt * stmt,Timestamp & timestamp)1084 int StepNext(bool isMemDB, sqlite3_stmt *stmt, Timestamp &timestamp)
1085 {
1086     if (stmt == nullptr) {
1087         return -E_INVALID_ARGS;
1088     }
1089     int errCode = SQLiteUtils::StepWithRetry(stmt, isMemDB);
1090     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1091         timestamp = INT64_MAX;
1092         errCode = E_OK;
1093     } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1094         timestamp = static_cast<uint64_t>(sqlite3_column_int64(stmt, 3));  // 3 means timestamp index
1095         errCode = E_OK;
1096     }
1097     return errCode;
1098 }
1099 
AppendData(const DataSizeSpecInfo & sizeInfo,size_t appendLength,size_t & overLongSize,size_t & dataTotalSize,std::vector<DataItem> & dataItems,DataItem && item)1100 int AppendData(const DataSizeSpecInfo &sizeInfo, size_t appendLength, size_t &overLongSize, size_t &dataTotalSize,
1101     std::vector<DataItem> &dataItems, DataItem &&item)
1102 {
1103     // If one record is over 4M, ignore it.
1104     if (item.value.size() > DBConstant::MAX_VALUE_SIZE) {
1105         overLongSize++;
1106     } else {
1107         // If dataTotalSize value is bigger than blockSize value , reserve the surplus data item.
1108         dataTotalSize += GetDataItemSerialSize(item, appendLength);
1109         if ((dataTotalSize > sizeInfo.blockSize && !dataItems.empty()) || dataItems.size() >= sizeInfo.packetSize) {
1110             return -E_UNFINISHED;
1111         } else {
1112             dataItems.push_back(item);
1113         }
1114     }
1115     return E_OK;
1116 }
1117 }
1118 
GetQueryDataAndStepNext(bool isFirstTime,bool isGettingDeletedData,sqlite3_stmt * queryStmt,DataItem & item,Timestamp & queryTime)1119 int SQLiteSingleVerRelationalStorageExecutor::GetQueryDataAndStepNext(bool isFirstTime, bool isGettingDeletedData,
1120     sqlite3_stmt *queryStmt, DataItem &item, Timestamp &queryTime)
1121 {
1122     if (!isFirstTime) { // For the first time, never step before, can get nothing
1123         int errCode = GetDataItemForSync(queryStmt, item, isGettingDeletedData);
1124         if (errCode != E_OK) {
1125             return errCode;
1126         }
1127     }
1128     return StepNext(isMemDb_, queryStmt, queryTime);
1129 }
1130 
GetMissQueryDataAndStepNext(sqlite3_stmt * fullStmt,DataItem & item,Timestamp & missQueryTime)1131 int SQLiteSingleVerRelationalStorageExecutor::GetMissQueryDataAndStepNext(sqlite3_stmt *fullStmt, DataItem &item,
1132     Timestamp &missQueryTime)
1133 {
1134     int errCode = GetMissQueryData(fullStmt, item);
1135     if (errCode != E_OK) {
1136         return errCode;
1137     }
1138     return StepNext(isMemDb_, fullStmt, missQueryTime);
1139 }
1140 
GetSyncDataByQuery(std::vector<DataItem> & dataItems,size_t appendLength,const DataSizeSpecInfo & sizeInfo,std::function<int (sqlite3 *,sqlite3_stmt * &,sqlite3_stmt * &,bool &)> getStmt,const TableInfo & tableInfo)1141 int SQLiteSingleVerRelationalStorageExecutor::GetSyncDataByQuery(std::vector<DataItem> &dataItems, size_t appendLength,
1142     const DataSizeSpecInfo &sizeInfo, std::function<int(sqlite3 *, sqlite3_stmt *&, sqlite3_stmt *&, bool &)> getStmt,
1143     const TableInfo &tableInfo)
1144 {
1145     baseTblName_ = tableInfo.GetTableName();
1146     SetTableInfo(tableInfo);
1147     sqlite3_stmt *queryStmt = nullptr;
1148     sqlite3_stmt *fullStmt = nullptr;
1149     bool isGettingDeletedData = false;
1150     int errCode = getStmt(dbHandle_, queryStmt, fullStmt, isGettingDeletedData);
1151     if (errCode != E_OK) {
1152         return errCode;
1153     }
1154 
1155     Timestamp queryTime = 0;
1156     Timestamp missQueryTime = (fullStmt == nullptr ? INT64_MAX : 0);
1157 
1158     bool isFirstTime = true;
1159     size_t dataTotalSize = 0;
1160     size_t overLongSize = 0;
1161     do {
1162         DataItem item;
1163         if (queryTime < missQueryTime) {
1164             errCode = GetQueryDataAndStepNext(isFirstTime, isGettingDeletedData, queryStmt, item, queryTime);
1165         } else if (queryTime == missQueryTime) {
1166             errCode = GetQueryDataAndStepNext(isFirstTime, isGettingDeletedData, queryStmt, item, queryTime);
1167             if (errCode != E_OK) {
1168                 break;
1169             }
1170             errCode = StepNext(isMemDb_, fullStmt, missQueryTime);
1171         } else {
1172             errCode = GetMissQueryDataAndStepNext(fullStmt, item, missQueryTime);
1173         }
1174 
1175         if (errCode == E_OK && !isFirstTime) {
1176             errCode = AppendData(sizeInfo, appendLength, overLongSize, dataTotalSize, dataItems, std::move(item));
1177         }
1178 
1179         if (errCode != E_OK) {
1180             break;
1181         }
1182 
1183         isFirstTime = false;
1184         if (queryTime == INT64_MAX && missQueryTime == INT64_MAX) {
1185             errCode = -E_FINISHED;
1186             break;
1187         }
1188     } while (true);
1189     LOGI("Get sync data finished, rc:%d, record size:%zu, overlong size:%zu, isDeleted:%d",
1190         errCode, dataItems.size(), overLongSize, isGettingDeletedData);
1191     SQLiteUtils::ResetStatement(queryStmt, true, errCode);
1192     SQLiteUtils::ResetStatement(fullStmt, true, errCode);
1193     return errCode;
1194 }
1195 
CheckDBModeForRelational()1196 int SQLiteSingleVerRelationalStorageExecutor::CheckDBModeForRelational()
1197 {
1198     std::string journalMode;
1199     int errCode = SQLiteUtils::GetJournalMode(dbHandle_, journalMode);
1200 
1201     for (auto &c : journalMode) { // convert to lowercase
1202         c = static_cast<char>(std::tolower(c));
1203     }
1204 
1205     if (errCode == E_OK && journalMode != "wal") {
1206         LOGE("Not support journal mode %s for relational db, expect wal mode.", journalMode.c_str());
1207         return -E_NOT_SUPPORT;
1208     }
1209     return errCode;
1210 }
1211 
DeleteDistributedDeviceTable(const std::string & device,const std::string & tableName)1212 int SQLiteSingleVerRelationalStorageExecutor::DeleteDistributedDeviceTable(const std::string &device,
1213     const std::string &tableName)
1214 {
1215     std::vector<std::string> deviceTables;
1216     int errCode = GetDeviceTableName(dbHandle_, tableName, device, deviceTables);
1217     if (errCode != E_OK) {
1218         LOGE("Get device table name for alter table failed. %d", errCode);
1219         return errCode;
1220     }
1221 
1222     LOGD("Begin to delete device table: deviceTable[%zu]", deviceTables.size());
1223     for (const auto &table : deviceTables) {
1224         std::string deleteSql = "DROP TABLE IF EXISTS " + table + ";"; // drop the found table
1225         errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, deleteSql);
1226         if (errCode != E_OK) {
1227             LOGE("Delete device data failed. %d", errCode);
1228             break;
1229         }
1230     }
1231     return errCode;
1232 }
1233 
DeleteDistributedDeviceTableLog(const std::string & device,const std::string & tableName,const std::map<std::string,TableInfo> & tables)1234 int SQLiteSingleVerRelationalStorageExecutor::DeleteDistributedDeviceTableLog(const std::string &device,
1235     const std::string &tableName, const std::map<std::string, TableInfo> &tables)
1236 {
1237     int errCode = E_OK;
1238     for (const auto &it : tables) {
1239         if (!tableName.empty() && it.second.GetTableName() != tableName) {
1240             continue; // Table name is specified, skip others
1241         }
1242         std::string deleteLogSql = "DELETE FROM " + DBConstant::RELATIONAL_PREFIX + it.second.GetTableName() +
1243             "_log WHERE device = ?";
1244         sqlite3_stmt *deleteLogStmt = nullptr;
1245         errCode = SQLiteUtils::GetStatement(dbHandle_, deleteLogSql, deleteLogStmt);
1246         if (errCode != E_OK) {
1247             LOGE("Get delete device data log statement failed. %d", errCode);
1248             return errCode;
1249         }
1250 
1251         errCode = SQLiteUtils::BindTextToStatement(deleteLogStmt, 1, device);
1252         if (errCode != E_OK) {
1253             LOGE("Bind device to delete data log statement failed. %d", errCode);
1254             SQLiteUtils::ResetStatement(deleteLogStmt, true, errCode);
1255             return errCode;
1256         }
1257 
1258         errCode = SQLiteUtils::StepWithRetry(deleteLogStmt);
1259         if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1260             errCode = E_OK;
1261         } else {
1262             LOGE("Delete data log failed. %d", errCode);
1263         }
1264 
1265         SQLiteUtils::ResetStatement(deleteLogStmt, true, errCode);
1266     }
1267 
1268     return errCode;
1269 }
1270 
DeleteDistributedLogTable(const std::string & tableName)1271 int SQLiteSingleVerRelationalStorageExecutor::DeleteDistributedLogTable(const std::string &tableName)
1272 {
1273     if (tableName.empty()) {
1274         return -E_INVALID_ARGS;
1275     }
1276     std::string logTableName = DBConstant::RELATIONAL_PREFIX + tableName + "_log";
1277     std::string deleteSql = "DROP TABLE IF EXISTS " + logTableName + ";";
1278     int errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, deleteSql);
1279     if (errCode != E_OK) {
1280         LOGE("Delete distributed log table failed. %d", errCode);
1281     }
1282     return errCode;
1283 }
1284 
CheckAndCleanDistributedTable(const std::vector<std::string> & tableNames,std::vector<std::string> & missingTables)1285 int SQLiteSingleVerRelationalStorageExecutor::CheckAndCleanDistributedTable(const std::vector<std::string> &tableNames,
1286     std::vector<std::string> &missingTables)
1287 {
1288     if (tableNames.empty()) {
1289         return E_OK;
1290     }
1291     const std::string checkSql = "SELECT name FROM sqlite_master WHERE type='table' AND name=?;";
1292     sqlite3_stmt *stmt = nullptr;
1293     int errCode = SQLiteUtils::GetStatement(dbHandle_, checkSql, stmt);
1294     if (errCode != E_OK) {
1295         SQLiteUtils::ResetStatement(stmt, true, errCode);
1296         return errCode;
1297     }
1298     for (const auto &tableName : tableNames) {
1299         errCode = SQLiteUtils::BindTextToStatement(stmt, 1, tableName); // 1: tablename bind index
1300         if (errCode != E_OK) {
1301             LOGE("Bind table name to check distributed table statement failed. %d", errCode);
1302             break;
1303         }
1304 
1305         errCode = SQLiteUtils::StepWithRetry(stmt, false);
1306         if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { // The table in schema was dropped
1307             errCode = DeleteDistributedDeviceTable({}, tableName); // Clean the auxiliary tables for the dropped table
1308             if (errCode != E_OK) {
1309                 LOGE("Delete device tables for missing distributed table failed. %d", errCode);
1310                 break;
1311             }
1312             errCode = DeleteDistributedLogTable(tableName);
1313             if (errCode != E_OK) {
1314                 LOGE("Delete log tables for missing distributed table failed. %d", errCode);
1315                 break;
1316             }
1317             missingTables.emplace_back(tableName);
1318         } else if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1319             LOGE("Check distributed table failed. %d", errCode);
1320             break;
1321         }
1322         errCode = E_OK; // Check result ok for distributed table is still exists
1323         SQLiteUtils::ResetStatement(stmt, false, errCode);
1324     }
1325     SQLiteUtils::ResetStatement(stmt, true, errCode);
1326     return CheckCorruptedStatus(errCode);
1327 }
1328 
CreateDistributedDeviceTable(const std::string & device,const TableInfo & baseTbl)1329 int SQLiteSingleVerRelationalStorageExecutor::CreateDistributedDeviceTable(const std::string &device,
1330     const TableInfo &baseTbl)
1331 {
1332     if (dbHandle_ == nullptr) {
1333         return -E_INVALID_DB;
1334     }
1335 
1336     if (device.empty() || !baseTbl.IsValid()) {
1337         return -E_INVALID_ARGS;
1338     }
1339 
1340     std::string deviceTableName = DBCommon::GetDistributedTableName(device, baseTbl.GetTableName());
1341     int errCode = SQLiteUtils::CreateSameStuTable(dbHandle_, baseTbl, deviceTableName);
1342     if (errCode != E_OK) {
1343         LOGE("Create device table failed. %d", errCode);
1344         return errCode;
1345     }
1346 
1347     errCode = SQLiteUtils::CloneIndexes(dbHandle_, baseTbl.GetTableName(), deviceTableName);
1348     if (errCode != E_OK) {
1349         LOGE("Copy index to device table failed. %d", errCode);
1350     }
1351     return errCode;
1352 }
1353 
CheckQueryObjectLegal(const TableInfo & table,QueryObject & query,const std::string & schemaVersion)1354 int SQLiteSingleVerRelationalStorageExecutor::CheckQueryObjectLegal(const TableInfo &table, QueryObject &query,
1355     const std::string &schemaVersion)
1356 {
1357     if (dbHandle_ == nullptr) {
1358         return -E_INVALID_DB;
1359     }
1360 
1361     TableInfo newTable;
1362     int errCode = SQLiteUtils::AnalysisSchema(dbHandle_, table.GetTableName(), newTable);
1363     if (errCode != E_OK && errCode != -E_NOT_FOUND) {
1364         LOGE("Check new schema failed. %d", errCode);
1365         return errCode;
1366     } else {
1367         errCode = table.CompareWithTable(newTable, schemaVersion);
1368         if (errCode != -E_RELATIONAL_TABLE_EQUAL && errCode != -E_RELATIONAL_TABLE_COMPATIBLE) {
1369             LOGE("Check schema failed, schema was changed. %d", errCode);
1370             return -E_DISTRIBUTED_SCHEMA_CHANGED;
1371         } else {
1372             errCode = E_OK;
1373         }
1374     }
1375 
1376     SqliteQueryHelper helper = query.GetQueryHelper(errCode);
1377     if (errCode != E_OK) {
1378         LOGE("Get query helper for check query failed. %d", errCode);
1379         return errCode;
1380     }
1381 
1382     if (!query.IsQueryForRelationalDB()) {
1383         LOGE("Not support for this query type.");
1384         return -E_NOT_SUPPORT;
1385     }
1386 
1387     SyncTimeRange defaultTimeRange;
1388     sqlite3_stmt *stmt = nullptr;
1389     errCode = helper.GetRelationalQueryStatement(dbHandle_, defaultTimeRange.beginTime, defaultTimeRange.endTime, {},
1390         stmt);
1391     if (errCode != E_OK) {
1392         LOGE("Get query statement for check query failed. %d", errCode);
1393     }
1394 
1395     SQLiteUtils::ResetStatement(stmt, true, errCode);
1396     return errCode;
1397 }
1398 
ResetStatements(bool isNeedFinalize)1399 int SQLiteSingleVerRelationalStorageExecutor::SaveSyncDataStmt::ResetStatements(bool isNeedFinalize)
1400 {
1401     int errCode = E_OK;
1402     if (saveDataStmt != nullptr) {
1403         SQLiteUtils::ResetStatement(saveDataStmt, isNeedFinalize, errCode);
1404     }
1405     if (saveLogStmt != nullptr) {
1406         SQLiteUtils::ResetStatement(saveLogStmt, isNeedFinalize, errCode);
1407     }
1408     if (queryStmt != nullptr) {
1409         SQLiteUtils::ResetStatement(queryStmt, isNeedFinalize, errCode);
1410     }
1411     if (rmDataStmt != nullptr) {
1412         SQLiteUtils::ResetStatement(rmDataStmt, isNeedFinalize, errCode);
1413     }
1414     if (rmLogStmt != nullptr) {
1415         SQLiteUtils::ResetStatement(rmLogStmt, isNeedFinalize, errCode);
1416     }
1417     return errCode;
1418 }
1419 
GetMaxTimestamp(const std::vector<std::string> & tableNames,Timestamp & maxTimestamp) const1420 int SQLiteSingleVerRelationalStorageExecutor::GetMaxTimestamp(const std::vector<std::string> &tableNames,
1421     Timestamp &maxTimestamp) const
1422 {
1423     maxTimestamp = 0;
1424     for (const auto &tableName : tableNames) {
1425         const std::string sql = "SELECT max(timestamp) from " + DBConstant::RELATIONAL_PREFIX + tableName + "_log;";
1426         sqlite3_stmt *stmt = nullptr;
1427         int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, stmt);
1428         if (errCode != E_OK) {
1429             return errCode;
1430         }
1431         errCode = SQLiteUtils::StepWithRetry(stmt, isMemDb_);
1432         if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1433             maxTimestamp = std::max(maxTimestamp, static_cast<Timestamp>(sqlite3_column_int64(stmt, 0))); // 0 is index
1434             errCode = E_OK;
1435         }
1436         SQLiteUtils::ResetStatement(stmt, true, errCode);
1437         if (errCode != E_OK) {
1438             maxTimestamp = 0;
1439             return errCode;
1440         }
1441     }
1442     return E_OK;
1443 }
1444 
SetLogTriggerStatus(bool status)1445 int SQLiteSingleVerRelationalStorageExecutor::SetLogTriggerStatus(bool status)
1446 {
1447     const std::string key = "log_trigger_switch";
1448     std::string val = status ? "true" : "false";
1449     std::string sql = "INSERT OR REPLACE INTO " + DBConstant::RELATIONAL_PREFIX + "metadata" +
1450         " VALUES ('" + key + "', '" + val + "')";
1451     int errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, sql);
1452     if (errCode != E_OK) {
1453         LOGE("Set log trigger to %s failed. errCode=%d", val.c_str(), errCode);
1454     }
1455     return errCode;
1456 }
1457 
1458 namespace {
GetRowDatas(sqlite3_stmt * stmt,bool isMemDb,std::vector<std::string> & colNames,std::vector<RelationalRowData * > & data)1459 int GetRowDatas(sqlite3_stmt *stmt, bool isMemDb, std::vector<std::string> &colNames,
1460     std::vector<RelationalRowData *> &data)
1461 {
1462     size_t totalLength = 0;
1463     do {
1464         int errCode = SQLiteUtils::StepWithRetry(stmt, isMemDb);
1465         if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1466             return E_OK;
1467         } else if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1468             LOGE("Get data by bind sql failed:%d", errCode);
1469             return errCode;
1470         }
1471 
1472         if (colNames.empty()) {
1473             SQLiteUtils::GetSelectCols(stmt, colNames);  // Get column names.
1474         }
1475         auto relaRowData = new (std::nothrow) RelationalRowDataImpl(SQLiteRelationalUtils::GetSelectValues(stmt));
1476         if (relaRowData == nullptr) {
1477             LOGE("ExecuteQueryBySqlStmt OOM");
1478             return -E_OUT_OF_MEMORY;
1479         }
1480 
1481         auto dataSz = relaRowData->CalcLength();
1482         if (dataSz == 0) {  // invalid data
1483             delete relaRowData;
1484             relaRowData = nullptr;
1485             continue;
1486         }
1487 
1488         totalLength += static_cast<size_t>(dataSz);
1489         if (totalLength > static_cast<uint32_t>(DBConstant::MAX_REMOTEDATA_SIZE)) {  // the set has been full
1490             delete relaRowData;
1491             relaRowData = nullptr;
1492             LOGE("ExecuteQueryBySqlStmt OVERSIZE");
1493             return -E_REMOTE_OVER_SIZE;
1494         }
1495         data.push_back(relaRowData);
1496     } while (true);
1497     return E_OK;
1498 }
1499 }
1500 
1501 // sql must not be empty, colNames and data must be empty
ExecuteQueryBySqlStmt(const std::string & sql,const std::vector<std::string> & bindArgs,int packetSize,std::vector<std::string> & colNames,std::vector<RelationalRowData * > & data)1502 int SQLiteSingleVerRelationalStorageExecutor::ExecuteQueryBySqlStmt(const std::string &sql,
1503     const std::vector<std::string> &bindArgs, int packetSize, std::vector<std::string> &colNames,
1504     std::vector<RelationalRowData *> &data)
1505 {
1506     int errCode = SQLiteUtils::SetAuthorizer(dbHandle_, &PermitSelect);
1507     if (errCode != E_OK) {
1508         return errCode;
1509     }
1510 
1511     sqlite3_stmt *stmt = nullptr;
1512     errCode = SQLiteUtils::GetStatement(dbHandle_, sql, stmt);
1513     if (errCode != E_OK) {
1514         (void)SQLiteUtils::SetAuthorizer(dbHandle_, nullptr);
1515         return errCode;
1516     }
1517     ResFinalizer finalizer([this, &stmt, &errCode] {
1518         (void)SQLiteUtils::SetAuthorizer(this->dbHandle_, nullptr);
1519         SQLiteUtils::ResetStatement(stmt, true, errCode);
1520     });
1521     for (size_t i = 0; i < bindArgs.size(); ++i) {
1522         errCode = SQLiteUtils::BindTextToStatement(stmt, i + 1, bindArgs.at(i));
1523         if (errCode != E_OK) {
1524             return errCode;
1525         }
1526     }
1527     return GetRowDatas(stmt, isMemDb_, colNames, data);
1528 }
1529 
CheckEncryptedOrCorrupted() const1530 int SQLiteSingleVerRelationalStorageExecutor::CheckEncryptedOrCorrupted() const
1531 {
1532     if (dbHandle_ == nullptr) {
1533         return -E_INVALID_DB;
1534     }
1535 
1536     int errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, "SELECT count(*) FROM sqlite_master;");
1537     if (errCode != E_OK) {
1538         LOGE("[SingVerRelaExec] CheckEncryptedOrCorrupted failed:%d", errCode);
1539     }
1540     return errCode;
1541 }
1542 } // namespace DistributedDB
1543 #endif
1544