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 "rdb_result_set_bridge.h"
17
18 #include "logger.h"
19 #include "rdb_errno.h"
20 #include "result_set.h"
21 #include "securec.h"
22
23 namespace OHOS {
24 namespace RdbDataShareAdapter {
25 using namespace OHOS::Rdb;
26 using namespace OHOS::NativeRdb;
27
RdbResultSetBridge(std::shared_ptr<ResultSet> resultSet)28 RdbResultSetBridge::RdbResultSetBridge(std::shared_ptr<ResultSet> resultSet) : rdbResultSet_(resultSet)
29 {
30 }
31
~RdbResultSetBridge()32 RdbResultSetBridge::~RdbResultSetBridge()
33 {
34 rdbResultSet_->Close();
35 }
36
GetRowCount(int & count)37 int RdbResultSetBridge::GetRowCount(int &count)
38 {
39 return rdbResultSet_->GetRowCount(count);
40 }
41
GetAllColumnNames(std::vector<std::string> & columnOrKeyNames)42 int RdbResultSetBridge::GetAllColumnNames(std::vector<std::string> &columnOrKeyNames)
43 {
44 return rdbResultSet_->GetAllColumnNames(columnOrKeyNames);
45 }
46
OnGo(int32_t start,int32_t target,Writer & writer)47 int RdbResultSetBridge::OnGo(int32_t start, int32_t target, Writer &writer)
48 {
49 int rowCount;
50 rdbResultSet_->GetRowCount(rowCount);
51 if (start < 0 || target < 0 || target >= rowCount) {
52 LOG_ERROR("Invalid targetRowIndex: %{public}d.", rowCount);
53 return -1;
54 }
55
56 int columnCount;
57 rdbResultSet_->GetColumnCount(columnCount);
58 if (columnCount <= 0) {
59 LOG_ERROR("Invalid columnCount: %{public}d.", columnCount);
60 return -1;
61 }
62 LOG_DEBUG("rowCount: %{public}d, columnCount: %{public}d.", rowCount, columnCount);
63
64 bool bResultSet = false;
65 rdbResultSet_->IsStarted(bResultSet);
66 if (!bResultSet) {
67 rdbResultSet_->GoToFirstRow();
68 }
69
70 int errCode = rdbResultSet_->GoToRow(start);
71 if (errCode) {
72 LOG_ERROR("Go to row %{public}d failed.", start);
73 return -1;
74 }
75
76 return WriteBlock(start, target, columnCount, writer);
77 }
78
WriteBlock(int32_t start,int32_t target,int columnCount,Writer & writer)79 int32_t RdbResultSetBridge::WriteBlock(int32_t start, int32_t target, int columnCount, Writer &writer)
80 {
81 int errCode = 0;
82 int row = start;
83
84 while (!errCode && row <= target) {
85 int status = writer.AllocRow();
86 if (status != 0) {
87 LOG_ERROR("SharedBlock is full.");
88 return row - 1;
89 }
90
91 WriteColumn(columnCount, writer, row);
92 row++;
93 errCode = rdbResultSet_->GoToNextRow();
94 }
95 return target;
96 }
97
WriteColumn(int columnCount,Writer & writer,int row)98 void RdbResultSetBridge::WriteColumn(int columnCount, Writer &writer, int row)
99 {
100 for (int i = 0; i < columnCount; i++) {
101 ColumnType type;
102 rdbResultSet_->GetColumnType(i, type);
103 switch (type) {
104 case ColumnType::TYPE_INTEGER:
105 int64_t value;
106 rdbResultSet_->GetLong(i, value);
107 if (writer.Write(i, value)) {
108 LOG_DEBUG("WriteLong failed of row: %{public}d, column: %{public}d", row, i);
109 }
110 break;
111 case ColumnType::TYPE_FLOAT:
112 double dValue;
113 rdbResultSet_->GetDouble(i, dValue);
114 if (writer.Write(i, dValue)) {
115 LOG_DEBUG("WriteDouble failed of row: %{public}d, column: %{public}d", row, i);
116 }
117 break;
118 case ColumnType::TYPE_NULL:
119 if (writer.Write(i)) {
120 LOG_DEBUG("WriteNull failed of row: row: %{public}d, column: %{public}d", row, i);
121 }
122 break;
123 case ColumnType::TYPE_BLOB:
124 if (WriteBlobData(i, writer)) {
125 LOG_DEBUG("WriteBlob failed of row: %{public}d, column: %{public}d", row, i);
126 }
127 break;
128 default:
129 std::string stringValue;
130 rdbResultSet_->GetString(i, stringValue);
131 if (writer.Write(i, stringValue.c_str(), stringValue.size() + 1)) {
132 LOG_DEBUG("WriteString failed of row: %{public}d, column: %{public}d", row, i);
133 }
134 }
135 }
136 }
137
WriteBlobData(int column,Writer & writer)138 bool RdbResultSetBridge::WriteBlobData(int column, Writer &writer)
139 {
140 std::vector<uint8_t> blobValue;
141 rdbResultSet_->GetBlob(column, blobValue);
142 if (blobValue.empty()) {
143 return false;
144 }
145
146 return writer.Write(column, &blobValue[0], blobValue.size() * sizeof(uint8_t));
147 }
148 } // namespace RdbDataShareAdapter
149 } // namespace OHOS
150