record refactoring
This commit is contained in:
parent
9a02abacea
commit
12919ba372
|
|
@ -206,13 +206,13 @@ TEST_CASE_METHOD(QueryRecordFixture, "Execute update record statement", "[sessio
|
|||
for (const auto &i: result) {
|
||||
REQUIRE(i.size() == 3);
|
||||
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(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(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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -93,13 +93,13 @@ TEST_CASE_METHOD(QueryFixture, "Execute select statement with where clause", "[s
|
|||
for (const auto &i: result_record) {
|
||||
REQUIRE(i.size() == 4);
|
||||
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(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(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);
|
||||
}
|
||||
|
||||
|
|
@ -144,13 +144,13 @@ TEST_CASE_METHOD(QueryFixture, "Execute insert statement", "[session]")
|
|||
for (const auto &i: result_record) {
|
||||
REQUIRE(i.size() == 3);
|
||||
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(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(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");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -108,8 +108,6 @@ private:
|
|||
using data_type_index = std::vector<data_type_t>;
|
||||
|
||||
private:
|
||||
friend class record;
|
||||
|
||||
static const data_type_index data_type_index_;
|
||||
|
||||
std::string name_;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "matador/sql/any_type.hpp"
|
||||
#include "matador/sql/any_type_to_visitor.hpp"
|
||||
#include "matador/sql/data_type_traits.hpp"
|
||||
|
||||
#include "matador/utils/types.hpp"
|
||||
|
||||
|
|
@ -64,11 +65,13 @@ class field
|
|||
public:
|
||||
explicit field(std::string name);
|
||||
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))
|
||||
, size_(size)
|
||||
, index_(index)
|
||||
, value_(value)
|
||||
, 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& operator=(const field &x) = default;
|
||||
field(field &&x) noexcept;
|
||||
|
|
@ -82,6 +85,7 @@ public:
|
|||
}
|
||||
|
||||
[[nodiscard]] const std::string& name() const;
|
||||
[[nodiscard]] size_t size() const;
|
||||
[[nodiscard]] int index() const;
|
||||
|
||||
template<class Type>
|
||||
|
|
@ -104,9 +108,21 @@ public:
|
|||
friend std::ostream& operator<<(std::ostream &out, const field &col);
|
||||
|
||||
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_;
|
||||
int index_{-1};
|
||||
any_type value_;
|
||||
size_t size_{};
|
||||
field_type type_;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef 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"
|
||||
|
||||
namespace matador::sql {
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ public:
|
|||
template<typename Type>
|
||||
Type fetch_value()
|
||||
{
|
||||
return fetch_one().at(0).as<Type>();
|
||||
return fetch_one().at(0).as<Type>().value();
|
||||
}
|
||||
|
||||
statement prepare();
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
namespace matador::sql {
|
||||
|
||||
class record;
|
||||
|
||||
template < typename Type >
|
||||
class query_result;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include "matador/sql/any_type.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 <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, 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);
|
||||
|
||||
template < class Pointer >
|
||||
void on_belongs_to(const char * /*id*/, Pointer &x, const utils::foreign_attributes &/*attr*/)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "matador/utils/access.hpp"
|
||||
|
||||
#include "matador/sql/column_definition.hpp"
|
||||
#include "matador/sql/field.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
|
@ -15,17 +15,17 @@ struct column;
|
|||
class record
|
||||
{
|
||||
private:
|
||||
using column_by_index = std::vector<column_definition>;
|
||||
using column_index_pair = std::pair<std::reference_wrapper<column_definition>, size_t>;
|
||||
using column_by_name_map = std::unordered_map<std::string, column_index_pair>;
|
||||
using field_by_index = std::vector<field>;
|
||||
using field_index_pair = std::pair<std::reference_wrapper<field>, field_by_index::difference_type>;
|
||||
using field_by_name_map = std::unordered_map<std::string, field_index_pair>;
|
||||
|
||||
public:
|
||||
using iterator = column_by_index::iterator;
|
||||
using const_iterator = column_by_index::const_iterator;
|
||||
using iterator = field_by_index::iterator;
|
||||
using const_iterator = field_by_index::const_iterator;
|
||||
|
||||
record() = default;
|
||||
record(std::initializer_list<column_definition> columns);
|
||||
explicit record(const std::vector<column_definition> &columns);
|
||||
record(std::initializer_list<field> columns);
|
||||
explicit record(const std::vector<field> &columns);
|
||||
record(const record &x);
|
||||
record& operator=(const record &x);
|
||||
record(record&&) noexcept = default;
|
||||
|
|
@ -35,25 +35,17 @@ public:
|
|||
template<class Operator>
|
||||
void process(Operator &op)
|
||||
{
|
||||
for(auto &col : columns_) {
|
||||
col.process(op);
|
||||
for(auto &f : fields_) {
|
||||
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]] std::optional<column_definition> primary_key() const;
|
||||
[[nodiscard]] const std::vector<field>& columns() const;
|
||||
|
||||
[[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;
|
||||
[[nodiscard]] const field& at(const column &col) const;
|
||||
[[nodiscard]] const field& at(size_t index) const;
|
||||
|
||||
iterator find(const std::string &column_name);
|
||||
[[nodiscard]] const_iterator find(const std::string &column_name) const;
|
||||
|
|
@ -70,17 +62,17 @@ public:
|
|||
[[nodiscard]] bool empty() const;
|
||||
void clear();
|
||||
|
||||
[[nodiscard]] bool unknown() const;
|
||||
// [[nodiscard]] bool unknown() const;
|
||||
|
||||
private:
|
||||
void init();
|
||||
void add_to_map(column_definition &col, size_t index);
|
||||
void add_to_map(field &col, size_t index);
|
||||
|
||||
private:
|
||||
column_by_index columns_;
|
||||
column_by_name_map columns_by_name_;
|
||||
field_by_index fields_;
|
||||
field_by_name_map fields_by_name_;
|
||||
|
||||
int pk_index_{-1};
|
||||
// int pk_index_{-1};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#define QUERY_SCHEMA_HPP
|
||||
|
||||
#include "matador/sql/column_generator.hpp"
|
||||
#include "matador/sql/record.hpp"
|
||||
#include "matador/sql/table_definition.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
|
@ -16,7 +16,7 @@ class connection;
|
|||
struct table_info
|
||||
{
|
||||
std::string name;
|
||||
record prototype;
|
||||
table_definition prototype;
|
||||
};
|
||||
|
||||
class schema
|
||||
|
|
@ -38,7 +38,7 @@ public:
|
|||
template<typename Type>
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ private:
|
|||
const class dialect &dialect_;
|
||||
|
||||
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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -36,6 +36,7 @@ set(SQL_SOURCES
|
|||
sql/query_part.cpp
|
||||
sql/any_type_to_string_visitor.cpp
|
||||
sql/field.cpp
|
||||
sql/table_definition.cpp
|
||||
)
|
||||
|
||||
set(SQL_HEADER
|
||||
|
|
@ -89,6 +90,7 @@ set(SQL_HEADER
|
|||
../include/matador/sql/query_helper.hpp
|
||||
../include/matador/sql/field.hpp
|
||||
../include/matador/sql/entity_query_builder.hpp
|
||||
../include/matador/sql/table_definition.hpp
|
||||
)
|
||||
|
||||
set(QUERY_SOURCES
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include "matador/sql/field.hpp"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
field::field(std::string name)
|
||||
|
|
@ -8,6 +10,11 @@ field::field(std::string name)
|
|||
, 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
|
||||
: name_(std::move(x.name_))
|
||||
, index_(x.index_)
|
||||
|
|
@ -37,6 +44,11 @@ const std::string &field::name() const
|
|||
return name_;
|
||||
}
|
||||
|
||||
size_t field::size() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
int field::index() const
|
||||
{
|
||||
return index_;
|
||||
|
|
@ -83,4 +95,24 @@ bool field::is_null() const
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,11 +1,17 @@
|
|||
#include "matador/sql/query_result.hpp"
|
||||
|
||||
#include "matador/sql/record.hpp"
|
||||
|
||||
namespace matador::sql::detail {
|
||||
|
||||
template<>
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -6,23 +6,23 @@
|
|||
|
||||
namespace matador::sql {
|
||||
|
||||
record::record(std::initializer_list<column_definition> columns)
|
||||
: columns_(columns)
|
||||
record::record(std::initializer_list<field> columns)
|
||||
: fields_(columns)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
record::record(const std::vector<column_definition> &columns)
|
||||
: columns_(columns)
|
||||
record::record(const std::vector<field> &columns)
|
||||
: fields_(columns)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
record::record(const record &x)
|
||||
: columns_(x.columns_)
|
||||
, pk_index_(x.pk_index_)
|
||||
: fields_(x.fields_)
|
||||
//, pk_index_(x.pk_index_)
|
||||
{
|
||||
for (auto& col : columns_) {
|
||||
for (auto& col : fields_) {
|
||||
add_to_map(col, col.index());
|
||||
}
|
||||
}
|
||||
|
|
@ -33,128 +33,128 @@ record &record::operator=(const record &x)
|
|||
return *this;
|
||||
}
|
||||
|
||||
columns_ = x.columns_;
|
||||
columns_by_name_.clear();
|
||||
pk_index_ = x.pk_index_;
|
||||
for (auto& col : columns_) {
|
||||
fields_ = x.fields_;
|
||||
fields_by_name_.clear();
|
||||
// pk_index_ = x.pk_index_;
|
||||
for (auto& col : fields_) {
|
||||
add_to_map(col, col.index());
|
||||
}
|
||||
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 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);
|
||||
return fields_.at(index);
|
||||
}
|
||||
|
||||
record::iterator record::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();
|
||||
auto it = fields_by_name_.find(column_name);
|
||||
return it != fields_by_name_.end() ? fields_.begin() + it->second.second : fields_.end();
|
||||
}
|
||||
|
||||
record::const_iterator record::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();
|
||||
auto it = fields_by_name_.find(column_name);
|
||||
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));
|
||||
add_to_map(ref, columns_.size()-1);
|
||||
auto &ref = fields_.emplace_back(std::move(col));
|
||||
add_to_map(ref, fields_.size() - 1);
|
||||
}
|
||||
|
||||
record::iterator record::begin()
|
||||
{
|
||||
return columns_.begin();
|
||||
return fields_.begin();
|
||||
}
|
||||
|
||||
record::const_iterator record::begin() const
|
||||
{
|
||||
return columns_.begin();
|
||||
return fields_.begin();
|
||||
}
|
||||
|
||||
record::const_iterator record::cbegin() const
|
||||
{
|
||||
return columns_.cbegin();
|
||||
return fields_.cbegin();
|
||||
}
|
||||
|
||||
record::iterator record::end()
|
||||
{
|
||||
return columns_.end();
|
||||
return fields_.end();
|
||||
}
|
||||
|
||||
record::const_iterator record::end() const
|
||||
{
|
||||
return columns_.end();
|
||||
return fields_.end();
|
||||
}
|
||||
|
||||
record::const_iterator record::cend() const
|
||||
{
|
||||
return columns_.cend();
|
||||
return fields_.cend();
|
||||
}
|
||||
|
||||
size_t record::size() const
|
||||
{
|
||||
return columns_.size();
|
||||
return fields_.size();
|
||||
}
|
||||
|
||||
bool record::empty() const
|
||||
{
|
||||
return columns_.empty();
|
||||
return fields_.empty();
|
||||
}
|
||||
|
||||
void record::clear()
|
||||
{
|
||||
columns_.clear();
|
||||
columns_by_name_.clear();
|
||||
fields_.clear();
|
||||
fields_by_name_.clear();
|
||||
}
|
||||
|
||||
bool record::unknown() const
|
||||
{
|
||||
return std::all_of(std::begin(columns_), std::end(columns_), [](const auto &col) {
|
||||
return col.type() == data_type_t::type_unknown;
|
||||
});
|
||||
}
|
||||
//bool record::unknown() const
|
||||
//{
|
||||
// return std::all_of(std::begin(columns_), std::end(columns_), [](const auto &col) {
|
||||
// return col.type() == data_type_t::type_unknown;
|
||||
// });
|
||||
//}
|
||||
|
||||
void record::init()
|
||||
{
|
||||
size_t index{0};
|
||||
for(auto &col : columns_) {
|
||||
for(auto &col : fields_) {
|
||||
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});
|
||||
if (utils::is_constraint_set(col.attributes().options(), utils::constraints::PRIMARY_KEY)) {
|
||||
pk_index_ = static_cast<int>(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)) {
|
||||
// pk_index_ = static_cast<int>(index);
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -9,6 +9,8 @@ using namespace matador::sql;
|
|||
|
||||
TEST_CASE("Load backend", "[backend provider]") {
|
||||
auto path = matador::utils::os::getenv("MATADOR_BACKENDS_PATH");
|
||||
REQUIRE(!path.empty());
|
||||
|
||||
if (path.back() != '\\') {
|
||||
path.push_back('\\');
|
||||
}
|
||||
|
|
@ -16,8 +18,8 @@ TEST_CASE("Load backend", "[backend provider]") {
|
|||
REQUIRE(!path.empty());
|
||||
|
||||
connection_info ci{};
|
||||
const auto &d = backend_provider::instance().connection_dialect("sqlite");
|
||||
auto *connection = backend_provider::instance().create_connection("sqlite", ci);
|
||||
const auto &d = backend_provider::instance().connection_dialect("noop");
|
||||
auto *connection = backend_provider::instance().create_connection("noop", ci);
|
||||
REQUIRE(connection != nullptr);
|
||||
backend_provider::instance().destroy_connection("sqlite", connection);
|
||||
backend_provider::instance().destroy_connection("noop", connection);
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@ include(Catch)
|
|||
|
||||
add_executable(tests
|
||||
QueryBuilderTest.cpp
|
||||
RecordTest.cpp
|
||||
TableDefinitionTest.cpp
|
||||
ConnectionPoolTest.cpp
|
||||
BackendProviderTest.cpp
|
||||
models/product.hpp
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ TEST_CASE("Field test", "[field]") {
|
|||
REQUIRE(bool_val.has_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.is_null());
|
||||
REQUIRE(!f.is_integer());
|
||||
|
|
|
|||
|
|
@ -1,26 +1,26 @@
|
|||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include <matador/sql/record.hpp>
|
||||
#include <matador/sql/table_definition.hpp>
|
||||
|
||||
#include <list>
|
||||
|
||||
using namespace matador::sql;
|
||||
|
||||
TEST_CASE("Create record", "[record]") {
|
||||
record rec({
|
||||
table_definition def({
|
||||
make_pk_column<unsigned long>("id"),
|
||||
make_column<std::string>("name", 255),
|
||||
make_column<std::string>("color", 255)
|
||||
});
|
||||
|
||||
REQUIRE(rec.size() == 3);
|
||||
REQUIRE(def.size() == 3);
|
||||
|
||||
std::list<std::string> expected_columns = {"id", "name", "color"};
|
||||
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());
|
||||
}
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ TEST_CASE("Create record", "[record]") {
|
|||
}
|
||||
|
||||
TEST_CASE("Append to record", "[record]") {
|
||||
record rec;
|
||||
table_definition rec;
|
||||
|
||||
rec.append(make_pk_column<unsigned long>("id"));
|
||||
rec.append<std::string>("name", 255);
|
||||
Loading…
Reference in New Issue