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 ×tamp)
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