added blob type (progress)

This commit is contained in:
Sascha Kuehl 2024-01-22 07:11:35 +01:00
parent b158b41556
commit 102a7fc604
24 changed files with 240 additions and 149 deletions

View File

@ -3,6 +3,8 @@
#include "matador/sql/placeholder.hpp" #include "matador/sql/placeholder.hpp"
#include "matador/utils/types.hpp"
#include <string> #include <string>
#include <variant> #include <variant>
@ -15,6 +17,7 @@ using any_type = std::variant<
bool, bool,
const char*, const char*,
std::string, std::string,
utils::blob,
placeholder, placeholder,
nullptr_t>; nullptr_t>;

View File

@ -1,111 +1,14 @@
#ifndef QUERY_ANY_TYPE_TO_VISITOR_HPP #ifndef QUERY_ANY_TYPE_TO_VISITOR_HPP
#define QUERY_ANY_TYPE_TO_VISITOR_HPP #define QUERY_ANY_TYPE_TO_VISITOR_HPP
#include <array> #include "matador/sql/convert.hpp"
#include <charconv>
#include <cstring>
#include <stdexcept>
#include <string> #include <string>
#include <type_traits>
namespace matador::sql { namespace matador::sql {
struct placeholder; struct placeholder;
template < typename DestType, typename SourceType >
void convert(DestType &dest, SourceType source, typename std::enable_if<std::is_same<DestType, SourceType>::value>::type* = nullptr)
{
dest = source;
}
template < typename DestType, typename SourceType >
void convert(DestType &dest, SourceType source, typename std::enable_if<std::is_integral<DestType>::value && std::is_arithmetic<SourceType>::value && !std::is_same<DestType, SourceType>::value>::type* = nullptr)
{
dest = static_cast<DestType>(source);
}
template < typename DestType, typename SourceType >
void convert(DestType &dest, SourceType source, typename std::enable_if<std::is_floating_point<DestType>::value && std::is_arithmetic<SourceType>::value && !std::is_same<DestType, SourceType>::value>::type* = nullptr)
{
dest = static_cast<DestType>(source);
}
void convert(std::string &dest, bool source);
template < typename SourceType >
void convert(std::string &dest, SourceType source, typename std::enable_if<std::is_integral<SourceType>::value && !std::is_same<bool, SourceType>::value>::type* = nullptr)
{
std::array<char, 128> buffer{};
auto [ptr, ec] = std::to_chars(buffer.data(), buffer.data() + buffer.size(), source, 10);
if (ec == std::errc{}) {
dest.assign(buffer.data(), ptr);
} else {
throw std::logic_error("couldn't convert value to std::string");
}
}
template < typename SourceType >
void convert(std::string &dest, SourceType source, typename std::enable_if<std::is_floating_point<SourceType>::value>::type* = nullptr)
{
std::array<char, 128> buffer{};
auto [ptr, ec] = std::to_chars(buffer.data(), buffer.data() + buffer.size(), source);
if (ec == std::errc{}) {
dest.assign(buffer.data(), ptr);
} else {
throw std::logic_error("couldn't convert value to std::string");
}
}
void convert(std::string &dest, const char* source);
unsigned long long to_unsigned_long_long(const char *source);
template < typename DestType >
void convert(DestType &dest, const std::string &source, typename std::enable_if<std::is_integral<DestType>::value && std::is_unsigned<DestType>::value>::type* = nullptr)
{
dest = to_unsigned_long_long(source.c_str());
}
template < typename DestType >
void convert(DestType &dest, const char *source, typename std::enable_if<std::is_integral<DestType>::value && std::is_unsigned<DestType>::value>::type* = nullptr)
{
dest = to_unsigned_long_long(source);
}
long long to_long_long(const char *source);
template < typename DestType >
void convert(DestType &dest, const std::string &source, typename std::enable_if<std::is_integral<DestType>::value && std::is_signed<DestType>::value>::type* = nullptr)
{
dest = to_long_long(source.c_str());
}
template < typename DestType >
void convert(DestType &dest, const char *source, typename std::enable_if<std::is_integral<DestType>::value && std::is_signed<DestType>::value>::type* = nullptr)
{
dest = to_long_long(source);
}
long double to_double(const char *source);
template < typename DestType >
void convert(DestType &dest, const std::string &source, typename std::enable_if<std::is_floating_point<DestType>::value>::type* = nullptr)
{
dest = to_double(source.c_str());
}
template < typename DestType >
void convert(DestType &dest, const char *source, typename std::enable_if<std::is_floating_point<DestType>::value>::type* = nullptr)
{
dest = to_double(source);
}
template < typename DestType >
void convert(DestType &dest, bool source, typename std::enable_if<std::is_floating_point<DestType>::value>::type* = nullptr)
{
dest = static_cast<DestType>(source);
}
template < typename Type > template < typename Type >
struct any_type_to_visitor struct any_type_to_visitor
{ {
@ -124,6 +27,7 @@ struct any_type_to_visitor
void operator()(double &x) { convert(result, x); } void operator()(double &x) { convert(result, x); }
void operator()(const char *x) { convert(result, x); } void operator()(const char *x) { convert(result, x); }
void operator()(std::string &x) { convert(result, x); } void operator()(std::string &x) { convert(result, x); }
void operator()(utils::blob &x) { convert(result, x); }
void operator()(placeholder &/*x*/) {} void operator()(placeholder &/*x*/) {}
Type result{}; Type result{};

View File

@ -3,7 +3,7 @@
#include "matador/sql/any_type.hpp" #include "matador/sql/any_type.hpp"
#include "matador/sql/any_type_to_visitor.hpp" #include "matador/sql/any_type_to_visitor.hpp"
#include "matador/sql/types.hpp" #include "matador/sql/data_type_traits.hpp"
#include "matador/utils/field_attributes.hpp" #include "matador/utils/field_attributes.hpp"

View File

@ -2,7 +2,7 @@
#define QUERY_COLUMN_GENERATOR_HPP #define QUERY_COLUMN_GENERATOR_HPP
#include "matador/sql/column.hpp" #include "matador/sql/column.hpp"
#include "matador/sql/types.hpp" #include "matador/sql/data_type_traits.hpp"
#include "matador/utils/access.hpp" #include "matador/utils/access.hpp"
#include "matador/utils/field_attributes.hpp" #include "matador/utils/field_attributes.hpp"

View File

@ -0,0 +1,108 @@
#ifndef QUERY_CONVERT_HPP
#define QUERY_CONVERT_HPP
#include <array>
#include <charconv>
#include <stdexcept>
#include <string>
#include <type_traits>
namespace matador::sql {
template < typename DestType, typename SourceType >
void convert(DestType &dest, SourceType source, typename std::enable_if<std::is_same<DestType, SourceType>::value>::type* = nullptr)
{
dest = source;
}
template < typename DestType, typename SourceType >
void convert(DestType &dest, SourceType source, typename std::enable_if<std::is_integral<DestType>::value && std::is_arithmetic<SourceType>::value && !std::is_same<DestType, SourceType>::value>::type* = nullptr)
{
dest = static_cast<DestType>(source);
}
template < typename DestType, typename SourceType >
void convert(DestType &dest, SourceType source, typename std::enable_if<std::is_floating_point<DestType>::value && std::is_arithmetic<SourceType>::value && !std::is_same<DestType, SourceType>::value>::type* = nullptr)
{
dest = static_cast<DestType>(source);
}
void convert(std::string &dest, bool source);
template < typename SourceType >
void convert(std::string &dest, SourceType source, typename std::enable_if<std::is_integral<SourceType>::value && !std::is_same<bool, SourceType>::value>::type* = nullptr)
{
std::array<char, 128> buffer{};
auto [ptr, ec] = std::to_chars(buffer.data(), buffer.data() + buffer.size(), source, 10);
if (ec == std::errc{}) {
dest.assign(buffer.data(), ptr);
} else {
throw std::logic_error("couldn't convert value to std::string");
}
}
template < typename SourceType >
void convert(std::string &dest, SourceType source, typename std::enable_if<std::is_floating_point<SourceType>::value>::type* = nullptr)
{
std::array<char, 128> buffer{};
auto [ptr, ec] = std::to_chars(buffer.data(), buffer.data() + buffer.size(), source);
if (ec == std::errc{}) {
dest.assign(buffer.data(), ptr);
} else {
throw std::logic_error("couldn't convert value to std::string");
}
}
void convert(std::string &dest, const char* source);
unsigned long long to_unsigned_long_long(const char *source);
template < typename DestType >
void convert(DestType &dest, const std::string &source, typename std::enable_if<std::is_integral<DestType>::value && std::is_unsigned<DestType>::value>::type* = nullptr)
{
dest = to_unsigned_long_long(source.c_str());
}
template < typename DestType >
void convert(DestType &dest, const char *source, typename std::enable_if<std::is_integral<DestType>::value && std::is_unsigned<DestType>::value>::type* = nullptr)
{
dest = to_unsigned_long_long(source);
}
long long to_long_long(const char *source);
template < typename DestType >
void convert(DestType &dest, const std::string &source, typename std::enable_if<std::is_integral<DestType>::value && std::is_signed<DestType>::value>::type* = nullptr)
{
dest = to_long_long(source.c_str());
}
template < typename DestType >
void convert(DestType &dest, const char *source, typename std::enable_if<std::is_integral<DestType>::value && std::is_signed<DestType>::value>::type* = nullptr)
{
dest = to_long_long(source);
}
long double to_double(const char *source);
template < typename DestType >
void convert(DestType &dest, const std::string &source, typename std::enable_if<std::is_floating_point<DestType>::value>::type* = nullptr)
{
dest = to_double(source.c_str());
}
template < typename DestType >
void convert(DestType &dest, const char *source, typename std::enable_if<std::is_floating_point<DestType>::value>::type* = nullptr)
{
dest = to_double(source);
}
template < typename DestType >
void convert(DestType &dest, bool source, typename std::enable_if<std::is_floating_point<DestType>::value>::type* = nullptr)
{
dest = static_cast<DestType>(source);
}
}
#endif //QUERY_CONVERT_HPP

View File

@ -1,8 +1,10 @@
#ifndef QUERY_TYPES_HPP #ifndef QUERY_DATA_TYPE_TRAITS_HPP
#define QUERY_TYPES_HPP #define QUERY_DATA_TYPE_TRAITS_HPP
#include "matador/sql/any_type.hpp" #include "matador/sql/any_type.hpp"
#include "matador/utils/types.hpp"
#include <cstdint> #include <cstdint>
#include <string> #include <string>
@ -205,6 +207,15 @@ template <> struct data_type_traits<std::string, void>
inline static any_type create_value(std::string &value) { return value; } inline static any_type create_value(std::string &value) { return value; }
}; };
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; }
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_result_value(result_parameter_binder &binder, size_t index, utils::blob &value);
inline static any_type create_value(utils::blob &value) { return value; }
};
//template <> struct data_type_traits<matador::date> //template <> struct data_type_traits<matador::date>
//{ //{
// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_date; } // inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_date; }
@ -242,4 +253,4 @@ struct data_type_traits<EnumType, typename std::enable_if<std::is_enum<EnumType>
/// @endcond /// @endcond
} }
#endif //QUERY_TYPES_HPP #endif //QUERY_DATA_TYPE_TRAITS_HPP

View File

@ -1,7 +1,7 @@
#ifndef QUERY_DIALECT_HPP #ifndef QUERY_DIALECT_HPP
#define QUERY_DIALECT_HPP #define QUERY_DIALECT_HPP
#include "matador/sql/types.hpp" #include "matador/sql/data_type_traits.hpp"
#include <cstdint> #include <cstdint>
#include <functional> #include <functional>
@ -26,11 +26,13 @@ public:
SELECT, SELECT,
TABLE, TABLE,
VALUES, VALUES,
INSERT_VALUES,
COLUMNS, COLUMNS,
COLUMN, COLUMN,
FROM, FROM,
INTO, INTO,
WHERE, WHERE,
WHERE_CLAUSE,
AND, AND,
OR, OR,
LIKE, LIKE,
@ -43,6 +45,7 @@ public:
OFFSET, OFFSET,
DISTINCT, DISTINCT,
SET, SET,
UPDATE_VALUES,
NOT_NULL, NOT_NULL,
PRIMARY_KEY, PRIMARY_KEY,
BEGIN, BEGIN,

View File

@ -2,7 +2,7 @@
#define QUERY_OBJECT_PARAMETER_BINDER_HPP #define QUERY_OBJECT_PARAMETER_BINDER_HPP
#include "matador/sql/parameter_binder.hpp" #include "matador/sql/parameter_binder.hpp"
#include "matador/sql/types.hpp" #include "matador/sql/data_type_traits.hpp"
#include "matador/utils/access.hpp" #include "matador/utils/access.hpp"
#include "matador/utils/cascade_type.hpp" #include "matador/utils/cascade_type.hpp"

View File

@ -28,6 +28,7 @@ public:
virtual void bind(size_t pos, const char *, size_t size) = 0; virtual void bind(size_t pos, const char *, size_t size) = 0;
virtual void bind(size_t pos, const std::string&) = 0; virtual void bind(size_t pos, const std::string&) = 0;
virtual void bind(size_t pos, const std::string &x, size_t size) = 0; virtual void bind(size_t pos, const std::string &x, size_t size) = 0;
virtual void bind(size_t pos, const utils::blob &) = 0;
// virtual void bind(size_t pos, const matador::time&) = 0; // virtual void bind(size_t pos, const matador::time&) = 0;
// virtual void bind(size_t pos, const matador::date&) = 0; // virtual void bind(size_t pos, const matador::date&) = 0;
}; };

View File

@ -3,6 +3,7 @@
#include "matador/sql/basic_condition.hpp" #include "matador/sql/basic_condition.hpp"
#include "matador/sql/column.hpp" #include "matador/sql/column.hpp"
#include "matador/sql/dialect.hpp"
#include "matador/sql/key_value_pair.hpp" #include "matador/sql/key_value_pair.hpp"
#include "matador/sql/query_context.hpp" #include "matador/sql/query_context.hpp"
#include "matador/sql/record.hpp" #include "matador/sql/record.hpp"
@ -10,12 +11,11 @@
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <utility>
#include <vector> #include <vector>
namespace matador::sql { namespace matador::sql {
class dialect;
namespace detail { namespace detail {
struct any_type_to_string_visitor struct any_type_to_string_visitor
{ {
@ -99,6 +99,15 @@ private:
REMOVE /**< Remove query command */ REMOVE /**< Remove query command */
}; };
struct query_part
{
query_part(dialect::token_t t, std::string p)
: token(t), part(std::move(p)) {}
dialect::token_t token;
std::string part;
};
public: public:
explicit query_builder(const dialect &d); explicit query_builder(const dialect &d);
@ -142,7 +151,7 @@ private:
command_t command_{command_t::UNKNOWN}; command_t command_{command_t::UNKNOWN};
state_t state_{state_t::QUERY_INIT}; state_t state_{state_t::QUERY_INIT};
std::vector<std::string> query_parts_; std::vector<query_part> query_parts_;
detail::any_type_to_string_visitor value_to_string_; detail::any_type_to_string_visitor value_to_string_;

View File

@ -7,7 +7,7 @@
#include "matador/sql/any_type.hpp" #include "matador/sql/any_type.hpp"
#include "matador/sql/query_result_reader.hpp" #include "matador/sql/query_result_reader.hpp"
#include "matador/sql/record.hpp" #include "matador/sql/record.hpp"
#include "matador/sql/types.hpp" #include "matador/sql/data_type_traits.hpp"
#include <memory> #include <memory>
#include <string> #include <string>

View File

@ -2,7 +2,7 @@
#define QUERY_QUERY_RESULT_READER_HPP #define QUERY_QUERY_RESULT_READER_HPP
#include "matador/sql/any_type.hpp" #include "matador/sql/any_type.hpp"
#include "matador/sql/types.hpp" #include "matador/sql/data_type_traits.hpp"
namespace matador::sql { namespace matador::sql {
@ -33,6 +33,7 @@ public:
virtual void read_value(const char *id, size_t index, char *value, size_t s); virtual void read_value(const char *id, size_t index, char *value, size_t s);
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, any_type &value, data_type_t type, size_t size); virtual void read_value(const char *id, size_t index, any_type &value, data_type_t type, size_t size);
}; };

View File

@ -6,7 +6,7 @@
#include "matador/utils/field_attributes.hpp" #include "matador/utils/field_attributes.hpp"
#include "matador/sql/any_type.hpp" #include "matador/sql/any_type.hpp"
#include "matador/sql/types.hpp" #include "matador/sql/data_type_traits.hpp"
#include <string> #include <string>

View File

@ -4,7 +4,7 @@
#include "matador/sql/query_context.hpp" #include "matador/sql/query_context.hpp"
#include "matador/sql/query_result_impl.hpp" #include "matador/sql/query_result_impl.hpp"
#include "matador/sql/parameter_binder.hpp" #include "matador/sql/parameter_binder.hpp"
#include "matador/sql/types.hpp" #include "matador/sql/data_type_traits.hpp"
#include <memory> #include <memory>

View File

@ -2,7 +2,7 @@
#define QUERY_VALUE_EXTRACTOR_HPP #define QUERY_VALUE_EXTRACTOR_HPP
#include "matador/sql/fk_value_extractor.hpp" #include "matador/sql/fk_value_extractor.hpp"
#include "matador/sql/types.hpp" #include "matador/sql/data_type_traits.hpp"
#include <vector> #include <vector>

View File

@ -0,0 +1,13 @@
#ifndef QUERY_UTILS_TYPES_HPP
#define QUERY_UTILS_TYPES_HPP
#include <vector>
namespace matador::utils {
using byte = unsigned char;
using blob = std::vector<byte>;
}
#endif //QUERY_UTILS_TYPES_HPP

View File

@ -17,7 +17,6 @@ set(SQL_SOURCES
sql/key_value_generator.cpp sql/key_value_generator.cpp
sql/fk_value_extractor.cpp sql/fk_value_extractor.cpp
sql/table_repository.cpp sql/table_repository.cpp
sql/any_type_to_visitor.cpp
sql/query_result.cpp sql/query_result.cpp
sql/query_result_reader.cpp sql/query_result_reader.cpp
sql/statement_cache.cpp sql/statement_cache.cpp
@ -25,15 +24,17 @@ set(SQL_SOURCES
sql/dialect_builder.cpp sql/dialect_builder.cpp
sql/object_parameter_binder.cpp sql/object_parameter_binder.cpp
sql/placeholder_generator.cpp sql/placeholder_generator.cpp
sql/types.cpp sql/data_type_traits.cpp
sql/result_parameter_binder.cpp sql/result_parameter_binder.cpp
sql/statement.cpp
sql/convert.cpp
) )
set(SQL_HEADER set(SQL_HEADER
../include/matador/sql/dialect.hpp ../include/matador/sql/dialect.hpp
../include/matador/sql/query_builder.hpp ../include/matador/sql/query_builder.hpp
../include/matador/sql/column.hpp ../include/matador/sql/column.hpp
../include/matador/sql/types.hpp ../include/matador/sql/data_type_traits.hpp
../include/matador/sql/key_value_pair.hpp ../include/matador/sql/key_value_pair.hpp
../include/matador/sql/basic_condition.hpp ../include/matador/sql/basic_condition.hpp
../include/matador/sql/condition.hpp ../include/matador/sql/condition.hpp
@ -62,12 +63,12 @@ set(SQL_HEADER
../include/matador/sql/statement.hpp ../include/matador/sql/statement.hpp
../include/matador/sql/statement_impl.hpp ../include/matador/sql/statement_impl.hpp
../include/matador/sql/query_context.hpp ../include/matador/sql/query_context.hpp
sql/statement.cpp
../include/matador/sql/parameter_binder.hpp ../include/matador/sql/parameter_binder.hpp
../include/matador/sql/dialect_builder.hpp ../include/matador/sql/dialect_builder.hpp
../include/matador/sql/object_parameter_binder.hpp ../include/matador/sql/object_parameter_binder.hpp
../include/matador/sql/placeholder_generator.hpp ../include/matador/sql/placeholder_generator.hpp
../include/matador/sql/result_parameter_binder.hpp ../include/matador/sql/result_parameter_binder.hpp
../include/matador/sql/convert.hpp
) )
set(UTILS_HEADER set(UTILS_HEADER
@ -80,7 +81,8 @@ set(UTILS_HEADER
../include/matador/utils/identifier.hpp ../include/matador/utils/identifier.hpp
../include/matador/utils/cascade_type.hpp ../include/matador/utils/cascade_type.hpp
../include/matador/utils/logger.hpp ../include/matador/utils/logger.hpp
../include/matador/utils/enum_mapper.hpp) ../include/matador/utils/enum_mapper.hpp
../include/matador/utils/types.hpp)
set(UTILS_SOURCES set(UTILS_SOURCES
utils/field_attributes.cpp utils/field_attributes.cpp

View File

@ -1,4 +1,6 @@
#include "matador/sql/any_type_to_visitor.hpp" #include "matador/sql/convert.hpp"
#include <cstring>
namespace matador::sql { namespace matador::sql {

View File

@ -1,4 +1,4 @@
#include "matador/sql/types.hpp" #include "matador/sql/data_type_traits.hpp"
#include "matador/sql/parameter_binder.hpp" #include "matador/sql/parameter_binder.hpp"
#include "matador/sql/query_result_reader.hpp" #include "matador/sql/query_result_reader.hpp"
@ -245,4 +245,19 @@ void data_type_traits<std::string, void>::bind_result_value(result_parameter_bin
{ {
binder.bind_result_value(index, value, size); binder.bind_result_value(index, value, size);
} }
void data_type_traits<utils::blob, void>::read_value(query_result_reader &reader, const char *id, size_t index, utils::blob &value)
{
}
void data_type_traits<utils::blob, void>::bind_value(parameter_binder &binder, size_t index, utils::blob &value)
{
}
void data_type_traits<utils::blob, void>::bind_result_value(result_parameter_binder &binder, size_t index, utils::blob &value)
{
}
} }

View File

@ -94,7 +94,7 @@ query_builder &query_builder::create()
{ {
initialize(command_t::CREATE, state_t::QUERY_CREATE); initialize(command_t::CREATE, state_t::QUERY_CREATE);
query_parts_.emplace_back(dialect_.token_at(dialect::token_t::CREATE)); query_parts_.emplace_back(dialect::token_t::CREATE, dialect_.token_at(dialect::token_t::CREATE));
return *this; return *this;
} }
@ -103,7 +103,7 @@ query_builder &query_builder::drop()
{ {
initialize(command_t::DROP, state_t::QUERY_DROP); initialize(command_t::DROP, state_t::QUERY_DROP);
query_parts_.emplace_back(dialect_.token_at(dialect::token_t::DROP)); query_parts_.emplace_back(dialect::token_t::DROP, dialect_.token_at(dialect::token_t::DROP));
return *this; return *this;
} }
@ -117,7 +117,7 @@ query_builder &query_builder::select(const std::vector<column> &columns)
{ {
initialize(command_t::SELECT, state_t::QUERY_SELECT); initialize(command_t::SELECT, state_t::QUERY_SELECT);
query_parts_.emplace_back(dialect_.token_at(dialect::token_t::SELECT) + " "); query_parts_.emplace_back(dialect::token_t::SELECT, dialect_.token_at(dialect::token_t::SELECT) + " ");
query_.prototype.clear(); query_.prototype.clear();
@ -141,7 +141,7 @@ query_builder &query_builder::select(const std::vector<column> &columns)
} }
} }
query_parts_.emplace_back(result); query_parts_.emplace_back(dialect::token_t::COLUMNS, result);
return *this; return *this;
} }
@ -149,7 +149,7 @@ query_builder &query_builder::insert()
{ {
initialize(command_t::INSERT, state_t::QUERY_INSERT); initialize(command_t::INSERT, state_t::QUERY_INSERT);
query_parts_.emplace_back(dialect_.token_at(dialect::token_t::INSERT)); query_parts_.emplace_back(dialect::token_t::INSERT, dialect_.token_at(dialect::token_t::INSERT));
return *this; return *this;
} }
@ -159,7 +159,7 @@ query_builder &query_builder::update(const std::string &table)
initialize(command_t::UPDATE, state_t::QUERY_UPDATE); initialize(command_t::UPDATE, state_t::QUERY_UPDATE);
query_.table_name = table; query_.table_name = table;
query_parts_.emplace_back(dialect_.token_at(dialect::token_t::UPDATE) + " " + dialect_.prepare_identifier(table)); query_parts_.emplace_back(dialect::token_t::UPDATE, dialect_.token_at(dialect::token_t::UPDATE) + " " + dialect_.prepare_identifier(table));
return *this; return *this;
} }
@ -168,7 +168,7 @@ query_builder &query_builder::remove()
{ {
initialize(command_t::REMOVE, state_t::QUERY_DELETE); initialize(command_t::REMOVE, state_t::QUERY_DELETE);
query_parts_.emplace_back(dialect_.token_at(dialect::token_t::REMOVE)); query_parts_.emplace_back(dialect::token_t::REMOVE, dialect_.token_at(dialect::token_t::REMOVE));
return *this; return *this;
} }
@ -197,7 +197,7 @@ query_builder &query_builder::table(const std::string &table, const std::vector<
{ {
transition_to(state_t::QUERY_TABLE_CREATE); transition_to(state_t::QUERY_TABLE_CREATE);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::TABLE) + " " + dialect_.prepare_identifier(table) + " "); query_parts_.emplace_back(dialect::token_t::TABLE, " " + dialect_.token_at(dialect::token_t::TABLE) + " " + dialect_.prepare_identifier(table) + " ");
query_.table_name = table; query_.table_name = table;
std::string result = "("; std::string result = "(";
@ -228,7 +228,7 @@ query_builder &query_builder::table(const std::string &table, const std::vector<
} }
result += ")"; result += ")";
query_parts_.emplace_back(result); query_parts_.emplace_back(dialect::token_t::COLUMNS, result);
return *this; return *this;
} }
@ -236,7 +236,7 @@ query_builder &query_builder::table(const std::string &table)
{ {
transition_to(state_t::QUERY_TABLE_DROP); transition_to(state_t::QUERY_TABLE_DROP);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::TABLE) + " " + dialect_.prepare_identifier(table)); query_parts_.emplace_back(dialect::token_t::TABLE, " " + dialect_.token_at(dialect::token_t::TABLE) + " " + dialect_.prepare_identifier(table));
query_.table_name = table; query_.table_name = table;
return *this; return *this;
@ -251,7 +251,7 @@ query_builder &query_builder::into(const std::string &table, const std::vector<s
{ {
transition_to(state_t::QUERY_INTO); transition_to(state_t::QUERY_INTO);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::INTO) + " " + dialect_.prepare_identifier(table) + " "); query_parts_.emplace_back(dialect::token_t::INTO, " " + dialect_.token_at(dialect::token_t::INTO) + " " + dialect_.prepare_identifier(table) + " ");
query_.table_name = table; query_.table_name = table;
std::string result{"("}; std::string result{"("};
@ -269,7 +269,7 @@ query_builder &query_builder::into(const std::string &table, const std::vector<s
} }
result += (")"); result += (")");
query_parts_.emplace_back(result); query_parts_.emplace_back(dialect::token_t::COLUMNS, result);
return *this; return *this;
} }
@ -282,7 +282,7 @@ query_builder &query_builder::values(const std::vector<any_type> &values)
{ {
transition_to(state_t::QUERY_VALUES); transition_to(state_t::QUERY_VALUES);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::VALUES) + " "); query_parts_.emplace_back(dialect::token_t::VALUES, " " + dialect_.token_at(dialect::token_t::VALUES) + " ");
std::string result{"("}; std::string result{"("};
if (values.size() < 2) { if (values.size() < 2) {
@ -307,7 +307,7 @@ query_builder &query_builder::values(const std::vector<any_type> &values)
} }
result += (")"); result += (")");
query_parts_.emplace_back(result); query_parts_.emplace_back(dialect::token_t::INSERT_VALUES, result);
return *this; return *this;
} }
@ -316,11 +316,11 @@ query_builder &query_builder::from(const std::string &table, const std::string &
transition_to(state_t::QUERY_FROM); transition_to(state_t::QUERY_FROM);
if (dialect_.default_schema_name().empty()) { if (dialect_.default_schema_name().empty()) {
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::FROM) + query_parts_.emplace_back(dialect::token_t::FROM, " " + dialect_.token_at(dialect::token_t::FROM) +
" " + dialect_.prepare_identifier(table) + " " + dialect_.prepare_identifier(table) +
(as.empty() ? "" : " " + as)); (as.empty() ? "" : " " + as));
} else { } else {
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::FROM) + query_parts_.emplace_back(dialect::token_t::FROM, " " + dialect_.token_at(dialect::token_t::FROM) +
" " + dialect_.prepare_identifier(dialect_.default_schema_name()) + " " + dialect_.prepare_identifier(dialect_.default_schema_name()) +
"." + dialect_.prepare_identifier(table) + "." + dialect_.prepare_identifier(table) +
(as.empty() ? "" : " " + as)); (as.empty() ? "" : " " + as));
@ -349,7 +349,7 @@ query_builder &query_builder::set(const std::vector<key_value_pair> &key_values)
{ {
transition_to(state_t::QUERY_SET); transition_to(state_t::QUERY_SET);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::SET) + " "); query_parts_.emplace_back(dialect::token_t::SET, " " + dialect_.token_at(dialect::token_t::SET) + " ");
std::string result; std::string result;
if (key_values.size() < 2) { if (key_values.size() < 2) {
@ -374,7 +374,7 @@ query_builder &query_builder::set(const std::vector<key_value_pair> &key_values)
} }
} }
query_parts_.emplace_back(result); query_parts_.emplace_back(dialect::token_t::UPDATE_VALUES, result);
return *this; return *this;
} }
@ -382,8 +382,8 @@ query_builder &query_builder::where(const basic_condition &cond)
{ {
transition_to(state_t::QUERY_WHERE); transition_to(state_t::QUERY_WHERE);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::WHERE) + " "); query_parts_.emplace_back(dialect::token_t::WHERE, " " + dialect_.token_at(dialect::token_t::WHERE) + " ");
query_parts_.emplace_back(cond.evaluate(const_cast<dialect &>(dialect_), query_)); query_parts_.emplace_back(dialect::token_t::WHERE_CLAUSE, cond.evaluate(const_cast<dialect &>(dialect_), query_));
return *this; return *this;
} }
@ -392,7 +392,7 @@ query_builder &query_builder::order_by(const std::string &column)
{ {
transition_to(state_t::QUERY_ORDER_BY); transition_to(state_t::QUERY_ORDER_BY);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::ORDER_BY) + " " + dialect_.prepare_identifier(column)); query_parts_.emplace_back(dialect::token_t::ORDER_BY, " " + dialect_.token_at(dialect::token_t::ORDER_BY) + " " + dialect_.prepare_identifier(column));
return *this; return *this;
} }
@ -401,7 +401,7 @@ query_builder &query_builder::group_by(const std::string &column)
{ {
transition_to(state_t::QUERY_GROUP_BY); transition_to(state_t::QUERY_GROUP_BY);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::GROUP_BY) + " " + dialect_.prepare_identifier(column)); query_parts_.emplace_back(dialect::token_t::GROUP_BY, " " + dialect_.token_at(dialect::token_t::GROUP_BY) + " " + dialect_.prepare_identifier(column));
return *this; return *this;
} }
@ -410,7 +410,7 @@ query_builder &query_builder::asc()
{ {
transition_to(state_t::QUERY_ORDER_DIRECTION); transition_to(state_t::QUERY_ORDER_DIRECTION);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::ASC)); query_parts_.emplace_back(dialect::token_t::ASC, " " + dialect_.token_at(dialect::token_t::ASC));
return *this; return *this;
} }
@ -419,7 +419,7 @@ query_builder &query_builder::desc()
{ {
transition_to(state_t::QUERY_ORDER_DIRECTION); transition_to(state_t::QUERY_ORDER_DIRECTION);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::DESC)); query_parts_.emplace_back(dialect::token_t::DESC, " " + dialect_.token_at(dialect::token_t::DESC));
return *this; return *this;
} }
@ -428,7 +428,7 @@ query_builder &query_builder::offset(size_t count)
{ {
transition_to(state_t::QUERY_OFFSET); transition_to(state_t::QUERY_OFFSET);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::OFFSET) + " " + std::to_string(count)); query_parts_.emplace_back(dialect::token_t::OFFSET, " " + dialect_.token_at(dialect::token_t::OFFSET) + " " + std::to_string(count));
return *this; return *this;
} }
@ -437,7 +437,7 @@ query_builder &query_builder::limit(size_t count)
{ {
transition_to(state_t::QUERY_LIMIT); transition_to(state_t::QUERY_LIMIT);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::LIMIT) + " " + std::to_string(count)); query_parts_.emplace_back(dialect::token_t::LIMIT, " " + dialect_.token_at(dialect::token_t::LIMIT) + " " + std::to_string(count));
return *this; return *this;
} }
@ -445,7 +445,7 @@ query_builder &query_builder::limit(size_t count)
query_context query_builder::compile() query_context query_builder::compile()
{ {
for (const auto &part: query_parts_) { for (const auto &part: query_parts_) {
query_.sql.append(part); query_.sql.append(part.part);
} }
query_.command_name = command_strings_[command_]; query_.command_name = command_strings_[command_];
return query_; return query_;

View File

@ -98,6 +98,11 @@ void query_result_reader::read_value(const char *id, size_t index, std::string &
value.assign(column(index)); value.assign(column(index));
} }
void query_result_reader::read_value(const char *id, size_t index, utils::blob &value)
{
}
template < typename Type > template < typename Type >
void convert(const char *valstr, sql::any_type &value) void convert(const char *valstr, sql::any_type &value)
{ {

View File

@ -32,7 +32,9 @@ add_executable(tests QueryBuilderTest.cpp
models/location.hpp models/location.hpp
TypeTraitsTest.cpp TypeTraitsTest.cpp
Databases.hpp Databases.hpp
models/optional.hpp) models/optional.hpp
ConvertTest.cpp)
target_link_libraries(tests PRIVATE target_link_libraries(tests PRIVATE
Catch2::Catch2WithMain Catch2::Catch2WithMain
matador matador

9
test/ConvertTest.cpp Normal file
View File

@ -0,0 +1,9 @@
#include <catch2/catch_test_macros.hpp>
#include "matador/sql/convert.hpp"
using namespace matador::sql;
TEST_CASE("Test convert function", "[convert]") {
}

View File

@ -3,6 +3,7 @@
#include "matador/utils/access.hpp" #include "matador/utils/access.hpp"
#include "matador/utils/field_attributes.hpp" #include "matador/utils/field_attributes.hpp"
#include "matador/utils/types.hpp"
#include <string> #include <string>
@ -13,6 +14,7 @@ struct person
unsigned long id{}; unsigned long id{};
std::string name; std::string name;
unsigned int age{}; unsigned int age{};
utils::blob image;
template<class Operator> template<class Operator>
void process(Operator &op) { void process(Operator &op) {
@ -21,6 +23,7 @@ struct person
field::primary_key(op, "id", id); field::primary_key(op, "id", id);
field::attribute(op, "name", name, 255); field::attribute(op, "name", name, 255);
field::attribute(op, "age", age); field::attribute(op, "age", age);
field::attribute(op, "image", image);
} }
}; };