1 /*
2 * Copyright (c) 2021 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 #ifdef RELATIONAL_STORE
16 #include "relational_row_data_set.h"
17 #include "relational_row_data_impl.h"
18
19 namespace DistributedDB {
RelationalRowDataSet()20 RelationalRowDataSet::RelationalRowDataSet() : serialLength_(Parcel::GetUInt32Len() + Parcel::GetUInt32Len()) {}
21
~RelationalRowDataSet()22 RelationalRowDataSet::~RelationalRowDataSet()
23 {
24 RelationalRowData::Release(data_);
25 }
26
operator =(RelationalRowDataSet && r)27 RelationalRowDataSet &RelationalRowDataSet::operator=(RelationalRowDataSet &&r) noexcept
28 {
29 if (&r == this) {
30 return *this;
31 }
32
33 colNames_ = std::move(r.colNames_);
34 data_ = std::move(r.data_);
35 serialLength_ = r.serialLength_;
36
37 r.serialLength_ = Parcel::GetUInt32Len() + Parcel::GetUInt32Len();
38 return *this;
39 }
40
GetSize() const41 int RelationalRowDataSet::GetSize() const
42 {
43 return data_.size();
44 }
45
CalcLength() const46 int RelationalRowDataSet::CalcLength() const
47 {
48 if (serialLength_ > static_cast<size_t>(INT32_MAX)) {
49 return 0;
50 }
51 return static_cast<int>(Parcel::GetEightByteAlign(serialLength_));
52 }
53
Serialize(Parcel & parcel) const54 int RelationalRowDataSet::Serialize(Parcel &parcel) const
55 {
56 if (serialLength_ > static_cast<size_t>(INT32_MAX) || parcel.IsError()) {
57 return -E_PARSE_FAIL;
58 }
59
60 (void)parcel.WriteUInt32(colNames_.size());
61 for (const auto &colName : colNames_) {
62 (void)parcel.WriteString(colName);
63 }
64 (void)parcel.WriteUInt32(data_.size());
65 for (const auto &rowData : data_) {
66 rowData->Serialize(parcel);
67 }
68
69 parcel.EightByteAlign();
70 if (parcel.IsError()) {
71 return -E_PARSE_FAIL;
72 }
73 return E_OK;
74 };
75
DeSerialize(Parcel & parcel)76 int RelationalRowDataSet::DeSerialize(Parcel &parcel)
77 {
78 Clear();
79 uint32_t size = 0;
80 parcel.ReadUInt32(size);
81 if (parcel.IsError() || size > DBConstant::MAX_REMOTEDATA_SIZE / parcel.GetStringLen(std::string {})) {
82 LOGE("parcel size is wrong when get string, errcode: %d, size: %" PRIu32, -E_PARSE_FAIL, size);
83 return -E_PARSE_FAIL;
84 }
85 while (size-- > 0) {
86 std::string str;
87 parcel.ReadString(str);
88 if (parcel.IsError()) {
89 LOGE("parcel read string wrong, errcode: %d", -E_PARSE_FAIL);
90 return -E_PARSE_FAIL;
91 }
92 colNames_.emplace_back(std::move(str));
93 }
94
95 parcel.ReadUInt32(size);
96 if (parcel.IsError() || size > DBConstant::MAX_REMOTEDATA_SIZE / parcel.GetUInt32Len()) {
97 LOGE("parcel size is wrong when get int, errcode: %d, size: %" PRIu32, -E_PARSE_FAIL, size);
98 return -E_PARSE_FAIL;
99 }
100 while (size-- > 0) {
101 auto rowData = new (std::nothrow) RelationalRowDataImpl();
102 if (rowData == nullptr) {
103 LOGE("alloc rowData wrong, errcode: %d", -E_OUT_OF_MEMORY);
104 return -E_OUT_OF_MEMORY;
105 }
106
107 if (rowData->DeSerialize(parcel) != E_OK) {
108 delete rowData;
109 rowData = nullptr;
110 LOGE("rowData deserialize wrong, errcode: %d", -E_PARSE_FAIL);
111 return -E_PARSE_FAIL;
112 }
113 data_.push_back(rowData);
114 }
115 parcel.EightByteAlign();
116 if (parcel.IsError()) {
117 LOGE("parcel align wrong, errcode: %d", -E_PARSE_FAIL);
118 return -E_PARSE_FAIL;
119 }
120 return E_OK;
121 };
122
SetColNames(std::vector<std::string> && colNames)123 void RelationalRowDataSet::SetColNames(std::vector<std::string> &&colNames)
124 {
125 for (const auto &colName : colNames_) {
126 serialLength_ -= Parcel::GetStringLen(colName);
127 }
128 colNames_ = std::move(colNames);
129 for (const auto &colName : colNames_) {
130 serialLength_ += Parcel::GetStringLen(colName);
131 }
132 }
133
SetRowData(std::vector<RelationalRowData * > && data)134 void RelationalRowDataSet::SetRowData(std::vector<RelationalRowData *> &&data)
135 {
136 for (const auto &rowData : data_) {
137 serialLength_ -= static_cast<size_t>(rowData->CalcLength());
138 }
139 data_ = data;
140 for (const auto &rowData : data_) {
141 serialLength_ += static_cast<size_t>(rowData->CalcLength());
142 }
143 }
144
Insert(RelationalRowData * rowData)145 int RelationalRowDataSet::Insert(RelationalRowData *rowData)
146 {
147 if (rowData == nullptr) {
148 return -E_INVALID_ARGS;
149 }
150 if ((serialLength_ + static_cast<size_t>(rowData->CalcLength())) > static_cast<size_t>(INT32_MAX)) {
151 return -E_INVALID_ARGS;
152 }
153 data_.push_back(rowData);
154 serialLength_ += static_cast<size_t>(rowData->CalcLength());
155 return E_OK;
156 }
157
Clear()158 void RelationalRowDataSet::Clear()
159 {
160 colNames_.clear();
161 RelationalRowData::Release(data_);
162 serialLength_ = Parcel::GetUInt32Len() + Parcel::GetUInt32Len();
163 }
164
GetColNames() const165 const std::vector<std::string> &RelationalRowDataSet::GetColNames() const
166 {
167 return colNames_;
168 }
169
Get(int index) const170 const RelationalRowData *RelationalRowDataSet::Get(int index) const
171 {
172 if (index < 0 || index >= static_cast<int>(data_.size())) {
173 return nullptr;
174 }
175 return data_.at(index);
176 }
177
Merge(RelationalRowDataSet && rowDataSet)178 int RelationalRowDataSet::Merge(RelationalRowDataSet &&rowDataSet)
179 {
180 if (this == &rowDataSet) {
181 return -E_INVALID_ARGS;
182 }
183
184 if (!rowDataSet.colNames_.empty()) {
185 if (colNames_.empty()) {
186 colNames_ = std::move(rowDataSet.colNames_);
187 } else if (colNames_ != rowDataSet.colNames_) {
188 return -E_INVALID_ARGS;
189 }
190 }
191
192 data_.insert(data_.end(), rowDataSet.data_.begin(), rowDataSet.data_.end());
193 rowDataSet.data_.clear();
194 rowDataSet.serialLength_ = Parcel::GetUInt32Len() + Parcel::GetUInt32Len();
195 return E_OK;
196 }
197 }
198 #endif