• 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 #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