introduced table repository

This commit is contained in:
2023-11-16 20:15:52 +01:00
parent 7c1e940814
commit c801d53e8c
25 changed files with 589 additions and 150 deletions
+1 -1
View File
@@ -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>;
+17 -1
View File
@@ -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_{};
+14 -7
View File
@@ -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 -5
View File
@@ -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>
+1 -1
View File
@@ -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();
+8 -3
View File
@@ -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
+13 -1
View File
@@ -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};
};
}
+19
View File
@@ -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_;
};
}
+55
View File
@@ -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