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