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 #define LOG_TAG "GdbStore"
16 #include "db_store_impl.h"
17
18 #include <utility>
19
20 #include "connection.h"
21 #include "db_trace.h"
22 #include "gdb_errors.h"
23 #include "gdb_transaction.h"
24 #include "gdb_utils.h"
25 #include "logger.h"
26 #include "transaction_impl.h"
27
28 namespace OHOS::DistributedDataAip {
29 static constexpr int32_t MAX_GQL_LEN = 1024 * 1024;
30
DBStoreImpl(StoreConfig config)31 DBStoreImpl::DBStoreImpl(StoreConfig config) : config_(std::move(config))
32 {
33 }
34
~DBStoreImpl()35 DBStoreImpl::~DBStoreImpl()
36 {
37 LOG_DEBUG("DBStoreImpl enter");
38 Close();
39 }
40
GetConnectionPool()41 std::shared_ptr<ConnectionPool> DBStoreImpl::GetConnectionPool()
42 {
43 std::lock_guard lock(mutex_);
44 return connectionPool_;
45 }
46
SetConnectionPool(std::shared_ptr<ConnectionPool> connectionPool)47 void DBStoreImpl::SetConnectionPool(std::shared_ptr<ConnectionPool> connectionPool)
48 {
49 std::lock_guard lock(mutex_);
50 connectionPool_ = connectionPool;
51 }
52
InitConn()53 int32_t DBStoreImpl::InitConn()
54 {
55 if (GetConnectionPool() != nullptr) {
56 LOG_INFO("connectionPool_ is not nullptr");
57 return E_OK;
58 }
59 int errCode;
60 auto connectionPool = ConnectionPool::Create(config_, errCode);
61 if (errCode != E_OK || connectionPool == nullptr) {
62 LOG_ERROR("Create conn failed, ret=%{public}d", errCode);
63 return errCode;
64 }
65 SetConnectionPool(connectionPool);
66 return E_OK;
67 }
68
QueryGql(const std::string & gql)69 std::pair<int32_t, std::shared_ptr<Result>> DBStoreImpl::QueryGql(const std::string &gql)
70 {
71 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
72 if (gql.empty() || gql.length() > MAX_GQL_LEN) {
73 LOG_ERROR("Gql is empty or length is too long.");
74 return { E_INVALID_ARGS, std::make_shared<FullResult>() };
75 }
76 if (GdbUtils::IsTransactionGql(gql)) {
77 LOG_ERROR("Transaction related statements are not supported.");
78 return { E_INVALID_ARGS, std::make_shared<FullResult>() };
79 }
80 auto connectionPool = GetConnectionPool();
81 if (connectionPool == nullptr) {
82 LOG_ERROR("The connpool is nullptr.");
83 return { E_STORE_HAS_CLOSED, std::make_shared<FullResult>() };
84 }
85 auto conn = connectionPool->AcquireRef(true);
86 if (conn == nullptr) {
87 LOG_ERROR("Get conn failed");
88 return { E_ACQUIRE_CONN_FAILED, std::make_shared<FullResult>() };
89 }
90 auto [ret, stmt] = conn->CreateStatement(gql, conn);
91 if (ret != E_OK || stmt == nullptr) {
92 LOG_ERROR("Create stmt failed, ret=%{public}d", ret);
93 return { ret, std::make_shared<FullResult>() };
94 }
95
96 auto result = std::make_shared<FullResult>();
97 ret = result->InitData(stmt);
98 if (ret != E_OK) {
99 LOG_ERROR("Get FullResult failed, ret=%{public}d", ret);
100 return { ret, std::make_shared<FullResult>() };
101 }
102
103 return { E_OK, result };
104 }
105
ExecuteGql(const std::string & gql)106 std::pair<int32_t, std::shared_ptr<Result>> DBStoreImpl::ExecuteGql(const std::string &gql)
107 {
108 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
109 if (gql.empty() || gql.length() > MAX_GQL_LEN) {
110 LOG_ERROR("Gql is empty or length is too long.");
111 return { E_INVALID_ARGS, std::make_shared<FullResult>() };
112 }
113 if (GdbUtils::IsTransactionGql(gql)) {
114 LOG_ERROR("Transaction related statements are not supported.");
115 return { E_INVALID_ARGS, std::make_shared<FullResult>() };
116 }
117 auto connectionPool = GetConnectionPool();
118 if (connectionPool == nullptr) {
119 LOG_ERROR("The connpool is nullptr.");
120 return { E_STORE_HAS_CLOSED, std::make_shared<FullResult>() };
121 }
122 auto conn = connectionPool->AcquireRef(false);
123 if (conn == nullptr) {
124 LOG_ERROR("Get conn failed");
125 return { E_ACQUIRE_CONN_FAILED, std::make_shared<FullResult>() };
126 }
127 auto [ret, stmt] = conn->CreateStatement(gql, conn);
128 if (ret != E_OK || stmt == nullptr) {
129 LOG_ERROR("Create stmt failed, ret=%{public}d", ret);
130 return { ret, std::make_shared<FullResult>() };
131 }
132 ret = stmt->Step();
133 if (ret != E_OK) {
134 LOG_ERROR("Step stmt failed, ret=%{public}d", ret);
135 }
136 return { ret, std::make_shared<FullResult>() };
137 }
138
CreateTransaction()139 std::pair<int32_t, std::shared_ptr<Transaction>> DBStoreImpl::CreateTransaction()
140 {
141 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
142 auto connectionPool = GetConnectionPool();
143 if (connectionPool == nullptr) {
144 LOG_ERROR("The connpool is nullptr.");
145 return { E_STORE_HAS_CLOSED, nullptr };
146 }
147 auto [ret, conn] = connectionPool->CreateTransConn();
148 if (ret != E_OK || conn == nullptr) {
149 LOG_ERROR("Get conn failed");
150 return { ret, nullptr };
151 }
152 std::shared_ptr<Transaction> trans;
153 std::tie(ret, trans) = TransactionImpl::Create(conn);
154 if (ret != E_OK || trans == nullptr) {
155 LOG_ERROR("Create trans failed, ret=%{public}d", ret);
156 return { ret, nullptr };
157 }
158
159 std::lock_guard lock(transMutex_);
160 for (auto it = transactions_.begin(); it != transactions_.end();) {
161 if (it->expired()) {
162 it = transactions_.erase(it);
163 } else {
164 it++;
165 }
166 }
167 transactions_.push_back(trans);
168 return { ret, trans };
169 }
170
Close()171 int32_t DBStoreImpl::Close()
172 {
173 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
174 SetConnectionPool(nullptr);
175
176 std::lock_guard lock(transMutex_);
177 for (auto &trans : transactions_) {
178 auto realTrans = trans.lock();
179 if (realTrans) {
180 (void)realTrans->Close();
181 }
182 }
183 transactions_ = {};
184 return E_OK;
185 }
186 } // namespace OHOS::DistributedDataAip