add column info (progress, not compiling)
This commit is contained in:
parent
78c5f64b34
commit
b966a7a1a7
|
|
@ -12,7 +12,7 @@ list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras)
|
|||
include(CTest)
|
||||
include(Catch)
|
||||
|
||||
set(POSTGRES_CONNECTION_STRING "postgres://test:test123@127.0.0.1:5432/matador_test")
|
||||
set(POSTGRES_CONNECTION_STRING "postgres://test:test123@127.0.0.1:15432/test")
|
||||
|
||||
configure_file(Connection.hpp.in ${PROJECT_BINARY_DIR}/backends/postgres/test/connection.hpp @ONLY IMMEDIATE)
|
||||
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ TEST_CASE_METHOD(QueryFixture, " Execute insert statement", "[session]")
|
|||
.execute();
|
||||
|
||||
auto res = db.insert()
|
||||
.into("person", {"id", "name", "color"})
|
||||
.into("person", {{"", "id", ""}, {"", "name", ""}, {"", "color", ""}})
|
||||
.values({7, "george", "green"})
|
||||
.execute();
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
namespace matador::sql {
|
||||
|
||||
class table_repository;
|
||||
class schema;
|
||||
|
||||
class fk_column_generator
|
||||
{
|
||||
|
|
@ -53,13 +53,13 @@ private:
|
|||
class column_generator
|
||||
{
|
||||
private:
|
||||
column_generator(std::vector<column> &columns, const table_repository &repo);
|
||||
column_generator(std::vector<column> &columns, const schema &repo);
|
||||
|
||||
public:
|
||||
~column_generator() = default;
|
||||
|
||||
template < class Type >
|
||||
static std::vector<column> generate(const table_repository &repo)
|
||||
static std::vector<column> generate(const schema &repo)
|
||||
{
|
||||
std::vector<column> columns;
|
||||
column_generator gen(columns, repo);
|
||||
|
|
@ -102,7 +102,7 @@ private:
|
|||
private:
|
||||
size_t index_ = 0;
|
||||
std::vector<column> &columns_;
|
||||
const table_repository &repo_;
|
||||
const schema &repo_;
|
||||
|
||||
fk_column_generator fk_column_generator_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,24 +5,38 @@
|
|||
#include "matador/utils/field_attributes.hpp"
|
||||
#include "matador/utils/foreign_attributes.hpp"
|
||||
|
||||
#include "matador/sql/schema.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
struct column_info
|
||||
{
|
||||
std::string table;
|
||||
std::string name;
|
||||
std::string alias;
|
||||
};
|
||||
|
||||
class column_name_generator
|
||||
{
|
||||
private:
|
||||
explicit column_name_generator(std::vector<std::string> &column_names);
|
||||
column_name_generator(std::vector<column_info> &column_infos, const sql::schema &ts, const std::string &table_name);
|
||||
|
||||
public:
|
||||
~column_name_generator() = default;
|
||||
|
||||
template < class Type >
|
||||
static std::vector<std::string> generate()
|
||||
static std::vector<column_info> generate(const sql::schema &ts)
|
||||
{
|
||||
std::vector<std::string> columns;
|
||||
column_name_generator gen(columns);
|
||||
const auto info = ts.info<Type>();
|
||||
if (!info) {
|
||||
return {};
|
||||
}
|
||||
std::vector<column_info> columns;
|
||||
column_name_generator gen(columns, ts, info.value().name);
|
||||
Type obj;
|
||||
matador::utils::access::process(gen, obj);
|
||||
return std::move(columns);
|
||||
|
|
@ -31,7 +45,7 @@ public:
|
|||
template < class V >
|
||||
void on_primary_key(const char *id, V &, typename std::enable_if<std::is_integral<V>::value && !std::is_same<bool, V>::value>::type* = 0)
|
||||
{
|
||||
column_names_.emplace_back(id);
|
||||
push(id);
|
||||
}
|
||||
void on_primary_key(const char *id, std::string &, size_t);
|
||||
void on_revision(const char *id, unsigned long long &/*rev*/);
|
||||
|
|
@ -39,26 +53,49 @@ public:
|
|||
template<typename Type>
|
||||
void on_attribute(const char *id, Type &, const utils::field_attributes &/*attr*/ = utils::null_attributes)
|
||||
{
|
||||
column_names_.emplace_back(id);
|
||||
push(id);
|
||||
}
|
||||
|
||||
template<class Pointer>
|
||||
void on_belongs_to(const char *id, Pointer &, const utils::foreign_attributes &/*attr*/)
|
||||
{
|
||||
column_names_.emplace_back(id);
|
||||
push(id);
|
||||
}
|
||||
template<class Pointer>
|
||||
void on_has_one(const char *id, Pointer &, const utils::foreign_attributes &/*attr*/)
|
||||
{
|
||||
column_names_.emplace_back(id);
|
||||
push(id);
|
||||
}
|
||||
template<class ContainerType>
|
||||
void on_has_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &/*attr*/) {}
|
||||
void on_has_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &attr)
|
||||
{
|
||||
if (attr.fetch() == fetch_type::LAZY) {
|
||||
return;
|
||||
}
|
||||
const auto info = table_schema_.info<typename ContainerType::value_type::value_type>();
|
||||
if (!info) {
|
||||
return;
|
||||
}
|
||||
|
||||
table_name_stack_.push(info.value().name);
|
||||
typename ContainerType::value_type::value_type obj;
|
||||
matador::utils::access::process(*this, obj);
|
||||
table_name_stack_.pop();
|
||||
}
|
||||
template<class ContainerType>
|
||||
void on_has_many(const char *, ContainerType &, const utils::foreign_attributes &/*attr*/) {}
|
||||
void on_has_many(const char *id, ContainerType &c, const utils::foreign_attributes &attr)
|
||||
{
|
||||
on_has_many(id, c, "", "", attr);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::string> &column_names_;
|
||||
void push(const std::string &column_name);
|
||||
|
||||
private:
|
||||
std::stack<std::string> table_name_stack_;
|
||||
std::vector<column_info> &column_infos_;
|
||||
const sql::schema &table_schema_;
|
||||
int column_index{0};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ namespace matador::sql {
|
|||
class connection
|
||||
{
|
||||
public:
|
||||
explicit connection(connection_info info, const std::shared_ptr<table_repository> &repo = std::make_shared<table_repository>());
|
||||
explicit connection(const std::string& dns, const std::shared_ptr<table_repository> &repo = std::make_shared<table_repository>());
|
||||
explicit connection(connection_info info, const std::shared_ptr<schema> &repo = std::make_shared<schema>());
|
||||
explicit connection(const std::string& dns, const std::shared_ptr<schema> &repo = std::make_shared<schema>());
|
||||
connection(const connection &x);
|
||||
connection& operator=(const connection &x);
|
||||
connection(connection &&x) noexcept = default;
|
||||
|
|
@ -51,20 +51,20 @@ public:
|
|||
statement prepare(query_context &&query) const;
|
||||
|
||||
const class dialect& dialect() const;
|
||||
std::shared_ptr<table_repository> tables() const;
|
||||
std::shared_ptr<schema> tables() const;
|
||||
|
||||
private:
|
||||
connection_info connection_info_;
|
||||
std::unique_ptr<connection_impl> connection_;
|
||||
utils::logger logger_;
|
||||
const class dialect &dialect_;
|
||||
std::shared_ptr<table_repository> table_repository_;
|
||||
std::shared_ptr<schema> schema_;
|
||||
};
|
||||
|
||||
template<class Type>
|
||||
query_select_intermediate connection::select()
|
||||
{
|
||||
return query_select_intermediate{*this, column_generator::generate<Type>(*table_repository_)};
|
||||
return query_select_intermediate{*this, column_generator::generate<Type>(*schema_)};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,8 +126,8 @@ public:
|
|||
query_builder& table(const std::string &table, std::initializer_list<column> columns);
|
||||
query_builder& table(const std::string &table, const std::vector<column> &columns);
|
||||
query_builder& table(const std::string &table);
|
||||
query_builder& into(const std::string &table, std::initializer_list<std::string> column_names);
|
||||
query_builder& into(const std::string &table, const std::vector<std::string> &column_names);
|
||||
query_builder& into(const std::string &table, std::initializer_list<column_info> column_names);
|
||||
query_builder& into(const std::string &table, const std::vector<column_info> &column_names);
|
||||
query_builder& values(std::initializer_list<any_type> values);
|
||||
query_builder& values(const std::vector<any_type> &values);
|
||||
query_builder& from(const std::string &table, const std::string &as = "");
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include "matador/sql/query_result.hpp"
|
||||
#include "matador/sql/record.hpp"
|
||||
#include "matador/sql/statement.hpp"
|
||||
#include "matador/sql/table_repository.hpp"
|
||||
#include "matador/sql/schema.hpp"
|
||||
#include "matador/sql/value_extractor.hpp"
|
||||
|
||||
#include <string>
|
||||
|
|
@ -21,13 +21,24 @@ namespace matador::sql {
|
|||
class basic_condition;
|
||||
class connection;
|
||||
|
||||
class query_intermediate
|
||||
class basic_query_intermediate
|
||||
{
|
||||
public:
|
||||
explicit basic_query_intermediate(connection &db);
|
||||
|
||||
protected:
|
||||
[[nodiscard]] std::shared_ptr<schema> tables() const;
|
||||
|
||||
protected:
|
||||
connection &connection_;
|
||||
};
|
||||
|
||||
class query_intermediate : public basic_query_intermediate
|
||||
{
|
||||
public:
|
||||
query_intermediate(connection &db, query_builder &query);
|
||||
|
||||
protected:
|
||||
connection &connection_;
|
||||
query_builder &builder_;
|
||||
};
|
||||
|
||||
|
|
@ -149,13 +160,12 @@ public:
|
|||
query_order_by_intermediate order_by(const std::string &name);
|
||||
};
|
||||
|
||||
class query_start_intermediate
|
||||
class query_start_intermediate : public basic_query_intermediate
|
||||
{
|
||||
public:
|
||||
explicit query_start_intermediate(connection &s);
|
||||
|
||||
protected:
|
||||
connection &connection_;
|
||||
query_builder builder_;
|
||||
};
|
||||
|
||||
|
|
@ -210,9 +220,6 @@ public:
|
|||
}
|
||||
return {connection_, builder_.table(table_name, column_generator::generate<Type>(*tables()))};
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<table_repository> tables() const;
|
||||
};
|
||||
|
||||
class query_drop_intermediate : query_start_intermediate
|
||||
|
|
@ -228,16 +235,16 @@ class query_insert_intermediate : public query_start_intermediate
|
|||
public:
|
||||
explicit query_insert_intermediate(connection &s);
|
||||
|
||||
query_into_intermediate into(const std::string &table, std::initializer_list<std::string> column_names);
|
||||
query_into_intermediate into(const std::string &table, std::initializer_list<column_info> column_names);
|
||||
template<class Type>
|
||||
query_into_intermediate into(const std::string &table)
|
||||
{
|
||||
return {connection_, builder_.into(table, column_name_generator::generate<Type>())};
|
||||
return {connection_, builder_.into(table, column_name_generator::generate<Type>(*tables()))};
|
||||
}
|
||||
template<class Type>
|
||||
query_execute_finish into(const std::string &table, const Type &obj)
|
||||
{
|
||||
return {connection_, builder_.into(table, column_name_generator::generate<Type>())
|
||||
return {connection_, builder_.into(table, column_name_generator::generate<Type>(*tables()))
|
||||
.values(value_extractor::extract(obj))};
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef QUERY_TABLE_REPOSITORY_HPP
|
||||
#define QUERY_TABLE_REPOSITORY_HPP
|
||||
#ifndef QUERY_SCHEMA_HPP
|
||||
#define QUERY_SCHEMA_HPP
|
||||
|
||||
#include "matador/sql/column_generator.hpp"
|
||||
#include "matador/sql/record.hpp"
|
||||
|
|
@ -21,7 +21,7 @@ struct table_info
|
|||
void drop(connection &conn) const;
|
||||
};
|
||||
|
||||
class table_repository
|
||||
class schema
|
||||
{
|
||||
public:
|
||||
using repository = std::unordered_map<std::type_index, table_info>;
|
||||
|
|
@ -37,12 +37,12 @@ public:
|
|||
const table_info& attach(std::type_index ti, const table_info& table);
|
||||
|
||||
template<typename Type>
|
||||
std::optional<table_info> info()
|
||||
[[nodiscard]] std::optional<table_info> info() const
|
||||
{
|
||||
return info(std::type_index(typeid(Type)));
|
||||
}
|
||||
|
||||
std::optional<table_info> info(std::type_index ti);
|
||||
[[nodiscard]] std::optional<table_info> info(std::type_index ti) const;
|
||||
|
||||
template<typename Type>
|
||||
[[nodiscard]] std::pair<std::string, std::string> reference() const
|
||||
|
|
@ -61,11 +61,11 @@ public:
|
|||
[[nodiscard]] bool exists(const std::type_index &ti) const;
|
||||
|
||||
iterator begin();
|
||||
const_iterator begin() const;
|
||||
[[nodiscard]] const_iterator begin() const;
|
||||
iterator end();
|
||||
const_iterator end() const;
|
||||
[[nodiscard]] const_iterator end() const;
|
||||
|
||||
bool empty() const;
|
||||
[[nodiscard]] bool empty() const;
|
||||
|
||||
private:
|
||||
repository repository_;
|
||||
|
|
@ -73,4 +73,4 @@ private:
|
|||
|
||||
}
|
||||
|
||||
#endif //QUERY_TABLE_REPOSITORY_HPP
|
||||
#endif //QUERY_SCHEMA_HPP
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
#include "matador/sql/connection_pool.hpp"
|
||||
#include "matador/sql/entity.hpp"
|
||||
#include "matador/sql/statement.hpp"
|
||||
#include "matador/sql/table_repository.hpp"
|
||||
#include "matador/sql/schema.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ public:
|
|||
record describe_table(const std::string &table_name) const;
|
||||
bool table_exists(const std::string &table_name) const;
|
||||
|
||||
[[nodiscard]] const table_repository& tables() const;
|
||||
[[nodiscard]] const schema& tables() const;
|
||||
|
||||
const class dialect& dialect() const;
|
||||
|
||||
|
|
@ -56,21 +56,21 @@ private:
|
|||
connection_pool<connection> &pool_;
|
||||
const class dialect &dialect_;
|
||||
|
||||
table_repository table_repository_;
|
||||
schema schema_;
|
||||
mutable std::unordered_map<std::string, record> prototypes_;
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
void session::attach(const std::string &table_name)
|
||||
{
|
||||
table_repository_.attach<Type>(table_name);
|
||||
schema_.attach<Type>(table_name);
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
entity<Type> session::insert(Type *obj)
|
||||
{
|
||||
auto c = pool_.acquire();
|
||||
auto info = table_repository_.info<Type>();
|
||||
auto info = schema_.info<Type>();
|
||||
if (!info) {
|
||||
return {};
|
||||
}
|
||||
|
|
@ -82,7 +82,7 @@ entity<Type> session::insert(Type *obj)
|
|||
template<typename Type>
|
||||
void session::drop_table()
|
||||
{
|
||||
auto info = table_repository_.info<Type>();
|
||||
auto info = schema_.info<Type>();
|
||||
if (info) {
|
||||
return drop_table(info.name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,13 +64,23 @@ void belongs_to(Operator &op, const char *id, Type &value, const foreign_attribu
|
|||
op.on_belongs_to(id, value, attr);
|
||||
}
|
||||
|
||||
//template<class Operator, class Type, template<class ...> class ContainerType>
|
||||
//void has_many(Operator &op, const char *id, container<Type, ContainerType> &container, const foreign_attributes &attr) {
|
||||
// op.on_has_many(id, container, attr);
|
||||
//}
|
||||
|
||||
template<class Operator, class Type, template<class ...> class ContainerType>
|
||||
void has_many(Operator &op, const char *id, container<Type, ContainerType> &container, const foreign_attributes &attr) {
|
||||
void has_many(Operator &op, const char *id, ContainerType<Type> &container, const foreign_attributes &attr) {
|
||||
op.on_has_many(id, container, attr);
|
||||
}
|
||||
|
||||
//template<class Operator, class Type, template<class ...> class ContainerType>
|
||||
//void has_many(Operator &op, const char *id, container<Type, ContainerType> &container, const char *left_column, const char *right_column, const foreign_attributes &attr) {
|
||||
// op.on_has_many(id, container, left_column, right_column, attr);
|
||||
//}
|
||||
|
||||
template<class Operator, class Type, template<class ...> class ContainerType>
|
||||
void has_many(Operator &op, const char *id, container<Type, ContainerType> &container, const char *left_column, const char *right_column, const foreign_attributes &attr) {
|
||||
void has_many(Operator &op, const char *id, ContainerType<Type> &container, const char *left_column, const char *right_column, const foreign_attributes &attr) {
|
||||
op.on_has_many(id, container, left_column, right_column, attr);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ set(SQL_SOURCES
|
|||
sql/column_name_generator.cpp
|
||||
sql/key_value_generator.cpp
|
||||
sql/fk_value_extractor.cpp
|
||||
sql/table_repository.cpp
|
||||
sql/schema.cpp
|
||||
sql/query_result.cpp
|
||||
sql/query_result_reader.cpp
|
||||
sql/statement_cache.cpp
|
||||
|
|
@ -55,7 +55,7 @@ set(SQL_HEADER
|
|||
../include/matador/sql/key_value_generator.hpp
|
||||
../include/matador/sql/entity.hpp
|
||||
../include/matador/sql/fk_value_extractor.hpp
|
||||
../include/matador/sql/table_repository.hpp
|
||||
../include/matador/sql/schema.hpp
|
||||
../include/matador/sql/any_type_to_visitor.hpp
|
||||
../include/matador/sql/query_result_reader.hpp
|
||||
../include/matador/sql/to_value.hpp
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
#include "matador/sql/column_generator.hpp"
|
||||
#include "matador/sql/table_repository.hpp"
|
||||
#include "matador/sql/schema.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
column_generator::column_generator(std::vector<column> &columns, const table_repository &repo)
|
||||
column_generator::column_generator(std::vector<column> &columns, const schema &repo)
|
||||
: columns_(columns)
|
||||
, repo_(repo)
|
||||
{}
|
||||
|
|
|
|||
|
|
@ -2,18 +2,30 @@
|
|||
|
||||
namespace matador::sql {
|
||||
|
||||
column_name_generator::column_name_generator(std::vector<std::string> &column_names)
|
||||
: column_names_(column_names)
|
||||
{}
|
||||
column_name_generator::column_name_generator(std::vector<column_info> &column_infos,
|
||||
const sql::schema &ts,
|
||||
const std::string &table_name)
|
||||
: column_infos_(column_infos)
|
||||
, table_schema_(ts)
|
||||
{
|
||||
table_name_stack_.push(table_name);
|
||||
}
|
||||
|
||||
void column_name_generator::on_primary_key(const char *id, std::string &, size_t)
|
||||
{
|
||||
column_names_.emplace_back(id);
|
||||
push(id);
|
||||
}
|
||||
|
||||
void column_name_generator::on_revision(const char *id, unsigned long long int &)
|
||||
{
|
||||
column_names_.emplace_back(id);
|
||||
push(id);
|
||||
}
|
||||
|
||||
void column_name_generator::push(const std::string &column_name)
|
||||
{
|
||||
char str[4];
|
||||
snprintf(str, 4, "c%02d", ++column_index);
|
||||
column_infos_.emplace_back(column_info{table_name_stack_.top(), column_name, str});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -8,16 +8,16 @@
|
|||
|
||||
namespace matador::sql {
|
||||
|
||||
connection::connection(connection_info info, const std::shared_ptr<table_repository> &repo)
|
||||
connection::connection(connection_info info, const std::shared_ptr<schema> &repo)
|
||||
: connection_info_(std::move(info))
|
||||
, logger_(stdout, "SQL")
|
||||
, dialect_(backend_provider::instance().connection_dialect(connection_info_.type))
|
||||
, table_repository_(repo)
|
||||
, schema_(repo)
|
||||
{
|
||||
connection_.reset(backend_provider::instance().create_connection(connection_info_.type, connection_info_));
|
||||
}
|
||||
|
||||
connection::connection(const std::string& dns, const std::shared_ptr<table_repository> &repo)
|
||||
connection::connection(const std::string& dns, const std::shared_ptr<schema> &repo)
|
||||
: connection(connection_info::parse(dns), repo)
|
||||
{}
|
||||
|
||||
|
|
@ -160,9 +160,9 @@ const class dialect &connection::dialect() const
|
|||
return dialect_;
|
||||
}
|
||||
|
||||
std::shared_ptr<table_repository> connection::tables() const
|
||||
std::shared_ptr<schema> connection::tables() const
|
||||
{
|
||||
return table_repository_;
|
||||
return schema_;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "matador/sql/query_builder.hpp"
|
||||
#include "matador/sql/column_name_generator.hpp"
|
||||
#include "matador/sql/dialect.hpp"
|
||||
|
||||
#include "matador/utils/string.hpp"
|
||||
|
|
@ -255,12 +256,12 @@ query_builder &query_builder::table(const std::string &table)
|
|||
return *this;
|
||||
}
|
||||
|
||||
query_builder &query_builder::into(const std::string &table, std::initializer_list<std::string> column_names)
|
||||
query_builder &query_builder::into(const std::string &table, std::initializer_list<column_info> column_names)
|
||||
{
|
||||
return into(table, std::vector<std::string>{column_names});
|
||||
return into(table, std::vector<column_info>{column_names});
|
||||
}
|
||||
|
||||
query_builder &query_builder::into(const std::string &table, const std::vector<std::string> &column_names)
|
||||
query_builder &query_builder::into(const std::string &table, const std::vector<column_info> &column_names)
|
||||
{
|
||||
transition_to(state_t::QUERY_INTO);
|
||||
|
||||
|
|
@ -270,14 +271,14 @@ query_builder &query_builder::into(const std::string &table, const std::vector<s
|
|||
std::string result{"("};
|
||||
if (column_names.size() < 2) {
|
||||
for (const auto &col: column_names) {
|
||||
result.append(dialect_.prepare_identifier(col));
|
||||
result.append(dialect_.prepare_identifier(col.name));
|
||||
}
|
||||
} else {
|
||||
auto it = column_names.begin();
|
||||
result.append(dialect_.prepare_identifier(*it++));
|
||||
result.append(dialect_.prepare_identifier((it++)->name));
|
||||
for (; it != column_names.end(); ++it) {
|
||||
result.append(", ");
|
||||
result.append(dialect_.prepare_identifier(*it));
|
||||
result.append(dialect_.prepare_identifier(it->name));
|
||||
}
|
||||
}
|
||||
result += (")");
|
||||
|
|
|
|||
|
|
@ -2,6 +2,13 @@
|
|||
#include "matador/sql/session.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
basic_query_intermediate::basic_query_intermediate(connection &db)
|
||||
: connection_(db) {}
|
||||
|
||||
std::shared_ptr<schema> basic_query_intermediate::tables() const
|
||||
{
|
||||
return connection_.tables();
|
||||
}
|
||||
|
||||
query_result<record> query_select_finish::fetch_all()
|
||||
{
|
||||
|
|
@ -24,7 +31,7 @@ statement query_select_finish::prepare()
|
|||
}
|
||||
|
||||
query_intermediate::query_intermediate(connection &db, query_builder &query)
|
||||
: connection_(db), builder_(query) {}
|
||||
: basic_query_intermediate(db), builder_(query) {}
|
||||
|
||||
query_offset_intermediate query_order_direction_intermediate::offset(size_t offset)
|
||||
{
|
||||
|
|
@ -128,7 +135,7 @@ query_insert_intermediate::query_insert_intermediate(connection &s)
|
|||
builder_.insert();
|
||||
}
|
||||
|
||||
query_into_intermediate query_insert_intermediate::into(const std::string &table, std::initializer_list<std::string> column_names)
|
||||
query_into_intermediate query_insert_intermediate::into(const std::string &table, std::initializer_list<column_info> column_names)
|
||||
{
|
||||
return {connection_, builder_.into(table, column_names)};
|
||||
}
|
||||
|
|
@ -163,11 +170,6 @@ query_execute_finish query_create_intermediate::table(const std::string &table_n
|
|||
return {connection_, builder_.table(table_name, columns)};
|
||||
}
|
||||
|
||||
std::shared_ptr<table_repository> query_create_intermediate::tables() const
|
||||
{
|
||||
return connection_.tables();
|
||||
}
|
||||
|
||||
query_drop_intermediate::query_drop_intermediate(connection &s)
|
||||
: query_start_intermediate(s)
|
||||
{
|
||||
|
|
@ -217,7 +219,7 @@ query_delete_from_intermediate query_delete_intermediate::from(const std::string
|
|||
}
|
||||
|
||||
query_start_intermediate::query_start_intermediate(connection &s)
|
||||
: connection_(s)
|
||||
: basic_query_intermediate(s)
|
||||
, builder_(s.dialect())
|
||||
{}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "matador/sql/table_repository.hpp"
|
||||
#include "matador/sql/schema.hpp"
|
||||
#include "matador/sql/connection.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
|
@ -15,12 +15,12 @@ void table_info::drop(connection &conn) const
|
|||
conn.drop().table(name).execute();
|
||||
}
|
||||
|
||||
const table_info& table_repository::attach(const std::type_index ti, const table_info& table)
|
||||
const table_info& schema::attach(const std::type_index ti, const table_info& table)
|
||||
{
|
||||
return repository_.try_emplace(ti, table).first->second;
|
||||
}
|
||||
|
||||
std::optional<table_info> table_repository::info(std::type_index ti)
|
||||
std::optional<table_info> schema::info(std::type_index ti) const
|
||||
{
|
||||
const auto it = repository_.find(ti);
|
||||
if (it == repository_.end()) {
|
||||
|
|
@ -29,7 +29,7 @@ std::optional<table_info> table_repository::info(std::type_index ti)
|
|||
return it->second;
|
||||
}
|
||||
|
||||
std::pair<std::string, std::string> table_repository::reference(const std::type_index &ti) const
|
||||
std::pair<std::string, std::string> schema::reference(const std::type_index &ti) const
|
||||
{
|
||||
const auto it = repository_.find(ti);
|
||||
if (it != repository_.end()) {
|
||||
|
|
@ -42,32 +42,32 @@ std::pair<std::string, std::string> table_repository::reference(const std::type_
|
|||
return {};
|
||||
}
|
||||
|
||||
bool table_repository::exists(const std::type_index &ti) const
|
||||
bool schema::exists(const std::type_index &ti) const
|
||||
{
|
||||
return repository_.count(ti) > 0;
|
||||
}
|
||||
|
||||
table_repository::iterator table_repository::begin()
|
||||
schema::iterator schema::begin()
|
||||
{
|
||||
return repository_.begin();
|
||||
}
|
||||
|
||||
table_repository::const_iterator table_repository::begin() const
|
||||
schema::const_iterator schema::begin() const
|
||||
{
|
||||
return repository_.begin();
|
||||
}
|
||||
|
||||
table_repository::iterator table_repository::end()
|
||||
schema::iterator schema::end()
|
||||
{
|
||||
return repository_.end();
|
||||
}
|
||||
|
||||
table_repository::const_iterator table_repository::end() const
|
||||
schema::const_iterator schema::end() const
|
||||
{
|
||||
return repository_.end();
|
||||
}
|
||||
|
||||
bool table_repository::empty() const
|
||||
bool schema::empty() const
|
||||
{
|
||||
return repository_.empty();
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@ session::session(connection_pool<connection> &pool)
|
|||
void session::create_schema()
|
||||
{
|
||||
auto c = pool_.acquire();
|
||||
for (const auto &t : table_repository_) {
|
||||
for (const auto &t : schema_) {
|
||||
t.second.create(*c);
|
||||
}
|
||||
}
|
||||
|
|
@ -88,9 +88,9 @@ bool session::table_exists(const std::string &table_name) const
|
|||
return c->exists(dialect_.default_schema_name(), table_name);
|
||||
}
|
||||
|
||||
const table_repository& session::tables() const
|
||||
const schema& session::tables() const
|
||||
{
|
||||
return table_repository_;
|
||||
return schema_;
|
||||
}
|
||||
|
||||
const class dialect &session::dialect() const
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ add_executable(tests QueryBuilderTest.cpp
|
|||
ConnectionPoolTest.cpp
|
||||
BackendProviderTest.cpp
|
||||
models/product.hpp
|
||||
models/order.hpp
|
||||
models/order_details.h
|
||||
ColumnGeneratorTest.cpp
|
||||
ColumnNameGeneratorTest.cpp
|
||||
ValueGeneratorTest.cpp
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "matador/sql/column_generator.hpp"
|
||||
#include "matador/sql/table_repository.hpp"
|
||||
#include "matador/sql/schema.hpp"
|
||||
|
||||
#include "models/product.hpp"
|
||||
#include "models/optional.hpp"
|
||||
|
|
@ -10,7 +10,7 @@ using namespace matador::sql;
|
|||
using namespace matador::utils;
|
||||
|
||||
TEST_CASE("Generate columns from object", "[column generator]") {
|
||||
table_repository repo;
|
||||
schema repo;
|
||||
|
||||
auto columns = column_generator::generate<matador::test::product>(repo);
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ TEST_CASE("Generate columns from object", "[column generator]") {
|
|||
}
|
||||
|
||||
TEST_CASE("Generate columns from object with nullable columns", "[column generator]") {
|
||||
table_repository repo;
|
||||
schema repo;
|
||||
|
||||
auto columns = column_generator::generate<matador::test::optional>(repo);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,18 @@
|
|||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "matador/sql/column_name_generator.hpp"
|
||||
#include "matador/sql/schema.hpp"
|
||||
|
||||
#include "models/order.hpp"
|
||||
#include "models/product.hpp"
|
||||
|
||||
using namespace matador::sql;
|
||||
|
||||
TEST_CASE("Generate column names from object", "[column name generator]") {
|
||||
schema s;
|
||||
s.attach<matador::test::product>("product");
|
||||
|
||||
auto columns = column_name_generator::generate<matador::test::product>();
|
||||
auto columns = column_name_generator::generate<matador::test::product>(s);
|
||||
|
||||
const std::vector<std::string> expected_columns = {
|
||||
"product_name",
|
||||
|
|
@ -25,6 +29,40 @@ TEST_CASE("Generate column names from object", "[column name generator]") {
|
|||
REQUIRE(columns.size() == expected_columns.size());
|
||||
|
||||
for (size_t i = 0; i != expected_columns.size(); ++i) {
|
||||
REQUIRE(expected_columns[i] == columns[i]);
|
||||
REQUIRE(expected_columns[i] == columns[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Generate column names for object with has many relation", "[column][relation]") {
|
||||
schema s;
|
||||
s.attach<matador::test::product>("product");
|
||||
s.attach<matador::test::order_details>("order_details");
|
||||
s.attach<matador::test::order>("order");
|
||||
|
||||
auto columns = column_name_generator::generate<matador::test::order>(s);
|
||||
|
||||
const std::vector<std::string> expected_columns = {
|
||||
"order_id",
|
||||
"order_date",
|
||||
"required_date",
|
||||
"shipped_date",
|
||||
"ship_via",
|
||||
"freight",
|
||||
"ship_name",
|
||||
"ship_address",
|
||||
"ship_city",
|
||||
"ship_region",
|
||||
"ship_postal_code",
|
||||
"ship_country",
|
||||
"order_details_id",
|
||||
"order_id",
|
||||
"product_id",
|
||||
};
|
||||
REQUIRE(!columns.empty());
|
||||
REQUIRE(columns.size() == expected_columns.size());
|
||||
|
||||
for (size_t i = 0; i != expected_columns.size(); ++i) {
|
||||
REQUIRE(expected_columns[i] == columns[i].name);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -164,7 +164,7 @@ TEST_CASE("Create, insert and select a blob column", "[query][blob]") {
|
|||
REQUIRE(q.table_name == "person");
|
||||
|
||||
q = query.insert().into("person", {
|
||||
"id", "name", "data"
|
||||
{"", "id", ""}, {"", "name", ""}, {"", "data", ""}
|
||||
}).values({7UL, "george", blob{1, 'A', 3, 4}}).compile();
|
||||
|
||||
REQUIRE(q.sql == R"(INSERT INTO "person" ("id", "name", "data") VALUES (7, 'george', X'01410304'))");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
#ifndef QUERY_ORDER_HPP
|
||||
#define QUERY_ORDER_HPP
|
||||
|
||||
#include "order_details.h"
|
||||
|
||||
#include "matador/utils/access.hpp"
|
||||
|
||||
#include "matador/sql/entity.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace matador::test {
|
||||
|
||||
struct order
|
||||
{
|
||||
unsigned long order_id{};
|
||||
std::string order_date;
|
||||
std::string required_date;
|
||||
std::string shipped_date;
|
||||
unsigned int ship_via{};
|
||||
unsigned int freight{};
|
||||
std::string ship_name;
|
||||
std::string ship_address;
|
||||
std::string ship_city;
|
||||
std::string ship_region;
|
||||
std::string ship_postal_code;
|
||||
std::string ship_country;
|
||||
std::vector<sql::entity<order_details>> order_details_;
|
||||
|
||||
template<class Operator>
|
||||
void process(Operator &op) {
|
||||
namespace field = matador::utils::access;
|
||||
field::primary_key(op, "order_id", order_id);
|
||||
field::attribute(op, "order_date", order_date, 255);
|
||||
field::attribute(op, "required_date", required_date, 255);
|
||||
field::attribute(op, "shipped_date", shipped_date, 255);
|
||||
field::attribute(op, "ship_via", ship_via);
|
||||
field::attribute(op, "freight", freight);
|
||||
field::attribute(op, "ship_name", ship_name, 255);
|
||||
field::attribute(op, "ship_address", ship_address, 255);
|
||||
field::attribute(op, "ship_city", ship_city, 255);
|
||||
field::attribute(op, "ship_region", ship_region, 255);
|
||||
field::attribute(op, "ship_postal_code", ship_postal_code, 255);
|
||||
field::attribute(op, "ship_country", ship_country, 255);
|
||||
field::has_many(op, "order_details", order_details_, fetch_type::EAGER);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_ORDER_HPP
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef QUERY_ORDER_DETAILS_H
|
||||
#define QUERY_ORDER_DETAILS_H
|
||||
|
||||
#include "product.hpp"
|
||||
|
||||
#include "matador/sql/entity.hpp"
|
||||
|
||||
namespace matador::test {
|
||||
|
||||
struct order;
|
||||
|
||||
struct order_details
|
||||
{
|
||||
unsigned long order_details_id;
|
||||
sql::entity<order> order_;
|
||||
sql::entity<product> product_;
|
||||
|
||||
template<class Operator>
|
||||
void process(Operator &op) {
|
||||
namespace field = matador::utils::access;
|
||||
field::primary_key(op, "order_details_id", order_details_id);
|
||||
field::belongs_to(op, "order_id", order_, utils::default_foreign_attributes);
|
||||
field::has_one(op, "product_id", product_, utils::default_foreign_attributes);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_ORDER_DETAILS_H
|
||||
Loading…
Reference in New Issue