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 "cloud/cloud_db_constant.h"
22 #include "cloud/cloud_storage_utils.h"
23 #include "data_transformer.h"
24 #include "db_common.h"
25 #include "log_table_manager_factory.h"
26 #include "relational_row_data_impl.h"
27 #include "res_finalizer.h"
28 #include "runtime_context.h"
29 #include "sqlite_meta_executor.h"
30 #include "sqlite_relational_utils.h"
31 #include "time_helper.h"
32 #include "value_hash_calc.h"
33 
34 namespace DistributedDB {
35 namespace {
36 static constexpr const char *DATAKEY = "DATA_KEY";
37 static constexpr const char *DEVICE_FIELD = "DEVICE";
38 static constexpr const char *CLOUD_GID_FIELD = "CLOUD_GID";
39 static constexpr const char *VERSION = "VERSION";
40 static constexpr const char *SHARING_RESOURCE = "SHARING_RESOURCE";
41 static constexpr const char *FLAG_IS_CLOUD = "FLAG & 0x02 = 0"; // see if 1th bit of a flag is cloud
42 static constexpr const char *FLAG_IS_CLOUD_CONSISTENCY = "FLAG & 0x20 = 0"; // see if flag is cloud_consistency
43 // set 1th bit of flag to one which is local, clean 5th bit of flag to one which is wait compensated sync
44 static constexpr const char *SET_FLAG_LOCAL_AND_CLEAN_WAIT_COMPENSATED_SYNC = "(CASE WHEN data_key = -1 and "
45     "FLAG & 0x02 = 0x02 THEN FLAG & (~0x10) & (~0x20) ELSE (FLAG | 0x02 | 0x20) & (~0x10) END)";
46 // clean 5th bit of flag to one which is wait compensated sync
47 static constexpr const char *SET_FLAG_CLEAN_WAIT_COMPENSATED_SYNC = "(CASE WHEN data_key = -1 and "
48     "FLAG & 0x02 = 0x02 THEN FLAG & (~0x10) & (~0x20) ELSE (FLAG | 0x20) & (~0x10) END)";
49 static constexpr const char *FLAG_IS_LOGIC_DELETE = "FLAG & 0x08 != 0"; // see if 3th bit of a flag is logic delete
50 // set data logic delete, exist passport, delete, not compensated and cloud
51 static constexpr const char *SET_FLAG_LOGIC_DELETE = "(FLAG | 0x08 | 0x800 | 0x01) & (~0x12)";
52 static constexpr const char *DATA_IS_DELETE = "data_key = -1 AND FLAG & 0X08 = 0"; // see if data is delete
53 static constexpr const char *UPDATE_CURSOR_SQL = "cursor=update_cursor()";
54 static constexpr const int SET_FLAG_ZERO_MASK = ~0x04; // clear 2th bit of flag
55 static constexpr const int SET_FLAG_ONE_MASK = 0x04; // set 2th bit of flag
56 static constexpr const int SET_CLOUD_FLAG = ~0x02; // set 1th bit of flag to 0
57 static constexpr const int DATA_KEY_INDEX = 0;
58 static constexpr const int TIMESTAMP_INDEX = 3;
59 static constexpr const int W_TIMESTAMP_INDEX = 4;
60 static constexpr const int FLAG_INDEX = 5;
61 static constexpr const int HASH_KEY_INDEX = 6;
62 static constexpr const int CLOUD_GID_INDEX = 7;
63 static constexpr const int VERSION_INDEX = 8;
64 static constexpr const int STATUS_INDEX = 9;
65 
PermitSelect(void * a,int b,const char * c,const char * d,const char * e,const char * f)66 int PermitSelect(void *a, int b, const char *c, const char *d, const char *e, const char *f)
67 {
68     if (b != SQLITE_SELECT && b != SQLITE_READ && b != SQLITE_FUNCTION) {
69         return SQLITE_DENY;
70     }
71     if (b == SQLITE_FUNCTION) {
72         if (d != nullptr && (strcmp(d, "fts3_tokenizer") == 0)) {
73             LOGE("Deny fts3_tokenizer in remote query");
74             return SQLITE_DENY;
75         }
76     }
77     return SQLITE_OK;
78 }
79 }
SQLiteSingleVerRelationalStorageExecutor(sqlite3 * dbHandle,bool writable,DistributedTableMode mode)80 SQLiteSingleVerRelationalStorageExecutor::SQLiteSingleVerRelationalStorageExecutor(sqlite3 *dbHandle, bool writable,
81     DistributedTableMode mode)
82     : SQLiteStorageExecutor(dbHandle, writable, false), mode_(mode), isLogicDelete_(false),
83       assetLoader_(nullptr), putDataMode_(PutDataMode::SYNC), markFlagOption_(MarkFlagOption::DEFAULT),
84       maxUploadCount_(0), maxUploadSize_(0)
85 {
86     bindCloudFieldFuncMap_[TYPE_INDEX<int64_t>] = &CloudStorageUtils::BindInt64;
87     bindCloudFieldFuncMap_[TYPE_INDEX<bool>] = &CloudStorageUtils::BindBool;
88     bindCloudFieldFuncMap_[TYPE_INDEX<double>] = &CloudStorageUtils::BindDouble;
89     bindCloudFieldFuncMap_[TYPE_INDEX<std::string>] = &CloudStorageUtils::BindText;
90     bindCloudFieldFuncMap_[TYPE_INDEX<Bytes>] = &CloudStorageUtils::BindBlob;
91     bindCloudFieldFuncMap_[TYPE_INDEX<Asset>] = &CloudStorageUtils::BindAsset;
92     bindCloudFieldFuncMap_[TYPE_INDEX<Assets>] = &CloudStorageUtils::BindAsset;
93 }
94 
CheckTableConstraint(const TableInfo & table,DistributedTableMode mode,TableSyncType syncType)95 int CheckTableConstraint(const TableInfo &table, DistributedTableMode mode, TableSyncType syncType)
96 {
97     std::string trimedSql = DBCommon::TrimSpace(table.GetCreateTableSql());
98     if (DBCommon::HasConstraint(trimedSql, "WITHOUT ROWID", " ),", " ,;")) {
99         LOGE("[CreateDistributedTable] Not support create distributed table without rowid.");
100         return -E_NOT_SUPPORT;
101     }
102     std::vector<FieldInfo> fieldInfos = table.GetFieldInfos();
103     for (const auto &field : fieldInfos) {
104         if (DBCommon::CaseInsensitiveCompare(field.GetFieldName(), std::string(DBConstant::SQLITE_INNER_ROWID))) {
105             LOGE("[CreateDistributedTable] Not support create distributed table with _rowid_ column.");
106             return -E_NOT_SUPPORT;
107         }
108     }
109 
110     if (mode == DistributedTableMode::COLLABORATION || syncType == CLOUD_COOPERATION) {
111         if (DBCommon::HasConstraint(trimedSql, "CHECK", " ,", " (")) {
112             LOGE("[CreateDistributedTable] Not support create distributed table with 'CHECK' constraint.");
113             return -E_NOT_SUPPORT;
114         }
115 
116         if (DBCommon::HasConstraint(trimedSql, "ON CONFLICT", " )", " ")) {
117             LOGE("[CreateDistributedTable] Not support create distributed table with 'ON CONFLICT' constraint.");
118             return -E_NOT_SUPPORT;
119         }
120 
121         if (mode == DistributedTableMode::COLLABORATION) {
122             if (DBCommon::HasConstraint(trimedSql, "REFERENCES", " )", " ")) {
123                 LOGE("[CreateDistributedTable] Not support create distributed table with 'FOREIGN KEY' constraint.");
124                 return -E_NOT_SUPPORT;
125             }
126         }
127 
128         if (syncType == CLOUD_COOPERATION) {
129             int errCode = CloudStorageUtils::ConstraintsCheckForCloud(table, trimedSql);
130             if (errCode != E_OK) {
131                 LOGE("ConstraintsCheckForCloud failed, errCode = %d", errCode);
132                 return errCode;
133             }
134         }
135     }
136 
137     if (mode == DistributedTableMode::SPLIT_BY_DEVICE && syncType == DEVICE_COOPERATION) {
138         if (table.GetPrimaryKey().size() > 1) {
139             LOGE("[CreateDistributedTable] Not support create distributed table with composite primary keys.");
140             return -E_NOT_SUPPORT;
141         }
142     }
143 
144     return E_OK;
145 }
146 
147 namespace {
GetExistedDataTimeOffset(sqlite3 * db,const std::string & tableName,bool isMem,int64_t & timeOffset)148 int GetExistedDataTimeOffset(sqlite3 *db, const std::string &tableName, bool isMem, int64_t &timeOffset)
149 {
150     std::string sql = "SELECT get_sys_time(0) - max(" + std::string(DBConstant::SQLITE_INNER_ROWID) + ") - 1 FROM '" +
151         tableName + "';";
152     sqlite3_stmt *stmt = nullptr;
153     int errCode = SQLiteUtils::GetStatement(db, sql, stmt);
154     if (errCode != E_OK) {
155         return errCode;
156     }
157     errCode = SQLiteUtils::StepWithRetry(stmt, isMem);
158     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
159         timeOffset = static_cast<int64_t>(sqlite3_column_int64(stmt, 0));
160         errCode = E_OK;
161     }
162     SQLiteUtils::ResetStatement(stmt, true, errCode);
163     return errCode;
164 }
165 }
166 
GeneLogInfoForExistedData(sqlite3 * db,const std::string & tableName,const std::string & calPrimaryKeyHash,TableInfo & tableInfo)167 int SQLiteSingleVerRelationalStorageExecutor::GeneLogInfoForExistedData(sqlite3 *db, const std::string &tableName,
168     const std::string &calPrimaryKeyHash, TableInfo &tableInfo)
169 {
170     int64_t timeOffset = 0;
171     int errCode = GetExistedDataTimeOffset(db, tableName, isMemDb_, timeOffset);
172     if (errCode != E_OK) {
173         return errCode;
174     }
175     errCode = SetLogTriggerStatus(false);
176     if (errCode != E_OK) {
177         return errCode;
178     }
179     std::string timeOffsetStr = std::to_string(timeOffset);
180     std::string logTable = DBConstant::RELATIONAL_PREFIX + tableName + "_log";
181     std::string rowid = std::string(DBConstant::SQLITE_INNER_ROWID);
182     std::string flag = std::to_string(static_cast<uint32_t>(LogInfoFlag::FLAG_LOCAL) |
183         static_cast<uint32_t>(LogInfoFlag::FLAG_DEVICE_CLOUD_INCONSISTENCY));
184     if (tableInfo.GetTableSyncType() == TableSyncType::DEVICE_COOPERATION) {
185         std::string sql = "INSERT OR REPLACE INTO " + logTable + " SELECT " + rowid + ", '', '', " + timeOffsetStr +
186             " + " + rowid + ", " + timeOffsetStr + " + " + rowid + ", " + flag + ", " + calPrimaryKeyHash + ", '', " +
187             "'', '', '', '', 0 FROM '" + tableName + "' AS a WHERE 1=1;";
188         errCode = SQLiteUtils::ExecuteRawSQL(db, sql);
189         if (errCode != E_OK) {
190             LOGE("Failed to initialize device type log data.%d", errCode);
191         }
192         return errCode;
193     }
194     TrackerTable trackerTable = tableInfo.GetTrackerTable();
195     trackerTable.SetTableName(tableName);
196     std::string sql = "INSERT OR REPLACE INTO " + logTable + " SELECT " + rowid +
197         ", '', '', " + timeOffsetStr + " + " + rowid + ", " +
198         timeOffsetStr + " + " + rowid + ", " + flag + ", " + calPrimaryKeyHash + ", '', ";
199     sql += tableInfo.GetTrackerTable().GetExtendName().empty() ? "''" : tableInfo.GetTrackerTable().GetExtendName();
200     sql += ", 0, '', '', 0 FROM '" + tableName + "' AS a WHERE 1=1;";
201     errCode = trackerTable.ReBuildTempTrigger(db, TriggerMode::TriggerModeEnum::INSERT, [db, &sql]() {
202         int ret = SQLiteUtils::ExecuteRawSQL(db, sql);
203         if (ret != E_OK) {
204             LOGE("Failed to initialize cloud type log data.%d", ret);
205         }
206         return ret;
207     });
208     return errCode;
209 }
210 
CreateDistributedTable(DistributedTableMode mode,bool isUpgraded,const std::string & identity,TableInfo & table,TableSyncType syncType)211 int SQLiteSingleVerRelationalStorageExecutor::CreateDistributedTable(DistributedTableMode mode, bool isUpgraded,
212     const std::string &identity, TableInfo &table, TableSyncType syncType)
213 {
214     if (dbHandle_ == nullptr) {
215         return -E_INVALID_DB;
216     }
217 
218     const std::string tableName = table.GetTableName();
219     int errCode = SQLiteUtils::AnalysisSchema(dbHandle_, tableName, table);
220     if (errCode != E_OK) {
221         LOGE("[CreateDistributedTable] analysis table schema failed. %d", errCode);
222         return errCode;
223     }
224 
225     if (mode == DistributedTableMode::SPLIT_BY_DEVICE && !isUpgraded) {
226         bool isEmpty = false;
227         errCode = SQLiteUtils::CheckTableEmpty(dbHandle_, tableName, isEmpty);
228         if (errCode != E_OK) {
229             LOGE("[CreateDistributedTable] check table empty failed. error=%d", errCode);
230             return -E_NOT_SUPPORT;
231         }
232         if (!isEmpty) {
233             LOGW("[CreateDistributedTable] generate %.3s log for existed data, table type %d",
234                 DBCommon::TransferStringToHex(DBCommon::TransferHashString(tableName)).c_str(),
235                 static_cast<int>(syncType));
236         }
237     }
238 
239     errCode = CheckTableConstraint(table, mode, syncType);
240     if (errCode != E_OK) {
241         LOGE("[CreateDistributedTable] check table constraint failed.");
242         return errCode;
243     }
244 
245     // create log table
246     auto tableManager = LogTableManagerFactory::GetTableManager(mode, syncType);
247     errCode = tableManager->CreateRelationalLogTable(dbHandle_, table);
248     if (errCode != E_OK) {
249         LOGE("[CreateDistributedTable] create log table failed");
250         return errCode;
251     }
252 
253     if (!isUpgraded) {
254         std::string calPrimaryKeyHash = tableManager->CalcPrimaryKeyHash("a.", table, identity);
255         errCode = GeneLogInfoForExistedData(dbHandle_, tableName, calPrimaryKeyHash, table);
256         if (errCode != E_OK) {
257             return errCode;
258         }
259     }
260 
261     // add trigger
262     errCode = tableManager->AddRelationalLogTableTrigger(dbHandle_, table, identity);
263     if (errCode != E_OK) {
264         LOGE("[CreateDistributedTable] Add relational log table trigger failed.");
265         return errCode;
266     }
267     return SetLogTriggerStatus(true);
268 }
269 
CompareSchemaTableColumns(const std::string & tableName)270 int SQLiteSingleVerRelationalStorageExecutor::CompareSchemaTableColumns(const std::string &tableName)
271 {
272     bool onceDropped = false;
273     int errCode = IsTableOnceDropped(tableName, onceDropped);
274     if (!onceDropped) {
275         // do not return error code to make sure main procedure will continue
276         return E_OK;
277     }
278     LOGI("[CompareSchemaTableColumns] table once dropped check schema. table name is %s length is %zu",
279         DBCommon::StringMiddleMasking(tableName).c_str(), tableName.size());
280     TableInfo newTableInfo;
281     errCode = SQLiteUtils::AnalysisSchema(dbHandle_, tableName, newTableInfo);
282     if (errCode != E_OK) {
283         LOGE("[CompareSchemaTableColumns] analysis table schema failed. %d", errCode);
284         return errCode;
285     }
286     // new table should has same or compatible upgrade
287     TableInfo tableInfo = localSchema_.GetTable(tableName);
288     errCode = tableInfo.CompareWithTable(newTableInfo, localSchema_.GetSchemaVersion());
289     if (errCode == -E_RELATIONAL_TABLE_INCOMPATIBLE) {
290         LOGE("[CompareSchemaTableColumns] Not support with incompatible table.");
291         return -E_SCHEMA_MISMATCH;
292     }
293     return errCode;
294 }
295 
UpgradeDistributedTable(const std::string & tableName,DistributedTableMode mode,bool & schemaChanged,RelationalSchemaObject & schema,TableSyncType syncType)296 int SQLiteSingleVerRelationalStorageExecutor::UpgradeDistributedTable(const std::string &tableName,
297     DistributedTableMode mode, bool &schemaChanged, RelationalSchemaObject &schema, TableSyncType syncType)
298 {
299     if (dbHandle_ == nullptr) {
300         return -E_INVALID_DB;
301     }
302     TableInfo newTableInfo;
303     int errCode = SQLiteUtils::AnalysisSchema(dbHandle_, tableName, newTableInfo);
304     if (errCode != E_OK) {
305         LOGE("[UpgradeDistributedTable] analysis table schema failed. %d", errCode);
306         return errCode;
307     }
308 
309     if (CheckTableConstraint(newTableInfo, mode, syncType)) {
310         LOGE("[UpgradeDistributedTable] Not support create distributed table when violate constraints.");
311         return -E_NOT_SUPPORT;
312     }
313 
314     // new table should has same or compatible upgrade
315     TableInfo tableInfo = schema.GetTable(tableName);
316     errCode = tableInfo.CompareWithTable(newTableInfo, schema.GetSchemaVersion());
317     if (errCode == -E_RELATIONAL_TABLE_INCOMPATIBLE) {
318         LOGE("[UpgradeDistributedTable] Not support with incompatible upgrade.");
319         return -E_SCHEMA_MISMATCH;
320     } else if (errCode == -E_RELATIONAL_TABLE_EQUAL) {
321         LOGD("[UpgradeDistributedTable] schema has not changed.");
322         // update table if tableName changed
323         schema.RemoveRelationalTable(tableName);
324         tableInfo.SetTableName(tableName);
325         schema.AddRelationalTable(tableInfo);
326         return E_OK;
327     }
328 
329     schemaChanged = true;
330     errCode = AlterAuxTableForUpgrade(tableInfo, newTableInfo);
331     if (errCode != E_OK) {
332         LOGE("[UpgradeDistributedTable] Alter aux table for upgrade failed. %d", errCode);
333     }
334 
335     schema.AddRelationalTable(newTableInfo);
336     return errCode;
337 }
338 
339 namespace {
GetDeviceTableName(sqlite3 * handle,const std::string & tableName,const std::string & device,std::vector<std::string> & deviceTables)340 int GetDeviceTableName(sqlite3 *handle, const std::string &tableName, const std::string &device,
341     std::vector<std::string> &deviceTables)
342 {
343     if (device.empty() && tableName.empty()) { // device and table name should not both be empty
344         return -E_INVALID_ARGS;
345     }
346     std::string devicePattern = device.empty() ? "%" : device;
347     std::string tablePattern = tableName.empty() ? "%" : tableName;
348     std::string deviceTableName = DBConstant::RELATIONAL_PREFIX + tablePattern + "_" + devicePattern;
349 
350     const std::string checkSql = "SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '" +
351         deviceTableName + "';";
352     sqlite3_stmt *stmt = nullptr;
353     int errCode = SQLiteUtils::GetStatement(handle, checkSql, stmt);
354     if (errCode != E_OK) {
355         return errCode;
356     }
357 
358     do {
359         errCode = SQLiteUtils::StepWithRetry(stmt, false);
360         if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
361             errCode = E_OK;
362             break;
363         } else if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
364             LOGE("Get table name failed. %d", errCode);
365             break;
366         }
367         std::string realTableName;
368         errCode = SQLiteUtils::GetColumnTextValue(stmt, 0, realTableName); // 0: table name result column index
369         if (errCode != E_OK || realTableName.empty()) { // sqlite might return a row with NULL
370             continue;
371         }
372         if (realTableName.rfind("_log") == (realTableName.length() - 4)) { // 4:suffix length of "_log"
373             continue;
374         }
375         deviceTables.emplace_back(realTableName);
376     } while (true);
377 
378     SQLiteUtils::ResetStatement(stmt, true, errCode);
379     return errCode;
380 }
381 
GetUpgradeFields(const TableInfo & oldTableInfo,const TableInfo & newTableInfo)382 std::vector<FieldInfo> GetUpgradeFields(const TableInfo &oldTableInfo, const TableInfo &newTableInfo)
383 {
384     std::vector<FieldInfo> fields;
385     auto itOld = oldTableInfo.GetFields().begin();
386     auto itNew = newTableInfo.GetFields().begin();
387     for (; itNew != newTableInfo.GetFields().end(); itNew++) {
388         if (itOld == oldTableInfo.GetFields().end() || itOld->first != itNew->first) {
389             fields.emplace_back(itNew->second);
390             continue;
391         }
392         itOld++;
393     }
394     return fields;
395 }
396 
UpgradeFields(sqlite3 * db,const std::vector<std::string> & tables,std::vector<FieldInfo> & fields)397 int UpgradeFields(sqlite3 *db, const std::vector<std::string> &tables, std::vector<FieldInfo> &fields)
398 {
399     if (db == nullptr) {
400         return -E_INVALID_ARGS;
401     }
402 
403     std::sort(fields.begin(), fields.end(), [] (const FieldInfo &a, const FieldInfo &b) {
404         return a.GetColumnId()< b.GetColumnId();
405     });
406     int errCode = E_OK;
407     for (const auto &table : tables) {
408         for (const auto &field : fields) {
409             std::string alterSql = "ALTER TABLE " + table + " ADD '" + field.GetFieldName() + "' ";
410             alterSql += "'" + field.GetDataType() + "'";
411             alterSql += field.IsNotNull() ? " NOT NULL" : "";
412             alterSql += field.HasDefaultValue() ? " DEFAULT " + field.GetDefaultValue() : "";
413             alterSql += ";";
414             errCode = SQLiteUtils::ExecuteRawSQL(db, alterSql);
415             if (errCode != E_OK) {
416                 LOGE("Alter table failed. %d", errCode);
417                 break;
418             }
419         }
420     }
421     return errCode;
422 }
423 
GetChangedIndexes(const TableInfo & oldTableInfo,const TableInfo & newTableInfo)424 IndexInfoMap GetChangedIndexes(const TableInfo &oldTableInfo, const TableInfo &newTableInfo)
425 {
426     IndexInfoMap indexes;
427     auto itOld = oldTableInfo.GetIndexDefine().begin();
428     auto itNew = newTableInfo.GetIndexDefine().begin();
429     auto itOldEnd = oldTableInfo.GetIndexDefine().end();
430     auto itNewEnd = newTableInfo.GetIndexDefine().end();
431 
432     while (itOld != itOldEnd && itNew != itNewEnd) {
433         if (itOld->first == itNew->first) {
434             if (itOld->second != itNew->second) {
435                 indexes.insert({itNew->first, itNew->second});
436             }
437             itOld++;
438             itNew++;
439         } else if (itOld->first < itNew->first) {
440             indexes.insert({itOld->first, {}});
441             itOld++;
442         } else {
443             indexes.insert({itNew->first, itNew->second});
444             itNew++;
445         }
446     }
447 
448     while (itOld != itOldEnd) {
449         indexes.insert({itOld->first, {}});
450         itOld++;
451     }
452 
453     while (itNew != itNewEnd) {
454         indexes.insert({itNew->first, itNew->second});
455         itNew++;
456     }
457 
458     return indexes;
459 }
460 
UpgradeIndexes(sqlite3 * db,const std::vector<std::string> & tables,const IndexInfoMap & indexes)461 int UpgradeIndexes(sqlite3 *db, const std::vector<std::string> &tables, const IndexInfoMap &indexes)
462 {
463     if (db == nullptr) {
464         return -E_INVALID_ARGS;
465     }
466 
467     int errCode = E_OK;
468     for (const auto &table : tables) {
469         for (const auto &index : indexes) {
470             if (index.first.empty()) {
471                 continue;
472             }
473             std::string realIndexName = table + "_" + index.first;
474             std::string deleteIndexSql = "DROP INDEX IF EXISTS " + realIndexName;
475             errCode = SQLiteUtils::ExecuteRawSQL(db, deleteIndexSql);
476             if (errCode != E_OK) {
477                 LOGE("Drop index failed. %d", errCode);
478                 return errCode;
479             }
480 
481             if (index.second.empty()) { // empty means drop index only
482                 continue;
483             }
484 
485             auto it = index.second.begin();
486             std::string indexDefine = *it++;
487             while (it != index.second.end()) {
488                 indexDefine += ", " + *it++;
489             }
490             std::string createIndexSql = "CREATE INDEX IF NOT EXISTS " + realIndexName + " ON " + table +
491                 "(" + indexDefine + ");";
492             errCode = SQLiteUtils::ExecuteRawSQL(db, createIndexSql);
493             if (errCode != E_OK) {
494                 LOGE("Create index failed. %d", errCode);
495                 break;
496             }
497         }
498     }
499     return errCode;
500 }
501 }
502 
AlterAuxTableForUpgrade(const TableInfo & oldTableInfo,const TableInfo & newTableInfo)503 int SQLiteSingleVerRelationalStorageExecutor::AlterAuxTableForUpgrade(const TableInfo &oldTableInfo,
504     const TableInfo &newTableInfo)
505 {
506     std::vector<FieldInfo> upgradeFields = GetUpgradeFields(oldTableInfo, newTableInfo);
507     IndexInfoMap upgradeIndexes = GetChangedIndexes(oldTableInfo, newTableInfo);
508     std::vector<std::string> deviceTables;
509     int errCode = GetDeviceTableName(dbHandle_, oldTableInfo.GetTableName(), {}, deviceTables);
510     if (errCode != E_OK) {
511         LOGE("Get device table name for alter table failed. %d", errCode);
512         return errCode;
513     }
514 
515     LOGD("Begin to alter table: upgrade fields[%zu], indexes[%zu], deviceTable[%zu]", upgradeFields.size(),
516         upgradeIndexes.size(), deviceTables.size());
517     errCode = UpgradeFields(dbHandle_, deviceTables, upgradeFields);
518     if (errCode != E_OK) {
519         LOGE("upgrade fields failed. %d", errCode);
520         return errCode;
521     }
522 
523     errCode = UpgradeIndexes(dbHandle_, deviceTables, upgradeIndexes);
524     if (errCode != E_OK) {
525         LOGE("upgrade indexes failed. %d", errCode);
526     }
527 
528     return errCode;
529 }
530 
StartTransaction(TransactType type)531 int SQLiteSingleVerRelationalStorageExecutor::StartTransaction(TransactType type)
532 {
533     if (dbHandle_ == nullptr) {
534         LOGE("Begin transaction failed, dbHandle is null.");
535         return -E_INVALID_DB;
536     }
537     int errCode = SQLiteUtils::BeginTransaction(dbHandle_, type);
538     if (errCode != E_OK) {
539         LOGE("Begin transaction failed, errCode = %d", errCode);
540     }
541     return errCode;
542 }
543 
Commit()544 int SQLiteSingleVerRelationalStorageExecutor::Commit()
545 {
546     if (dbHandle_ == nullptr) {
547         return -E_INVALID_DB;
548     }
549 
550     return SQLiteUtils::CommitTransaction(dbHandle_);
551 }
552 
Rollback()553 int SQLiteSingleVerRelationalStorageExecutor::Rollback()
554 {
555     if (dbHandle_ == nullptr) {
556         return -E_INVALID_DB;
557     }
558     int errCode = SQLiteUtils::RollbackTransaction(dbHandle_);
559     if (errCode != E_OK) {
560         LOGE("sqlite single ver storage executor rollback fail! errCode = [%d]", errCode);
561     }
562     return errCode;
563 }
564 
SetTableInfo(const TableInfo & tableInfo)565 void SQLiteSingleVerRelationalStorageExecutor::SetTableInfo(const TableInfo &tableInfo)
566 {
567     table_ = tableInfo;
568 }
569 
GetLogData(sqlite3_stmt * logStatement,LogInfo & logInfo)570 static int GetLogData(sqlite3_stmt *logStatement, LogInfo &logInfo)
571 {
572     logInfo.dataKey = sqlite3_column_int64(logStatement, 0);  // 0 means dataKey index
573 
574     std::vector<uint8_t> dev;
575     int errCode = SQLiteUtils::GetColumnBlobValue(logStatement, 1, dev);  // 1 means dev index
576     if (errCode != E_OK) {
577         return errCode;
578     }
579     logInfo.device = std::string(dev.begin(), dev.end());
580 
581     std::vector<uint8_t> oriDev;
582     errCode = SQLiteUtils::GetColumnBlobValue(logStatement, 2, oriDev);  // 2 means ori_dev index
583     if (errCode != E_OK) {
584         return errCode;
585     }
586     logInfo.originDev = std::string(oriDev.begin(), oriDev.end());
587     logInfo.timestamp = static_cast<uint64_t>(sqlite3_column_int64(logStatement, 3));  // 3 means timestamp index
588     logInfo.wTimestamp = static_cast<uint64_t>(sqlite3_column_int64(logStatement, 4));  // 4 means w_timestamp index
589     logInfo.flag = static_cast<uint64_t>(sqlite3_column_int64(logStatement, 5));  // 5 means flag index
590     logInfo.flag &= (~DataItem::LOCAL_FLAG);
591     logInfo.flag &= (~DataItem::UPDATE_FLAG);
592     return SQLiteUtils::GetColumnBlobValue(logStatement, 6, logInfo.hashKey);  // 6 means hashKey index
593 }
594 
595 namespace {
GetCloudLog(sqlite3_stmt * logStatement,VBucket & logInfo,uint32_t & totalSize)596 void GetCloudLog(sqlite3_stmt *logStatement, VBucket &logInfo, uint32_t &totalSize)
597 {
598     int64_t modifyTime = static_cast<int64_t>(sqlite3_column_int64(logStatement, TIMESTAMP_INDEX));
599     uint64_t curTime = 0;
600     if (TimeHelper::GetSysCurrentRawTime(curTime) == E_OK) {
601         if (modifyTime > static_cast<int64_t>(curTime)) {
602             modifyTime = static_cast<int64_t>(curTime);
603         }
604     } else {
605         LOGW("[Relational] get raw sys time failed.");
606     }
607     logInfo.insert_or_assign(CloudDbConstant::MODIFY_FIELD, modifyTime);
608     logInfo.insert_or_assign(CloudDbConstant::CREATE_FIELD,
609         static_cast<int64_t>(sqlite3_column_int64(logStatement, W_TIMESTAMP_INDEX)));
610     totalSize += sizeof(int64_t) + sizeof(int64_t);
611     if (sqlite3_column_text(logStatement, CLOUD_GID_INDEX) != nullptr) {
612         std::string cloudGid = reinterpret_cast<const std::string::value_type *>(
613             sqlite3_column_text(logStatement, CLOUD_GID_INDEX));
614         if (!cloudGid.empty()) {
615             logInfo.insert_or_assign(CloudDbConstant::GID_FIELD, cloudGid);
616             totalSize += cloudGid.size();
617         }
618     }
619     std::string version;
620     SQLiteUtils::GetColumnTextValue(logStatement, VERSION_INDEX, version);
621     logInfo.insert_or_assign(CloudDbConstant::VERSION_FIELD, version);
622     totalSize += version.size();
623 }
624 
GetCloudExtraLog(sqlite3_stmt * logStatement,VBucket & flags)625 void GetCloudExtraLog(sqlite3_stmt *logStatement, VBucket &flags)
626 {
627     flags.insert_or_assign(CloudDbConstant::ROWID,
628         static_cast<int64_t>(sqlite3_column_int64(logStatement, DATA_KEY_INDEX)));
629     flags.insert_or_assign(CloudDbConstant::TIMESTAMP,
630         static_cast<int64_t>(sqlite3_column_int64(logStatement, TIMESTAMP_INDEX)));
631     flags.insert_or_assign(CloudDbConstant::FLAG,
632         static_cast<int64_t>(sqlite3_column_int64(logStatement, FLAG_INDEX)));
633     Bytes hashKey;
634     (void)SQLiteUtils::GetColumnBlobValue(logStatement, HASH_KEY_INDEX, hashKey);
635     flags.insert_or_assign(CloudDbConstant::HASH_KEY, hashKey);
636     flags.insert_or_assign(CloudDbConstant::STATUS,
637         static_cast<int64_t>(sqlite3_column_int(logStatement, STATUS_INDEX)));
638 }
639 
GetCloudGid(sqlite3_stmt * logStatement,std::vector<std::string> & cloudGid)640 void GetCloudGid(sqlite3_stmt *logStatement, std::vector<std::string> &cloudGid)
641 {
642     if (sqlite3_column_text(logStatement, CLOUD_GID_INDEX) == nullptr) {
643         return;
644     }
645     std::string gid = reinterpret_cast<const std::string::value_type *>(
646         sqlite3_column_text(logStatement, CLOUD_GID_INDEX));
647     if (gid.empty()) {
648         LOGW("[Relational] Get cloud gid is null.");
649         return;
650     }
651     cloudGid.emplace_back(gid);
652 }
653 }
654 
GetDataItemSerialSize(DataItem & item,size_t appendLen)655 static size_t GetDataItemSerialSize(DataItem &item, size_t appendLen)
656 {
657     // timestamp and local flag: 3 * uint64_t, version(uint32_t), key, value, origin dev and the padding size.
658     // the size would not be very large.
659     static const size_t maxOrigDevLength = 40;
660     size_t devLength = std::max(maxOrigDevLength, item.origDev.size());
661     size_t dataSize = (Parcel::GetUInt64Len() * 3 + Parcel::GetUInt32Len() + Parcel::GetVectorCharLen(item.key) +
662         Parcel::GetVectorCharLen(item.value) + devLength + appendLen);
663     return dataSize;
664 }
665 
GetKvData(const Key & key,Value & value) const666 int SQLiteSingleVerRelationalStorageExecutor::GetKvData(const Key &key, Value &value) const
667 {
668     static const std::string SELECT_META_VALUE_SQL = "SELECT value FROM " + DBConstant::RELATIONAL_PREFIX +
669         "metadata WHERE key=?;";
670     sqlite3_stmt *statement = nullptr;
671     int errCode = SQLiteUtils::GetStatement(dbHandle_, SELECT_META_VALUE_SQL, statement);
672     if (errCode != E_OK) {
673         goto END;
674     }
675 
676     errCode = SQLiteUtils::BindBlobToStatement(statement, 1, key, false); // first arg.
677     if (errCode != E_OK) {
678         goto END;
679     }
680 
681     errCode = SQLiteUtils::StepWithRetry(statement, isMemDb_);
682     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
683         errCode = -E_NOT_FOUND;
684         goto END;
685     } else if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
686         goto END;
687     }
688 
689     errCode = SQLiteUtils::GetColumnBlobValue(statement, 0, value); // only one result.
690     END:
691     SQLiteUtils::ResetStatement(statement, true, errCode);
692     return errCode;
693 }
694 
PutKvData(const Key & key,const Value & value) const695 int SQLiteSingleVerRelationalStorageExecutor::PutKvData(const Key &key, const Value &value) const
696 {
697     static const std::string INSERT_META_SQL = "INSERT OR REPLACE INTO " + DBConstant::RELATIONAL_PREFIX +
698         "metadata VALUES(?,?);";
699     sqlite3_stmt *statement = nullptr;
700     int errCode = SQLiteUtils::GetStatement(dbHandle_, INSERT_META_SQL, statement);
701     if (errCode != E_OK) {
702         return errCode;
703     }
704 
705     errCode = SQLiteUtils::BindBlobToStatement(statement, 1, key, false);  // 1 means key index
706     if (errCode != E_OK) {
707         LOGE("[SingleVerExe][BindPutKv]Bind key error:%d", errCode);
708         goto ERROR;
709     }
710 
711     errCode = SQLiteUtils::BindBlobToStatement(statement, 2, value, true);  // 2 means value index
712     if (errCode != E_OK) {
713         LOGE("[SingleVerExe][BindPutKv]Bind value error:%d", errCode);
714         goto ERROR;
715     }
716     errCode = SQLiteUtils::StepWithRetry(statement, isMemDb_);
717     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
718         errCode = E_OK;
719     }
720 ERROR:
721     SQLiteUtils::ResetStatement(statement, true, errCode);
722     return errCode;
723 }
724 
DeleteMetaData(const std::vector<Key> & keys) const725 int SQLiteSingleVerRelationalStorageExecutor::DeleteMetaData(const std::vector<Key> &keys) const
726 {
727     static const std::string REMOVE_META_VALUE_SQL = "DELETE FROM " + DBConstant::RELATIONAL_PREFIX +
728         "metadata WHERE key=?;";
729     sqlite3_stmt *statement = nullptr;
730     int errCode = SQLiteUtils::GetStatement(dbHandle_, REMOVE_META_VALUE_SQL, statement);
731     if (errCode != E_OK) {
732         return errCode;
733     }
734 
735     for (const auto &key : keys) {
736         errCode = SQLiteUtils::BindBlobToStatement(statement, 1, key, false); // first arg.
737         if (errCode != E_OK) {
738             break;
739         }
740 
741         errCode = SQLiteUtils::StepWithRetry(statement, isMemDb_);
742         if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
743             break;
744         }
745         errCode = E_OK;
746         SQLiteUtils::ResetStatement(statement, false, errCode);
747     }
748     SQLiteUtils::ResetStatement(statement, true, errCode);
749     return CheckCorruptedStatus(errCode);
750 }
751 
DeleteMetaDataByPrefixKey(const Key & keyPrefix) const752 int SQLiteSingleVerRelationalStorageExecutor::DeleteMetaDataByPrefixKey(const Key &keyPrefix) const
753 {
754     static const std::string REMOVE_META_VALUE_BY_KEY_PREFIX_SQL = "DELETE FROM " + DBConstant::RELATIONAL_PREFIX +
755         "metadata WHERE key>=? AND key<=?;";
756     sqlite3_stmt *statement = nullptr;
757     int errCode = SQLiteUtils::GetStatement(dbHandle_, REMOVE_META_VALUE_BY_KEY_PREFIX_SQL, statement);
758     if (errCode != E_OK) {
759         return errCode;
760     }
761 
762     errCode = SQLiteUtils::BindPrefixKey(statement, 1, keyPrefix); // 1 is first arg.
763     if (errCode == E_OK) {
764         errCode = SQLiteUtils::StepWithRetry(statement, isMemDb_);
765         if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
766             errCode = E_OK;
767         }
768     }
769     SQLiteUtils::ResetStatement(statement, true, errCode);
770     return CheckCorruptedStatus(errCode);
771 }
772 
GetAllMetaKeys(std::vector<Key> & keys) const773 int SQLiteSingleVerRelationalStorageExecutor::GetAllMetaKeys(std::vector<Key> &keys) const
774 {
775     static const std::string SELECT_ALL_META_KEYS = "SELECT key FROM " + DBConstant::RELATIONAL_PREFIX + "metadata;";
776     sqlite3_stmt *statement = nullptr;
777     int errCode = SQLiteUtils::GetStatement(dbHandle_, SELECT_ALL_META_KEYS, statement);
778     if (errCode != E_OK) {
779         LOGE("[Relational][GetAllKey] Get statement failed:%d", errCode);
780         return errCode;
781     }
782     errCode = SqliteMetaExecutor::GetAllKeys(statement, isMemDb_, keys);
783     SQLiteUtils::ResetStatement(statement, true, errCode);
784     return errCode;
785 }
786 
GetLogInfoPre(sqlite3_stmt * queryStmt,const DataItem & dataItem,LogInfo & logInfoGet)787 int SQLiteSingleVerRelationalStorageExecutor::GetLogInfoPre(sqlite3_stmt *queryStmt, const DataItem &dataItem,
788     LogInfo &logInfoGet)
789 {
790     if (queryStmt == nullptr) {
791         return -E_INVALID_ARGS;
792     }
793     int errCode = SQLiteUtils::BindBlobToStatement(queryStmt, 1, dataItem.hashKey);  // 1 means hashkey index.
794     if (errCode != E_OK) {
795         return errCode;
796     }
797     if (mode_ != DistributedTableMode::COLLABORATION) {
798         errCode = SQLiteUtils::BindTextToStatement(queryStmt, 2, dataItem.dev);  // 2 means device index.
799         if (errCode != E_OK) {
800             return errCode;
801         }
802     }
803 
804     errCode = SQLiteUtils::StepWithRetry(queryStmt, isMemDb_);
805     if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
806         errCode = -E_NOT_FOUND;
807     } else {
808         errCode = GetLogData(queryStmt, logInfoGet);
809     }
810     return errCode;
811 }
812 
SaveSyncLog(sqlite3_stmt * statement,sqlite3_stmt * queryStmt,const DataItem & dataItem,int64_t rowid)813 int SQLiteSingleVerRelationalStorageExecutor::SaveSyncLog(sqlite3_stmt *statement, sqlite3_stmt *queryStmt,
814     const DataItem &dataItem, int64_t rowid)
815 {
816     LogInfo logInfoGet;
817     int errCode = GetLogInfoPre(queryStmt, dataItem, logInfoGet);
818     LogInfo logInfoBind;
819     logInfoBind.hashKey = dataItem.hashKey;
820     logInfoBind.device = dataItem.dev;
821     logInfoBind.timestamp = dataItem.timestamp;
822     logInfoBind.flag = dataItem.flag;
823 
824     if (errCode == -E_NOT_FOUND) { // insert
825         logInfoBind.wTimestamp = dataItem.writeTimestamp;
826         logInfoBind.originDev = dataItem.dev;
827     } else if (errCode == E_OK) { // update
828         logInfoBind.wTimestamp = logInfoGet.wTimestamp;
829         logInfoBind.originDev = logInfoGet.originDev;
830     } else {
831         return errCode;
832     }
833 
834     // bind
835     SQLiteUtils::BindInt64ToStatement(statement, 1, rowid);  // 1 means dataKey index
836     std::vector<uint8_t> originDev(logInfoBind.originDev.begin(), logInfoBind.originDev.end());
837     SQLiteUtils::BindBlobToStatement(statement, 2, originDev);  // 2 means ori_dev index
838     SQLiteUtils::BindInt64ToStatement(statement, 3, logInfoBind.timestamp);  // 3 means timestamp index
839     SQLiteUtils::BindInt64ToStatement(statement, 4, logInfoBind.wTimestamp);  // 4 means w_timestamp index
840     SQLiteUtils::BindInt64ToStatement(statement, 5, logInfoBind.flag);  // 5 means flag index
841     SQLiteUtils::BindBlobToStatement(statement, 6, logInfoBind.hashKey);  // 6 means hashKey index
842     errCode = SQLiteUtils::StepWithRetry(statement, isMemDb_);
843     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
844         return E_OK;
845     }
846     return errCode;
847 }
848 
DeleteSyncDataItem(const DataItem & dataItem,RelationalSyncDataInserter & inserter,sqlite3_stmt * & stmt)849 int SQLiteSingleVerRelationalStorageExecutor::DeleteSyncDataItem(const DataItem &dataItem,
850     RelationalSyncDataInserter &inserter, sqlite3_stmt *&stmt)
851 {
852     if (stmt == nullptr) {
853         int errCode = inserter.GetDeleteSyncDataStmt(dbHandle_, stmt);
854         if (errCode != E_OK) {
855             LOGE("[DeleteSyncDataItem] Get statement fail!, errCode:%d", errCode);
856             return errCode;
857         }
858     }
859 
860     int errCode = SQLiteUtils::BindBlobToStatement(stmt, 1, dataItem.hashKey); // 1 means hash_key index
861     if (errCode != E_OK) {
862         SQLiteUtils::ResetStatement(stmt, true, errCode);
863         return errCode;
864     }
865     if (mode_ != DistributedTableMode::COLLABORATION) {
866         errCode = SQLiteUtils::BindTextToStatement(stmt, 2, dataItem.dev); // 2 means device index
867         if (errCode != E_OK) {
868             SQLiteUtils::ResetStatement(stmt, true, errCode);
869             return errCode;
870         }
871     }
872     errCode = SQLiteUtils::StepWithRetry(stmt, isMemDb_);
873     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
874         errCode = E_OK;
875     }
876     SQLiteUtils::ResetStatement(stmt, false, errCode);  // Finalize outside.
877     return errCode;
878 }
879 
SaveSyncDataItem(const DataItem & dataItem,SaveSyncDataStmt & saveStmt,RelationalSyncDataInserter & inserter,int64_t & rowid)880 int SQLiteSingleVerRelationalStorageExecutor::SaveSyncDataItem(const DataItem &dataItem, SaveSyncDataStmt &saveStmt,
881     RelationalSyncDataInserter &inserter, int64_t &rowid)
882 {
883     if ((dataItem.flag & DataItem::DELETE_FLAG) != 0) {
884         return DeleteSyncDataItem(dataItem, inserter, saveStmt.rmDataStmt);
885     }
886     if ((mode_ == DistributedTableMode::COLLABORATION && inserter.GetLocalTable().GetIdentifyKey().size() == 1u &&
887         inserter.GetLocalTable().GetIdentifyKey().at(0) == "rowid") ||
888         (mode_ == DistributedTableMode::SPLIT_BY_DEVICE && inserter.GetLocalTable().GetPrimaryKey().size() == 1u &&
889         inserter.GetLocalTable().GetPrimaryKey().at(0) == "rowid") ||
890         inserter.GetLocalTable().GetAutoIncrement()) {  // No primary key of auto increment
891         int errCode = DeleteSyncDataItem(dataItem, inserter, saveStmt.rmDataStmt);
892         if (errCode != E_OK) {
893             LOGE("Delete no pk data before insert failed, errCode=%d.", errCode);
894             return errCode;
895         }
896     }
897 
898     int errCode = inserter.BindInsertStatement(saveStmt.saveDataStmt, dataItem);
899     if (errCode != E_OK) {
900         LOGE("Bind data failed, errCode=%d.", errCode);
901         return errCode;
902     }
903     errCode = SQLiteUtils::StepWithRetry(saveStmt.saveDataStmt, isMemDb_);
904     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
905         rowid = SQLiteUtils::GetLastRowId(dbHandle_);
906         errCode = E_OK;
907     }
908     return errCode;
909 }
910 
DeleteSyncLog(const DataItem & dataItem,RelationalSyncDataInserter & inserter,sqlite3_stmt * & stmt)911 int SQLiteSingleVerRelationalStorageExecutor::DeleteSyncLog(const DataItem &dataItem,
912     RelationalSyncDataInserter &inserter, sqlite3_stmt *&stmt)
913 {
914     if (stmt == nullptr) {
915         int errCode = inserter.GetDeleteLogStmt(dbHandle_, stmt);
916         if (errCode != E_OK) {
917             LOGE("[DeleteSyncLog] Get statement fail!");
918             return errCode;
919         }
920     }
921 
922     int errCode = SQLiteUtils::BindBlobToStatement(stmt, 1, dataItem.hashKey); // 1 means hashkey index
923     if (errCode != E_OK) {
924         SQLiteUtils::ResetStatement(stmt, true, errCode);
925         return errCode;
926     }
927     if (mode_ != DistributedTableMode::COLLABORATION) {
928         errCode = SQLiteUtils::BindTextToStatement(stmt, 2, dataItem.dev); // 2 means device index
929         if (errCode != E_OK) {
930             SQLiteUtils::ResetStatement(stmt, true, errCode);
931             return errCode;
932         }
933     }
934     errCode = SQLiteUtils::StepWithRetry(stmt, isMemDb_);
935     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
936         errCode = E_OK;
937     }
938     SQLiteUtils::ResetStatement(stmt, false, errCode);  // Finalize outside.
939     return errCode;
940 }
941 
ProcessMissQueryData(const DataItem & item,RelationalSyncDataInserter & inserter,sqlite3_stmt * & rmDataStmt,sqlite3_stmt * & rmLogStmt)942 int SQLiteSingleVerRelationalStorageExecutor::ProcessMissQueryData(const DataItem &item,
943     RelationalSyncDataInserter &inserter, sqlite3_stmt *&rmDataStmt, sqlite3_stmt *&rmLogStmt)
944 {
945     int errCode = DeleteSyncDataItem(item, inserter, rmDataStmt);
946     if (errCode != E_OK) {
947         return errCode;
948     }
949     return DeleteSyncLog(item, inserter, rmLogStmt);
950 }
951 
GetSyncDataPre(const DataItem & dataItem,sqlite3_stmt * queryStmt,DataItem & itemGet)952 int SQLiteSingleVerRelationalStorageExecutor::GetSyncDataPre(const DataItem &dataItem, sqlite3_stmt *queryStmt,
953     DataItem &itemGet)
954 {
955     LogInfo logInfoGet;
956     int errCode = GetLogInfoPre(queryStmt, dataItem, logInfoGet);
957     itemGet.timestamp = logInfoGet.timestamp;
958     SQLiteUtils::ResetStatement(queryStmt, false, errCode);
959     return errCode;
960 }
961 
CheckDataConflictDefeated(const DataItem & dataItem,sqlite3_stmt * queryStmt,bool & isDefeated)962 int SQLiteSingleVerRelationalStorageExecutor::CheckDataConflictDefeated(const DataItem &dataItem,
963     sqlite3_stmt *queryStmt, bool &isDefeated)
964 {
965     if ((dataItem.flag & DataItem::REMOTE_DEVICE_DATA_MISS_QUERY) != DataItem::REMOTE_DEVICE_DATA_MISS_QUERY &&
966         mode_ == DistributedTableMode::SPLIT_BY_DEVICE) {
967         isDefeated = false; // no need to solve conflict except miss query data
968         return E_OK;
969     }
970 
971     DataItem itemGet;
972     int errCode = GetSyncDataPre(dataItem, queryStmt, itemGet);
973     if (errCode != E_OK && errCode != -E_NOT_FOUND) {
974         LOGE("Failed to get raw data. %d", errCode);
975         return errCode;
976     }
977     isDefeated = (dataItem.timestamp <= itemGet.timestamp); // defeated if item timestamp is earlier then raw data
978     return E_OK;
979 }
980 
SaveSyncDataItem(RelationalSyncDataInserter & inserter,SaveSyncDataStmt & saveStmt,DataItem & item)981 int SQLiteSingleVerRelationalStorageExecutor::SaveSyncDataItem(RelationalSyncDataInserter &inserter,
982     SaveSyncDataStmt &saveStmt, DataItem &item)
983 {
984     bool isDefeated = false;
985     int errCode = CheckDataConflictDefeated(item, saveStmt.queryStmt, isDefeated);
986     if (errCode != E_OK) {
987         LOGE("check data conflict failed. %d", errCode);
988         return errCode;
989     }
990 
991     if (isDefeated) {
992         LOGD("Data was defeated.");
993         return E_OK;
994     }
995     if ((item.flag & DataItem::REMOTE_DEVICE_DATA_MISS_QUERY) != 0) {
996         return ProcessMissQueryData(item, inserter, saveStmt.rmDataStmt, saveStmt.rmLogStmt);
997     }
998     int64_t rowid = -1;
999     errCode = SaveSyncDataItem(item, saveStmt, inserter, rowid);
1000     if (errCode == E_OK || errCode == -E_NOT_FOUND) {
1001         errCode = SaveSyncLog(saveStmt.saveLogStmt, saveStmt.queryStmt, item, rowid);
1002     }
1003     return errCode;
1004 }
1005 
SaveSyncDataItems(RelationalSyncDataInserter & inserter)1006 int SQLiteSingleVerRelationalStorageExecutor::SaveSyncDataItems(RelationalSyncDataInserter &inserter)
1007 {
1008     SaveSyncDataStmt saveStmt;
1009     int errCode = inserter.PrepareStatement(dbHandle_, saveStmt);
1010     if (errCode != E_OK) {
1011         LOGE("Prepare insert sync data statement failed.");
1012         return errCode;
1013     }
1014 
1015     errCode = inserter.Iterate([this, &saveStmt, &inserter] (DataItem &item) -> int {
1016         if (item.neglect) { // Do not save this record if it is neglected
1017             return E_OK;
1018         }
1019         int errCode = SaveSyncDataItem(inserter, saveStmt, item);
1020         if (errCode != E_OK) {
1021             LOGE("save sync data item failed. err=%d", errCode);
1022             return errCode;
1023         }
1024         // Need not reset rmDataStmt and rmLogStmt here.
1025         return saveStmt.ResetStatements(false);
1026     });
1027 
1028     int ret = saveStmt.ResetStatements(true);
1029     return errCode != E_OK ? errCode : ret;
1030 }
1031 
SaveSyncItems(RelationalSyncDataInserter & inserter,bool useTrans)1032 int SQLiteSingleVerRelationalStorageExecutor::SaveSyncItems(RelationalSyncDataInserter &inserter, bool useTrans)
1033 {
1034     if (useTrans) {
1035         int errCode = StartTransaction(TransactType::IMMEDIATE);
1036         if (errCode != E_OK) {
1037             return errCode;
1038         }
1039     }
1040 
1041     int errCode = SetLogTriggerStatus(false);
1042     if (errCode != E_OK) {
1043         goto END;
1044     }
1045 
1046     errCode = SaveSyncDataItems(inserter);
1047     if (errCode != E_OK) {
1048         LOGE("Save sync data items failed. errCode=%d", errCode);
1049         goto END;
1050     }
1051 
1052     errCode = SetLogTriggerStatus(true);
1053 END:
1054     if (useTrans) {
1055         if (errCode == E_OK) {
1056             errCode = Commit();
1057         } else {
1058             (void)Rollback(); // Keep the error code of the first scene
1059         }
1060     }
1061     return errCode;
1062 }
1063 
GetDataItemForSync(sqlite3_stmt * stmt,DataItem & dataItem,bool isGettingDeletedData) const1064 int SQLiteSingleVerRelationalStorageExecutor::GetDataItemForSync(sqlite3_stmt *stmt, DataItem &dataItem,
1065     bool isGettingDeletedData) const
1066 {
1067     RowDataWithLog data;
1068     int errCode = GetLogData(stmt, data.logInfo);
1069     if (errCode != E_OK) {
1070         LOGE("relational data value transfer to kv fail");
1071         return errCode;
1072     }
1073 
1074     if (!isGettingDeletedData) {
1075         for (size_t cid = 0; cid < table_.GetFields().size(); ++cid) {
1076             DataValue value;
1077             errCode = SQLiteRelationalUtils::GetDataValueByType(stmt, cid + DBConstant::RELATIONAL_LOG_TABLE_FIELD_NUM,
1078                 value);
1079             if (errCode != E_OK) {
1080                 return errCode;
1081             }
1082             data.rowData.push_back(std::move(value)); // sorted by cid
1083         }
1084     }
1085 
1086     errCode = DataTransformer::SerializeDataItem(data,
1087         isGettingDeletedData ? std::vector<FieldInfo>() : table_.GetFieldInfos(), dataItem);
1088     if (errCode != E_OK) {
1089         LOGE("relational data value transfer to kv fail");
1090     }
1091     return errCode;
1092 }
1093 
GetMissQueryData(sqlite3_stmt * fullStmt,DataItem & item)1094 int SQLiteSingleVerRelationalStorageExecutor::GetMissQueryData(sqlite3_stmt *fullStmt, DataItem &item)
1095 {
1096     int errCode = GetDataItemForSync(fullStmt, item, false);
1097     if (errCode != E_OK) {
1098         return errCode;
1099     }
1100     item.value = {};
1101     item.flag |= DataItem::REMOTE_DEVICE_DATA_MISS_QUERY;
1102     return E_OK;
1103 }
1104 
1105 namespace {
StepNext(bool isMemDB,sqlite3_stmt * stmt,Timestamp & timestamp)1106 int StepNext(bool isMemDB, sqlite3_stmt *stmt, Timestamp &timestamp)
1107 {
1108     if (stmt == nullptr) {
1109         return -E_INVALID_ARGS;
1110     }
1111     int errCode = SQLiteUtils::StepWithRetry(stmt, isMemDB);
1112     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1113         timestamp = INT64_MAX;
1114         errCode = E_OK;
1115     } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1116         timestamp = static_cast<uint64_t>(sqlite3_column_int64(stmt, 3));  // 3 means timestamp index
1117         errCode = E_OK;
1118     }
1119     return errCode;
1120 }
1121 
AppendData(const DataSizeSpecInfo & sizeInfo,size_t appendLength,size_t & overLongSize,size_t & dataTotalSize,std::vector<DataItem> & dataItems,DataItem && item)1122 int AppendData(const DataSizeSpecInfo &sizeInfo, size_t appendLength, size_t &overLongSize, size_t &dataTotalSize,
1123     std::vector<DataItem> &dataItems, DataItem &&item)
1124 {
1125     // If one record is over 4M, ignore it.
1126     if (item.value.size() > DBConstant::MAX_VALUE_SIZE) {
1127         overLongSize++;
1128     } else {
1129         // If dataTotalSize value is bigger than blockSize value , reserve the surplus data item.
1130         dataTotalSize += GetDataItemSerialSize(item, appendLength);
1131         if ((dataTotalSize > sizeInfo.blockSize && !dataItems.empty()) || dataItems.size() >= sizeInfo.packetSize) {
1132             return -E_UNFINISHED;
1133         } else {
1134             dataItems.push_back(item);
1135         }
1136     }
1137     return E_OK;
1138 }
1139 }
1140 
GetQueryDataAndStepNext(bool isFirstTime,bool isGettingDeletedData,sqlite3_stmt * queryStmt,DataItem & item,Timestamp & queryTime)1141 int SQLiteSingleVerRelationalStorageExecutor::GetQueryDataAndStepNext(bool isFirstTime, bool isGettingDeletedData,
1142     sqlite3_stmt *queryStmt, DataItem &item, Timestamp &queryTime)
1143 {
1144     if (!isFirstTime) { // For the first time, never step before, can get nothing
1145         int errCode = GetDataItemForSync(queryStmt, item, isGettingDeletedData);
1146         if (errCode != E_OK) {
1147             return errCode;
1148         }
1149     }
1150     return StepNext(isMemDb_, queryStmt, queryTime);
1151 }
1152 
GetMissQueryDataAndStepNext(sqlite3_stmt * fullStmt,DataItem & item,Timestamp & missQueryTime)1153 int SQLiteSingleVerRelationalStorageExecutor::GetMissQueryDataAndStepNext(sqlite3_stmt *fullStmt, DataItem &item,
1154     Timestamp &missQueryTime)
1155 {
1156     int errCode = GetMissQueryData(fullStmt, item);
1157     if (errCode != E_OK) {
1158         return errCode;
1159     }
1160     return StepNext(isMemDb_, fullStmt, missQueryTime);
1161 }
1162 
GetSyncDataByQuery(std::vector<DataItem> & dataItems,size_t appendLength,const DataSizeSpecInfo & sizeInfo,std::function<int (sqlite3 *,sqlite3_stmt * &,sqlite3_stmt * &,bool &)> getStmt,const TableInfo & tableInfo)1163 int SQLiteSingleVerRelationalStorageExecutor::GetSyncDataByQuery(std::vector<DataItem> &dataItems, size_t appendLength,
1164     const DataSizeSpecInfo &sizeInfo, std::function<int(sqlite3 *, sqlite3_stmt *&, sqlite3_stmt *&, bool &)> getStmt,
1165     const TableInfo &tableInfo)
1166 {
1167     baseTblName_ = tableInfo.GetTableName();
1168     SetTableInfo(tableInfo);
1169     sqlite3_stmt *queryStmt = nullptr;
1170     sqlite3_stmt *fullStmt = nullptr;
1171     bool isGettingDeletedData = false;
1172     int errCode = getStmt(dbHandle_, queryStmt, fullStmt, isGettingDeletedData);
1173     if (errCode != E_OK) {
1174         return errCode;
1175     }
1176 
1177     Timestamp queryTime = 0;
1178     Timestamp missQueryTime = (fullStmt == nullptr ? INT64_MAX : 0);
1179 
1180     bool isFirstTime = true;
1181     size_t dataTotalSize = 0;
1182     size_t overLongSize = 0;
1183     do {
1184         DataItem item;
1185         if (queryTime < missQueryTime) {
1186             errCode = GetQueryDataAndStepNext(isFirstTime, isGettingDeletedData, queryStmt, item, queryTime);
1187         } else if (queryTime == missQueryTime) {
1188             errCode = GetQueryDataAndStepNext(isFirstTime, isGettingDeletedData, queryStmt, item, queryTime);
1189             if (errCode != E_OK) {
1190                 break;
1191             }
1192             errCode = StepNext(isMemDb_, fullStmt, missQueryTime);
1193         } else {
1194             errCode = GetMissQueryDataAndStepNext(fullStmt, item, missQueryTime);
1195         }
1196 
1197         if (errCode == E_OK && !isFirstTime) {
1198             errCode = AppendData(sizeInfo, appendLength, overLongSize, dataTotalSize, dataItems, std::move(item));
1199         }
1200 
1201         if (errCode != E_OK) {
1202             break;
1203         }
1204 
1205         isFirstTime = false;
1206         if (queryTime == INT64_MAX && missQueryTime == INT64_MAX) {
1207             errCode = -E_FINISHED;
1208             break;
1209         }
1210     } while (true);
1211     LOGI("Get sync data finished, rc:%d, record size:%zu, overlong size:%zu, isDeleted:%d",
1212         errCode, dataItems.size(), overLongSize, isGettingDeletedData);
1213     SQLiteUtils::ResetStatement(queryStmt, true, errCode);
1214     SQLiteUtils::ResetStatement(fullStmt, true, errCode);
1215     return errCode;
1216 }
1217 
CheckDBModeForRelational()1218 int SQLiteSingleVerRelationalStorageExecutor::CheckDBModeForRelational()
1219 {
1220     std::string journalMode;
1221     int errCode = SQLiteUtils::GetJournalMode(dbHandle_, journalMode);
1222 
1223     for (auto &c : journalMode) { // convert to lowercase
1224         c = static_cast<char>(std::tolower(c));
1225     }
1226 
1227     if (errCode == E_OK && journalMode != "wal") {
1228         LOGE("Not support journal mode %s for relational db, expect wal mode.", journalMode.c_str());
1229         return -E_NOT_SUPPORT;
1230     }
1231     return errCode;
1232 }
1233 
DeleteDistributedDeviceTable(const std::string & device,const std::string & tableName)1234 int SQLiteSingleVerRelationalStorageExecutor::DeleteDistributedDeviceTable(const std::string &device,
1235     const std::string &tableName)
1236 {
1237     std::vector<std::string> deviceTables;
1238     int errCode = GetDeviceTableName(dbHandle_, tableName, device, deviceTables);
1239     if (errCode != E_OK) {
1240         LOGE("Get device table name for alter table failed. %d", errCode);
1241         return errCode;
1242     }
1243 
1244     LOGD("Begin to delete device table: deviceTable[%zu]", deviceTables.size());
1245     for (const auto &table : deviceTables) {
1246         std::string deleteSql = "DROP TABLE IF EXISTS " + table + ";"; // drop the found table
1247         errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, deleteSql);
1248         if (errCode != E_OK) {
1249             LOGE("Delete device data failed. %d", errCode);
1250             break;
1251         }
1252     }
1253     return errCode;
1254 }
1255 
DeleteDistributedAllDeviceTableLog(const std::string & tableName)1256 int SQLiteSingleVerRelationalStorageExecutor::DeleteDistributedAllDeviceTableLog(const std::string &tableName)
1257 {
1258     std::string deleteLogSql =
1259         "DELETE FROM " + DBConstant::RELATIONAL_PREFIX + tableName +
1260         "_log WHERE flag&0x02=0 AND (cloud_gid = '' OR cloud_gid IS NULL)";
1261     return SQLiteUtils::ExecuteRawSQL(dbHandle_, deleteLogSql);
1262 }
1263 
DeleteDistributedDeviceTableLog(const std::string & device,const std::string & tableName)1264 int SQLiteSingleVerRelationalStorageExecutor::DeleteDistributedDeviceTableLog(const std::string &device,
1265     const std::string &tableName)
1266 {
1267     std::string deleteLogSql = "DELETE FROM " + DBConstant::RELATIONAL_PREFIX + tableName + "_log WHERE device = ?";
1268     sqlite3_stmt *deleteLogStmt = nullptr;
1269     int errCode = SQLiteUtils::GetStatement(dbHandle_, deleteLogSql, deleteLogStmt);
1270     if (errCode != E_OK) {
1271         LOGE("Get delete device data log statement failed. %d", errCode);
1272         return errCode;
1273     }
1274 
1275     errCode = SQLiteUtils::BindTextToStatement(deleteLogStmt, 1, device);
1276     if (errCode != E_OK) {
1277         LOGE("Bind device to delete data log statement failed. %d", errCode);
1278         SQLiteUtils::ResetStatement(deleteLogStmt, true, errCode);
1279         return errCode;
1280     }
1281 
1282     errCode = SQLiteUtils::StepWithRetry(deleteLogStmt);
1283     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1284         errCode = E_OK;
1285     } else {
1286         LOGE("Delete data log failed. %d", errCode);
1287     }
1288 
1289     SQLiteUtils::ResetStatement(deleteLogStmt, true, errCode);
1290     return errCode;
1291 }
1292 
DeleteDistributedLogTable(const std::string & tableName)1293 int SQLiteSingleVerRelationalStorageExecutor::DeleteDistributedLogTable(const std::string &tableName)
1294 {
1295     if (tableName.empty()) {
1296         return -E_INVALID_ARGS;
1297     }
1298     std::string logTableName = DBConstant::RELATIONAL_PREFIX + tableName + "_log";
1299     std::string deleteSql = "DROP TABLE IF EXISTS " + logTableName + ";";
1300     int errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, deleteSql);
1301     if (errCode != E_OK) {
1302         LOGE("Delete distributed log table failed. %d", errCode);
1303     }
1304     return errCode;
1305 }
1306 
IsTableOnceDropped(const std::string & tableName,bool & onceDropped)1307 int SQLiteSingleVerRelationalStorageExecutor::IsTableOnceDropped(const std::string &tableName, bool &onceDropped)
1308 {
1309     std::string keyStr = DBConstant::TABLE_IS_DROPPED + tableName;
1310     Key key;
1311     DBCommon::StringToVector(keyStr, key);
1312     Value value;
1313 
1314     int errCode = GetKvData(key, value);
1315     if (errCode == E_OK) {
1316         onceDropped = true;
1317         return E_OK;
1318     } else if (errCode == -E_NOT_FOUND) {
1319         onceDropped = false;
1320         return E_OK;
1321     }
1322     return errCode;
1323 }
1324 
CleanResourceForDroppedTable(const std::string & tableName)1325 int SQLiteSingleVerRelationalStorageExecutor::CleanResourceForDroppedTable(const std::string &tableName)
1326 {
1327     int errCode = DeleteDistributedDeviceTable({}, tableName); // Clean the auxiliary tables for the dropped table
1328     if (errCode != E_OK) {
1329         LOGE("Delete device tables for missing distributed table failed. %d", errCode);
1330         return errCode;
1331     }
1332     errCode = DeleteDistributedLogTable(tableName);
1333     if (errCode != E_OK) {
1334         LOGE("Delete log tables for missing distributed table failed. %d", errCode);
1335         return errCode;
1336     }
1337     errCode = DeleteTableTrigger(tableName);
1338     if (errCode != E_OK) {
1339         LOGE("Delete trigger for missing distributed table failed. %d", errCode);
1340     }
1341     return errCode;
1342 }
1343 
CheckAndCleanDistributedTable(const std::vector<std::string> & tableNames,std::vector<std::string> & missingTables)1344 int SQLiteSingleVerRelationalStorageExecutor::CheckAndCleanDistributedTable(const std::vector<std::string> &tableNames,
1345     std::vector<std::string> &missingTables)
1346 {
1347     if (tableNames.empty()) {
1348         return E_OK;
1349     }
1350     const std::string checkSql = "SELECT name FROM sqlite_master WHERE type='table' AND name=?;";
1351     sqlite3_stmt *stmt = nullptr;
1352     int errCode = SQLiteUtils::GetStatement(dbHandle_, checkSql, stmt);
1353     if (errCode != E_OK) {
1354         SQLiteUtils::ResetStatement(stmt, true, errCode);
1355         return errCode;
1356     }
1357     for (const auto &tableName : tableNames) {
1358         errCode = SQLiteUtils::BindTextToStatement(stmt, 1, tableName); // 1: tablename bind index
1359         if (errCode != E_OK) {
1360             LOGE("Bind table name to check distributed table statement failed. %d", errCode);
1361             break;
1362         }
1363 
1364         errCode = SQLiteUtils::StepWithRetry(stmt, false);
1365         if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { // The table in schema was dropped
1366             errCode = DeleteDistributedDeviceTable({}, tableName); // Clean the auxiliary tables for the dropped table
1367             if (errCode != E_OK) {
1368                 LOGE("Delete device tables for missing distributed table failed. %d", errCode);
1369                 break;
1370             }
1371             errCode = DeleteDistributedLogTable(tableName);
1372             if (errCode != E_OK) {
1373                 LOGE("Delete log tables for missing distributed table failed. %d", errCode);
1374                 break;
1375             }
1376             errCode = DeleteTableTrigger(tableName);
1377             if (errCode != E_OK) {
1378                 LOGE("Delete trigger for missing distributed table failed. %d", errCode);
1379                 break;
1380             }
1381             missingTables.emplace_back(tableName);
1382         } else if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1383             LOGE("Check distributed table failed. %d", errCode);
1384             break;
1385         }
1386         errCode = E_OK; // Check result ok for distributed table is still exists
1387         SQLiteUtils::ResetStatement(stmt, false, errCode);
1388     }
1389     SQLiteUtils::ResetStatement(stmt, true, errCode);
1390     return CheckCorruptedStatus(errCode);
1391 }
1392 
CreateDistributedDeviceTable(const std::string & device,const TableInfo & baseTbl,const StoreInfo & info)1393 int SQLiteSingleVerRelationalStorageExecutor::CreateDistributedDeviceTable(const std::string &device,
1394     const TableInfo &baseTbl, const StoreInfo &info)
1395 {
1396     if (dbHandle_ == nullptr) {
1397         return -E_INVALID_DB;
1398     }
1399 
1400     if (device.empty() || !baseTbl.IsValid()) {
1401         return -E_INVALID_ARGS;
1402     }
1403 
1404     std::string deviceTableName = DBCommon::GetDistributedTableName(device, baseTbl.GetTableName(), info);
1405     int errCode = SQLiteUtils::CreateSameStuTable(dbHandle_, baseTbl, deviceTableName);
1406     if (errCode != E_OK) {
1407         LOGE("Create device table failed. %d", errCode);
1408         return errCode;
1409     }
1410 
1411     errCode = SQLiteUtils::CloneIndexes(dbHandle_, baseTbl.GetTableName(), deviceTableName);
1412     if (errCode != E_OK) {
1413         LOGE("Copy index to device table failed. %d", errCode);
1414     }
1415     return errCode;
1416 }
1417 
CheckQueryObjectLegal(const TableInfo & table,QueryObject & query,const std::string & schemaVersion)1418 int SQLiteSingleVerRelationalStorageExecutor::CheckQueryObjectLegal(const TableInfo &table, QueryObject &query,
1419     const std::string &schemaVersion)
1420 {
1421     if (dbHandle_ == nullptr) {
1422         return -E_INVALID_DB;
1423     }
1424 
1425     TableInfo newTable;
1426     int errCode = SQLiteUtils::AnalysisSchema(dbHandle_, table.GetTableName(), newTable);
1427     if (errCode != E_OK && errCode != -E_NOT_FOUND) {
1428         LOGE("Check new schema failed. %d", errCode);
1429         return errCode;
1430     } else {
1431         errCode = table.CompareWithTable(newTable, schemaVersion);
1432         if (errCode != -E_RELATIONAL_TABLE_EQUAL && errCode != -E_RELATIONAL_TABLE_COMPATIBLE) {
1433             LOGE("Check schema failed, schema was changed. %d", errCode);
1434             return -E_DISTRIBUTED_SCHEMA_CHANGED;
1435         } else {
1436             errCode = E_OK;
1437         }
1438     }
1439 
1440     SqliteQueryHelper helper = query.GetQueryHelper(errCode);
1441     if (errCode != E_OK) {
1442         LOGE("Get query helper for check query failed. %d", errCode);
1443         return errCode;
1444     }
1445 
1446     if (!query.IsQueryForRelationalDB()) {
1447         LOGE("Not support for this query type.");
1448         return -E_NOT_SUPPORT;
1449     }
1450 
1451     SyncTimeRange defaultTimeRange;
1452     sqlite3_stmt *stmt = nullptr;
1453     errCode = helper.GetRelationalQueryStatement(dbHandle_, defaultTimeRange.beginTime, defaultTimeRange.endTime, {},
1454         stmt);
1455     if (errCode != E_OK) {
1456         LOGE("Get query statement for check query failed. %d", errCode);
1457     }
1458 
1459     SQLiteUtils::ResetStatement(stmt, true, errCode);
1460     return errCode;
1461 }
1462 
CheckQueryObjectLegal(const QuerySyncObject & query)1463 int SQLiteSingleVerRelationalStorageExecutor::CheckQueryObjectLegal(const QuerySyncObject &query)
1464 {
1465     if (dbHandle_ == nullptr) {
1466         return -E_INVALID_DB;
1467     }
1468     TableInfo newTable;
1469     int errCode = SQLiteUtils::AnalysisSchema(dbHandle_, query.GetTableName(), newTable);
1470     if (errCode != E_OK) {
1471         LOGE("Check new schema failed. %d", errCode);
1472     }
1473     return errCode;
1474 }
1475 
GetMaxTimestamp(const std::vector<std::string> & tableNames,Timestamp & maxTimestamp) const1476 int SQLiteSingleVerRelationalStorageExecutor::GetMaxTimestamp(const std::vector<std::string> &tableNames,
1477     Timestamp &maxTimestamp) const
1478 {
1479     maxTimestamp = 0;
1480     for (const auto &tableName : tableNames) {
1481         const std::string sql = "SELECT MAX(timestamp) FROM " + DBConstant::RELATIONAL_PREFIX + tableName + "_log;";
1482         sqlite3_stmt *stmt = nullptr;
1483         int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, stmt);
1484         if (errCode != E_OK) {
1485             return errCode;
1486         }
1487         errCode = SQLiteUtils::StepWithRetry(stmt, isMemDb_);
1488         if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1489             maxTimestamp = std::max(maxTimestamp, static_cast<Timestamp>(sqlite3_column_int64(stmt, 0))); // 0 is index
1490             errCode = E_OK;
1491         }
1492         SQLiteUtils::ResetStatement(stmt, true, errCode);
1493         if (errCode != E_OK) {
1494             maxTimestamp = 0;
1495             return errCode;
1496         }
1497     }
1498     return E_OK;
1499 }
1500 
SetLogTriggerStatus(bool status)1501 int SQLiteSingleVerRelationalStorageExecutor::SetLogTriggerStatus(bool status)
1502 {
1503     const std::string key = "log_trigger_switch";
1504     std::string val = status ? "true" : "false";
1505     std::string sql = "INSERT OR REPLACE INTO " + DBConstant::RELATIONAL_PREFIX + "metadata" +
1506         " VALUES ('" + key + "', '" + val + "')";
1507     int errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, sql);
1508     if (errCode != E_OK) {
1509         LOGE("Set log trigger to %s failed. errCode=%d", val.c_str(), errCode);
1510     }
1511     return errCode;
1512 }
1513 
1514 namespace {
GetRowDatas(sqlite3_stmt * stmt,bool isMemDb,std::vector<std::string> & colNames,std::vector<RelationalRowData * > & data)1515 int GetRowDatas(sqlite3_stmt *stmt, bool isMemDb, std::vector<std::string> &colNames,
1516     std::vector<RelationalRowData *> &data)
1517 {
1518     size_t totalLength = 0;
1519     do {
1520         int errCode = SQLiteUtils::StepWithRetry(stmt, isMemDb);
1521         if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1522             return E_OK;
1523         } else if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1524             LOGE("Get data by bind sql failed:%d", errCode);
1525             return errCode;
1526         }
1527 
1528         if (colNames.empty()) {
1529             SQLiteUtils::GetSelectCols(stmt, colNames);  // Get column names.
1530         }
1531         auto relaRowData = new (std::nothrow) RelationalRowDataImpl(SQLiteRelationalUtils::GetSelectValues(stmt));
1532         if (relaRowData == nullptr) {
1533             LOGE("ExecuteQueryBySqlStmt OOM");
1534             return -E_OUT_OF_MEMORY;
1535         }
1536 
1537         auto dataSz = relaRowData->CalcLength();
1538         if (dataSz == 0) {  // invalid data
1539             delete relaRowData;
1540             relaRowData = nullptr;
1541             continue;
1542         }
1543 
1544         totalLength += static_cast<size_t>(dataSz);
1545         if (totalLength > static_cast<uint32_t>(DBConstant::MAX_REMOTEDATA_SIZE)) {  // the set has been full
1546             delete relaRowData;
1547             relaRowData = nullptr;
1548             LOGE("ExecuteQueryBySqlStmt OVERSIZE");
1549             return -E_REMOTE_OVER_SIZE;
1550         }
1551         data.push_back(relaRowData);
1552     } while (true);
1553     return E_OK;
1554 }
1555 }
1556 
1557 // 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)1558 int SQLiteSingleVerRelationalStorageExecutor::ExecuteQueryBySqlStmt(const std::string &sql,
1559     const std::vector<std::string> &bindArgs, int packetSize, std::vector<std::string> &colNames,
1560     std::vector<RelationalRowData *> &data)
1561 {
1562     int errCode = SQLiteUtils::SetAuthorizer(dbHandle_, &PermitSelect);
1563     if (errCode != E_OK) {
1564         return errCode;
1565     }
1566 
1567     sqlite3_stmt *stmt = nullptr;
1568     errCode = SQLiteUtils::GetStatement(dbHandle_, sql, stmt);
1569     if (errCode != E_OK) {
1570         (void)SQLiteUtils::SetAuthorizer(dbHandle_, nullptr);
1571         return errCode;
1572     }
1573     ResFinalizer finalizer([this, &stmt, &errCode] {
1574         (void)SQLiteUtils::SetAuthorizer(this->dbHandle_, nullptr);
1575         SQLiteUtils::ResetStatement(stmt, true, errCode);
1576     });
1577     for (size_t i = 0; i < bindArgs.size(); ++i) {
1578         errCode = SQLiteUtils::BindTextToStatement(stmt, i + 1, bindArgs.at(i));
1579         if (errCode != E_OK) {
1580             return errCode;
1581         }
1582     }
1583     return GetRowDatas(stmt, isMemDb_, colNames, data);
1584 }
1585 
CheckEncryptedOrCorrupted() const1586 int SQLiteSingleVerRelationalStorageExecutor::CheckEncryptedOrCorrupted() const
1587 {
1588     if (dbHandle_ == nullptr) {
1589         return -E_INVALID_DB;
1590     }
1591 
1592     int errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, "SELECT count(*) FROM sqlite_master;");
1593     if (errCode != E_OK) {
1594         LOGE("[SingVerRelaExec] CheckEncryptedOrCorrupted failed:%d", errCode);
1595     }
1596     return errCode;
1597 }
1598 
GetExistsDeviceList(std::set<std::string> & devices) const1599 int SQLiteSingleVerRelationalStorageExecutor::GetExistsDeviceList(std::set<std::string> &devices) const
1600 {
1601     return SqliteMetaExecutor::GetExistsDevicesFromMeta(dbHandle_, SqliteMetaExecutor::MetaMode::RDB,
1602         isMemDb_, devices);
1603 }
1604 
GetSyncCloudGid(QuerySyncObject & query,const SyncTimeRange & syncTimeRange,bool isCloudForcePushStrategy,bool isCompensatedTask,std::vector<std::string> & cloudGid)1605 int SQLiteSingleVerRelationalStorageExecutor::GetSyncCloudGid(QuerySyncObject &query,
1606     const SyncTimeRange &syncTimeRange, bool isCloudForcePushStrategy,
1607     bool isCompensatedTask, std::vector<std::string> &cloudGid)
1608 {
1609     sqlite3_stmt *queryStmt = nullptr;
1610     int errCode = E_OK;
1611     SqliteQueryHelper helper = query.GetQueryHelper(errCode);
1612     if (errCode != E_OK) {
1613         return errCode;
1614     }
1615     std::string sql = helper.GetGidRelationalCloudQuerySql(tableSchema_.fields, isCloudForcePushStrategy,
1616         isCompensatedTask);
1617     errCode = helper.GetCloudQueryStatement(false, dbHandle_, syncTimeRange.beginTime, sql, queryStmt);
1618     if (errCode != E_OK) {
1619         return errCode;
1620     }
1621     do {
1622         errCode = SQLiteUtils::StepNext(queryStmt, isMemDb_);
1623         if (errCode != E_OK) {
1624             errCode = (errCode == -E_FINISHED ? E_OK : errCode);
1625             break;
1626         }
1627         GetCloudGid(queryStmt, cloudGid);
1628     } while (errCode == E_OK);
1629     int resetStatementErrCode = E_OK;
1630     SQLiteUtils::ResetStatement(queryStmt, true, resetStatementErrCode);
1631     queryStmt = nullptr;
1632     return (errCode == E_OK ? resetStatementErrCode : errCode);
1633 }
1634 
GetCloudDataForSync(const CloudUploadRecorder & uploadRecorder,sqlite3_stmt * statement,CloudSyncData & cloudDataResult,uint32_t & stepNum,uint32_t & totalSize)1635 int SQLiteSingleVerRelationalStorageExecutor::GetCloudDataForSync(const CloudUploadRecorder &uploadRecorder,
1636     sqlite3_stmt *statement, CloudSyncData &cloudDataResult, uint32_t &stepNum, uint32_t &totalSize)
1637 {
1638     VBucket log;
1639     VBucket extraLog;
1640     uint32_t preSize = totalSize;
1641     GetCloudLog(statement, log, totalSize);
1642     GetCloudExtraLog(statement, extraLog);
1643 
1644     VBucket data;
1645     int64_t flag = 0;
1646     int errCode = CloudStorageUtils::GetValueFromVBucket(CloudDbConstant::FLAG, extraLog, flag);
1647     if (errCode != E_OK) {
1648         return errCode;
1649     }
1650     if ((static_cast<uint64_t>(flag) & DataItem::DELETE_FLAG) == 0) {
1651         for (size_t cid = 0; cid < tableSchema_.fields.size(); ++cid) {
1652             Type cloudValue;
1653             errCode = SQLiteRelationalUtils::GetCloudValueByType(statement,
1654                 tableSchema_.fields[cid].type, cid + STATUS_INDEX + 1, cloudValue);
1655             if (errCode != E_OK) {
1656                 return errCode;
1657             }
1658             SQLiteRelationalUtils::CalCloudValueLen(cloudValue, totalSize);
1659             errCode = PutVBucketByType(data, tableSchema_.fields[cid], cloudValue);
1660             if (errCode != E_OK) {
1661                 return errCode;
1662             }
1663         }
1664     }
1665 
1666     if (CloudStorageUtils::IsGetCloudDataContinue(stepNum, totalSize, maxUploadSize_, maxUploadCount_)) {
1667         errCode = CloudStorageUtils::IdentifyCloudType(uploadRecorder, cloudDataResult, data, log, extraLog);
1668     } else {
1669         errCode = -E_UNFINISHED;
1670     }
1671     if (errCode == -E_IGNORE_DATA) {
1672         errCode = E_OK;
1673         totalSize = preSize;
1674         stepNum--;
1675     }
1676     return errCode;
1677 }
1678 
SetLocalSchema(const RelationalSchemaObject & localSchema)1679 void SQLiteSingleVerRelationalStorageExecutor::SetLocalSchema(const RelationalSchemaObject &localSchema)
1680 {
1681     localSchema_ = localSchema;
1682 }
1683 
CleanCloudDataOnLogTable(const std::string & logTableName,ClearMode mode)1684 int SQLiteSingleVerRelationalStorageExecutor::CleanCloudDataOnLogTable(const std::string &logTableName, ClearMode mode)
1685 {
1686     std::string setFlag;
1687     if (mode == FLAG_ONLY && isLogicDelete_) {
1688         setFlag = SET_FLAG_CLEAN_WAIT_COMPENSATED_SYNC;
1689     } else {
1690         setFlag = SET_FLAG_LOCAL_AND_CLEAN_WAIT_COMPENSATED_SYNC;
1691     }
1692     std::string cleanLogSql = "UPDATE " + logTableName + " SET " + CloudDbConstant::FLAG + " = " + setFlag +
1693         ", " + VERSION + " = '', " + DEVICE_FIELD + " = '', " + CLOUD_GID_FIELD + " = '', " +
1694         SHARING_RESOURCE + " = '' " + "WHERE (" + FLAG_IS_LOGIC_DELETE + ") OR " +
1695         CLOUD_GID_FIELD + " IS NOT NULL AND " + CLOUD_GID_FIELD + " != '';";
1696     int errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, cleanLogSql);
1697     if (errCode != E_OK) {
1698         LOGE("clean cloud log failed, %d", errCode);
1699         return errCode;
1700     }
1701     cleanLogSql = "DELETE FROM " + logTableName + " WHERE " + FLAG_IS_CLOUD + " AND " + DATA_IS_DELETE + ";";
1702     errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, cleanLogSql);
1703     if (errCode != E_OK) {
1704         LOGE("delete cloud log failed, %d", errCode);
1705         return errCode;
1706     }
1707     // set all flag logout and data upload is not finished.
1708     cleanLogSql = "UPDATE " + logTableName + " SET " + CloudDbConstant::FLAG;
1709     if (mode == FLAG_ONLY) {
1710         cleanLogSql += " = flag | 0x800 & ~0x400;";
1711     } else {
1712         cleanLogSql += " = flag & ~0x400;";
1713     }
1714     return SQLiteUtils::ExecuteRawSQL(dbHandle_, cleanLogSql);
1715 }
1716 
CleanUploadFinishedFlag(const std::string & tableName)1717 int SQLiteSingleVerRelationalStorageExecutor::CleanUploadFinishedFlag(const std::string &tableName)
1718 {
1719     // unset upload finished flag
1720     std::string cleanUploadFinishedSql = "UPDATE " + DBCommon::GetLogTableName(tableName) + " SET " +
1721         CloudDbConstant::FLAG + " = flag & ~0x400;";
1722     return SQLiteUtils::ExecuteRawSQL(dbHandle_, cleanUploadFinishedSql);
1723 }
1724 
CleanCloudDataAndLogOnUserTable(const std::string & tableName,const std::string & logTableName,const RelationalSchemaObject & localSchema)1725 int SQLiteSingleVerRelationalStorageExecutor::CleanCloudDataAndLogOnUserTable(const std::string &tableName,
1726     const std::string &logTableName, const RelationalSchemaObject &localSchema)
1727 {
1728     std::string sql = "DELETE FROM '" + tableName + "' WHERE " + std::string(DBConstant::SQLITE_INNER_ROWID) +
1729         " IN (SELECT " + DATAKEY + " FROM '" + logTableName + "' WHERE (" + FLAG_IS_LOGIC_DELETE +
1730         ") OR CLOUD_GID IS NOT NULL AND CLOUD_GID != '' AND (" + FLAG_IS_CLOUD + " OR " + FLAG_IS_CLOUD_CONSISTENCY +
1731         "));";
1732     int errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, sql);
1733     if (errCode != E_OK) {
1734         LOGE("Failed to delete cloud data on usertable, %d.", errCode);
1735         return errCode;
1736     }
1737     std::string cleanLogSql = "DELETE FROM '" + logTableName + "' WHERE " + FLAG_IS_CLOUD + " OR " +
1738         FLAG_IS_CLOUD_CONSISTENCY + ";";
1739     errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, cleanLogSql);
1740     if (errCode != E_OK) {
1741         LOGE("Failed to delete cloud data on log table, %d.", errCode);
1742         return errCode;
1743     }
1744     errCode = DoCleanAssetId(tableName, localSchema);
1745     if (errCode != E_OK) {
1746         LOGE("[Storage Executor] failed to clean asset id when clean cloud data, %d", errCode);
1747         return errCode;
1748     }
1749     errCode = CleanCloudDataOnLogTable(logTableName, FLAG_AND_DATA);
1750     if (errCode != E_OK) {
1751         LOGE("Failed to clean gid on log table, %d.", errCode);
1752     }
1753     return errCode;
1754 }
1755 
ChangeCloudDataFlagOnLogTable(const std::string & logTableName)1756 int SQLiteSingleVerRelationalStorageExecutor::ChangeCloudDataFlagOnLogTable(const std::string &logTableName)
1757 {
1758     std::string cleanLogSql = "UPDATE " + logTableName + " SET " + CloudDbConstant::FLAG + " = " +
1759         SET_FLAG_LOCAL_AND_CLEAN_WAIT_COMPENSATED_SYNC + ", " + VERSION + " = '', " + DEVICE_FIELD + " = '', " +
1760         CLOUD_GID_FIELD + " = '', " + SHARING_RESOURCE + " = '' " + "WHERE NOT " + FLAG_IS_CLOUD_CONSISTENCY + ";";
1761     int errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, cleanLogSql);
1762     if (errCode != E_OK) {
1763         LOGE("change cloud log flag failed, %d", errCode);
1764     }
1765     return errCode;
1766 }
1767 
SetDataOnUserTableWithLogicDelete(const std::string & tableName,const std::string & logTableName)1768 int SQLiteSingleVerRelationalStorageExecutor::SetDataOnUserTableWithLogicDelete(const std::string &tableName,
1769     const std::string &logTableName)
1770 {
1771     UpdateCursorContext context;
1772     context.cursor = GetCursor(tableName);
1773     LOGI("removeData start and cursor is, %d.", context.cursor);
1774     int errCode = CreateFuncUpdateCursor(context, &UpdateCursor);
1775     std::string sql = "UPDATE '" + logTableName + "' SET " + CloudDbConstant::FLAG + " = " + SET_FLAG_LOGIC_DELETE +
1776                       ", " + VERSION + " = '', " + DEVICE_FIELD + " = '', " + CLOUD_GID_FIELD + " = '', " +
1777                       SHARING_RESOURCE + " = '', " + UPDATE_CURSOR_SQL +
1778                       " WHERE (CLOUD_GID IS NOT NULL AND CLOUD_GID != '' AND " + FLAG_IS_CLOUD_CONSISTENCY + ");";
1779     errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, sql);
1780     if (errCode != E_OK) {
1781         LOGE("Failed to change cloud data flag on usertable, %d.", errCode);
1782         CreateFuncUpdateCursor(context, nullptr);
1783         return errCode;
1784     }
1785     // deal when data is logicDelete
1786     sql = "UPDATE '" + logTableName + "' SET " + VERSION + " = '', " + DEVICE_FIELD + " = '', " + CLOUD_GID_FIELD +
1787           " = '', " + SHARING_RESOURCE + " = '' WHERE " + FLAG_IS_LOGIC_DELETE + ";";
1788     errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, sql);
1789     if (errCode != E_OK) {
1790         LOGE("Failed to deal logic delete data flag on usertable, %d.", errCode);
1791         CreateFuncUpdateCursor(context, nullptr);
1792         return errCode;
1793     }
1794     LOGI("removeData finish and cursor is %d.", context.cursor);
1795     errCode = SetCursor(tableName, context.cursor);
1796     if (errCode != E_OK) {
1797         CreateFuncUpdateCursor(context, nullptr);
1798         LOGE("set new cursor after removeData error %d.", errCode);
1799         return errCode;
1800     }
1801     errCode = CreateFuncUpdateCursor(context, nullptr);
1802     if (errCode != E_OK) {
1803         LOGE("Clear FuncUpdateCursor error %d.", errCode);
1804     }
1805     return ChangeCloudDataFlagOnLogTable(logTableName);
1806 }
1807 
GetCleanCloudDataKeys(const std::string & logTableName,std::vector<int64_t> & dataKeys,bool distinguishCloudFlag)1808 int SQLiteSingleVerRelationalStorageExecutor::GetCleanCloudDataKeys(const std::string &logTableName,
1809     std::vector<int64_t> &dataKeys, bool distinguishCloudFlag)
1810 {
1811     sqlite3_stmt *selectStmt = nullptr;
1812     std::string sql = "SELECT DATA_KEY FROM '" + logTableName + "' WHERE " + CLOUD_GID_FIELD +
1813         " IS NOT NULL AND " + CLOUD_GID_FIELD + " != '' AND data_key != '-1'";
1814     if (distinguishCloudFlag) {
1815         sql += " AND (";
1816         sql += FLAG_IS_CLOUD;
1817         sql += " OR ";
1818         sql +=  FLAG_IS_CLOUD_CONSISTENCY;
1819         sql += " ) ";
1820     }
1821     sql += ";";
1822     int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, selectStmt);
1823     if (errCode != E_OK) {
1824         LOGE("Get select data_key statement failed, %d", errCode);
1825         return errCode;
1826     }
1827     do {
1828         errCode = SQLiteUtils::StepWithRetry(selectStmt);
1829         if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1830             dataKeys.push_back(sqlite3_column_int64(selectStmt, 0));
1831         } else if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1832             LOGE("SQLite step failed when query log's data_key : %d", errCode);
1833             break;
1834         }
1835     } while (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW));
1836     SQLiteUtils::ResetStatement(selectStmt, true, errCode);
1837     return (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) ? E_OK : errCode;
1838 }
1839 
GetUpdateLogRecordStatement(const TableSchema & tableSchema,const VBucket & vBucket,OpType opType,std::vector<std::string> & updateColName,sqlite3_stmt * & updateLogStmt)1840 int SQLiteSingleVerRelationalStorageExecutor::GetUpdateLogRecordStatement(const TableSchema &tableSchema,
1841     const VBucket &vBucket, OpType opType, std::vector<std::string> &updateColName, sqlite3_stmt *&updateLogStmt)
1842 {
1843     std::string updateLogSql = "update " + DBCommon::GetLogTableName(tableSchema.name) + " set ";
1844     if (opType == OpType::ONLY_UPDATE_GID) {
1845         updateLogSql += "cloud_gid = ?";
1846         updateColName.push_back(CloudDbConstant::GID_FIELD);
1847         CloudStorageUtils::AddUpdateColForShare(tableSchema, updateLogSql, updateColName);
1848     } else if (opType == OpType::SET_CLOUD_FORCE_PUSH_FLAG_ZERO) {
1849         updateLogSql += "flag = flag & " + std::to_string(SET_FLAG_ZERO_MASK); // clear 2th bit of flag
1850         CloudStorageUtils::AddUpdateColForShare(tableSchema, updateLogSql, updateColName);
1851     } else if (opType == OpType::SET_CLOUD_FORCE_PUSH_FLAG_ONE) {
1852         updateLogSql += "flag = flag | " + std::to_string(SET_FLAG_ONE_MASK); // set 2th bit of flag
1853         CloudStorageUtils::AddUpdateColForShare(tableSchema, updateLogSql, updateColName);
1854     }  else if (opType == OpType::UPDATE_TIMESTAMP) {
1855         updateLogSql += "device = 'cloud', flag = flag & " + std::to_string(SET_CLOUD_FLAG) +
1856             ", timestamp = ?, cloud_gid = '', version = '', sharing_resource = ''";
1857         updateColName.push_back(CloudDbConstant::MODIFY_FIELD);
1858     } else if (opType == OpType::CLEAR_GID) {
1859         updateLogSql += "cloud_gid = '', version = '', sharing_resource = '', flag = flag & " +
1860             std::to_string(SET_FLAG_ZERO_MASK);
1861     } else if (opType == OpType::LOCKED_NOT_HANDLE) {
1862         updateLogSql += std::string(CloudDbConstant::TO_LOCAL_CHANGE) + ", cloud_gid = ?";
1863         updateColName.push_back(CloudDbConstant::GID_FIELD);
1864     } else {
1865         updateLogSql += " device = 'cloud', timestamp = ?,";
1866         updateColName.push_back(CloudDbConstant::MODIFY_FIELD);
1867         if (opType == OpType::DELETE) {
1868             updateLogSql += GetCloudDeleteSql(tableSchema.name);
1869         } else {
1870             updateLogSql += GetUpdateDataFlagSql() + ", cloud_gid = ?";
1871             updateColName.push_back(CloudDbConstant::GID_FIELD);
1872             CloudStorageUtils::AddUpdateColForShare(tableSchema, updateLogSql, updateColName);
1873         }
1874     }
1875 
1876     int errCode = AppendUpdateLogRecordWhereSqlCondition(tableSchema, vBucket, updateLogSql);
1877     if (errCode != E_OK) {
1878         return errCode;
1879     }
1880 
1881     errCode = SQLiteUtils::GetStatement(dbHandle_, updateLogSql, updateLogStmt);
1882     if (errCode != E_OK) {
1883         LOGE("Get update log statement failed when update cloud data, %d", errCode);
1884     }
1885     return errCode;
1886 }
1887 } // namespace DistributedDB
1888 #endif
1889