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