introduced table repository
This commit is contained in:
@@ -9,8 +9,8 @@ namespace matador::sql {
|
||||
using any_type = std::variant<
|
||||
char, short, int, long, long long,
|
||||
unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long,
|
||||
bool,
|
||||
float, double,
|
||||
bool,
|
||||
const char*,
|
||||
std::string,
|
||||
nullptr_t>;
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
#include "matador/utils/field_attributes.hpp"
|
||||
|
||||
#include <any>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
@@ -37,6 +38,17 @@ public:
|
||||
[[nodiscard]] const std::string& ref_table() const;
|
||||
[[nodiscard]] const std::string& ref_column() const;
|
||||
|
||||
template< typename Type >
|
||||
[[nodiscard]] bool is_type_of() const {
|
||||
return std::holds_alternative<Type>(value_);
|
||||
}
|
||||
|
||||
template< typename Type >
|
||||
std::optional<Type> value() const {
|
||||
const Type* ptr= std::get_if<Type>(&value_);
|
||||
return ptr ? std::make_optional<Type>(*ptr) : std::nullopt;
|
||||
}
|
||||
|
||||
private:
|
||||
template<class Operator>
|
||||
void process(Operator &op)
|
||||
@@ -44,9 +56,13 @@ private:
|
||||
op.on_attribute(name_.c_str(), value_, type_, attributes_);
|
||||
}
|
||||
|
||||
using data_type_index = std::vector<data_type_t>;
|
||||
|
||||
private:
|
||||
friend class record;
|
||||
|
||||
static const data_type_index data_type_index_;
|
||||
|
||||
std::string name_;
|
||||
utils::field_attributes attributes_;
|
||||
data_type_t type_{};
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define QUERY_COLUMN_GENERATOR_HPP
|
||||
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/table_repository.hpp"
|
||||
#include "matador/sql/types.hpp"
|
||||
|
||||
#include "matador/utils/access.hpp"
|
||||
@@ -18,10 +19,10 @@ public:
|
||||
fk_column_generator() = default;
|
||||
|
||||
template<class Type>
|
||||
column generate(const char *id, Type &x)
|
||||
column generate(const char *id, Type &x, const std::string &ref_table, const std::string &ref_column)
|
||||
{
|
||||
utils::access::process(*this, x);
|
||||
return column{id, type_, { utils::constraints::FOREIGN_KEY }};
|
||||
return column{id, type_, ref_table, ref_column, { utils::constraints::FOREIGN_KEY }};
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
@@ -50,16 +51,16 @@ private:
|
||||
class column_generator
|
||||
{
|
||||
private:
|
||||
explicit column_generator(std::vector<column> &columns);
|
||||
column_generator(std::vector<column> &columns, const table_repository &repo);
|
||||
|
||||
public:
|
||||
~column_generator() = default;
|
||||
|
||||
template < class Type >
|
||||
static std::vector<column> generate()
|
||||
static std::vector<column> generate(const table_repository &repo)
|
||||
{
|
||||
std::vector<column> columns;
|
||||
column_generator gen(columns);
|
||||
column_generator gen(columns, repo);
|
||||
Type obj;
|
||||
matador::utils::access::process(gen, obj);
|
||||
return std::move(columns);
|
||||
@@ -76,21 +77,27 @@ public:
|
||||
template<class Pointer>
|
||||
void on_belongs_to(const char *id, Pointer &x, utils::cascade_type)
|
||||
{
|
||||
columns_.push_back(fk_column_generator_.generate(id, *x));
|
||||
const auto [ref_table, ref_column] = determine_foreign_ref(std::type_index(typeid(typename Pointer::value_type)));
|
||||
columns_.push_back(fk_column_generator_.generate(id, *x, ref_table, ref_column));
|
||||
}
|
||||
template<class Pointer>
|
||||
void on_has_one(const char *id, Pointer &x, utils::cascade_type)
|
||||
{
|
||||
columns_.push_back(fk_column_generator_.generate(id, *x));
|
||||
const auto [ref_table, ref_column] = determine_foreign_ref(std::type_index(typeid(typename Pointer::value_type)));
|
||||
columns_.push_back(fk_column_generator_.generate(id, *x, ref_table, ref_column));
|
||||
}
|
||||
template<class ContainerType>
|
||||
void on_has_many(const char *, ContainerType &, const char *, const char *, utils::cascade_type) {}
|
||||
template<class ContainerType>
|
||||
void on_has_many(const char *, ContainerType &, utils::cascade_type) {}
|
||||
|
||||
private:
|
||||
std::pair<std::string, std::string> determine_foreign_ref(const std::type_index &ti);
|
||||
|
||||
private:
|
||||
size_t index_ = 0;
|
||||
std::vector<column> &columns_;
|
||||
const table_repository &repo_;
|
||||
|
||||
fk_column_generator fk_column_generator_;
|
||||
};
|
||||
|
||||
@@ -9,18 +9,22 @@ template < class Type >
|
||||
class foreign
|
||||
{
|
||||
public:
|
||||
using value_type = Type;
|
||||
using pointer = value_type*;
|
||||
using reference = value_type&;
|
||||
|
||||
foreign() = default;
|
||||
explicit foreign(Type *obj)
|
||||
: obj_(obj) {}
|
||||
|
||||
Type* operator->() { return obj_.get(); }
|
||||
const Type* operator->() const { return obj_.get(); }
|
||||
pointer operator->() { return obj_.get(); }
|
||||
const value_type* operator->() const { return obj_.get(); }
|
||||
|
||||
Type& operator*() { return *obj_; }
|
||||
const Type& operator*() const { return *obj_; }
|
||||
reference operator*() { return *obj_; }
|
||||
const value_type& operator*() const { return *obj_; }
|
||||
|
||||
private:
|
||||
std::unique_ptr<Type> obj_;
|
||||
std::unique_ptr<value_type> obj_;
|
||||
};
|
||||
|
||||
template<class Type, typename... Args>
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
class dialect;
|
||||
@@ -97,6 +96,7 @@ public:
|
||||
query_builder& create();
|
||||
query_builder& drop();
|
||||
query_builder& select(std::initializer_list<std::string> column_names);
|
||||
query_builder& select(const std::vector<std::string> &column_names);
|
||||
query_builder& insert();
|
||||
query_builder& update(const std::string &table);
|
||||
query_builder& remove();
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "matador/sql/query_builder.hpp"
|
||||
#include "matador/sql/query_result.hpp"
|
||||
#include "matador/sql/record.hpp"
|
||||
#include "matador/sql/table_repository.hpp"
|
||||
#include "matador/sql/value_extractor.hpp"
|
||||
|
||||
#include <string>
|
||||
@@ -142,14 +143,18 @@ public:
|
||||
class query_create_intermediate : query_intermediate
|
||||
{
|
||||
public:
|
||||
using query_intermediate::query_intermediate;
|
||||
query_create_intermediate(session &db, query_builder &query, table_repository &repo);
|
||||
|
||||
query_execute_finish table(const std::string &table, std::initializer_list<column> columns);
|
||||
template<class Type>
|
||||
query_execute_finish table(const std::string &table)
|
||||
query_execute_finish table(const std::string &table_name)
|
||||
{
|
||||
return {db(), query().table(table, column_generator::generate<Type>())};
|
||||
const auto &info = repository_.attach<Type>(table_name, record{column_generator::generate<Type>(repository_)});
|
||||
return {db(), query().table(table_name, info.prototype.columns())};
|
||||
}
|
||||
|
||||
private:
|
||||
table_repository &repository_;
|
||||
};
|
||||
|
||||
class query_drop_intermediate : query_intermediate
|
||||
|
||||
@@ -23,6 +23,7 @@ public:
|
||||
|
||||
record() = default;
|
||||
record(std::initializer_list<column> columns);
|
||||
explicit record(const std::vector<column> &columns);
|
||||
record(const record&) = default;
|
||||
record& operator=(const record&) = default;
|
||||
record(record&&) noexcept = default;
|
||||
@@ -44,8 +45,13 @@ public:
|
||||
|
||||
void append(column col);
|
||||
|
||||
bool has_primary_key() const;
|
||||
const column& primary_key() const;
|
||||
|
||||
[[nodiscard]] const std::vector<column>& columns() const;
|
||||
|
||||
[[nodiscard]] const column& at(const std::string &name) const;
|
||||
const column& at(size_t index) const;
|
||||
[[nodiscard]] const column& at(size_t index) const;
|
||||
|
||||
iterator find(const std::string &column_name);
|
||||
[[nodiscard]] const_iterator find(const std::string &column_name) const;
|
||||
@@ -62,9 +68,15 @@ public:
|
||||
[[nodiscard]] bool empty() const;
|
||||
void clear();
|
||||
|
||||
private:
|
||||
void init();
|
||||
void add_to_map(column &col, size_t index);
|
||||
|
||||
private:
|
||||
column_by_index columns_;
|
||||
column_by_name_map columns_by_name_;
|
||||
|
||||
int pk_index_{-1};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
#ifndef QUERY_SESSION_HPP
|
||||
#define QUERY_SESSION_HPP
|
||||
|
||||
#include "matador/sql/column_name_generator.hpp"
|
||||
#include "matador/sql/connection.hpp"
|
||||
#include "matador/sql/connection_pool.hpp"
|
||||
#include "matador/sql/query_builder.hpp"
|
||||
#include "matador/sql/query_intermediates.hpp"
|
||||
#include "matador/sql/table_repository.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
@@ -15,6 +19,11 @@ public:
|
||||
|
||||
query_create_intermediate create();
|
||||
query_drop_intermediate drop();
|
||||
template < class Type >
|
||||
query_select_intermediate select()
|
||||
{
|
||||
return query_select_intermediate{*this, query_.select(column_name_generator::generate<Type>())};
|
||||
}
|
||||
query_select_intermediate select(std::initializer_list<std::string> column_names);
|
||||
query_insert_intermediate insert();
|
||||
query_update_intermediate update(const std::string &table);
|
||||
@@ -23,9 +32,19 @@ public:
|
||||
query_result<record> fetch(const std::string &sql);
|
||||
std::pair<size_t, std::string> execute(const std::string &sql);
|
||||
|
||||
template<typename Type>
|
||||
void attach(const std::string &table_name)
|
||||
{
|
||||
table_repository_.attach<Type>(table_name);
|
||||
}
|
||||
|
||||
[[nodiscard]] const table_repository& tables() const;
|
||||
|
||||
private:
|
||||
connection_pool<connection> &pool_;
|
||||
query_builder query_;
|
||||
|
||||
table_repository table_repository_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef QUERY_TABLE_REPOSITORY_HPP
|
||||
#define QUERY_TABLE_REPOSITORY_HPP
|
||||
|
||||
#include "matador/sql/record.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <typeindex>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
struct table_info
|
||||
{
|
||||
std::string name;
|
||||
record prototype;
|
||||
};
|
||||
|
||||
class table_repository
|
||||
{
|
||||
public:
|
||||
template<typename Type>
|
||||
const table_info& attach(const std::string &table_name, const record &proto)
|
||||
{
|
||||
return attach(std::type_index(typeid(Type)), table_name, proto);
|
||||
}
|
||||
|
||||
const table_info& attach(std::type_index ti, const std::string &table_name, const record &proto);
|
||||
const table_info& attach(std::type_index ti, const table_info& table);
|
||||
|
||||
template<typename Type>
|
||||
std::optional<table_info> info()
|
||||
{
|
||||
return info(std::type_index(typeid(Type)));
|
||||
}
|
||||
|
||||
std::optional<table_info> info(std::type_index ti);
|
||||
|
||||
template<typename Type>
|
||||
[[nodiscard]] std::pair<std::string, std::string> reference() const
|
||||
{
|
||||
return reference(std::type_index(typeid(Type)));
|
||||
}
|
||||
|
||||
[[nodiscard]] std::pair<std::string, std::string> reference(const std::type_index &ti) const;
|
||||
|
||||
private:
|
||||
using repository = std::unordered_map<std::type_index, table_info>;
|
||||
repository repository_;
|
||||
};
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_TABLE_REPOSITORY_HPP
|
||||
@@ -4,13 +4,14 @@
|
||||
namespace matador::utils {
|
||||
|
||||
enum class constraints : unsigned char {
|
||||
NONE = 0,
|
||||
NOT_NULL = 1 << 0,
|
||||
INDEX = 1 << 1,
|
||||
UNIQUE = 1 << 2,
|
||||
PRIMARY_KEY = 1 << 3,
|
||||
FOREIGN_KEY = 1 << 4,
|
||||
DEFAULT = 1 << 5,
|
||||
NONE = 0,
|
||||
NOT_NULL = 1 << 0,
|
||||
INDEX = 1 << 1,
|
||||
UNIQUE = 1 << 2,
|
||||
PRIMARY_KEY = 1 << 3,
|
||||
FOREIGN_KEY = 1 << 4,
|
||||
DEFAULT = 1 << 5,
|
||||
AUTO_INCREMENT = 1 << 6,
|
||||
UNIQUE_NOT_NULL = UNIQUE | NOT_NULL
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user