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