• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #define LOG_TAG "GdbTrans"
16 #include "transaction_impl.h"
17 
18 #include <utility>
19 
20 #include "gdb_errors.h"
21 #include "db_trace.h"
22 #include "logger.h"
23 #include "trans_db.h"
24 
25 namespace OHOS::DistributedDataAip {
26 
27 constexpr const char *START_GQL = "START TRANSACTION;";
28 constexpr const char *COMMIT_GQL = "COMMIT;";
29 constexpr const char *ROLLBACK_GQL = "ROLLBACK;";
30 
31 __attribute__((used))
32 const int32_t TransactionImpl::regCreator_ = Transaction::RegisterCreator(TransactionImpl::Create);
33 
TransactionImpl(std::shared_ptr<Connection> connection)34 TransactionImpl::TransactionImpl(std::shared_ptr<Connection> connection)
35     : connection_(std::move(connection))
36 {
37 }
38 
~TransactionImpl()39 TransactionImpl::~TransactionImpl()
40 {
41     CloseInner();
42 }
43 
Create(std::shared_ptr<Connection> conn)44 std::pair<int32_t, std::shared_ptr<Transaction>> TransactionImpl::Create(std::shared_ptr<Connection> conn)
45 {
46     if (conn == nullptr) {
47         LOG_ERROR("conn is nullptr");
48         return { E_ERROR, nullptr };
49     }
50     auto trans = std::make_shared<TransactionImpl>(std::move(conn));
51     if (trans == nullptr) {
52         LOG_ERROR("trans is nullptr");
53         return { E_ERROR, nullptr };
54     }
55     auto errorCode = trans->Start();
56     if (errorCode != E_OK) {
57         LOG_ERROR("transaction start failed, errorCode=%{public}d", errorCode);
58         return { errorCode, nullptr };
59     }
60     return { E_OK, trans };
61 }
62 
Start()63 int32_t TransactionImpl::Start()
64 {
65     std::lock_guard lock(mutex_);
66     store_ = std::make_shared<TransDB>(connection_);
67     if (store_ == nullptr) {
68         LOG_ERROR("create trans db failed");
69         return E_ERROR;
70     }
71 
72     if (connection_ == nullptr) {
73         LOG_ERROR("connection already closed");
74         return E_GRD_DB_INSTANCE_ABNORMAL;
75     }
76 
77     auto [errorCode, statement] = connection_->CreateStatement(START_GQL, connection_);
78     if (errorCode != E_OK || statement == nullptr) {
79         LOG_ERROR("create statement failed, errorCode=%{public}d", errorCode);
80         CloseInner();
81         return errorCode;
82     }
83     errorCode = statement->Step();
84     if (errorCode != E_OK) {
85         LOG_ERROR("statement execute failed, errorCode=%{public}d", errorCode);
86         CloseInner();
87         return errorCode;
88     }
89     return E_OK;
90 }
91 
Commit()92 int32_t TransactionImpl::Commit()
93 {
94     DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
95     std::lock_guard lock(mutex_);
96     if (connection_ == nullptr) {
97         LOG_ERROR("connection already closed");
98         return E_GRD_DB_INSTANCE_ABNORMAL;
99     }
100 
101     auto [errorCode, statement] = connection_->CreateStatement(COMMIT_GQL, connection_);
102     if (errorCode != E_OK || statement == nullptr) {
103         LOG_ERROR("create statement failed, errorCode=%{public}d", errorCode);
104         CloseInner();
105         return errorCode;
106     }
107 
108     errorCode = statement->Step();
109     CloseInner();
110     if (errorCode != E_OK) {
111         LOG_ERROR("statement execute failed, errorCode=%{public}d", errorCode);
112         return errorCode;
113     }
114     return E_OK;
115 }
116 
Rollback()117 int32_t TransactionImpl::Rollback()
118 {
119     DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
120     std::lock_guard lock(mutex_);
121     if (connection_ == nullptr) {
122         LOG_ERROR("connection already closed");
123         return E_GRD_DB_INSTANCE_ABNORMAL;
124     }
125 
126     auto [errorCode, statement] = connection_->CreateStatement(ROLLBACK_GQL, connection_);
127     if (errorCode != E_OK || statement == nullptr) {
128         LOG_ERROR("create statement failed, errorCode=%{public}d", errorCode);
129         CloseInner();
130         return errorCode;
131     }
132 
133     errorCode = statement->Step();
134     CloseInner();
135     if (errorCode != E_OK) {
136         LOG_ERROR("statement execute failed, errorCode=%{public}d", errorCode);
137         return errorCode;
138     }
139     return E_OK;
140 }
141 
CloseInner()142 int32_t TransactionImpl::CloseInner()
143 {
144     std::lock_guard lock(mutex_);
145     store_ = nullptr;
146     connection_ = nullptr;
147     return E_OK;
148 }
149 
Close()150 int32_t TransactionImpl::Close()
151 {
152     return Rollback();
153 }
154 
GetStore()155 std::shared_ptr<DBStore> TransactionImpl::GetStore()
156 {
157     std::lock_guard lock(mutex_);
158     return store_;
159 }
160 
Query(const std::string & gql)161 std::pair<int32_t, std::shared_ptr<Result>> TransactionImpl::Query(const std::string &gql)
162 {
163     auto store = GetStore();
164     if (store == nullptr) {
165         LOG_ERROR("transaction already close");
166         return { E_GRD_DB_INSTANCE_ABNORMAL, std::make_shared<FullResult>() };
167     }
168     return store->QueryGql(gql);
169 }
170 
Execute(const std::string & gql)171 std::pair<int32_t, std::shared_ptr<Result>> TransactionImpl::Execute(const std::string &gql)
172 {
173     auto store = GetStore();
174     if (store == nullptr) {
175         LOG_ERROR("transaction already close");
176         return { E_GRD_DB_INSTANCE_ABNORMAL, std::make_shared<FullResult>() };
177     }
178     return store->ExecuteGql(gql);
179 }
180 } // namespace OHOS::DistributedDataAip
181