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 }