• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 #include "datashare_result_set_proxy.h"
17 
18 #include <functional>
19 
20 #include "datashare_result_set.h"
21 #include "datashare_js_utils.h"
22 #include "string_ex.h"
23 #include "datashare_log.h"
24 
25 namespace OHOS {
26 namespace DataShare {
27 constexpr int MAX_INPUT_COUNT = 10;
28 static napi_ref __thread ctorRef_ = nullptr;
NewInstance(napi_env env,std::shared_ptr<DataShareResultSet> resultSet)29 napi_value DataShareResultSetProxy::NewInstance(napi_env env, std::shared_ptr<DataShareResultSet> resultSet)
30 {
31     napi_value cons = GetConstructor(env);
32     if (cons == nullptr) {
33         LOG_ERROR("GetConstructor is nullptr!");
34         return nullptr;
35     }
36     napi_value instance;
37     napi_status status = napi_new_instance(env, cons, 0, nullptr, &instance);
38     if (status != napi_ok) {
39         LOG_ERROR("napi_new_instance failed! code:%{public}d!", status);
40         return nullptr;
41     }
42 
43     DataShareResultSetProxy *proxy = nullptr;
44     status = napi_unwrap(env, instance, reinterpret_cast<void **>(&proxy));
45     if (proxy == nullptr) {
46         LOG_ERROR("native instance is nullptr! code:%{public}d!", status);
47         return instance;
48     }
49 
50     *proxy = std::move(resultSet);
51     return instance;
52 }
53 
GetNativeObject(napi_env const & env,napi_value const & arg)54 std::shared_ptr<DataShareResultSet> DataShareResultSetProxy::GetNativeObject(
55     napi_env const &env, napi_value const &arg)
56 {
57     if (arg == nullptr) {
58         LOG_ERROR("arg is null.");
59         return nullptr;
60     }
61     DataShareResultSetProxy *proxy = nullptr;
62     napi_unwrap(env, arg, reinterpret_cast<void **>(&proxy));
63     if (proxy == nullptr) {
64         LOG_ERROR("proxy is null.");
65         return nullptr;
66     }
67     return proxy->resultSet_;
68 }
69 
GetConstructor(napi_env env)70 napi_value DataShareResultSetProxy::GetConstructor(napi_env env)
71 {
72     napi_value cons;
73     if (ctorRef_ != nullptr) {
74         NAPI_CALL(env, napi_get_reference_value(env, ctorRef_, &cons));
75         return cons;
76     }
77     LOG_INFO("Get DataShareResultSet constructor");
78     napi_property_descriptor clzDes[] = {
79         DECLARE_NAPI_FUNCTION("goToFirstRow", GoToFirstRow),
80         DECLARE_NAPI_FUNCTION("goToLastRow", GoToLastRow),
81         DECLARE_NAPI_FUNCTION("goToNextRow", GoToNextRow),
82         DECLARE_NAPI_FUNCTION("goToPreviousRow", GoToPreviousRow),
83         DECLARE_NAPI_FUNCTION("goTo", GoTo),
84         DECLARE_NAPI_FUNCTION("goToRow", GoToRow),
85         DECLARE_NAPI_FUNCTION("getBlob", GetBlob),
86         DECLARE_NAPI_FUNCTION("getString", GetString),
87         DECLARE_NAPI_FUNCTION("getLong", GetLong),
88         DECLARE_NAPI_FUNCTION("getDouble", GetDouble),
89         DECLARE_NAPI_FUNCTION("close", Close),
90         DECLARE_NAPI_FUNCTION("getColumnIndex", GetColumnIndex),
91         DECLARE_NAPI_FUNCTION("getColumnName", GetColumnName),
92         DECLARE_NAPI_FUNCTION("getDataType", GetDataType),
93 
94         DECLARE_NAPI_GETTER("columnNames", GetAllColumnNames),
95         DECLARE_NAPI_GETTER("columnCount", GetColumnCount),
96         DECLARE_NAPI_GETTER("rowCount", GetRowCount),
97         DECLARE_NAPI_GETTER("isClosed", IsClosed),
98     };
99     NAPI_CALL(env, napi_define_class(env, "DataShareResultSet", NAPI_AUTO_LENGTH, Initialize, nullptr,
100         sizeof(clzDes) / sizeof(napi_property_descriptor), clzDes, &cons));
101     NAPI_CALL(env, napi_create_reference(env, cons, 1, &ctorRef_));
102     return cons;
103 }
104 
Initialize(napi_env env,napi_callback_info info)105 napi_value DataShareResultSetProxy::Initialize(napi_env env, napi_callback_info info)
106 {
107     napi_value self = nullptr;
108     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &self, nullptr));
109     auto *proxy = new (std::nothrow) DataShareResultSetProxy();
110     if (proxy == nullptr) {
111         LOG_ERROR("DataShareResultSetProxy::Initialize new DataShareResultSetProxy error.");
112         return nullptr;
113     }
114     auto finalize = [](napi_env env, void *data, void *hint) {
115         DataShareResultSetProxy *proxy = reinterpret_cast<DataShareResultSetProxy *>(data);
116         if (proxy != nullptr) {
117             delete proxy;
118         }
119     };
120     napi_status status = napi_wrap(env, self, proxy, finalize, nullptr, nullptr);
121     if (status != napi_ok) {
122         LOG_ERROR("napi_wrap failed! code:%{public}d!", status);
123         finalize(env, proxy, nullptr);
124         return nullptr;
125     }
126     return self;
127 }
128 
~DataShareResultSetProxy()129 DataShareResultSetProxy::~DataShareResultSetProxy()
130 {
131     LOG_DEBUG("DataShareResultSetProxy destructor!");
132     if (resultSet_ != nullptr && !resultSet_->IsClosed()) {
133         resultSet_->Close();
134     }
135 }
136 
DataShareResultSetProxy(std::shared_ptr<DataShareResultSet> resultSet)137 DataShareResultSetProxy::DataShareResultSetProxy(std::shared_ptr<DataShareResultSet> resultSet)
138 {
139     if (resultSet_ == resultSet) {
140         return;
141     }
142     resultSet_ = std::move(resultSet);
143 }
144 
operator =(std::shared_ptr<DataShareResultSet> resultSet)145 DataShareResultSetProxy &DataShareResultSetProxy::operator=(std::shared_ptr<DataShareResultSet> resultSet)
146 {
147     if (resultSet_ == resultSet) {
148         return *this;
149     }
150     resultSet_ = std::move(resultSet);
151     return *this;
152 }
153 
GetInnerResultSet(napi_env env,napi_callback_info info)154 std::shared_ptr<DataShareResultSet> DataShareResultSetProxy::GetInnerResultSet(napi_env env,
155     napi_callback_info info)
156 {
157     DataShareResultSetProxy *resultSet = nullptr;
158     napi_value self = nullptr;
159     napi_get_cb_info(env, info, nullptr, nullptr, &self, nullptr);
160     napi_unwrap(env, self, reinterpret_cast<void **>(&resultSet));
161     return resultSet->resultSet_;
162 }
163 
GoToFirstRow(napi_env env,napi_callback_info info)164 napi_value DataShareResultSetProxy::GoToFirstRow(napi_env env, napi_callback_info info)
165 {
166     int errCode = E_ERROR;
167     std::shared_ptr<DataShareResultSet> innerResultSet = GetInnerResultSet(env, info);
168     if (innerResultSet != nullptr) {
169         errCode = innerResultSet->GoToFirstRow();
170         if (errCode != E_OK) {
171             LOG_ERROR("failed code:%{public}d", errCode);
172         }
173     } else {
174         LOG_ERROR("GetInnerResultSet failed.");
175     }
176     return DataShareJSUtils::Convert2JSValue(env, (errCode == E_OK));
177 }
178 
GoToLastRow(napi_env env,napi_callback_info info)179 napi_value DataShareResultSetProxy::GoToLastRow(napi_env env, napi_callback_info info)
180 {
181     int errCode = E_ERROR;
182     std::shared_ptr<DataShareResultSet> innerResultSet = GetInnerResultSet(env, info);
183     if (innerResultSet != nullptr) {
184         errCode = innerResultSet->GoToLastRow();
185         if (errCode != E_OK) {
186             LOG_ERROR("failed code:%{public}d", errCode);
187         }
188     } else {
189         LOG_ERROR("GetInnerResultSet failed.");
190     }
191     return DataShareJSUtils::Convert2JSValue(env, (errCode == E_OK));
192 }
193 
GoToNextRow(napi_env env,napi_callback_info info)194 napi_value DataShareResultSetProxy::GoToNextRow(napi_env env, napi_callback_info info)
195 {
196     int errCode = E_ERROR;
197     std::shared_ptr<DataShareResultSet> innerResultSet = GetInnerResultSet(env, info);
198     if (innerResultSet != nullptr) {
199         errCode = innerResultSet->GoToNextRow();
200         if (errCode != E_OK) {
201             LOG_ERROR("failed code:%{public}d", errCode);
202         }
203     } else {
204         LOG_ERROR("GetInnerResultSet failed.");
205     }
206     return DataShareJSUtils::Convert2JSValue(env, (errCode == E_OK));
207 }
208 
GoToPreviousRow(napi_env env,napi_callback_info info)209 napi_value DataShareResultSetProxy::GoToPreviousRow(napi_env env, napi_callback_info info)
210 {
211     int errCode = E_ERROR;
212     std::shared_ptr<DataShareResultSet> innerResultSet = GetInnerResultSet(env, info);
213     if (innerResultSet != nullptr) {
214         errCode = innerResultSet->GoToPreviousRow();
215         if (errCode != E_OK) {
216             LOG_ERROR("failed code:%{public}d", errCode);
217         }
218     } else {
219         LOG_ERROR("GetInnerResultSet failed.");
220     }
221     return DataShareJSUtils::Convert2JSValue(env, (errCode == E_OK));
222 }
223 
GoTo(napi_env env,napi_callback_info info)224 napi_value DataShareResultSetProxy::GoTo(napi_env env, napi_callback_info info)
225 {
226     int32_t offset = -1;
227     size_t argc = MAX_INPUT_COUNT;
228     napi_value args[MAX_INPUT_COUNT] = { 0 };
229     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
230     NAPI_ASSERT(env, argc > 0, "Invalid argvs!");
231     NAPI_CALL(env, napi_get_value_int32(env, args[0], &offset));
232     int errCode = E_ERROR;
233     std::shared_ptr<DataShareResultSet> innerResultSet = GetInnerResultSet(env, info);
234     if (innerResultSet != nullptr) {
235         errCode = innerResultSet->GoTo(offset);
236         if (errCode != E_OK) {
237             LOG_ERROR("failed code:%{public}d", errCode);
238         }
239     } else {
240         LOG_ERROR("GetInnerResultSet failed.");
241     }
242     return DataShareJSUtils::Convert2JSValue(env, (errCode == E_OK));
243 }
244 
GoToRow(napi_env env,napi_callback_info info)245 napi_value DataShareResultSetProxy::GoToRow(napi_env env, napi_callback_info info)
246 {
247     int32_t position = -1;
248     size_t argc = MAX_INPUT_COUNT;
249     napi_value args[MAX_INPUT_COUNT] = { 0 };
250     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
251     NAPI_ASSERT(env, argc > 0, "Invalid argvs!");
252     NAPI_CALL(env, napi_get_value_int32(env, args[0], &position));
253     int errCode = E_ERROR;
254     std::shared_ptr<DataShareResultSet> innerResultSet = GetInnerResultSet(env, info);
255     if (innerResultSet != nullptr) {
256         errCode = innerResultSet->GoToRow(position);
257         if (errCode != E_OK) {
258             LOG_ERROR("failed code:%{public}d", errCode);
259         }
260     } else {
261         LOG_ERROR("GetInnerResultSet failed.");
262     }
263     return DataShareJSUtils::Convert2JSValue(env, (errCode == E_OK));
264 }
265 
GetBlob(napi_env env,napi_callback_info info)266 napi_value DataShareResultSetProxy::GetBlob(napi_env env, napi_callback_info info)
267 {
268     int32_t columnIndex = -1;
269     std::vector<uint8_t> blob;
270     size_t argc = MAX_INPUT_COUNT;
271     napi_value args[MAX_INPUT_COUNT] = { 0 };
272     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
273     NAPI_ASSERT(env, argc > 0, "Invalid argvs!");
274     NAPI_CALL(env, napi_get_value_int32(env, args[0], &columnIndex));
275     std::shared_ptr<DataShareResultSet> innerResultSet = GetInnerResultSet(env, info);
276     if (innerResultSet != nullptr) {
277         int errCode = innerResultSet->GetBlob(columnIndex, blob);
278         if (errCode != E_OK) {
279             LOG_ERROR("failed code:%{public}d", errCode);
280         }
281     } else {
282         LOG_ERROR("GetInnerResultSet failed.");
283     }
284     return DataShareJSUtils::Convert2JSValue(env, blob);
285 }
286 
GetString(napi_env env,napi_callback_info info)287 napi_value DataShareResultSetProxy::GetString(napi_env env, napi_callback_info info)
288 {
289     int32_t columnIndex = -1;
290     std::string value;
291     size_t argc = MAX_INPUT_COUNT;
292     napi_value args[MAX_INPUT_COUNT] = { 0 };
293     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
294     NAPI_ASSERT(env, argc > 0, "Invalid argvs!");
295     NAPI_CALL(env, napi_get_value_int32(env, args[0], &columnIndex));
296     std::shared_ptr<DataShareResultSet> innerResultSet = GetInnerResultSet(env, info);
297     if (innerResultSet != nullptr) {
298         int errCode = innerResultSet->GetString(columnIndex, value);
299         if (errCode != E_OK) {
300             LOG_ERROR("failed code:%{public}d", errCode);
301         }
302     } else {
303         LOG_ERROR("GetInnerResultSet failed.");
304     }
305     return DataShareJSUtils::Convert2JSValue(env, value);
306 }
307 
GetLong(napi_env env,napi_callback_info info)308 napi_value DataShareResultSetProxy::GetLong(napi_env env, napi_callback_info info)
309 {
310     int32_t columnIndex = -1;
311     int64_t value = -1;
312     size_t argc = MAX_INPUT_COUNT;
313     napi_value args[MAX_INPUT_COUNT] = { 0 };
314     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
315     NAPI_ASSERT(env, argc > 0, "Invalid argvs!");
316     NAPI_CALL(env, napi_get_value_int32(env, args[0], &columnIndex));
317     std::shared_ptr<DataShareResultSet> innerResultSet = GetInnerResultSet(env, info);
318     if (innerResultSet != nullptr) {
319         int errCode = innerResultSet->GetLong(columnIndex, value);
320         if (errCode != E_OK) {
321             LOG_ERROR("failed code:%{public}d", errCode);
322         }
323     } else {
324         LOG_ERROR("GetInnerResultSet failed.");
325     }
326     return DataShareJSUtils::Convert2JSValue(env, value);
327 }
328 
GetDouble(napi_env env,napi_callback_info info)329 napi_value DataShareResultSetProxy::GetDouble(napi_env env, napi_callback_info info)
330 {
331     int32_t columnIndex = -1;
332     double value = 0.0;
333     size_t argc = MAX_INPUT_COUNT;
334     napi_value args[MAX_INPUT_COUNT] = { 0 };
335     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
336     NAPI_ASSERT(env, argc > 0, "Invalid argvs!");
337     NAPI_CALL(env, napi_get_value_int32(env, args[0], &columnIndex));
338     std::shared_ptr<DataShareResultSet> innerResultSet = GetInnerResultSet(env, info);
339     if (innerResultSet != nullptr) {
340         int errCode = innerResultSet->GetDouble(columnIndex, value);
341         if (errCode != E_OK) {
342             LOG_ERROR("failed code:%{public}d", errCode);
343         }
344     } else {
345         LOG_ERROR("GetInnerResultSet failed.");
346     }
347     return DataShareJSUtils::Convert2JSValue(env, value);
348 }
349 
Close(napi_env env,napi_callback_info info)350 napi_value DataShareResultSetProxy::Close(napi_env env, napi_callback_info info)
351 {
352     int errCode = E_ERROR;
353     DataShareResultSetProxy *resultSet = nullptr;
354     napi_value self = nullptr;
355     napi_get_cb_info(env, info, nullptr, nullptr, &self, nullptr);
356     napi_unwrap(env, self, reinterpret_cast<void **>(&resultSet));
357     if (resultSet == nullptr) {
358         return DataShareJSUtils::Convert2JSValue(env, (errCode == E_OK));
359     }
360     auto innerResultSet = resultSet->resultSet_;
361     if (innerResultSet != nullptr) {
362         errCode = innerResultSet->Close();
363         if (errCode != E_OK) {
364             LOG_ERROR("failed code:%{public}d", errCode);
365         }
366         resultSet->resultSet_ = nullptr;
367     } else {
368         LOG_ERROR("GetInnerResultSet failed.");
369     }
370     return DataShareJSUtils::Convert2JSValue(env, (errCode == E_OK));
371 }
372 
GetColumnIndex(napi_env env,napi_callback_info info)373 napi_value DataShareResultSetProxy::GetColumnIndex(napi_env env, napi_callback_info info)
374 {
375     int32_t columnIndex = -1;
376     size_t argc = MAX_INPUT_COUNT;
377     napi_value args[MAX_INPUT_COUNT] = { 0 };
378     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
379     NAPI_ASSERT(env, argc > 0, "Invalid argvs!");
380     std::string columnName = DataShareJSUtils::Convert2String(env, args[0], DataShareJSUtils::DEFAULT_BUF_SIZE);
381     std::shared_ptr<DataShareResultSet> innerResultSet = GetInnerResultSet(env, info);
382     if (innerResultSet != nullptr) {
383         int errCode = innerResultSet->GetColumnIndex(columnName, columnIndex);
384         if (errCode != E_OK) {
385             LOG_ERROR("failed code:%{public}d", errCode);
386         }
387     } else {
388         LOG_ERROR("GetInnerResultSet failed.");
389     }
390     return DataShareJSUtils::Convert2JSValue(env, columnIndex);
391 }
392 
GetColumnName(napi_env env,napi_callback_info info)393 napi_value DataShareResultSetProxy::GetColumnName(napi_env env, napi_callback_info info)
394 {
395     int32_t columnIndex = -1;
396     std::string columnName;
397     size_t argc = MAX_INPUT_COUNT;
398     napi_value args[MAX_INPUT_COUNT] = { 0 };
399     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
400     NAPI_ASSERT(env, argc > 0, "Invalid argvs!");
401     NAPI_CALL(env, napi_get_value_int32(env, args[0], &columnIndex));
402     std::shared_ptr<DataShareResultSet> innerResultSet = GetInnerResultSet(env, info);
403     if (innerResultSet != nullptr) {
404         int errCode = innerResultSet->GetColumnName(columnIndex, columnName);
405         if (errCode != E_OK) {
406             LOG_ERROR("failed code:%{public}d", errCode);
407         }
408     } else {
409         LOG_ERROR("GetInnerResultSet failed.");
410     }
411     return DataShareJSUtils::Convert2JSValue(env, columnName);
412 }
413 
GetDataType(napi_env env,napi_callback_info info)414 napi_value DataShareResultSetProxy::GetDataType(napi_env env, napi_callback_info info)
415 {
416     int32_t columnIndex = -1;
417     DataType dataType = DataType::TYPE_NULL;
418     size_t argc = MAX_INPUT_COUNT;
419     napi_value args[MAX_INPUT_COUNT] = { 0 };
420     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
421     NAPI_ASSERT(env, argc > 0, "Invalid argvs!");
422     NAPI_CALL(env, napi_get_value_int32(env, args[0], &columnIndex));
423     std::shared_ptr<DataShareResultSet> innerResultSet = GetInnerResultSet(env, info);
424     if (innerResultSet != nullptr) {
425         int errCode = innerResultSet->GetDataType(columnIndex, dataType);
426         if (errCode != E_OK) {
427             LOG_ERROR("failed code:%{public}d", errCode);
428         }
429     } else {
430         LOG_ERROR("GetInnerResultSet failed.");
431     }
432     return DataShareJSUtils::Convert2JSValue(env, int32_t(dataType));
433 }
434 
GetAllColumnNames(napi_env env,napi_callback_info info)435 napi_value DataShareResultSetProxy::GetAllColumnNames(napi_env env, napi_callback_info info)
436 {
437     std::vector<std::string> columnNames;
438     std::shared_ptr<DataShareResultSet> innerResultSet = GetInnerResultSet(env, info);
439     if (innerResultSet != nullptr) {
440         int errCode = innerResultSet->GetAllColumnNames(columnNames);
441         if (errCode != E_OK) {
442             LOG_ERROR("failed code:%{public}d", errCode);
443         }
444     } else {
445         LOG_ERROR("GetInnerResultSet failed.");
446     }
447     return DataShareJSUtils::Convert2JSValue(env, columnNames);
448 }
449 
GetColumnCount(napi_env env,napi_callback_info info)450 napi_value DataShareResultSetProxy::GetColumnCount(napi_env env, napi_callback_info info)
451 {
452     int32_t count = -1;
453     std::shared_ptr<DataShareResultSet> innerResultSet = GetInnerResultSet(env, info);
454     if (innerResultSet != nullptr) {
455         int errCode = innerResultSet->GetColumnCount(count);
456         if (errCode != E_OK) {
457             LOG_ERROR("failed code:%{public}d", errCode);
458         }
459     } else {
460         LOG_ERROR("GetInnerResultSet failed.");
461     }
462     return DataShareJSUtils::Convert2JSValue(env, count);
463 }
464 
GetRowCount(napi_env env,napi_callback_info info)465 napi_value DataShareResultSetProxy::GetRowCount(napi_env env, napi_callback_info info)
466 {
467     int32_t count = -1;
468     std::shared_ptr<DataShareResultSet> innerResultSet = GetInnerResultSet(env, info);
469     if (innerResultSet != nullptr) {
470         int errCode = innerResultSet->GetRowCount(count);
471         if (errCode != E_OK) {
472             LOG_ERROR("failed code:%{public}d", errCode);
473         }
474     } else {
475         LOG_ERROR("GetInnerResultSet failed.");
476     }
477     return DataShareJSUtils::Convert2JSValue(env, count);
478 }
479 
IsClosed(napi_env env,napi_callback_info info)480 napi_value DataShareResultSetProxy::IsClosed(napi_env env, napi_callback_info info)
481 {
482     bool result = false;
483     std::shared_ptr<DataShareResultSet> innerResultSet = GetInnerResultSet(env, info);
484     if (innerResultSet != nullptr) {
485         result = innerResultSet->IsClosed();
486     } else {
487         LOG_ERROR("GetInnerResultSet failed.");
488     }
489     napi_value output;
490     napi_get_boolean(env, result, &output);
491     return output;
492 }
493 } // namespace DataShare
494 } // namespace OHOS
495