1 /*
2 * Copyright (c) 2024 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 #include "rdb_store.h"
16
17 #include "sqlite_sql_builder.h"
18 #include "sqlite_utils.h"
19 #include "traits.h"
20 namespace OHOS::NativeRdb {
ModifyTime(std::shared_ptr<ResultSet> result,std::map<std::vector<uint8_t>,PRIKey> hashKeys,bool isFromRowId)21 RdbStore::ModifyTime::ModifyTime(std::shared_ptr<ResultSet> result, std::map<std::vector<uint8_t>, PRIKey> hashKeys,
22 bool isFromRowId)
23 : result_(std::move(result)), hash_(std::move(hashKeys)), isFromRowId_(isFromRowId)
24 {
25 for (auto &[_, priKey] : hash_) {
26 if (priKey.index() != Traits::variant_index_of_v<std::string, PRIKey>) {
27 break;
28 }
29 auto *val = Traits::get_if<std::string>(&priKey);
30 if (val != nullptr && maxOriginKeySize_ <= val->length()) {
31 maxOriginKeySize_ = val->length() + 1;
32 }
33 }
34 }
35
operator std::map<PRIKey,Date>()36 RdbStore::ModifyTime::operator std::map<PRIKey, Date>()
37 {
38 if (result_ == nullptr) {
39 return {};
40 }
41 int count = 0;
42 if (result_->GetRowCount(count) != E_OK || count <= 0) {
43 return {};
44 }
45 std::map<PRIKey, Date> result;
46 for (int i = 0; i < count; i++) {
47 result_->GoToRow(i);
48 int64_t timeStamp = 0;
49 result_->GetLong(1, timeStamp);
50 PRIKey index = 0;
51 if (isFromRowId_) {
52 int64_t rowid = 0;
53 result_->GetLong(0, rowid);
54 index = rowid;
55 } else {
56 std::vector<uint8_t> hashKey;
57 result_->GetBlob(0, hashKey);
58 index = hash_[hashKey];
59 }
60 result[index] = Date(timeStamp);
61 }
62 return result;
63 }
64
operator std::shared_ptr<ResultSet>()65 RdbStore::ModifyTime::operator std::shared_ptr<ResultSet>()
66 {
67 return result_;
68 }
69
GetOriginKey(const std::vector<uint8_t> & hash)70 RdbStore::PRIKey RdbStore::ModifyTime::GetOriginKey(const std::vector<uint8_t> &hash)
71 {
72 auto it = hash_.find(hash);
73 return it != hash_.end() ? it->second : std::monostate();
74 }
75
GetMaxOriginKeySize()76 size_t RdbStore::ModifyTime::GetMaxOriginKeySize()
77 {
78 return maxOriginKeySize_;
79 }
80
NeedConvert() const81 bool RdbStore::ModifyTime::NeedConvert() const
82 {
83 return !hash_.empty();
84 }
85
ToValues(const std::vector<std::string> & args)86 static std::vector<ValueObject> ToValues(const std::vector<std::string> &args)
87 {
88 std::vector<ValueObject> newArgs;
89 std::for_each(args.begin(), args.end(), [&newArgs](const auto &it) {
90 newArgs.push_back(ValueObject(it));
91 });
92 return newArgs;
93 }
94
ColHasSpecificField(const std::vector<std::string> & columns)95 static bool ColHasSpecificField(const std::vector<std::string> &columns)
96 {
97 for (const std::string &column : columns) {
98 if (column.find(SqliteUtils::REP) != std::string::npos) {
99 return true;
100 }
101 }
102 return false;
103 }
104
Insert(const std::string & table,const Row & row,Resolution resolution)105 std::pair<int, int64_t> RdbStore::Insert(const std::string &table, const Row &row, Resolution resolution)
106 {
107 (void)table;
108 (void)row;
109 (void)resolution;
110 return { E_NOT_SUPPORT, -1 };
111 }
112
Insert(int64_t & outRowId,const std::string & table,const Row & row)113 int RdbStore::Insert(int64_t &outRowId, const std::string &table, const Row &row)
114 {
115 auto [errCode, rowid] = Insert(table, row, NO_ACTION);
116 if (errCode == E_OK) {
117 outRowId = rowid;
118 }
119 return errCode;
120 }
121
InsertWithConflictResolution(int64_t & outRowId,const std::string & table,const Row & row,Resolution resolution)122 int RdbStore::InsertWithConflictResolution(int64_t &outRowId, const std::string &table, const Row &row,
123 Resolution resolution)
124 {
125 auto [errCode, rowid] = Insert(table, row, resolution);
126 if (errCode == E_OK) {
127 outRowId = rowid;
128 }
129 return errCode;
130 }
131
Replace(int64_t & outRowId,const std::string & table,const Row & row)132 int RdbStore::Replace(int64_t &outRowId, const std::string &table, const Row &row)
133 {
134 auto [errCode, rowid] = Insert(table, row, Resolution::ON_CONFLICT_REPLACE);
135 if (errCode == E_OK) {
136 outRowId = rowid;
137 }
138 return errCode;
139 }
140
BatchInsert(int64_t & outInsertNum,const std::string & table,const Rows & rows)141 int RdbStore::BatchInsert(int64_t &outInsertNum, const std::string &table, const Rows &rows)
142 {
143 ValuesBuckets refRows;
144 for (auto &row : rows) {
145 refRows.Put(row);
146 }
147 auto [errCode, count] = BatchInsert(table, refRows);
148 if (errCode == E_OK) {
149 outInsertNum = count;
150 }
151 return errCode;
152 }
153
BatchInsert(const std::string & table,const RefRows & rows)154 std::pair<int, int64_t> RdbStore::BatchInsert(const std::string &table, const RefRows &rows)
155 {
156 return { E_NOT_SUPPORT, -1 };
157 }
158
Update(const std::string & table,const Row & row,const std::string & where,const Values & args,Resolution resolution)159 std::pair<int, int> RdbStore::Update(const std::string &table, const Row &row, const std::string &where,
160 const Values &args, Resolution resolution)
161 {
162 (void)table;
163 (void)row;
164 (void)where;
165 (void)args;
166 (void)resolution;
167 return { E_NOT_SUPPORT, 0 };
168 }
169
Update(int & changedRows,const std::string & table,const Row & row,const std::string & whereClause,const Values & args)170 int RdbStore::Update(int &changedRows, const std::string &table, const Row &row, const std::string &whereClause,
171 const Values &args)
172 {
173 auto [errCode, changes] = Update(table, row, whereClause, args, NO_ACTION);
174 if (errCode == E_OK) {
175 changedRows = changes;
176 }
177 return errCode;
178 }
179
Update(int & changedRows,const Row & row,const AbsRdbPredicates & predicates)180 int RdbStore::Update(int &changedRows, const Row &row, const AbsRdbPredicates &predicates)
181 {
182 return Update(changedRows, predicates.GetTableName(), row, predicates.GetWhereClause(), predicates.GetBindArgs());
183 }
184
Update(int & changedRows,const std::string & table,const Row & row,const std::string & whereClause,const Olds & args)185 int RdbStore::Update(int &changedRows, const std::string &table, const Row &row, const std::string &whereClause,
186 const Olds &args)
187 {
188 return Update(changedRows, table, row, whereClause, ToValues(args));
189 };
190
UpdateWithConflictResolution(int & changedRows,const std::string & table,const Row & row,const std::string & whereClause,const Olds & args,Resolution resolution)191 int RdbStore::UpdateWithConflictResolution(int &changedRows, const std::string &table, const Row &row,
192 const std::string &whereClause, const Olds &args, Resolution resolution)
193 {
194 auto [errCode, changes] = Update(table, row, whereClause, ToValues(args), resolution);
195 if (errCode == E_OK) {
196 changedRows = changes;
197 }
198 return errCode;
199 }
200
UpdateWithConflictResolution(int & changedRows,const std::string & table,const Row & row,const std::string & whereClause,const Values & args,Resolution resolution)201 int RdbStore::UpdateWithConflictResolution(int &changedRows, const std::string &table, const Row &row,
202 const std::string &whereClause, const Values &args, Resolution resolution)
203 {
204 auto [errCode, changes] = Update(table, row, whereClause, args, resolution);
205 if (errCode == E_OK) {
206 changedRows = changes;
207 }
208 return errCode;
209 }
210
Delete(int & deletedRows,const std::string & table,const std::string & whereClause,const Olds & args)211 int RdbStore::Delete(int &deletedRows, const std::string &table, const std::string &whereClause, const Olds &args)
212 {
213 return Delete(deletedRows, table, whereClause, ToValues(args));
214 }
215
Delete(int & deletedRows,const AbsRdbPredicates & predicates)216 int RdbStore::Delete(int &deletedRows, const AbsRdbPredicates &predicates)
217 {
218 return Delete(deletedRows, predicates.GetTableName(), predicates.GetWhereClause(), predicates.GetBindArgs());
219 }
220
Query(int & errCode,bool distinct,const std::string & table,const Fields & columns,const std::string & whereClause,const Values & args,const std::string & groupBy,const std::string & indexName,const std::string & orderBy,const int & limit,const int & offset)221 std::shared_ptr<AbsSharedResultSet> RdbStore::Query(int &errCode, bool distinct, const std::string &table,
222 const Fields &columns, const std::string &whereClause, const Values &args, const std::string &groupBy,
223 const std::string &indexName, const std::string &orderBy, const int &limit, const int &offset)
224 {
225 std::string sql;
226 errCode = SqliteSqlBuilder::BuildQueryString(distinct, table, "", columns, whereClause, groupBy, indexName,
227 orderBy, limit, offset, sql);
228 if (errCode != E_OK) {
229 return nullptr;
230 }
231 return QuerySql(sql, args);
232 }
233
Query(const AbsRdbPredicates & predicates,const Fields & columns)234 std::shared_ptr<AbsSharedResultSet> RdbStore::Query(const AbsRdbPredicates &predicates, const Fields &columns)
235 {
236 std::string sql;
237 std::pair<bool, bool> queryStatus = { ColHasSpecificField(columns), predicates.HasSpecificField() };
238 if (queryStatus.first || queryStatus.second) {
239 std::string table = predicates.GetTableName();
240 std::string logTable = GetLogTableName(table);
241 sql = SqliteSqlBuilder::BuildCursorQueryString(predicates, columns, logTable, queryStatus);
242 } else {
243 sql = SqliteSqlBuilder::BuildQueryString(predicates, columns);
244 }
245 return QuerySql(sql, predicates.GetBindArgs());
246 }
247
QuerySql(const std::string & sql,const Olds & args)248 std::shared_ptr<AbsSharedResultSet> RdbStore::QuerySql(const std::string &sql, const Olds &args)
249 {
250 return QuerySql(sql, ToValues(args));
251 }
252
QueryByStep(const std::string & sql,const Olds & args)253 std::shared_ptr<ResultSet> RdbStore::QueryByStep(const std::string &sql, const Olds &args)
254 {
255 return QueryByStep(sql, ToValues(args));
256 }
257
QueryByStep(const AbsRdbPredicates & predicates,const RdbStore::Fields & columns)258 std::shared_ptr<ResultSet> RdbStore::QueryByStep(const AbsRdbPredicates &predicates, const RdbStore::Fields &columns)
259 {
260 std::string sql;
261 if (predicates.HasSpecificField()) {
262 std::string table = predicates.GetTableName();
263 std::string logTable = GetLogTableName(table);
264 sql = SqliteSqlBuilder::BuildLockRowQueryString(predicates, columns, logTable);
265 } else {
266 sql = SqliteSqlBuilder::BuildQueryString(predicates, columns);
267 }
268 return QueryByStep(sql, predicates.GetBindArgs());
269 }
270
RemoteQuery(const std::string & device,const AbsRdbPredicates & predicates,const Fields & columns,int & errCode)271 std::shared_ptr<ResultSet> RdbStore::RemoteQuery(const std::string &device, const AbsRdbPredicates &predicates,
272 const Fields &columns, int &errCode)
273 {
274 (void)device;
275 (void)predicates;
276 (void)columns;
277 errCode = E_NOT_SUPPORT;
278 return nullptr;
279 }
280
QuerySharingResource(const AbsRdbPredicates & predicates,const Fields & columns)281 std::pair<int32_t, std::shared_ptr<ResultSet>> RdbStore::QuerySharingResource(const AbsRdbPredicates &predicates,
282 const Fields &columns)
283 {
284 (void)predicates;
285 (void)columns;
286 return { E_NOT_SUPPORT, nullptr };
287 }
288
ExecuteSql(const std::string & sql,const Values & args)289 int RdbStore::ExecuteSql(const std::string &sql, const Values &args)
290 {
291 auto [errCode, value] = Execute(sql, args, 0);
292 return errCode;
293 }
294
Execute(const std::string & sql,const Values & args,int64_t trxId)295 std::pair<int32_t, ValueObject> RdbStore::Execute(const std::string &sql, const Values &args, int64_t trxId)
296 {
297 return { E_NOT_SUPPORT, ValueObject() };
298 }
299
ExecuteAndGetLong(int64_t & outValue,const std::string & sql,const Values & args)300 int RdbStore::ExecuteAndGetLong(int64_t &outValue, const std::string &sql, const Values &args)
301 {
302 auto [errCode, value] = Execute(sql, args);
303 if (errCode == E_OK) {
304 outValue = static_cast<int64_t>(value);
305 }
306 return errCode;
307 }
308
ExecuteAndGetString(std::string & outValue,const std::string & sql,const Values & args)309 int RdbStore::ExecuteAndGetString(std::string &outValue, const std::string &sql, const Values &args)
310 {
311 auto [errCode, value] = Execute(sql, args);
312 if (errCode == E_OK) {
313 outValue = static_cast<std::string>(value);
314 }
315 return errCode;
316 }
317
ExecuteForLastInsertedRowId(int64_t & outValue,const std::string & sql,const Values & args)318 int RdbStore::ExecuteForLastInsertedRowId(int64_t &outValue, const std::string &sql, const Values &args)
319 {
320 auto [errCode, value] = Execute(sql, args);
321 if (errCode == E_OK) {
322 (void)value.GetLong(outValue);
323 }
324 return errCode;
325 }
326
ExecuteForChangedRowCount(int64_t & outValue,const std::string & sql,const Values & args)327 int RdbStore::ExecuteForChangedRowCount(int64_t &outValue, const std::string &sql, const Values &args)
328 {
329 auto [errCode, value] = Execute(sql, args);
330 if (errCode == E_OK) {
331 (void)value.GetLong(outValue);
332 }
333 return errCode;
334 }
335
Backup(const std::string & databasePath,const std::vector<uint8_t> & encryptKey)336 int RdbStore::Backup(const std::string &databasePath, const std::vector<uint8_t> &encryptKey)
337 {
338 (void)databasePath;
339 (void)encryptKey;
340 return E_NOT_SUPPORT;
341 }
342
Attach(const std::string & alias,const std::string & pathName,const std::vector<uint8_t> encryptKey)343 int RdbStore::Attach(const std::string &alias, const std::string &pathName, const std::vector<uint8_t> encryptKey)
344 {
345 (void)alias;
346 (void)pathName;
347 (void)encryptKey;
348 return E_OK;
349 }
350
Count(int64_t & outValue,const AbsRdbPredicates & predicates)351 int RdbStore::Count(int64_t &outValue, const AbsRdbPredicates &predicates)
352 {
353 (void)outValue;
354 (void)predicates;
355 return E_NOT_SUPPORT;
356 }
357
CreateTransaction(int32_t type)358 std::pair<int32_t, std::shared_ptr<Transaction>> RdbStore::CreateTransaction(int32_t type)
359 {
360 (void)type;
361 return { E_NOT_SUPPORT, nullptr };
362 }
363
BeginTransaction()364 int RdbStore::BeginTransaction()
365 {
366 return E_NOT_SUPPORT;
367 }
368
BeginTrans()369 std::pair<int, int64_t> RdbStore::BeginTrans()
370 {
371 return { E_NOT_SUPPORT, 0 };
372 }
373
RollBack()374 int RdbStore::RollBack()
375 {
376 return E_NOT_SUPPORT;
377 }
378
RollBack(int64_t trxId)379 int RdbStore::RollBack(int64_t trxId)
380 {
381 (void)trxId;
382 return E_NOT_SUPPORT;
383 }
384
Commit()385 int RdbStore::Commit()
386 {
387 return E_NOT_SUPPORT;
388 }
389
Commit(int64_t trxId)390 int RdbStore::Commit(int64_t trxId)
391 {
392 (void)trxId;
393 return E_NOT_SUPPORT;
394 }
395
IsInTransaction()396 bool RdbStore::IsInTransaction()
397 {
398 return true;
399 }
400
GetPath()401 std::string RdbStore::GetPath()
402 {
403 return "";
404 }
405
IsHoldingConnection()406 bool RdbStore::IsHoldingConnection()
407 {
408 return true;
409 }
410
IsOpen() const411 bool RdbStore::IsOpen() const
412 {
413 return true;
414 }
415
IsReadOnly() const416 bool RdbStore::IsReadOnly() const
417 {
418 return false;
419 }
420
IsMemoryRdb() const421 bool RdbStore::IsMemoryRdb() const
422 {
423 return false;
424 }
425
Restore(const std::string & backupPath,const std::vector<uint8_t> & newKey)426 int RdbStore::Restore(const std::string &backupPath, const std::vector<uint8_t> &newKey)
427 {
428 (void)backupPath;
429 (void)newKey;
430 return E_NOT_SUPPORT;
431 }
432
SetDistributedTables(const std::vector<std::string> & tables,int32_t type,const DistributedRdb::DistributedConfig & distributedConfig)433 int RdbStore::SetDistributedTables(const std::vector<std::string> &tables, int32_t type,
434 const DistributedRdb::DistributedConfig &distributedConfig)
435 {
436 (void)tables;
437 (void)type;
438 (void)distributedConfig;
439 return E_NOT_SUPPORT;
440 }
441
ObtainDistributedTableName(const std::string & device,const std::string & table,int & errCode)442 std::string RdbStore::ObtainDistributedTableName(const std::string &device, const std::string &table, int &errCode)
443 {
444 errCode = E_NOT_SUPPORT;
445 return table + "_" + device;
446 }
447
Sync(const SyncOption & option,const AbsRdbPredicates & predicate,const AsyncBrief & async)448 int RdbStore::Sync(const SyncOption &option, const AbsRdbPredicates &predicate, const AsyncBrief &async)
449 {
450 (void)option;
451 (void)predicate;
452 (void)async;
453 return E_NOT_SUPPORT;
454 }
455
Sync(const SyncOption & option,const std::vector<std::string> & tables,const AsyncDetail & async)456 int RdbStore::Sync(const SyncOption &option, const std::vector<std::string> &tables, const AsyncDetail &async)
457 {
458 (void)option;
459 (void)tables;
460 (void)async;
461 return E_NOT_SUPPORT;
462 }
463
Sync(const SyncOption & option,const AbsRdbPredicates & predicate,const AsyncDetail & async)464 int RdbStore::Sync(const SyncOption &option, const AbsRdbPredicates &predicate, const AsyncDetail &async)
465 {
466 (void)option;
467 (void)predicate;
468 (void)async;
469 return E_NOT_SUPPORT;
470 }
471
Subscribe(const SubscribeOption & option,RdbStoreObserver * observer)472 int RdbStore::Subscribe(const SubscribeOption& option, RdbStoreObserver *observer)
473 {
474 (void)option;
475 (void)observer;
476 return E_NOT_SUPPORT;
477 }
478
UnSubscribe(const SubscribeOption & option,RdbStoreObserver * observer)479 int RdbStore::UnSubscribe(const SubscribeOption& option, RdbStoreObserver *observer)
480 {
481 (void)option;
482 (void)observer;
483 return E_NOT_SUPPORT;
484 }
485
SubscribeObserver(const SubscribeOption & option,const std::shared_ptr<RdbStoreObserver> & observer)486 int RdbStore::SubscribeObserver(const SubscribeOption& option, const std::shared_ptr<RdbStoreObserver> &observer)
487 {
488 (void)option;
489 (void)observer;
490 return E_NOT_SUPPORT;
491 }
492
UnsubscribeObserver(const SubscribeOption & option,const std::shared_ptr<RdbStoreObserver> & observer)493 int RdbStore::UnsubscribeObserver(const SubscribeOption& option, const std::shared_ptr<RdbStoreObserver> &observer)
494 {
495 (void)option;
496 (void)observer;
497 return E_NOT_SUPPORT;
498 }
499
RegisterAutoSyncCallback(std::shared_ptr<DetailProgressObserver> observer)500 int RdbStore::RegisterAutoSyncCallback(std::shared_ptr<DetailProgressObserver> observer)
501 {
502 (void)observer;
503 return E_NOT_SUPPORT;
504 }
505
UnregisterAutoSyncCallback(std::shared_ptr<DetailProgressObserver> observer)506 int RdbStore::UnregisterAutoSyncCallback(std::shared_ptr<DetailProgressObserver> observer)
507 {
508 (void)observer;
509 return E_NOT_SUPPORT;
510 }
511
Notify(const std::string & event)512 int RdbStore::Notify(const std::string &event)
513 {
514 (void)event;
515 return E_NOT_SUPPORT;
516 }
517
IsSlaveDiffFromMaster() const518 bool RdbStore::IsSlaveDiffFromMaster() const
519 {
520 return false;
521 }
522
GetDbType() const523 int32_t RdbStore::GetDbType() const
524 {
525 return DB_SQLITE;
526 }
527
LockCloudContainer()528 std::pair<int32_t, uint32_t> RdbStore::LockCloudContainer()
529 {
530 return { E_OK, 0 };
531 }
532
UnlockCloudContainer()533 int32_t RdbStore::UnlockCloudContainer()
534 {
535 return E_OK;
536 }
537
InterruptBackup()538 int RdbStore::InterruptBackup()
539 {
540 return E_OK;
541 }
542
GetBackupStatus() const543 int32_t RdbStore::GetBackupStatus() const
544 {
545 return SlaveStatus::UNDEFINED;
546 }
547
GetModifyTime(const std::string & table,const std::string & column,std::vector<PRIKey> & keys)548 RdbStore::ModifyTime RdbStore::GetModifyTime(const std::string &table, const std::string &column,
549 std::vector<PRIKey> &keys)
550 {
551 (void)table;
552 (void)column;
553 (void)keys;
554 return {};
555 }
556
CleanDirtyData(const std::string & table,uint64_t cursor)557 int RdbStore::CleanDirtyData(const std::string &table, uint64_t cursor)
558 {
559 (void)table;
560 (void)cursor;
561 return E_NOT_SUPPORT;
562 }
563
GetRebuilt(RebuiltType & rebuilt)564 int RdbStore::GetRebuilt(RebuiltType &rebuilt)
565 {
566 (void)rebuilt;
567 return E_NOT_SUPPORT;
568 }
569
Attach(const RdbStoreConfig & config,const std::string & attachName,int32_t waitTime)570 std::pair<int32_t, int32_t> RdbStore::Attach(const RdbStoreConfig &config, const std::string &attachName,
571 int32_t waitTime)
572 {
573 (void)config;
574 (void)attachName;
575 (void)waitTime;
576 return { E_NOT_SUPPORT, 0 };
577 }
578
Detach(const std::string & attachName,int32_t waitTime)579 std::pair<int32_t, int32_t> RdbStore::Detach(const std::string &attachName, int32_t waitTime)
580 {
581 (void)attachName;
582 (void)waitTime;
583 return { E_NOT_SUPPORT, 0 };
584 }
585
ModifyLockStatus(const AbsRdbPredicates & predicates,bool isLock)586 int RdbStore::ModifyLockStatus(const AbsRdbPredicates &predicates, bool isLock)
587 {
588 (void)predicates;
589 (void)isLock;
590 return E_NOT_SUPPORT;
591 }
592
SetSearchable(bool isSearchable)593 int RdbStore::SetSearchable(bool isSearchable)
594 {
595 (void)isSearchable;
596 return E_NOT_SUPPORT;
597 }
598
GetLogTableName(const std::string & tableName)599 std::string RdbStore::GetLogTableName(const std::string &tableName)
600 {
601 return "naturalbase_rdb_aux_" + tableName + "_log";
602 }
603 }