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 #define LOG_TAG "JsKVStoreResultSet"
16 #include "js_kv_store_resultset.h"
17 
18 #include "js_util.h"
19 #include "kv_utils.h"
20 #include "log_print.h"
21 #include "napi_queue.h"
22 #include "uv_queue.h"
23 
24 using namespace OHOS::DistributedKv;
25 using namespace OHOS::DataShare;
26 namespace OHOS::DistributedKVStore {
27 
Constructor(napi_env env)28 napi_value JsKVStoreResultSet::Constructor(napi_env env)
29 {
30     auto lambda = []() -> std::vector<napi_property_descriptor> {
31         std::vector<napi_property_descriptor> properties = {
32             DECLARE_NAPI_FUNCTION("getCount", JsKVStoreResultSet::GetCount),
33             DECLARE_NAPI_FUNCTION("getPosition", JsKVStoreResultSet::GetPosition),
34             DECLARE_NAPI_FUNCTION("moveToFirst", JsKVStoreResultSet::MoveToFirst),
35             DECLARE_NAPI_FUNCTION("moveToLast", JsKVStoreResultSet::MoveToLast),
36             DECLARE_NAPI_FUNCTION("moveToNext", JsKVStoreResultSet::MoveToNext),
37             DECLARE_NAPI_FUNCTION("moveToPrevious", JsKVStoreResultSet::MoveToPrevious),
38             DECLARE_NAPI_FUNCTION("move", JsKVStoreResultSet::Move),
39             DECLARE_NAPI_FUNCTION("moveToPosition", JsKVStoreResultSet::MoveToPosition),
40             DECLARE_NAPI_FUNCTION("isFirst", JsKVStoreResultSet::IsFirst),
41             DECLARE_NAPI_FUNCTION("isLast", JsKVStoreResultSet::IsLast),
42             DECLARE_NAPI_FUNCTION("isBeforeFirst", JsKVStoreResultSet::IsBeforeFirst),
43             DECLARE_NAPI_FUNCTION("isAfterLast", JsKVStoreResultSet::IsAfterLast),
44             DECLARE_NAPI_FUNCTION("getEntry", JsKVStoreResultSet::GetEntry),
45         };
46         return properties;
47     };
48     return JSUtil::DefineClass(env, "ohos.data.distributedKVStore", "KVStoreResultSet", lambda,
49         JsKVStoreResultSet::New);
50 }
51 
New(napi_env env,napi_callback_info info)52 napi_value JsKVStoreResultSet::New(napi_env env, napi_callback_info info)
53 {
54     ZLOGD("constructor JsKVStoreResultSet!");
55     auto ctxt = std::make_shared<ContextBase>();
56     ctxt->GetCbInfoSync(env, info);
57     NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!");
58 
59     JsKVStoreResultSet* resultSet = new (std::nothrow) JsKVStoreResultSet();
60     NAPI_ASSERT(env, resultSet !=nullptr, "no memory for resultSet");
61 
62     auto finalize = [](napi_env env, void* data, void* hint) {
63         ZLOGD("kvStoreResultSet finalize.");
64         auto* resultSet = reinterpret_cast<JsKVStoreResultSet*>(data);
65         ASSERT_VOID(resultSet != nullptr, "resultSet is null!");
66         delete resultSet;
67     };
68     ASSERT_CALL(env, napi_wrap(env, ctxt->self, resultSet, finalize, nullptr, nullptr), resultSet);
69     return ctxt->self;
70 }
71 
GetCount(napi_env env,napi_callback_info info)72 napi_value JsKVStoreResultSet::GetCount(napi_env env, napi_callback_info info) /* number  */
73 {
74     ZLOGD("KVStoreResultSet::GetCount()");
75     auto ctxt = std::make_shared<ContextBase>();
76     ctxt->GetCbInfoSync(env, info);
77     NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!");
78     ZLOGD("KVStoreResultSet::GetCount(status=%{public}d)", ctxt->status);
79 
80     auto resultSet = reinterpret_cast<JsKVStoreResultSet*>(ctxt->native)->GetInstance();
81     NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!");
82     int count = resultSet->GetCount();
83 
84     napi_create_int32(env, count, &ctxt->output);
85     return ctxt->output;
86 }
87 
GetPosition(napi_env env,napi_callback_info info)88 napi_value JsKVStoreResultSet::GetPosition(napi_env env, napi_callback_info info) /* number */
89 {
90     ZLOGD("KVStoreResultSet::GetPosition()");
91     auto ctxt = std::make_shared<ContextBase>();
92     ctxt->GetCbInfoSync(env, info);
93     NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!");
94 
95     auto resultSet = reinterpret_cast<JsKVStoreResultSet*>(ctxt->native)->GetInstance();
96     NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!");
97     int position = resultSet->GetPosition();
98 
99     napi_create_int32(env, position, &ctxt->output);
100     return ctxt->output;
101 }
102 
MoveToFirst(napi_env env,napi_callback_info info)103 napi_value JsKVStoreResultSet::MoveToFirst(napi_env env, napi_callback_info info) /* boolean  */
104 {
105     ZLOGD("KVStoreResultSet::MoveToFirst()");
106     auto ctxt = std::make_shared<ContextBase>();
107     ctxt->GetCbInfoSync(env, info);
108     NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!");
109 
110     auto resultSet = reinterpret_cast<JsKVStoreResultSet*>(ctxt->native)->GetInstance();
111     NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!");
112     bool isMoved = resultSet->MoveToFirst();
113 
114     napi_get_boolean(env, isMoved, &ctxt->output);
115     return ctxt->output;
116 }
117 
MoveToLast(napi_env env,napi_callback_info info)118 napi_value JsKVStoreResultSet::MoveToLast(napi_env env, napi_callback_info info) /* boolean */
119 {
120     ZLOGD("KVStoreResultSet::MoveToLast()");
121     auto ctxt = std::make_shared<ContextBase>();
122     ctxt->GetCbInfoSync(env, info);
123     NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!");
124 
125     auto resultSet = reinterpret_cast<JsKVStoreResultSet*>(ctxt->native)->GetInstance();
126     NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!");
127     bool isMoved = resultSet->MoveToLast();
128 
129     napi_get_boolean(env, isMoved, &ctxt->output);
130     return ctxt->output;
131 }
132 
MoveToNext(napi_env env,napi_callback_info info)133 napi_value JsKVStoreResultSet::MoveToNext(napi_env env, napi_callback_info info) /* boolean */
134 {
135     ZLOGD("KVStoreResultSet::MoveToNext()");
136     auto ctxt = std::make_shared<ContextBase>();
137     ctxt->GetCbInfoSync(env, info);
138     NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!");
139 
140     auto resultSet = reinterpret_cast<JsKVStoreResultSet*>(ctxt->native)->GetInstance();
141     NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!");
142     bool isMoved = resultSet->MoveToNext();
143 
144     napi_get_boolean(env, isMoved, &ctxt->output);
145     return ctxt->output;
146 }
147 
MoveToPrevious(napi_env env,napi_callback_info info)148 napi_value JsKVStoreResultSet::MoveToPrevious(napi_env env, napi_callback_info info) /* boolean */
149 {
150     ZLOGD("KVStoreResultSet::MoveToPrevious()");
151     auto ctxt = std::make_shared<ContextBase>();
152     ctxt->GetCbInfoSync(env, info);
153     NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!");
154 
155     auto resultSet = reinterpret_cast<JsKVStoreResultSet*>(ctxt->native)->GetInstance();
156     NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!");
157     bool isMoved = resultSet->MoveToPrevious();
158 
159     napi_get_boolean(env, isMoved, &ctxt->output);
160     return ctxt->output;
161 }
162 
Move(napi_env env,napi_callback_info info)163 napi_value JsKVStoreResultSet::Move(napi_env env, napi_callback_info info) /* boolean  */
164 {
165     ZLOGD("KVStoreResultSet::Move()");
166     int offset = 0;
167     auto ctxt = std::make_shared<ContextBase>();
168     auto input = [env, ctxt, &offset](size_t argc, napi_value* argv) {
169         // required 1 arguments :: <offset>
170         ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT,
171             "Parameter error:Mandatory parameters are left unspecified");
172         ctxt->status = napi_get_value_int32(env, argv[0], reinterpret_cast<int32_t*>(&offset));
173     };
174     ctxt->GetCbInfoSync(env, info, input);
175     ASSERT_NULL(!ctxt->isThrowError, "Move exit");
176     ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "Parameter error:params offset must be number");
177 
178     auto resultSet = reinterpret_cast<JsKVStoreResultSet*>(ctxt->native)->GetInstance();
179     NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!");
180     bool isMoved = resultSet->Move(offset);
181 
182     napi_get_boolean(env, isMoved, &ctxt->output);
183     return ctxt->output;
184 }
185 
MoveToPosition(napi_env env,napi_callback_info info)186 napi_value JsKVStoreResultSet::MoveToPosition(napi_env env, napi_callback_info info) /* boolean  */
187 {
188     int position = 0;
189     auto ctxt = std::make_shared<ContextBase>();
190     auto input = [env, ctxt, &position](size_t argc, napi_value* argv) {
191         // required 1 arguments :: <position>
192         ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT,
193             "Parameter error:Mandatory parameters are left unspecified");
194         ctxt->status = napi_get_value_int32(env, argv[0], reinterpret_cast<int32_t*>(&position));
195     };
196     ctxt->GetCbInfoSync(env, info, input);
197     ASSERT_NULL(!ctxt->isThrowError, "MoveToPosition exit");
198     ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT,
199         "Parameter error:params position must be number");
200     ZLOGD("KVStoreResultSet::MoveToPosition(%{public}d)", position);
201 
202     auto resultSet = reinterpret_cast<JsKVStoreResultSet*>(ctxt->native)->GetInstance();
203     NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!");
204     bool isMoved = resultSet->MoveToPosition(position);
205 
206     napi_get_boolean(env, isMoved, &ctxt->output);
207     return ctxt->output;
208 }
209 
IsFirst(napi_env env,napi_callback_info info)210 napi_value JsKVStoreResultSet::IsFirst(napi_env env, napi_callback_info info) /* boolean  */
211 {
212     ZLOGD("KVStoreResultSet::IsFirst()");
213     auto ctxt = std::make_shared<ContextBase>();
214     ctxt->GetCbInfoSync(env, info);
215     NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!");
216 
217     auto resultSet = reinterpret_cast<JsKVStoreResultSet*>(ctxt->native)->GetInstance();
218     NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!");
219     bool isFirst = resultSet->IsFirst();
220 
221     napi_get_boolean(env, isFirst, &ctxt->output);
222     return ctxt->output;
223 }
224 
IsLast(napi_env env,napi_callback_info info)225 napi_value JsKVStoreResultSet::IsLast(napi_env env, napi_callback_info info) /* boolean */
226 {
227     ZLOGD("KVStoreResultSet::IsLast()");
228     auto ctxt = std::make_shared<ContextBase>();
229     ctxt->GetCbInfoSync(env, info);
230     NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!");
231 
232     auto resultSet = reinterpret_cast<JsKVStoreResultSet*>(ctxt->native)->GetInstance();
233     NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!");
234     bool isLast = resultSet->IsLast();
235 
236     napi_get_boolean(env, isLast, &ctxt->output);
237     return ctxt->output;
238 }
239 
IsBeforeFirst(napi_env env,napi_callback_info info)240 napi_value JsKVStoreResultSet::IsBeforeFirst(napi_env env, napi_callback_info info) /* boolean  */
241 {
242     ZLOGD("KVStoreResultSet::IsBeforeFirst()");
243     auto ctxt = std::make_shared<ContextBase>();
244     ctxt->GetCbInfoSync(env, info);
245     NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!");
246 
247     auto resultSet = reinterpret_cast<JsKVStoreResultSet*>(ctxt->native)->GetInstance();
248     NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!");
249     bool isBeforeFirst = resultSet->IsBeforeFirst();
250 
251     napi_get_boolean(env, isBeforeFirst, &ctxt->output);
252     return ctxt->output;
253 }
254 
IsAfterLast(napi_env env,napi_callback_info info)255 napi_value JsKVStoreResultSet::IsAfterLast(napi_env env, napi_callback_info info) /* boolean  */
256 {
257     ZLOGD("KVStoreResultSet::IsAfterLast()");
258     auto ctxt = std::make_shared<ContextBase>();
259     ctxt->GetCbInfoSync(env, info);
260     NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!");
261 
262     auto resultSet = reinterpret_cast<JsKVStoreResultSet*>(ctxt->native)->GetInstance();
263     NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!");
264     bool isAfterLast = resultSet->IsAfterLast();
265 
266     napi_get_boolean(env, isAfterLast, &ctxt->output);
267     return ctxt->output;
268 }
269 
GetEntry(napi_env env,napi_callback_info info)270 napi_value JsKVStoreResultSet::GetEntry(napi_env env, napi_callback_info info) /* Entry */
271 {
272     ZLOGD("KVStoreResultSet::GetEntry()");
273     auto ctxt = std::make_shared<ContextBase>();
274     ctxt->GetCbInfoSync(env, info);
275     NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!");
276 
277     DistributedKv::Entry entry;
278     auto resultSet = reinterpret_cast<JsKVStoreResultSet*>(ctxt->native)->GetInstance();
279     NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!");
280     bool isSchema = reinterpret_cast<JsKVStoreResultSet*>(ctxt->native)->isSchema_;
281     auto status = resultSet->GetEntry(entry);
282     if (status != Status::SUCCESS) {
283         return nullptr;
284     }
285 
286     ctxt->status = JSUtil::SetValue(env, entry, ctxt->output, isSchema);
287     NAPI_ASSERT(env, ctxt->status == napi_ok, "GetEntry failed!");
288     return ctxt->output;
289 }
290 
Create()291 std::shared_ptr<ResultSetBridge> JsKVStoreResultSet::Create()
292 {
293     auto instance = GetInstance();
294     if (instance == nullptr) {
295         ZLOGE("resultSet is null");
296         return nullptr;
297     }
298     SetInstance(nullptr);
299     return KvUtils::ToResultSetBridge(instance);
300 }
301 
SetSchema(bool isSchema)302 void JsKVStoreResultSet::SetSchema(bool isSchema)
303 {
304     isSchema_ = isSchema;
305 }
306 } // namespace OHOS::DistributedKVStore
307