column, placeholder and column_value generator progress
This commit is contained in:
parent
9e76203bc9
commit
1c5b2b21b0
|
|
@ -6,8 +6,8 @@
|
||||||
|
|
||||||
#include "matador/query/criteria.hpp"
|
#include "matador/query/criteria.hpp"
|
||||||
#include "matador/query/query.hpp"
|
#include "matador/query/query.hpp"
|
||||||
|
#include "matador/query/generator.hpp"
|
||||||
|
|
||||||
#include "matador/sql/column_generator.hpp"
|
|
||||||
#include "matador/sql/connection.hpp"
|
#include "matador/sql/connection.hpp"
|
||||||
#include "matador/sql/connection_pool.hpp"
|
#include "matador/sql/connection_pool.hpp"
|
||||||
#include "matador/sql/executor.hpp"
|
#include "matador/sql/executor.hpp"
|
||||||
|
|
@ -172,8 +172,8 @@ utils::result<object::object_ptr<Type>, utils::error> session::insert(Type *obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
auto res = query::query::insert()
|
auto res = query::query::insert()
|
||||||
.into(info->get().name(), sql::column_generator::generate<Type>(*schema_, true))
|
.into(info->get().name(), query::generator::columns<Type>(*schema_))
|
||||||
.values(*obj)
|
.values(query::generator::placeholders<Type>())
|
||||||
.prepare(*this);
|
.prepare(*this);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
return utils::failure(res.err());
|
return utils::failure(res.err());
|
||||||
|
|
@ -248,7 +248,7 @@ utils::result<object::object_ptr<Type>, utils::error> session::update( const obj
|
||||||
|
|
||||||
const auto col = sql::column(info.value().get().definition().primary_key()->name());
|
const auto col = sql::column(info.value().get().definition().primary_key()->name());
|
||||||
auto res = matador::query::query::update(info->get().name())
|
auto res = matador::query::query::update(info->get().name())
|
||||||
.set(*obj)
|
.set(generator::placeholders<Type>())
|
||||||
.where(col == _)
|
.where(col == _)
|
||||||
.prepare(*this);
|
.prepare(*this);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
|
|
|
||||||
|
|
@ -280,7 +280,7 @@ void session_query_builder::on_foreign_object(const char *id, Pointer &, const u
|
||||||
using namespace matador::utils;
|
using namespace matador::utils;
|
||||||
using namespace matador::query;
|
using namespace matador::query;
|
||||||
// create select query
|
// create select query
|
||||||
auto result = matador::query::query::select(sql::column_generator::generate<typename Pointer::value_type>(schema_, true))
|
auto result = matador::query::query::select(generator::columns<typename Pointer::value_type>(schema_, generator::column_generator_options::ForceLazy))
|
||||||
.from(*foreign_table)
|
.from(*foreign_table)
|
||||||
.where(sql::column(foreign_table, pk->name(), "") == _)
|
.where(sql::column(foreign_table, pk->name(), "") == _)
|
||||||
.prepare(executor_);
|
.prepare(executor_);
|
||||||
|
|
|
||||||
|
|
@ -39,11 +39,11 @@ inline bool is_column_generator_option_set(const column_generator_options source
|
||||||
|
|
||||||
constexpr auto default_column_generator_options = column_generator_options::ForceLazy;
|
constexpr auto default_column_generator_options = column_generator_options::ForceLazy;
|
||||||
|
|
||||||
class column_generator2 {
|
class column_generator {
|
||||||
public:
|
public:
|
||||||
explicit column_generator2(const std::string &table_name = "",
|
explicit column_generator(const std::string &table_name = "",
|
||||||
column_generator_options options = default_column_generator_options);
|
column_generator_options options = default_column_generator_options);
|
||||||
explicit column_generator2(const object::repository &repo,
|
explicit column_generator(const object::repository &repo,
|
||||||
const std::string &table_name = "",
|
const std::string &table_name = "",
|
||||||
column_generator_options options = default_column_generator_options);
|
column_generator_options options = default_column_generator_options);
|
||||||
|
|
||||||
|
|
@ -105,7 +105,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class ContainerType>
|
template<class ContainerType>
|
||||||
void on_has_many_to_many(const char * /*id*/, ContainerType & /*cont*/, const char *join_column, const char *inverse_join_column, const utils::foreign_attributes &/*attr*/) {
|
void on_has_many_to_many(const char * /*id*/, ContainerType & /*cont*/, const char *join_column, const char *inverse_join_column, const utils::foreign_attributes &attr) {
|
||||||
|
if (attr.fetch() == utils::fetch_type::LAZY || is_column_generator_option_set(options_, column_generator_options::ForceLazy)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
push(join_column);
|
push(join_column);
|
||||||
push(inverse_join_column);
|
push(inverse_join_column);
|
||||||
}
|
}
|
||||||
|
|
@ -184,7 +187,11 @@ public:
|
||||||
result_.emplace_back(utils::_);
|
result_.emplace_back(utils::_);
|
||||||
}
|
}
|
||||||
template<class ContainerType>
|
template<class ContainerType>
|
||||||
static void on_has_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &/*attr*/) {}
|
static void on_has_many(const char * /*id*/, ContainerType &, const char *, const utils::foreign_attributes &attr) {}
|
||||||
|
template<class ContainerType>
|
||||||
|
static void on_has_many_to_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &/*attr*/) {}
|
||||||
|
template<class ContainerType>
|
||||||
|
static void on_has_many_to_many(const char *, ContainerType &, const utils::foreign_attributes &/*attr*/) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<utils::placeholder> result_;
|
std::vector<utils::placeholder> result_;
|
||||||
|
|
@ -226,7 +233,11 @@ public:
|
||||||
result_.emplace_back(id, fk_value_extractor_.extract(*x));
|
result_.emplace_back(id, fk_value_extractor_.extract(*x));
|
||||||
}
|
}
|
||||||
template<class ContainerType>
|
template<class ContainerType>
|
||||||
static void on_has_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &/*attr*/) {}
|
static void on_has_many(const char * /*id*/, ContainerType &, const char *, const utils::foreign_attributes &attr) {}
|
||||||
|
template<class ContainerType>
|
||||||
|
static void on_has_many_to_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &/*attr*/) {}
|
||||||
|
template<class ContainerType>
|
||||||
|
static void on_has_many_to_many(const char *, ContainerType &, const utils::foreign_attributes &/*attr*/) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
detail::fk_value_extractor fk_value_extractor_{};
|
detail::fk_value_extractor fk_value_extractor_{};
|
||||||
|
|
@ -256,7 +267,18 @@ template<typename Type>
|
||||||
std::vector<sql::column> columns(const object::repository &repo,
|
std::vector<sql::column> columns(const object::repository &repo,
|
||||||
const std::string &table_name = "",
|
const std::string &table_name = "",
|
||||||
const column_generator_options options = default_column_generator_options) {
|
const column_generator_options options = default_column_generator_options) {
|
||||||
column_generator2 generator(repo, table_name, options);
|
column_generator generator(repo, table_name, options);
|
||||||
|
return generator.generate<Type>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
std::vector<sql::column> columns(const object::repository &repo,
|
||||||
|
const column_generator_options options) {
|
||||||
|
std::string table_name;
|
||||||
|
if (const auto result = repo.info<Type>()) {
|
||||||
|
table_name = result.value().get().name();
|
||||||
|
}
|
||||||
|
column_generator generator(repo, table_name, options);
|
||||||
return generator.generate<Type>();
|
return generator.generate<Type>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -265,14 +287,14 @@ std::vector<sql::column> columns(const Type &obj,
|
||||||
const object::repository &repo,
|
const object::repository &repo,
|
||||||
const std::string &table_name = "",
|
const std::string &table_name = "",
|
||||||
const column_generator_options options = default_column_generator_options) {
|
const column_generator_options options = default_column_generator_options) {
|
||||||
column_generator2 generator(repo, table_name, options);
|
column_generator generator(repo, table_name, options);
|
||||||
return generator.generate(obj);
|
return generator.generate(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
std::vector<sql::column> columns(const std::string &table_name = "",
|
std::vector<sql::column> columns(const std::string &table_name = "",
|
||||||
const column_generator_options options = default_column_generator_options) {
|
const column_generator_options options = default_column_generator_options) {
|
||||||
column_generator2 generator(table_name, options);
|
column_generator generator(table_name, options);
|
||||||
return generator.generate<Type>();
|
return generator.generate<Type>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -280,7 +302,7 @@ template<typename Type>
|
||||||
std::vector<sql::column> columns(const Type &obj,
|
std::vector<sql::column> columns(const Type &obj,
|
||||||
const std::string &table_name = "",
|
const std::string &table_name = "",
|
||||||
const column_generator_options options = default_column_generator_options) {
|
const column_generator_options options = default_column_generator_options) {
|
||||||
column_generator2 generator(table_name, options);
|
column_generator generator(table_name, options);
|
||||||
return generator.generate(obj);
|
return generator.generate(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
#include "matador/query/intermediates/query_intermediate.hpp"
|
#include "matador/query/intermediates/query_intermediate.hpp"
|
||||||
#include "matador/query/intermediates/query_into_intermediate.hpp"
|
#include "matador/query/intermediates/query_into_intermediate.hpp"
|
||||||
|
|
||||||
#include "matador/sql/column_generator.hpp"
|
#include "matador/query/generator.hpp"
|
||||||
|
|
||||||
namespace matador::query {
|
namespace matador::query {
|
||||||
|
|
||||||
|
|
@ -15,7 +15,7 @@ public:
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
query_into_intermediate into(const sql::table &table, const object::repository &schema) {
|
query_into_intermediate into(const sql::table &table, const object::repository &schema) {
|
||||||
return into(table, sql::column_generator::generate<Type>(schema));
|
return into(table, generator::columns<Type>(schema));
|
||||||
}
|
}
|
||||||
query_into_intermediate into(const sql::table &table, std::initializer_list<sql::column> columns);
|
query_into_intermediate into(const sql::table &table, std::initializer_list<sql::column> columns);
|
||||||
query_into_intermediate into(const sql::table &table, std::vector<sql::column> &&columns);
|
query_into_intermediate into(const sql::table &table, std::vector<sql::column> &&columns);
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ public:
|
||||||
|
|
||||||
executable_query values(std::initializer_list<std::variant<utils::placeholder, utils::database_type>> values);
|
executable_query values(std::initializer_list<std::variant<utils::placeholder, utils::database_type>> values);
|
||||||
executable_query values(std::vector<std::variant<utils::placeholder, utils::database_type>> &&values);
|
executable_query values(std::vector<std::variant<utils::placeholder, utils::database_type>> &&values);
|
||||||
|
executable_query values(std::vector<utils::placeholder> &&values);
|
||||||
executable_query values(std::vector<utils::database_type> &&values);
|
executable_query values(std::vector<utils::database_type> &&values);
|
||||||
template<class Type>
|
template<class Type>
|
||||||
executable_query values() {
|
executable_query values() {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "matador/query/query_intermediates.hpp"
|
#include "matador/query/query_intermediates.hpp"
|
||||||
|
|
||||||
#include "matador/sql/column_generator.hpp"
|
#include "matador/query/generator.hpp"
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
class connection;
|
class connection;
|
||||||
|
|
@ -27,7 +27,7 @@ public:
|
||||||
[[nodiscard]] static query_select_intermediate select(std::vector<sql::column> columns, std::initializer_list<sql::column> additional_columns);
|
[[nodiscard]] static query_select_intermediate select(std::vector<sql::column> columns, std::initializer_list<sql::column> additional_columns);
|
||||||
template<class Type>
|
template<class Type>
|
||||||
[[nodiscard]] static query_select_intermediate select(const object::repository &schema) {
|
[[nodiscard]] static query_select_intermediate select(const object::repository &schema) {
|
||||||
return select(sql::column_generator::generate<Type>(schema));
|
return select(generator::columns<Type>(schema));
|
||||||
}
|
}
|
||||||
[[nodiscard]] static query_insert_intermediate insert();
|
[[nodiscard]] static query_insert_intermediate insert();
|
||||||
[[nodiscard]] static query_update_intermediate update(const sql::table &table);
|
[[nodiscard]] static query_update_intermediate update(const sql::table &table);
|
||||||
|
|
|
||||||
|
|
@ -1,126 +0,0 @@
|
||||||
#ifndef QUERY_COLUMN_GENERATOR_HPP
|
|
||||||
#define QUERY_COLUMN_GENERATOR_HPP
|
|
||||||
|
|
||||||
#include "matador/utils/access.hpp"
|
|
||||||
#include "matador/utils/field_attributes.hpp"
|
|
||||||
#include "matador/utils/foreign_attributes.hpp"
|
|
||||||
#include "matador/utils/primary_key_attribute.hpp"
|
|
||||||
|
|
||||||
#include "matador/sql/column.hpp"
|
|
||||||
|
|
||||||
#include "matador/object/repository.hpp"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <stack>
|
|
||||||
|
|
||||||
namespace matador::sql {
|
|
||||||
|
|
||||||
class column_generator
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
column_generator(std::vector<column> &column_infos,
|
|
||||||
const object::repository &ts,
|
|
||||||
const std::string &table_name,
|
|
||||||
bool force_lazy);
|
|
||||||
|
|
||||||
public:
|
|
||||||
template < class Type >
|
|
||||||
static std::vector<column> generate(const object::repository &scm, const bool force_lazy = false) {
|
|
||||||
const auto info = scm.info<Type>();
|
|
||||||
if (!info) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
std::vector<column> columns;
|
|
||||||
column_generator gen(columns, scm, info.value().get().name(), force_lazy);
|
|
||||||
Type obj;
|
|
||||||
access::process(gen, obj);
|
|
||||||
return columns;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::vector<column> generate(const object::repository &scm, const std::string &name, bool force_lazy = false);
|
|
||||||
|
|
||||||
template < class V >
|
|
||||||
void on_primary_key(const char *id, V &, const utils::primary_key_attribute& /*attr*/ = utils::default_pk_attributes) {
|
|
||||||
push(id);
|
|
||||||
}
|
|
||||||
void on_revision(const char *id, uint64_t &/*rev*/);
|
|
||||||
|
|
||||||
template<typename Type>
|
|
||||||
void on_attribute(const char *id, Type &, const utils::field_attributes &/*attr*/ = utils::null_attributes) {
|
|
||||||
push(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Pointer>
|
|
||||||
void on_belongs_to(const char *id, Pointer &x, const utils::foreign_attributes &attr) {
|
|
||||||
on_foreign_key(id, x, attr);
|
|
||||||
}
|
|
||||||
template<class Pointer>
|
|
||||||
void on_has_one(const char *id, Pointer &x, const utils::foreign_attributes &attr) {
|
|
||||||
on_foreign_key(id, x, attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class ContainerType>
|
|
||||||
void on_has_many(const char * /*id*/, ContainerType &, const char *, const utils::foreign_attributes &attr) {
|
|
||||||
if (attr.fetch() == utils::fetch_type::LAZY || force_lazy_) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto info = table_schema_.info<typename ContainerType::value_type::value_type>();
|
|
||||||
if (!info) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (seen_tables.count(info->get().name()) == 0) {
|
|
||||||
auto it = seen_tables.insert(info->get().name()).first;
|
|
||||||
table_name_stack_.push(info.value().get().name());
|
|
||||||
typename ContainerType::value_type::value_type obj;
|
|
||||||
access::process(*this, obj);
|
|
||||||
table_name_stack_.pop();
|
|
||||||
seen_tables.erase(it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class ContainerType>
|
|
||||||
void on_has_many_to_many(const char * /*id*/, ContainerType & /*cont*/, const char *join_column, const char *inverse_join_column, const utils::foreign_attributes &/*attr*/) {
|
|
||||||
push(join_column);
|
|
||||||
push(inverse_join_column);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class ContainerType>
|
|
||||||
static void on_has_many_to_many(const char * /*id*/, ContainerType & /*cont*/, const utils::foreign_attributes &/*attr*/) {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template<class Pointer>
|
|
||||||
void on_foreign_key(const char *id, Pointer &, const utils::foreign_attributes &attr) {
|
|
||||||
if (attr.fetch() == utils::fetch_type::LAZY || force_lazy_) {
|
|
||||||
push(id);
|
|
||||||
} else {
|
|
||||||
const auto info = table_schema_.info<typename Pointer::value_type>();
|
|
||||||
if (!info) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (seen_tables.count(info->get().name()) == 0) {
|
|
||||||
auto it = seen_tables.insert(info->get().name()).first;
|
|
||||||
table_name_stack_.push(info.value().get().name());
|
|
||||||
typename Pointer::value_type obj;
|
|
||||||
access::process(*this, obj);
|
|
||||||
table_name_stack_.pop();
|
|
||||||
seen_tables.erase(it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void push(const std::string &column_name);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::stack<std::string> table_name_stack_;
|
|
||||||
std::vector<column> &column_infos_;
|
|
||||||
std::unordered_set<std::string> seen_tables;
|
|
||||||
const object::repository &table_schema_;
|
|
||||||
int column_index{0};
|
|
||||||
bool force_lazy_{false};
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //QUERY_COLUMN_GENERATOR_HPP
|
|
||||||
|
|
@ -57,7 +57,6 @@ add_library(matador-orm STATIC
|
||||||
../../include/matador/sql/abstract_sql_logger.hpp
|
../../include/matador/sql/abstract_sql_logger.hpp
|
||||||
../../include/matador/sql/backend_provider.hpp
|
../../include/matador/sql/backend_provider.hpp
|
||||||
../../include/matador/sql/column.hpp
|
../../include/matador/sql/column.hpp
|
||||||
../../include/matador/sql/column_generator.hpp
|
|
||||||
../../include/matador/sql/connection.hpp
|
../../include/matador/sql/connection.hpp
|
||||||
../../include/matador/sql/connection_info.hpp
|
../../include/matador/sql/connection_info.hpp
|
||||||
../../include/matador/sql/dialect.hpp
|
../../include/matador/sql/dialect.hpp
|
||||||
|
|
@ -133,7 +132,6 @@ add_library(matador-orm STATIC
|
||||||
query/value_extractor.cpp
|
query/value_extractor.cpp
|
||||||
sql/backend_provider.cpp
|
sql/backend_provider.cpp
|
||||||
sql/column.cpp
|
sql/column.cpp
|
||||||
sql/column_generator.cpp
|
|
||||||
sql/connection.cpp
|
sql/connection.cpp
|
||||||
sql/connection_info.cpp
|
sql/connection_info.cpp
|
||||||
sql/connection_pool.cpp
|
sql/connection_pool.cpp
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,22 @@
|
||||||
#include "matador/query/generator.hpp"
|
#include "matador/query/generator.hpp"
|
||||||
|
|
||||||
namespace matador::query::generator {
|
namespace matador::query::generator {
|
||||||
column_generator2::column_generator2( const std::string& table_name, const column_generator_options options)
|
column_generator::column_generator( const std::string& table_name, const column_generator_options options)
|
||||||
: options_(options) {
|
: options_(options) {
|
||||||
table_stack_.push(table_name.empty() ? std::make_shared<sql::table>() : std::make_shared<sql::table>(table_name));
|
table_stack_.push(table_name.empty() ? std::make_shared<sql::table>() : std::make_shared<sql::table>(table_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
column_generator2::column_generator2(const object::repository& repo, const std::string& table_name, const column_generator_options options)
|
column_generator::column_generator(const object::repository& repo, const std::string& table_name, const column_generator_options options)
|
||||||
: repo_(std::cref(repo))
|
: repo_(std::cref(repo))
|
||||||
, options_(options) {
|
, options_(options) {
|
||||||
table_stack_.push(table_name.empty() ? std::make_shared<sql::table>() : std::make_shared<sql::table>(table_name));
|
table_stack_.push(table_name.empty() ? std::make_shared<sql::table>() : std::make_shared<sql::table>(table_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
void column_generator2::on_revision( const char* id, uint64_t& ) {
|
void column_generator::on_revision( const char* id, uint64_t& ) {
|
||||||
push(id);
|
push(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void column_generator2::push( const std::string& column_name ) {
|
void column_generator::push( const std::string& column_name ) {
|
||||||
if (is_column_generator_option_set(options_, column_generator_options::GenerateAlias)) {
|
if (is_column_generator_option_set(options_, column_generator_options::GenerateAlias)) {
|
||||||
char str[4];
|
char str[4];
|
||||||
snprintf(str, 4, "c%02d", ++column_index);
|
snprintf(str, 4, "c%02d", ++column_index);
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,15 @@ executable_query query_into_intermediate::values(std::vector<std::variant<utils:
|
||||||
return {context_};
|
return {context_};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
executable_query query_into_intermediate::values(std::vector<utils::placeholder>&& values) {
|
||||||
|
std::vector<std::variant<utils::placeholder, utils::database_type>> transformed_values;
|
||||||
|
transformed_values.reserve(values.size());
|
||||||
|
for (auto&& val : values) {
|
||||||
|
transformed_values.emplace_back(val);
|
||||||
|
}
|
||||||
|
return this->values(std::move(transformed_values));
|
||||||
|
}
|
||||||
|
|
||||||
executable_query query_into_intermediate::values(std::vector<utils::database_type>&& values) {
|
executable_query query_into_intermediate::values(std::vector<utils::database_type>&& values) {
|
||||||
std::vector<std::variant<utils::placeholder, utils::database_type>> transformed_values;
|
std::vector<std::variant<utils::placeholder, utils::database_type>> transformed_values;
|
||||||
transformed_values.reserve(values.size());
|
transformed_values.reserve(values.size());
|
||||||
|
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
#include "matador/sql/column_generator.hpp"
|
|
||||||
|
|
||||||
#include "matador/sql/table.hpp"
|
|
||||||
|
|
||||||
namespace matador::sql {
|
|
||||||
|
|
||||||
column_generator::column_generator(std::vector<column> &column_infos,
|
|
||||||
const object::repository &scm,
|
|
||||||
const std::string &table_name,
|
|
||||||
const bool force_lazy)
|
|
||||||
: column_infos_(column_infos)
|
|
||||||
, table_schema_(scm)
|
|
||||||
, force_lazy_(force_lazy)
|
|
||||||
{
|
|
||||||
table_name_stack_.push(table_name);
|
|
||||||
seen_tables.insert(table_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<column> column_generator::generate( const object::repository& scm, const std::string& name, bool /*force_lazy*/ ) {
|
|
||||||
const auto info = scm.basic_info(name);
|
|
||||||
if (!info) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<column> columns;
|
|
||||||
for (const auto& attr : info.value().get().definition()) {
|
|
||||||
columns.emplace_back(attr.name());
|
|
||||||
}
|
|
||||||
return columns;
|
|
||||||
}
|
|
||||||
|
|
||||||
void column_generator::on_revision(const char *id, uint64_t &)
|
|
||||||
{
|
|
||||||
push(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void column_generator::push(const std::string &column_name)
|
|
||||||
{
|
|
||||||
char str[4];
|
|
||||||
snprintf(str, 4, "c%02d", ++column_index);
|
|
||||||
column_infos_.emplace_back(table{table_name_stack_.top()}, column_name, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -6,9 +6,9 @@
|
||||||
|
|
||||||
#include "matador/sql/connection.hpp"
|
#include "matador/sql/connection.hpp"
|
||||||
#include "matador/sql/dialect.hpp"
|
#include "matador/sql/dialect.hpp"
|
||||||
#include "matador/sql/column_generator.hpp"
|
|
||||||
|
|
||||||
#include "matador/query/criteria.hpp"
|
#include "matador/query/criteria.hpp"
|
||||||
|
#include "matador/query/generator.hpp"
|
||||||
#include "matador/query/query.hpp"
|
#include "matador/query/query.hpp"
|
||||||
|
|
||||||
#include "matador/utils/basic_types.hpp"
|
#include "matador/utils/basic_types.hpp"
|
||||||
|
|
@ -75,7 +75,7 @@ TEST_CASE_METHOD( QueryFixture, "Insert and select basic datatypes", "[query][da
|
||||||
};
|
};
|
||||||
|
|
||||||
res = query::insert()
|
res = query::insert()
|
||||||
.into("types", column_generator::generate<types>(repo, true))
|
.into("types", generator::columns<types>(repo))
|
||||||
.values(t)
|
.values(t)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
|
|
@ -363,7 +363,7 @@ TEST_CASE_METHOD(QueryFixture, "Test primary key", "[query][primary key]") {
|
||||||
pk pk1{ 7, "george" };
|
pk pk1{ 7, "george" };
|
||||||
|
|
||||||
res = query::insert()
|
res = query::insert()
|
||||||
.into("pk", column_generator::generate<pk>(repo))
|
.into("pk", generator::columns<pk>(repo))
|
||||||
.values(pk1)
|
.values(pk1)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
|
|
@ -392,7 +392,7 @@ TEST_CASE_METHOD(QueryFixture, "Test primary key prepared", "[query][primary key
|
||||||
pk pk1{ 7, "george" };
|
pk pk1{ 7, "george" };
|
||||||
|
|
||||||
auto stmt = query::insert()
|
auto stmt = query::insert()
|
||||||
.into("pk", column_generator::generate<pk>(repo))
|
.into("pk", generator::columns<pk>(repo))
|
||||||
.values<pk>()
|
.values<pk>()
|
||||||
.prepare(db);
|
.prepare(db);
|
||||||
REQUIRE(stmt);
|
REQUIRE(stmt);
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,8 @@
|
||||||
|
|
||||||
#include "matador/object/attribute_definition.hpp"
|
#include "matador/object/attribute_definition.hpp"
|
||||||
|
|
||||||
#include "matador/sql/column_generator.hpp"
|
|
||||||
|
|
||||||
#include "matador/query/criteria.hpp"
|
#include "matador/query/criteria.hpp"
|
||||||
|
#include "matador/query/generator.hpp"
|
||||||
#include "matador/query/query.hpp"
|
#include "matador/query/query.hpp"
|
||||||
|
|
||||||
#include "QueryFixture.hpp"
|
#include "QueryFixture.hpp"
|
||||||
|
|
@ -58,14 +57,14 @@ TEST_CASE_METHOD(QueryFixture, "Execute select statement with where clause", "[q
|
||||||
george.image.emplace_back(37);
|
george.image.emplace_back(37);
|
||||||
|
|
||||||
res = query::insert()
|
res = query::insert()
|
||||||
.into("person", column_generator::generate<person>(repo, true))
|
.into("person", generator::columns<person>(repo))
|
||||||
.values(george)
|
.values(george)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
REQUIRE(*res == 1);
|
REQUIRE(*res == 1);
|
||||||
|
|
||||||
// fetch person as record
|
// fetch person as record
|
||||||
auto result_record = query::select(column_generator::generate<person>(repo, true))
|
auto result_record = query::select(generator::columns<person>(repo))
|
||||||
.from("person")
|
.from("person")
|
||||||
.where("id"_col == 7)
|
.where("id"_col == 7)
|
||||||
.fetch_all(db);
|
.fetch_all(db);
|
||||||
|
|
@ -85,7 +84,7 @@ TEST_CASE_METHOD(QueryFixture, "Execute select statement with where clause", "[q
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetch person as person
|
// fetch person as person
|
||||||
auto result_person = query::select(column_generator::generate<person>(repo, true))
|
auto result_person = query::select(generator::columns<person>(repo))
|
||||||
.from("person")
|
.from("person")
|
||||||
.where("id"_col == 7)
|
.where("id"_col == 7)
|
||||||
.fetch_all<person>(db);
|
.fetch_all<person>(db);
|
||||||
|
|
@ -171,7 +170,7 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key", "[query][for
|
||||||
|
|
||||||
for (const auto &plane: planes) {
|
for (const auto &plane: planes) {
|
||||||
res = query::insert()
|
res = query::insert()
|
||||||
.into("airplane", column_generator::generate<airplane>(repo, true))
|
.into("airplane", generator::columns<airplane>(repo))
|
||||||
.values(*plane)
|
.values(*plane)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
|
|
@ -187,13 +186,13 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key", "[query][for
|
||||||
flight f4711{4, planes.at(1), "hans"};
|
flight f4711{4, planes.at(1), "hans"};
|
||||||
|
|
||||||
res = query::insert()
|
res = query::insert()
|
||||||
.into("flight", column_generator::generate<flight>(repo, true))
|
.into("flight", generator::columns<flight>(repo))
|
||||||
.values(f4711)
|
.values(f4711)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
REQUIRE(*res == 1);
|
REQUIRE(*res == 1);
|
||||||
|
|
||||||
auto f = query::select(column_generator::generate<flight>(repo, true))
|
auto f = query::select(generator::columns<flight>(repo))
|
||||||
.from("flight")
|
.from("flight")
|
||||||
.fetch_one(db);
|
.fetch_one(db);
|
||||||
REQUIRE(f.is_ok());
|
REQUIRE(f.is_ok());
|
||||||
|
|
@ -234,7 +233,7 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left"
|
||||||
|
|
||||||
for (const auto &plane: planes) {
|
for (const auto &plane: planes) {
|
||||||
res = query::insert()
|
res = query::insert()
|
||||||
.into("airplane", column_generator::generate<airplane>(repo, true))
|
.into("airplane", generator::columns<airplane>(repo))
|
||||||
.values(*plane)
|
.values(*plane)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
|
|
@ -262,7 +261,7 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left"
|
||||||
REQUIRE(*res == 1);
|
REQUIRE(*res == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto f = query::select(column_generator::generate<flight>(repo, true))
|
auto f = query::select(generator::columns<flight>(repo))
|
||||||
.from("flight")
|
.from("flight")
|
||||||
.fetch_one(db);
|
.fetch_one(db);
|
||||||
REQUIRE(f.is_ok());
|
REQUIRE(f.is_ok());
|
||||||
|
|
@ -324,7 +323,7 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single
|
||||||
|
|
||||||
for (const auto &plane: planes) {
|
for (const auto &plane: planes) {
|
||||||
res = query::insert()
|
res = query::insert()
|
||||||
.into("airplane", column_generator::generate<airplane>(repo, true))
|
.into("airplane", generator::columns<airplane>(repo))
|
||||||
.values(*plane)
|
.values(*plane)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
|
|
@ -347,14 +346,14 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single
|
||||||
|
|
||||||
for (const auto &f: flights) {
|
for (const auto &f: flights) {
|
||||||
res = query::insert()
|
res = query::insert()
|
||||||
.into("flight", column_generator::generate<flight>(repo, true))
|
.into("flight", generator::columns<flight>(repo))
|
||||||
.values(*f)
|
.values(*f)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
REQUIRE(*res == 1);
|
REQUIRE(*res == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto f = query::select(column_generator::generate<flight>(repo, true))
|
auto f = query::select(generator::columns<flight>(repo))
|
||||||
.from("flight")
|
.from("flight")
|
||||||
.fetch_one(db);
|
.fetch_one(db);
|
||||||
REQUIRE(f.is_ok());
|
REQUIRE(f.is_ok());
|
||||||
|
|
@ -426,7 +425,7 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with many to many relationship"
|
||||||
|
|
||||||
for (const auto &i: ingredients) {
|
for (const auto &i: ingredients) {
|
||||||
res = query::insert()
|
res = query::insert()
|
||||||
.into("ingredients", column_generator::generate<ingredient>(repo, true))
|
.into("ingredients", generator::columns<ingredient>(repo))
|
||||||
.values(i)
|
.values(i)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
|
|
@ -441,7 +440,7 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with many to many relationship"
|
||||||
|
|
||||||
for (const auto &r: recipes) {
|
for (const auto &r: recipes) {
|
||||||
res = query::insert()
|
res = query::insert()
|
||||||
.into("recipes", column_generator::generate<recipe>(repo, true))
|
.into("recipes", generator::columns<recipe>(repo))
|
||||||
.values(r)
|
.values(r)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
|
|
@ -461,7 +460,7 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with many to many relationship"
|
||||||
|
|
||||||
for (const auto & [recipe_id, ingredient_id]: recipe_ingredients) {
|
for (const auto & [recipe_id, ingredient_id]: recipe_ingredients) {
|
||||||
res = query::insert()
|
res = query::insert()
|
||||||
.into("recipe_ingredients", column_generator::generate(repo, "recipe_ingredients", true))
|
.into("recipe_ingredients", generator::columns<recipe_ingredient>(repo))
|
||||||
.values({recipe_id, ingredient_id})
|
.values({recipe_id, ingredient_id})
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@
|
||||||
#include "matador/object/attribute_definition.hpp"
|
#include "matador/object/attribute_definition.hpp"
|
||||||
|
|
||||||
#include "matador/sql/connection.hpp"
|
#include "matador/sql/connection.hpp"
|
||||||
#include "matador/sql/column_generator.hpp"
|
|
||||||
|
|
||||||
#include "matador/query/criteria.hpp"
|
#include "matador/query/criteria.hpp"
|
||||||
|
#include "matador/query/generator.hpp"
|
||||||
#include "matador/query/query.hpp"
|
#include "matador/query/query.hpp"
|
||||||
|
|
||||||
#include "matador/object/object_ptr.hpp"
|
#include "matador/object/object_ptr.hpp"
|
||||||
|
|
@ -47,19 +47,14 @@ protected:
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// template<class Type>
|
|
||||||
// std::vector<matador::utils::placeholder> to_placeholder() {
|
|
||||||
// return placeholder_generator::generate<Type>();
|
|
||||||
// }
|
|
||||||
TEST_CASE_METHOD(StatementTestFixture, "Create prepared statement", "[statement]") {
|
TEST_CASE_METHOD(StatementTestFixture, "Create prepared statement", "[statement]") {
|
||||||
using namespace matador::utils;
|
using namespace matador::utils;
|
||||||
REQUIRE(repo.attach<airplane>("airplane"));
|
REQUIRE(repo.attach<airplane>("airplane"));
|
||||||
table ap{"airplane"};
|
table ap{"airplane"};
|
||||||
SECTION("Insert with prepared statement and placeholder") {
|
SECTION("Insert with prepared statement and placeholder") {
|
||||||
auto stmt = query::insert()
|
auto stmt = query::insert()
|
||||||
.into("airplane", generator::placeholder<airplane>())
|
.into("airplane", generator::columns<airplane>(repo))
|
||||||
// .into("airplane", column_generator::generate<airplane>(repo, true))
|
.values(generator::placeholders<airplane>())
|
||||||
.values<airplane>()
|
|
||||||
.prepare(db);
|
.prepare(db);
|
||||||
REQUIRE(stmt.is_ok());
|
REQUIRE(stmt.is_ok());
|
||||||
|
|
||||||
|
|
@ -70,7 +65,7 @@ TEST_CASE_METHOD(StatementTestFixture, "Create prepared statement", "[statement]
|
||||||
stmt->reset();
|
stmt->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = query::select(column_generator::generate<airplane>(repo, true))
|
auto result = query::select(generator::columns<airplane>(repo))
|
||||||
.from(ap)
|
.from(ap)
|
||||||
.fetch_all<airplane>(db);
|
.fetch_all<airplane>(db);
|
||||||
|
|
||||||
|
|
@ -86,14 +81,14 @@ TEST_CASE_METHOD(StatementTestFixture, "Create prepared statement", "[statement]
|
||||||
SECTION("Select with prepared statement") {
|
SECTION("Select with prepared statement") {
|
||||||
for (const auto &plane: planes) {
|
for (const auto &plane: planes) {
|
||||||
auto res = query::insert()
|
auto res = query::insert()
|
||||||
.into("airplane", column_generator::generate<airplane>(repo, true))
|
.into("airplane", generator::columns<airplane>(repo))
|
||||||
.values(*plane)
|
.values(*plane)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
REQUIRE(*res == 1);
|
REQUIRE(*res == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto stmt = query::select(column_generator::generate<airplane>(repo, true))
|
auto stmt = query::select(generator::columns<airplane>(repo))
|
||||||
.from(ap)
|
.from(ap)
|
||||||
.where("brand"_col == _)
|
.where("brand"_col == _)
|
||||||
.prepare(db);
|
.prepare(db);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,8 @@
|
||||||
#include "ColorEnumTraits.hpp"
|
#include "ColorEnumTraits.hpp"
|
||||||
|
|
||||||
#include "matador/sql/connection.hpp"
|
#include "matador/sql/connection.hpp"
|
||||||
#include "matador/sql/column_generator.hpp"
|
|
||||||
|
#include "matador/query/generator.hpp"
|
||||||
#include "matador/query/query.hpp"
|
#include "matador/query/query.hpp"
|
||||||
|
|
||||||
#include "QueryFixture.hpp"
|
#include "QueryFixture.hpp"
|
||||||
|
|
@ -32,13 +33,13 @@ TEST_CASE_METHOD(TypeTraitsTestFixture, "Special handling of attributes with typ
|
||||||
location loc{1, "center", {1, 2, 3}, Color::Black};
|
location loc{1, "center", {1, 2, 3}, Color::Black};
|
||||||
|
|
||||||
auto res = query::insert()
|
auto res = query::insert()
|
||||||
.into("location", column_generator::generate<location>(repo, true))
|
.into("location", generator::columns<location>(repo))
|
||||||
.values(loc)
|
.values(loc)
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
REQUIRE(*res == 1);
|
REQUIRE(*res == 1);
|
||||||
|
|
||||||
auto result = query::select(column_generator::generate<location>(repo, true))
|
auto result = query::select(generator::columns<location>(repo))
|
||||||
.from("location")
|
.from("location")
|
||||||
.fetch_one<location>(db);
|
.fetch_one<location>(db);
|
||||||
|
|
||||||
|
|
@ -54,7 +55,7 @@ TEST_CASE_METHOD(TypeTraitsTestFixture, "Special handling of attributes with typ
|
||||||
location loc{1, "center", {1, 2, 3}, Color::Black};
|
location loc{1, "center", {1, 2, 3}, Color::Black};
|
||||||
|
|
||||||
auto stmt = query::insert()
|
auto stmt = query::insert()
|
||||||
.into("location", column_generator::generate<location>(repo, true))
|
.into("location", generator::columns<location>(repo))
|
||||||
.values<location>()
|
.values<location>()
|
||||||
.prepare(db);
|
.prepare(db);
|
||||||
REQUIRE(stmt);
|
REQUIRE(stmt);
|
||||||
|
|
@ -63,7 +64,7 @@ TEST_CASE_METHOD(TypeTraitsTestFixture, "Special handling of attributes with typ
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
REQUIRE(*res == 1);
|
REQUIRE(*res == 1);
|
||||||
|
|
||||||
auto result = query::select(column_generator::generate<location>(repo, true))
|
auto result = query::select(generator::columns<location>(repo))
|
||||||
.from("location")
|
.from("location")
|
||||||
.fetch_one<location>(db);
|
.fetch_one<location>(db);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include <catch2/catch_test_macros.hpp>
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
|
||||||
#include "matador/sql/column_generator.hpp"
|
#include "matador/query/generator.hpp"
|
||||||
|
|
||||||
#include "matador/object/repository.hpp"
|
#include "matador/object/repository.hpp"
|
||||||
|
|
||||||
#include "../test/models/product.hpp"
|
#include "../test/models/product.hpp"
|
||||||
|
|
@ -10,6 +11,7 @@
|
||||||
#include "matador/sql/table.hpp"
|
#include "matador/sql/table.hpp"
|
||||||
|
|
||||||
using namespace matador::sql;
|
using namespace matador::sql;
|
||||||
|
using namespace matador::query;
|
||||||
using namespace matador::object;
|
using namespace matador::object;
|
||||||
|
|
||||||
TEST_CASE("Generate columns from object", "[column][generator]") {
|
TEST_CASE("Generate columns from object", "[column][generator]") {
|
||||||
|
|
@ -18,7 +20,7 @@ TEST_CASE("Generate columns from object", "[column][generator]") {
|
||||||
auto result = s.attach<product>("product");
|
auto result = s.attach<product>("product");
|
||||||
REQUIRE( result );
|
REQUIRE( result );
|
||||||
|
|
||||||
auto columns = column_generator::generate<product>(s);
|
auto columns = generator::columns<product>(s);
|
||||||
|
|
||||||
const std::vector<std::string> expected_columns = {
|
const std::vector<std::string> expected_columns = {
|
||||||
"product_name",
|
"product_name",
|
||||||
|
|
@ -49,7 +51,7 @@ TEST_CASE("Generate columns for object with has many relation", "[column][genera
|
||||||
.and_then( [&s] { return s.attach<order>("order"); } );
|
.and_then( [&s] { return s.attach<order>("order"); } );
|
||||||
REQUIRE(result);
|
REQUIRE(result);
|
||||||
|
|
||||||
auto columns = column_generator::generate<order>(s);
|
auto columns = generator::columns<order>(s, generator::column_generator_options::GenerateAlias);
|
||||||
|
|
||||||
const auto order_table = std::make_shared<table>("order");
|
const auto order_table = std::make_shared<table>("order");
|
||||||
const auto order_details_table = std::make_shared<table>("order_details");
|
const auto order_details_table = std::make_shared<table>("order_details");
|
||||||
|
|
@ -99,7 +101,7 @@ TEST_CASE("Generate columns for object with eager foreign key relation", "[colum
|
||||||
{ authors_table, "distinguished", "c08" },
|
{ authors_table, "distinguished", "c08" },
|
||||||
{ books_table, "published_in", "c09" }
|
{ books_table, "published_in", "c09" }
|
||||||
};
|
};
|
||||||
auto columns = column_generator::generate<book>(s);
|
auto columns = generator::columns<book>(s, generator::column_generator_options::GenerateAlias);
|
||||||
|
|
||||||
REQUIRE(!columns.empty());
|
REQUIRE(!columns.empty());
|
||||||
REQUIRE(columns.size() == expected_columns.size());
|
REQUIRE(columns.size() == expected_columns.size());
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue