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