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 "GdbStmt"
16 #include "graph_statement.h"
17
18 #include <utility>
19
20 #include "gdb_errors.h"
21 #include "connection.h"
22 #include "full_result.h"
23 #include "grd_error.h"
24 #include "logger.h"
25
26 namespace OHOS::DistributedDataAip {
GraphStatement(GRD_DB * db,const std::string & gql,std::shared_ptr<Connection> conn,int32_t & errCode)27 GraphStatement::GraphStatement(GRD_DB *db, const std::string &gql, std::shared_ptr<Connection> conn, int32_t &errCode)
28 : conn_(conn), gql_(gql), dbHandle_(db)
29 {
30 errCode = E_OK;
31 if (db == nullptr || gql.empty()) {
32 errCode = E_PREPARE_CHECK_FAILED;
33 return;
34 }
35
36 errCode = GrdAdapter::Prepare(dbHandle_, gql_.c_str(), gql_.size(), &stmtHandle_, nullptr);
37 if (errCode != E_OK) {
38 LOG_ERROR("GRD_GqlPrepare failed. ret=%{public}d", errCode);
39 if (stmtHandle_ != nullptr) {
40 GrdAdapter::Finalize(stmtHandle_);
41 }
42 }
43 }
44
~GraphStatement()45 GraphStatement::~GraphStatement()
46 {
47 Finalize();
48 }
49
Prepare()50 int32_t GraphStatement::Prepare()
51 {
52 if (dbHandle_ == nullptr || gql_.empty()) {
53 return E_PREPARE_CHECK_FAILED;
54 }
55
56 int32_t ret = GrdAdapter::Prepare(dbHandle_, gql_.c_str(), gql_.size(), &stmtHandle_, nullptr);
57 if (ret != E_OK) {
58 LOG_ERROR("GRD_GqlPrepare failed. ret=%{public}d", ret);
59 }
60 return ret;
61 }
62
Step()63 int32_t GraphStatement::Step()
64 {
65 if (stmtHandle_ == nullptr) {
66 return E_STEP_CHECK_FAILED;
67 }
68 int32_t ret = GrdAdapter::Step(stmtHandle_);
69 if (ret != E_OK && ret != E_GRD_NO_DATA) {
70 LOG_ERROR("GRD_GqlStep failed. ret=%{public}d", ret);
71 }
72 return ret;
73 }
74
Finalize()75 int32_t GraphStatement::Finalize()
76 {
77 if (stmtHandle_ == nullptr) {
78 return E_OK;
79 }
80 int32_t ret = GrdAdapter::Finalize(stmtHandle_);
81 if (ret != E_OK) {
82 LOG_ERROR("GRD_GqlFinalize failed. ret=%{public}d", ret);
83 return ret;
84 }
85 stmtHandle_ = nullptr;
86 gql_ = "";
87 return E_OK;
88 }
89
GetColumnCount() const90 uint32_t GraphStatement::GetColumnCount() const
91 {
92 if (stmtHandle_ == nullptr) {
93 return E_STATEMENT_EMPTY;
94 }
95 return GrdAdapter::ColumnCount(stmtHandle_);
96 }
97
GetColumnName(int32_t index) const98 std::pair<int32_t, std::string> GraphStatement::GetColumnName(int32_t index) const
99 {
100 if (stmtHandle_ == nullptr) {
101 return { E_STATEMENT_EMPTY, "" };
102 }
103 const char *name = GrdAdapter::ColumnName(stmtHandle_, index);
104 if (name == nullptr) {
105 LOG_ERROR("column_name is null. index=%{public}d", index);
106 return { E_GETTED_COLNAME_EMPTY, "" };
107 }
108 return { E_OK, name };
109 }
110
GetColumnType(int32_t index) const111 std::pair<int32_t, ColumnType> GraphStatement::GetColumnType(int32_t index) const
112 {
113 if (stmtHandle_ == nullptr) {
114 return { E_STATEMENT_EMPTY, ColumnType::TYPE_NULL };
115 }
116 GRD_DbDataTypeE type = GrdAdapter::ColumnType(stmtHandle_, index);
117 return { E_OK, GrdAdapter::TransColType(type) };
118 }
119
ParseJsonStr(const std::string & jsonStr,int32_t & errCode)120 GraphValue GraphStatement::ParseJsonStr(const std::string &jsonStr, int32_t &errCode)
121 {
122 if (jsonStr.empty()) {
123 LOG_WARN("parse json string. jsonStr is empty");
124 errCode = E_OK;
125 return nullptr;
126 }
127 nlohmann::json json = nlohmann::json::parse(jsonStr, nullptr, false);
128 if (json.is_discarded()) {
129 LOG_ERROR("parse json string failed. jsonStr=%{public}s", jsonStr.c_str());
130 errCode = E_PARSE_JSON_FAILED;
131 return nullptr;
132 }
133
134 errCode = E_OK;
135 if (json.is_null()) {
136 LOG_WARN("parse json string. jsonStr is empty");
137 return nullptr;
138 }
139 if (!json.is_object()) {
140 LOG_ERROR("json format error. jsonStr=%{public}s", jsonStr.c_str());
141 errCode = E_PARSE_JSON_FAILED;
142 return nullptr;
143 }
144
145 if (json.contains(Path::SEGMENTS)) {
146 return Path::Parse(json, errCode);
147 }
148 if (json.contains(Edge::SOURCEID) && json.contains(Edge::TARGETID)) {
149 return Edge::Parse(json, errCode);
150 }
151 return Vertex::Parse(json, errCode);
152 }
153
GetColumnValue(int32_t index) const154 std::pair<int32_t, GraphValue> GraphStatement::GetColumnValue(int32_t index) const
155 {
156 if (stmtHandle_ == nullptr) {
157 return { E_STATEMENT_EMPTY, nullptr };
158 }
159 ColumnType type = GetColumnType(index).second;
160 GraphValue value;
161
162 auto ret = 0;
163 switch (type) {
164 case ColumnType::TYPE_INTEGER:
165 value = GrdAdapter::ColumnInt(stmtHandle_, index);
166 break;
167 case ColumnType::TYPE_FLOAT:
168 value = GrdAdapter::ColumnDouble(stmtHandle_, index);
169 break;
170 case ColumnType::TYPE_JSONSTR: {
171 auto text = "";
172 text = GrdAdapter::ColumnText(stmtHandle_, index);
173 value = ParseJsonStr(text, ret);
174 if (ret != E_OK) {
175 LOG_ERROR("ParseJsonStr failed. index=%{public}d, ret=%{public}d", index, ret);
176 return { ret, nullptr };
177 }
178 break;
179 }
180 case ColumnType::TYPE_TEXT:
181 value = GrdAdapter::ColumnText(stmtHandle_, index);
182 break;
183 case ColumnType::TYPE_BLOB:
184 LOG_ERROR("not support blob type. index=%{public}d", index);
185 return { E_NOT_SUPPORT, nullptr };
186 case ColumnType::TYPE_FLOATVECTOR:
187 LOG_ERROR("not support float vector type. index=%{public}d", index);
188 return { E_NOT_SUPPORT, nullptr };
189 case ColumnType::TYPE_NULL:
190 default:
191 value = nullptr;
192 }
193 return { E_OK, value };
194 }
195
IsReady() const196 bool GraphStatement::IsReady() const
197 {
198 return !gql_.empty() && stmtHandle_ != nullptr && dbHandle_ != nullptr;
199 }
200 } // namespace OHOS::DistributedDataAip
201