LiteLoaderBDS-1.16.40/LiteLoader/Kernel/DB/Row.cpp
2022-09-21 19:47:03 +08:00

191 lines
4.8 KiB
C++

#include <DB/Row.h>
namespace DB {
RowHeader::RowHeader(const std::initializer_list<std::string>& list)
: std::vector<std::string>(list) {
}
RowHeader::~RowHeader() {
}
size_t RowHeader::add(const std::string& name) {
push_back(name);
hashes.push_back(do_hash2(name));
return size() - 1;
}
bool RowHeader::contains(const std::string& name) {
return std::find(hashes.begin(), hashes.end(), do_hash2(name)) != hashes.end();
}
void RowHeader::remove(const std::string& name) {
auto hs = do_hash2(name);
for (size_t i = 0; i < size(); ++i) {
if (hashes[i] == hs) {
erase(begin() + i);
hashes.erase(hashes.begin() + i);
return;
}
}
throw std::runtime_error("RowHeader::remove: Column " + name + " is not found");
}
size_t RowHeader::at(const std::string& name) {
auto hs = do_hash2(name);
for (size_t i = 0; i < size(); ++i) {
if (hashes[i] == hs)
return i;
}
throw std::out_of_range("RowHeader::at: Column " + name + " is not found");
}
std::string& RowHeader::at(size_t index) {
return Base::at(index);
}
size_t RowHeader::size() const {
return Base::size();
}
bool RowHeader::empty() const {
return Base::empty();
}
std::vector<std::string>::iterator RowHeader::begin() {
return Base::begin();
}
std::vector<std::string>::iterator RowHeader::end() {
return Base::end();
}
bool RowHeader::check(const Row& row) const {
if (row.header.get() == this)
return true;
if (row.size() == size()) {
if (row.header && !row.header->empty()) {
if (row.header->size() == size())
return true;
else
return false;
}
return true;
}
return false;
}
size_t RowHeader::operator[](const std::string& name) {
auto hs = do_hash2(name);
for (size_t i = 0; i < size(); ++i) {
if (hashes[i] == hs)
return i;
}
return add(name);
}
std::string& RowHeader::operator[](size_t index) {
return at(index);
}
Row::Row(const std::shared_ptr<RowHeader>& header)
: header(header) {
}
Row::Row(const RowHeader& header)
: header(new RowHeader(header)) {
}
Row::Row(const std::initializer_list<Any>& list, const RowHeader& header)
: std::vector<Any>(list)
, header(new RowHeader(header)) {
if (!header.empty() && list.size() != header.size()) {
throw std::invalid_argument("Row::Row: The row and the header mismatch");
}
}
Row::Row(const std::initializer_list<Any>& list, const std::shared_ptr<RowHeader>& header)
: std::vector<Any>(list)
, header(header) {
if (header != nullptr && list.size() != header->size()) {
throw std::invalid_argument("Row::Row: The row and the header mismatch");
}
}
Row::Row(std::vector<Any>&& list, const RowHeader& header)
: std::vector<Any>(std::move(list))
, header(new RowHeader(header)) {
if (size() != header.size()) {
list = std::move(*this); // Restore
throw std::invalid_argument("Row::Row: The row and the header mismatch");
}
}
Row::Row(const std::vector<Any>& list, const RowHeader& header)
: std::vector<Any>(list)
, header(new RowHeader(header)) {
if (list.size() != header.size()) {
throw std::invalid_argument("Row::Row: The row and the header mismatch");
}
}
Row::Row(const std::initializer_list<std::pair<std::string, Any>>& list)
: header(new RowHeader()) {
for (auto& pair : list) {
header->add(pair.first);
this->push_back(pair.second);
}
}
Row::Row(Row&& row) noexcept
: header(row.header) {
*this = std::move(row);
}
Row::Row(const Row& row)
: header(row.header) {
*this = row;
}
Row& Row::operator=(Row&& row) noexcept {
header = row.header;
this->swap(row);
return *this;
}
Row& Row::operator=(const Row& row) {
header = row.header;
this->assign(row.begin(), row.end());
return *this;
}
Any& Row::operator[](const std::string& name) {
auto idx = (*header)[name];
if (idx < (int)size())
return std::vector<Any>::at(idx);
resize((size_t)idx + 1, Any());
return std::vector<Any>::at(idx);
}
const Any& Row::operator[](const std::string& name) const {
return std::vector<Any>::at(header->at(name));
}
Any& Row::at(const std::string& name) {
return std::vector<Any>::at(header->at(name));
}
const Any& Row::at(const std::string& name) const {
return std::vector<Any>::at(header->at(name));
}
void Row::forEach_ref(std::function<bool(const std::string&, Any&)> cb) {
if (!this->header)
return;
for (auto& col : *this->header) {
if (!cb(col, this->at(col)))
break;
}
}
void Row::forEach(std::function<bool(const std::string&, const Any&)> cb) const {
if (!this->header)
return;
int i = 0;
for (auto& col : *this->header) {
if (!cb(col, this->data()[i]))
break;
i++;
}
}
} // namespace DB