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