• 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 
16 #include "relational_store_impl_resultsetproxy.h"
17 #include "relational_store_utils.h"
18 #include "napi_rdb_error.h"
19 #include "value_object.h"
20 #include "native_log.h"
21 #include "js_utils.h"
22 #include "rdb_errno.h"
23 
24 namespace OHOS {
25 namespace Relational {
26     static const int E_OK = 0;
27 
ResultSetImpl(std::shared_ptr<NativeRdb::ResultSet> resultSet)28     ResultSetImpl::ResultSetImpl(std::shared_ptr<NativeRdb::ResultSet> resultSet)
29     {
30         resultSetValue = resultSet;
31     }
32 
GetClassType()33     OHOS::FFI::RuntimeType* ResultSetImpl::GetClassType()
34     {
35         static OHOS::FFI::RuntimeType runtimeType = OHOS::FFI::RuntimeType::Create<OHOS::FFI::FFIData>("ResultSetImpl");
36         return &runtimeType;
37     }
38 
GetAllColumnNames()39     CArrStr ResultSetImpl::GetAllColumnNames()
40     {
41         std::vector<std::string> colNames;
42         if (resultSetValue == nullptr) {
43             return CArrStr{nullptr, 0};
44         }
45         int errCode = resultSetValue->GetAllColumnNames(colNames);
46         if (errCode != RelationalStoreJsKit::OK) {
47             LOGE("GetAllColumnNames failed code: %{public}d", errCode);
48             return CArrStr{nullptr, 0};
49         }
50         if (colNames.size() == 0) {
51             return CArrStr{nullptr, 0};
52         }
53         char** result = static_cast<char**>(malloc(colNames.size() * sizeof(char*)));
54         if (result == nullptr) {
55             return CArrStr{nullptr, -1};
56         }
57         for (size_t i = 0; i < colNames.size(); i++) {
58             result[i] = MallocCString(colNames[i]);
59             if (result[i] == nullptr) {
60                 for (size_t j = 0; j < i; j++) {
61                     free(result[j]);
62                 }
63                 free(result);
64                 return CArrStr{nullptr, -1};
65             }
66         }
67         return CArrStr{result, int64_t(colNames.size())};
68     }
69 
GetColumnCount()70     int32_t ResultSetImpl::GetColumnCount()
71     {
72         int32_t count = 0;
73         if (resultSetValue == nullptr) {
74             return count;
75         }
76         int errCode = resultSetValue->GetColumnCount(count);
77         if (errCode != RelationalStoreJsKit::OK) {
78             LOGE("GetColumnCount failed code:%{public}d", errCode);
79         }
80         return count;
81     }
82 
GetRowCount()83     int32_t ResultSetImpl::GetRowCount()
84     {
85         int32_t result;
86         if (resultSetValue == nullptr) {
87             return -1;
88         }
89         int errCode = resultSetValue->GetRowCount(result);
90         if (errCode != RelationalStoreJsKit::OK) {
91             LOGE("GetRowCount failed code:%{public}d", errCode);
92         }
93         return result;
94     }
95 
GetRowIndex()96     int32_t ResultSetImpl::GetRowIndex()
97     {
98         int32_t result;
99         if (resultSetValue == nullptr) {
100             return -1;
101         }
102         int errCode = resultSetValue->GetRowIndex(result);
103         if (errCode != RelationalStoreJsKit::OK) {
104             LOGE("GetRowIndex failed code:%{public}d", errCode);
105         }
106         return result;
107     }
108 
IsAtFirstRow()109     bool ResultSetImpl::IsAtFirstRow()
110     {
111         bool result = false;
112         if (resultSetValue == nullptr) {
113             return result;
114         }
115         int errCode = resultSetValue->IsAtFirstRow(result);
116         if (errCode != RelationalStoreJsKit::OK) {
117             LOGE("IsAtFirstRow failed code:%{public}d", errCode);
118         }
119         return result;
120     }
121 
IsAtLastRow()122     bool ResultSetImpl::IsAtLastRow()
123     {
124         bool result = false;
125         if (resultSetValue == nullptr) {
126             return result;
127         }
128         int errCode = resultSetValue->IsAtLastRow(result);
129         if (errCode != RelationalStoreJsKit::OK) {
130             LOGE("IsAtLastRow failed code:%{public}d", errCode);
131         }
132         return result;
133     }
134 
IsEnded()135     bool ResultSetImpl::IsEnded()
136     {
137         bool result = false;
138         if (resultSetValue == nullptr) {
139             return result;
140         }
141         int errCode = resultSetValue->IsEnded(result);
142         if (errCode != RelationalStoreJsKit::OK) {
143             LOGE("IsEnded failed code:%{public}d", errCode);
144             result = true;
145         }
146         return result;
147     }
148 
IsStarted()149     bool ResultSetImpl::IsStarted()
150     {
151         bool result = false;
152         if (resultSetValue == nullptr) {
153             return result;
154         }
155         int errCode = resultSetValue->IsStarted(result);
156         if (errCode != RelationalStoreJsKit::OK) {
157             LOGE("IsBegin failed code:%{public}d", errCode);
158         }
159         return result;
160     }
161 
IsClosed()162     bool ResultSetImpl::IsClosed()
163     {
164         if (resultSetValue == nullptr) {
165             return false;
166         }
167         return resultSetValue->IsClosed();
168     }
169 
GetDouble(int32_t columnIndex,int32_t * rtnCode)170     double ResultSetImpl::GetDouble(int32_t columnIndex, int32_t* rtnCode)
171     {
172         double result = 0.0;
173         if (resultSetValue == nullptr || rtnCode == nullptr) {
174             return result;
175         }
176         *rtnCode = resultSetValue->GetDouble(columnIndex, result);
177         return result;
178     }
179 
GoToRow(int32_t position,int32_t * rtnCode)180     bool ResultSetImpl::GoToRow(int32_t position, int32_t* rtnCode)
181     {
182         if (resultSetValue == nullptr || rtnCode == nullptr) {
183             return false;
184         }
185         *rtnCode = resultSetValue->GoToRow(position);
186         return *rtnCode == RelationalStoreJsKit::OK;
187     }
188 
GoToPreviousRow(int32_t * rtnCode)189     bool ResultSetImpl::GoToPreviousRow(int32_t* rtnCode)
190     {
191         if (resultSetValue == nullptr || rtnCode == nullptr) {
192             return false;
193         }
194         *rtnCode = resultSetValue->GoToPreviousRow();
195         return *rtnCode == RelationalStoreJsKit::OK;
196     }
197 
GoToLastRow(int32_t * rtnCode)198     bool ResultSetImpl::GoToLastRow(int32_t* rtnCode)
199     {
200         if (resultSetValue == nullptr || rtnCode == nullptr) {
201             return false;
202         }
203         *rtnCode = resultSetValue->GoToLastRow();
204         return *rtnCode == RelationalStoreJsKit::OK;
205     }
206 
GetColumnName(int32_t columnIndex,int32_t * rtnCode)207     char* ResultSetImpl::GetColumnName(int32_t columnIndex, int32_t* rtnCode)
208     {
209         std::string result;
210         if (resultSetValue == nullptr || rtnCode == nullptr) {
211             return nullptr;
212         }
213         *rtnCode = resultSetValue->GetColumnName(columnIndex, result);
214         if (*rtnCode != RelationalStoreJsKit::OK) {
215             LOGE("IsAtLastRow failed code:%{public}d", *rtnCode);
216         }
217         return MallocCString(result);
218     }
219 
IsColumnNull(int32_t columnIndex,int32_t * rtnCode)220     bool ResultSetImpl::IsColumnNull(int32_t columnIndex, int32_t* rtnCode)
221     {
222         bool result;
223         if (resultSetValue == nullptr || rtnCode == nullptr) {
224             return false;
225         }
226         *rtnCode = resultSetValue->IsColumnNull(columnIndex, result);
227         return result;
228     }
229 
GetAsset(int32_t columnIndex,int32_t * rtnCode)230     Asset ResultSetImpl::GetAsset(int32_t columnIndex, int32_t* rtnCode)
231     {
232         NativeRdb::ValueObject::Asset asset;
233         if (resultSetValue == nullptr || rtnCode == nullptr) {
234             return Asset{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, 0};
235         }
236         *rtnCode = resultSetValue->GetAsset(columnIndex, asset);
237         if (*rtnCode != RelationalStoreJsKit::OK) {
238             return Asset{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, 0};
239         }
240         Asset result = {
241             .name= MallocCString(asset.name),
242             .uri= MallocCString(asset.uri),
243             .path= MallocCString(asset.path),
244             .createTime= MallocCString(asset.createTime),
245             .modifyTime= MallocCString(asset.modifyTime),
246             .size= MallocCString(asset.size),
247             .status= (int32_t)asset.status
248         };
249         return result;
250     }
251 
Close()252     int32_t ResultSetImpl::Close()
253     {
254         if (resultSetValue == nullptr) {
255             return -1;
256         }
257         return resultSetValue->Close();
258     }
259 
GetColumnIndex(char * columnName,int32_t * rtnCode)260     int32_t ResultSetImpl::GetColumnIndex(char* columnName, int32_t* rtnCode)
261     {
262         int32_t result = -1;
263         if (resultSetValue == nullptr || rtnCode == nullptr || columnName == nullptr) {
264             return result;
265         }
266         *rtnCode = resultSetValue->GetColumnIndex(columnName, result);
267         // If the API version is less than 13, directly return.
268         if (AppDataMgrJsKit::JSUtils::GetHapVersion() < 13 || (*rtnCode == NativeRdb::E_INVALID_ARGS)) {
269             *rtnCode = E_OK;
270         }
271         return result;
272     }
273 
GetString(int32_t columnIndex,int32_t * rtnCode)274     char* ResultSetImpl::GetString(int32_t columnIndex, int32_t* rtnCode)
275     {
276         std::string result;
277         if (resultSetValue == nullptr || rtnCode == nullptr) {
278             return nullptr;
279         }
280         *rtnCode = resultSetValue->GetString(columnIndex, result);
281         return MallocCString(result);
282     }
283 
GoToFirstRow(int32_t * rtnCode)284     bool ResultSetImpl::GoToFirstRow(int32_t* rtnCode)
285     {
286         if (resultSetValue == nullptr || rtnCode == nullptr) {
287             return false;
288         }
289         *rtnCode = resultSetValue->GoToFirstRow();
290         return *rtnCode == RelationalStoreJsKit::OK;
291     }
292 
GetLong(int32_t columnIndex,int32_t * rtnCode)293     int64_t ResultSetImpl::GetLong(int32_t columnIndex, int32_t* rtnCode)
294     {
295         if (resultSetValue == nullptr || rtnCode == nullptr) {
296             return -1;
297         }
298         int64_t result;
299         *rtnCode = resultSetValue->GetLong(columnIndex, result);
300         return result;
301     }
302 
GoToNextRow(int32_t * rtnCode)303     bool ResultSetImpl::GoToNextRow(int32_t* rtnCode)
304     {
305         if (resultSetValue == nullptr || rtnCode == nullptr) {
306             return false;
307         }
308         *rtnCode = resultSetValue->GoToNextRow();
309         return *rtnCode == RelationalStoreJsKit::OK;
310     }
311 
GetBlob(int32_t columnIndex,int32_t * rtnCode)312     CArrUI8 ResultSetImpl::GetBlob(int32_t columnIndex, int32_t* rtnCode)
313     {
314         std::vector<uint8_t> vec;
315         if (resultSetValue == nullptr || rtnCode == nullptr) {
316             return CArrUI8{nullptr, 0};
317         }
318         *rtnCode = resultSetValue->GetBlob(columnIndex, vec);
319         if (*rtnCode != RelationalStoreJsKit::OK || vec.size() == 0) {
320             return CArrUI8{nullptr, 0};
321         }
322         uint8_t* result = static_cast<uint8_t*>(malloc(vec.size() * sizeof(uint8_t)));
323         if (result == nullptr) {
324             return CArrUI8{nullptr, -1};
325         }
326         for (size_t i = 0; i < vec.size(); i++) {
327             result[i] = vec[i];
328         }
329         return CArrUI8{result, int64_t(vec.size())};
330     }
331 
GoTo(int32_t offset,int32_t * rtnCode)332     bool ResultSetImpl::GoTo(int32_t offset, int32_t* rtnCode)
333     {
334         if (resultSetValue == nullptr || rtnCode == nullptr) {
335             return false;
336         }
337         *rtnCode = resultSetValue->GoTo(offset);
338         return *rtnCode == RelationalStoreJsKit::OK;
339     }
340 
GetAssets(int32_t columnIndex,int32_t * rtnCode)341     Assets ResultSetImpl::GetAssets(int32_t columnIndex, int32_t* rtnCode)
342     {
343         std::vector<NativeRdb::ValueObject::Asset> assets;
344         if (resultSetValue == nullptr || rtnCode == nullptr) {
345             return Assets{nullptr, 0};
346         }
347         *rtnCode = resultSetValue->GetAssets(columnIndex, assets);
348         if (*rtnCode != RelationalStoreJsKit::OK || assets.size() == 0) {
349             return Assets{nullptr, 0};
350         }
351         Asset* result = static_cast<Asset*>(malloc(assets.size() * sizeof(Asset)));
352         if (result == nullptr) {
353             return Assets{nullptr, -1};
354         }
355         for (size_t i = 0; i < assets.size(); i++) {
356             result[i] = Asset {
357                 .name= MallocCString(assets[i].name),
358                 .uri= MallocCString(assets[i].uri),
359                 .path= MallocCString(assets[i].path),
360                 .createTime= MallocCString(assets[i].createTime),
361                 .modifyTime= MallocCString(assets[i].modifyTime),
362                 .size= MallocCString(assets[i].size),
363                 .status= (int32_t)assets[i].status
364             };
365         }
366         return Assets{.head = result, .size = (int64_t)(assets.size())};
367     }
368 
GetRow(int32_t * rtnCode)369     ValuesBucket ResultSetImpl::GetRow(int32_t* rtnCode)
370     {
371         NativeRdb::RowEntity rowEntity;
372         if (resultSetValue == nullptr || rtnCode == nullptr) {
373             return ValuesBucket{nullptr, nullptr, 0};
374         }
375         *rtnCode = resultSetValue->GetRow(rowEntity);
376         if (*rtnCode != E_OK) {
377             return ValuesBucket{nullptr, nullptr, 0};
378         }
379         const std::map<std::string, NativeRdb::ValueObject> map = rowEntity.Get();
380         size_t size = map.size();
381         if (size == 0) {
382             return ValuesBucket{nullptr, nullptr, 0};
383         }
384         ValuesBucket result = ValuesBucket {
385             .key = static_cast<char**>(malloc(sizeof(char*) * size)),
386             .value = static_cast<ValueType*>(malloc(sizeof(ValueType) * size)),
387             .size = size
388         };
389         if (result.key == nullptr || result.value == nullptr) {
390             free(result.key);
391             free(result.value);
392             return ValuesBucket{nullptr, nullptr, -1};
393         }
394         int64_t i = 0;
395         for (auto &t : map) {
396             result.key[i] = MallocCString(t.first);
397             result.value[i] = ValueObjectToValueType(t.second);
398             i++;
399         }
400         return result;
401     }
402 
GetRowEx(int32_t * rtnCode)403     ValuesBucketEx ResultSetImpl::GetRowEx(int32_t* rtnCode)
404     {
405         NativeRdb::RowEntity rowEntity;
406         if (resultSetValue == nullptr || rtnCode == nullptr) {
407             return ValuesBucketEx{nullptr, nullptr, 0};
408         }
409         *rtnCode = resultSetValue->GetRow(rowEntity);
410         if (*rtnCode != E_OK) {
411             return ValuesBucketEx{nullptr, nullptr, 0};
412         }
413         const std::map<std::string, NativeRdb::ValueObject> map = rowEntity.Get();
414         size_t size = map.size();
415         if (size == 0) {
416             return ValuesBucketEx{nullptr, nullptr, 0};
417         }
418         ValuesBucketEx result = ValuesBucketEx {
419             .key = static_cast<char**>(malloc(sizeof(char*) * size)),
420             .value = static_cast<ValueTypeEx*>(malloc(sizeof(ValueTypeEx) * size)),
421             .size = size
422         };
423         if (result.key == nullptr || result.value == nullptr) {
424             free(result.key);
425             free(result.value);
426             return ValuesBucketEx{nullptr, nullptr, ERROR_VALUE};
427         }
428         int64_t i = 0;
429         for (auto &t : map) {
430             result.key[i] = MallocCString(t.first);
431             result.value[i] = ValueObjectToValueTypeEx(t.second);
432             i++;
433         }
434         return result;
435     }
436 
GetValue(int32_t columnIndex,int32_t * rtnCode)437     ValueTypeEx ResultSetImpl::GetValue(int32_t columnIndex, int32_t* rtnCode)
438     {
439         NativeRdb::ValueObject object;
440         if (resultSetValue == nullptr || rtnCode == nullptr) {
441             return ValueTypeEx{ 0 };
442         }
443         *rtnCode = NativeRdb::E_ALREADY_CLOSED;
444         if (resultSetValue != nullptr) {
445             *rtnCode = resultSetValue->Get(columnIndex, object);
446         }
447         if (*rtnCode != E_OK) {
448             return ValueTypeEx{ 0 };
449         }
450         return ValueObjectToValueTypeEx(object);
451     }
452 }
453 }