query builder progress
This commit is contained in:
parent
c156ab5e74
commit
bfbbd4c589
|
|
@ -240,9 +240,9 @@ utils::result<std::vector<object::attribute>, utils::error> postgres_connection:
|
|||
// Todo: extract size
|
||||
auto type = (string2type(reader.column(2)));
|
||||
end = nullptr;
|
||||
object::null_option_type null_opt{object::null_option_type::NULLABLE};
|
||||
object::null_option_type null_opt{object::null_option_type::Nullable};
|
||||
if (strtoul(reader.column(4), &end, 10) == 0) {
|
||||
null_opt = object::null_option_type::NOT_NULL;
|
||||
null_opt = object::null_option_type::NotNull;
|
||||
}
|
||||
// f.default_value(res->column(4));
|
||||
prototype.emplace_back(name, type, utils::null_attributes, null_opt, index);
|
||||
|
|
|
|||
|
|
@ -10,14 +10,9 @@
|
|||
namespace matador::object {
|
||||
|
||||
enum class null_option_type : uint8_t {
|
||||
NULLABLE, NOT_NULL
|
||||
Nullable, NotNull
|
||||
};
|
||||
|
||||
struct attribute_options {
|
||||
utils::field_attributes attributes;
|
||||
null_option_type null_option{null_option_type::NOT_NULL};
|
||||
int index{-1};
|
||||
};
|
||||
class object;
|
||||
class attribute_generator;
|
||||
|
||||
|
|
@ -33,20 +28,17 @@ public:
|
|||
attribute() = default;
|
||||
attribute(std::string name,
|
||||
utils::basic_type type,
|
||||
const utils::field_attributes&,
|
||||
null_option_type null_opt);
|
||||
const utils::field_attributes &attr = utils::null_attributes,
|
||||
null_option_type null_opt = null_option_type::NotNull);
|
||||
|
||||
[[nodiscard]] const std::string& name() const;
|
||||
void name(const std::string& n);
|
||||
[[nodiscard]] std::string full_name() const;
|
||||
[[nodiscard]] int index() const;
|
||||
[[nodiscard]] const utils::field_attributes& attributes() const;
|
||||
[[nodiscard]] utils::field_attributes& attributes();
|
||||
[[nodiscard]] bool is_nullable() const;
|
||||
[[nodiscard]] utils::basic_type type() const;
|
||||
[[nodiscard]] object* owner() const;
|
||||
// [[nodiscard]] const std::string& table_name() const;
|
||||
// void table_name(const std::string& name);
|
||||
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) {
|
||||
|
|
@ -75,8 +67,9 @@ private:
|
|||
|
||||
std::string name_;
|
||||
object *owner_{nullptr};
|
||||
attribute_options options_;
|
||||
utils::basic_type type_{utils::basic_type::type_null};
|
||||
utils::field_attributes options_{};
|
||||
null_option_type null_option_{null_option_type::NotNull};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ public:
|
|||
template<class Type>
|
||||
attribute generate(const char *id, Type &x) {
|
||||
access::process(*this, x);
|
||||
return attribute{id, type_, {utils::constraints::ForeignKey }, null_option_type::NOT_NULL};
|
||||
return attribute{id, type_, {utils::constraints::ForeignKey }, null_option_type::NotNull};
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
|
|
@ -139,18 +139,18 @@ private:
|
|||
|
||||
template<typename ValueType>
|
||||
void attribute_generator::on_primary_key(const char *id, ValueType &x, const utils::primary_key_attribute& attr) {
|
||||
auto &ref = emplace_attribute<ValueType>(id, { attr.size(), utils::constraints::PrimaryKey }, null_option_type::NOT_NULL);
|
||||
auto &ref = emplace_attribute<ValueType>(id, { attr.size(), utils::constraints::PrimaryKey }, null_option_type::NotNull);
|
||||
prepare_primary_key(ref, utils::identifier(x));
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
void attribute_generator::on_attribute(const char *id, Type &/*x*/, const utils::field_attributes &attr) {
|
||||
std::ignore = emplace_attribute<Type>(id, attr, null_option_type::NOT_NULL);
|
||||
std::ignore = emplace_attribute<Type>(id, attr, null_option_type::NotNull);
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
void attribute_generator::on_attribute(const char *id, std::optional<Type> & /*x*/, const utils::field_attributes &attr) {
|
||||
std::ignore = emplace_attribute<Type>(id, attr, null_option_type::NULLABLE);
|
||||
std::ignore = emplace_attribute<Type>(id, attr, null_option_type::Nullable);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#define BASIC_PROTOTYPE_INFO_HPP
|
||||
|
||||
#include "matador/object/attribute.hpp"
|
||||
#include "matador/object/constraint.hpp"
|
||||
#include "matador/object/relation_endpoint.hpp"
|
||||
|
||||
#include "matador/utils/identifier.hpp"
|
||||
|
|
@ -26,6 +27,7 @@ public:
|
|||
[[nodiscard]] std::type_index type_index() const;
|
||||
[[nodiscard]] std::string name() const;
|
||||
[[nodiscard]] const std::list<attribute>& attributes() const;
|
||||
[[nodiscard]] const std::list<class constraint>& constraints() const;
|
||||
|
||||
[[nodiscard]] bool has_primary_key() const;
|
||||
[[nodiscard]] const utils::identifier& primary_key() const;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "matador/utils/constraints.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
namespace matador::object {
|
||||
|
||||
|
|
@ -18,6 +19,14 @@ public:
|
|||
explicit constraint(std::string name);
|
||||
|
||||
[[nodiscard]] const std::string& name() const;
|
||||
[[nodiscard]] const class attribute* attribute() const;
|
||||
[[nodiscard]] std::string column_name() const;
|
||||
[[nodiscard]] const object* owner() const;
|
||||
[[nodiscard]] bool is_primary_key_constraint() const;
|
||||
[[nodiscard]] bool is_foreign_key_constraint() const;
|
||||
[[nodiscard]] bool is_unique_constraint() const;
|
||||
[[nodiscard]] const std::string& ref_table_name() const;
|
||||
[[nodiscard]] const std::string& ref_column_name() const;
|
||||
|
||||
private:
|
||||
friend class constraint_builder;
|
||||
|
|
@ -26,7 +35,8 @@ private:
|
|||
friend class object;
|
||||
|
||||
std::string name_;
|
||||
attribute* attr_{nullptr};
|
||||
std::variant<class attribute*, std::string> attr_;
|
||||
// class attribute* attr_{nullptr};
|
||||
object *owner_{nullptr};
|
||||
utils::constraints options_{utils::constraints::None};
|
||||
std::string ref_table_name_{};
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ public:
|
|||
template <class Pointer>
|
||||
void on_foreign_key(const char *id, Pointer &/*x*/) {
|
||||
const auto type = pk_type_determinator::determine<typename Pointer::value_type>();
|
||||
auto &ref = object_->attributes_.emplace_back(id, type, utils::constraints::ForeignKey, null_option_type::NOT_NULL);
|
||||
auto &ref = object_->attributes_.emplace_back(id, type, utils::constraints::ForeignKey, null_option_type::NotNull);
|
||||
ref.owner_ = object_.get();
|
||||
}
|
||||
template<class ContainerType>
|
||||
|
|
@ -121,19 +121,19 @@ private:
|
|||
|
||||
template<typename ValueType>
|
||||
void object_generator::on_primary_key(const char *id, ValueType &x, const utils::primary_key_attribute& attr) {
|
||||
auto &ref = emplace_attribute<ValueType>(id, { attr.size(), utils::constraints::PrimaryKey }, null_option_type::NOT_NULL);
|
||||
auto &ref = emplace_attribute<ValueType>(id, { attr.size(), utils::constraints::PrimaryKey }, null_option_type::NotNull);
|
||||
prepare_primary_key(ref, utils::identifier(x));
|
||||
create_pk_constraint(id);
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
void object_generator::on_attribute(const char *id, Type &/*x*/, const utils::field_attributes &attr) {
|
||||
std::ignore = emplace_attribute<Type>(id, attr, null_option_type::NOT_NULL);
|
||||
std::ignore = emplace_attribute<Type>(id, attr, null_option_type::NotNull);
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
void object_generator::on_attribute(const char *id, std::optional<Type> & /*x*/, const utils::field_attributes &attr) {
|
||||
std::ignore = emplace_attribute<Type>(id, attr, null_option_type::NULLABLE);
|
||||
std::ignore = emplace_attribute<Type>(id, attr, null_option_type::Nullable);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -272,7 +272,7 @@ void session_query_builder::on_foreign_object(const char *id, Pointer &, const u
|
|||
|
||||
append_join(
|
||||
query::column{table_info_stack_.top().table, id},
|
||||
query::column{next->second, info->get().reference_column()->name()}
|
||||
query::column{next->second, info->get().primary_key_attribute()->name()}
|
||||
);
|
||||
} else {
|
||||
push(id);
|
||||
|
|
@ -281,7 +281,7 @@ void session_query_builder::on_foreign_object(const char *id, Pointer &, const u
|
|||
// create select query
|
||||
auto result = matador::query::query::select(generator::columns<typename Pointer::value_type>(schema_, generator::column_generator_options::ForceLazy))
|
||||
.from(*foreign_table)
|
||||
.where(column(foreign_table, info->get().reference_column()->name(), "") == _)
|
||||
.where(column(foreign_table, info->get().primary_key_attribute()->name(), "") == _)
|
||||
.prepare(executor_);
|
||||
if (!result) {
|
||||
throw query_builder_exception(query_build_error::QueryError, result.release_error());
|
||||
|
|
|
|||
|
|
@ -26,10 +26,8 @@ private:
|
|||
|
||||
class data_type {
|
||||
public:
|
||||
template<typename Type>
|
||||
data_type() : type_(utils::data_type_traits<Type>()) {}
|
||||
template<typename Type>
|
||||
explicit data_type(const size_t size) : type_(utils::data_type_traits<Type>()), size_(size) {}
|
||||
explicit data_type(const utils::basic_type type, const size_t size = 0)
|
||||
: type_(type), size_(size) {}
|
||||
|
||||
[[nodiscard]] const utils::basic_type& type() const { return type_; }
|
||||
[[nodiscard]] size_t size() const { return size_; }
|
||||
|
|
@ -39,10 +37,28 @@ private:
|
|||
size_t size_{0};
|
||||
};
|
||||
|
||||
// using BigInt = data_type<int64_t>();
|
||||
// using Real = data_type<float>;
|
||||
// using double_ = data_type<double>;
|
||||
// using string = data_type<std::string>;
|
||||
template<typename Type>
|
||||
class typed_data_type final : public data_type {
|
||||
public:
|
||||
typed_data_type()
|
||||
: data_type(utils::data_type_traits<Type>::type()) {}
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
class sized_typed_data_type final : public data_type {
|
||||
public:
|
||||
explicit sized_typed_data_type(size_t size)
|
||||
: data_type(utils::data_type_traits<Type>::type(size), size) {}
|
||||
};
|
||||
|
||||
using BigInt = typed_data_type<int64_t>;
|
||||
using Integer = typed_data_type<int64_t>;
|
||||
using Real = typed_data_type<float>;
|
||||
using Double_ = typed_data_type<double>;
|
||||
using String = typed_data_type<std::string>;
|
||||
using Boolean = typed_data_type<bool>;
|
||||
using Varchar = sized_typed_data_type<std::string>;
|
||||
|
||||
|
||||
class constraint {
|
||||
public:
|
||||
|
|
@ -50,7 +66,7 @@ public:
|
|||
: name_(std::move(name)) {}
|
||||
|
||||
[[nodiscard]] const std::string& name() const;
|
||||
[[nodiscard]] const std::string& column_name() const;
|
||||
[[nodiscard]] std::string column_name() const;
|
||||
[[nodiscard]] const utils::constraints& type() const;
|
||||
[[nodiscard]] bool is_primary_key_constraint() const;
|
||||
[[nodiscard]] bool is_foreign_key_constraint() const;
|
||||
|
|
@ -64,6 +80,7 @@ private:
|
|||
utils::constraints type_{};
|
||||
std::string referenced_table_;
|
||||
std::string referenced_column_;
|
||||
data_type dt = Varchar{255};
|
||||
};
|
||||
}
|
||||
namespace matador::query {
|
||||
|
|
|
|||
|
|
@ -5,16 +5,32 @@
|
|||
|
||||
#include "matador/query/intermediates/executable_query.hpp"
|
||||
|
||||
#include "matador/object/attribute_generator.hpp"
|
||||
#include "matador/object/attribute.hpp"
|
||||
#include "matador/object/constraint.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_create_table_columns_intermediate : public executable_query {
|
||||
public:
|
||||
using executable_query::executable_query;
|
||||
|
||||
executable_query constraints(std::initializer_list<class object::constraint> constraints);
|
||||
executable_query constraints(const std::list<class object::constraint> &constraints);
|
||||
};
|
||||
|
||||
class query_create_table_intermediate : public query_intermediate {
|
||||
public:
|
||||
using query_intermediate::query_intermediate;
|
||||
|
||||
query_create_table_columns_intermediate columns(std::initializer_list<object::attribute> columns);
|
||||
query_create_table_columns_intermediate columns(const std::list<object::attribute> &columns);
|
||||
};
|
||||
|
||||
class query_create_intermediate : public query_intermediate {
|
||||
public:
|
||||
query_create_intermediate();
|
||||
|
||||
executable_query table(const table &tab, std::initializer_list<object::attribute> columns);
|
||||
executable_query table(const query::table &tab, const std::vector<object::attribute> &columns);
|
||||
query_create_table_intermediate table(const table &tab);
|
||||
executable_query schema(const std::string &schema_name);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "matador/query/table.hpp"
|
||||
|
||||
#include "matador/object/attribute.hpp"
|
||||
#include "matador/object/constraint.hpp"
|
||||
|
||||
#include "matador/utils/placeholder.hpp"
|
||||
|
||||
|
|
@ -364,17 +365,41 @@ private:
|
|||
class query_create_table_part final : public query_part
|
||||
{
|
||||
public:
|
||||
query_create_table_part(class table tab, std::vector<object::attribute> columns);
|
||||
explicit query_create_table_part(class table tab);
|
||||
|
||||
[[nodiscard]] const class table& table() const;
|
||||
[[nodiscard]] const std::vector<object::attribute>& columns() const;
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
class table table_;
|
||||
std::vector<object::attribute> columns_;
|
||||
};
|
||||
|
||||
class query_create_table_columns_part final : public query_part {
|
||||
public:
|
||||
explicit query_create_table_columns_part(const std::list<object::attribute> &columns);
|
||||
|
||||
[[nodiscard]] const std::list<object::attribute>& columns() const;
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
std::list<object::attribute> columns_;
|
||||
};
|
||||
|
||||
class query_create_table_constraints_part final : public query_part {
|
||||
public:
|
||||
explicit query_create_table_constraints_part(const std::list<class object::constraint> &constraints);
|
||||
|
||||
[[nodiscard]] const std::list<class object::constraint>& constraints() const;
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
std::list<class object::constraint> constraints_;
|
||||
};
|
||||
|
||||
class query_create_schema_part final : public query_part {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "matador/utils/placeholder.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
|
||||
namespace matador::sql {
|
||||
|
|
@ -64,6 +65,8 @@ protected:
|
|||
|
||||
void visit(internal::query_create_part &part) override;
|
||||
void visit(internal::query_create_table_part &part) override;
|
||||
void visit(internal::query_create_table_columns_part& part) override;
|
||||
void visit(internal::query_create_table_constraints_part& part) override;
|
||||
void visit(internal::query_create_schema_part& part) override;
|
||||
|
||||
void visit(internal::query_drop_part &part) override;
|
||||
|
|
@ -79,6 +82,8 @@ protected:
|
|||
size_t table_index{0};
|
||||
const sql::dialect *dialect_{nullptr};
|
||||
std::optional<std::reference_wrapper<const sql::connection_impl>> connection_{};
|
||||
|
||||
std::function<void(sql::query_context&)> finisher_ = [](sql::query_context&) {};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ class query_delete_part;
|
|||
class query_delete_from_part;
|
||||
class query_create_part;
|
||||
class query_create_table_part;
|
||||
class query_create_table_columns_part;
|
||||
class query_create_table_constraints_part;
|
||||
class query_create_schema_part;
|
||||
class query_drop_part;
|
||||
class query_drop_table_part;
|
||||
|
|
@ -75,6 +77,8 @@ public:
|
|||
|
||||
virtual void visit(internal::query_create_part &part) = 0;
|
||||
virtual void visit(internal::query_create_table_part &part) = 0;
|
||||
virtual void visit(internal::query_create_table_columns_part &part) = 0;
|
||||
virtual void visit(internal::query_create_table_constraints_part &part) = 0;
|
||||
virtual void visit(internal::query_create_schema_part &part) = 0;
|
||||
|
||||
virtual void visit(internal::query_drop_part &part) = 0;
|
||||
|
|
|
|||
|
|
@ -137,6 +137,7 @@ public:
|
|||
[[nodiscard]] const std::string& column() const;
|
||||
[[nodiscard]] const std::string& columns() const;
|
||||
[[nodiscard]] const std::string& commit() const;
|
||||
[[nodiscard]] const std::string& constraint() const;
|
||||
[[nodiscard]] const std::string& create() const;
|
||||
[[nodiscard]] const std::string& desc() const;
|
||||
[[nodiscard]] const std::string& distinct() const;
|
||||
|
|
@ -201,6 +202,7 @@ private:
|
|||
{dialect_token::Column, "COLUMN"},
|
||||
{dialect_token::Columns, "COLUMNS"},
|
||||
{dialect_token::Commit, "COMMIT TRANSACTION"},
|
||||
{dialect_token::Constraint, "CONSTRAINT"},
|
||||
{dialect_token::Create, "CREATE"},
|
||||
{dialect_token::Desc, "DESC"},
|
||||
{dialect_token::Distinct, "DISTINCT"},
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ enum class dialect_token : uint8_t {
|
|||
Column,
|
||||
Columns,
|
||||
Commit,
|
||||
Constraint,
|
||||
Create,
|
||||
Database,
|
||||
Desc,
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ enum class basic_type : uint8_t {
|
|||
type_date, /*!< Data type date */
|
||||
type_time, /*!< Data type time */
|
||||
type_blob, /*!< Data type blob */
|
||||
type_null /*!< Data type null */
|
||||
type_null, /*!< Data type null */
|
||||
type_unknown /*!< Data type unknown */
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,11 @@ class attribute_writer;
|
|||
* for a data type
|
||||
*/
|
||||
template < class Type, class Enable = void >
|
||||
struct data_type_traits;
|
||||
struct data_type_traits {
|
||||
static basic_type type(std::size_t /*size*/) { return basic_type::type_unknown; }
|
||||
static void read_value(attribute_reader &/*reader*/, const char *id, size_t index, nullptr_t &/*value*/, size_t /*size*/ = 0) {}
|
||||
static void bind_value(attribute_writer &/*binder*/, size_t index, nullptr_t &/*value*/, size_t /*size*/ = 0) {}
|
||||
};
|
||||
|
||||
}
|
||||
#endif //BASIC_TYPE_TRAITS_HPP
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
namespace matador::object {
|
||||
attribute::attribute(std::string name)
|
||||
: attribute(std::move(name), utils::basic_type::type_null, {}, null_option_type::NOT_NULL) {
|
||||
: attribute(std::move(name), utils::basic_type::type_null, {}, null_option_type::NotNull) {
|
||||
}
|
||||
|
||||
attribute::attribute(std::string name,
|
||||
|
|
@ -14,8 +14,9 @@ attribute::attribute(std::string name,
|
|||
const utils::field_attributes &attr,
|
||||
const null_option_type null_opt)
|
||||
: name_(std::move(name))
|
||||
, options_{attr, null_opt}
|
||||
, type_(type)
|
||||
, options_(attr)
|
||||
, null_option_(null_opt)
|
||||
{}
|
||||
|
||||
const std::string &attribute::name() const {
|
||||
|
|
@ -30,20 +31,16 @@ std::string attribute::full_name() const {
|
|||
return owner_ ? owner_->name() + "." + name_ : name_;
|
||||
}
|
||||
|
||||
int attribute::index() const {
|
||||
return options_.index;
|
||||
}
|
||||
|
||||
const utils::field_attributes &attribute::attributes() const {
|
||||
return options_.attributes;
|
||||
return options_;
|
||||
}
|
||||
|
||||
utils::field_attributes& attribute::attributes() {
|
||||
return options_.attributes;
|
||||
return options_;
|
||||
}
|
||||
|
||||
bool attribute::is_nullable() const {
|
||||
return options_.null_option == null_option_type::NULLABLE;
|
||||
return null_option_ == null_option_type::Nullable;
|
||||
}
|
||||
|
||||
utils::basic_type attribute::type() const {
|
||||
|
|
@ -54,16 +51,8 @@ object* attribute::owner() const {
|
|||
return owner_;
|
||||
}
|
||||
|
||||
// const std::string& attribute::table_name() const {
|
||||
// return owner_ ? owner_->name() : "";
|
||||
// }
|
||||
//
|
||||
// void attribute::table_name( const std::string& name ) {
|
||||
// table_name_ = name;
|
||||
// }
|
||||
|
||||
void attribute::change_type(const utils::basic_type type, const utils::field_attributes& attr) {
|
||||
options_.attributes = attr;
|
||||
options_ = attr;
|
||||
type_ = type;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@ const std::list<attribute>& basic_object_info::attributes() const {
|
|||
return object_->attributes();
|
||||
}
|
||||
|
||||
const std::list<class constraint>& basic_object_info::constraints() const {
|
||||
return object_->constraints();
|
||||
}
|
||||
|
||||
bool basic_object_info::has_primary_key() const {
|
||||
return object_->has_primary_key();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "matador/object/constraint.hpp"
|
||||
#include "matador/object/attribute.hpp"
|
||||
|
||||
namespace matador::object {
|
||||
constraint::constraint(std::string name)
|
||||
|
|
@ -8,6 +9,49 @@ const std::string & constraint::name() const {
|
|||
return name_;
|
||||
}
|
||||
|
||||
const class attribute* constraint::attribute() const {
|
||||
if (std::holds_alternative<class attribute*>(attr_)) {
|
||||
return std::get<class attribute*>(attr_);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string constraint::column_name() const {
|
||||
if (std::holds_alternative<class attribute*>(attr_)) {
|
||||
return std::get<class attribute*>(attr_)->name();
|
||||
}
|
||||
if (std::holds_alternative<std::string>(attr_)) {
|
||||
return std::get<std::string>(attr_);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
const object* constraint::owner() const {
|
||||
return owner_;
|
||||
}
|
||||
|
||||
bool constraint::is_primary_key_constraint() const {
|
||||
return utils::is_constraint_set(options_, utils::constraints::PrimaryKey);
|
||||
}
|
||||
|
||||
bool constraint::is_foreign_key_constraint() const {
|
||||
return utils::is_constraint_set(options_, utils::constraints::ForeignKey);
|
||||
}
|
||||
|
||||
bool constraint::is_unique_constraint() const {
|
||||
return utils::is_constraint_set(options_, utils::constraints::Unique);
|
||||
}
|
||||
|
||||
const std::string& constraint::ref_table_name() const {
|
||||
return ref_table_name_;
|
||||
}
|
||||
|
||||
const std::string& constraint::ref_column_name() const {
|
||||
return ref_column_name_;
|
||||
}
|
||||
|
||||
constraint_builder & constraint_builder::constraint(std::string name) {
|
||||
constraint_name = std::move(name);
|
||||
return *this;
|
||||
|
|
@ -35,10 +79,11 @@ constraint_builder & constraint_builder::references(std::string table, std::stri
|
|||
constraint_builder::operator class constraint() const {
|
||||
class constraint c;
|
||||
c.name_ = constraint_name;
|
||||
c.attr_ = column_name;
|
||||
c.options_ = options_;
|
||||
c.ref_column_name_ = ref_column_name;
|
||||
c.ref_table_name_ = ref_table_name;
|
||||
return {};
|
||||
return c;
|
||||
}
|
||||
|
||||
constraint_builder constraint(std::string name) {
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ attribute* repository_node::determine_reference_column(const std::type_index& ti
|
|||
repository& repo) {
|
||||
const auto it = repo.missing_references_.find(ti);
|
||||
if (it == repo.missing_references_.end()) {
|
||||
return new attribute(pk_info.pk_column_name, pk_info.type, {utils::constraints::ForeignKey}, null_option_type::NOT_NULL);
|
||||
return new attribute(pk_info.pk_column_name, pk_info.type, {utils::constraints::ForeignKey}, null_option_type::NotNull);
|
||||
}
|
||||
|
||||
auto ref_column = it->second;
|
||||
|
|
|
|||
|
|
@ -57,7 +57,9 @@ matador::utils::result<void, matador::utils::error> matador::orm::schema::create
|
|||
// std::cout << result.sql << std::endl;
|
||||
for (const auto &node: repo_) {
|
||||
auto ctx = query::query::create()
|
||||
.table(node->name(), node->info().attributes())
|
||||
.table(node->name())
|
||||
.columns(node->info().attributes())
|
||||
.constraints(node->info().constraints())
|
||||
.compile(*c);
|
||||
|
||||
for ( const auto& [sql, command] : ctx.additional_commands ) {
|
||||
|
|
|
|||
|
|
@ -52,7 +52,9 @@ utils::result<void, utils::error> session::create_schema() const {
|
|||
auto c = cache_.pool().acquire();
|
||||
for (const auto &node: *schema_) {
|
||||
auto ctx = query::query::create()
|
||||
.table(node->name(), node->info().attributes())
|
||||
.table(node->name())
|
||||
.columns(node->info().attributes())
|
||||
.constraints(node->info().constraints())
|
||||
.compile(*c);
|
||||
|
||||
for ( const auto& [sql, command] : ctx.additional_commands ) {
|
||||
|
|
|
|||
|
|
@ -9,13 +9,14 @@ namespace matador::query {
|
|||
namespace detail {
|
||||
sql::record *create_prototype(const std::vector<object::attribute> &prototype) {
|
||||
auto result = std::make_unique<sql::record>();
|
||||
int index{0};
|
||||
for (const auto &col: prototype) {
|
||||
result->append({
|
||||
col.name(),
|
||||
col.type(),
|
||||
col.attributes().options(),
|
||||
col.attributes().size(),
|
||||
col.index()
|
||||
index++
|
||||
});
|
||||
}
|
||||
return result.release();
|
||||
|
|
|
|||
|
|
@ -8,12 +8,8 @@ query_create_intermediate::query_create_intermediate() {
|
|||
context_->parts.push_back(std::make_unique<internal::query_create_part>());
|
||||
}
|
||||
|
||||
executable_query query_create_intermediate::table(const class table &tab, const std::initializer_list<object::attribute> columns) {
|
||||
return this->table(tab, std::vector<object::attribute>{columns});
|
||||
}
|
||||
|
||||
executable_query query_create_intermediate::table(const class table &tab, const std::vector<object::attribute> &columns) {
|
||||
context_->parts.push_back(std::make_unique<internal::query_create_table_part>(tab, columns));
|
||||
query_create_table_intermediate query_create_intermediate::table(const class table &tab) {
|
||||
context_->parts.push_back(std::make_unique<internal::query_create_table_part>(tab));
|
||||
return {context_};
|
||||
}
|
||||
|
||||
|
|
@ -21,4 +17,24 @@ executable_query query_create_intermediate::schema( const std::string& schema_na
|
|||
context_->parts.push_back(std::make_unique<internal::query_create_schema_part>(schema_name));
|
||||
return {context_};
|
||||
}
|
||||
|
||||
executable_query query_create_table_columns_intermediate::constraints( std::initializer_list<class object::constraint> constraints ) {
|
||||
return this->constraints(std::list(constraints));
|
||||
}
|
||||
|
||||
executable_query query_create_table_columns_intermediate::constraints( const std::list<class object::constraint>& constraints ) {
|
||||
|
||||
context_->parts.push_back(std::make_unique<internal::query_create_table_constraints_part>(constraints));
|
||||
return {context_};
|
||||
}
|
||||
|
||||
query_create_table_columns_intermediate query_create_table_intermediate::columns( std::initializer_list<object::attribute> columns ) {
|
||||
context_->parts.push_back(std::make_unique<internal::query_create_table_columns_part>(columns));
|
||||
return {context_};
|
||||
}
|
||||
|
||||
query_create_table_columns_intermediate query_create_table_intermediate::columns( const std::list<object::attribute>& columns ) {
|
||||
context_->parts.push_back(std::make_unique<internal::query_create_table_columns_part>(columns));
|
||||
return {context_};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -344,23 +344,41 @@ void query_create_part::accept(query_part_visitor &visitor)
|
|||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
query_create_table_part::query_create_table_part(class table tab, std::vector<object::attribute> columns)
|
||||
query_create_table_part::query_create_table_part(class table tab)
|
||||
: query_part(sql::dialect_token::Table)
|
||||
, table_(std::move(tab))
|
||||
, columns_(std::move(columns)) {}
|
||||
, table_(std::move(tab)) {}
|
||||
|
||||
const table &query_create_table_part::table() const
|
||||
{
|
||||
return table_;
|
||||
}
|
||||
|
||||
const std::vector<object::attribute> &query_create_table_part::columns() const
|
||||
void query_create_table_part::accept(query_part_visitor &visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
query_create_table_columns_part::query_create_table_columns_part(const std::list<object::attribute>& columns)
|
||||
: query_part( sql::dialect_token::Columns )
|
||||
, columns_(columns){}
|
||||
|
||||
const std::list<object::attribute>& query_create_table_columns_part::columns() const {
|
||||
return columns_;
|
||||
}
|
||||
|
||||
void query_create_table_part::accept(query_part_visitor &visitor)
|
||||
{
|
||||
void query_create_table_columns_part::accept(query_part_visitor& visitor) {
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
query_create_table_constraints_part::query_create_table_constraints_part(const std::list<class object::constraint>& constraints)
|
||||
: query_part( sql::dialect_token::Constraint )
|
||||
, constraints_(constraints) {}
|
||||
|
||||
const std::list<class object::constraint>& query_create_table_constraints_part::constraints() const {
|
||||
return constraints_;
|
||||
}
|
||||
|
||||
void query_create_table_constraints_part::accept( query_part_visitor& visitor ) {
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ sql::query_context query_compiler::compile(const query_data &data,
|
|||
for (const auto &part: data.parts) {
|
||||
part->accept(*this);
|
||||
}
|
||||
finisher_(query_);
|
||||
connection_ = std::nullopt;
|
||||
dialect_ = nullptr;
|
||||
data_ = nullptr;
|
||||
|
|
@ -289,55 +290,55 @@ void query_compiler::visit(internal::query_create_part &/*create_part*/)
|
|||
query_.sql = dialect_->token_at(sql::dialect_token::Create);
|
||||
}
|
||||
|
||||
struct fk_context {
|
||||
std::string column;
|
||||
std::shared_ptr<object::attribute> reference_column;
|
||||
};
|
||||
|
||||
struct column_context
|
||||
{
|
||||
std::vector<std::string> primary_keys;
|
||||
std::vector<fk_context> foreign_contexts;
|
||||
};
|
||||
|
||||
std::string build_create_column(const object::attribute &col, const sql::dialect &d, column_context &context);
|
||||
std::string build_create_column(const object::attribute &col, const sql::dialect &d);
|
||||
std::string build_constraint(const class object::constraint &cons, const sql::dialect &d);
|
||||
|
||||
void query_compiler::visit(internal::query_create_table_part &part)
|
||||
{
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Table) + " " + dialect_->prepare_identifier_string(part.table().name()) + " ";
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Table) + " " + dialect_->prepare_identifier_string(part.table().name()) + " (";
|
||||
query_.table_name = part.table().name();
|
||||
|
||||
std::string result = "(";
|
||||
// if (!context.primary_keys.empty()) {
|
||||
// result.append(", CONSTRAINT PK_" + part.table().name() + " PRIMARY KEY (" + utils::join(context.primary_keys, ", ") + ")");
|
||||
// }
|
||||
// for (const auto &[column, reference_column]: context.foreign_contexts) {
|
||||
// // ALTER TABLE Orders ADD CONSTRAINT FK_PersonOrder FOREIGN KEY (PersonID) REFERENCES Persons(PersonID);
|
||||
// std::string fk_cmd = "ALTER TABLE " + dialect_->prepare_identifier_string(query_.table_name) + " ADD";
|
||||
// fk_cmd += " CONSTRAINT FK_" + query_.table_name;
|
||||
// fk_cmd += "_" + column;
|
||||
// fk_cmd += " FOREIGN KEY (" + dialect_->prepare_identifier_string(column) + ")";
|
||||
// fk_cmd += " REFERENCES " + reference_column->table_name() + "(" + reference_column->name() + ")";
|
||||
// query_.additional_commands.push_back({fk_cmd, sql::sql_command::SQL_ALTER_TABLE});
|
||||
// }
|
||||
|
||||
column_context context;
|
||||
finisher_ = [](sql::query_context &ctx) { ctx.sql += ")"; };
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_create_table_columns_part& part) {
|
||||
std::string result = "(";
|
||||
|
||||
if (part.columns().size() < 2) {
|
||||
for (const auto &col: part.columns()) {
|
||||
result.append(build_create_column(col, *dialect_, context));
|
||||
result.append(build_create_column(col, *dialect_));
|
||||
}
|
||||
} else {
|
||||
auto it = part.columns().begin();
|
||||
result.append(build_create_column(*it++, *dialect_, context));
|
||||
result.append(build_create_column(*it++, *dialect_));
|
||||
for (; it != part.columns().end(); ++it) {
|
||||
result.append(", ");
|
||||
result.append(build_create_column(*it, *dialect_, context));
|
||||
result.append(build_create_column(*it, *dialect_));
|
||||
}
|
||||
}
|
||||
|
||||
if (!context.primary_keys.empty()) {
|
||||
result.append(", CONSTRAINT PK_" + part.table().name() + " PRIMARY KEY (" + utils::join(context.primary_keys, ", ") + ")");
|
||||
}
|
||||
for (const auto &[column, reference_column]: context.foreign_contexts) {
|
||||
// ALTER TABLE Orders ADD CONSTRAINT FK_PersonOrder FOREIGN KEY (PersonID) REFERENCES Persons(PersonID);
|
||||
std::string fk_cmd = "ALTER TABLE " + dialect_->prepare_identifier_string(query_.table_name) + " ADD";
|
||||
fk_cmd += " CONSTRAINT FK_" + query_.table_name;
|
||||
fk_cmd += "_" + column;
|
||||
fk_cmd += " FOREIGN KEY (" + dialect_->prepare_identifier_string(column) + ")";
|
||||
fk_cmd += " REFERENCES " + reference_column->table_name() + "(" + reference_column->name() + ")";
|
||||
query_.additional_commands.push_back({fk_cmd, sql::sql_command::SQL_ALTER_TABLE});
|
||||
query_.sql += result;
|
||||
}
|
||||
|
||||
result += ")";
|
||||
void query_compiler::visit(internal::query_create_table_constraints_part& part) {
|
||||
std::string result;
|
||||
for (const auto& c : part.constraints()) {
|
||||
result.append(", ");
|
||||
result.append(build_constraint(c, *dialect_));
|
||||
}
|
||||
query_.sql += result;
|
||||
}
|
||||
|
||||
|
|
@ -387,7 +388,7 @@ void query_compiler::visit(internal::query_drop_table_part &part)
|
|||
query_.sql += " " + build_table_name(part.token(), *dialect_, query_.table_name);
|
||||
}
|
||||
|
||||
std::string build_create_column(const object::attribute &col, const sql::dialect &d, column_context &context)
|
||||
std::string build_create_column(const object::attribute &col, const sql::dialect &d)
|
||||
{
|
||||
std::string result = d.prepare_identifier_string(col.name()) + " " + d.data_type_at(col.type());
|
||||
if (col.attributes().size() > 0) {
|
||||
|
|
@ -399,13 +400,23 @@ std::string build_create_column(const object::attribute &col, const sql::dialect
|
|||
if (is_constraint_set(col.attributes().options(), utils::constraints::Unique)) {
|
||||
result.append(" UNIQUE");
|
||||
}
|
||||
if (is_constraint_set(col.attributes().options(), utils::constraints::PrimaryKey)) {
|
||||
context.primary_keys.emplace_back(col.name());
|
||||
}
|
||||
if (is_constraint_set(col.attributes().options(), utils::constraints::ForeignKey)) {
|
||||
context.foreign_contexts.push_back({col.name(), col.reference_column()});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string build_constraint(const class object::constraint& cons, const sql::dialect& d) {
|
||||
std::string result;
|
||||
if (!cons.name().empty()) {
|
||||
result.append(d.constraint()).append(" ").append(d.prepare_identifier_string(cons.name())).append(" ");
|
||||
}
|
||||
if (cons.is_primary_key_constraint()) {
|
||||
result.append(d.primary_key());
|
||||
} else if (cons.is_foreign_key_constraint()) {
|
||||
result.append(d.foreign_key());
|
||||
} else {
|
||||
// handle error
|
||||
}
|
||||
result.append("(").append(cons.attribute()->full_name()).append(")");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -172,6 +172,10 @@ const std::string& dialect::commit() const {
|
|||
return token_at(dialect_token::Commit);
|
||||
}
|
||||
|
||||
const std::string& dialect::constraint() const {
|
||||
return token_at(dialect_token::Constraint);
|
||||
}
|
||||
|
||||
const std::string& dialect::create() const {
|
||||
return token_at(dialect_token::Create);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,13 +8,14 @@ namespace matador::sql::detail {
|
|||
template<>
|
||||
record *create_prototype<record>(const std::vector<object::attribute> &prototype) {
|
||||
auto result = std::make_unique<record>();
|
||||
int index{0};
|
||||
for (const auto &col: prototype) {
|
||||
result->append({
|
||||
col.name(),
|
||||
col.type(),
|
||||
col.attributes().options(),
|
||||
col.attributes().size(),
|
||||
col.index()
|
||||
index++
|
||||
});
|
||||
}
|
||||
return result.release();
|
||||
|
|
|
|||
|
|
@ -22,15 +22,15 @@ TEST_CASE("Generate column definitions from object", "[column][definition][gener
|
|||
auto columns = attribute_generator::generate<matador::test::product>(repo, obj);
|
||||
|
||||
const std::vector expected_columns = {
|
||||
attribute{"product_name", basic_type::type_varchar, constraints::PrimaryKey, null_option_type::NOT_NULL },
|
||||
attribute{"supplier_id", basic_type::type_uint32, constraints::ForeignKey, null_option_type::NOT_NULL },
|
||||
attribute{"category_id", basic_type::type_uint32, constraints::ForeignKey, null_option_type::NOT_NULL },
|
||||
attribute{"quantity_per_unit", basic_type::type_varchar, null_attributes, null_option_type::NOT_NULL },
|
||||
attribute{"unit_price", basic_type::type_uint32, null_attributes, null_option_type::NOT_NULL },
|
||||
attribute{"units_in_stock", basic_type::type_uint32, null_attributes, null_option_type::NOT_NULL },
|
||||
attribute{"units_in_order", basic_type::type_uint32, null_attributes, null_option_type::NOT_NULL },
|
||||
attribute{"reorder_level", basic_type::type_uint32, null_attributes, null_option_type::NOT_NULL },
|
||||
attribute{"discontinued", basic_type::type_bool, null_attributes, null_option_type::NOT_NULL }
|
||||
attribute{"product_name", basic_type::type_varchar, constraints::PrimaryKey, null_option_type::NotNull },
|
||||
attribute{"supplier_id", basic_type::type_uint32, constraints::ForeignKey, null_option_type::NotNull },
|
||||
attribute{"category_id", basic_type::type_uint32, constraints::ForeignKey, null_option_type::NotNull },
|
||||
attribute{"quantity_per_unit", basic_type::type_varchar, null_attributes, null_option_type::NotNull },
|
||||
attribute{"unit_price", basic_type::type_uint32, null_attributes, null_option_type::NotNull },
|
||||
attribute{"units_in_stock", basic_type::type_uint32, null_attributes, null_option_type::NotNull },
|
||||
attribute{"units_in_order", basic_type::type_uint32, null_attributes, null_option_type::NotNull },
|
||||
attribute{"reorder_level", basic_type::type_uint32, null_attributes, null_option_type::NotNull },
|
||||
attribute{"discontinued", basic_type::type_bool, null_attributes, null_option_type::NotNull }
|
||||
};
|
||||
REQUIRE(!columns.empty());
|
||||
REQUIRE(columns.size() == expected_columns.size());
|
||||
|
|
@ -49,9 +49,9 @@ TEST_CASE("Generate columns from object with nullable columns", "[column generat
|
|||
auto columns = attribute_generator::generate<matador::test::optional>(repo, obj);
|
||||
|
||||
const std::vector expected_columns = {
|
||||
attribute{"id", basic_type::type_uint32, constraints::PrimaryKey, null_option_type::NOT_NULL },
|
||||
attribute{"name", basic_type::type_varchar, null_attributes, null_option_type::NOT_NULL },
|
||||
attribute{"age", basic_type::type_uint32, null_attributes, null_option_type::NOT_NULL }
|
||||
attribute{"id", basic_type::type_uint32, constraints::PrimaryKey, null_option_type::NotNull },
|
||||
attribute{"name", basic_type::type_varchar, null_attributes, null_option_type::NotNull },
|
||||
attribute{"age", basic_type::type_uint32, null_attributes, null_option_type::NotNull }
|
||||
};
|
||||
REQUIRE(!columns.empty());
|
||||
REQUIRE(columns.size() == expected_columns.size());
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@
|
|||
#include <matador/query/query.hpp>
|
||||
#include "matador/query/table.hpp"
|
||||
|
||||
#include "matador/object/attribute_generator.hpp"
|
||||
|
||||
#include "matador/sql/connection.hpp"
|
||||
|
||||
#include "matador/utils/placeholder.hpp"
|
||||
|
|
@ -37,21 +35,32 @@ TEST_CASE_METHOD(QueryFixture, "Test alter table sql statement", "[query][alter]
|
|||
|
||||
TEST_CASE_METHOD(QueryFixture, "Test create table sql statement string", "[query]") {
|
||||
auto result = query::create()
|
||||
.table({"person"}, {
|
||||
make_pk_column<uint32_t>("id"),
|
||||
make_column<std::string>("name", 255),
|
||||
make_column<unsigned short>("age")
|
||||
}).str(*db);
|
||||
.table({"person"})
|
||||
.columns({
|
||||
attribute("id", basic_type::type_uint32),
|
||||
attribute("name", basic_type::type_varchar, 255),
|
||||
attribute("age", basic_type::type_uint16)
|
||||
})
|
||||
.constraints({
|
||||
constraint("PK_person").primary_key({"id"})
|
||||
})
|
||||
.str(*db);
|
||||
|
||||
REQUIRE(result == R"##(CREATE TABLE "person" ("id" BIGINT NOT NULL, "name" VARCHAR(255) NOT NULL, "age" INTEGER NOT NULL, CONSTRAINT PK_person PRIMARY KEY (id)))##");
|
||||
|
||||
auto ctx = query::create()
|
||||
.table("person", {
|
||||
make_pk_column<uint32_t>("id"),
|
||||
make_column<std::string>("name", {255, constraints::Unique}, null_option_type::NOT_NULL),
|
||||
make_column<unsigned short>("age"),
|
||||
make_fk_column<uint32_t>("address", "address", "id")
|
||||
}).compile(*db);
|
||||
.table("person")
|
||||
.columns({
|
||||
attribute("id", basic_type::type_uint32),
|
||||
attribute("name", basic_type::type_varchar, 255),
|
||||
attribute("age", basic_type::type_uint16),
|
||||
attribute("address", basic_type::type_uint32)
|
||||
})
|
||||
.constraints({
|
||||
constraint("PK_person").primary_key({"id"}),
|
||||
constraint("FK_person_address").foreign_key({"address"}).references("address", {"id"})
|
||||
})
|
||||
.compile(*db);
|
||||
|
||||
REQUIRE(ctx.sql == R"##(CREATE TABLE "person" ("id" BIGINT NOT NULL, "name" VARCHAR(255) NOT NULL UNIQUE, "age" INTEGER NOT NULL, "address" BIGINT NOT NULL, CONSTRAINT PK_person PRIMARY KEY (id)))##");
|
||||
REQUIRE(ctx.additional_commands.size() == 1);
|
||||
|
|
@ -210,10 +219,14 @@ TEST_CASE_METHOD(QueryFixture, "Test select sql statement string with offset and
|
|||
|
||||
TEST_CASE_METHOD(QueryFixture, "Test create, insert and select a blob column", "[query][blob]") {
|
||||
auto result = query::create()
|
||||
.table("person", {
|
||||
make_pk_column<uint32_t>("id"),
|
||||
make_column<std::string>("name", 255),
|
||||
make_column<blob>("data")
|
||||
.table("person")
|
||||
.columns({
|
||||
attribute("id", basic_type::type_uint32),
|
||||
attribute("name", basic_type::type_varchar, 255),
|
||||
attribute("data", basic_type::type_blob)
|
||||
})
|
||||
.constraints({
|
||||
constraint("PK_person").primary_key({"id"})
|
||||
})
|
||||
.str(*db);
|
||||
|
||||
|
|
|
|||
|
|
@ -9,9 +9,7 @@ TEST_CASE("Test create empty column", "[column]") {
|
|||
attribute c("name");
|
||||
|
||||
REQUIRE(c.name() == "name");
|
||||
REQUIRE(c.index() == -1);
|
||||
REQUIRE(c.type() == basic_type::type_null);
|
||||
REQUIRE(!c.reference_column());
|
||||
|
||||
c.change_type<std::string>(255);
|
||||
REQUIRE(c.type() == basic_type::type_varchar);
|
||||
|
|
@ -24,39 +22,39 @@ TEST_CASE("Test copy and move column", "[column]") {
|
|||
attribute c(
|
||||
"name",
|
||||
basic_type::type_varchar,
|
||||
2,
|
||||
std::make_shared<attribute>("author", basic_type::type_uint32, "books", attribute_options{constraints::ForeignKey}),
|
||||
// 2,
|
||||
// std::make_shared<attribute>("author", basic_type::type_uint32, "books", attribute_options{constraints::ForeignKey}),
|
||||
{255, constraints::ForeignKey},
|
||||
null_option_type::NOT_NULL
|
||||
null_option_type::NotNull
|
||||
);
|
||||
REQUIRE(c.name() == "name");
|
||||
REQUIRE(c.index() == 2);
|
||||
REQUIRE(c.reference_column());
|
||||
REQUIRE(c.reference_column()->name() == "author");
|
||||
REQUIRE(c.reference_column()->table_name() == "books");
|
||||
// REQUIRE(c.index() == 2);
|
||||
// REQUIRE(c.reference_column());
|
||||
// REQUIRE(c.reference_column()->name() == "author");
|
||||
// REQUIRE(c.reference_column()->table_name() == "books");
|
||||
REQUIRE(c.type() == basic_type::type_varchar);
|
||||
REQUIRE(c.attributes().size() == 255);
|
||||
|
||||
auto c2 = c;
|
||||
REQUIRE(c2.name() == "name");
|
||||
REQUIRE(c2.index() == 2);
|
||||
REQUIRE(c2.reference_column());
|
||||
REQUIRE(c2.reference_column()->name() == "author");
|
||||
REQUIRE(c2.reference_column()->table_name() == "books");
|
||||
// REQUIRE(c2.index() == 2);
|
||||
// REQUIRE(c2.reference_column());
|
||||
// REQUIRE(c2.reference_column()->name() == "author");
|
||||
// REQUIRE(c2.reference_column()->table_name() == "books");
|
||||
REQUIRE(c2.type() == basic_type::type_varchar);
|
||||
REQUIRE(c2.attributes().size() == 255);
|
||||
|
||||
auto c3 = std::move(c2);
|
||||
REQUIRE(c3.name() == "name");
|
||||
REQUIRE(c3.index() == 2);
|
||||
REQUIRE(c3.reference_column());
|
||||
REQUIRE(c3.reference_column()->name() == "author");
|
||||
REQUIRE(c3.reference_column()->table_name() == "books");
|
||||
// REQUIRE(c3.index() == 2);
|
||||
// REQUIRE(c3.reference_column());
|
||||
// REQUIRE(c3.reference_column()->name() == "author");
|
||||
// REQUIRE(c3.reference_column()->table_name() == "books");
|
||||
REQUIRE(c3.type() == basic_type::type_varchar);
|
||||
REQUIRE(c3.attributes().size() == 255);
|
||||
|
||||
REQUIRE(c2.name().empty());
|
||||
REQUIRE(c2.index() == 2);
|
||||
REQUIRE(!c2.reference_column());
|
||||
// REQUIRE(c2.index() == 2);
|
||||
// REQUIRE(!c2.reference_column());
|
||||
REQUIRE(c2.attributes().size() == 255);
|
||||
}
|
||||
Loading…
Reference in New Issue