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) {
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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_;
|
||||||
|
|
|
||||||
|
|
@ -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_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
|
|
||||||
|
class record;
|
||||||
|
|
||||||
template < typename Type >
|
template < typename Type >
|
||||||
class query_result;
|
class query_result;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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*/)
|
||||||
|
|
|
||||||
|
|
@ -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};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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/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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -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);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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]") {
|
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);
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
Loading…
Reference in New Issue