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_relational_storage_engine.h"
17 
18 #include "db_common.h"
19 #include "db_errno.h"
20 #include "res_finalizer.h"
21 #include "sqlite_relational_database_upgrader.h"
22 #include "sqlite_single_ver_relational_storage_executor.h"
23 #include "sqlite_relational_utils.h"
24 
25 
26 namespace DistributedDB {
SQLiteSingleRelationalStorageEngine(RelationalDBProperties properties)27 SQLiteSingleRelationalStorageEngine::SQLiteSingleRelationalStorageEngine(RelationalDBProperties properties)
28     : properties_(properties)
29 {}
30 
~SQLiteSingleRelationalStorageEngine()31 SQLiteSingleRelationalStorageEngine::~SQLiteSingleRelationalStorageEngine()
32 {}
33 
NewSQLiteStorageExecutor(sqlite3 * dbHandle,bool isWrite,bool isMemDb)34 StorageExecutor *SQLiteSingleRelationalStorageEngine::NewSQLiteStorageExecutor(sqlite3 *dbHandle, bool isWrite,
35     bool isMemDb)
36 {
37     auto mode = static_cast<DistributedTableMode>(properties_.GetIntProp(RelationalDBProperties::DISTRIBUTED_TABLE_MODE,
38         DistributedTableMode::SPLIT_BY_DEVICE));
39     return new (std::nothrow) SQLiteSingleVerRelationalStorageExecutor(dbHandle, isWrite, mode);
40 }
41 
Upgrade(sqlite3 * db)42 int SQLiteSingleRelationalStorageEngine::Upgrade(sqlite3 *db)
43 {
44     int errCode = CreateRelationalMetaTable(db);
45     if (errCode != E_OK) {
46         LOGE("Create relational store meta table failed. err=%d", errCode);
47         return errCode;
48     }
49     LOGD("[RelationalEngine][Upgrade] upgrade relational store.");
50     auto upgrader = std::make_unique<SqliteRelationalDatabaseUpgrader>(db);
51     return upgrader->Upgrade();
52 }
53 
RegisterFunction(sqlite3 * db) const54 int SQLiteSingleRelationalStorageEngine::RegisterFunction(sqlite3 *db) const
55 {
56     int errCode = SQLiteUtils::RegisterCalcHash(db);
57     if (errCode != E_OK) {
58         LOGE("[engine] register calculate hash failed!");
59         return errCode;
60     }
61 
62     errCode = SQLiteUtils::RegisterGetLastTime(db);
63     if (errCode != E_OK) {
64         LOGE("[engine] register get last time failed!");
65         return errCode;
66     }
67 
68     errCode = SQLiteUtils::RegisterGetSysTime(db);
69     if (errCode != E_OK) {
70         LOGE("[engine] register get sys time failed!");
71         return errCode;
72     }
73 
74     errCode = SQLiteUtils::RegisterGetRawSysTime(db);
75     if (errCode != E_OK) {
76         LOGE("[engine] register get raw sys time failed!");
77         return errCode;
78     }
79 
80     errCode = SQLiteUtils::RegisterCloudDataChangeObserver(db);
81     if (errCode != E_OK) {
82         LOGE("[engine] register cloud observer failed!");
83     }
84 
85     errCode = SQLiteUtils::RegisterCloudDataChangeServerObserver(db);
86     if (errCode != E_OK) {
87         LOGE("[engine] register cloud server observer failed!");
88     }
89 
90     return errCode;
91 }
92 
CreateNewExecutor(bool isWrite,StorageExecutor * & handle)93 int SQLiteSingleRelationalStorageEngine::CreateNewExecutor(bool isWrite, StorageExecutor *&handle)
94 {
95     sqlite3 *db = nullptr;
96     int errCode = SQLiteUtils::OpenDatabase(option_, db, false);
97     if (errCode != E_OK) {
98         return errCode;
99     }
100     do {
101         errCode = Upgrade(db); // create meta_data table.
102         if (errCode != E_OK) {
103             break;
104         }
105 
106         errCode = RegisterFunction(db);
107         if (errCode != E_OK) {
108             break;
109         }
110 
111         handle = NewSQLiteStorageExecutor(db, isWrite, false);
112         if (handle == nullptr) {
113             LOGE("[Relational] New SQLiteStorageExecutor[%d] for the pool failed.", isWrite);
114             errCode = -E_OUT_OF_MEMORY;
115             break;
116         }
117         return E_OK;
118     } while (false);
119 
120     (void)sqlite3_close_v2(db);
121     db = nullptr;
122     return errCode;
123 }
124 
ReleaseExecutor(SQLiteSingleVerRelationalStorageExecutor * & handle,bool isExternal)125 void SQLiteSingleRelationalStorageEngine::ReleaseExecutor(SQLiteSingleVerRelationalStorageExecutor *&handle,
126     bool isExternal)
127 {
128     if (handle == nullptr) {
129         return;
130     }
131     StorageExecutor *databaseHandle = handle;
132     Recycle(databaseHandle, isExternal);
133     handle = nullptr;
134 }
135 
SetSchema(const RelationalSchemaObject & schema)136 void SQLiteSingleRelationalStorageEngine::SetSchema(const RelationalSchemaObject &schema)
137 {
138     std::lock_guard lock(schemaMutex_);
139     schema_ = schema;
140 }
141 
GetSchema() const142 RelationalSchemaObject SQLiteSingleRelationalStorageEngine::GetSchema() const
143 {
144     std::lock_guard lock(schemaMutex_);
145     return schema_;
146 }
147 
148 namespace {
149 const std::string DEVICE_TYPE = "device";
150 const std::string CLOUD_TYPE = "cloud";
151 const std::string SYNC_TABLE_TYPE = "sync_table_type_";
152 
SaveSchemaToMetaTable(SQLiteSingleVerRelationalStorageExecutor * handle,const RelationalSchemaObject & schema)153 int SaveSchemaToMetaTable(SQLiteSingleVerRelationalStorageExecutor *handle, const RelationalSchemaObject &schema)
154 {
155     const Key schemaKey(DBConstant::RELATIONAL_SCHEMA_KEY.begin(), DBConstant::RELATIONAL_SCHEMA_KEY.end());
156     Value schemaVal;
157     DBCommon::StringToVector(schema.ToSchemaString(), schemaVal);
158     int errCode = handle->PutKvData(schemaKey, schemaVal); // save schema to meta_data
159     if (errCode != E_OK) {
160         LOGE("Save schema to meta table failed. %d", errCode);
161     }
162     return errCode;
163 }
164 
SaveTrackerSchemaToMetaTable(SQLiteSingleVerRelationalStorageExecutor * handle,const RelationalSchemaObject & schema)165 int SaveTrackerSchemaToMetaTable(SQLiteSingleVerRelationalStorageExecutor *handle,
166     const RelationalSchemaObject &schema)
167 {
168     const Key schemaKey(DBConstant::RELATIONAL_TRACKER_SCHEMA_KEY.begin(),
169         DBConstant::RELATIONAL_TRACKER_SCHEMA_KEY.end());
170     Value schemaVal;
171     DBCommon::StringToVector(schema.ToSchemaString(), schemaVal);
172     int errCode = handle->PutKvData(schemaKey, schemaVal); // save schema to meta_data
173     if (errCode != E_OK) {
174         LOGE("Save schema to meta table failed. %d", errCode);
175     }
176     return errCode;
177 }
178 
SaveSyncTableTypeAndDropFlagToMeta(SQLiteSingleVerRelationalStorageExecutor * handle,const std::string & tableName,TableSyncType syncType)179 int SaveSyncTableTypeAndDropFlagToMeta(SQLiteSingleVerRelationalStorageExecutor *handle, const std::string &tableName,
180     TableSyncType syncType)
181 {
182     Key key;
183     DBCommon::StringToVector(SYNC_TABLE_TYPE + tableName, key);
184     Value value;
185     DBCommon::StringToVector(syncType == DEVICE_COOPERATION ? DEVICE_TYPE : CLOUD_TYPE, value);
186     int errCode = handle->PutKvData(key, value);
187     if (errCode != E_OK) {
188         LOGE("Save sync table type to meta table failed. %d", errCode);
189         return errCode;
190     }
191     DBCommon::StringToVector(DBConstant::TABLE_IS_DROPPED + tableName, key);
192     errCode = handle->DeleteMetaData({ key });
193     if (errCode != E_OK) {
194         LOGE("Save table drop flag to meta table failed. %d", errCode);
195         return errCode;
196     }
197     return handle->InitCursorToMeta(tableName);
198 }
199 }
200 
CreateDistributedTable(const std::string & tableName,const std::string & identity,bool & schemaChanged,TableSyncType syncType,bool trackerSchemaChanged)201 int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(const std::string &tableName,
202     const std::string &identity, bool &schemaChanged, TableSyncType syncType, bool trackerSchemaChanged)
203 {
204     std::lock_guard<std::mutex> autoLock(createDistributedTableMutex_);
205     RelationalSchemaObject schema = GetSchema();
206     bool isUpgraded = false;
207     if (DBCommon::CaseInsensitiveCompare(schema.GetTable(tableName).GetTableName(), tableName)) {
208         LOGI("distributed table bas been created.");
209         if (schema.GetTable(tableName).GetTableSyncType() != syncType) {
210             LOGE("table sync type mismatch.");
211             return -E_TYPE_MISMATCH;
212         }
213         isUpgraded = true;
214         int errCode = UpgradeDistributedTable(tableName, schemaChanged, syncType);
215         if (errCode != E_OK) {
216             LOGE("Upgrade distributed table failed. %d", errCode);
217             return errCode;
218         }
219         // Triggers may need to be rebuilt, no return directly
220     } else if (schema.GetTables().size() >= DBConstant::MAX_DISTRIBUTED_TABLE_COUNT) {
221         LOGE("The number of distributed tables is exceeds limit.");
222         return -E_MAX_LIMITS;
223     } else {
224         schemaChanged = true;
225     }
226 
227     int errCode = CreateDistributedTable(tableName, isUpgraded, identity, schema, syncType);
228     if (errCode != E_OK) {
229         LOGE("CreateDistributedTable failed. %d", errCode);
230         return errCode;
231     }
232     if (isUpgraded && (schemaChanged || trackerSchemaChanged)) {
233         // Used for upgrading the stock data of the trackerTable
234         errCode = GenLogInfoForUpgrade(tableName, schema, schemaChanged);
235     }
236     return errCode;
237 }
238 
CreateDistributedSharedTable(SQLiteSingleVerRelationalStorageExecutor * & handle,const std::string & tableName,const std::string & sharedTableName,TableSyncType tableSyncType,RelationalSchemaObject & schema)239 int SQLiteSingleRelationalStorageEngine::CreateDistributedSharedTable(SQLiteSingleVerRelationalStorageExecutor *&handle,
240     const std::string &tableName, const std::string &sharedTableName, TableSyncType tableSyncType,
241     RelationalSchemaObject &schema)
242 {
243     TableInfo table;
244     table.SetTableName(sharedTableName);
245     table.SetOriginTableName(tableName);
246     table.SetSharedTableMark(true);
247     table.SetTableSyncType(tableSyncType);
248     table.SetTrackerTable(trackerSchema_.GetTrackerTable(sharedTableName));
249     if (!table.GetTrackerTable().IsEmpty() && tableSyncType == TableSyncType::DEVICE_COOPERATION) { // LCOV_EXCL_BR_LINE
250         LOGE("current is trackerTable, not support creating device distributed table.");
251         return -E_NOT_SUPPORT;
252     }
253     bool isUpgraded = schema.GetTable(sharedTableName).GetTableName() == sharedTableName;
254     int errCode = CreateDistributedTable(handle, isUpgraded, "", table, schema);
255     if (errCode != E_OK) {
256         LOGE("create distributed table failed. %d", errCode);
257         return errCode;
258     }
259     std::lock_guard lock(schemaMutex_);
260     schema_ = schema;
261     return errCode;
262 }
263 
CreateDistributedTable(const std::string & tableName,bool isUpgraded,const std::string & identity,RelationalSchemaObject & schema,TableSyncType tableSyncType)264 int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(const std::string &tableName, bool isUpgraded,
265     const std::string &identity, RelationalSchemaObject &schema, TableSyncType tableSyncType)
266 {
267     LOGD("Create distributed table.");
268     int errCode = E_OK;
269     auto *handle = static_cast<SQLiteSingleVerRelationalStorageExecutor *>(FindExecutor(true, OperatePerm::NORMAL_PERM,
270         errCode));
271     if (handle == nullptr) {
272         return errCode;
273     }
274     ResFinalizer finalizer([&handle, this] { this->ReleaseExecutor(handle); });
275 
276     errCode = handle->StartTransaction(TransactType::IMMEDIATE);
277     if (errCode != E_OK) {
278         return errCode;
279     }
280 
281     TableInfo table;
282     table.SetTableName(tableName);
283     table.SetTableSyncType(tableSyncType);
284     table.SetTrackerTable(GetTrackerSchema().GetTrackerTable(tableName));
285     if (isUpgraded) {
286         table.SetSourceTableReference(schema.GetTable(tableName).GetTableReference());
287     }
288     if (!table.GetTrackerTable().IsEmpty() && tableSyncType == TableSyncType::DEVICE_COOPERATION) {
289         LOGE("current is trackerTable, not support creating device distributed table. %d", errCode);
290         (void)handle->Rollback();
291         return -E_NOT_SUPPORT;
292     }
293     errCode = CreateDistributedTable(handle, isUpgraded, identity, table, schema);
294     if (errCode != E_OK) {
295         LOGE("create distributed table failed. %d", errCode);
296         (void)handle->Rollback();
297         return errCode;
298     }
299     errCode = handle->Commit();
300     if (errCode == E_OK) {
301         SetSchema(schema);
302     }
303     return errCode;
304 }
305 
CreateDistributedTable(SQLiteSingleVerRelationalStorageExecutor * & handle,bool isUpgraded,const std::string & identity,TableInfo & table,RelationalSchemaObject & schema)306 int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(SQLiteSingleVerRelationalStorageExecutor *&handle,
307     bool isUpgraded, const std::string &identity, TableInfo &table, RelationalSchemaObject &schema)
308 {
309     auto mode = static_cast<DistributedTableMode>(properties_.GetIntProp(
310         RelationalDBProperties::DISTRIBUTED_TABLE_MODE, DistributedTableMode::SPLIT_BY_DEVICE));
311     TableSyncType tableSyncType = table.GetTableSyncType();
312     int errCode = handle->CreateDistributedTable(mode, isUpgraded, identity, table, tableSyncType);
313     if (errCode != E_OK) {
314         LOGE("create distributed table failed. %d", errCode);
315         return errCode;
316     }
317 
318     schema.SetTableMode(mode);
319     std::string tableName = table.GetTableName();
320     // update table if tableName changed
321     schema.RemoveRelationalTable(tableName);
322     schema.AddRelationalTable(table);
323     errCode = SaveSchemaToMetaTable(handle, schema);
324     if (errCode != E_OK) {
325         LOGE("Save schema to meta table for create distributed table failed. %d", errCode);
326         return errCode;
327     }
328 
329     errCode = SaveSyncTableTypeAndDropFlagToMeta(handle, tableName, tableSyncType);
330     if (errCode != E_OK) {
331         LOGE("Save sync table type or drop flag to meta table failed. %d", errCode);
332     }
333     return errCode;
334 }
335 
UpgradeDistributedTable(const std::string & tableName,bool & schemaChanged,TableSyncType syncType)336 int SQLiteSingleRelationalStorageEngine::UpgradeDistributedTable(const std::string &tableName, bool &schemaChanged,
337     TableSyncType syncType)
338 {
339     LOGD("Upgrade distributed table.");
340     RelationalSchemaObject schema = GetSchema();
341     int errCode = E_OK;
342     auto *handle = static_cast<SQLiteSingleVerRelationalStorageExecutor *>(FindExecutor(true, OperatePerm::NORMAL_PERM,
343         errCode));
344     if (handle == nullptr) {
345         return errCode;
346     }
347 
348     errCode = handle->StartTransaction(TransactType::IMMEDIATE);
349     if (errCode != E_OK) {
350         ReleaseExecutor(handle);
351         return errCode;
352     }
353 
354     auto mode = static_cast<DistributedTableMode>(properties_.GetIntProp(
355         RelationalDBProperties::DISTRIBUTED_TABLE_MODE, DistributedTableMode::SPLIT_BY_DEVICE));
356     errCode = handle->UpgradeDistributedTable(tableName, mode, schemaChanged, schema, syncType);
357     if (errCode != E_OK) {
358         LOGE("Upgrade distributed table failed. %d", errCode);
359         (void)handle->Rollback();
360         ReleaseExecutor(handle);
361         return errCode;
362     }
363 
364     errCode = SaveSchemaToMetaTable(handle, schema);
365         if (errCode != E_OK) {
366         LOGE("Save schema to meta table for upgrade distributed table failed. %d", errCode);
367         (void)handle->Rollback();
368         ReleaseExecutor(handle);
369         return errCode;
370     }
371 
372     errCode = handle->Commit();
373     if (errCode == E_OK) {
374         SetSchema(schema);
375     }
376     ReleaseExecutor(handle);
377     return errCode;
378 }
379 
CleanDistributedDeviceTable(std::vector<std::string> & missingTables)380 int SQLiteSingleRelationalStorageEngine::CleanDistributedDeviceTable(std::vector<std::string> &missingTables)
381 {
382     int errCode = E_OK;
383     auto handle = static_cast<SQLiteSingleVerRelationalStorageExecutor *>(FindExecutor(true, OperatePerm::NORMAL_PERM,
384         errCode));
385     if (handle == nullptr) {
386         return errCode;
387     }
388 
389     // go fast to check missing tables without transaction
390     errCode = handle->CheckAndCleanDistributedTable(schema_.GetTableNames(), missingTables);
391     if (errCode == E_OK) {
392         if (missingTables.empty()) {
393             LOGI("Check missing distributed table is empty.");
394             ReleaseExecutor(handle);
395             return errCode;
396         }
397     } else {
398         LOGE("Get missing distributed table failed. %d", errCode);
399         ReleaseExecutor(handle);
400         return errCode;
401     }
402     missingTables.clear();
403 
404     std::lock_guard lock(schemaMutex_);
405     errCode = handle->StartTransaction(TransactType::IMMEDIATE);
406     if (errCode != E_OK) {
407         ReleaseExecutor(handle);
408         return errCode;
409     }
410 
411     errCode = handle->CheckAndCleanDistributedTable(schema_.GetTableNames(), missingTables);
412     if (errCode == E_OK) {
413         // Remove non-existent tables from the schema
414         for (const auto &tableName : missingTables) {
415             schema_.RemoveRelationalTable(tableName);
416         }
417         errCode = SaveSchemaToMetaTable(handle, schema_); // save schema to meta_data
418         if (errCode != E_OK) {
419             LOGE("Save schema to metaTable failed. %d", errCode);
420             (void)handle->Rollback();
421         } else {
422             errCode = handle->Commit();
423         }
424     } else {
425         LOGE("Check distributed table failed. %d", errCode);
426         (void)handle->Rollback();
427     }
428     ReleaseExecutor(handle);
429     return errCode;
430 }
431 
GetProperties() const432 const RelationalDBProperties &SQLiteSingleRelationalStorageEngine::GetProperties() const
433 {
434     return properties_;
435 }
436 
SetProperties(const RelationalDBProperties & properties)437 void SQLiteSingleRelationalStorageEngine::SetProperties(const RelationalDBProperties &properties)
438 {
439     properties_ = properties;
440 }
441 
CreateRelationalMetaTable(sqlite3 * db)442 int SQLiteSingleRelationalStorageEngine::CreateRelationalMetaTable(sqlite3 *db)
443 {
444     std::string sql =
445         "CREATE TABLE IF NOT EXISTS " + DBConstant::RELATIONAL_PREFIX + "metadata(" \
446         "key    BLOB PRIMARY KEY NOT NULL," \
447         "value  BLOB);";
448     int errCode = SQLiteUtils::ExecuteRawSQL(db, sql);
449     if (errCode != E_OK) {
450         LOGE("[SQLite] execute create table sql failed, err=%d", errCode);
451     }
452     return errCode;
453 }
454 
SetTrackerTable(const TrackerSchema & schema)455 int SQLiteSingleRelationalStorageEngine::SetTrackerTable(const TrackerSchema &schema)
456 {
457     int errCode = E_OK;
458     auto *handle = static_cast<SQLiteSingleVerRelationalStorageExecutor *>(FindExecutor(true, OperatePerm::NORMAL_PERM,
459         errCode));
460     if (handle == nullptr) {
461         return errCode;
462     }
463 
464     errCode = handle->StartTransaction(TransactType::IMMEDIATE);
465     if (errCode != E_OK) {
466         ReleaseExecutor(handle);
467         return errCode;
468     }
469     RelationalSchemaObject tracker = trackerSchema_;
470     if (!tracker.GetTrackerTable(schema.tableName).IsChanging(schema) && !schema.isForceUpgrade) {
471         (void)handle->Rollback();
472         ReleaseExecutor(handle);
473         LOGW("tracker schema is no change.");
474         return E_OK;
475     }
476     bool isUpgrade = !tracker.GetTrackerTable(schema.tableName).IsEmpty();
477     tracker.InsertTrackerSchema(schema);
478     int ret = handle->CreateTrackerTable(tracker.GetTrackerTable(schema.tableName), isUpgrade);
479     if (ret != E_OK && ret != -E_WITH_INVENTORY_DATA) {
480         (void)handle->Rollback();
481         ReleaseExecutor(handle);
482         return ret;
483     }
484 
485     if (schema.trackerColNames.empty()) {
486         tracker.RemoveTrackerSchema(schema);
487     }
488     errCode = SaveTrackerSchemaToMetaTable(handle, tracker);
489     if (errCode != E_OK) {
490         (void)handle->Rollback();
491         ReleaseExecutor(handle);
492         return errCode;
493     }
494 
495     errCode = handle->Commit();
496     if (errCode != E_OK) {
497         ReleaseExecutor(handle);
498         return errCode;
499     }
500 
501     trackerSchema_ = tracker;
502     ReleaseExecutor(handle);
503     return ret;
504 }
505 
CheckAndCacheTrackerSchema(const TrackerSchema & schema,TableInfo & tableInfo,bool & isFirstCreate)506 int SQLiteSingleRelationalStorageEngine::CheckAndCacheTrackerSchema(const TrackerSchema &schema, TableInfo &tableInfo,
507     bool &isFirstCreate)
508 {
509     if (tableInfo.GetTableSyncType() == TableSyncType::DEVICE_COOPERATION) {
510         return -E_NOT_SUPPORT;
511     }
512     int errCode = E_OK;
513     auto *handle = static_cast<SQLiteSingleVerRelationalStorageExecutor *>(FindExecutor(true,
514         OperatePerm::NORMAL_PERM, errCode));
515     if (handle == nullptr) {
516         return errCode;
517     }
518     RelationalSchemaObject tracker = trackerSchema_;
519     if (!tracker.GetTrackerTable(schema.tableName).IsChanging(schema) && !schema.isForceUpgrade) { // LCOV_EXCL_BR_LINE
520         ReleaseExecutor(handle);
521         LOGW("tracker schema is no change for distributed table.");
522         return -E_IGNORE_DATA;
523     }
524     isFirstCreate = tracker.GetTrackerTable(schema.tableName).IsEmpty();
525     tracker.InsertTrackerSchema(schema);
526     tableInfo.SetTrackerTable(tracker.GetTrackerTable(schema.tableName));
527     errCode = tableInfo.CheckTrackerTable();
528     if (errCode != E_OK) {
529         LOGE("check tracker table schema failed. %d", errCode);
530         ReleaseExecutor(handle);
531         return errCode;
532     }
533 
534     if (schema.trackerColNames.empty()) {
535         tracker.RemoveTrackerSchema(schema);
536     }
537 
538     trackerSchema_ = tracker;
539     ReleaseExecutor(handle);
540     return errCode;
541 }
542 
GetOrInitTrackerSchemaFromMeta()543 int SQLiteSingleRelationalStorageEngine::GetOrInitTrackerSchemaFromMeta()
544 {
545     RelationalSchemaObject trackerSchema;
546     int errCode = E_OK;
547     auto *handle = static_cast<SQLiteSingleVerRelationalStorageExecutor *>(FindExecutor(true, OperatePerm::NORMAL_PERM,
548         errCode));
549     if (handle == nullptr) {
550         return errCode;
551     }
552     errCode = handle->GetOrInitTrackerSchemaFromMeta(trackerSchema);
553     if (errCode != E_OK) {
554         ReleaseExecutor(handle);
555         return errCode;
556     }
557     const TableInfoMap tableInfoMap = trackerSchema.GetTrackerTables();
558     for (const auto &iter: tableInfoMap) {
559         TableInfo tableInfo;
560         errCode = handle->AnalysisTrackerTable(iter.second.GetTrackerTable(), tableInfo);
561         if (errCode == -E_NOT_FOUND) { // LCOV_EXCL_BR_LINE
562             const std::string trackerTableName = iter.second.GetTrackerTable().GetTableName();
563             errCode = CleanTrackerDeviceTable({ trackerTableName }, trackerSchema, handle);
564             if (errCode != E_OK) {
565                 LOGE("cancel tracker table failed during db opening. %d", errCode);
566                 ReleaseExecutor(handle);
567                 return errCode;
568             }
569         } else if (errCode != E_OK) { // LCOV_EXCL_BR_LINE
570             LOGE("the tracker schema does not match the tracker schema. %d", errCode);
571             ReleaseExecutor(handle);
572             return errCode;
573         }
574     }
575     trackerSchema_ = trackerSchema;
576     ReleaseExecutor(handle);
577     return E_OK;
578 }
579 
SaveTrackerSchema(const std::string & tableName,bool isFirstCreate)580 int SQLiteSingleRelationalStorageEngine::SaveTrackerSchema(const std::string &tableName, bool isFirstCreate)
581 {
582     int errCode = E_OK;
583     auto *handle = static_cast<SQLiteSingleVerRelationalStorageExecutor *>(FindExecutor(true, OperatePerm::NORMAL_PERM,
584         errCode));
585     if (handle == nullptr) {
586         return errCode;
587     }
588     RelationalSchemaObject tracker = trackerSchema_;
589     errCode = SaveTrackerSchemaToMetaTable(handle, tracker);
590     if (errCode != E_OK || !isFirstCreate) {
591         ReleaseExecutor(handle);
592         return errCode;
593     }
594     errCode = handle->CheckInventoryData(DBCommon::GetLogTableName(tableName));
595     ReleaseExecutor(handle);
596     return errCode;
597 }
598 
ExecuteSql(const SqlCondition & condition,std::vector<VBucket> & records)599 int SQLiteSingleRelationalStorageEngine::ExecuteSql(const SqlCondition &condition, std::vector<VBucket> &records)
600 {
601     int errCode = E_OK;
602     auto *handle = static_cast<SQLiteSingleVerRelationalStorageExecutor *>(FindExecutor(!condition.readOnly,
603         OperatePerm::NORMAL_PERM, errCode, true));
604     if (handle == nullptr) {
605         return errCode;
606     }
607     errCode = handle->ExecuteSql(condition, records);
608     ReleaseExecutor(handle, true);
609     return errCode;
610 }
611 
CheckReference(const std::vector<TableReferenceProperty> & tableReferenceProperty,const RelationalSchemaObject & schema)612 static int CheckReference(const std::vector<TableReferenceProperty> &tableReferenceProperty,
613     const RelationalSchemaObject &schema)
614 {
615     for (const auto &reference : tableReferenceProperty) {
616         TableInfo sourceTableInfo = schema.GetTable(reference.sourceTableName);
617         TableInfo targetTableInfo = schema.GetTable(reference.targetTableName);
618         if (strcasecmp(sourceTableInfo.GetTableName().c_str(), reference.sourceTableName.c_str()) != 0 ||
619             strcasecmp(targetTableInfo.GetTableName().c_str(), reference.targetTableName.c_str()) != 0) {
620             LOGE("can't set reference for table which doesn't create distributed table.");
621             return -E_DISTRIBUTED_SCHEMA_NOT_FOUND;
622         }
623         if (sourceTableInfo.GetTableSyncType() != CLOUD_COOPERATION ||
624             targetTableInfo.GetTableSyncType() != CLOUD_COOPERATION) {
625             LOGE("can't set reference for table which doesn't create distributed table with cloud mode.");
626             return -E_DISTRIBUTED_SCHEMA_NOT_FOUND;
627         }
628         if (sourceTableInfo.GetSharedTableMark() || targetTableInfo.GetSharedTableMark()) {
629             LOGE("can't set reference for shared table.");
630             return -E_NOT_SUPPORT;
631         }
632 
633         FieldInfoMap sourceFieldMap = sourceTableInfo.GetFields();
634         FieldInfoMap targetFieldMap = targetTableInfo.GetFields();
635         for (const auto &[sourceFieldName, targetFieldName] : reference.columns) {
636             if (sourceFieldMap.find(sourceFieldName) == sourceFieldMap.end() ||
637                 targetFieldMap.find(targetFieldName) == targetFieldMap.end()) {
638                 LOGE("reference field doesn't exists in table.");
639                 return -E_INVALID_ARGS;
640             }
641         }
642     }
643     return E_OK;
644 }
645 
SetReference(const std::vector<TableReferenceProperty> & tableReferenceProperty,SQLiteSingleVerRelationalStorageExecutor * handle,std::set<std::string> & clearWaterMarkTables,RelationalSchemaObject & schema)646 int SQLiteSingleRelationalStorageEngine::SetReference(const std::vector<TableReferenceProperty> &tableReferenceProperty,
647     SQLiteSingleVerRelationalStorageExecutor *handle, std::set<std::string> &clearWaterMarkTables,
648     RelationalSchemaObject &schema)
649 {
650     std::lock_guard lock(schemaMutex_);
651     schema = schema_;
652     int errCode = CheckReference(tableReferenceProperty, schema);
653     if (errCode != E_OK) {
654         LOGE("check reference failed, errCode = %d.", errCode);
655         return errCode;
656     }
657 
658     errCode = handle->GetClearWaterMarkTables(tableReferenceProperty, schema, clearWaterMarkTables);
659     if (errCode != E_OK) {
660         return errCode;
661     }
662     schema.SetReferenceProperty(tableReferenceProperty);
663     errCode = SaveSchemaToMetaTable(handle, schema);
664     if (errCode != E_OK) {
665         LOGE("Save schema to meta table for reference failed. %d", errCode);
666         return errCode;
667     }
668     auto mode = static_cast<DistributedTableMode>(properties_.GetIntProp(
669         RelationalDBProperties::DISTRIBUTED_TABLE_MODE, DistributedTableMode::SPLIT_BY_DEVICE));
670     for (auto &table : schema.GetTables()) {
671         if (table.second.GetTableSyncType() == TableSyncType::DEVICE_COOPERATION) {
672             continue;
673         }
674         TableInfo tableInfo = table.second;
675         errCode = handle->RenewTableTrigger(mode, tableInfo, TableSyncType::CLOUD_COOPERATION);
676         if (errCode != E_OK) {
677             LOGE("renew table trigger for reference failed. %d", errCode);
678             return errCode;
679         }
680     }
681     return clearWaterMarkTables.empty() ? E_OK : -E_TABLE_REFERENCE_CHANGED;
682 }
683 
GetTrackerSchema() const684 RelationalSchemaObject SQLiteSingleRelationalStorageEngine::GetTrackerSchema() const
685 {
686     return trackerSchema_;
687 }
688 
CleanTrackerData(const std::string & tableName,int64_t cursor)689 int SQLiteSingleRelationalStorageEngine::CleanTrackerData(const std::string &tableName, int64_t cursor)
690 {
691     int errCode = E_OK;
692     auto *handle = static_cast<SQLiteSingleVerRelationalStorageExecutor *>(FindExecutor(true, OperatePerm::NORMAL_PERM,
693         errCode));
694     if (handle == nullptr) { // LCOV_EXCL_BR_LINE
695         return errCode;
696     }
697     TrackerTable trackerTable = GetTrackerSchema().GetTrackerTable(tableName);
698     bool isOnlyTrackTable = false;
699     RelationalSchemaObject schema = GetSchema();
700     if (!trackerTable.IsTableNameEmpty() &&
701         !DBCommon::CaseInsensitiveCompare(schema.GetTable(tableName).GetTableName(), tableName)) {
702         isOnlyTrackTable = true;
703     }
704     errCode = handle->CleanTrackerData(tableName, cursor, isOnlyTrackTable);
705     ReleaseExecutor(handle);
706     return errCode;
707 }
708 
UpgradeSharedTable(const DataBaseSchema & cloudSchema,const std::vector<std::string> & deleteTableNames,const std::map<std::string,std::vector<Field>> & updateTableNames,const std::map<std::string,std::string> & alterTableNames)709 int SQLiteSingleRelationalStorageEngine::UpgradeSharedTable(const DataBaseSchema &cloudSchema,
710     const std::vector<std::string> &deleteTableNames, const std::map<std::string, std::vector<Field>> &updateTableNames,
711     const std::map<std::string, std::string> &alterTableNames)
712 {
713     int errCode = E_OK;
714     auto *handle = static_cast<SQLiteSingleVerRelationalStorageExecutor *>(FindExecutor(true, OperatePerm::NORMAL_PERM,
715         errCode));
716     if (handle == nullptr) {
717         return errCode;
718     }
719     errCode = handle->StartTransaction(TransactType::IMMEDIATE);
720     if (errCode != E_OK) {
721         ReleaseExecutor(handle);
722         return errCode;
723     }
724     RelationalSchemaObject schema = GetSchema();
725     errCode = UpgradeSharedTableInner(handle, cloudSchema, deleteTableNames, updateTableNames, alterTableNames);
726     if (errCode != E_OK) {
727         handle->Rollback();
728         ReleaseExecutor(handle);
729         return errCode;
730     }
731     errCode = handle->Commit();
732     if (errCode != E_OK) {
733         std::lock_guard lock(schemaMutex_);
734         schema_ = schema; // revert schema to the initial state
735     }
736     ReleaseExecutor(handle);
737     return errCode;
738 }
739 
UpgradeSharedTableInner(SQLiteSingleVerRelationalStorageExecutor * & handle,const DataBaseSchema & cloudSchema,const std::vector<std::string> & deleteTableNames,const std::map<std::string,std::vector<Field>> & updateTableNames,const std::map<std::string,std::string> & alterTableNames)740 int SQLiteSingleRelationalStorageEngine::UpgradeSharedTableInner(SQLiteSingleVerRelationalStorageExecutor *&handle,
741     const DataBaseSchema &cloudSchema, const std::vector<std::string> &deleteTableNames,
742     const std::map<std::string, std::vector<Field>> &updateTableNames,
743     const std::map<std::string, std::string> &alterTableNames)
744 {
745     RelationalSchemaObject schema = GetSchema();
746     int errCode = DoDeleteSharedTable(handle, deleteTableNames, schema);
747     if (errCode != E_OK) {
748         LOGE("[RelationalStorageEngine] delete shared table or distributed table failed. %d", errCode);
749         return errCode;
750     }
751     errCode = DoUpdateSharedTable(handle, updateTableNames, cloudSchema, schema);
752     if (errCode != E_OK) {
753         LOGE("[RelationalStorageEngine] update shared table or distributed table failed. %d", errCode);
754         return errCode;
755     }
756     errCode = CheckIfExistUserTable(handle, cloudSchema, alterTableNames, schema);
757     if (errCode != E_OK) {
758         LOGE("[RelationalStorageEngine] check local user table failed. %d", errCode);
759         return errCode;
760     }
761     errCode = DoAlterSharedTableName(handle, alterTableNames, schema);
762     if (errCode != E_OK) {
763         LOGE("[RelationalStorageEngine] alter shared table or distributed table failed. %d", errCode);
764         return errCode;
765     }
766     errCode = DoCreateSharedTable(handle, cloudSchema, updateTableNames, alterTableNames, schema);
767     if (errCode != E_OK) {
768         LOGE("[RelationalStorageEngine] create shared table or distributed table failed. %d", errCode);
769         return errCode;
770     }
771     std::lock_guard lock(schemaMutex_);
772     schema_ = schema;
773     return E_OK;
774 }
775 
DoDeleteSharedTable(SQLiteSingleVerRelationalStorageExecutor * & handle,const std::vector<std::string> & deleteTableNames,RelationalSchemaObject & schema)776 int SQLiteSingleRelationalStorageEngine::DoDeleteSharedTable(SQLiteSingleVerRelationalStorageExecutor *&handle,
777     const std::vector<std::string> &deleteTableNames, RelationalSchemaObject &schema)
778 {
779     if (deleteTableNames.empty()) {
780         return E_OK;
781     }
782     int errCode = handle->DeleteTable(deleteTableNames);
783     if (errCode != E_OK) {
784         LOGE("[RelationalStorageEngine] delete shared table failed. %d", errCode);
785         return errCode;
786     }
787     std::vector<Key> keys;
788     for (const auto &tableName : deleteTableNames) {
789         errCode = handle->CleanResourceForDroppedTable(tableName);
790         if (errCode != E_OK) {
791             LOGE("[RelationalStorageEngine] delete shared distributed table failed. %d", errCode);
792             return errCode;
793         }
794         Key sharedTableKey = DBCommon::GetPrefixTableName(tableName);
795         if (sharedTableKey.empty() || sharedTableKey.size() > DBConstant::MAX_KEY_SIZE) {
796             LOGE("[RelationalStorageEngine] shared table key is invalid.");
797             return -E_INVALID_ARGS;
798         }
799         keys.push_back(sharedTableKey);
800         schema.RemoveRelationalTable(tableName);
801     }
802     errCode = handle->DeleteMetaData(keys);
803     if (errCode != E_OK) {
804         LOGE("[RelationalStorageEngine] delete meta data failed. %d", errCode);
805     }
806     return errCode;
807 }
808 
DoUpdateSharedTable(SQLiteSingleVerRelationalStorageExecutor * & handle,const std::map<std::string,std::vector<Field>> & updateTableNames,const DataBaseSchema & cloudSchema,RelationalSchemaObject & localSchema)809 int SQLiteSingleRelationalStorageEngine::DoUpdateSharedTable(SQLiteSingleVerRelationalStorageExecutor *&handle,
810     const std::map<std::string, std::vector<Field>> &updateTableNames, const DataBaseSchema &cloudSchema,
811     RelationalSchemaObject &localSchema)
812 {
813     if (updateTableNames.empty()) {
814         return E_OK;
815     }
816     int errCode = handle->UpdateSharedTable(updateTableNames);
817     if (errCode != E_OK) {
818         LOGE("[RelationalStorageEngine] update shared table failed. %d", errCode);
819         return errCode;
820     }
821     for (const auto &tableSchema : cloudSchema.tables) {
822         if (updateTableNames.find(tableSchema.sharedTableName) != updateTableNames.end()) {
823             errCode = CreateDistributedSharedTable(handle, tableSchema.name, tableSchema.sharedTableName,
824                 TableSyncType::CLOUD_COOPERATION, localSchema);
825             if (errCode != E_OK) {
826                 LOGE("[RelationalStorageEngine] update shared distributed table failed. %d", errCode);
827                 return errCode;
828             }
829         }
830     }
831     return E_OK;
832 }
833 
DoAlterSharedTableName(SQLiteSingleVerRelationalStorageExecutor * & handle,const std::map<std::string,std::string> & alterTableNames,RelationalSchemaObject & schema)834 int SQLiteSingleRelationalStorageEngine::DoAlterSharedTableName(SQLiteSingleVerRelationalStorageExecutor *&handle,
835     const std::map<std::string, std::string> &alterTableNames, RelationalSchemaObject &schema)
836 {
837     if (alterTableNames.empty()) {
838         return E_OK;
839     }
840     int errCode = handle->AlterTableName(alterTableNames);
841     if (errCode != E_OK) {
842         LOGE("[RelationalStorageEngine] alter shared table failed. %d", errCode);
843         return errCode;
844     }
845     std::map<std::string, std::string> distributedSharedTableNames;
846     for (const auto &tableName : alterTableNames) {
847         errCode = handle->DeleteTableTrigger(tableName.first);
848         if (errCode != E_OK) {
849             LOGE("[RelationalStorageEngine] delete shared table trigger failed. %d", errCode);
850             return errCode;
851         }
852         std::string oldDistributedName = DBCommon::GetLogTableName(tableName.first);
853         std::string newDistributedName = DBCommon::GetLogTableName(tableName.second);
854         distributedSharedTableNames[oldDistributedName] = newDistributedName;
855     }
856     errCode = handle->AlterTableName(distributedSharedTableNames);
857     if (errCode != E_OK) {
858         LOGE("[RelationalStorageEngine] alter distributed shared table failed. %d", errCode);
859         return errCode;
860     }
861     for (const auto &[oldTableName, newTableName] : alterTableNames) {
862         TableInfo tableInfo = schema.GetTable(oldTableName);
863         tableInfo.SetTableName(newTableName);
864         schema.AddRelationalTable(tableInfo);
865         schema.RemoveRelationalTable(oldTableName);
866     }
867     errCode = UpdateKvData(handle, alterTableNames);
868     if (errCode != E_OK) {
869         LOGE("[RelationalStorageEngine] update kv data failed. %d", errCode);
870     }
871     return errCode;
872 }
873 
DoCreateSharedTable(SQLiteSingleVerRelationalStorageExecutor * & handle,const DataBaseSchema & cloudSchema,const std::map<std::string,std::vector<Field>> & updateTableNames,const std::map<std::string,std::string> & alterTableNames,RelationalSchemaObject & schema)874 int SQLiteSingleRelationalStorageEngine::DoCreateSharedTable(SQLiteSingleVerRelationalStorageExecutor *&handle,
875     const DataBaseSchema &cloudSchema, const std::map<std::string, std::vector<Field>> &updateTableNames,
876     const std::map<std::string, std::string> &alterTableNames, RelationalSchemaObject &schema)
877 {
878     for (auto const &tableSchema : cloudSchema.tables) {
879         if (tableSchema.sharedTableName.empty()) {
880             continue;
881         }
882         if (updateTableNames.find(tableSchema.sharedTableName) != updateTableNames.end()) {
883             continue;
884         }
885         bool isUpdated = false;
886         for (const auto &alterTableName : alterTableNames) {
887             if (alterTableName.second == tableSchema.sharedTableName) {
888                 isUpdated = true;
889                 break;
890             }
891         }
892         if (isUpdated) {
893             continue;
894         }
895         int errCode = handle->CreateSharedTable(tableSchema);
896         if (errCode != E_OK) {
897             return errCode;
898         }
899         errCode = CreateDistributedSharedTable(handle, tableSchema.name, tableSchema.sharedTableName,
900             TableSyncType::CLOUD_COOPERATION, schema);
901         if (errCode != E_OK) {
902             return errCode;
903         }
904     }
905     return E_OK;
906 }
907 
UpdateKvData(SQLiteSingleVerRelationalStorageExecutor * & handle,const std::map<std::string,std::string> & alterTableNames)908 int SQLiteSingleRelationalStorageEngine::UpdateKvData(SQLiteSingleVerRelationalStorageExecutor *&handle,
909     const std::map<std::string, std::string> &alterTableNames)
910 {
911     std::vector<Key> keys;
912     for (const auto &tableName : alterTableNames) {
913         Key oldKey = DBCommon::GetPrefixTableName(tableName.first);
914         Value value;
915         int ret = handle->GetKvData(oldKey, value);
916         if (ret == -E_NOT_FOUND) {
917             continue;
918         }
919         if (ret != E_OK) {
920             LOGE("[RelationalStorageEngine] get meta data failed. %d", ret);
921             return ret;
922         }
923         keys.push_back(oldKey);
924         Key newKey = DBCommon::GetPrefixTableName(tableName.second);
925         ret = handle->PutKvData(newKey, value);
926         if (ret != E_OK) {
927             LOGE("[RelationalStorageEngine] put meta data failed. %d", ret);
928             return ret;
929         }
930     }
931     int errCode = handle->DeleteMetaData(keys);
932     if (errCode != E_OK) {
933         LOGE("[RelationalStorageEngine] delete meta data failed. %d", errCode);
934     }
935     return errCode;
936 }
937 
CheckIfExistUserTable(SQLiteSingleVerRelationalStorageExecutor * & handle,const DataBaseSchema & cloudSchema,const std::map<std::string,std::string> & alterTableNames,const RelationalSchemaObject & schema)938 int SQLiteSingleRelationalStorageEngine::CheckIfExistUserTable(SQLiteSingleVerRelationalStorageExecutor *&handle,
939     const DataBaseSchema &cloudSchema, const std::map<std::string, std::string> &alterTableNames,
940     const RelationalSchemaObject &schema)
941 {
942     for (const auto &tableSchema : cloudSchema.tables) {
943         if (alterTableNames.find(tableSchema.sharedTableName) != alterTableNames.end()) {
944             continue;
945         }
946         TableInfo tableInfo = schema.GetTable(tableSchema.sharedTableName);
947         if (tableInfo.GetSharedTableMark()) {
948             continue;
949         }
950         int errCode = handle->CheckIfExistUserTable(tableSchema.sharedTableName);
951         if (errCode != E_OK) {
952             LOGE("[RelationalStorageEngine] local exists table. %d", errCode);
953             return errCode;
954         }
955     }
956     return E_OK;
957 }
958 
CalTableRef(const std::vector<std::string> & tableNames,const std::map<std::string,std::string> & sharedTableOriginNames)959 std::pair<std::vector<std::string>, int> SQLiteSingleRelationalStorageEngine::CalTableRef(
960     const std::vector<std::string> &tableNames, const std::map<std::string, std::string> &sharedTableOriginNames)
961 {
962     std::pair<std::vector<std::string>, int> res = { tableNames, E_OK };
963     std::map<std::string, std::map<std::string, bool>> reachableReference;
964     std::map<std::string, int> tableWeight;
965     {
966         std::lock_guard lock(schemaMutex_);
967         reachableReference = schema_.GetReachableRef();
968         tableWeight = schema_.GetTableWeight();
969     }
970     if (reachableReference.empty()) {
971         return res;
972     }
973     auto reachableWithShared = GetReachableWithShared(reachableReference, sharedTableOriginNames);
974     // check dependency conflict
975     for (size_t i = 0; i < tableNames.size(); ++i) {
976         for (size_t j = i + 1; j < tableNames.size(); ++j) {
977             // such as table A B, if dependency is A->B
978             // sync should not be A->B, it should be B->A
979             // so if A can reach B, it's wrong
980             if (reachableWithShared[tableNames[i]][tableNames[j]]) {
981                 LOGE("[RDBStorageEngine] table %zu reach table %zu", i, j);
982                 res.second = -E_INVALID_ARGS;
983                 return res;
984             }
985         }
986     }
987     tableWeight = GetTableWeightWithShared(tableWeight, sharedTableOriginNames);
988     auto actualTable = DBCommon::GenerateNodesByNodeWeight(tableNames, reachableWithShared, tableWeight);
989     res.first.assign(actualTable.begin(), actualTable.end());
990     return res;
991 }
992 
CleanTrackerDeviceTable(const std::vector<std::string> & tableNames,RelationalSchemaObject & trackerSchemaObj,SQLiteSingleVerRelationalStorageExecutor * & handle)993 int SQLiteSingleRelationalStorageEngine::CleanTrackerDeviceTable(const std::vector<std::string> &tableNames,
994     RelationalSchemaObject &trackerSchemaObj, SQLiteSingleVerRelationalStorageExecutor *&handle)
995 {
996     std::vector<std::string> missingTrackerTables;
997     int errCode = handle->CheckAndCleanDistributedTable(tableNames, missingTrackerTables);
998     if (errCode != E_OK) { // LCOV_EXCL_BR_LINE
999         LOGE("Check tracker table failed. %d", errCode);
1000         return errCode;
1001     }
1002     if (missingTrackerTables.empty()) { // LCOV_EXCL_BR_LINE
1003         return E_OK;
1004     }
1005     for (const auto &tableName : missingTrackerTables) {
1006         TrackerSchema schema;
1007         schema.tableName = tableName;
1008         trackerSchemaObj.RemoveTrackerSchema(schema);
1009     }
1010     errCode = SaveTrackerSchemaToMetaTable(handle, trackerSchemaObj); // save schema to meta_data
1011     if (errCode != E_OK) { // LCOV_EXCL_BR_LINE
1012         LOGE("Save tracker schema to metaTable failed. %d", errCode);
1013     }
1014     return errCode;
1015 }
1016 
GenLogInfoForUpgrade(const std::string & tableName,RelationalSchemaObject & schema,bool schemaChanged)1017 int SQLiteSingleRelationalStorageEngine::GenLogInfoForUpgrade(const std::string &tableName,
1018     RelationalSchemaObject &schema, bool schemaChanged)
1019 {
1020     int errCode = E_OK;
1021     auto *handle = static_cast<SQLiteSingleVerRelationalStorageExecutor *>(FindExecutor(true,
1022         OperatePerm::NORMAL_PERM, errCode));
1023     if (handle == nullptr) {
1024         return errCode;
1025     }
1026     ResFinalizer finalizer([&handle, this] { this->ReleaseExecutor(handle); });
1027 
1028     errCode = handle->StartTransaction(TransactType::IMMEDIATE);
1029     if (errCode != E_OK) {
1030         return errCode;
1031     }
1032 
1033     TableInfo table = GetSchema().GetTable(tableName);
1034     errCode = handle->UpgradedLogForExistedData(table, schemaChanged);
1035     if (errCode != E_OK) {
1036         LOGE("Upgrade tracker table log failed. %d", errCode);
1037         (void)handle->Rollback();
1038         return errCode;
1039     }
1040     return handle->Commit();
1041 }
1042 
GetReachableWithShared(const std::map<std::string,std::map<std::string,bool>> & reachableReference,const std::map<std::string,std::string> & tableToShared)1043 std::map<std::string, std::map<std::string, bool>> SQLiteSingleRelationalStorageEngine::GetReachableWithShared(
1044     const std::map<std::string, std::map<std::string, bool>> &reachableReference,
1045     const std::map<std::string, std::string> &tableToShared)
1046 {
1047     // we translate all origin table to shared table
1048     std::map<std::string, std::map<std::string, bool>> reachableWithShared;
1049     for (const auto &[source, reach] : reachableReference) {
1050         bool sourceHasNoShared = tableToShared.find(source) == tableToShared.end();
1051         for (const auto &[target, isReach] : reach) {
1052             // merge two reachable reference
1053             reachableWithShared[source][target] = isReach;
1054             if (sourceHasNoShared || tableToShared.find(target) == tableToShared.end()) {
1055                 continue;
1056             }
1057             // record shared reachable reference
1058             reachableWithShared[tableToShared.at(source)][tableToShared.at(target)] = isReach;
1059         }
1060     }
1061     return reachableWithShared;
1062 }
1063 
GetTableWeightWithShared(const std::map<std::string,int> & tableWeight,const std::map<std::string,std::string> & tableToShared)1064 std::map<std::string, int> SQLiteSingleRelationalStorageEngine::GetTableWeightWithShared(
1065     const std::map<std::string, int> &tableWeight, const std::map<std::string, std::string> &tableToShared)
1066 {
1067     std::map<std::string, int> res;
1068     for (const auto &[table, weight] : tableWeight) {
1069         res[table] = weight;
1070         if (tableToShared.find(table) == tableToShared.end()) {
1071             continue;
1072         }
1073         res[tableToShared.at(table)] = weight;
1074     }
1075     return res;
1076 }
1077 }
1078 #endif