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 "ResultSetProxy"
16 #include "result_set_proxy.h"
17
18 #include "itypes_util.h"
19 #include "logger.h"
20 #include "message_parcel.h"
21 #include "rdb_errno.h"
22
23 namespace OHOS::NativeRdb {
24 using namespace OHOS::Rdb;
25 using Code = RemoteResultSet::Code;
26
ResultSetProxy(const sptr<IRemoteObject> & impl)27 ResultSetProxy::ResultSetProxy(const sptr<IRemoteObject> &impl) : IRemoteProxy<IResultSet>(impl)
28 {
29 LOG_INFO("Init result set proxy.");
30 remote_ = Remote();
31 }
32
~ResultSetProxy()33 ResultSetProxy::~ResultSetProxy()
34 {
35 LOG_INFO("Result set destroy, close result.");
36 Close();
37 }
38
GetColumnCount(int & count)39 int ResultSetProxy::GetColumnCount(int &count)
40 {
41 return Send(Code::CMD_GET_COLUMN_COUNT, count);
42 }
43
GetColumnType(int columnIndex,ColumnType & columnType)44 int ResultSetProxy::GetColumnType(int columnIndex, ColumnType &columnType)
45 {
46 MessageParcel reply;
47 int status = SendRequest(Code::CMD_GET_COLUMN_TYPE, reply, columnIndex);
48 if (status != E_OK) {
49 return status;
50 }
51 int32_t type;
52 if (!ITypesUtil::Unmarshal(reply, type)) {
53 return E_ERROR;
54 }
55 columnType = static_cast<ColumnType>(type);
56 return E_OK;
57 }
58
GetRowCount(int & count)59 int ResultSetProxy::GetRowCount(int &count)
60 {
61 return Send(Code::CMD_GET_ROW_COUNT, count);
62 }
63
GetRowIndex(int & position) const64 int ResultSetProxy::GetRowIndex(int &position) const
65 {
66 return Send(Code::CMD_GET_ROW_INDEX, position);
67 }
68
GoTo(int offset)69 int ResultSetProxy::GoTo(int offset)
70 {
71 MessageParcel reply;
72 return SendRequest(Code::CMD_GO_TO, reply, offset);
73 }
74
GoToRow(int position)75 int ResultSetProxy::GoToRow(int position)
76 {
77 MessageParcel reply;
78 return SendRequest(Code::CMD_GO_TO_ROW, reply, position);
79 }
80
GoToFirstRow()81 int ResultSetProxy::GoToFirstRow()
82 {
83 return Send(Code::CMD_GO_TO_FIRST_ROW);
84 }
85
GoToLastRow()86 int ResultSetProxy::GoToLastRow()
87 {
88 return Send(Code::CMD_GO_TO_LAST_ROW);
89 }
90
GoToNextRow()91 int ResultSetProxy::GoToNextRow()
92 {
93 return Send(Code::CMD_GO_TO_NEXT_ROW);
94 }
95
GoToPreviousRow()96 int ResultSetProxy::GoToPreviousRow()
97 {
98 return Send(Code::CMD_GO_TO_PREV_ROW);
99 }
100
IsEnded(bool & result)101 int ResultSetProxy::IsEnded(bool &result)
102 {
103 return Send(Code::CMD_IS_ENDED_ROW, result);
104 }
105
IsStarted(bool & result) const106 int ResultSetProxy::IsStarted(bool &result) const
107 {
108 return Send(Code::CMD_IS_STARTED_ROW, result);
109 }
110
IsAtFirstRow(bool & result) const111 int ResultSetProxy::IsAtFirstRow(bool &result) const
112 {
113 return Send(Code::CMD_IS_AT_FIRST_ROW, result);
114 }
115
IsAtLastRow(bool & result)116 int ResultSetProxy::IsAtLastRow(bool &result)
117 {
118 return Send(Code::CMD_IS_AT_LAST_ROW, result);
119 }
120
Get(int32_t col,ValueObject & value)121 int ResultSetProxy::Get(int32_t col, ValueObject &value)
122 {
123 MessageParcel reply;
124 int status = SendRequest(Code::CMD_GET, reply, col);
125 if (status != E_OK) {
126 return status;
127 }
128
129 if (!ITypesUtil::Unmarshal(reply, value.value)) {
130 return E_ERROR;
131 }
132 return E_OK;
133 }
134
GetSize(int columnIndex,size_t & size)135 int ResultSetProxy::GetSize(int columnIndex, size_t &size)
136 {
137 MessageParcel reply;
138 int status = SendRequest(Code::CMD_GET_SIZE, reply, columnIndex);
139 if (status != E_OK) {
140 return status;
141 }
142 if (!ITypesUtil::Unmarshal(reply, size)) {
143 return E_ERROR;
144 }
145 return E_OK;
146 }
147
Close()148 int ResultSetProxy::Close()
149 {
150 auto ret = Send(Code::CMD_CLOSE);
151 if (ret == E_OK) {
152 AbsResultSet::Close();
153 }
154 return ret;
155 }
156
GetColumnNames()157 std::pair<int, std::vector<std::string>> ResultSetProxy::GetColumnNames()
158 {
159 std::vector<std::string> colNames;
160 auto status = Send(Code::CMD_GET_ALL_COLUMN_NAMES, colNames);
161 if (status != E_OK) {
162 LOG_ERROR("Reply error, status:%{public}d, code:%{public}d.", status, Code::CMD_GET_ALL_COLUMN_NAMES);
163 return { status, {} };
164 }
165 return { E_OK, std::move(colNames) };
166 }
167
168 template<typename... T>
Send(uint32_t code,T &...output) const169 int ResultSetProxy::Send(uint32_t code, T &...output) const
170 {
171 MessageParcel reply;
172 auto status = SendRequest(code, reply);
173 if (status != E_OK) {
174 return status;
175 }
176 if (!ITypesUtil::Unmarshal(reply, output...)) {
177 LOG_ERROR("Unmarshal failed, code:%{public}d.", code);
178 return E_ERROR;
179 }
180 return E_OK;
181 }
182
183 template<typename... T>
SendRequest(uint32_t code,MessageParcel & reply,const T &...input) const184 int ResultSetProxy::SendRequest(uint32_t code, MessageParcel &reply, const T &...input) const
185 {
186 if (remote_ == nullptr) {
187 LOG_ERROR("remote_ is null, code:%{public}d, input:%{public}zu.", code, sizeof...(input));
188 return E_ERROR;
189 }
190
191 MessageParcel data;
192 if (!data.WriteInterfaceToken(ResultSetProxy::GetDescriptor())) {
193 LOG_ERROR("Write descriptor failed, code is %{public}d.", code);
194 return E_ERROR;
195 }
196
197 if (!ITypesUtil::Marshal(data, input...)) {
198 LOG_ERROR("Marshal failed, code is %{public}d.", code);
199 return E_ERROR;
200 }
201
202 if (!reply.SetMaxCapacity(MAX_IPC_CAPACITY)) {
203 LOG_ERROR("Set max capacity failed, code is %{public}d.", code);
204 return E_ERROR;
205 }
206
207 MessageOption mo{ MessageOption::TF_SYNC };
208 int32_t status = remote_->SendRequest(code, data, reply, mo);
209 if (status != 0) {
210 LOG_ERROR("Send failed, error:%{public}d, code:%{public}d.", status, code);
211 return E_ERROR;
212 }
213 auto success = ITypesUtil::Unmarshal(reply, status);
214 if (status != E_OK || !success) {
215 LOG_ERROR("Reply failed, status:%{public}d, code:%{public}d.", status, code);
216 return E_ERROR;
217 }
218 return status;
219 }
220 } // namespace OHOS::NativeRdb