added sqlite query result and enhanced column generator and value extractor
This commit is contained in:
@@ -12,7 +12,8 @@ using any_type = std::variant<
|
||||
bool,
|
||||
float, double,
|
||||
const char*,
|
||||
std::string>;
|
||||
std::string,
|
||||
nullptr_t>;
|
||||
|
||||
}
|
||||
#endif //QUERY_ANY_TYPE_HPP
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef QUERY_COLUMN_HPP
|
||||
#define QUERY_COLUMN_HPP
|
||||
|
||||
#include "matador/sql/any_type.hpp"
|
||||
#include "matador/sql/types.hpp"
|
||||
|
||||
#include "matador/utils/field_attributes.hpp"
|
||||
@@ -24,16 +25,25 @@ public:
|
||||
: column(std::move(name), data_type_traits<Type>::builtin_type(attr.size()), attr)
|
||||
{}
|
||||
column(std::string name, data_type_t type, utils::field_attributes attr = utils::null_attributes);
|
||||
template<typename Type>
|
||||
column(std::string name, std::string ref_table, std::string ref_column, utils::field_attributes attr = utils::null_attributes)
|
||||
: column(std::move(name), data_type_traits<Type>::builtin_type(attr.size()), ref_table, ref_column, attr)
|
||||
{}
|
||||
column(std::string name, data_type_t type, std::string ref_table, std::string ref_column, utils::field_attributes attr = utils::null_attributes);
|
||||
|
||||
[[nodiscard]] const std::string& name() const;
|
||||
[[nodiscard]] const utils::field_attributes& attributes() const;
|
||||
[[nodiscard]] data_type_t type() const;
|
||||
[[nodiscard]] const std::string& ref_table() const;
|
||||
[[nodiscard]] const std::string& ref_column() const;
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
utils::field_attributes attributes_;
|
||||
data_type_t type_{};
|
||||
std::any value_;
|
||||
any_type value_;
|
||||
std::string ref_table_;
|
||||
std::string ref_column_;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -64,13 +74,19 @@ template <>
|
||||
column make_pk_column<std::string>(const std::string &name, size_t size);
|
||||
|
||||
template < typename Type >
|
||||
column make_fk_column(const std::string &name, size_t size = 0)
|
||||
column make_fk_column(const std::string &name, size_t size, const std::string &ref_table, const std::string &ref_column)
|
||||
{
|
||||
return make_column<Type>(name, { size, utils::constraints::FOREIGN_KEY });
|
||||
return {name, data_type_traits<Type>::builtin_type(size), ref_table, ref_column, { size, utils::constraints::FOREIGN_KEY }};
|
||||
}
|
||||
|
||||
template < typename Type >
|
||||
[[maybe_unused]] column make_fk_column(const std::string &name, const std::string &ref_table, const std::string &ref_column)
|
||||
{
|
||||
return {name, data_type_traits<Type>::builtin_type(0), ref_table, ref_column, { 0, utils::constraints::FOREIGN_KEY }};
|
||||
}
|
||||
|
||||
template <>
|
||||
column make_fk_column<std::string>(const std::string &name, size_t size);
|
||||
column make_fk_column<std::string>(const std::string &name, size_t size, const std::string &ref_table, const std::string &ref_column);
|
||||
|
||||
}
|
||||
#endif //QUERY_COLUMN_HPP
|
||||
|
||||
@@ -6,39 +6,23 @@
|
||||
|
||||
#include "matador/utils/access.hpp"
|
||||
#include "matador/utils/field_attributes.hpp"
|
||||
#include "matador/utils/identifiable.hpp"
|
||||
#include "matador/utils/identifier.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace matador::utils {
|
||||
enum class cascade_type;
|
||||
class identifiable;
|
||||
}
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
namespace detail {
|
||||
class null_identifiable : public utils::identifiable
|
||||
{
|
||||
public:
|
||||
void reset(const utils::identifier &) override {};
|
||||
[[nodiscard]] bool has_primary_key() const override { return false; }
|
||||
[[nodiscard]] const utils::identifier& primary_key() const override { return id_; }
|
||||
utils::identifier& primary_key() override { return id_; }
|
||||
[[nodiscard]] utils::identifier create_identifier() const override { return utils::identifier(id_); }
|
||||
|
||||
private:
|
||||
utils::identifier id_;
|
||||
};
|
||||
|
||||
static null_identifiable null_id;
|
||||
|
||||
}
|
||||
|
||||
class fk_column_generator : public utils::identifier_serializer
|
||||
{
|
||||
public:
|
||||
fk_column_generator() = default;
|
||||
|
||||
column generate(const char *id, utils::identifiable &x);
|
||||
|
||||
void serialize(short &i, const utils::field_attributes &attributes) override;
|
||||
void serialize(int &i, const utils::field_attributes &attributes) override;
|
||||
void serialize(long &i, const utils::field_attributes &attributes) override;
|
||||
@@ -51,9 +35,7 @@ public:
|
||||
void serialize(utils::null_type_t &type, const utils::field_attributes &attributes) override;
|
||||
|
||||
private:
|
||||
utils::identifiable &identifiable_{detail::null_id};
|
||||
const char *id_{};
|
||||
column column_;
|
||||
data_type_t type_{};
|
||||
};
|
||||
|
||||
class column_generator
|
||||
|
||||
@@ -47,8 +47,10 @@ public:
|
||||
|
||||
void on_belongs_to(const char *id, utils::identifiable &, utils::cascade_type);
|
||||
void on_has_one(const char *id, utils::identifiable &, utils::cascade_type);
|
||||
// void on_has_many(const char *, abstract_container &, const char *, const char *, cascade_type) {}
|
||||
// void on_has_many(const char *, abstract_container &, cascade_type) {}
|
||||
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::vector<std::string> &column_names_;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define QUERY_CONNECTION_HPP
|
||||
|
||||
#include "matador/sql/connection_info.hpp"
|
||||
#include "matador/sql/connection_impl.hpp"
|
||||
#include "matador/sql/dialect.hpp"
|
||||
#include "matador/sql/query_result.hpp"
|
||||
#include "matador/sql/record.hpp"
|
||||
@@ -17,6 +18,10 @@ class connection
|
||||
public:
|
||||
explicit connection(connection_info info);
|
||||
explicit connection(const std::string& dns);
|
||||
connection(const connection &x);
|
||||
connection& operator=(const connection &x);
|
||||
connection(connection &&x) noexcept = default;
|
||||
connection& operator=(connection &&x) noexcept = default;
|
||||
~connection();
|
||||
|
||||
void open();
|
||||
@@ -24,13 +29,18 @@ public:
|
||||
[[nodiscard]] bool is_open() const;
|
||||
[[nodiscard]] const connection_info& info() const;
|
||||
|
||||
template<class Type>
|
||||
query_result<Type> fetch(const std::string &sql)
|
||||
{
|
||||
return query_result<Type>(connection_->execute(sql));
|
||||
}
|
||||
query_result<record> fetch(const std::string &sql);
|
||||
std::pair<size_t, std::string> execute(const std::string &sql);
|
||||
|
||||
private:
|
||||
const connection_info connection_info_;
|
||||
connection_info connection_info_;
|
||||
bool is_open_{false};
|
||||
connection_impl *connection_{};
|
||||
std::unique_ptr<connection_impl> connection_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
#define QUERY_CONNECTION_IMPL_HPP
|
||||
|
||||
#include "matador/sql/connection_info.hpp"
|
||||
#include "matador/sql/query_result_impl.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
class query_result_impl;
|
||||
|
||||
class connection_impl
|
||||
{
|
||||
public:
|
||||
@@ -14,7 +19,8 @@ public:
|
||||
virtual void close() = 0;
|
||||
virtual bool is_open() = 0;
|
||||
|
||||
virtual void execute(const std::string &stmt) = 0;
|
||||
virtual size_t execute(const std::string &stmt) = 0;
|
||||
virtual std::unique_ptr<query_result_impl> fetch(const std::string &stmt) = 0;
|
||||
virtual void prepare(const std::string &stmt) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
#ifndef QUERY_FK_VALUE_EXTRACTOR_HPP
|
||||
#define QUERY_FK_VALUE_EXTRACTOR_HPP
|
||||
|
||||
#include "matador/sql/any_type.hpp"
|
||||
|
||||
#include "matador/utils/access.hpp"
|
||||
#include "matador/utils/field_attributes.hpp"
|
||||
|
||||
namespace matador::sql::detail {
|
||||
|
||||
class fk_value_extractor
|
||||
{
|
||||
public:
|
||||
fk_value_extractor() = default;
|
||||
|
||||
template<class Type>
|
||||
any_type extract(Type &x)
|
||||
{
|
||||
matador::utils::access::process(*this, x);
|
||||
return value_;
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
void on_primary_key(const char *, ValueType &pk, typename std::enable_if<std::is_integral<ValueType>::value && !std::is_same<bool, ValueType>::value>::type* = 0)
|
||||
{
|
||||
value_ = pk;
|
||||
}
|
||||
void on_primary_key(const char * /*id*/, std::string &pk, size_t size);
|
||||
void on_revision(const char * /*id*/, unsigned long long &/*rev*/) {}
|
||||
template < class Type >
|
||||
void on_attribute(const char * /*id*/, Type &/*x*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
|
||||
void on_attribute(const char * /*id*/, char * /*x*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
|
||||
template<class Pointer>
|
||||
void on_belongs_to(const char * /*id*/, Pointer &/*x*/, utils::cascade_type) {}
|
||||
template<class Pointer>
|
||||
void on_has_one(const char * /*id*/, Pointer &/*x*/, utils::cascade_type) {}
|
||||
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:
|
||||
any_type value_{};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_FK_VALUE_EXTRACTOR_HPP
|
||||
@@ -0,0 +1,54 @@
|
||||
#ifndef QUERY_FOREIGN_HPP
|
||||
#define QUERY_FOREIGN_HPP
|
||||
|
||||
#include "matador/utils/identifiable.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
template < class Type >
|
||||
class foreign : public utils::identifiable
|
||||
{
|
||||
public:
|
||||
foreign() = default;
|
||||
explicit foreign(Type *obj)
|
||||
: obj_(obj) {}
|
||||
|
||||
void reset(const utils::identifier &id) override {
|
||||
id_ = id;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool has_primary_key() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] const utils::identifier &primary_key() const override {
|
||||
return id_;
|
||||
}
|
||||
|
||||
utils::identifier &primary_key() override {
|
||||
return id_;
|
||||
}
|
||||
|
||||
[[nodiscard]] utils::identifier create_identifier() const override {
|
||||
return {id_};
|
||||
}
|
||||
|
||||
Type* operator->() { return obj_.get(); }
|
||||
const Type* operator->() const { return obj_.get(); }
|
||||
|
||||
Type& operator*() { return *obj_; }
|
||||
const Type& operator*() const { return *obj_; }
|
||||
|
||||
private:
|
||||
utils::identifier id_;
|
||||
std::unique_ptr<Type> obj_;
|
||||
};
|
||||
|
||||
template<class Type, typename... Args>
|
||||
[[maybe_unused]] foreign<Type> make_foreign(Args&&... args)
|
||||
{
|
||||
return foreign(new Type(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
}
|
||||
#endif //QUERY_FOREIGN_HPP
|
||||
@@ -0,0 +1,67 @@
|
||||
#ifndef QUERY_KEY_VALUE_GENERATOR_HPP
|
||||
#define QUERY_KEY_VALUE_GENERATOR_HPP
|
||||
|
||||
#include "matador/sql/fk_value_extractor.hpp"
|
||||
#include "matador/sql/key_value_pair.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace matador::utils {
|
||||
class identifiable;
|
||||
}
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
class key_value_generator
|
||||
{
|
||||
private:
|
||||
public:
|
||||
explicit key_value_generator(std::vector<key_value_pair> &result) : result_(result) {}
|
||||
|
||||
public:
|
||||
template < class Type >
|
||||
static std::vector<key_value_pair> generate(const Type &obj)
|
||||
{
|
||||
std::vector<key_value_pair> result;
|
||||
key_value_generator generator(result);
|
||||
matador::utils::access::process(generator, obj);
|
||||
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
template < class V >
|
||||
void on_primary_key(const char *id, V &x, typename std::enable_if<std::is_integral<V>::value && !std::is_same<bool, V>::value>::type* = 0)
|
||||
{
|
||||
result_.emplace_back(id, x);
|
||||
}
|
||||
void on_primary_key(const char *id, std::string &, size_t);
|
||||
void on_revision(const char *id, unsigned long long &/*rev*/);
|
||||
|
||||
template<typename Type>
|
||||
void on_attribute(const char *id, Type &x, const utils::field_attributes &/*attr*/ = utils::null_attributes)
|
||||
{
|
||||
result_.emplace_back(id, x);
|
||||
}
|
||||
|
||||
template<class Type, template < class ... > class Pointer>
|
||||
void on_belongs_to(const char *id, Pointer<Type> &x, utils::cascade_type)
|
||||
{
|
||||
result_.emplace_back(id, fk_value_extractor_.extract(*x));
|
||||
}
|
||||
template<class Type, template < class ... > class Pointer>
|
||||
void on_has_one(const char *id, Pointer<Type> &x, utils::cascade_type)
|
||||
{
|
||||
result_.emplace_back(id, fk_value_extractor_.extract(*x));
|
||||
}
|
||||
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:
|
||||
detail::fk_value_extractor fk_value_extractor_;
|
||||
std::vector<key_value_pair> &result_;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_KEY_VALUE_GENERATOR_HPP
|
||||
@@ -103,11 +103,14 @@ public:
|
||||
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& 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 = "");
|
||||
query_builder& join(const std::string &table, join_type_t);
|
||||
query_builder& on(const std::string &column, const std::string &join_column);
|
||||
query_builder& set(std::initializer_list<key_value_pair> key_values);
|
||||
query_builder& set(const std::vector<key_value_pair> &key_values);
|
||||
query_builder& where(const basic_condition &cond);
|
||||
query_builder& order_by(const std::string &column);
|
||||
query_builder& group_by(const std::string &column);
|
||||
|
||||
@@ -4,9 +4,12 @@
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/column_generator.hpp"
|
||||
#include "matador/sql/column_name_generator.hpp"
|
||||
#include "matador/sql/key_value_generator.hpp"
|
||||
#include "matador/sql/key_value_pair.hpp"
|
||||
#include "matador/sql/query_builder.hpp"
|
||||
#include "matador/sql/query_result.hpp"
|
||||
#include "matador/sql/record.hpp"
|
||||
#include "matador/sql/value_extractor.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -14,7 +17,6 @@ namespace matador::sql {
|
||||
|
||||
class basic_condition;
|
||||
class session;
|
||||
class query_builder;
|
||||
|
||||
class query_intermediate
|
||||
{
|
||||
@@ -130,6 +132,11 @@ public:
|
||||
using query_intermediate::query_intermediate;
|
||||
|
||||
query_execute_finish values(std::initializer_list<any_type> values);
|
||||
template<class Type>
|
||||
query_execute_finish values(const Type &obj)
|
||||
{
|
||||
return {db(), query().values(value_extractor::extract(obj))};
|
||||
}
|
||||
};
|
||||
|
||||
class query_create_intermediate : query_intermediate
|
||||
@@ -162,7 +169,13 @@ public:
|
||||
template<class Type>
|
||||
query_into_intermediate into(const std::string &table)
|
||||
{
|
||||
return into(table, column_name_generator::generate<Type>());
|
||||
return {db(), query().into(table, column_name_generator::generate<Type>())};
|
||||
}
|
||||
template<class Type>
|
||||
query_execute_finish into(const std::string &table, const Type &obj)
|
||||
{
|
||||
return {db(), query().into(table, column_name_generator::generate<Type>())
|
||||
.values(value_extractor::extract(obj))};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -188,6 +201,11 @@ public:
|
||||
using query_intermediate::query_intermediate;
|
||||
|
||||
query_set_intermediate set(std::initializer_list<key_value_pair> columns);
|
||||
template<class Type>
|
||||
query_set_intermediate set(const Type &obj)
|
||||
{
|
||||
return {db(), query().set(key_value_generator::generate(obj))};
|
||||
}
|
||||
};
|
||||
|
||||
class query_delete_from_intermediate : public query_execute_finish
|
||||
@@ -203,7 +221,7 @@ class query_delete_intermediate : public query_intermediate
|
||||
public:
|
||||
using query_intermediate::query_intermediate;
|
||||
|
||||
query_delete_from_intermediate from(const std::string &table, const std::string &as = "");
|
||||
query_delete_from_intermediate from(const std::string &table);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef QUERY_QUERY_RESULT_HPP
|
||||
#define QUERY_QUERY_RESULT_HPP
|
||||
|
||||
#include "matador/sql/query_result_impl.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace matador::sql {
|
||||
@@ -15,13 +17,17 @@ public:
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using value_type = Type;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using self = query_result_iterator<Type>; /**< Shortcut for this class. */
|
||||
using pointer = value_type*; /**< Shortcut for the pointer type. */
|
||||
using reference = value_type&; /**< Shortcut for the reference type */
|
||||
|
||||
public:
|
||||
query_result_iterator() = default;
|
||||
explicit query_result_iterator(query_result<Type> &res, Type *obj = nullptr)
|
||||
: obj_(obj)
|
||||
explicit query_result_iterator(query_result<Type> &res)
|
||||
: result_(res)
|
||||
{}
|
||||
query_result_iterator(query_result<Type> &res, std::unique_ptr<Type> obj)
|
||||
: obj_(std::move(obj))
|
||||
, result_(res)
|
||||
{}
|
||||
query_result_iterator(query_result_iterator&& x) noexcept
|
||||
@@ -48,19 +54,38 @@ public:
|
||||
return obj_ != rhs.obj_;
|
||||
}
|
||||
|
||||
self& operator++()
|
||||
{
|
||||
obj_.reset(result_.create());
|
||||
result_.bind(*obj_);
|
||||
if (!result_.fetch(*obj_)) {
|
||||
obj_.reset();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
self operator++(int)
|
||||
{
|
||||
const self tmp(result_, obj_);
|
||||
|
||||
obj_.reset(result_.create());
|
||||
result_.bind(*obj_);
|
||||
if (!result_.fetch(*obj_)) {
|
||||
obj_.reset();
|
||||
}
|
||||
|
||||
return std::move(tmp);
|
||||
}
|
||||
|
||||
pointer operator->()
|
||||
{
|
||||
return obj_.get();
|
||||
}
|
||||
|
||||
reference operator&()
|
||||
reference operator*()
|
||||
{
|
||||
return &obj_.get();
|
||||
}
|
||||
|
||||
std::unique_ptr<Type> operator*()
|
||||
{
|
||||
return std::move(obj_);
|
||||
return *obj_;
|
||||
}
|
||||
|
||||
pointer get()
|
||||
@@ -73,7 +98,7 @@ public:
|
||||
return obj_.release();
|
||||
}
|
||||
|
||||
protected:
|
||||
private:
|
||||
std::unique_ptr<Type> obj_;
|
||||
query_result<Type> &result_;
|
||||
};
|
||||
@@ -82,13 +107,32 @@ template < typename Type >
|
||||
class query_result
|
||||
{
|
||||
public:
|
||||
query_result(std::string sql) : sql_(std::move(sql)) {}
|
||||
using iterator = query_result_iterator<Type>;
|
||||
|
||||
[[nodiscard]] const std::string& str() const { return sql_; }
|
||||
public:
|
||||
explicit query_result(std::unique_ptr<query_result_impl> impl)
|
||||
: impl_(std::move(impl)) {}
|
||||
|
||||
iterator begin() { return std::move(++iterator(*this)); }
|
||||
iterator end() { return {}; }
|
||||
|
||||
Type begin() { return {}; }
|
||||
private:
|
||||
std::string sql_;
|
||||
friend class query_result_iterator<Type>;
|
||||
|
||||
Type* create() { return new Type; }
|
||||
|
||||
void bind(const Type &obj)
|
||||
{
|
||||
impl_->bind(obj);
|
||||
}
|
||||
|
||||
bool fetch(Type &obj)
|
||||
{
|
||||
return impl_->fetch(obj);
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<query_result_impl> impl_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
#ifndef QUERY_QUERY_RESULT_IMPL_HPP
|
||||
#define QUERY_QUERY_RESULT_IMPL_HPP
|
||||
|
||||
#include "matador/utils/access.hpp"
|
||||
#include "matador/utils/field_attributes.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace matador::utils {
|
||||
class identifiable;
|
||||
}
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
class query_result_impl
|
||||
{
|
||||
public:
|
||||
virtual ~query_result_impl() = default;
|
||||
|
||||
virtual void read_value(const char *id, size_t index, char &value) = 0;
|
||||
virtual void read_value(const char *id, size_t index, short &value) = 0;
|
||||
virtual void read_value(const char *id, size_t index, int &value) = 0;
|
||||
@@ -45,11 +52,29 @@ public:
|
||||
void on_attribute(const char *id, char *value, const utils::field_attributes &attr = utils::null_attributes);
|
||||
void on_attribute(const char *id, std::string &value, const utils::field_attributes &attr = utils::null_attributes);
|
||||
|
||||
// void on_belongs_to(const char *id, matador::identifiable_holder &x, cascade_type);
|
||||
// void on_has_one(const char *id, matador::identifiable_holder &x, cascade_type);
|
||||
void on_belongs_to(const char *id, utils::identifiable &x, utils::cascade_type);
|
||||
void on_has_one(const char *id, utils::identifiable &x, utils::cascade_type);
|
||||
|
||||
// void on_has_many(const char *, abstract_container &, const char *, const char *, cascade_type) {}
|
||||
// void on_has_many(const char *, abstract_container &, cascade_type) {}
|
||||
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) {}
|
||||
|
||||
template<class Type>
|
||||
void bind(const Type &) {}
|
||||
|
||||
template<class Type>
|
||||
bool fetch(Type &obj)
|
||||
{
|
||||
if (!next_row()) {
|
||||
return false;
|
||||
}
|
||||
matador::utils::access::process(*this, obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
[[nodiscard]] virtual bool next_row() = 0;
|
||||
|
||||
protected:
|
||||
size_t column_index_ = 0;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef QUERY_RECORD_HPP
|
||||
#define QUERY_RECORD_HPP
|
||||
|
||||
#include "matador/utils/access.hpp"
|
||||
|
||||
#include "matador/sql/column.hpp"
|
||||
|
||||
#include <vector>
|
||||
@@ -23,6 +25,15 @@ public:
|
||||
record(std::initializer_list<column> columns);
|
||||
~record() = default;
|
||||
|
||||
template<class Operator>
|
||||
void process(Operator &op)
|
||||
{
|
||||
for(auto &col : columns_) {
|
||||
// Todo: Find a solution to handle a column with process
|
||||
int todo{};
|
||||
matador::utils::access::attribute(op, col.name().c_str(), todo, col.attributes());
|
||||
}
|
||||
}
|
||||
template < typename Type >
|
||||
void append(const std::string &name, long size = -1)
|
||||
{
|
||||
|
||||
@@ -1,34 +1,26 @@
|
||||
#ifndef QUERY_VALUE_GENERATOR_HPP
|
||||
#define QUERY_VALUE_GENERATOR_HPP
|
||||
#ifndef QUERY_VALUE_EXTRACTOR_HPP
|
||||
#define QUERY_VALUE_EXTRACTOR_HPP
|
||||
|
||||
#include "matador/sql/any_type.hpp"
|
||||
|
||||
#include "matador/utils/access.hpp"
|
||||
#include "matador/utils/field_attributes.hpp"
|
||||
#include "matador/utils/identifiable.hpp"
|
||||
#include "matador/sql/fk_value_extractor.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace matador::utils {
|
||||
enum class cascade_type;
|
||||
}
|
||||
namespace matador::sql {
|
||||
|
||||
class value_generator
|
||||
class value_extractor
|
||||
{
|
||||
private:
|
||||
explicit value_generator(std::vector<any_type> &values);
|
||||
explicit value_extractor(std::vector<any_type> &values);
|
||||
|
||||
public:
|
||||
~value_generator() = default;
|
||||
~value_extractor() = default;
|
||||
|
||||
template < class Type >
|
||||
static std::vector<any_type> generate()
|
||||
static std::vector<any_type> extract(const Type &type)
|
||||
{
|
||||
std::vector<any_type> values;
|
||||
value_generator gen(values);
|
||||
Type obj;
|
||||
matador::utils::access::process(gen, obj);
|
||||
value_extractor gen(values);
|
||||
matador::utils::access::process(gen, type);
|
||||
return std::move(values);
|
||||
}
|
||||
|
||||
@@ -46,9 +38,17 @@ public:
|
||||
}
|
||||
void on_attribute(const char *id, char *x, const utils::field_attributes &/*attr*/ = utils::null_attributes);
|
||||
void on_attribute(const char *id, std::string &x, const utils::field_attributes &/*attr*/ = utils::null_attributes);
|
||||
void on_belongs_to(const char *id, utils::identifiable &x, utils::cascade_type);
|
||||
void on_has_one(const char *id, utils::identifiable &x, utils::cascade_type);
|
||||
|
||||
template<class Type, template < class ... > class Pointer>
|
||||
void on_belongs_to(const char * /*id*/, Pointer<Type> &x, utils::cascade_type)
|
||||
{
|
||||
values_.emplace_back(fk_value_extractor_.extract(*x));
|
||||
}
|
||||
template<class Type, template < class ... > class Pointer>
|
||||
void on_has_one(const char * /*id*/, Pointer<Type> &x, utils::cascade_type)
|
||||
{
|
||||
values_.emplace_back(fk_value_extractor_.extract(*x));
|
||||
}
|
||||
template<class ContainerType>
|
||||
void on_has_many(const char *, ContainerType &, const char *, const char *, utils::cascade_type) {}
|
||||
template<class ContainerType>
|
||||
@@ -62,9 +62,10 @@ private:
|
||||
}
|
||||
|
||||
private:
|
||||
detail::fk_value_extractor fk_value_extractor_;
|
||||
std::vector<any_type> &values_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_VALUE_GENERATOR_HPP
|
||||
#endif //QUERY_VALUE_EXTRACTOR_HPP
|
||||
@@ -1,12 +1,12 @@
|
||||
#ifndef QUERY_ACCESS_HPP
|
||||
#define QUERY_ACCESS_HPP
|
||||
|
||||
#include "matador/utils/cascade_type.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace matador::utils {
|
||||
|
||||
enum class cascade_type;
|
||||
|
||||
template < class Type, template < class ... > class ContainerType >
|
||||
class container;
|
||||
|
||||
|
||||
@@ -15,5 +15,35 @@ namespace matador::utils {
|
||||
*/
|
||||
void replace_all(std::string &in, const std::string &from, const std::string &to);
|
||||
|
||||
const std::string& to_string(const std::string &str);
|
||||
|
||||
/**
|
||||
* Joins a range of elements as string within a list
|
||||
* with a given delimiter and writes it to the
|
||||
* given stream
|
||||
*
|
||||
* @tparam R Type og the range (e.g. map, list, vector, etc)
|
||||
* @param range The range with the elements to join
|
||||
* @param delim The delimiter for the elements
|
||||
* @return The ostream reference
|
||||
*/
|
||||
template < class R >
|
||||
std::string join(R &range, const std::string &delim)
|
||||
{
|
||||
std::string result {};
|
||||
if (range.size() < 2) {
|
||||
for (const auto &i : range) {
|
||||
result += to_string(i);
|
||||
}
|
||||
} else {
|
||||
auto it = range.begin();
|
||||
result += to_string(*it++);
|
||||
for (;it != range.end(); ++it) {
|
||||
result += delim + to_string(*it);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
#endif //QUERY_STRING_HPP
|
||||
|
||||
Reference in New Issue
Block a user