record refactoring

This commit is contained in:
Sascha Kuehl 2024-03-17 16:32:08 +01:00
parent 9a02abacea
commit 12919ba372
21 changed files with 390 additions and 118 deletions

View File

@ -206,13 +206,13 @@ TEST_CASE_METHOD(QueryRecordFixture, "Execute update record statement", "[sessio
for (const auto &i: result) { for (const auto &i: result) {
REQUIRE(i.size() == 3); REQUIRE(i.size() == 3);
REQUIRE(i.at(0).name() == "id"); REQUIRE(i.at(0).name() == "id");
REQUIRE(i.at(0).type() == data_type_t::type_long_long); REQUIRE(i.at(0).is_integer());
REQUIRE(i.at(0).as<long long>() == 7); REQUIRE(i.at(0).as<long long>() == 7);
REQUIRE(i.at(1).name() == "name"); REQUIRE(i.at(1).name() == "name");
REQUIRE(i.at(1).type() == data_type_t::type_varchar); REQUIRE(i.at(1).is_string());
REQUIRE(i.at(1).as<std::string>() == "jane"); REQUIRE(i.at(1).as<std::string>() == "jane");
REQUIRE(i.at(2).name() == "age"); REQUIRE(i.at(2).name() == "age");
REQUIRE(i.at(2).type() == matador::sql::data_type_t::type_int); REQUIRE(i.at(2).is_integer());
REQUIRE(i.at(2).as<int>() == 35); REQUIRE(i.at(2).as<int>() == 35);
} }

View File

@ -93,13 +93,13 @@ TEST_CASE_METHOD(QueryFixture, "Execute select statement with where clause", "[s
for (const auto &i: result_record) { for (const auto &i: result_record) {
REQUIRE(i.size() == 4); REQUIRE(i.size() == 4);
REQUIRE(i.at(0).name() == "id"); REQUIRE(i.at(0).name() == "id");
REQUIRE(i.at(0).type() == data_type_t::type_long_long); REQUIRE(i.at(0).is_integer());
REQUIRE(i.at(0).as<long long>() == george.id); REQUIRE(i.at(0).as<long long>() == george.id);
REQUIRE(i.at(1).name() == "name"); REQUIRE(i.at(1).name() == "name");
REQUIRE(i.at(1).type() == data_type_t::type_varchar); REQUIRE(i.at(1).is_string());
REQUIRE(i.at(1).as<std::string>() == george.name); REQUIRE(i.at(1).as<std::string>() == george.name);
REQUIRE(i.at(2).name() == "age"); REQUIRE(i.at(2).name() == "age");
REQUIRE(i.at(2).type() == matador::sql::data_type_t::type_long_long); REQUIRE(i.at(2).is_integer());
REQUIRE(i.at(2).as<long long>() == george.age); REQUIRE(i.at(2).as<long long>() == george.age);
} }
@ -144,13 +144,13 @@ TEST_CASE_METHOD(QueryFixture, "Execute insert statement", "[session]")
for (const auto &i: result_record) { for (const auto &i: result_record) {
REQUIRE(i.size() == 3); REQUIRE(i.size() == 3);
REQUIRE(i.at(0).name() == "id"); REQUIRE(i.at(0).name() == "id");
REQUIRE(i.at(0).type() == data_type_t::type_long_long); REQUIRE(i.at(0).is_integer());
REQUIRE(i.at(0).as<unsigned long>() == 7); REQUIRE(i.at(0).as<unsigned long>() == 7);
REQUIRE(i.at(1).name() == "name"); REQUIRE(i.at(1).name() == "name");
REQUIRE(i.at(1).type() == data_type_t::type_varchar); REQUIRE(i.at(1).is_string());
REQUIRE(i.at(1).as<std::string>() == "george"); REQUIRE(i.at(1).as<std::string>() == "george");
REQUIRE(i.at(2).name() == "color"); REQUIRE(i.at(2).name() == "color");
REQUIRE(i.at(2).type() == matador::sql::data_type_t::type_varchar); REQUIRE(i.at(2).is_string());
REQUIRE(i.at(2).as<std::string>() == "green"); REQUIRE(i.at(2).as<std::string>() == "green");
} }

View File

@ -108,8 +108,6 @@ private:
using data_type_index = std::vector<data_type_t>; using data_type_index = std::vector<data_type_t>;
private: private:
friend class record;
static const data_type_index data_type_index_; static const data_type_index data_type_index_;
std::string name_; std::string name_;

View File

@ -3,6 +3,7 @@
#include "matador/sql/any_type.hpp" #include "matador/sql/any_type.hpp"
#include "matador/sql/any_type_to_visitor.hpp" #include "matador/sql/any_type_to_visitor.hpp"
#include "matador/sql/data_type_traits.hpp"
#include "matador/utils/types.hpp" #include "matador/utils/types.hpp"
@ -64,11 +65,13 @@ class field
public: public:
explicit field(std::string name); explicit field(std::string name);
template<typename Type> template<typename Type>
field(std::string name, Type value, int index = -1) field(std::string name, Type value, size_t size = 0, int index = -1)
: name_(std::move(name)) : name_(std::move(name))
, size_(size)
, index_(index) , index_(index)
, value_(value) , value_(value)
, type_(field_traits<Type>::type()) {} , type_(field_traits<Type>::type()) {}
field(std::string name, data_type_t data_type, size_t size = 0, int index = -1);
field(const field &x) = default; field(const field &x) = default;
field& operator=(const field &x) = default; field& operator=(const field &x) = default;
field(field &&x) noexcept; field(field &&x) noexcept;
@ -82,6 +85,7 @@ public:
} }
[[nodiscard]] const std::string& name() const; [[nodiscard]] const std::string& name() const;
[[nodiscard]] size_t size() const;
[[nodiscard]] int index() const; [[nodiscard]] int index() const;
template<class Type> template<class Type>
@ -104,9 +108,21 @@ public:
friend std::ostream& operator<<(std::ostream &out, const field &col); friend std::ostream& operator<<(std::ostream &out, const field &col);
private: private:
template<class Operator>
void process(Operator &op)
{
op.on_attribute(name_.c_str(), value_, field_type_to_data_type(type_), size_);
}
private:
friend class record;
static data_type_t field_type_to_data_type(field_type type);
std::string name_; std::string name_;
int index_{-1}; int index_{-1};
any_type value_; any_type value_;
size_t size_{};
field_type type_; field_type type_;
}; };

View File

@ -1,7 +1,7 @@
#ifndef QUERY_QUERY_CONTEXT_HPP #ifndef QUERY_QUERY_CONTEXT_HPP
#define QUERY_QUERY_CONTEXT_HPP #define QUERY_QUERY_CONTEXT_HPP
#include "matador/sql/record.hpp" #include "matador/sql/column_definition.hpp"
#include "matador/sql/table.hpp" #include "matador/sql/table.hpp"
namespace matador::sql { namespace matador::sql {

View File

@ -67,7 +67,7 @@ public:
template<typename Type> template<typename Type>
Type fetch_value() Type fetch_value()
{ {
return fetch_one().at(0).as<Type>(); return fetch_one().at(0).as<Type>().value();
} }
statement prepare(); statement prepare();

View File

@ -8,6 +8,8 @@
namespace matador::sql { namespace matador::sql {
class record;
template < typename Type > template < typename Type >
class query_result; class query_result;

View File

@ -7,7 +7,7 @@
#include "matador/sql/any_type.hpp" #include "matador/sql/any_type.hpp"
#include "matador/sql/query_result_reader.hpp" #include "matador/sql/query_result_reader.hpp"
#include "matador/sql/record.hpp" #include "matador/sql/column_definition.hpp"
#include "matador/sql/data_type_traits.hpp" #include "matador/sql/data_type_traits.hpp"
#include <memory> #include <memory>
@ -73,6 +73,7 @@ public:
void on_attribute(const char *id, char *value, const utils::field_attributes &attr = utils::null_attributes); void on_attribute(const char *id, char *value, const utils::field_attributes &attr = utils::null_attributes);
void on_attribute(const char *id, std::string &value, const utils::field_attributes &attr = utils::null_attributes); void on_attribute(const char *id, std::string &value, const utils::field_attributes &attr = utils::null_attributes);
void on_attribute(const char *id, any_type &value, data_type_t type, const utils::field_attributes &attr = utils::null_attributes); void on_attribute(const char *id, any_type &value, data_type_t type, const utils::field_attributes &attr = utils::null_attributes);
// void on_attribute(const char *id, any_type &value, data_type_t type, const utils::field_attributes &attr = utils::null_attributes);
template < class Pointer > template < class Pointer >
void on_belongs_to(const char * /*id*/, Pointer &x, const utils::foreign_attributes &/*attr*/) void on_belongs_to(const char * /*id*/, Pointer &x, const utils::foreign_attributes &/*attr*/)

View File

@ -3,7 +3,7 @@
#include "matador/utils/access.hpp" #include "matador/utils/access.hpp"
#include "matador/sql/column_definition.hpp" #include "matador/sql/field.hpp"
#include <vector> #include <vector>
#include <unordered_map> #include <unordered_map>
@ -15,17 +15,17 @@ struct column;
class record class record
{ {
private: private:
using column_by_index = std::vector<column_definition>; using field_by_index = std::vector<field>;
using column_index_pair = std::pair<std::reference_wrapper<column_definition>, size_t>; using field_index_pair = std::pair<std::reference_wrapper<field>, field_by_index::difference_type>;
using column_by_name_map = std::unordered_map<std::string, column_index_pair>; using field_by_name_map = std::unordered_map<std::string, field_index_pair>;
public: public:
using iterator = column_by_index::iterator; using iterator = field_by_index::iterator;
using const_iterator = column_by_index::const_iterator; using const_iterator = field_by_index::const_iterator;
record() = default; record() = default;
record(std::initializer_list<column_definition> columns); record(std::initializer_list<field> columns);
explicit record(const std::vector<column_definition> &columns); explicit record(const std::vector<field> &columns);
record(const record &x); record(const record &x);
record& operator=(const record &x); record& operator=(const record &x);
record(record&&) noexcept = default; record(record&&) noexcept = default;
@ -35,25 +35,17 @@ public:
template<class Operator> template<class Operator>
void process(Operator &op) void process(Operator &op)
{ {
for(auto &col : columns_) { for(auto &f : fields_) {
col.process(op); f.process(op);
} }
} }
template < typename Type >
void append(const std::string &name, long size = -1)
{
append(make_column<Type>(name, size));
}
void append(column_definition col); void append(field col);
[[nodiscard]] bool has_primary_key() const; [[nodiscard]] const std::vector<field>& columns() const;
[[nodiscard]] std::optional<column_definition> primary_key() const;
[[nodiscard]] const std::vector<column_definition>& columns() const; [[nodiscard]] const field& at(const column &col) const;
[[nodiscard]] const field& at(size_t index) const;
[[nodiscard]] const column_definition& at(const column &col) const;
[[nodiscard]] const column_definition& at(size_t index) const;
iterator find(const std::string &column_name); iterator find(const std::string &column_name);
[[nodiscard]] const_iterator find(const std::string &column_name) const; [[nodiscard]] const_iterator find(const std::string &column_name) const;
@ -70,17 +62,17 @@ public:
[[nodiscard]] bool empty() const; [[nodiscard]] bool empty() const;
void clear(); void clear();
[[nodiscard]] bool unknown() const; // [[nodiscard]] bool unknown() const;
private: private:
void init(); void init();
void add_to_map(column_definition &col, size_t index); void add_to_map(field &col, size_t index);
private: private:
column_by_index columns_; field_by_index fields_;
column_by_name_map columns_by_name_; field_by_name_map fields_by_name_;
int pk_index_{-1}; // int pk_index_{-1};
}; };
} }

View File

@ -2,7 +2,7 @@
#define QUERY_SCHEMA_HPP #define QUERY_SCHEMA_HPP
#include "matador/sql/column_generator.hpp" #include "matador/sql/column_generator.hpp"
#include "matador/sql/record.hpp" #include "matador/sql/table_definition.hpp"
#include <optional> #include <optional>
#include <string> #include <string>
@ -16,7 +16,7 @@ class connection;
struct table_info struct table_info
{ {
std::string name; std::string name;
record prototype; table_definition prototype;
}; };
class schema class schema
@ -38,7 +38,7 @@ public:
template<typename Type> template<typename Type>
const table_info& attach(const std::string &table_name) const table_info& attach(const std::string &table_name)
{ {
return attach(std::type_index(typeid(Type)), table_info{table_name, record{column_generator::generate<Type>(*this)}}); return attach(std::type_index(typeid(Type)), table_info{table_name, table_definition{column_generator::generate<Type>(*this)}});
} }
const table_info& attach(std::type_index ti, const table_info& table); const table_info& attach(std::type_index ti, const table_info& table);

View File

@ -79,7 +79,7 @@ private:
const class dialect &dialect_; const class dialect &dialect_;
std::unique_ptr<schema> schema_; std::unique_ptr<schema> schema_;
mutable std::unordered_map<std::string, record> prototypes_; mutable std::unordered_map<std::string, table_definition> prototypes_;
}; };
template<typename Type> template<typename Type>

View File

@ -0,0 +1,73 @@
#ifndef QUERY_TABLE_DEFINITION_HPP
#define QUERY_TABLE_DEFINITION_HPP
#include "matador/sql/column.hpp"
#include "matador/sql/column_definition.hpp"
#include <unordered_map>
namespace matador::sql {
class table_definition final
{
private:
using column_by_index = std::vector<column_definition>;
using column_index_pair = std::pair<std::reference_wrapper<column_definition>, column_by_index::difference_type>;
using column_by_name_map = std::unordered_map<std::string, column_index_pair>;
public:
using iterator = column_by_index::iterator;
using const_iterator = column_by_index::const_iterator;
table_definition() = default;
table_definition(std::initializer_list<column_definition> columns);
explicit table_definition(const std::vector<column_definition> &columns);
table_definition(const table_definition &x);
table_definition& operator=(const table_definition &x);
table_definition(table_definition&&) noexcept = default;
table_definition& operator=(table_definition&&) noexcept = default;
~table_definition() = default;
[[nodiscard]] bool has_primary_key() const;
[[nodiscard]] std::optional<column_definition> primary_key() const;
template < typename Type >
void append(const std::string &name, long size = -1)
{
append(make_column<Type>(name, size));
}
void append(column_definition col);
[[nodiscard]] const std::vector<column_definition>& columns() const;
[[nodiscard]] const column_definition& at(const column &col) const;
[[nodiscard]] const column_definition& at(size_t index) const;
iterator find(const std::string &column_name);
[[nodiscard]] const_iterator find(const std::string &column_name) const;
iterator begin();
[[nodiscard]] const_iterator begin() const;
[[nodiscard]] const_iterator cbegin() const;
iterator end();
[[nodiscard]] const_iterator end() const;
[[nodiscard]] const_iterator cend() const;
[[nodiscard]] size_t size() const;
[[nodiscard]] bool empty() const;
void clear();
private:
void init();
void add_to_map(column_definition &col, size_t index);
private:
column_by_index columns_;
column_by_name_map columns_by_name_;
int pk_index_{-1};
};
}
#endif //QUERY_TABLE_DEFINITION_HPP

View File

@ -36,6 +36,7 @@ set(SQL_SOURCES
sql/query_part.cpp sql/query_part.cpp
sql/any_type_to_string_visitor.cpp sql/any_type_to_string_visitor.cpp
sql/field.cpp sql/field.cpp
sql/table_definition.cpp
) )
set(SQL_HEADER set(SQL_HEADER
@ -89,6 +90,7 @@ set(SQL_HEADER
../include/matador/sql/query_helper.hpp ../include/matador/sql/query_helper.hpp
../include/matador/sql/field.hpp ../include/matador/sql/field.hpp
../include/matador/sql/entity_query_builder.hpp ../include/matador/sql/entity_query_builder.hpp
../include/matador/sql/table_definition.hpp
) )
set(QUERY_SOURCES set(QUERY_SOURCES

View File

@ -1,5 +1,7 @@
#include "matador/sql/field.hpp" #include "matador/sql/field.hpp"
#include <ostream>
namespace matador::sql { namespace matador::sql {
field::field(std::string name) field::field(std::string name)
@ -8,6 +10,11 @@ field::field(std::string name)
, type_(field_traits<nullptr_t>::type()) , type_(field_traits<nullptr_t>::type())
{} {}
field::field(std::string name, data_type_t data_type, size_t size, int index)
{
}
field::field(field &&x) noexcept field::field(field &&x) noexcept
: name_(std::move(x.name_)) : name_(std::move(x.name_))
, index_(x.index_) , index_(x.index_)
@ -37,6 +44,11 @@ const std::string &field::name() const
return name_; return name_;
} }
size_t field::size() const
{
return size_;
}
int field::index() const int field::index() const
{ {
return index_; return index_;
@ -83,4 +95,24 @@ bool field::is_null() const
return type_ == field_type::Null; return type_ == field_type::Null;
} }
data_type_t field::field_type_to_data_type(field_type type)
{
switch (type) {
case field_type::Integer:
return data_type_t::type_long_long;
case field_type::FloatingPoint:
return data_type_t::type_double;
case field_type::String:
return data_type_t::type_varchar;
case field_type::Boolean:
return data_type_t::type_bool;
case field_type::Blob:
return data_type_t::type_blob;
case field_type::Null:
return data_type_t::type_null;
default:
return data_type_t::type_unknown;
}
}
} }

View File

@ -1,11 +1,17 @@
#include "matador/sql/query_result.hpp" #include "matador/sql/query_result.hpp"
#include "matador/sql/record.hpp"
namespace matador::sql::detail { namespace matador::sql::detail {
template<> template<>
record *create_prototype<record>(const std::vector<column_definition> &prototype) record *create_prototype<record>(const std::vector<column_definition> &prototype)
{ {
return new record{prototype}; auto result = std::make_unique<record>();
// for (const auto &col: prototype) {
// result->append({})
// }
return result.release();
} }
} }

View File

@ -6,23 +6,23 @@
namespace matador::sql { namespace matador::sql {
record::record(std::initializer_list<column_definition> columns) record::record(std::initializer_list<field> columns)
: columns_(columns) : fields_(columns)
{ {
init(); init();
} }
record::record(const std::vector<column_definition> &columns) record::record(const std::vector<field> &columns)
: columns_(columns) : fields_(columns)
{ {
init(); init();
} }
record::record(const record &x) record::record(const record &x)
: columns_(x.columns_) : fields_(x.fields_)
, pk_index_(x.pk_index_) //, pk_index_(x.pk_index_)
{ {
for (auto& col : columns_) { for (auto& col : fields_) {
add_to_map(col, col.index()); add_to_map(col, col.index());
} }
} }
@ -33,128 +33,128 @@ record &record::operator=(const record &x)
return *this; return *this;
} }
columns_ = x.columns_; fields_ = x.fields_;
columns_by_name_.clear(); fields_by_name_.clear();
pk_index_ = x.pk_index_; // pk_index_ = x.pk_index_;
for (auto& col : columns_) { for (auto& col : fields_) {
add_to_map(col, col.index()); add_to_map(col, col.index());
} }
return *this; return *this;
} }
const std::vector<column_definition> &record::columns() const const std::vector<field> &record::columns() const
{ {
return columns_; return fields_;
} }
bool record::has_primary_key() const //bool record::has_primary_key() const
//{
// return pk_index_ > -1;
//}
//
//std::optional<field> record::primary_key() const
//{
// if (!has_primary_key()) {
// return std::nullopt;
// }
//
// return columns_[pk_index_];
//}
const field &record::at(const column &col) const
{ {
return pk_index_ > -1; return fields_by_name_.at(col.name).first;
} }
std::optional<column_definition> record::primary_key() const const field &record::at(size_t index) const
{ {
if (!has_primary_key()) { return fields_.at(index);
return std::nullopt;
}
return columns_[pk_index_];
}
const column_definition &record::at(const column &col) const
{
return columns_by_name_.at(col.name).first;
}
const column_definition &record::at(size_t index) const
{
return columns_.at(index);
} }
record::iterator record::find(const std::string &column_name) record::iterator record::find(const std::string &column_name)
{ {
auto it = columns_by_name_.find(column_name); auto it = fields_by_name_.find(column_name);
return it != columns_by_name_.end() ? columns_.begin() + it->second.second : columns_.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 = columns_by_name_.find(column_name); auto it = fields_by_name_.find(column_name);
return it != columns_by_name_.end() ? columns_.begin() + it->second.second : columns_.end(); return it != fields_by_name_.end() ? fields_.begin() + it->second.second : fields_.end();
} }
void record::append(column_definition col) void record::append(field col)
{ {
auto &ref = columns_.emplace_back(std::move(col)); auto &ref = fields_.emplace_back(std::move(col));
add_to_map(ref, columns_.size()-1); add_to_map(ref, fields_.size() - 1);
} }
record::iterator record::begin() record::iterator record::begin()
{ {
return columns_.begin(); return fields_.begin();
} }
record::const_iterator record::begin() const record::const_iterator record::begin() const
{ {
return columns_.begin(); return fields_.begin();
} }
record::const_iterator record::cbegin() const record::const_iterator record::cbegin() const
{ {
return columns_.cbegin(); return fields_.cbegin();
} }
record::iterator record::end() record::iterator record::end()
{ {
return columns_.end(); return fields_.end();
} }
record::const_iterator record::end() const record::const_iterator record::end() const
{ {
return columns_.end(); return fields_.end();
} }
record::const_iterator record::cend() const record::const_iterator record::cend() const
{ {
return columns_.cend(); return fields_.cend();
} }
size_t record::size() const size_t record::size() const
{ {
return columns_.size(); return fields_.size();
} }
bool record::empty() const bool record::empty() const
{ {
return columns_.empty(); return fields_.empty();
} }
void record::clear() void record::clear()
{ {
columns_.clear(); fields_.clear();
columns_by_name_.clear(); fields_by_name_.clear();
} }
bool record::unknown() const //bool record::unknown() const
{ //{
return std::all_of(std::begin(columns_), std::end(columns_), [](const auto &col) { // return std::all_of(std::begin(columns_), std::end(columns_), [](const auto &col) {
return col.type() == data_type_t::type_unknown; // return col.type() == data_type_t::type_unknown;
}); // });
} //}
void record::init() void record::init()
{ {
size_t index{0}; size_t index{0};
for(auto &col : columns_) { for(auto &col : fields_) {
add_to_map(col, index++); add_to_map(col, index++);
} }
} }
void record::add_to_map(column_definition &col, size_t index) void record::add_to_map(field &col, size_t index)
{ {
columns_by_name_.emplace(col.name(), column_index_pair {std::ref(col), index}); fields_by_name_.emplace(col.name(), field_index_pair {std::ref(col), index});
if (utils::is_constraint_set(col.attributes().options(), utils::constraints::PRIMARY_KEY)) { // if (utils::is_constraint_set(col.attributes().options(), utils::constraints::PRIMARY_KEY)) {
pk_index_ = static_cast<int>(index); // pk_index_ = static_cast<int>(index);
} // }
} }
} }

View File

@ -0,0 +1,148 @@
#include "matador/sql/table_definition.hpp"
namespace matador::sql {
table_definition::table_definition(std::initializer_list<column_definition> columns)
: columns_(columns)
{
init();
}
table_definition::table_definition(const std::vector<column_definition> &columns)
: columns_(columns)
{
init();
}
table_definition::table_definition(const table_definition &x)
: columns_(x.columns_)
, pk_index_(x.pk_index_)
{
for (auto& col : columns_) {
add_to_map(col, col.index());
}
}
table_definition &table_definition::operator=(const table_definition &x)
{
if (&x == this) {
return *this;
}
columns_ = x.columns_;
columns_by_name_.clear();
pk_index_ = x.pk_index_;
for (auto& col : columns_) {
add_to_map(col, col.index());
}
return *this;
}
bool table_definition::has_primary_key() const
{
return pk_index_ > -1;
}
std::optional<column_definition> table_definition::primary_key() const
{
if (!has_primary_key()) {
return std::nullopt;
}
return columns_[pk_index_];
}
void table_definition::append(column_definition col)
{
auto &ref = columns_.emplace_back(std::move(col));
add_to_map(ref, columns_.size()-1);
}
const std::vector<column_definition> &table_definition::columns() const
{
return columns_;
}
const column_definition &table_definition::at(const column &col) const
{
return columns_by_name_.at(col.name).first;
}
const column_definition &table_definition::at(size_t index) const
{
return columns_.at(index);
}
table_definition::iterator table_definition::find(const std::string &column_name)
{
auto it = columns_by_name_.find(column_name);
return it != columns_by_name_.end() ? columns_.begin() + it->second.second : columns_.end();
}
table_definition::const_iterator table_definition::find(const std::string &column_name) const {
auto it = columns_by_name_.find(column_name);
return it != columns_by_name_.end() ? columns_.begin() + it->second.second : columns_.end();
}
table_definition::iterator table_definition::begin()
{
return columns_.begin();
}
table_definition::const_iterator table_definition::begin() const
{
return columns_.begin();
}
table_definition::const_iterator table_definition::cbegin() const
{
return columns_.cbegin();
}
table_definition::iterator table_definition::end()
{
return columns_.end();
}
table_definition::const_iterator table_definition::end() const
{
return columns_.end();
}
table_definition::const_iterator table_definition::cend() const
{
return columns_.cend();
}
size_t table_definition::size() const
{
return columns_.size();
}
bool table_definition::empty() const
{
return columns_.empty();
}
void table_definition::clear()
{
columns_.clear();
columns_by_name_.clear();
}
void table_definition::init()
{
size_t index{0};
for(auto &col : columns_) {
add_to_map(col, index++);
}
}
void table_definition::add_to_map(column_definition &col, size_t index)
{
columns_by_name_.emplace(col.name(), column_index_pair {std::ref(col), index});
if (utils::is_constraint_set(col.attributes().options(), utils::constraints::PRIMARY_KEY)) {
pk_index_ = static_cast<int>(index);
}
}
}

View File

@ -9,6 +9,8 @@ using namespace matador::sql;
TEST_CASE("Load backend", "[backend provider]") { TEST_CASE("Load backend", "[backend provider]") {
auto path = matador::utils::os::getenv("MATADOR_BACKENDS_PATH"); auto path = matador::utils::os::getenv("MATADOR_BACKENDS_PATH");
REQUIRE(!path.empty());
if (path.back() != '\\') { if (path.back() != '\\') {
path.push_back('\\'); path.push_back('\\');
} }
@ -16,8 +18,8 @@ TEST_CASE("Load backend", "[backend provider]") {
REQUIRE(!path.empty()); REQUIRE(!path.empty());
connection_info ci{}; connection_info ci{};
const auto &d = backend_provider::instance().connection_dialect("sqlite"); const auto &d = backend_provider::instance().connection_dialect("noop");
auto *connection = backend_provider::instance().create_connection("sqlite", ci); auto *connection = backend_provider::instance().create_connection("noop", ci);
REQUIRE(connection != nullptr); REQUIRE(connection != nullptr);
backend_provider::instance().destroy_connection("sqlite", connection); backend_provider::instance().destroy_connection("noop", connection);
} }

View File

@ -14,7 +14,7 @@ include(Catch)
add_executable(tests add_executable(tests
QueryBuilderTest.cpp QueryBuilderTest.cpp
RecordTest.cpp TableDefinitionTest.cpp
ConnectionPoolTest.cpp ConnectionPoolTest.cpp
BackendProviderTest.cpp BackendProviderTest.cpp
models/product.hpp models/product.hpp

View File

@ -37,7 +37,7 @@ TEST_CASE("Field test", "[field]") {
REQUIRE(bool_val.has_value()); REQUIRE(bool_val.has_value());
REQUIRE(bool_val.value()); REQUIRE(bool_val.value());
f = sql::field("name", utils::blob{ 7,8,6,5,4,3 }, 1); f = sql::field("name", utils::blob{ 7,8,6,5,4,3 }, 0, 1);
REQUIRE(f.index() == 1); REQUIRE(f.index() == 1);
REQUIRE(!f.is_null()); REQUIRE(!f.is_null());
REQUIRE(!f.is_integer()); REQUIRE(!f.is_integer());

View File

@ -1,26 +1,26 @@
#include <catch2/catch_test_macros.hpp> #include <catch2/catch_test_macros.hpp>
#include <matador/sql/record.hpp> #include <matador/sql/table_definition.hpp>
#include <list> #include <list>
using namespace matador::sql; using namespace matador::sql;
TEST_CASE("Create record", "[record]") { TEST_CASE("Create record", "[record]") {
record rec({ table_definition def({
make_pk_column<unsigned long>("id"), make_pk_column<unsigned long>("id"),
make_column<std::string>("name", 255), make_column<std::string>("name", 255),
make_column<std::string>("color", 255) make_column<std::string>("color", 255)
}); });
REQUIRE(rec.size() == 3); REQUIRE(def.size() == 3);
std::list<std::string> expected_columns = {"id", "name", "color"}; std::list<std::string> expected_columns = {"id", "name", "color"};
for(const auto &col : expected_columns) { for(const auto &col : expected_columns) {
REQUIRE(rec.find(col) != rec.end()); REQUIRE(def.find(col) != def.end());
} }
for(const auto& col : rec) { for(const auto& col : def) {
expected_columns.remove(col.name()); expected_columns.remove(col.name());
} }
@ -28,7 +28,7 @@ TEST_CASE("Create record", "[record]") {
} }
TEST_CASE("Append to record", "[record]") { TEST_CASE("Append to record", "[record]") {
record rec; table_definition rec;
rec.append(make_pk_column<unsigned long>("id")); rec.append(make_pk_column<unsigned long>("id"));
rec.append<std::string>("name", 255); rec.append<std::string>("name", 255);