• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #define LOG_TAG "RdbTransaction"
17 
18 #include "oh_rdb_transaction.h"
19 #include "oh_data_define.h"
20 #include "oh_data_utils.h"
21 #include "relational_values_bucket.h"
22 #include "relational_store_error_code.h"
23 #include "convertor_error_code.h"
24 #include "relational_predicates.h"
25 #include "relational_cursor.h"
26 #include "logger.h"
27 
28 using namespace OHOS::RdbNdk;
29 using namespace OHOS::NativeRdb;
30 
IsValidRdbTransOptions(const OH_RDB_TransOptions * options)31 static bool IsValidRdbTransOptions(const OH_RDB_TransOptions *options)
32 {
33     if (options == nullptr) {
34         LOG_ERROR("options is null");
35         return false;
36     }
37     bool ret = options->IsValid();
38     if (!ret) {
39         LOG_ERROR("invalid transaction options object.");
40     }
41     return ret;
42 }
43 
OH_RdbTrans_CreateOptions(void)44 OH_RDB_TransOptions *OH_RdbTrans_CreateOptions(void)
45 {
46     OH_RDB_TransOptions *value = new (std::nothrow) OH_RDB_TransOptions;
47     if (value == nullptr) {
48         LOG_ERROR("new OH_RDB_TransOptions failed.");
49         return nullptr;
50     }
51     value->type_ = RDB_TRANS_DEFERRED;
52     return value;
53 }
54 
OH_RdbTrans_DestroyOptions(OH_RDB_TransOptions * opitons)55 int OH_RdbTrans_DestroyOptions(OH_RDB_TransOptions *opitons)
56 {
57     if (!IsValidRdbTransOptions(opitons)) {
58         return RDB_E_INVALID_ARGS;
59     }
60     delete opitons;
61     return RDB_OK;
62 }
63 
OH_RdbTransOption_SetType(OH_RDB_TransOptions * opitons,OH_RDB_TransType type)64 int OH_RdbTransOption_SetType(OH_RDB_TransOptions *opitons, OH_RDB_TransType type)
65 {
66     if (!IsValidRdbTransOptions(opitons) || type < RDB_TRANS_DEFERRED || type >= RDB_TRANS_BUTT) {
67         LOG_ERROR("invalid options, type=%{public}d.", type);
68         return RDB_E_INVALID_ARGS;
69     }
70     opitons->type_ = type;
71     return RDB_OK;
72 }
73 
IsValidRdbTrans(const OH_Rdb_Transaction * trans)74 static bool IsValidRdbTrans(const OH_Rdb_Transaction *trans)
75 {
76     if (trans == nullptr || trans->trans_ == nullptr) {
77         LOG_ERROR("trans param has null data");
78         return false;
79     }
80     bool ret = trans->IsValid();
81     if (!ret) {
82         LOG_ERROR("invalid transaction object.");
83     }
84     return ret;
85 }
86 
OH_RdbTrans_Commit(OH_Rdb_Transaction * trans)87 int OH_RdbTrans_Commit(OH_Rdb_Transaction *trans)
88 {
89     if (!IsValidRdbTrans(trans)) {
90         return RDB_E_INVALID_ARGS;
91     }
92     auto errCode = trans->trans_->Commit();
93     if (errCode != E_OK) {
94         LOG_ERROR("commit fail, errCode=%{public}d", errCode);
95     }
96     return ConvertorErrorCode::GetInterfaceCode(errCode);
97 }
98 
OH_RdbTrans_Rollback(OH_Rdb_Transaction * trans)99 int OH_RdbTrans_Rollback(OH_Rdb_Transaction *trans)
100 {
101     if (!IsValidRdbTrans(trans)) {
102         return RDB_E_INVALID_ARGS;
103     }
104     auto errCode = trans->trans_->Rollback();
105     if (errCode != E_OK) {
106         LOG_ERROR("commit fail, errCode=%{public}d", errCode);
107     }
108     return ConvertorErrorCode::GetInterfaceCode(errCode);
109 }
110 
OH_RdbTrans_Insert(OH_Rdb_Transaction * trans,const char * table,const OH_VBucket * row,int64_t * rowId)111 int OH_RdbTrans_Insert(OH_Rdb_Transaction *trans, const char *table, const OH_VBucket *row, int64_t *rowId)
112 {
113     auto valuesBucket = RelationalValuesBucket::GetSelf(const_cast<OH_VBucket *>(row));
114     if (!IsValidRdbTrans(trans) || table == nullptr || valuesBucket == nullptr || rowId == nullptr) {
115         return RDB_E_INVALID_ARGS;
116     }
117 
118     auto [errCode, id] = trans->trans_->Insert(table, valuesBucket->Get());
119     *rowId = id;
120     if (errCode != E_OK) {
121         LOG_ERROR("insert fail, errCode=%{public}d id=%{public}" PRId64, errCode, id);
122     }
123     return ConvertorErrorCode::GetInterfaceCode(errCode);
124 }
125 
OH_RdbTrans_BatchInsert(OH_Rdb_Transaction * trans,const char * table,const OH_Data_VBuckets * rows,Rdb_ConflictResolution resolution,int64_t * changes)126 int OH_RdbTrans_BatchInsert(OH_Rdb_Transaction *trans, const char *table, const OH_Data_VBuckets *rows,
127     Rdb_ConflictResolution resolution, int64_t *changes)
128 {
129     if (!IsValidRdbTrans(trans) || table == nullptr || rows == nullptr || !rows->IsValid() || changes == nullptr ||
130         resolution < RDB_CONFLICT_NONE || resolution > RDB_CONFLICT_REPLACE) {
131         return RDB_E_INVALID_ARGS;
132     }
133     ValuesBuckets datas;
134     for (size_t i = 0; i < rows->rows_.size(); i++) {
135         auto valuesBucket = RelationalValuesBucket::GetSelf(const_cast<OH_VBucket *>(rows->rows_[i]));
136         if (valuesBucket == nullptr) {
137             continue;
138         }
139         datas.Put(valuesBucket->Get());
140     }
141     auto [errCode, count] =
142         trans->trans_->BatchInsertWithConflictResolution(table, datas, Utils::ConvertConflictResolution(resolution));
143     *changes = count;
144     if (errCode != E_OK) {
145         LOG_ERROR("batch insert fail, errCode=%{public}d count=%{public}" PRId64, errCode, count);
146     }
147     return ConvertorErrorCode::GetInterfaceCode(errCode);
148 }
149 
OH_RdbTrans_Update(OH_Rdb_Transaction * trans,const OH_VBucket * row,const OH_Predicates * predicates,int64_t * changes)150 int OH_RdbTrans_Update(OH_Rdb_Transaction *trans, const OH_VBucket *row, const OH_Predicates *predicates,
151     int64_t *changes)
152 {
153     auto rdbPredicate = RelationalPredicate::GetSelf(const_cast<OH_Predicates *>(predicates));
154     auto rdbValuesBucket = RelationalValuesBucket::GetSelf(const_cast<OH_VBucket *>(row));
155     if (!IsValidRdbTrans(trans) || rdbValuesBucket == nullptr || rdbPredicate == nullptr || changes == nullptr) {
156         return RDB_E_INVALID_ARGS;
157     }
158     auto [errCode, count] = trans->trans_->Update(rdbValuesBucket->Get(), rdbPredicate->Get());
159     *changes = count;
160     if (errCode != E_OK) {
161         LOG_ERROR("update fail, errCode=%{public}d count=%{public}d", errCode, count);
162     }
163     return ConvertorErrorCode::GetInterfaceCode(errCode);
164 }
165 
OH_RdbTrans_Delete(OH_Rdb_Transaction * trans,const OH_Predicates * predicates,int64_t * changes)166 int OH_RdbTrans_Delete(OH_Rdb_Transaction *trans, const OH_Predicates *predicates, int64_t *changes)
167 {
168     auto rdbPredicate = RelationalPredicate::GetSelf(const_cast<OH_Predicates *>(predicates));
169     if (!IsValidRdbTrans(trans) || rdbPredicate == nullptr || changes == nullptr) {
170         return RDB_E_INVALID_ARGS;
171     }
172 
173     auto [errCode, count] = trans->trans_->Delete(rdbPredicate->Get());
174     *changes = count;
175     if (errCode != E_OK) {
176         LOG_ERROR("delete fail, errCode=%{public}d count=%{public}d", errCode, count);
177     }
178     return ConvertorErrorCode::GetInterfaceCode(errCode);
179 }
180 
OH_RdbTrans_Query(OH_Rdb_Transaction * trans,const OH_Predicates * predicates,const char * columns[],int len)181 OH_Cursor *OH_RdbTrans_Query(OH_Rdb_Transaction *trans, const OH_Predicates *predicates, const char *columns[], int len)
182 {
183     auto rdbPredicate = RelationalPredicate::GetSelf(const_cast<OH_Predicates *>(predicates));
184     if (!IsValidRdbTrans(trans) || rdbPredicate == nullptr) {
185         return nullptr;
186     }
187     std::vector<std::string> fields;
188     if (columns != nullptr && len > 0) {
189         for (int i = 0; i < len; i++) {
190             fields.emplace_back(columns[i]);
191         }
192     }
193     auto resultSet = trans->trans_->QueryByStep(rdbPredicate->Get(), fields);
194     if (resultSet == nullptr) {
195         LOG_ERROR("resultSet is null.");
196         return nullptr;
197     }
198     return new (std::nothrow) RelationalCursor(std::move(resultSet));
199 }
200 
OH_RdbTrans_QuerySql(OH_Rdb_Transaction * trans,const char * sql,const OH_Data_Values * args)201 OH_Cursor *OH_RdbTrans_QuerySql(OH_Rdb_Transaction *trans, const char *sql, const OH_Data_Values *args)
202 {
203     if (!IsValidRdbTrans(trans) || sql == nullptr || (args != nullptr && !args->IsValid())) {
204         return nullptr;
205     }
206     std::vector<ValueObject> datas;
207     if (args != nullptr) {
208         for (auto arg : args->values_) {
209             if (!arg.IsValid()) {
210                 continue;
211             }
212             datas.push_back(arg.value_);
213         }
214     }
215     auto resultSet = trans->trans_->QueryByStep(sql, datas);
216     if (resultSet == nullptr) {
217         LOG_ERROR("resultSet is null.");
218         return nullptr;
219     }
220     return new (std::nothrow) RelationalCursor(std::move(resultSet));
221 }
222 
OH_RdbTrans_Execute(OH_Rdb_Transaction * trans,const char * sql,const OH_Data_Values * args,OH_Data_Value ** result)223 int OH_RdbTrans_Execute(OH_Rdb_Transaction *trans, const char *sql, const OH_Data_Values *args, OH_Data_Value **result)
224 {
225     if (!IsValidRdbTrans(trans) || sql == nullptr || (args != nullptr && !args->IsValid())) {
226         return RDB_E_INVALID_ARGS;
227     }
228     std::vector<ValueObject> datas;
229     if (args != nullptr) {
230         for (auto arg : args->values_) {
231             if (!arg.IsValid()) {
232                 continue;
233             }
234             datas.push_back(arg.value_);
235         }
236     }
237     auto [errCode, valueObj] = trans->trans_->Execute(sql, datas);
238     if (errCode != OHOS::NativeRdb::E_OK) {
239         LOG_ERROR("execute fail, errCode=%{public}d", errCode);
240         return ConvertorErrorCode::GetInterfaceCode(errCode);
241     }
242     if (result != nullptr) {
243         OH_Data_Value *value = OH_Value_Create();
244         if (value == nullptr) {
245             return RDB_E_ERROR;
246         }
247         value->value_ = valueObj;
248         *result = value;
249     }
250     return RDB_OK;
251 }
252 
OH_RdbTrans_Destroy(OH_Rdb_Transaction * trans)253 int OH_RdbTrans_Destroy(OH_Rdb_Transaction *trans)
254 {
255     if (!IsValidRdbTrans(trans)) {
256         LOG_ERROR("invalid trans");
257         return RDB_E_INVALID_ARGS;
258     }
259     trans->trans_ = nullptr;
260     delete trans;
261     return RDB_OK;
262 }
263 
IsValid() const264 bool OH_Rdb_Transaction::IsValid() const
265 {
266     if (trans_ == nullptr) {
267         return false;
268     }
269     return id == OH_RDB_TRANS_ID;
270 }
271 
IsValid() const272 bool OH_RDB_TransOptions::IsValid() const
273 {
274     if (type_ < RDB_TRANS_DEFERRED || type_ >= RDB_TRANS_BUTT) {
275         LOG_ERROR("invalid type=%{public}d", type_);
276         return false;
277     }
278     return id == OH_TRANS_OPTION_ID;
279 }