add column info (progress, not compiling)

This commit is contained in:
2024-02-08 20:09:24 +01:00
parent 78c5f64b34
commit b966a7a1a7
24 changed files with 286 additions and 99 deletions
+4 -4
View File
@@ -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_;
};
+48 -11
View File
@@ -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};
};
}
+5 -5
View File
@@ -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_)};
}
}
+2 -2
View File
@@ -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 = "");
+18 -11
View File
@@ -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
+6 -6
View File
@@ -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);
}
+12 -2
View File
@@ -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);
}