added value class
This commit is contained in:
parent
f977b2afc9
commit
8f754f3542
|
|
@ -32,7 +32,7 @@ public:
|
||||||
void read_value(const char *id, size_t index, char *value, size_t s) override;
|
void read_value(const char *id, size_t index, char *value, size_t s) override;
|
||||||
void read_value(const char *id, size_t index, std::string &value) override;
|
void read_value(const char *id, size_t index, std::string &value) override;
|
||||||
void read_value(const char *id, size_t index, std::string &value, size_t s) override;
|
void read_value(const char *id, size_t index, std::string &value, size_t s) override;
|
||||||
void read_value(const char *id, size_t index, sql::any_type &value, sql::data_type_t type, size_t size) override;
|
void read_value(const char *id, size_t index, sql::value &val, size_t size) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sqlite3 *db_{nullptr};
|
sqlite3 *db_{nullptr};
|
||||||
|
|
|
||||||
|
|
@ -107,8 +107,8 @@ void sqlite_prepared_result_reader::read_value(const char *id, size_t index, std
|
||||||
query_result_reader::read_value(id, index, value, s);
|
query_result_reader::read_value(id, index, value, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sqlite_prepared_result_reader::read_value(const char *id, size_t index, sql::any_type &value, sql::data_type_t type, size_t size)
|
void sqlite_prepared_result_reader::read_value(const char *id, size_t index, sql::value &val, size_t size)
|
||||||
{
|
{
|
||||||
query_result_reader::read_value(id, index, value, type, size);
|
query_result_reader::read_value(id, index, val, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -45,7 +45,7 @@ TEST_CASE_METHOD(SessionFixture, "Session relation test", "[session][relation]")
|
||||||
REQUIRE(true);
|
REQUIRE(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(SessionFixture, "Find object with id", "[session][find]") {
|
TEST_CASE_METHOD(SessionFixture, "Use session to find object with id", "[session][find]") {
|
||||||
using namespace matador::test;
|
using namespace matador::test;
|
||||||
ses.attach<airplane>("airplane");
|
ses.attach<airplane>("airplane");
|
||||||
ses.create_schema();
|
ses.create_schema();
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,15 @@ template < class Type, class Enable = void >
|
||||||
struct data_type_traits;
|
struct data_type_traits;
|
||||||
|
|
||||||
/// @cond MATADOR_DEV
|
/// @cond MATADOR_DEV
|
||||||
|
template <> struct data_type_traits<nullptr_t, void>
|
||||||
|
{
|
||||||
|
inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_null; }
|
||||||
|
static void read_value(query_result_reader &reader, const char *id, size_t index, nullptr_t &/*value*/);
|
||||||
|
static void bind_value(parameter_binder &binder, size_t index, nullptr_t &/*value*/);
|
||||||
|
static void bind_result_value(result_parameter_binder &binder, size_t index, nullptr_t &/*value*/);
|
||||||
|
inline static any_type create_value(char &value) { return value; }
|
||||||
|
};
|
||||||
|
|
||||||
template <> struct data_type_traits<char, void>
|
template <> struct data_type_traits<char, void>
|
||||||
{
|
{
|
||||||
inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_char; }
|
inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_char; }
|
||||||
|
|
@ -199,7 +208,7 @@ template <> struct data_type_traits<std::string, void>
|
||||||
|
|
||||||
template <> struct data_type_traits<utils::blob, void>
|
template <> struct data_type_traits<utils::blob, void>
|
||||||
{
|
{
|
||||||
inline static data_type_t builtin_type(std::size_t size) { return data_type_t::type_blob; }
|
inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_blob; }
|
||||||
static void read_value(query_result_reader &reader, const char *id, size_t index, utils::blob &value);
|
static void read_value(query_result_reader &reader, const char *id, size_t index, utils::blob &value);
|
||||||
static void bind_value(parameter_binder &binder, size_t index, utils::blob &value);
|
static void bind_value(parameter_binder &binder, size_t index, utils::blob &value);
|
||||||
static void bind_result_value(result_parameter_binder &binder, size_t index, utils::blob &value);
|
static void bind_result_value(result_parameter_binder &binder, size_t index, utils::blob &value);
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include "matador/sql/query_context.hpp"
|
#include "matador/sql/query_context.hpp"
|
||||||
#include "matador/sql/query.hpp"
|
#include "matador/sql/query.hpp"
|
||||||
#include "matador/sql/query_intermediates.hpp"
|
#include "matador/sql/query_intermediates.hpp"
|
||||||
|
#include "matador/sql/value.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
@ -24,20 +25,19 @@ struct entity_query_data {
|
||||||
std::unique_ptr<basic_condition> where_clause;
|
std::unique_ptr<basic_condition> where_clause;
|
||||||
};
|
};
|
||||||
|
|
||||||
template < typename PrimaryKeyType >
|
|
||||||
class entity_query_builder
|
class entity_query_builder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit entity_query_builder(const PrimaryKeyType &pk, const schema &scm)
|
explicit entity_query_builder(const schema &scm)
|
||||||
: pk_(pk)
|
: schema_(scm) {}
|
||||||
, schema_(scm) {}
|
|
||||||
|
|
||||||
template<class EntityType>
|
template<class EntityType, typename PrimaryKeyType>
|
||||||
std::optional<entity_query_data> build() {
|
std::optional<entity_query_data> build(const PrimaryKeyType &pk) {
|
||||||
const auto info = schema_.info<EntityType>();
|
const auto info = schema_.info<EntityType>();
|
||||||
if (!info) {
|
if (!info) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
pk_ = pk;
|
||||||
table_info_stack_.push(info.value());
|
table_info_stack_.push(info.value());
|
||||||
entity_query_data_ = { info->name };
|
entity_query_data_ = { info->name };
|
||||||
EntityType obj;
|
EntityType obj;
|
||||||
|
|
@ -50,24 +50,13 @@ public:
|
||||||
void on_primary_key(const char *id, V &, typename std::enable_if<std::is_integral<V>::value && !std::is_same<bool, V>::value>::type* = 0)
|
void on_primary_key(const char *id, V &, typename std::enable_if<std::is_integral<V>::value && !std::is_same<bool, V>::value>::type* = 0)
|
||||||
{
|
{
|
||||||
push(id);
|
push(id);
|
||||||
if (is_root_entity() && std::is_integral_v<PrimaryKeyType>) {
|
if (is_root_entity() && pk_.is_integer()) {
|
||||||
entity_query_data_.where_clause = make_condition(column{table_info_stack_.top().name, id, ""} == pk_);
|
entity_query_data_.where_clause = make_condition(column{table_info_stack_.top().name, id, ""} == *pk_.as<V>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_primary_key(const char *id, std::string &, size_t)
|
void on_primary_key(const char *id, std::string &, size_t);
|
||||||
{
|
void on_revision(const char *id, unsigned long long &/*rev*/);
|
||||||
push(id);
|
|
||||||
if (!is_root_entity()) {
|
|
||||||
auto b = std::is_same_v<PrimaryKeyType, std::string>;
|
|
||||||
std::cout << "is matching primary key: " << std::boolalpha << b << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_revision(const char *id, unsigned long long &/*rev*/)
|
|
||||||
{
|
|
||||||
push(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
void on_attribute(const char *id, Type &, const utils::field_attributes &/*attr*/ = utils::null_attributes)
|
void on_attribute(const char *id, Type &, const utils::field_attributes &/*attr*/ = utils::null_attributes)
|
||||||
|
|
@ -174,26 +163,12 @@ public:
|
||||||
void on_has_many_to_many(const char *id, ContainerType &c, const utils::foreign_attributes &/*attr*/) {}
|
void on_has_many_to_many(const char *id, ContainerType &c, const utils::foreign_attributes &/*attr*/) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void push(const std::string &column_name)
|
void push(const std::string &column_name);
|
||||||
{
|
[[nodiscard]] bool is_root_entity() const;
|
||||||
char str[4];
|
void append_join(const column &left, const column &right);
|
||||||
snprintf(str, 4, "c%02d", ++column_index);
|
|
||||||
entity_query_data_.columns.emplace_back(table_info_stack_.top().name, column_name, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] bool is_root_entity() const {
|
|
||||||
return table_info_stack_.size() == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void append_join(const column &left, const column &right)
|
|
||||||
{
|
|
||||||
entity_query_data_.joins.push_back({
|
|
||||||
{ left.table },
|
|
||||||
make_condition(left == right)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
PrimaryKeyType pk_;
|
value pk_;
|
||||||
std::stack<table_info> table_info_stack_;
|
std::stack<table_info> table_info_stack_;
|
||||||
const schema &schema_;
|
const schema &schema_;
|
||||||
entity_query_data entity_query_data_;
|
entity_query_data entity_query_data_;
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,7 @@
|
||||||
#ifndef QUERY_FIELD_HPP
|
#ifndef QUERY_FIELD_HPP
|
||||||
#define QUERY_FIELD_HPP
|
#define QUERY_FIELD_HPP
|
||||||
|
|
||||||
#include "matador/sql/any_type.hpp"
|
#include "matador/sql/value.hpp"
|
||||||
#include "matador/sql/any_type_to_visitor.hpp"
|
|
||||||
#include "matador/sql/data_type_traits.hpp"
|
|
||||||
|
|
||||||
#include "matador/utils/types.hpp"
|
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -19,10 +15,8 @@ public:
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
field(std::string name, Type value, size_t size = 0, int index = -1)
|
field(std::string name, Type value, size_t size = 0, int index = -1)
|
||||||
: name_(std::move(name))
|
: name_(std::move(name))
|
||||||
, size_(size)
|
|
||||||
, index_(index)
|
, index_(index)
|
||||||
, value_(value)
|
, value_(value, size) {}
|
||||||
, type_(data_type_traits<Type>::builtin_type(size)) {}
|
|
||||||
field(std::string name, data_type_t data_type, size_t size = 0, int index = -1);
|
field(std::string name, data_type_t data_type, 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;
|
||||||
|
|
@ -32,7 +26,7 @@ public:
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
field& operator=(Type value) {
|
field& operator=(Type value) {
|
||||||
value_ = std::move(value);
|
value_ = std::move(value);
|
||||||
type_ = data_type_traits<Type>::builtin_type(-1);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,9 +37,7 @@ public:
|
||||||
template<class Type>
|
template<class Type>
|
||||||
std::optional<Type> as() const
|
std::optional<Type> as() const
|
||||||
{
|
{
|
||||||
any_type_to_visitor<Type> visitor;
|
return value_.as<Type>();
|
||||||
std::visit(visitor, const_cast<any_type&>(value_));
|
|
||||||
return visitor.result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::string str() const;
|
[[nodiscard]] std::string str() const;
|
||||||
|
|
@ -65,7 +57,7 @@ private:
|
||||||
template<class Operator>
|
template<class Operator>
|
||||||
void process(Operator &op)
|
void process(Operator &op)
|
||||||
{
|
{
|
||||||
op.on_attribute(name_.c_str(), value_, type_, size_);
|
op.on_attribute(name_.c_str(), value_, value_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -73,9 +65,8 @@ private:
|
||||||
|
|
||||||
std::string name_;
|
std::string name_;
|
||||||
int index_{-1};
|
int index_{-1};
|
||||||
any_type value_;
|
|
||||||
size_t size_{};
|
value value_;
|
||||||
data_type_t type_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
|
|
||||||
|
class value;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
class pk_reader
|
class pk_reader
|
||||||
{
|
{
|
||||||
|
|
@ -74,7 +76,7 @@ public:
|
||||||
}
|
}
|
||||||
void on_attribute(const char *id, char *value, const utils::field_attributes &attr = utils::null_attributes);
|
void on_attribute(const char *id, char *value, const utils::field_attributes &attr = utils::null_attributes);
|
||||||
void on_attribute(const char *id, std::string &value, const utils::field_attributes &attr = utils::null_attributes);
|
void on_attribute(const char *id, std::string &value, const utils::field_attributes &attr = utils::null_attributes);
|
||||||
void on_attribute(const char *id, any_type &value, data_type_t type, const utils::field_attributes &attr = utils::null_attributes);
|
void on_attribute(const char *id, value &val, const utils::field_attributes &attr = utils::null_attributes);
|
||||||
|
|
||||||
template < class Pointer >
|
template < class Pointer >
|
||||||
void on_belongs_to(const char * /*id*/, Pointer &x, const utils::foreign_attributes &attr)
|
void on_belongs_to(const char * /*id*/, Pointer &x, const utils::foreign_attributes &attr)
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
|
|
||||||
|
class value;
|
||||||
|
|
||||||
class query_result_reader
|
class query_result_reader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -34,7 +36,7 @@ public:
|
||||||
virtual void read_value(const char *id, size_t index, std::string &value);
|
virtual void read_value(const char *id, size_t index, std::string &value);
|
||||||
virtual void read_value(const char *id, size_t index, std::string &value, size_t s);
|
virtual void read_value(const char *id, size_t index, std::string &value, size_t s);
|
||||||
virtual void read_value(const char *id, size_t index, utils::blob &value);
|
virtual void read_value(const char *id, size_t index, utils::blob &value);
|
||||||
virtual void read_value(const char *id, size_t index, any_type &value, data_type_t type, size_t size);
|
virtual void read_value(const char *id, size_t index, value &val, size_t size);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,8 @@ public:
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
entity_query_builder<PrimaryKeyType> eqb(pk, *schema_);
|
entity_query_builder eqb(*schema_);
|
||||||
auto data = eqb.template build<Type>();
|
auto data = eqb.build<Type>(pk);
|
||||||
|
|
||||||
auto q = c->query(*schema_)
|
auto q = c->query(*schema_)
|
||||||
.select(data->columns)
|
.select(data->columns)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
#ifndef QUERY_VALUE_HPP
|
||||||
|
#define QUERY_VALUE_HPP
|
||||||
|
|
||||||
|
#include "matador/sql/any_type.hpp"
|
||||||
|
#include "matador/sql/any_type_to_visitor.hpp"
|
||||||
|
#include "matador/sql/data_type_traits.hpp"
|
||||||
|
|
||||||
|
#include "matador/utils/types.hpp"
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
namespace matador::sql {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template<typename Type>
|
||||||
|
size_t determine_size(const Type &/*val*/)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
size_t determine_size(const std::string &val);
|
||||||
|
size_t determine_size(const char *val);
|
||||||
|
size_t determine_size(const utils::blob &val);
|
||||||
|
|
||||||
|
}
|
||||||
|
class value
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
value() = default;
|
||||||
|
template<typename Type>
|
||||||
|
explicit value(Type value, size_t size = 0)
|
||||||
|
: size_(size)
|
||||||
|
, value_(value)
|
||||||
|
, type_(data_type_traits<Type>::builtin_type(size)) {}
|
||||||
|
explicit value(data_type_t data_type, size_t size = 0);
|
||||||
|
value(const value &x) = default;
|
||||||
|
value& operator=(const value &x) = default;
|
||||||
|
template<typename Type>
|
||||||
|
value& operator=(Type val)
|
||||||
|
{
|
||||||
|
value_ = val;
|
||||||
|
size_ = detail::determine_size(val);
|
||||||
|
type_ = data_type_traits<Type>::builtin_type(size_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
value(value &&x) noexcept;
|
||||||
|
value& operator=(value &&x) noexcept;
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
std::optional<Type> as() const
|
||||||
|
{
|
||||||
|
if (std::holds_alternative<Type>(value_)) {
|
||||||
|
return std::get<Type>(value_);
|
||||||
|
} else {
|
||||||
|
any_type_to_visitor<Type> visitor;
|
||||||
|
std::visit(visitor, const_cast<any_type &>(value_));
|
||||||
|
return visitor.result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[[nodiscard]] std::string str() const;
|
||||||
|
|
||||||
|
[[nodiscard]] size_t size() const;
|
||||||
|
[[nodiscard]] data_type_t type() const;
|
||||||
|
|
||||||
|
[[nodiscard]] bool is_integer() const;
|
||||||
|
[[nodiscard]] bool is_floating_point() const;
|
||||||
|
[[nodiscard]] bool is_bool() const;
|
||||||
|
[[nodiscard]] bool is_string() const;
|
||||||
|
[[nodiscard]] bool is_varchar() const;
|
||||||
|
[[nodiscard]] bool is_blob() const;
|
||||||
|
[[nodiscard]] bool is_null() const;
|
||||||
|
[[nodiscard]] bool is_unknown() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
any_type value_;
|
||||||
|
size_t size_{};
|
||||||
|
data_type_t type_{data_type_t::type_unknown};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif //QUERY_VALUE_HPP
|
||||||
|
|
@ -37,6 +37,8 @@ set(SQL_SOURCES
|
||||||
sql/any_type_to_string_visitor.cpp
|
sql/any_type_to_string_visitor.cpp
|
||||||
sql/field.cpp
|
sql/field.cpp
|
||||||
sql/table_definition.cpp
|
sql/table_definition.cpp
|
||||||
|
sql/value.cpp
|
||||||
|
sql/entity_query_builder.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SQL_HEADER
|
set(SQL_HEADER
|
||||||
|
|
@ -92,6 +94,7 @@ set(SQL_HEADER
|
||||||
../include/matador/sql/entity_query_builder.hpp
|
../include/matador/sql/entity_query_builder.hpp
|
||||||
../include/matador/sql/table_definition.hpp
|
../include/matador/sql/table_definition.hpp
|
||||||
../include/matador/sql/has_many_to_many_relation.hpp
|
../include/matador/sql/has_many_to_many_relation.hpp
|
||||||
|
../include/matador/sql/value.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(UTILS_HEADER
|
set(UTILS_HEADER
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,10 @@ void column_definition::type(data_type_t type)
|
||||||
|
|
||||||
std::string column_definition::str() const
|
std::string column_definition::str() const
|
||||||
{
|
{
|
||||||
|
if (std::holds_alternative<std::string>(value_)) {
|
||||||
|
return std::get<std::string>(value_);
|
||||||
|
}
|
||||||
|
|
||||||
any_type_to_visitor<std::string> visitor;
|
any_type_to_visitor<std::string> visitor;
|
||||||
std::visit(visitor, const_cast<any_type &>(value_));
|
std::visit(visitor, const_cast<any_type &>(value_));
|
||||||
return visitor.result;
|
return visitor.result;
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,21 @@
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
|
|
||||||
|
void data_type_traits<nullptr_t>::read_value(query_result_reader &reader, const char *id, size_t index, nullptr_t &/*value*/)
|
||||||
|
{
|
||||||
|
// reader.read_value(id, index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void data_type_traits<nullptr_t>::bind_value(parameter_binder &binder, size_t index, nullptr_t &/*value*/)
|
||||||
|
{
|
||||||
|
// binder.bind(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void data_type_traits<nullptr_t>::bind_result_value(result_parameter_binder &binder, size_t index, nullptr_t &/*value*/)
|
||||||
|
{
|
||||||
|
// binder.bind_result_value(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
void data_type_traits<char>::read_value(query_result_reader &reader, const char *id, size_t index, char &value)
|
void data_type_traits<char>::read_value(query_result_reader &reader, const char *id, size_t index, char &value)
|
||||||
{
|
{
|
||||||
reader.read_value(id, index, value);
|
reader.read_value(id, index, value);
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ std::string dialect::prepare_identifier_string(const std::string &col) const
|
||||||
|
|
||||||
for (auto &part : parts) {
|
for (auto &part : parts) {
|
||||||
escape_quotes_in_identifier(part);
|
escape_quotes_in_identifier(part);
|
||||||
// quote_identifier(part);
|
quote_identifier(part);
|
||||||
}
|
}
|
||||||
return utils::join(parts, ".");
|
return utils::join(parts, ".");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
#include "matador/sql/entity_query_builder.hpp"
|
||||||
|
|
||||||
|
namespace matador::sql {
|
||||||
|
|
||||||
|
void entity_query_builder::on_primary_key(const char *id, std::string &, size_t)
|
||||||
|
{
|
||||||
|
push(id);
|
||||||
|
if (!is_root_entity()) {
|
||||||
|
auto b = pk_.is_varchar();
|
||||||
|
std::cout << "is matching primary key: " << std::boolalpha << b << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void entity_query_builder::on_revision(const char *id, unsigned long long &/*rev*/)
|
||||||
|
{
|
||||||
|
push(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entity_query_builder::push(const std::string &column_name)
|
||||||
|
{
|
||||||
|
char str[4];
|
||||||
|
snprintf(str, 4, "c%02d", ++column_index);
|
||||||
|
entity_query_data_.columns.emplace_back(table_info_stack_.top().name, column_name, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool entity_query_builder::is_root_entity() const {
|
||||||
|
return table_info_stack_.size() == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void entity_query_builder::append_join(const column &left, const column &right)
|
||||||
|
{
|
||||||
|
entity_query_data_.joins.push_back({
|
||||||
|
{ left.table },
|
||||||
|
make_condition(left == right)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -7,24 +7,20 @@ namespace matador::sql {
|
||||||
field::field(std::string name)
|
field::field(std::string name)
|
||||||
: name_(std::move(name))
|
: name_(std::move(name))
|
||||||
, value_(nullptr)
|
, value_(nullptr)
|
||||||
, type_(data_type_t::type_unknown)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
field::field(std::string name, data_type_t data_type, size_t size, int index)
|
field::field(std::string name, data_type_t data_type, size_t size, int index)
|
||||||
: name_(std::move(name))
|
: name_(std::move(name))
|
||||||
, size_(size)
|
|
||||||
, index_(index)
|
, index_(index)
|
||||||
, type_(data_type) {}
|
, value_(data_type, size) {}
|
||||||
|
|
||||||
field::field(field &&x) noexcept
|
field::field(field &&x) noexcept
|
||||||
: name_(std::move(x.name_))
|
: name_(std::move(x.name_))
|
||||||
, index_(x.index_)
|
, index_(x.index_)
|
||||||
, value_(std::move(x.value_))
|
, value_(std::move(x.value_))
|
||||||
, type_(x.type_)
|
|
||||||
{
|
{
|
||||||
x.value_ = nullptr;
|
x.value_ = nullptr;
|
||||||
x.index_ = -1;
|
x.index_ = -1;
|
||||||
x.type_ = data_type_t::type_unknown;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
field &field::operator=(field &&x) noexcept
|
field &field::operator=(field &&x) noexcept
|
||||||
|
|
@ -32,10 +28,8 @@ field &field::operator=(field &&x) noexcept
|
||||||
name_ = std::move(x.name_);
|
name_ = std::move(x.name_);
|
||||||
index_ = x.index_;
|
index_ = x.index_;
|
||||||
value_ = std::move(x.value_);
|
value_ = std::move(x.value_);
|
||||||
type_ = x.type_;
|
|
||||||
x.index_ = -1;
|
x.index_ = -1;
|
||||||
x.value_ = nullptr;
|
x.value_ = nullptr;
|
||||||
x.type_ = data_type_t::type_unknown;
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -47,7 +41,7 @@ const std::string &field::name() const
|
||||||
|
|
||||||
size_t field::size() const
|
size_t field::size() const
|
||||||
{
|
{
|
||||||
return size_;
|
return value_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int field::index() const
|
int field::index() const
|
||||||
|
|
@ -68,42 +62,42 @@ std::string field::str() const
|
||||||
|
|
||||||
bool field::is_integer() const
|
bool field::is_integer() const
|
||||||
{
|
{
|
||||||
return type_ >= data_type_t::type_char && type_ <= data_type_t::type_unsigned_long_long;
|
return value_.is_integer();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool field::is_floating_point() const
|
bool field::is_floating_point() const
|
||||||
{
|
{
|
||||||
return type_ == data_type_t::type_float || type_ == data_type_t::type_double;
|
return value_.is_floating_point();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool field::is_bool() const
|
bool field::is_bool() const
|
||||||
{
|
{
|
||||||
return type_ == data_type_t::type_bool;
|
return value_.is_bool();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool field::is_string() const
|
bool field::is_string() const
|
||||||
{
|
{
|
||||||
return type_ == data_type_t::type_text;
|
return value_.is_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool field::is_varchar() const
|
bool field::is_varchar() const
|
||||||
{
|
{
|
||||||
return type_ == data_type_t::type_varchar;
|
return value_.is_varchar();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool field::is_blob() const
|
bool field::is_blob() const
|
||||||
{
|
{
|
||||||
return type_ == data_type_t::type_blob;
|
return value_.is_blob();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool field::is_null() const
|
bool field::is_null() const
|
||||||
{
|
{
|
||||||
return type_ == data_type_t::type_null;
|
return value_.is_null();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool field::is_unknown() const
|
bool field::is_unknown() const
|
||||||
{
|
{
|
||||||
return type_ == data_type_t::type_unknown;
|
return value_.is_unknown();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include "matador/sql/query_result_impl.hpp"
|
#include "matador/sql/query_result_impl.hpp"
|
||||||
#include "matador/sql/query_result_reader.hpp"
|
#include "matador/sql/query_result_reader.hpp"
|
||||||
|
#include "matador/sql/value.hpp"
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
|
|
||||||
|
|
@ -39,9 +40,9 @@ void query_result_impl::on_attribute(const char *id, std::string &value, const u
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
query_result_impl::on_attribute(const char *id, any_type &value, data_type_t type, const utils::field_attributes &attr)
|
query_result_impl::on_attribute(const char *id, value &val, const utils::field_attributes &attr)
|
||||||
{
|
{
|
||||||
reader_->read_value(id, column_index_++, value, type, attr.size());
|
reader_->read_value(id, column_index_++, val, attr.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<column_definition>& query_result_impl::prototype() const
|
const std::vector<column_definition>& query_result_impl::prototype() const
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include "matador/sql/query_result_reader.hpp"
|
#include "matador/sql/query_result_reader.hpp"
|
||||||
#include "matador/sql/to_value.hpp"
|
#include "matador/sql/to_value.hpp"
|
||||||
|
#include "matador/sql/value.hpp"
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
|
|
||||||
|
|
@ -104,82 +105,82 @@ void query_result_reader::read_value(const char *id, size_t index, utils::blob &
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename Type >
|
template < typename Type >
|
||||||
void convert(const char *valstr, sql::any_type &value)
|
void convert(const char *valstr, value &val)
|
||||||
{
|
{
|
||||||
Type val{};
|
Type local_val{};
|
||||||
sql::to_value(val, valstr);
|
sql::to_value(local_val, valstr);
|
||||||
value = val;
|
val = local_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void query_result_reader::read_value(const char *id, size_t index, any_type &value, data_type_t type, size_t size)
|
void query_result_reader::read_value(const char *id, size_t index, value &val, size_t size)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (val.type()) {
|
||||||
case sql::data_type_t::type_char:
|
case sql::data_type_t::type_char:
|
||||||
convert<char>(column(index), value);
|
convert<char>(column(index), val);
|
||||||
break;
|
break;
|
||||||
case sql::data_type_t::type_short:
|
case sql::data_type_t::type_short:
|
||||||
convert<short>(column(index), value);
|
convert<short>(column(index), val);
|
||||||
break;
|
break;
|
||||||
case sql::data_type_t::type_int:
|
case sql::data_type_t::type_int:
|
||||||
convert<int>(column(index), value);
|
convert<int>(column(index), val);
|
||||||
break;
|
break;
|
||||||
case sql::data_type_t::type_long:
|
case sql::data_type_t::type_long:
|
||||||
convert<long>(column(index), value);
|
convert<long>(column(index), val);
|
||||||
break;
|
break;
|
||||||
case sql::data_type_t::type_long_long:
|
case sql::data_type_t::type_long_long:
|
||||||
convert<long long>(column(index), value);
|
convert<long long>(column(index), val);
|
||||||
break;
|
break;
|
||||||
case sql::data_type_t::type_unsigned_char:
|
case sql::data_type_t::type_unsigned_char:
|
||||||
convert<unsigned char>(column(index), value);
|
convert<unsigned char>(column(index), val);
|
||||||
break;
|
break;
|
||||||
case sql::data_type_t::type_unsigned_short:
|
case sql::data_type_t::type_unsigned_short:
|
||||||
convert<unsigned short>(column(index), value);
|
convert<unsigned short>(column(index), val);
|
||||||
break;
|
break;
|
||||||
case sql::data_type_t::type_unsigned_int:
|
case sql::data_type_t::type_unsigned_int:
|
||||||
convert<unsigned int>(column(index), value);
|
convert<unsigned int>(column(index), val);
|
||||||
break;
|
break;
|
||||||
case sql::data_type_t::type_unsigned_long:
|
case sql::data_type_t::type_unsigned_long:
|
||||||
convert<unsigned long>(column(index), value);
|
convert<unsigned long>(column(index), val);
|
||||||
break;
|
break;
|
||||||
case sql::data_type_t::type_unsigned_long_long:
|
case sql::data_type_t::type_unsigned_long_long:
|
||||||
convert<unsigned long long>(column(index), value);
|
convert<unsigned long long>(column(index), val);
|
||||||
break;
|
break;
|
||||||
case sql::data_type_t::type_float:
|
case sql::data_type_t::type_float:
|
||||||
convert<float>(column(index), value);
|
convert<float>(column(index), val);
|
||||||
break;
|
break;
|
||||||
case sql::data_type_t::type_double:
|
case sql::data_type_t::type_double:
|
||||||
convert<double>(column(index), value);
|
convert<double>(column(index), val);
|
||||||
break;
|
break;
|
||||||
case sql::data_type_t::type_bool: {
|
case sql::data_type_t::type_bool: {
|
||||||
int val{};
|
int local_val{};
|
||||||
sql::to_value(val, column(index));
|
sql::to_value(local_val, column(index));
|
||||||
value = val > 0;
|
val = local_val > 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case sql::data_type_t::type_text:
|
case sql::data_type_t::type_text:
|
||||||
case sql::data_type_t::type_varchar: {
|
case sql::data_type_t::type_varchar: {
|
||||||
value = std::string{column(index)};
|
val = std::string{column(index)};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case sql::data_type_t::type_char_pointer: {
|
case sql::data_type_t::type_char_pointer: {
|
||||||
value = column(index);
|
val = column(index);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case sql::data_type_t::type_time:
|
case sql::data_type_t::type_time:
|
||||||
case sql::data_type_t::type_date: {
|
case sql::data_type_t::type_date: {
|
||||||
value = std::string{column(index)};
|
val = std::string{column(index)};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case sql::data_type_t::type_null: {
|
case sql::data_type_t::type_null: {
|
||||||
value = nullptr_t{};
|
val = nullptr_t{};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case sql::data_type_t::type_blob: {
|
case sql::data_type_t::type_blob: {
|
||||||
value = utils::blob{};
|
val = utils::blob{};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case sql::data_type_t::type_unknown: {
|
case sql::data_type_t::type_unknown: {
|
||||||
value = std::string(column(index));
|
val = std::string(column(index));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
#include "matador/sql/value.hpp"
|
||||||
|
|
||||||
|
namespace matador::sql {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
size_t determine_size(const std::string &val)
|
||||||
|
{
|
||||||
|
return val.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t determine_size(const char *val)
|
||||||
|
{
|
||||||
|
return strlen(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t determine_size(const utils::blob &val)
|
||||||
|
{
|
||||||
|
return val.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
value::value(data_type_t data_type, size_t size)
|
||||||
|
: size_(size)
|
||||||
|
, type_(data_type) {}
|
||||||
|
|
||||||
|
value::value(value &&x) noexcept
|
||||||
|
: value_(std::move(x.value_))
|
||||||
|
, type_(x.type_)
|
||||||
|
{
|
||||||
|
x.value_ = nullptr;
|
||||||
|
x.type_ = data_type_t::type_unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
value &value::operator=(value &&x) noexcept
|
||||||
|
{
|
||||||
|
value_ = std::move(x.value_);
|
||||||
|
type_ = x.type_;
|
||||||
|
x.value_ = nullptr;
|
||||||
|
x.type_ = data_type_t::type_unknown;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string value::str() const
|
||||||
|
{
|
||||||
|
return as<std::string>().value();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t value::size() const
|
||||||
|
{
|
||||||
|
return size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
data_type_t value::type() const
|
||||||
|
{
|
||||||
|
return type_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool value::is_integer() const
|
||||||
|
{
|
||||||
|
return type_ >= data_type_t::type_char && type_ <= data_type_t::type_unsigned_long_long;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool value::is_floating_point() const
|
||||||
|
{
|
||||||
|
return type_ == data_type_t::type_float || type_ == data_type_t::type_double;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool value::is_bool() const
|
||||||
|
{
|
||||||
|
return type_ == data_type_t::type_bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool value::is_string() const
|
||||||
|
{
|
||||||
|
return type_ == data_type_t::type_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool value::is_varchar() const
|
||||||
|
{
|
||||||
|
return type_ == data_type_t::type_varchar || type_ == data_type_t::type_char_pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool value::is_blob() const
|
||||||
|
{
|
||||||
|
return type_ == data_type_t::type_blob;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool value::is_null() const
|
||||||
|
{
|
||||||
|
return type_ == data_type_t::type_null;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool value::is_unknown() const
|
||||||
|
{
|
||||||
|
return type_ == data_type_t::type_unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -40,7 +40,8 @@ add_executable(tests
|
||||||
models/author.hpp
|
models/author.hpp
|
||||||
models/book.hpp
|
models/book.hpp
|
||||||
FieldTest.cpp
|
FieldTest.cpp
|
||||||
models/recipe.hpp)
|
models/recipe.hpp
|
||||||
|
ValueTest.cpp)
|
||||||
|
|
||||||
target_link_libraries(tests PRIVATE
|
target_link_libraries(tests PRIVATE
|
||||||
Catch2::Catch2WithMain
|
Catch2::Catch2WithMain
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
using namespace matador::sql;
|
using namespace matador::sql;
|
||||||
using namespace matador::utils;
|
using namespace matador::utils;
|
||||||
|
|
||||||
TEST_CASE("Generate columns from object", "[column generator]") {
|
TEST_CASE("Generate column definitions from object", "[column][definition][generator]") {
|
||||||
schema repo("main");
|
schema repo("main");
|
||||||
|
|
||||||
auto columns = column_definition_generator::generate<matador::test::product>(repo);
|
auto columns = column_definition_generator::generate<matador::test::product>(repo);
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,9 @@ TEST_CASE("Create sql query data for entity with eager belongs to", "[query][ent
|
||||||
scm.attach<author>("authors");
|
scm.attach<author>("authors");
|
||||||
scm.attach<book>("books");
|
scm.attach<book>("books");
|
||||||
|
|
||||||
entity_query_builder eqb(17, scm);
|
entity_query_builder eqb(scm);
|
||||||
|
|
||||||
auto data = eqb.build<book>();
|
auto data = eqb.build<book>(17);
|
||||||
|
|
||||||
REQUIRE(data.has_value());
|
REQUIRE(data.has_value());
|
||||||
REQUIRE(data->root_table_name == "books");
|
REQUIRE(data->root_table_name == "books");
|
||||||
|
|
@ -41,7 +41,7 @@ TEST_CASE("Create sql query data for entity with eager belongs to", "[query][ent
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<std::string, std::string>> expected_join_data {
|
std::vector<std::pair<std::string, std::string>> expected_join_data {
|
||||||
{ "books", "books.author_id = authors.id"}
|
{ "books", R"("books"."author_id" = "authors"."id")"}
|
||||||
};
|
};
|
||||||
|
|
||||||
query_context qc;
|
query_context qc;
|
||||||
|
|
@ -54,7 +54,7 @@ TEST_CASE("Create sql query data for entity with eager belongs to", "[query][ent
|
||||||
|
|
||||||
REQUIRE(data->where_clause);
|
REQUIRE(data->where_clause);
|
||||||
auto cond = data->where_clause->evaluate(db.dialect(), qc);
|
auto cond = data->where_clause->evaluate(db.dialect(), qc);
|
||||||
REQUIRE(cond == "books.id = 17");
|
REQUIRE(cond == R"("books"."id" = 17)");
|
||||||
|
|
||||||
auto q = db.query(scm)
|
auto q = db.query(scm)
|
||||||
.select(data->columns)
|
.select(data->columns)
|
||||||
|
|
@ -77,9 +77,9 @@ TEST_CASE("Create sql query data for entity with eager has many belongs to", "[q
|
||||||
scm.attach<order_details>("order_details");
|
scm.attach<order_details>("order_details");
|
||||||
scm.attach<order>("orders");
|
scm.attach<order>("orders");
|
||||||
|
|
||||||
entity_query_builder eqb(17, scm);
|
entity_query_builder eqb(scm);
|
||||||
|
|
||||||
auto data = eqb.build<order>();
|
auto data = eqb.build<order>(17);
|
||||||
|
|
||||||
REQUIRE(data.has_value());
|
REQUIRE(data.has_value());
|
||||||
REQUIRE(data->root_table_name == "orders");
|
REQUIRE(data->root_table_name == "orders");
|
||||||
|
|
@ -107,7 +107,7 @@ TEST_CASE("Create sql query data for entity with eager has many belongs to", "[q
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<std::string, std::string>> expected_join_data {
|
std::vector<std::pair<std::string, std::string>> expected_join_data {
|
||||||
{ "orders", "orders.order_id = order_details.order_id"}
|
{ "orders", R"("orders"."order_id" = "order_details"."order_id")"}
|
||||||
};
|
};
|
||||||
|
|
||||||
query_context qc;
|
query_context qc;
|
||||||
|
|
@ -120,7 +120,7 @@ TEST_CASE("Create sql query data for entity with eager has many belongs to", "[q
|
||||||
|
|
||||||
REQUIRE(data->where_clause);
|
REQUIRE(data->where_clause);
|
||||||
auto cond = data->where_clause->evaluate(db.dialect(), qc);
|
auto cond = data->where_clause->evaluate(db.dialect(), qc);
|
||||||
REQUIRE(cond == "orders.order_id = 17");
|
REQUIRE(cond == R"("orders"."order_id" = 17)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Create sql query data for entity with eager many to many", "[query][entity][builder]") {
|
TEST_CASE("Create sql query data for entity with eager many to many", "[query][entity][builder]") {
|
||||||
|
|
@ -131,9 +131,9 @@ TEST_CASE("Create sql query data for entity with eager many to many", "[query][e
|
||||||
scm.attach<ingredient>("ingredients");
|
scm.attach<ingredient>("ingredients");
|
||||||
scm.attach<recipe_ingredient>("recipe_ingredients");
|
scm.attach<recipe_ingredient>("recipe_ingredients");
|
||||||
|
|
||||||
entity_query_builder eqb(17, scm);
|
entity_query_builder eqb(scm);
|
||||||
|
|
||||||
auto data = eqb.build<ingredient>();
|
auto data = eqb.build<ingredient>(17);
|
||||||
|
|
||||||
REQUIRE(data.has_value());
|
REQUIRE(data.has_value());
|
||||||
REQUIRE(data->root_table_name == "ingredients");
|
REQUIRE(data->root_table_name == "ingredients");
|
||||||
|
|
@ -150,8 +150,8 @@ TEST_CASE("Create sql query data for entity with eager many to many", "[query][e
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<std::string, std::string>> expected_join_data {
|
std::vector<std::pair<std::string, std::string>> expected_join_data {
|
||||||
{ "ingredients", "ingredients.id = recipe_ingredients.ingredient_id"},
|
{ "ingredients", R"("ingredients"."id" = "recipe_ingredients"."ingredient_id")"},
|
||||||
{ "recipes", "recipes.id = recipe_ingredients.recipe_id"}
|
{ "recipes", R"("recipes"."id" = "recipe_ingredients"."recipe_id")"}
|
||||||
};
|
};
|
||||||
|
|
||||||
query_context qc;
|
query_context qc;
|
||||||
|
|
@ -164,5 +164,5 @@ TEST_CASE("Create sql query data for entity with eager many to many", "[query][e
|
||||||
|
|
||||||
REQUIRE(data->where_clause);
|
REQUIRE(data->where_clause);
|
||||||
auto cond = data->where_clause->evaluate(db.dialect(), qc);
|
auto cond = data->where_clause->evaluate(db.dialect(), qc);
|
||||||
REQUIRE(cond == "ingredients.id = 17");
|
REQUIRE(cond == R"("ingredients"."id" = 17)");
|
||||||
}
|
}
|
||||||
|
|
@ -9,8 +9,8 @@ TEST_CASE("Field test", "[field]") {
|
||||||
|
|
||||||
REQUIRE(f.name() == "name");
|
REQUIRE(f.name() == "name");
|
||||||
REQUIRE(f.index() == -1);
|
REQUIRE(f.index() == -1);
|
||||||
REQUIRE(f.is_unknown());
|
REQUIRE(!f.is_unknown());
|
||||||
REQUIRE(!f.is_null());
|
REQUIRE(f.is_null());
|
||||||
REQUIRE(!f.is_integer());
|
REQUIRE(!f.is_integer());
|
||||||
REQUIRE(!f.is_floating_point());
|
REQUIRE(!f.is_floating_point());
|
||||||
REQUIRE(!f.is_blob());
|
REQUIRE(!f.is_blob());
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
|
||||||
|
#include "matador/sql/value.hpp"
|
||||||
|
#include "matador/utils/types.hpp"
|
||||||
|
|
||||||
|
using namespace matador::sql;
|
||||||
|
|
||||||
|
TEST_CASE("Test value class", "[value]") {
|
||||||
|
value v;
|
||||||
|
|
||||||
|
REQUIRE(v.is_unknown());
|
||||||
|
REQUIRE(v.type() == data_type_t::type_unknown);
|
||||||
|
REQUIRE(v.size() == 0);
|
||||||
|
|
||||||
|
v = 7;
|
||||||
|
|
||||||
|
REQUIRE(v.is_integer());
|
||||||
|
REQUIRE(v.type() == data_type_t::type_int);
|
||||||
|
REQUIRE(v.size() == 0);
|
||||||
|
REQUIRE(v.as<int>() == 7);
|
||||||
|
REQUIRE(v.as<long>() == 7);
|
||||||
|
|
||||||
|
v = "test";
|
||||||
|
|
||||||
|
REQUIRE(v.is_varchar());
|
||||||
|
REQUIRE(v.type() == data_type_t::type_char_pointer);
|
||||||
|
REQUIRE(v.size() == 4);
|
||||||
|
|
||||||
|
v = std::string{"hello"};
|
||||||
|
|
||||||
|
REQUIRE(v.is_varchar());
|
||||||
|
REQUIRE(v.type() == data_type_t::type_varchar);
|
||||||
|
REQUIRE(v.size() == 5);
|
||||||
|
|
||||||
|
v = 4.5;
|
||||||
|
|
||||||
|
REQUIRE(v.is_floating_point());
|
||||||
|
REQUIRE(v.type() == data_type_t::type_double);
|
||||||
|
REQUIRE(v.size() == 0);
|
||||||
|
|
||||||
|
v = 6.7f;
|
||||||
|
|
||||||
|
REQUIRE(v.is_floating_point());
|
||||||
|
REQUIRE(v.type() == data_type_t::type_float);
|
||||||
|
REQUIRE(v.size() == 0);
|
||||||
|
|
||||||
|
v = std::string();
|
||||||
|
|
||||||
|
REQUIRE(v.is_string());
|
||||||
|
REQUIRE(v.type() == data_type_t::type_text);
|
||||||
|
REQUIRE(v.size() == 0);
|
||||||
|
|
||||||
|
v = true;
|
||||||
|
|
||||||
|
REQUIRE(v.is_bool());
|
||||||
|
REQUIRE(v.type() == data_type_t::type_bool);
|
||||||
|
REQUIRE(v.size() == 0);
|
||||||
|
|
||||||
|
v = nullptr;
|
||||||
|
|
||||||
|
REQUIRE(v.is_null());
|
||||||
|
REQUIRE(v.type() == data_type_t::type_null);
|
||||||
|
REQUIRE(v.size() == 0);
|
||||||
|
|
||||||
|
v = matador::utils::blob{ 1, 2, 3, 4 };
|
||||||
|
|
||||||
|
REQUIRE(v.is_blob());
|
||||||
|
REQUIRE(v.type() == data_type_t::type_blob);
|
||||||
|
REQUIRE(v.size() == 4);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue