Compare commits
No commits in common. "7242dc2612353ff75d79c346c0b0c999feea2d50" and "d1731a7f154f9de2d50698c7a52ccaddd2794206" have entirely different histories.
7242dc2612
...
d1731a7f15
|
|
@ -102,7 +102,7 @@ utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> postgres_co
|
||||||
const auto type = oid2type(PQftype(res, i));
|
const auto type = oid2type(PQftype(res, i));
|
||||||
// const char *col_name = PQfname(res, i);
|
// const char *col_name = PQfname(res, i);
|
||||||
// const auto size = PQfmod(res, i);
|
// const auto size = PQfmod(res, i);
|
||||||
prototype.at(i).change_type(type);
|
prototype.at(i).type(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils::ok(std::make_unique<sql::query_result_impl>(std::make_unique<postgres_result_reader>(res), prototype));
|
return utils::ok(std::make_unique<sql::query_result_impl>(std::make_unique<postgres_result_reader>(res), prototype));
|
||||||
|
|
@ -110,7 +110,7 @@ utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> postgres_co
|
||||||
|
|
||||||
std::string postgres_connection::generate_statement_name(const sql::query_context &query) {
|
std::string postgres_connection::generate_statement_name(const sql::query_context &query) {
|
||||||
std::stringstream name;
|
std::stringstream name;
|
||||||
name << query.table.name() << "_" << query.command_name;
|
name << query.table.name << "_" << query.command_name;
|
||||||
auto result = postgres_connection::statement_name_map_.find(name.str());
|
auto result = postgres_connection::statement_name_map_.find(name.str());
|
||||||
|
|
||||||
if (result == postgres_connection::statement_name_map_.end()) {
|
if (result == postgres_connection::statement_name_map_.end()) {
|
||||||
|
|
@ -240,9 +240,9 @@ utils::result<std::vector<object::attribute_definition>, utils::error> postgres_
|
||||||
// Todo: extract size
|
// Todo: extract size
|
||||||
auto type = (string2type(reader.column(2)));
|
auto type = (string2type(reader.column(2)));
|
||||||
end = nullptr;
|
end = nullptr;
|
||||||
object::null_option_type null_opt{object::null_option_type::NULLABLE};
|
object::null_option null_opt{object::null_option::NULLABLE};
|
||||||
if (strtoul(reader.column(4), &end, 10) == 0) {
|
if (strtoul(reader.column(4), &end, 10) == 0) {
|
||||||
null_opt = object::null_option_type::NOT_NULL;
|
null_opt = object::null_option::NOT_NULL;
|
||||||
}
|
}
|
||||||
// f.default_value(res->column(4));
|
// f.default_value(res->column(4));
|
||||||
prototype.emplace_back(name, type, utils::null_attributes, null_opt, index);
|
prototype.emplace_back(name, type, utils::null_attributes, null_opt, index);
|
||||||
|
|
|
||||||
|
|
@ -11,18 +11,10 @@
|
||||||
|
|
||||||
namespace matador::object {
|
namespace matador::object {
|
||||||
|
|
||||||
enum class null_option_type : uint8_t {
|
enum class null_option : uint8_t {
|
||||||
NULLABLE, NOT_NULL
|
NULLABLE, NOT_NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
class object_definition;
|
|
||||||
|
|
||||||
struct attribute_options {
|
|
||||||
utils::field_attributes attributes;
|
|
||||||
null_option_type null_option{null_option_type::NOT_NULL};
|
|
||||||
int index{-1};
|
|
||||||
};
|
|
||||||
|
|
||||||
class attribute_definition {
|
class attribute_definition {
|
||||||
public:
|
public:
|
||||||
explicit attribute_definition(const char *name); // NOLINT(*-explicit-constructor)
|
explicit attribute_definition(const char *name); // NOLINT(*-explicit-constructor)
|
||||||
|
|
@ -34,49 +26,48 @@ public:
|
||||||
attribute_definition& operator=(attribute_definition&&) noexcept = default;
|
attribute_definition& operator=(attribute_definition&&) noexcept = default;
|
||||||
|
|
||||||
attribute_definition() = default;
|
attribute_definition() = default;
|
||||||
|
template<typename Type>
|
||||||
|
explicit attribute_definition(std::string name, std::string table_name, const utils::field_attributes& attr)
|
||||||
|
: attribute_definition(std::move(name), std::move(table_name), utils::data_type_traits<Type>::type(attr.size()), attr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
attribute_definition(std::string name, std::string table_name, utils::basic_type type, const utils::field_attributes& attr);
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
attribute_definition(std::string name, const utils::field_attributes& attr)
|
explicit attribute_definition(std::string name, const utils::field_attributes& attr)
|
||||||
: attribute_definition(std::move(name), utils::data_type_traits<Type>::type(attr.size()), attr)
|
: attribute_definition(std::move(name), utils::data_type_traits<Type>::type(attr.size()), attr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
attribute_definition(std::string name, const Type &, const utils::field_attributes& attr, null_option_type null_opt)
|
attribute_definition(std::string name, const Type &, const utils::field_attributes& attr, null_option null_opt)
|
||||||
: attribute_definition(std::move(name), utils::data_type_traits<Type>::type(attr.size()), attr, null_opt)
|
: attribute_definition(std::move(name), utils::data_type_traits<Type>::type(attr.size()), attr, null_opt)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<size_t SIZE>
|
template<size_t SIZE>
|
||||||
attribute_definition(std::string name, const char (&)[SIZE], const utils::field_attributes& attr, const null_option_type null_opt)
|
attribute_definition(std::string name, const char (&)[SIZE], const utils::field_attributes& attr, const null_option null_opt)
|
||||||
: attribute_definition(std::move(name), utils::data_type_traits<const char*>::type(attr.size()), attr, null_opt)
|
: attribute_definition(std::move(name), utils::data_type_traits<const char*>::type(attr.size()), attr, null_opt)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
attribute_definition(std::string name, utils::basic_type type, const utils::field_attributes&, null_option_type null_opt, int index = 0);
|
attribute_definition(std::string name, utils::basic_type type, const utils::field_attributes&, null_option null_opt, size_t index = 0);
|
||||||
|
attribute_definition(std::string name, std::string table_name, utils::basic_type type, const utils::field_attributes&, null_option null_opt, size_t index = 0);
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
attribute_definition(std::string name, const std::shared_ptr<attribute_definition> &ref_column, const utils::field_attributes& attr, null_option_type null_opt)
|
attribute_definition(std::string name, const std::shared_ptr<attribute_definition> &ref_column, const utils::field_attributes& attr, null_option null_opt)
|
||||||
: attribute_definition(std::move(name), utils::data_type_traits<Type>::type(attr.size()), ref_column, attr, null_opt)
|
: attribute_definition(std::move(name), utils::data_type_traits<Type>::type(attr.size()), ref_column, attr, null_opt)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
attribute_definition(std::string name, utils::basic_type type, int index, const std::shared_ptr<attribute_definition> &ref_column, const utils::field_attributes& attr, null_option_type null_opt);
|
attribute_definition(std::string name, utils::basic_type type, size_t index, const std::shared_ptr<attribute_definition> &ref_column, const utils::field_attributes& attr, null_option null_opt);
|
||||||
|
|
||||||
attribute_definition(std::string name, utils::basic_type type, const std::shared_ptr<attribute_definition> &ref_column = {});
|
|
||||||
attribute_definition(std::string name, utils::basic_type type, const attribute_options& options, const std::shared_ptr<object_definition>& obj = {}, const std::shared_ptr<attribute_definition> &ref_column = {});
|
|
||||||
|
|
||||||
[[nodiscard]] const std::string& name() const;
|
[[nodiscard]] const std::string& name() const;
|
||||||
void name(const std::string& n);
|
void name(const std::string& n);
|
||||||
[[nodiscard]] std::string full_name() const;
|
[[nodiscard]] std::string full_name() const;
|
||||||
[[nodiscard]] std::shared_ptr<object_definition> object() const;
|
[[nodiscard]] std::string table_name() const;
|
||||||
void object(const std::shared_ptr<object_definition> &obj);
|
void table_name(const std::string& tn);
|
||||||
[[nodiscard]] int index() const;
|
[[nodiscard]] int index() const;
|
||||||
[[nodiscard]] const utils::field_attributes& attributes() const;
|
[[nodiscard]] const utils::field_attributes& attributes() const;
|
||||||
[[nodiscard]] utils::field_attributes& attributes();
|
[[nodiscard]] utils::field_attributes& attributes();
|
||||||
[[nodiscard]] bool is_nullable() const;
|
[[nodiscard]] bool is_nullable() const;
|
||||||
[[nodiscard]] utils::basic_type type() const;
|
[[nodiscard]] utils::basic_type type() const;
|
||||||
void change_type(utils::basic_type type, const utils::field_attributes &attr = utils::null_attributes);
|
|
||||||
template < typename Type >
|
|
||||||
void change_type(const utils::field_attributes &attr = utils::null_attributes) {
|
|
||||||
type_ = utils::data_type_traits<Type>::type(attr.size());
|
|
||||||
}
|
|
||||||
[[nodiscard]] std::shared_ptr<attribute_definition> reference_column() const;
|
[[nodiscard]] std::shared_ptr<attribute_definition> reference_column() const;
|
||||||
[[nodiscard]] bool is_foreign_reference() const;
|
[[nodiscard]] bool is_foreign_reference() const;
|
||||||
|
|
||||||
|
|
@ -90,24 +81,60 @@ public:
|
||||||
[[nodiscard]] bool is_blob() const;
|
[[nodiscard]] bool is_blob() const;
|
||||||
[[nodiscard]] bool is_null() const;
|
[[nodiscard]] bool is_null() const;
|
||||||
|
|
||||||
|
void type(utils::basic_type type);
|
||||||
|
|
||||||
template< typename Type >
|
template< typename Type >
|
||||||
[[nodiscard]] bool is_type_of() const {
|
[[nodiscard]] bool is_type_of() const {
|
||||||
return type() == utils::data_type_traits<Type>::type(attributes().size());
|
return std::holds_alternative<Type>(value_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] std::string str() const;
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
void set(const Type &value, const utils::field_attributes &attr = utils::null_attributes)
|
||||||
|
{
|
||||||
|
attributes_ = attr;
|
||||||
|
value_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(const std::string &value, const utils::field_attributes &attr)
|
||||||
|
{
|
||||||
|
value_ = value;
|
||||||
|
attributes_ = attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(const char *value, const utils::field_attributes &attr)
|
||||||
|
{
|
||||||
|
value_ = std::string(value);
|
||||||
|
attributes_ = attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
std::optional<Type> as() const
|
||||||
|
{
|
||||||
|
return value_.as<Type>();
|
||||||
|
}
|
||||||
|
|
||||||
|
friend std::ostream& operator<<(std::ostream &out, const attribute_definition &col);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
template<class Operator>
|
||||||
|
void process(Operator &op)
|
||||||
|
{
|
||||||
|
op.on_attribute(name_.c_str(), value_, attributes_);
|
||||||
|
}
|
||||||
|
|
||||||
using data_type_index = std::vector<utils::basic_type>;
|
using data_type_index = std::vector<utils::basic_type>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class object_definition;
|
|
||||||
|
|
||||||
static const data_type_index data_type_index_;
|
static const data_type_index data_type_index_;
|
||||||
|
|
||||||
std::string name_;
|
std::string name_;
|
||||||
std::shared_ptr<object_definition> object_{};
|
std::string table_;
|
||||||
attribute_options options_;
|
int index_{-1};
|
||||||
utils::basic_type type_{utils::basic_type::type_null};
|
utils::field_attributes attributes_;
|
||||||
|
null_option null_option_{null_option::NOT_NULL};
|
||||||
|
utils::value value_;
|
||||||
std::shared_ptr<attribute_definition> reference_column_;
|
std::shared_ptr<attribute_definition> reference_column_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -119,15 +146,15 @@ private:
|
||||||
* @param null_opt
|
* @param null_opt
|
||||||
* @return A column object with a given name
|
* @return A column object with a given name
|
||||||
*/
|
*/
|
||||||
attribute_definition make_column(const std::string &name, utils::basic_type type, utils::field_attributes attr = utils::null_attributes, null_option_type null_opt = null_option_type::NOT_NULL);
|
attribute_definition make_column(const std::string &name, utils::basic_type type, utils::field_attributes attr = utils::null_attributes, null_option null_opt = null_option::NOT_NULL);
|
||||||
|
|
||||||
template < typename Type >
|
template < typename Type >
|
||||||
attribute_definition make_column(const std::string &name, utils::field_attributes attr = utils::null_attributes, null_option_type null_opt = null_option_type::NOT_NULL)
|
attribute_definition make_column(const std::string &name, utils::field_attributes attr = utils::null_attributes, null_option null_opt = null_option::NOT_NULL)
|
||||||
{
|
{
|
||||||
return make_column(name, utils::data_type_traits<Type>::type(0), attr, null_opt);
|
return make_column(name, utils::data_type_traits<Type>::type(0), attr, null_opt);
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
attribute_definition make_column<std::string>(const std::string &name, utils::field_attributes attr, null_option_type null_opt);
|
attribute_definition make_column<std::string>(const std::string &name, utils::field_attributes attr, null_option null_opt);
|
||||||
|
|
||||||
template < typename Type >
|
template < typename Type >
|
||||||
attribute_definition make_pk_column(const std::string &name, size_t size = 0)
|
attribute_definition make_pk_column(const std::string &name, size_t size = 0)
|
||||||
|
|
@ -146,7 +173,7 @@ attribute_definition make_fk_column(const std::string &name, size_t size, const
|
||||||
template < typename Type >
|
template < typename Type >
|
||||||
[[maybe_unused]] attribute_definition make_fk_column(const std::string &name, const std::shared_ptr<attribute_definition> &ref_column)
|
[[maybe_unused]] attribute_definition make_fk_column(const std::string &name, const std::shared_ptr<attribute_definition> &ref_column)
|
||||||
{
|
{
|
||||||
return {name, utils::data_type_traits<Type>::type(0), 0, ref_column, { 0, utils::constraints::FOREIGN_KEY }, null_option_type::NOT_NULL};
|
return {name, utils::data_type_traits<Type>::type(0), 0, ref_column, { 0, utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
|
@ -157,7 +184,7 @@ template < typename Type >
|
||||||
return {
|
return {
|
||||||
name, utils::data_type_traits<Type>::type(size), 0,
|
name, utils::data_type_traits<Type>::type(size), 0,
|
||||||
std::make_shared<attribute_definition>(ref_column_name, ref_table_name, utils::data_type_traits<Type>::type(size), utils::constraints::FOREIGN_KEY),
|
std::make_shared<attribute_definition>(ref_column_name, ref_table_name, utils::data_type_traits<Type>::type(size), utils::constraints::FOREIGN_KEY),
|
||||||
{ 0, utils::constraints::FOREIGN_KEY }, null_option_type::NOT_NULL
|
{ 0, utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,7 +193,7 @@ template < typename Type >
|
||||||
return {
|
return {
|
||||||
name, utils::data_type_traits<Type>::type(0), 0,
|
name, utils::data_type_traits<Type>::type(0), 0,
|
||||||
std::make_shared<attribute_definition>(ref_column_name, ref_table_name, utils::data_type_traits<Type>::type(0), utils::constraints::FOREIGN_KEY),
|
std::make_shared<attribute_definition>(ref_column_name, ref_table_name, utils::data_type_traits<Type>::type(0), utils::constraints::FOREIGN_KEY),
|
||||||
{ 0, utils::constraints::FOREIGN_KEY }, null_option_type::NOT_NULL
|
{ 0, utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ public:
|
||||||
template<class Type>
|
template<class Type>
|
||||||
attribute_definition generate(const char *id, Type &x, const std::shared_ptr<attribute_definition> &ref_column) {
|
attribute_definition generate(const char *id, Type &x, const std::shared_ptr<attribute_definition> &ref_column) {
|
||||||
access::process(*this, x);
|
access::process(*this, x);
|
||||||
return attribute_definition{id, type_, 0, ref_column, {utils::constraints::FOREIGN_KEY }, null_option_type::NOT_NULL};
|
return attribute_definition{id, type_, 0, ref_column, {utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ValueType>
|
template<typename ValueType>
|
||||||
|
|
@ -122,7 +122,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]] utils::result<std::shared_ptr<attribute_definition>, utils::error> determine_foreign_ref(const std::type_index &ti) const;
|
[[nodiscard]] utils::result<std::shared_ptr<attribute_definition>, utils::error> determine_foreign_ref(const std::type_index &ti) const;
|
||||||
void insert_missing_reference_column(const std::type_index &ti, const std::shared_ptr<attribute_definition>& ref_column) const;
|
void insert_missing_reference_column(const std::type_index &ti, std::shared_ptr<attribute_definition> ref_column) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
size_t index_ = 0;
|
size_t index_ = 0;
|
||||||
|
|
@ -140,13 +140,13 @@ void attribute_definition_generator::on_primary_key(const char *id, ValueType &x
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
void attribute_definition_generator::on_attribute(const char *id, Type &x, const utils::field_attributes &attr)
|
void attribute_definition_generator::on_attribute(const char *id, Type &x, const utils::field_attributes &attr)
|
||||||
{
|
{
|
||||||
columns_.emplace_back(id, x, attr, null_option_type::NOT_NULL);
|
columns_.emplace_back(id, x, attr, null_option::NOT_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
void attribute_definition_generator::on_attribute(const char *id, std::optional<Type> & /*x*/, const utils::field_attributes &attr)
|
void attribute_definition_generator::on_attribute(const char *id, std::optional<Type> & /*x*/, const utils::field_attributes &attr)
|
||||||
{
|
{
|
||||||
columns_.emplace_back(id, utils::data_type_traits<Type>::type(attr.size()), attr, null_option_type::NULLABLE);
|
columns_.emplace_back(id, utils::data_type_traits<Type>::type(attr.size()), attr, null_option::NULLABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,17 +18,14 @@ public:
|
||||||
using const_iterator = column_by_index::const_iterator;
|
using const_iterator = column_by_index::const_iterator;
|
||||||
|
|
||||||
object_definition() = default;
|
object_definition() = default;
|
||||||
explicit object_definition(std::string name);
|
object_definition(std::initializer_list<attribute_definition> columns);
|
||||||
object_definition(std::string name, std::initializer_list<attribute_definition> columns);
|
explicit object_definition(const std::vector<attribute_definition> &columns);
|
||||||
explicit object_definition(std::string name, const std::vector<attribute_definition> &columns);
|
|
||||||
object_definition(const object_definition &x);
|
object_definition(const object_definition &x);
|
||||||
object_definition& operator=(const object_definition &x);
|
object_definition& operator=(const object_definition &x);
|
||||||
object_definition(object_definition&&) noexcept = default;
|
object_definition(object_definition&&) noexcept = default;
|
||||||
object_definition& operator=(object_definition&&) noexcept = default;
|
object_definition& operator=(object_definition&&) noexcept = default;
|
||||||
~object_definition() = default;
|
~object_definition() = default;
|
||||||
|
|
||||||
[[nodiscard]] const std::string& name() const;
|
|
||||||
|
|
||||||
[[nodiscard]] bool has_primary_key() const;
|
[[nodiscard]] bool has_primary_key() const;
|
||||||
[[nodiscard]] std::optional<attribute_definition> primary_key() const;
|
[[nodiscard]] std::optional<attribute_definition> primary_key() const;
|
||||||
|
|
||||||
|
|
@ -36,7 +33,7 @@ public:
|
||||||
void append(const std::string &name, long size = -1) {
|
void append(const std::string &name, long size = -1) {
|
||||||
append(make_column<Type>(name, size));
|
append(make_column<Type>(name, size));
|
||||||
}
|
}
|
||||||
void append(attribute_definition&& col);
|
void append(attribute_definition col);
|
||||||
|
|
||||||
[[nodiscard]] const std::vector<attribute_definition>& columns() const;
|
[[nodiscard]] const std::vector<attribute_definition>& columns() const;
|
||||||
|
|
||||||
|
|
@ -63,9 +60,6 @@ private:
|
||||||
void add_to_map(attribute_definition &col, size_t index);
|
void add_to_map(attribute_definition &col, size_t index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class repository_node;
|
|
||||||
|
|
||||||
std::string name_;
|
|
||||||
column_by_index columns_;
|
column_by_index columns_;
|
||||||
column_by_name_map columns_by_name_;
|
column_by_name_map columns_by_name_;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,22 +17,17 @@ public:
|
||||||
using node_ptr = std::shared_ptr<repository_node>;
|
using node_ptr = std::shared_ptr<repository_node>;
|
||||||
|
|
||||||
template < typename Type >
|
template < typename Type >
|
||||||
static std::shared_ptr<repository_node> make_node(repository& repo, const std::string& name) {
|
static std::shared_ptr<repository_node> make_node(object::repository& tree, const std::string& name) {
|
||||||
auto node = std::shared_ptr<repository_node>(new repository_node(repo, name, typeid(Type)));
|
auto node = std::shared_ptr<repository_node>(new repository_node(tree, name, typeid(Type)));
|
||||||
|
|
||||||
primary_key_resolver resolver;
|
primary_key_resolver resolver;
|
||||||
object_definition obj{name, {}};
|
|
||||||
auto pk_info = resolver.resolve<Type>();
|
auto pk_info = resolver.resolve<Type>();
|
||||||
auto ref_column = determine_reference_column(typeid(Type), name, pk_info, repo);
|
auto ref_column = determine_reference_column(typeid(Type), name, pk_info, tree);
|
||||||
const auto attributes = attribute_definition_generator::generate<Type>(repo);
|
|
||||||
for (auto&& attr : attributes) {
|
|
||||||
obj.append(std::move(attr));
|
|
||||||
}
|
|
||||||
auto info = std::make_unique<object_info<Type>>(
|
auto info = std::make_unique<object_info<Type>>(
|
||||||
node,
|
node,
|
||||||
std::move(pk_info.pk),
|
std::move(pk_info.pk),
|
||||||
ref_column,
|
ref_column,
|
||||||
std::move(obj),
|
object_definition{attribute_definition_generator::generate<Type>(tree)},
|
||||||
[]{ return std::make_unique<Type>(); }
|
[]{ return std::make_unique<Type>(); }
|
||||||
);
|
);
|
||||||
node->info_ = std::move(info);
|
node->info_ = std::move(info);
|
||||||
|
|
@ -92,11 +87,11 @@ private:
|
||||||
|
|
||||||
void unlink();
|
void unlink();
|
||||||
|
|
||||||
static utils::result<node_ptr, utils::error> make_and_attach_node(repository& repo, const std::string& name, const std::type_index& ti);
|
static utils::result<node_ptr, utils::error> make_and_attach_node(object::repository& tree, const std::string& name, const std::type_index& ti);
|
||||||
static std::shared_ptr<attribute_definition> determine_reference_column(const std::type_index& ti,
|
static std::shared_ptr<attribute_definition> determine_reference_column(const std::type_index& ti,
|
||||||
object_definition& obj,
|
const std::string& name,
|
||||||
const primary_key_info& pk_info,
|
const primary_key_info& pk_info,
|
||||||
repository& repo);
|
object::repository& tree);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class repository;
|
friend class repository;
|
||||||
|
|
@ -105,7 +100,7 @@ private:
|
||||||
friend class foreign_node_completer;
|
friend class foreign_node_completer;
|
||||||
friend class const_repository_node_iterator;
|
friend class const_repository_node_iterator;
|
||||||
|
|
||||||
repository &repo_;
|
object::repository &repo_;
|
||||||
std::type_index type_index_;
|
std::type_index type_index_;
|
||||||
std::unique_ptr<basic_object_info> info_;
|
std::unique_ptr<basic_object_info> info_;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,22 @@
|
||||||
|
|
||||||
#include "matador/utils/value.hpp"
|
#include "matador/utils/value.hpp"
|
||||||
|
|
||||||
#include "matador/utils/constraints.hpp"
|
#include "matador/utils/basic_types.hpp"
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
namespace matador::utils {
|
||||||
|
enum class constraints : unsigned char;
|
||||||
|
}
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
|
|
||||||
|
enum struct field_type {
|
||||||
|
Attribute,
|
||||||
|
PrimaryKey,
|
||||||
|
ForeignKey
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -17,12 +26,12 @@ class field {
|
||||||
public:
|
public:
|
||||||
explicit field(std::string name);
|
explicit field(std::string name);
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
field(std::string name, Type value, const utils::constraints type = utils::constraints::NONE, const size_t size = 0, const int index = -1)
|
field(std::string name, Type value, const field_type type = field_type::Attribute, const size_t size = 0, const int index = -1)
|
||||||
: name_(std::move(name))
|
: name_(std::move(name))
|
||||||
, type_(type)
|
, type_(type)
|
||||||
, index_(index)
|
, index_(index)
|
||||||
, value_(value, size) {}
|
, value_(value, size) {}
|
||||||
field(std::string name, utils::basic_type dt, utils::constraints type = utils::constraints::NONE, size_t size = 0, int index = -1);
|
field(std::string name, utils::basic_type dt, field_type type = field_type::Attribute, size_t size = 0, int index = -1);
|
||||||
field(const field &x) = default;
|
field(const field &x) = default;
|
||||||
field& operator=(const field &x) = default;
|
field& operator=(const field &x) = default;
|
||||||
field(field &&x) noexcept;
|
field(field &&x) noexcept;
|
||||||
|
|
@ -36,7 +45,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] const std::string& name() const;
|
[[nodiscard]] const std::string& name() const;
|
||||||
[[nodiscard]] utils::constraints type() const;
|
[[nodiscard]] field_type type() const;
|
||||||
[[nodiscard]] size_t size() const;
|
[[nodiscard]] size_t size() const;
|
||||||
[[nodiscard]] int index() const;
|
[[nodiscard]] int index() const;
|
||||||
|
|
||||||
|
|
@ -62,16 +71,18 @@ public:
|
||||||
friend std::ostream& operator<<(std::ostream &out, const field &col);
|
friend std::ostream& operator<<(std::ostream &out, const field &col);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static utils::constraints determine_constraint(field_type type);
|
||||||
|
|
||||||
template<class Operator>
|
template<class Operator>
|
||||||
void process(Operator &op) {
|
void process(Operator &op) {
|
||||||
op.on_attribute(name_.c_str(), value_, { value_.size(), type_ } );
|
op.on_attribute(name_.c_str(), value_, { value_.size(), determine_constraint(type_) } );
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class record;
|
friend class record;
|
||||||
|
|
||||||
std::string name_;
|
std::string name_;
|
||||||
utils::constraints type_{utils::constraints::NONE};
|
field_type type_{field_type::Attribute};
|
||||||
int index_{-1};
|
int index_{-1};
|
||||||
|
|
||||||
utils::value value_;
|
utils::value value_;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,10 @@ namespace matador::utils {
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
size_t determine_size(const Type &/*val*/) { return 0; }
|
size_t determine_size(const Type &/*val*/)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
size_t determine_size(const std::string &val);
|
size_t determine_size(const std::string &val);
|
||||||
size_t determine_size(const char *val);
|
size_t determine_size(const char *val);
|
||||||
size_t determine_size(const blob &val);
|
size_t determine_size(const blob &val);
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,64 @@
|
||||||
#include "matador/object/attribute_definition.hpp"
|
#include "matador/object/attribute_definition.hpp"
|
||||||
|
|
||||||
#include "matador/object/object_definition.hpp"
|
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace matador::object {
|
namespace matador::object {
|
||||||
attribute_definition::attribute_definition(const char *name)
|
attribute_definition::attribute_definition(const char *name)
|
||||||
: attribute_definition(name, utils::basic_type::type_null, {utils::null_attributes}) {
|
: name_(name)
|
||||||
|
, attributes_(utils::null_attributes) {
|
||||||
}
|
}
|
||||||
|
|
||||||
attribute_definition::attribute_definition(std::string name)
|
attribute_definition::attribute_definition(std::string name)
|
||||||
: attribute_definition(std::move(name), utils::basic_type::type_null, {utils::null_attributes}) {
|
: name_(std::move(name))
|
||||||
|
, attributes_(utils::null_attributes) {
|
||||||
|
}
|
||||||
|
|
||||||
|
attribute_definition::attribute_definition(std::string name,
|
||||||
|
std::string table_name,
|
||||||
|
const utils::basic_type type,
|
||||||
|
const utils::field_attributes& attr)
|
||||||
|
: name_(std::move(name))
|
||||||
|
, table_(std::move(table_name))
|
||||||
|
, index_(0)
|
||||||
|
, attributes_(attr)
|
||||||
|
, value_(type, attr.size()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
attribute_definition::attribute_definition(std::string name, const utils::basic_type type,
|
||||||
|
const utils::field_attributes &attr, const null_option null_opt,
|
||||||
|
const size_t index)
|
||||||
|
: name_(std::move(name))
|
||||||
|
, index_(index)
|
||||||
|
, attributes_(attr)
|
||||||
|
, null_option_(null_opt)
|
||||||
|
, value_(type, attr.size()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
attribute_definition::attribute_definition(std::string name,
|
||||||
|
std::string table_name,
|
||||||
|
const utils::basic_type type,
|
||||||
|
const utils::field_attributes &attr, const null_option null_opt,
|
||||||
|
const size_t index)
|
||||||
|
: name_(std::move(name))
|
||||||
|
, table_(std::move(table_name))
|
||||||
|
, index_(index)
|
||||||
|
, attributes_(attr)
|
||||||
|
, null_option_(null_opt)
|
||||||
|
, value_(type, attr.size()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
attribute_definition::attribute_definition(std::string name,
|
attribute_definition::attribute_definition(std::string name,
|
||||||
const utils::basic_type type,
|
const utils::basic_type type,
|
||||||
const utils::field_attributes &attr,
|
const size_t index,
|
||||||
const null_option_type null_opt,
|
|
||||||
const int index)
|
|
||||||
: attribute_definition(std::move(name), type, {attr, null_opt, index}) {
|
|
||||||
}
|
|
||||||
|
|
||||||
attribute_definition::attribute_definition(std::string name,
|
|
||||||
const utils::basic_type type,
|
|
||||||
const int index,
|
|
||||||
const std::shared_ptr<attribute_definition> &ref_column,
|
const std::shared_ptr<attribute_definition> &ref_column,
|
||||||
const utils::field_attributes &attr,
|
const utils::field_attributes &attr, const null_option null_opt)
|
||||||
const null_option_type null_opt)
|
: name_(std::move(name))
|
||||||
: attribute_definition(std::move(name), type, {attr, null_opt, index}, {}, ref_column) {
|
, index_(index)
|
||||||
}
|
, attributes_(attr)
|
||||||
|
, null_option_(null_opt)
|
||||||
attribute_definition::attribute_definition( std::string name, const utils::basic_type type, const std::shared_ptr<attribute_definition>& ref_column )
|
, value_(type, attr.size())
|
||||||
: attribute_definition(std::move(name), type, {}, {}, ref_column) {
|
, reference_column_(ref_column) {
|
||||||
}
|
|
||||||
|
|
||||||
attribute_definition::attribute_definition( std::string name, const utils::basic_type type, const attribute_options& options, const std::shared_ptr<object_definition>& obj, const std::shared_ptr<attribute_definition>& ref_column )
|
|
||||||
: name_( std::move( name ) )
|
|
||||||
, options_( options )
|
|
||||||
, type_( type )
|
|
||||||
, reference_column_( ref_column ) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &attribute_definition::name() const {
|
const std::string &attribute_definition::name() const {
|
||||||
|
|
@ -51,40 +70,35 @@ void attribute_definition::name( const std::string& n ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string attribute_definition::full_name() const {
|
std::string attribute_definition::full_name() const {
|
||||||
return object_ ? object_->name() + "." + name_ : name_;
|
return table_ + "." + name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<object_definition> attribute_definition::object() const {
|
std::string attribute_definition::table_name() const {
|
||||||
return object_;
|
return table_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_definition::object(const std::shared_ptr<object_definition>& obj) {
|
void attribute_definition::table_name( const std::string& tn ) {
|
||||||
object_ = obj;
|
table_= tn;
|
||||||
}
|
}
|
||||||
|
|
||||||
int attribute_definition::index() const {
|
int attribute_definition::index() const {
|
||||||
return options_.index;
|
return index_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const utils::field_attributes &attribute_definition::attributes() const {
|
const utils::field_attributes &attribute_definition::attributes() const {
|
||||||
return options_.attributes;
|
return attributes_;
|
||||||
}
|
}
|
||||||
|
|
||||||
utils::field_attributes& attribute_definition::attributes() {
|
utils::field_attributes& attribute_definition::attributes() {
|
||||||
return options_.attributes;
|
return attributes_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool attribute_definition::is_nullable() const {
|
bool attribute_definition::is_nullable() const {
|
||||||
return options_.null_option == null_option_type::NULLABLE;
|
return null_option_ == null_option::NULLABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
utils::basic_type attribute_definition::type() const {
|
utils::basic_type attribute_definition::type() const {
|
||||||
return type_;
|
return value_.type();
|
||||||
}
|
|
||||||
|
|
||||||
void attribute_definition::change_type(const utils::basic_type type, const utils::field_attributes& attr) {
|
|
||||||
options_.attributes = attr;
|
|
||||||
type_ = type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<attribute_definition> attribute_definition::reference_column() const {
|
std::shared_ptr<attribute_definition> attribute_definition::reference_column() const {
|
||||||
|
|
@ -96,49 +110,62 @@ bool attribute_definition::is_foreign_reference() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool attribute_definition::is_integer() const {
|
bool attribute_definition::is_integer() const {
|
||||||
return type_ >= utils::basic_type::type_int8 && type_ <= utils::basic_type::type_uint64;
|
return value_.is_integer();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool attribute_definition::is_floating_point() const {
|
bool attribute_definition::is_floating_point() const {
|
||||||
return type_ == utils::basic_type::type_float || type_ == utils::basic_type::type_double;
|
return value_.is_floating_point();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool attribute_definition::is_bool() const {
|
bool attribute_definition::is_bool() const {
|
||||||
return type_ == utils::basic_type::type_bool;
|
return value_.is_bool();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool attribute_definition::is_string() const {
|
bool attribute_definition::is_string() const {
|
||||||
return type_ == utils::basic_type::type_text;
|
return value_.is_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool attribute_definition::is_varchar() const {
|
bool attribute_definition::is_varchar() const {
|
||||||
return type_ == utils::basic_type::type_varchar;
|
return value_.is_varchar();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool attribute_definition::is_date() const {
|
bool attribute_definition::is_date() const {
|
||||||
return type_ == utils::basic_type::type_date;
|
return value_.is_date();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool attribute_definition::is_time() const {
|
bool attribute_definition::is_time() const {
|
||||||
return type_ == utils::basic_type::type_time;
|
return value_.is_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool attribute_definition::is_blob() const {
|
bool attribute_definition::is_blob() const {
|
||||||
return type_ == utils::basic_type::type_blob;
|
return value_.is_blob();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool attribute_definition::is_null() const {
|
bool attribute_definition::is_null() const {
|
||||||
return type_ == utils::basic_type::type_null;
|
return value_.is_null();
|
||||||
|
}
|
||||||
|
|
||||||
|
void attribute_definition::type(const utils::basic_type type) {
|
||||||
|
value_.type(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string attribute_definition::str() const {
|
||||||
|
return value_.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const attribute_definition &col) {
|
||||||
|
out << col.str();
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
attribute_definition make_column(const std::string &name, utils::basic_type type, utils::field_attributes attr,
|
attribute_definition make_column(const std::string &name, utils::basic_type type, utils::field_attributes attr,
|
||||||
null_option_type null_opt) {
|
null_option null_opt) {
|
||||||
return {name, type, attr, null_opt};
|
return {name, type, attr, null_opt};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
attribute_definition make_column<std::string>(const std::string &name, utils::field_attributes attr,
|
attribute_definition make_column<std::string>(const std::string &name, utils::field_attributes attr,
|
||||||
null_option_type null_opt) {
|
null_option null_opt) {
|
||||||
return make_column(name, utils::data_type_traits<std::string>::type(attr.size()), attr, null_opt);
|
return make_column(name, utils::data_type_traits<std::string>::type(attr.size()), attr, null_opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -151,7 +178,7 @@ template<>
|
||||||
attribute_definition make_fk_column<std::string>(const std::string &name, size_t size, const std::shared_ptr<attribute_definition> &ref_column) {
|
attribute_definition make_fk_column<std::string>(const std::string &name, size_t size, const std::shared_ptr<attribute_definition> &ref_column) {
|
||||||
return {
|
return {
|
||||||
name, utils::data_type_traits<std::string>::type(size), 0, ref_column,
|
name, utils::data_type_traits<std::string>::type(size), 0, ref_column,
|
||||||
{size, utils::constraints::FOREIGN_KEY}, null_option_type::NOT_NULL
|
{size, utils::constraints::FOREIGN_KEY}, null_option::NOT_NULL
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,8 +186,8 @@ template<>
|
||||||
attribute_definition make_fk_column<std::string>( const std::string& name, const std::string& ref_table_name, const std::string& ref_column_name ) {
|
attribute_definition make_fk_column<std::string>( const std::string& name, const std::string& ref_table_name, const std::string& ref_column_name ) {
|
||||||
return {
|
return {
|
||||||
name, utils::basic_type::type_varchar, 0,
|
name, utils::basic_type::type_varchar, 0,
|
||||||
std::make_shared<attribute_definition>(ref_column_name, std::make_shared<object_definition>(ref_table_name), utils::basic_type::type_varchar, utils::constraints::FOREIGN_KEY),
|
std::make_shared<attribute_definition>(ref_column_name, ref_table_name, utils::basic_type::type_varchar, utils::constraints::FOREIGN_KEY),
|
||||||
{ 0, utils::constraints::FOREIGN_KEY }, null_option_type::NOT_NULL
|
{ 0, utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,7 +196,7 @@ attribute_definition make_fk_column<std::string>(const std::string &name, size_t
|
||||||
const auto ref_column = std::make_shared<attribute_definition>(ref_column_name, ref_table_name, utils::basic_type::type_varchar, utils::constraints::FOREIGN_KEY);
|
const auto ref_column = std::make_shared<attribute_definition>(ref_column_name, ref_table_name, utils::basic_type::type_varchar, utils::constraints::FOREIGN_KEY);
|
||||||
return {
|
return {
|
||||||
name, utils::data_type_traits<std::string>::type(size), 0, ref_column,
|
name, utils::data_type_traits<std::string>::type(size), 0, ref_column,
|
||||||
{size, utils::constraints::FOREIGN_KEY}, null_option_type::NOT_NULL
|
{size, utils::constraints::FOREIGN_KEY}, null_option::NOT_NULL
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,13 @@
|
||||||
|
|
||||||
namespace matador::object {
|
namespace matador::object {
|
||||||
|
|
||||||
attribute_definition_generator::attribute_definition_generator(std::vector<attribute_definition> &columns, const repository &repo)
|
attribute_definition_generator::attribute_definition_generator(std::vector<object::attribute_definition> &columns, const repository &repo)
|
||||||
: columns_(columns)
|
: columns_(columns)
|
||||||
, repo_(repo)
|
, repo_(repo)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void attribute_definition_generator::on_revision(const char *id, uint64_t &rev) {
|
void attribute_definition_generator::on_revision(const char *id, uint64_t &rev)
|
||||||
|
{
|
||||||
on_attribute(id, rev);
|
on_attribute(id, rev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -16,7 +17,7 @@ utils::result<std::shared_ptr<attribute_definition>, utils::error> attribute_def
|
||||||
return repo_.reference_column(ti);
|
return repo_.reference_column(ti);
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_definition_generator::insert_missing_reference_column(const std::type_index& ti, const std::shared_ptr<attribute_definition>& ref_column) const {
|
void attribute_definition_generator::insert_missing_reference_column(const std::type_index& ti, std::shared_ptr<attribute_definition> ref_column) const {
|
||||||
const_cast<repository&>(repo_).missing_references_.insert({ti, ref_column});
|
const_cast<repository&>(repo_).missing_references_.insert({ti, ref_column});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,18 @@
|
||||||
#include "matador/object/object_definition.hpp"
|
#include "matador/object/object_definition.hpp"
|
||||||
|
|
||||||
namespace matador::object {
|
namespace matador::object {
|
||||||
object_definition::object_definition(std::string name)
|
object_definition::object_definition(const std::initializer_list<attribute_definition> columns)
|
||||||
: name_(std::move(name)) {}
|
: columns_(columns) {
|
||||||
|
|
||||||
object_definition::object_definition(std::string name, const std::initializer_list<attribute_definition> columns)
|
|
||||||
: name_(std::move(name))
|
|
||||||
, columns_(columns) {
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
object_definition::object_definition(std::string name, const std::vector<attribute_definition> &columns)
|
object_definition::object_definition(const std::vector<attribute_definition> &columns)
|
||||||
: name_(std::move(name))
|
: columns_(columns) {
|
||||||
, columns_(columns) {
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
object_definition::object_definition(const object_definition &x)
|
object_definition::object_definition(const object_definition &x)
|
||||||
: name_(x.name_)
|
: columns_(x.columns_)
|
||||||
, columns_(x.columns_)
|
|
||||||
, pk_index_(x.pk_index_) {
|
, pk_index_(x.pk_index_) {
|
||||||
for (auto& col : columns_) {
|
for (auto& col : columns_) {
|
||||||
add_to_map(col, col.index());
|
add_to_map(col, col.index());
|
||||||
|
|
@ -31,7 +25,6 @@ object_definition &object_definition::operator=(const object_definition &x)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
name_ = x.name_;
|
|
||||||
columns_ = x.columns_;
|
columns_ = x.columns_;
|
||||||
columns_by_name_.clear();
|
columns_by_name_.clear();
|
||||||
pk_index_ = x.pk_index_;
|
pk_index_ = x.pk_index_;
|
||||||
|
|
@ -41,11 +34,8 @@ object_definition &object_definition::operator=(const object_definition &x)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& object_definition::name() const {
|
bool object_definition::has_primary_key() const
|
||||||
return name_;
|
{
|
||||||
}
|
|
||||||
|
|
||||||
bool object_definition::has_primary_key() const {
|
|
||||||
return pk_index_ > -1;
|
return pk_index_ > -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,12 +48,14 @@ std::optional<attribute_definition> object_definition::primary_key() const
|
||||||
return columns_[pk_index_];
|
return columns_[pk_index_];
|
||||||
}
|
}
|
||||||
|
|
||||||
void object_definition::append(attribute_definition&& col) {
|
void object_definition::append(attribute_definition col)
|
||||||
|
{
|
||||||
auto &ref = columns_.emplace_back(std::move(col));
|
auto &ref = columns_.emplace_back(std::move(col));
|
||||||
add_to_map(ref, columns_.size()-1);
|
add_to_map(ref, columns_.size()-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<object::attribute_definition> &object_definition::columns() const {
|
const std::vector<object::attribute_definition> &object_definition::columns() const
|
||||||
|
{
|
||||||
return columns_;
|
return columns_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,12 +71,12 @@ const attribute_definition &object_definition::at( const size_t index) const
|
||||||
|
|
||||||
object_definition::iterator object_definition::find(const std::string &column_name)
|
object_definition::iterator object_definition::find(const std::string &column_name)
|
||||||
{
|
{
|
||||||
const auto it = columns_by_name_.find(column_name);
|
auto it = columns_by_name_.find(column_name);
|
||||||
return it != columns_by_name_.end() ? columns_.begin() + it->second.second : columns_.end();
|
return it != columns_by_name_.end() ? columns_.begin() + it->second.second : columns_.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
object_definition::const_iterator object_definition::find(const std::string &column_name) const {
|
object_definition::const_iterator object_definition::find(const std::string &column_name) const {
|
||||||
const auto it = columns_by_name_.find(column_name);
|
auto it = columns_by_name_.find(column_name);
|
||||||
return it != columns_by_name_.end() ? columns_.begin() + it->second.second : columns_.end();
|
return it != columns_by_name_.end() ? columns_.begin() + it->second.second : columns_.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,12 +45,10 @@ const basic_object_info &repository_node::info() const {
|
||||||
|
|
||||||
void repository_node::update_name(const std::string& name) {
|
void repository_node::update_name(const std::string& name) {
|
||||||
name_ = name;
|
name_ = name;
|
||||||
if (info_->reference_column() && info_->reference_column()->object() != nullptr) {
|
info_->reference_column()->table_name(name);
|
||||||
info_->reference_column()->object()->name_ = name;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const repository& repository_node::schema() const {
|
const object::repository& repository_node::schema() const {
|
||||||
return repo_;
|
return repo_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,27 +96,27 @@ void repository_node::unlink() {
|
||||||
previous_sibling_.reset();
|
previous_sibling_.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
utils::result<repository_node::node_ptr, utils::error> repository_node::make_and_attach_node(repository& repo, const std::string& name, const std::type_index& ti) {
|
utils::result<repository_node::node_ptr, utils::error> repository_node::make_and_attach_node(object::repository& tree, const std::string& name, const std::type_index& ti) {
|
||||||
const auto node = std::shared_ptr<repository_node>(new repository_node(repo, name, ti));
|
const auto node = std::shared_ptr<repository_node>(new repository_node(tree, name, ti));
|
||||||
|
|
||||||
return repo.attach_node(node, "");
|
return tree.attach_node(node, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<attribute_definition> repository_node::determine_reference_column(const std::type_index& ti, object_definition& obj, const primary_key_info& pk_info, repository& repo) {
|
std::shared_ptr<attribute_definition> repository_node::determine_reference_column(const std::type_index& ti, const std::string& name, const primary_key_info& pk_info, object::repository& tree) {
|
||||||
const auto it = repo.missing_references_.find(ti);
|
const auto it = tree.missing_references_.find(ti);
|
||||||
if (it == repo.missing_references_.end()) {
|
if (it == tree.missing_references_.end()) {
|
||||||
return std::make_shared<attribute_definition>(pk_info.pk_column_name, pk_info.type, attribute_options{utils::constraints::FOREIGN_KEY});
|
return std::make_shared<attribute_definition>(pk_info.pk_column_name, name, pk_info.type, utils::constraints::FOREIGN_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ref_column = it->second;
|
auto ref_column = it->second;
|
||||||
repo.missing_references_.erase(it);
|
tree.missing_references_.erase(it);
|
||||||
ref_column->name(pk_info.pk_column_name);
|
ref_column->name(pk_info.pk_column_name);
|
||||||
ref_column->object(obj);
|
ref_column->table_name(name);
|
||||||
ref_column->change_type(pk_info.type);
|
ref_column->type(pk_info.type);
|
||||||
ref_column->attributes() = utils::constraints::FOREIGN_KEY;
|
ref_column->attributes() = utils::constraints::FOREIGN_KEY;
|
||||||
|
|
||||||
if (obj.name().empty()) {
|
if (name.empty()) {
|
||||||
repo.missing_references_.insert({ti, ref_column});
|
tree.missing_references_.insert({ti, ref_column});
|
||||||
}
|
}
|
||||||
|
|
||||||
return ref_column;
|
return ref_column;
|
||||||
|
|
|
||||||
|
|
@ -7,15 +7,18 @@ namespace detail {
|
||||||
|
|
||||||
void initialize_by_basic_type(basic_type type, database_type &val);
|
void initialize_by_basic_type(basic_type type, database_type &val);
|
||||||
|
|
||||||
size_t determine_size(const std::string &val) {
|
size_t determine_size(const std::string &val)
|
||||||
|
{
|
||||||
return val.size();
|
return val.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t determine_size(const char *val) {
|
size_t determine_size(const char *val)
|
||||||
|
{
|
||||||
return strlen(val);
|
return strlen(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t determine_size(const blob &val) {
|
size_t determine_size(const blob &val)
|
||||||
|
{
|
||||||
return val.size();
|
return val.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ utils::result<sql::query_result<sql::record>, utils::error> session::fetch_all(c
|
||||||
// adjust columns from given query
|
// adjust columns from given query
|
||||||
for (auto &col: q.prototype) {
|
for (auto &col: q.prototype) {
|
||||||
if (const auto rit = it->second.find(col.name()); rit != it->second.end()) {
|
if (const auto rit = it->second.find(col.name()); rit != it->second.end()) {
|
||||||
const_cast<object::attribute_definition &>(col).change_type(rit->type());
|
const_cast<object::attribute_definition &>(col).type(rit->type());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto res = fetch(q);
|
auto res = fetch(q);
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,23 @@
|
||||||
namespace matador::query {
|
namespace matador::query {
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
sql::field_type determine_field_type(const utils::constraints c) {
|
||||||
|
if (is_constraint_set(c, utils::constraints::FOREIGN_KEY)) {
|
||||||
|
return sql::field_type::ForeignKey;
|
||||||
|
}
|
||||||
|
if (is_constraint_set(c, utils::constraints::PRIMARY_KEY)) {
|
||||||
|
return sql::field_type::PrimaryKey;
|
||||||
|
}
|
||||||
|
return sql::field_type::Attribute;
|
||||||
|
}
|
||||||
|
|
||||||
sql::record *create_prototype(const std::vector<object::attribute_definition> &prototype) {
|
sql::record *create_prototype(const std::vector<object::attribute_definition> &prototype) {
|
||||||
auto result = std::make_unique<sql::record>();
|
auto result = std::make_unique<sql::record>();
|
||||||
for (const auto &col: prototype) {
|
for (const auto &col: prototype) {
|
||||||
result->append({
|
result->append({
|
||||||
col.name(),
|
col.name(),
|
||||||
col.type(),
|
col.type(),
|
||||||
col.attributes().options(),
|
determine_field_type(col.attributes().options()),
|
||||||
col.attributes().size(),
|
col.attributes().size(),
|
||||||
col.index()
|
col.index()
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ std::string handle_column(sql::query_context &ctx, const sql::dialect *d, const
|
||||||
ctx.column_aliases.insert({column_table->has_alias() ? column_table->alias() : column_table->name() + "." + col.column_name(), col.alias()});
|
ctx.column_aliases.insert({column_table->has_alias() ? column_table->alias() : column_table->name() + "." + col.column_name(), col.alias()});
|
||||||
if (col.is_function()) {
|
if (col.is_function()) {
|
||||||
ctx.prototype.emplace_back(col.has_alias() ? col.alias() : col.column_name());
|
ctx.prototype.emplace_back(col.has_alias() ? col.alias() : col.column_name());
|
||||||
ctx.prototype.back().change_type(utils::basic_type::type_int32);
|
ctx.prototype.back().type(utils::basic_type::type_int32);
|
||||||
} else {
|
} else {
|
||||||
ctx.prototype.emplace_back(col.column_name());
|
ctx.prototype.emplace_back(col.column_name());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -229,7 +229,7 @@ utils::result<std::unique_ptr<statement_impl>, utils::error> connection::perform
|
||||||
[&col](const auto &value) { return value.name() == col.name(); }
|
[&col](const auto &value) { return value.name() == col.name(); }
|
||||||
);
|
);
|
||||||
if (col.type() == utils::basic_type::type_null && rit != result->end()) {
|
if (col.type() == utils::basic_type::type_null && rit != result->end()) {
|
||||||
const_cast<object::attribute_definition&>(col).change_type(rit->type());
|
const_cast<object::attribute_definition&>(col).type(rit->type());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
#include "matador/sql/field.hpp"
|
#include "matador/sql/field.hpp"
|
||||||
|
|
||||||
|
#include "matador/utils/constraints.hpp"
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
|
|
@ -9,7 +11,7 @@ field::field(std::string name)
|
||||||
, value_(nullptr)
|
, value_(nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
field::field(std::string name, const utils::basic_type dt, const utils::constraints type, const size_t size, const int index)
|
field::field(std::string name, const utils::basic_type dt, const field_type type, const size_t size, const int index)
|
||||||
: name_(std::move(name))
|
: name_(std::move(name))
|
||||||
, type_(type)
|
, type_(type)
|
||||||
, index_(index)
|
, index_(index)
|
||||||
|
|
@ -40,7 +42,7 @@ const std::string &field::name() const
|
||||||
return name_;
|
return name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
utils::constraints field::type() const {
|
field_type field::type() const {
|
||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -60,6 +62,19 @@ std::ostream &operator<<(std::ostream &out, const field &col)
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
utils::constraints field::determine_constraint(const field_type type) {
|
||||||
|
switch (type) {
|
||||||
|
case field_type::PrimaryKey:
|
||||||
|
return utils::constraints::PRIMARY_KEY;
|
||||||
|
case field_type::ForeignKey:
|
||||||
|
return utils::constraints::FOREIGN_KEY;
|
||||||
|
case field_type::Attribute:
|
||||||
|
default:
|
||||||
|
return utils::constraints::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
std::string field::str() const
|
std::string field::str() const
|
||||||
{
|
{
|
||||||
return as<std::string>().value_or("");
|
return as<std::string>().value_or("");
|
||||||
|
|
@ -101,15 +116,15 @@ bool field::is_null() const
|
||||||
}
|
}
|
||||||
|
|
||||||
bool field::is_primary_key() const {
|
bool field::is_primary_key() const {
|
||||||
return type_ == utils::constraints::PRIMARY_KEY;
|
return type_ == field_type::PrimaryKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool field::is_foreign_key() const {
|
bool field::is_foreign_key() const {
|
||||||
return type_ == utils::constraints::FOREIGN_KEY;
|
return type_ == field_type::ForeignKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool field::is_attribute() const {
|
bool field::is_attribute() const {
|
||||||
return !is_primary_key() && !is_foreign_key();
|
return type_ == field_type::Attribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,16 @@
|
||||||
|
|
||||||
namespace matador::sql::detail {
|
namespace matador::sql::detail {
|
||||||
|
|
||||||
|
field_type determine_field_type(const utils::constraints c) {
|
||||||
|
if (is_constraint_set(c, utils::constraints::FOREIGN_KEY)) {
|
||||||
|
return field_type::ForeignKey;
|
||||||
|
}
|
||||||
|
if (is_constraint_set(c, utils::constraints::PRIMARY_KEY)) {
|
||||||
|
return field_type::PrimaryKey;
|
||||||
|
}
|
||||||
|
return field_type::Attribute;
|
||||||
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
record *create_prototype<record>(const std::vector<object::attribute_definition> &prototype) {
|
record *create_prototype<record>(const std::vector<object::attribute_definition> &prototype) {
|
||||||
auto result = std::make_unique<record>();
|
auto result = std::make_unique<record>();
|
||||||
|
|
@ -12,7 +22,7 @@ record *create_prototype<record>(const std::vector<object::attribute_definition>
|
||||||
result->append({
|
result->append({
|
||||||
col.name(),
|
col.name(),
|
||||||
col.type(),
|
col.type(),
|
||||||
col.attributes().options(),
|
determine_field_type(col.attributes().options()),
|
||||||
col.attributes().size(),
|
col.attributes().size(),
|
||||||
col.index()
|
col.index()
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ using namespace matador::test;
|
||||||
|
|
||||||
TEST_CASE_METHOD(SchemaFixture, "Test schema one-two-many", "[schema]") {
|
TEST_CASE_METHOD(SchemaFixture, "Test schema one-two-many", "[schema]") {
|
||||||
using namespace matador::test;
|
using namespace matador::test;
|
||||||
orm::schema repo(pool/*, "NoopSchema"*/);
|
orm::schema repo(pool, "NoopSchema");
|
||||||
|
|
||||||
auto result = repo.attach<department>("departments")
|
auto result = repo.attach<department>("departments")
|
||||||
.and_then( [&repo] { return repo.attach<employee>("employees"); } );
|
.and_then( [&repo] { return repo.attach<employee>("employees"); } );
|
||||||
|
|
|
||||||
|
|
@ -20,15 +20,15 @@ TEST_CASE("Generate column definitions from object", "[column][definition][gener
|
||||||
auto columns = attribute_definition_generator::generate<matador::test::product>(repo);
|
auto columns = attribute_definition_generator::generate<matador::test::product>(repo);
|
||||||
|
|
||||||
const std::vector expected_columns = {
|
const std::vector expected_columns = {
|
||||||
attribute_definition{"product_name", basic_type::type_varchar, constraints::PRIMARY_KEY, null_option_type::NOT_NULL },
|
attribute_definition{"product_name", basic_type::type_varchar, constraints::PRIMARY_KEY, null_option::NOT_NULL },
|
||||||
attribute_definition{"supplier_id", basic_type::type_uint32, constraints::FOREIGN_KEY, null_option_type::NOT_NULL },
|
attribute_definition{"supplier_id", basic_type::type_uint32, constraints::FOREIGN_KEY, null_option::NOT_NULL },
|
||||||
attribute_definition{"category_id", basic_type::type_uint32, constraints::FOREIGN_KEY, null_option_type::NOT_NULL },
|
attribute_definition{"category_id", basic_type::type_uint32, constraints::FOREIGN_KEY, null_option::NOT_NULL },
|
||||||
attribute_definition{"quantity_per_unit", basic_type::type_varchar, null_attributes, null_option_type::NOT_NULL },
|
attribute_definition{"quantity_per_unit", basic_type::type_varchar, null_attributes, null_option::NOT_NULL },
|
||||||
attribute_definition{"unit_price", basic_type::type_uint32, null_attributes, null_option_type::NOT_NULL },
|
attribute_definition{"unit_price", basic_type::type_uint32, null_attributes, null_option::NOT_NULL },
|
||||||
attribute_definition{"units_in_stock", basic_type::type_uint32, null_attributes, null_option_type::NOT_NULL },
|
attribute_definition{"units_in_stock", basic_type::type_uint32, null_attributes, null_option::NOT_NULL },
|
||||||
attribute_definition{"units_in_order", basic_type::type_uint32, null_attributes, null_option_type::NOT_NULL },
|
attribute_definition{"units_in_order", basic_type::type_uint32, null_attributes, null_option::NOT_NULL },
|
||||||
attribute_definition{"reorder_level", basic_type::type_uint32, null_attributes, null_option_type::NOT_NULL },
|
attribute_definition{"reorder_level", basic_type::type_uint32, null_attributes, null_option::NOT_NULL },
|
||||||
attribute_definition{"discontinued", basic_type::type_bool, null_attributes, null_option_type::NOT_NULL }
|
attribute_definition{"discontinued", basic_type::type_bool, null_attributes, null_option::NOT_NULL }
|
||||||
};
|
};
|
||||||
REQUIRE(!columns.empty());
|
REQUIRE(!columns.empty());
|
||||||
REQUIRE(columns.size() == expected_columns.size());
|
REQUIRE(columns.size() == expected_columns.size());
|
||||||
|
|
@ -46,9 +46,9 @@ TEST_CASE("Generate columns from object with nullable columns", "[column generat
|
||||||
auto columns = attribute_definition_generator::generate<matador::test::optional>(repo);
|
auto columns = attribute_definition_generator::generate<matador::test::optional>(repo);
|
||||||
|
|
||||||
const std::vector expected_columns = {
|
const std::vector expected_columns = {
|
||||||
attribute_definition{"id", basic_type::type_uint32, constraints::PRIMARY_KEY, null_option_type::NOT_NULL },
|
attribute_definition{"id", basic_type::type_uint32, constraints::PRIMARY_KEY, null_option::NOT_NULL },
|
||||||
attribute_definition{"name", basic_type::type_varchar, null_attributes, null_option_type::NOT_NULL },
|
attribute_definition{"name", basic_type::type_varchar, null_attributes, null_option::NOT_NULL },
|
||||||
attribute_definition{"age", basic_type::type_uint32, null_attributes, null_option_type::NOT_NULL }
|
attribute_definition{"age", basic_type::type_uint32, null_attributes, null_option::NOT_NULL }
|
||||||
};
|
};
|
||||||
REQUIRE(!columns.empty());
|
REQUIRE(!columns.empty());
|
||||||
REQUIRE(columns.size() == expected_columns.size());
|
REQUIRE(columns.size() == expected_columns.size());
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ TEST_CASE_METHOD(QueryFixture, "Test create table sql statement string", "[query
|
||||||
auto ctx = query::create()
|
auto ctx = query::create()
|
||||||
.table("person", {
|
.table("person", {
|
||||||
make_pk_column<uint32_t>("id"),
|
make_pk_column<uint32_t>("id"),
|
||||||
make_column<std::string>("name", {255, constraints::UNIQUE}, null_option_type::NOT_NULL),
|
make_column<std::string>("name", {255, constraints::UNIQUE}, null_option::NOT_NULL),
|
||||||
make_column<unsigned short>("age"),
|
make_column<unsigned short>("age"),
|
||||||
make_fk_column<uint32_t>("address", "address", "id")
|
make_fk_column<uint32_t>("address", "address", "id")
|
||||||
}).compile(*db);
|
}).compile(*db);
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,15 @@ TEST_CASE("Test create empty column", "[column]") {
|
||||||
REQUIRE(c.type() == basic_type::type_null);
|
REQUIRE(c.type() == basic_type::type_null);
|
||||||
REQUIRE(!c.reference_column());
|
REQUIRE(!c.reference_column());
|
||||||
|
|
||||||
c.change_type<std::string>(255);
|
c.set(std::string{"george"}, 255);
|
||||||
REQUIRE(c.type() == basic_type::type_varchar);
|
REQUIRE(c.type() == basic_type::type_varchar);
|
||||||
|
REQUIRE(c.as<std::string>() == "george");
|
||||||
|
|
||||||
c.change_type<int32_t>(7);
|
c.set(7);
|
||||||
REQUIRE(c.type() == basic_type::type_int32);
|
REQUIRE(c.type() == basic_type::type_int32);
|
||||||
|
REQUIRE(c.as<std::string>() == "7");
|
||||||
|
REQUIRE(c.as<int>() == 7);
|
||||||
|
REQUIRE(c.str() == "7");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Test copy and move column", "[column]") {
|
TEST_CASE("Test copy and move column", "[column]") {
|
||||||
|
|
@ -26,15 +30,17 @@ TEST_CASE("Test copy and move column", "[column]") {
|
||||||
basic_type::type_varchar,
|
basic_type::type_varchar,
|
||||||
2,
|
2,
|
||||||
std::make_shared<attribute_definition>("author", "books", basic_type::type_uint32, constraints::FOREIGN_KEY),
|
std::make_shared<attribute_definition>("author", "books", basic_type::type_uint32, constraints::FOREIGN_KEY),
|
||||||
{255, constraints::FOREIGN_KEY},
|
constraints::FOREIGN_KEY,
|
||||||
null_option_type::NOT_NULL
|
null_option::NOT_NULL
|
||||||
);
|
);
|
||||||
|
c.set(std::string{"george"}, 255);
|
||||||
REQUIRE(c.name() == "name");
|
REQUIRE(c.name() == "name");
|
||||||
REQUIRE(c.index() == 2);
|
REQUIRE(c.index() == 2);
|
||||||
REQUIRE(c.reference_column());
|
REQUIRE(c.reference_column());
|
||||||
REQUIRE(c.reference_column()->name() == "author");
|
REQUIRE(c.reference_column()->name() == "author");
|
||||||
REQUIRE(c.reference_column()->table_name() == "books");
|
REQUIRE(c.reference_column()->table_name() == "books");
|
||||||
REQUIRE(c.type() == basic_type::type_varchar);
|
REQUIRE(c.type() == basic_type::type_varchar);
|
||||||
|
REQUIRE(c.as<std::string>() == "george");
|
||||||
REQUIRE(c.attributes().size() == 255);
|
REQUIRE(c.attributes().size() == 255);
|
||||||
|
|
||||||
auto c2 = c;
|
auto c2 = c;
|
||||||
|
|
@ -44,6 +50,7 @@ TEST_CASE("Test copy and move column", "[column]") {
|
||||||
REQUIRE(c2.reference_column()->name() == "author");
|
REQUIRE(c2.reference_column()->name() == "author");
|
||||||
REQUIRE(c2.reference_column()->table_name() == "books");
|
REQUIRE(c2.reference_column()->table_name() == "books");
|
||||||
REQUIRE(c2.type() == basic_type::type_varchar);
|
REQUIRE(c2.type() == basic_type::type_varchar);
|
||||||
|
REQUIRE(c2.as<std::string>() == "george");
|
||||||
REQUIRE(c2.attributes().size() == 255);
|
REQUIRE(c2.attributes().size() == 255);
|
||||||
|
|
||||||
auto c3 = std::move(c2);
|
auto c3 = std::move(c2);
|
||||||
|
|
@ -53,10 +60,13 @@ TEST_CASE("Test copy and move column", "[column]") {
|
||||||
REQUIRE(c3.reference_column()->name() == "author");
|
REQUIRE(c3.reference_column()->name() == "author");
|
||||||
REQUIRE(c3.reference_column()->table_name() == "books");
|
REQUIRE(c3.reference_column()->table_name() == "books");
|
||||||
REQUIRE(c3.type() == basic_type::type_varchar);
|
REQUIRE(c3.type() == basic_type::type_varchar);
|
||||||
|
REQUIRE(c3.as<std::string>() == "george");
|
||||||
REQUIRE(c3.attributes().size() == 255);
|
REQUIRE(c3.attributes().size() == 255);
|
||||||
|
|
||||||
REQUIRE(c2.name().empty());
|
REQUIRE(c2.name().empty());
|
||||||
REQUIRE(c2.index() == 2);
|
REQUIRE(c2.index() == 2);
|
||||||
REQUIRE(!c2.reference_column());
|
REQUIRE(!c2.reference_column());
|
||||||
|
REQUIRE(c2.type() == basic_type::type_null);
|
||||||
|
// REQUIRE(!c2.as<std::string>().has_value());
|
||||||
REQUIRE(c2.attributes().size() == 255);
|
REQUIRE(c2.attributes().size() == 255);
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue