1 /*
2  * Copyright (C) 2023 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 
16 #include "database.h"
17 
18 #include <thread>
19 
20 #include "result_set.h"
21 #include "rdb_errno.h"
22 #include "rdb_helper.h"
23 
24 #include "security_guard_log.h"
25 
26 namespace OHOS::Security::SecurityGuard {
27 namespace {
28     constexpr int32_t MAX_TIMES = 5;
29     constexpr int32_t SLEEP_INTERVAL = 500;
30 }
31 
CreateRdbStore(const NativeRdb::RdbStoreConfig & config,int version,NativeRdb::RdbOpenCallback & openCallback,int & errCode)32 void Database::CreateRdbStore(const NativeRdb::RdbStoreConfig &config, int version,
33     NativeRdb::RdbOpenCallback &openCallback, int &errCode)
34 {
35     SGLOGI("EventStore::CreateRdbStore");
36     store_ = NativeRdb::RdbHelper::GetRdbStore(config, version, openCallback, errCode);
37 }
38 
Insert(int64_t & outRowId,const std::string & table,const NativeRdb::ValuesBucket & initialValues)39 int Database::Insert(int64_t &outRowId, const std::string &table, const NativeRdb::ValuesBucket &initialValues)
40 {
41     int ret = IsExistStore();
42     if (ret == NativeRdb::E_OK) {
43         ret = store_->Insert(outRowId, table, initialValues);
44     }
45     return ret;
46 }
47 
BatchInsert(int64_t & outInsertNum,const std::string & table,const std::vector<NativeRdb::ValuesBucket> & initialBatchValues)48 int Database::BatchInsert(int64_t &outInsertNum, const std::string &table,
49     const std::vector<NativeRdb::ValuesBucket> &initialBatchValues)
50 {
51     int ret = IsExistStore();
52     if (ret == NativeRdb::E_OK) {
53         ret = store_->BatchInsert(outInsertNum, table, initialBatchValues);
54     }
55     return ret;
56 }
57 
Update(int & changedRows,const NativeRdb::ValuesBucket & values,const NativeRdb::AbsRdbPredicates & predicates)58 int Database::Update(int &changedRows, const NativeRdb::ValuesBucket &values,
59     const NativeRdb::AbsRdbPredicates &predicates)
60 {
61     int ret = IsExistStore();
62     if (ret == NativeRdb::E_OK) {
63         ret = store_->Update(changedRows, values, predicates);
64     }
65     return ret;
66 }
67 
Delete(int & deletedRows,const NativeRdb::AbsRdbPredicates & predicates)68 int Database::Delete(int &deletedRows, const NativeRdb::AbsRdbPredicates &predicates)
69 {
70     int ret = IsExistStore();
71     if (ret == NativeRdb::E_OK) {
72         ret = store_->Delete(deletedRows, predicates);
73     }
74     return ret;
75 }
76 
Query(const NativeRdb::AbsRdbPredicates & predicates,const std::vector<std::string> columns)77 std::shared_ptr<NativeRdb::ResultSet> Database::Query(
78     const NativeRdb::AbsRdbPredicates &predicates, const std::vector<std::string> columns)
79 {
80     int ret = IsExistStore();
81     if (ret == NativeRdb::E_OK) {
82         return store_->Query(predicates, columns);
83     }
84     return nullptr;
85 }
86 
ExecuteSql(const std::string & sql)87 int Database::ExecuteSql(const std::string &sql)
88 {
89     int ret = IsExistStore();
90     if (ret == NativeRdb::E_OK) {
91         ret = store_->ExecuteSql(sql);
92     }
93     return ret;
94 }
95 
ExecuteAndGetLong(int64_t & outValue,const std::string & sql,const std::vector<NativeRdb::ValueObject> & bindArgs)96 int Database::ExecuteAndGetLong(int64_t &outValue, const std::string &sql,
97     const std::vector<NativeRdb::ValueObject> &bindArgs)
98 {
99     int ret = IsExistStore();
100     if (ret == NativeRdb::E_OK) {
101         ret = store_->ExecuteAndGetLong(outValue, sql, bindArgs);
102     }
103     return ret;
104 }
105 
Count(int64_t & outValue,const NativeRdb::AbsRdbPredicates & predicates)106 int Database::Count(int64_t &outValue, const NativeRdb::AbsRdbPredicates &predicates)
107 {
108     int ret = IsExistStore();
109     if (ret == NativeRdb::E_OK) {
110         ret = store_->Count(outValue, predicates);
111     }
112     return ret;
113 }
114 
BeginTransaction()115 int Database::BeginTransaction()
116 {
117     int ret = IsExistStore();
118     if (ret == NativeRdb::E_OK) {
119         ret = store_->BeginTransaction();
120     }
121     return ret;
122 }
123 
RollBack()124 int Database::RollBack()
125 {
126     int ret = IsExistStore();
127     if (ret == NativeRdb::E_OK) {
128         ret = store_->RollBack();
129     }
130     return ret;
131 }
132 
Commit()133 int Database::Commit()
134 {
135     int ret = IsExistStore();
136     if (ret == NativeRdb::E_OK) {
137         ret = store_->Commit();
138     }
139     return ret;
140 }
141 
Attach(const std::string & alias,const std::string & pathName,const std::vector<uint8_t> destEncryptKey)142 int Database::Attach(const std::string &alias, const std::string &pathName,
143     const std::vector<uint8_t> destEncryptKey)
144 {
145     int ret = IsExistStore();
146     if (ret == NativeRdb::E_OK) {
147         ret = store_->Attach(alias, pathName, destEncryptKey);
148     }
149     return ret;
150 }
151 
IsExistStore()152 int Database::IsExistStore()
153 {
154     if (store_ != nullptr) {
155         return NativeRdb::E_OK;
156     }
157     int32_t tryTimes = MAX_TIMES;
158     while (tryTimes > 0) {
159         if (store_ != nullptr) {
160             return NativeRdb::E_OK;
161         }
162 
163         SGLOGW("tryTimes = %{public}d", tryTimes);
164         std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_INTERVAL));
165         tryTimes--;
166     }
167     if (store_ == nullptr) {
168         SGLOGE("EventStore::IsExistStore NativeRdb::RdbStore is null!");
169         return NativeRdb::E_ERROR;
170     }
171     return NativeRdb::E_OK;
172 }
173 }