1 /*
2 * Copyright (C) 2025 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 "pdp_result_set_bridge.h"
17 #include "data_storage_log_wrapper.h"
18 #include "rdb_errno.h"
19 #include "rdb_store_config.h"
20 #include "rdb_utils.h"
21
22 namespace OHOS {
23 namespace Telephony {
24 using std::vector;
25 using std::string;
26 using namespace DataShare;
27 using namespace DistributedKv;
28
PdpResultSetBridge(const NativeDataSet & dataSet)29 PdpResultSetBridge::PdpResultSetBridge(const NativeDataSet &dataSet) : data_(dataSet.records)
30 {
31 columnsNames_ = dataSet.columnNames;
32 count_ = static_cast<uint32_t>(dataSet.records.size());
33 }
34
GetRowCount(int32_t & count)35 int PdpResultSetBridge::GetRowCount(int32_t &count)
36 {
37 count = static_cast<int32_t>(this->data_.size());
38 return NativeRdb::E_OK;
39 }
40
WriteString(ResultSetBridge::Writer & writer,uint32_t columnIndex,const string & value)41 inline int WriteString(ResultSetBridge::Writer &writer, uint32_t columnIndex, const string &value)
42 {
43 DistributedKv::Value insertValue(value);
44 auto converted = insertValue.ToString();
45 auto chars = converted.c_str();
46 auto size = insertValue.Size() + 1;
47 auto errCode = writer.Write(columnIndex, chars, size);
48 if (errCode != 0) {
49 DATA_STORAGE_LOGE("WriteString error:%{public}d", errCode);
50 return errCode;
51 }
52 return errCode;
53 }
54
WriteOptionalString(ResultSetBridge::Writer & writer,uint32_t columnIndex,const std::optional<string> & opt)55 inline int WriteOptionalString(ResultSetBridge::Writer &writer, uint32_t columnIndex, const std::optional<string> &opt)
56 {
57 return opt.has_value() ? WriteString(writer, columnIndex, opt.value()) : ERR_OK;
58 }
59
WriteInt64(ResultSetBridge::Writer & writer,uint32_t columnIndex,int64_t value)60 inline int WriteInt64(ResultSetBridge::Writer &writer, uint32_t columnIndex, int64_t value)
61 {
62 auto errCode = writer.Write(columnIndex, value);
63 if (errCode != 0) {
64 DATA_STORAGE_LOGE("WriteInt64 error:%{public}d", errCode);
65 return errCode;
66 }
67 return errCode;
68 }
69
WriteDouble64(ResultSetBridge::Writer & writer,uint32_t columnIndex,double_t value)70 inline int WriteDouble64(ResultSetBridge::Writer &writer, uint32_t columnIndex, double_t value)
71 {
72 auto errCode = writer.Write(columnIndex, value);
73 if (errCode != 0) {
74 DATA_STORAGE_LOGE("WriteDouble64 error:%{public}d", errCode);
75 return errCode;
76 }
77 return errCode;
78 }
79
WriteBlob(ResultSetBridge::Writer & writer,uint32_t columnIndex,const vector<uint8_t> & value)80 inline int WriteBlob(ResultSetBridge::Writer &writer, uint32_t columnIndex, const vector<uint8_t> &value)
81 {
82 auto errCode = writer.Write(columnIndex, value.data(), value.size());
83 if (errCode != 0) {
84 DATA_STORAGE_LOGE("WriteBlob error:%{public}d", errCode);
85 return errCode;
86 }
87 return errCode;
88 }
89
GetAllColumnNames(vector<string> & columnNames)90 int PdpResultSetBridge::GetAllColumnNames(vector<string> &columnNames)
91 {
92 columnNames = columnsNames_;
93 return 0;
94 }
95
OnGo(int32_t startRowIndex,int32_t targetRowIndex,DataShare::ResultSetBridge::Writer & writer)96 int PdpResultSetBridge::OnGo(int32_t startRowIndex, int32_t targetRowIndex, DataShare::ResultSetBridge::Writer &writer)
97 {
98 DATA_STORAGE_LOGI("PdpProfileAbility::OnGo startRowIndex = %{public}d targetRowIndex = %{public}d",
99 startRowIndex, targetRowIndex);
100 if ((startRowIndex < 0) || (targetRowIndex < 0) || (startRowIndex > targetRowIndex) ||
101 (targetRowIndex >= static_cast<int32_t>(count_))) {
102 // When failed to move, we should return -1.
103 return -1;
104 }
105 // When called DataShareResultSet.GoToRow(index),
106 // DataShareResultSet will try to call `OnGo(index, rowCount - 1, writer)`.
107 // If we decide not to fill all the data at one `move`,
108 // `OnGo` should return the final row index of actual filled blocks.
109 // Here we fill all the data in range [index, target].
110 return FillBlocks(startRowIndex, targetRowIndex, writer);
111 }
112
FillBlocks(int32_t startRowIndex,int32_t targetRowIndex,ResultSetBridge::Writer & writer)113 int PdpResultSetBridge::FillBlocks(int32_t startRowIndex, int32_t targetRowIndex, ResultSetBridge::Writer &writer)
114 {
115 int allocatedRows = 0;
116 for (int32_t rowIndex = startRowIndex; rowIndex <= targetRowIndex; ++rowIndex) {
117 auto errCode = writer.AllocRow();
118 if (errCode != 0) {
119 DATA_STORAGE_LOGE("PdpProfileAbility::FillBlock. AllocRow fail");
120 return rowIndex - 1;
121 }
122 ++allocatedRows;
123 NativeRecord markInfo = data_[rowIndex];
124 uint32_t markInfoSize = static_cast<uint32_t>(markInfo.size());
125 uint32_t columnsNameSize = static_cast<uint32_t>(columnsNames_.size());
126 if (markInfoSize != columnsNameSize) {
127 DATA_STORAGE_LOGE("columnsNameSize:%{public}d, markInfoSize:%{public}d", columnsNameSize, markInfoSize);
128 return rowIndex - 1;
129 }
130 for (uint32_t i = 0; i < columnsNameSize; i++) {
131 auto errCode = 0;
132 const NativeData *cell = &markInfo[i];
133 if (auto ptr = std::get_if<int64_t>(cell); ptr != nullptr) {
134 errCode = WriteInt64(writer, i, *ptr);
135 } else if (auto ptr = std::get_if<double_t>(cell); ptr != nullptr) {
136 errCode = WriteDouble64(writer, i, *ptr);
137 } else if (auto ptr = std::get_if<string>(cell); ptr != nullptr) {
138 errCode = WriteString(writer, i, *ptr);
139 } else if (auto ptr = std::get_if<vector<uint8_t>>(cell); ptr != nullptr) {
140 errCode = WriteBlob(writer, i, *ptr);
141 } else {
142 errCode = -1;
143 }
144 if (errCode != 0) {
145 DATA_STORAGE_LOGE("FillBlocks failed errCode = %{public}d", errCode);
146 return rowIndex;
147 }
148 }
149 }
150 DATA_STORAGE_LOGI("FillBlocks %{public}d rows", allocatedRows);
151 return targetRowIndex;
152 }
153 } // namespace NativeRdb
154 } // namespace OHOS