refactored record classe

This commit is contained in:
Sascha Kühl 2026-02-15 18:33:22 +01:00
parent 746fd9e8d2
commit 9065355ee0
3 changed files with 52 additions and 98 deletions

View File

@ -9,20 +9,14 @@
namespace matador::sql { namespace matador::sql {
class record final { class record final {
private:
using field_ref = std::reference_wrapper<field>;
using field_by_index = std::vector<field_ref>;
using field_index_pair = std::pair<field, field_by_index::difference_type>;
using field_by_name_map = std::unordered_map<std::string, field_index_pair>;
public: public:
using iterator = field_by_index::iterator; using iterator = std::vector<field>::iterator;
using const_iterator = field_by_index::const_iterator; using const_iterator = std::vector<field>::const_iterator;
record() = default; record() = default;
record(std::initializer_list<field> columns); record(std::initializer_list<field> columns);
explicit record(const std::vector<field> &columns); explicit record(const std::vector<field> &columns);
record(const record &x); record(const record &x) = default;
record& operator=(const record &x); record& operator=(const record &x);
record(record&&) noexcept = default; record(record&&) noexcept = default;
record& operator=(record&&) noexcept = default; record& operator=(record&&) noexcept = default;
@ -34,13 +28,13 @@ public:
template<class Operator> template<class Operator>
void process(Operator &op) { void process(Operator &op) {
for(auto &f : fields_) { for(auto &f : fields_) {
f.get().process(op); f.process(op);
} }
} }
void append(const field &col); void append(field col);
[[nodiscard]] const std::vector<field_ref>& columns() const; [[nodiscard]] const std::vector<field>& columns() const;
[[nodiscard]] const field& at(const std::string &name) const; [[nodiscard]] const field& at(const std::string &name) const;
[[nodiscard]] const field& at(size_t index) const; [[nodiscard]] const field& at(size_t index) const;
@ -71,12 +65,8 @@ public:
void clear(); void clear();
private: private:
void init(); std::vector<field> fields_;
void add_to_map(field &col, size_t index); std::unordered_map<std::string, std::size_t> index_by_name_;
private:
field_by_index fields_;
field_by_name_map fields_by_name_;
}; };
} }

View File

@ -7,76 +7,66 @@ namespace matador::sql {
record::record(const std::initializer_list<field> columns) { record::record(const std::initializer_list<field> columns) {
for (auto &&col :columns) { for (auto &&col :columns) {
const auto it = fields_by_name_.emplace(col.name(), field_index_pair {col, fields_.size()}); index_by_name_.emplace(col.name(), fields_.size());
fields_.push_back(std::ref(it.first->second.first)); fields_.push_back(col);
} }
} }
record::record(const std::vector<field> &columns) { record::record(const std::vector<field> &columns)
for (auto &&col :columns) { : fields_(columns) {
const auto it = fields_by_name_.emplace(col.name(), field_index_pair {col, fields_.size()}); for (auto i = 0u; i < columns.size(); ++i) {
fields_.push_back(std::ref(it.first->second.first)); index_by_name_.emplace(columns[i].name(), i);
} }
} }
record::record(const record &x) record &record::operator=(const record &x) {
: fields_by_name_(x.fields_by_name_)
{
for (auto& col : x.fields_) {
auto &it = fields_by_name_.at(col.get().name());
fields_.push_back(std::ref(it.first));
}
}
record &record::operator=(const record &x)
{
if (&x == this) { if (&x == this) {
return *this; return *this;
} }
fields_by_name_ = x.fields_by_name_; fields_ = x.fields_;
fields_.clear(); index_by_name_ = x.index_by_name_;
// pk_index_ = x.pk_index_;
for (auto& col : x.fields_) {
auto &it = fields_by_name_.at(col.get().name());
fields_.push_back(std::ref(it.first));
}
return *this; return *this;
} }
const std::vector<record::field_ref> &record::columns() const { const std::vector<field> &record::columns() const {
return fields_; return fields_;
} }
const field &record::at(const std::string &name) const { const field &record::at(const std::string &name) const {
const auto &res = fields_by_name_.at(name); const auto it = index_by_name_.find(name);
const auto &f = res.first; if (it == index_by_name_.end()) {
return f; throw std::out_of_range("Column not found");
} }
const field &record::at(const size_t index) const return fields_[it->second];
{ }
const field &record::at(const size_t index) const {
return fields_.at(index); return fields_.at(index);
} }
field &record::at(const std::string &name) { field &record::at(const std::string &name) {
auto &[fst, snd] = fields_by_name_.at(name); const auto it = index_by_name_.find(name);
return fst; if (it == index_by_name_.end()) {
throw std::out_of_range("Column not found");
}
return fields_[it->second];
} }
field &record::at(const size_t index) { field &record::at(const size_t index) {
return fields_.at(index); return fields_.at(index);
} }
record::iterator record::find(const std::string &column_name) record::iterator record::find(const std::string &column_name) {
{ const auto it = index_by_name_.find(column_name);
auto it = fields_by_name_.find(column_name); return it != index_by_name_.end() ? fields_.begin() + static_cast<long>(it->second) : fields_.end();
return it != fields_by_name_.end() ? fields_.begin() + it->second.second : fields_.end();
} }
record::const_iterator record::find(const std::string &column_name) const { record::const_iterator record::find(const std::string &column_name) const {
auto it = fields_by_name_.find(column_name); const auto it = index_by_name_.find(column_name);
return it != fields_by_name_.end() ? fields_.begin() + it->second.second : fields_.end(); return it != index_by_name_.end() ? fields_.begin() + static_cast<long>(it->second) : fields_.end();
} }
bool record::operator==(const record &rhs) const { bool record::operator==(const record &rhs) const {
@ -95,68 +85,45 @@ bool record::operator!=(const record &rhs) const {
return !operator==(rhs); return !operator==(rhs);
} }
void record::append(const field &col) { void record::append(field col) {
const auto [fst, snd] = fields_by_name_.emplace(col.name(), field_index_pair {col, fields_.size()}); index_by_name_.emplace(col.name(), fields_.size());
fields_.push_back(std::ref(fst->second.first)); fields_.push_back(std::move(col));
} }
record::iterator record::begin() record::iterator record::begin() {
{
return fields_.begin(); return fields_.begin();
} }
record::const_iterator record::begin() const record::const_iterator record::begin() const {
{
return fields_.begin(); return fields_.begin();
} }
record::const_iterator record::cbegin() const record::const_iterator record::cbegin() const {
{
return fields_.cbegin(); return fields_.cbegin();
} }
record::iterator record::end() record::iterator record::end() {
{
return fields_.end(); return fields_.end();
} }
record::const_iterator record::end() const record::const_iterator record::end() const {
{
return fields_.end(); return fields_.end();
} }
record::const_iterator record::cend() const record::const_iterator record::cend() const {
{
return fields_.cend(); return fields_.cend();
} }
size_t record::size() const size_t record::size() const {
{
return fields_.size(); return fields_.size();
} }
bool record::empty() const bool record::empty() const {
{
return fields_.empty(); return fields_.empty();
} }
void record::clear() void record::clear() {
{
fields_.clear(); fields_.clear();
fields_by_name_.clear(); index_by_name_.clear();
}
void record::init()
{
size_t index{0};
for(auto &col : fields_) {
add_to_map(col, index++);
} }
} }
void record::add_to_map(field &col, size_t index)
{
fields_by_name_.emplace(col.name(), field_index_pair {std::ref(col), index});
}
}

View File

@ -33,22 +33,19 @@ record_printer::record_printer(std::ostream &os)
} }
void record_printer::print_header(const sql::record &rec) const { void record_printer::print_header(const sql::record &rec) const {
for (const auto &f_ref: rec.columns()) { for (const auto &f: rec.columns()) {
const auto &f = f_ref.get();
os_ << std::left << std::setw(width(f)) << f.name() << " "; os_ << std::left << std::setw(width(f)) << f.name() << " ";
} }
os_ << "\n"; os_ << "\n";
for (const auto &f_ref: rec.columns()) { for (const auto &f: rec.columns()) {
const auto &f = f_ref.get();
os_ << std::string(width(f), '-') << " "; os_ << std::string(width(f), '-') << " ";
} }
os_ << "\n"; os_ << "\n";
} }
void record_printer::print(const sql::record &rec) const { void record_printer::print(const sql::record &rec) const {
for (const auto &f_ref: rec.columns()) { for (const auto &f: rec.columns()) {
const auto &f = f_ref.get();
os_ << std::left << std::setw(width(f)) << f.str() << " "; os_ << std::left << std::setw(width(f)) << f.str() << " ";
} }
os_ << "\n"; os_ << "\n";