mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-15 20:31:16 +08:00
Merge branch 'feature/prepared_statements' into develop
This commit is contained in:
commit
46b4ac349e
@ -41,13 +41,9 @@ namespace sqlpp
|
|||||||
template<typename T>\
|
template<typename T>\
|
||||||
struct _member_t\
|
struct _member_t\
|
||||||
{\
|
{\
|
||||||
template<typename... TT>\
|
|
||||||
_member_t(TT&&... t): name(std::forward<TT>(t)...) {}\
|
|
||||||
\
|
|
||||||
template<typename TT>\
|
|
||||||
_member_t& operator=(TT&& t) { name = std::forward<TT>(t); return *this; }\
|
|
||||||
\
|
|
||||||
T name;\
|
T name;\
|
||||||
|
T& operator()() { return name; }\
|
||||||
|
const T& operator()() const { return name; }\
|
||||||
};\
|
};\
|
||||||
};\
|
};\
|
||||||
};\
|
};\
|
||||||
|
@ -52,6 +52,8 @@ namespace sqlpp
|
|||||||
struct _member_t
|
struct _member_t
|
||||||
{
|
{
|
||||||
T any;
|
T any;
|
||||||
|
T& operator()() { return any; }
|
||||||
|
const T& operator()() const { return any; }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _is_assignment_list = std::true_type;
|
using _is_assignment_list = std::true_type;
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
using _parameter_tuple_t = std::tuple<Assignments...>;
|
||||||
|
|
||||||
// check for at least one order expression
|
// check for at least one order expression
|
||||||
static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one assignment expression required in set()");
|
static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one assignment expression required in set()");
|
||||||
@ -70,7 +71,13 @@ namespace sqlpp
|
|||||||
_dynamic_assignments.serialize(os, db, sizeof...(Assignments) == 0);
|
_dynamic_assignments.serialize(os, db, sizeof...(Assignments) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<typename std::decay<Assignments>::type...> _assignments;
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
index = set_parameter_index(_assignments, index);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
_parameter_tuple_t _assignments;
|
||||||
typename detail::serializable_list<Database> _dynamic_assignments;
|
typename detail::serializable_list<Database> _dynamic_assignments;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,6 +51,8 @@ namespace sqlpp
|
|||||||
struct _member_t
|
struct _member_t
|
||||||
{
|
{
|
||||||
T avg;
|
T avg;
|
||||||
|
T& operator()() { return avg; }
|
||||||
|
const T& operator()() const { return avg; }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <sqlpp11/detail/basic_operators.h>
|
#include <sqlpp11/detail/basic_operators.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/raw_result_row.h>
|
|
||||||
#include <sqlpp11/exception.h>
|
#include <sqlpp11/exception.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
@ -50,12 +49,6 @@ namespace sqlpp
|
|||||||
static constexpr const char* _name = "AND";
|
static constexpr const char* _name = "AND";
|
||||||
};
|
};
|
||||||
|
|
||||||
struct not_
|
|
||||||
{
|
|
||||||
using _value_type = boolean;
|
|
||||||
static constexpr const char* _name = "NOT";
|
|
||||||
};
|
|
||||||
|
|
||||||
// boolean value type
|
// boolean value type
|
||||||
struct boolean
|
struct boolean
|
||||||
{
|
{
|
||||||
@ -63,30 +56,108 @@ namespace sqlpp
|
|||||||
using _is_boolean = std::true_type;
|
using _is_boolean = std::true_type;
|
||||||
using _is_value = std::true_type;
|
using _is_value = std::true_type;
|
||||||
using _is_expression = std::true_type;
|
using _is_expression = std::true_type;
|
||||||
|
using _cpp_value_type = bool;
|
||||||
|
|
||||||
struct plus_
|
struct _parameter_t
|
||||||
{
|
{
|
||||||
using _value_type = boolean;
|
using _value_type = boolean;
|
||||||
static constexpr const char* _name = "+";
|
|
||||||
};
|
|
||||||
|
|
||||||
template<size_t index>
|
_parameter_t(const std::true_type&):
|
||||||
struct _result_entry_t
|
_trivial_value_is_null(true),
|
||||||
{
|
_value(false),
|
||||||
_result_entry_t(const raw_result_row_t& row):
|
_is_null(_trivial_value_is_null and _is_trivial())
|
||||||
_is_valid(row.data != nullptr),
|
|
||||||
_is_null(row.data == nullptr or row.data[index] == nullptr),
|
|
||||||
_value(_is_null ? false : (std::strtoll(row.data[index], nullptr, 10) != 0))
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
_result_entry_t& operator=(const raw_result_row_t& row)
|
_parameter_t(const std::false_type&):
|
||||||
|
_trivial_value_is_null(false),
|
||||||
|
_value(false),
|
||||||
|
_is_null(_trivial_value_is_null and _is_trivial())
|
||||||
|
{}
|
||||||
|
|
||||||
|
_parameter_t(const _cpp_value_type& value):
|
||||||
|
_value(value),
|
||||||
|
_is_null(_trivial_value_is_null and _is_trivial())
|
||||||
|
{}
|
||||||
|
|
||||||
|
_parameter_t& operator=(const _cpp_value_type& value)
|
||||||
{
|
{
|
||||||
_is_valid = (row.data != nullptr);
|
_value = value;
|
||||||
_is_null = row.data == nullptr or row.data[index] == nullptr;
|
_is_null = (_trivial_value_is_null and _is_trivial());
|
||||||
_value = _is_null ? false : (std::strtoll(row.data[index], nullptr, 10) != 0);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_parameter_t& operator=(const std::nullptr_t&)
|
||||||
|
{
|
||||||
|
_value = false;
|
||||||
|
_is_null = true;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Db>
|
||||||
|
void serialize(std::ostream& os, Db& db) const
|
||||||
|
{
|
||||||
|
os << value();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _is_trivial() const { return value() == false; }
|
||||||
|
|
||||||
|
bool is_null() const
|
||||||
|
{
|
||||||
|
return _is_null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_cpp_value_type value() const
|
||||||
|
{
|
||||||
|
return _value;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator _cpp_value_type() const { return value(); }
|
||||||
|
|
||||||
|
template<typename Target>
|
||||||
|
void bind(Target& target, size_t index) const
|
||||||
|
{
|
||||||
|
target.bind_boolean_parameter(index, &_value, _is_null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _trivial_value_is_null;
|
||||||
|
signed char _value;
|
||||||
|
bool _is_null;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _result_entry_t
|
||||||
|
{
|
||||||
|
_result_entry_t():
|
||||||
|
_is_valid(false),
|
||||||
|
_is_null(true),
|
||||||
|
_value(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
_result_entry_t(const char* data, size_t):
|
||||||
|
_is_valid(true),
|
||||||
|
_is_null(data == nullptr),
|
||||||
|
_value(_is_null ? false : (data[0] == 't' or data[0] == '1'))
|
||||||
|
{}
|
||||||
|
|
||||||
|
void assign(const char* data, size_t)
|
||||||
|
{
|
||||||
|
_is_valid = true;
|
||||||
|
_is_null = data == nullptr;
|
||||||
|
_value = _is_null ? false : (data[0] == 't' or data[0] == '1');
|
||||||
|
}
|
||||||
|
|
||||||
|
void validate()
|
||||||
|
{
|
||||||
|
_is_valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void invalidate()
|
||||||
|
{
|
||||||
|
_is_valid = false;
|
||||||
|
_is_null = true;
|
||||||
|
_value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
void serialize(std::ostream& os, Db& db) const
|
void serialize(std::ostream& os, Db& db) const
|
||||||
{
|
{
|
||||||
@ -102,19 +173,25 @@ namespace sqlpp
|
|||||||
return _is_null;
|
return _is_null;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool value() const
|
_cpp_value_type value() const
|
||||||
{
|
{
|
||||||
if (not _is_valid)
|
if (not _is_valid)
|
||||||
throw exception("accessing value in non-existing row");
|
throw exception("accessing value in non-existing row");
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator bool() const { return value(); }
|
operator _cpp_value_type() const { return value(); }
|
||||||
|
|
||||||
|
template<typename Target>
|
||||||
|
void bind(Target& target, size_t i)
|
||||||
|
{
|
||||||
|
target.bind_boolean_result(i, &_value, &_is_null);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _is_valid;
|
bool _is_valid;
|
||||||
bool _is_null;
|
bool _is_null;
|
||||||
bool _value;
|
signed char _value;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -145,8 +222,7 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template<size_t index>
|
inline std::ostream& operator<<(std::ostream& os, const boolean::_result_entry_t& e)
|
||||||
std::ostream& operator<<(std::ostream& os, const boolean::_result_entry_t<index>& e)
|
|
||||||
{
|
{
|
||||||
return os << e.value();
|
return os << e.value();
|
||||||
}
|
}
|
||||||
|
@ -24,17 +24,17 @@
|
|||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SQLPP_RAW_RESULT_ROW_H
|
#ifndef SQLPP_CHAR_RESULT_ROW_H
|
||||||
#define SQLPP_RAW_RESULT_ROW_H
|
#define SQLPP_CHAR_RESULT_ROW_H
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
struct raw_result_row_t
|
struct char_result_row_t
|
||||||
{
|
{
|
||||||
const char** data;
|
char** data;
|
||||||
const size_t* len;
|
size_t* len;
|
||||||
|
|
||||||
bool operator==(const raw_result_row_t& rhs) const
|
bool operator==(const char_result_row_t& rhs) const
|
||||||
{
|
{
|
||||||
return data == rhs.data and len == rhs.len;
|
return data == rhs.data and len == rhs.len;
|
||||||
}
|
}
|
@ -51,6 +51,8 @@ namespace sqlpp
|
|||||||
struct _member_t
|
struct _member_t
|
||||||
{
|
{
|
||||||
T count;
|
T count;
|
||||||
|
T& operator()() { return count; }
|
||||||
|
const T& operator()() const { return count; }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <sqlpp11/parameter_list.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -65,6 +66,7 @@ namespace sqlpp
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct _impl_t: public _impl_base
|
struct _impl_t: public _impl_base
|
||||||
{
|
{
|
||||||
|
static_assert(not make_parameter_list_t<T>::type::size::value, "parameters not supported in dynamic query parts");
|
||||||
_impl_t(const T& t):
|
_impl_t(const T& t):
|
||||||
_t(t)
|
_t(t)
|
||||||
{}
|
{}
|
||||||
|
@ -51,6 +51,8 @@ namespace sqlpp
|
|||||||
struct _member_t
|
struct _member_t
|
||||||
{
|
{
|
||||||
T exists;
|
T exists;
|
||||||
|
T& operator()() { return exists; }
|
||||||
|
const T& operator()() const { return exists; }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <sqlpp11/detail/serialize_tuple.h>
|
#include <sqlpp11/detail/serialize_tuple.h>
|
||||||
#include <sqlpp11/alias.h>
|
#include <sqlpp11/alias.h>
|
||||||
#include <sqlpp11/noop.h>
|
#include <sqlpp11/noop.h>
|
||||||
|
#include <sqlpp11/parameter_list.h> // FIXME: a forward for set_parameter_index would be nice here
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -40,6 +41,14 @@ namespace sqlpp
|
|||||||
using _is_assignment = std::true_type;
|
using _is_assignment = std::true_type;
|
||||||
using column_type = Lhs;
|
using column_type = Lhs;
|
||||||
using value_type = Rhs;
|
using value_type = Rhs;
|
||||||
|
using _parameter_tuple_t = std::tuple<Lhs, Rhs>;
|
||||||
|
|
||||||
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
index = set_parameter_index(_lhs, index);
|
||||||
|
index = set_parameter_index(_rhs, index);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
void serialize(std::ostream& os, Db& db) const
|
void serialize(std::ostream& os, Db& db) const
|
||||||
@ -64,6 +73,13 @@ namespace sqlpp
|
|||||||
struct equal_t: public ValueType::template operators<equal_t<Lhs, Rhs>>
|
struct equal_t: public ValueType::template operators<equal_t<Lhs, Rhs>>
|
||||||
{
|
{
|
||||||
using _value_type = ValueType;
|
using _value_type = ValueType;
|
||||||
|
using _parameter_tuple_t = std::tuple<Lhs, Rhs>;
|
||||||
|
|
||||||
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
index = set_parameter_index(_lhs, index);
|
||||||
|
return set_parameter_index(_rhs, index);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename L, typename R>
|
template<typename L, typename R>
|
||||||
equal_t(L&& l, R&& r):
|
equal_t(L&& l, R&& r):
|
||||||
@ -103,6 +119,13 @@ namespace sqlpp
|
|||||||
struct not_equal_t: public ValueType::template operators<not_equal_t<Lhs, Rhs>>
|
struct not_equal_t: public ValueType::template operators<not_equal_t<Lhs, Rhs>>
|
||||||
{
|
{
|
||||||
using _value_type = ValueType;
|
using _value_type = ValueType;
|
||||||
|
using _parameter_tuple_t = std::tuple<Lhs, Rhs>;
|
||||||
|
|
||||||
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
index = set_parameter_index(_lhs, index);
|
||||||
|
return set_parameter_index(_rhs, index);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename L, typename R>
|
template<typename L, typename R>
|
||||||
not_equal_t(L&& l, R&& r):
|
not_equal_t(L&& l, R&& r):
|
||||||
@ -142,10 +165,15 @@ namespace sqlpp
|
|||||||
struct not_t: public ValueType::template operators<not_t<Lhs>>
|
struct not_t: public ValueType::template operators<not_t<Lhs>>
|
||||||
{
|
{
|
||||||
using _value_type = ValueType;
|
using _value_type = ValueType;
|
||||||
|
using _parameter_tuple_t = std::tuple<Lhs>;
|
||||||
|
|
||||||
template<typename L>
|
size_t _set_parameter_index(size_t index)
|
||||||
not_t(L&& l):
|
{
|
||||||
_lhs(std::forward<L>(l))
|
return set_parameter_index(_lhs, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
not_t(Lhs l):
|
||||||
|
_lhs(l)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
not_t(const not_t&) = default;
|
not_t(const not_t&) = default;
|
||||||
@ -179,6 +207,13 @@ namespace sqlpp
|
|||||||
struct binary_expression_t: public O::_value_type::template operators<binary_expression_t<Lhs, O, Rhs>>
|
struct binary_expression_t: public O::_value_type::template operators<binary_expression_t<Lhs, O, Rhs>>
|
||||||
{
|
{
|
||||||
using _value_type = typename O::_value_type;
|
using _value_type = typename O::_value_type;
|
||||||
|
using _parameter_tuple_t = std::tuple<Lhs, Rhs>;
|
||||||
|
|
||||||
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
index = set_parameter_index(_lhs, index);
|
||||||
|
return set_parameter_index(_rhs, index);
|
||||||
|
}
|
||||||
|
|
||||||
binary_expression_t(Lhs&& l, Rhs&& r):
|
binary_expression_t(Lhs&& l, Rhs&& r):
|
||||||
_lhs(std::move(l)),
|
_lhs(std::move(l)),
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <sqlpp11/detail/basic_operators.h>
|
#include <sqlpp11/detail/basic_operators.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/raw_result_row.h>
|
#include <sqlpp11/char_result_row.h> // FIXME: Need to update floating_point
|
||||||
#include <sqlpp11/exception.h>
|
#include <sqlpp11/exception.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
@ -46,25 +46,110 @@ namespace sqlpp
|
|||||||
using _is_floating_point = std::true_type;
|
using _is_floating_point = std::true_type;
|
||||||
using _is_value = std::true_type;
|
using _is_value = std::true_type;
|
||||||
using _is_expression = std::true_type;
|
using _is_expression = std::true_type;
|
||||||
|
using _cpp_value_type = double;
|
||||||
|
|
||||||
template<size_t index>
|
struct _parameter_t
|
||||||
struct _result_entry_t
|
|
||||||
{
|
{
|
||||||
using _value_type = floating_point;
|
using _value_type = integral;
|
||||||
_result_entry_t(const raw_result_row_t& row):
|
|
||||||
_is_valid(row.data != nullptr),
|
_parameter_t(const std::true_type&):
|
||||||
_is_null(row.data == nullptr or row.data[index] == nullptr),
|
_trivial_value_is_null(true),
|
||||||
_value(_is_null ? 0 : std::strtod(row.data[index], nullptr))
|
_value(0),
|
||||||
|
_is_null(_trivial_value_is_null and _is_trivial())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
_result_entry_t& operator=(const raw_result_row_t& row)
|
_parameter_t(const std::false_type&):
|
||||||
|
_trivial_value_is_null(false),
|
||||||
|
_value(0),
|
||||||
|
_is_null(_trivial_value_is_null and _is_trivial())
|
||||||
|
{}
|
||||||
|
|
||||||
|
_parameter_t(const _cpp_value_type& value):
|
||||||
|
_value(value),
|
||||||
|
_is_null(_trivial_value_is_null and _is_trivial())
|
||||||
|
{}
|
||||||
|
|
||||||
|
_parameter_t& operator=(const _cpp_value_type& value)
|
||||||
{
|
{
|
||||||
_is_valid = (row.data != nullptr);
|
_value = value;
|
||||||
_is_null = row.data == nullptr or row.data[index] == nullptr;
|
_is_null = (_trivial_value_is_null and _is_trivial());
|
||||||
_value = _is_null ? 0 : std::strtod(row.data[index], nullptr);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_parameter_t& operator=(const std::nullptr_t&)
|
||||||
|
{
|
||||||
|
_value = 0;
|
||||||
|
_is_null = true;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Db>
|
||||||
|
void serialize(std::ostream& os, Db& db) const
|
||||||
|
{
|
||||||
|
os << value();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _is_trivial() const { return value() == 0; }
|
||||||
|
|
||||||
|
bool is_null() const
|
||||||
|
{
|
||||||
|
return _is_null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const _cpp_value_type& value() const
|
||||||
|
{
|
||||||
|
return _value;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator _cpp_value_type() const { return _value; }
|
||||||
|
|
||||||
|
template<typename Target>
|
||||||
|
void bind(Target& target, size_t index) const
|
||||||
|
{
|
||||||
|
target.bind_floating_point_parameter(index, &_value, _is_null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _trivial_value_is_null;
|
||||||
|
_cpp_value_type _value;
|
||||||
|
bool _is_null;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _result_entry_t
|
||||||
|
{
|
||||||
|
using _value_type = integral;
|
||||||
|
|
||||||
|
_result_entry_t():
|
||||||
|
_is_valid(false),
|
||||||
|
_is_null(true),
|
||||||
|
_value(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
_result_entry_t(const char* data, size_t):
|
||||||
|
_is_valid(true),
|
||||||
|
_is_null(data == nullptr),
|
||||||
|
_value(_is_null ? 0 : std::strtoll(data, nullptr, 10))
|
||||||
|
{}
|
||||||
|
|
||||||
|
void assign(const char* data, size_t)
|
||||||
|
{
|
||||||
|
_is_valid = true;
|
||||||
|
_is_null = data == nullptr;
|
||||||
|
_value = _is_null ? 0 : std::strtoll(data, nullptr, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void validate()
|
||||||
|
{
|
||||||
|
_is_valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void invalidate()
|
||||||
|
{
|
||||||
|
_is_valid = false;
|
||||||
|
_is_null = true;
|
||||||
|
_value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
void serialize(std::ostream& os, Db& db) const
|
void serialize(std::ostream& os, Db& db) const
|
||||||
{
|
{
|
||||||
@ -80,19 +165,25 @@ namespace sqlpp
|
|||||||
return _is_null;
|
return _is_null;
|
||||||
}
|
}
|
||||||
|
|
||||||
double value() const
|
_cpp_value_type value() const
|
||||||
{
|
{
|
||||||
if (not _is_valid)
|
if (not _is_valid)
|
||||||
throw exception("accessing value in non-existing row");
|
throw exception("accessing value in non-existing row");
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator double() const { return value(); }
|
operator _cpp_value_type() const { return value(); }
|
||||||
|
|
||||||
|
template<typename Target>
|
||||||
|
void bind(Target& target, size_t i)
|
||||||
|
{
|
||||||
|
target.bind_floating_point_result(i, &_value, &_is_null);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _is_valid;
|
bool _is_valid;
|
||||||
bool _is_null;
|
bool _is_null;
|
||||||
double _value;
|
_cpp_value_type _value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct plus_
|
struct plus_
|
||||||
@ -181,8 +272,7 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template<size_t index>
|
inline std::ostream& operator<<(std::ostream& os, const floating_point::_result_entry_t& e)
|
||||||
std::ostream& operator<<(std::ostream& os, const floating_point::_result_entry_t<index>& e)
|
|
||||||
{
|
{
|
||||||
return os << e.value();
|
return os << e.value();
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ namespace sqlpp
|
|||||||
using _valid_expressions = typename detail::make_set_if<is_table_t, TableOrJoin...>::type;
|
using _valid_expressions = typename detail::make_set_if<is_table_t, TableOrJoin...>::type;
|
||||||
static_assert(_valid_expressions::size::value == sizeof...(TableOrJoin), "at least one argument is not a table or join in from()");
|
static_assert(_valid_expressions::size::value == sizeof...(TableOrJoin), "at least one argument is not a table or join in from()");
|
||||||
|
|
||||||
// FIXME: Joins contain two tables. This is not being dealt with at the moment
|
// FIXME: Joins contain two tables. This is not being dealt with at the moment when looking at duplicates, for instance
|
||||||
|
|
||||||
|
|
||||||
template<typename Table>
|
template<typename Table>
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
#define SQLPP_FUNCTIONS_H
|
#define SQLPP_FUNCTIONS_H
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <sqlpp11/parameter.h>
|
||||||
|
#include <sqlpp11/parameter_list.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/column_types.h>
|
#include <sqlpp11/column_types.h>
|
||||||
#include <sqlpp11/exists.h>
|
#include <sqlpp11/exists.h>
|
||||||
|
@ -43,6 +43,7 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _is_group_by = std::true_type;
|
using _is_group_by = std::true_type;
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
using _parameter_tuple_t = std::tuple<Expr...>;
|
||||||
|
|
||||||
// ensure one argument at least
|
// ensure one argument at least
|
||||||
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression (e.g. a column) required in group_by()");
|
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression (e.g. a column) required in group_by()");
|
||||||
@ -73,7 +74,13 @@ namespace sqlpp
|
|||||||
_dynamic_expressions.serialize(os, db, sizeof...(Expr) == 0);
|
_dynamic_expressions.serialize(os, db, sizeof...(Expr) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<Expr...> _expressions;
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
index = set_parameter_index(_expressions, index);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
_parameter_tuple_t _expressions;
|
||||||
detail::serializable_list<Database> _dynamic_expressions;
|
detail::serializable_list<Database> _dynamic_expressions;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -41,11 +41,15 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _is_having = std::true_type;
|
using _is_having = std::true_type;
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
using _parameter_tuple_t = std::tuple<Expr...>;
|
||||||
|
|
||||||
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in having()");
|
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in having()");
|
||||||
using _valid_expressions = typename detail::make_set_if<is_expression_t, Expr...>::type;
|
using _valid_expressions = typename detail::make_set_if<is_expression_t, Expr...>::type;
|
||||||
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in having()");
|
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in having()");
|
||||||
|
|
||||||
|
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
|
||||||
|
static_assert(not _parameter_list_t::_contains_trivial_value_is_null_t::value, "must not use trivial_value_is_null in parameters of having expression, use where_parameter() instead of parameter() to turn off automatic conversion");
|
||||||
|
|
||||||
template<typename E>
|
template<typename E>
|
||||||
void add(E&& expr)
|
void add(E&& expr)
|
||||||
{
|
{
|
||||||
@ -65,7 +69,13 @@ namespace sqlpp
|
|||||||
_dynamic_expressions.serialize(os, db, " AND ", sizeof...(Expr) == 0);
|
_dynamic_expressions.serialize(os, db, " AND ", sizeof...(Expr) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<Expr...> _expressions;
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
index = set_parameter_index(_expressions, index);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
_parameter_tuple_t _expressions;
|
||||||
detail::serializable_list<Database> _dynamic_expressions;
|
detail::serializable_list<Database> _dynamic_expressions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -32,6 +32,9 @@
|
|||||||
#include <sqlpp11/select_fwd.h>
|
#include <sqlpp11/select_fwd.h>
|
||||||
#include <sqlpp11/insert_list.h>
|
#include <sqlpp11/insert_list.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
|
#include <sqlpp11/parameter_list.h>
|
||||||
|
#include <sqlpp11/prepared_insert.h>
|
||||||
|
|
||||||
#include <sqlpp11/detail/serialize_tuple.h>
|
#include <sqlpp11/detail/serialize_tuple.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
@ -56,6 +59,9 @@ namespace sqlpp
|
|||||||
template<typename AssignmentT>
|
template<typename AssignmentT>
|
||||||
using set_insert_list_t = insert_t<Database, Table, AssignmentT>;
|
using set_insert_list_t = insert_t<Database, Table, AssignmentT>;
|
||||||
|
|
||||||
|
using _parameter_tuple_t = std::tuple<Table, InsertList>;
|
||||||
|
using _parameter_list_t = typename make_parameter_list_t<insert_t>::type;
|
||||||
|
|
||||||
template<typename... Assignment>
|
template<typename... Assignment>
|
||||||
auto set(Assignment&&... assignment)
|
auto set(Assignment&&... assignment)
|
||||||
-> set_insert_list_t<insert_list_t<void, must_not_insert_t, typename std::decay<Assignment>::type...>>
|
-> set_insert_list_t<insert_list_t<void, must_not_insert_t, typename std::decay<Assignment>::type...>>
|
||||||
@ -112,17 +118,46 @@ namespace sqlpp
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static constexpr size_t _get_static_no_of_parameters()
|
||||||
|
{
|
||||||
|
return _parameter_list_t::size::value;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t _get_no_of_parameters()
|
||||||
|
{
|
||||||
|
return _parameter_list_t::size::value; // FIXME: Need to add dynamic parameters here
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
std::size_t run(Db& db) const
|
std::size_t run(Db& db) const
|
||||||
{
|
{
|
||||||
constexpr bool calledSet = not is_noop<InsertList>::value;
|
constexpr bool calledSet = not is_noop<InsertList>::value;
|
||||||
constexpr bool requireSet = Table::_required_insert_columns::size::value > 0;
|
constexpr bool requireSet = Table::_required_insert_columns::size::value > 0;
|
||||||
static_assert(calledSet or not requireSet, "calling set() required for given table");
|
static_assert(calledSet or not requireSet, "calling set() required for given table");
|
||||||
std::ostringstream oss;
|
static_assert(_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead");
|
||||||
serialize(oss, db);
|
return db.insert(*this);
|
||||||
return db.insert(oss.str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Db>
|
||||||
|
auto prepare(Db& db)
|
||||||
|
-> prepared_insert_t<typename std::decay<Db>::type, insert_t>
|
||||||
|
{
|
||||||
|
constexpr bool calledSet = not is_noop<InsertList>::value;
|
||||||
|
constexpr bool requireSet = Table::_required_insert_columns::size::value > 0;
|
||||||
|
static_assert(calledSet or not requireSet, "calling set() required for given table");
|
||||||
|
|
||||||
|
_set_parameter_index(0);
|
||||||
|
return {{}, db.prepare_insert(*this)};
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
index = set_parameter_index(_table, index);
|
||||||
|
index = set_parameter_index(_insert_list, index);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Table _table;
|
Table _table;
|
||||||
InsertList _insert_list;
|
InsertList _insert_list;
|
||||||
};
|
};
|
||||||
|
@ -63,6 +63,7 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _is_insert_list = std::true_type;
|
using _is_insert_list = std::true_type;
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
using _parameter_tuple_t = std::tuple<typename Assignments::value_type...>;
|
||||||
|
|
||||||
// check for at least one order expression
|
// check for at least one order expression
|
||||||
static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one select expression required in set()");
|
static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one select expression required in set()");
|
||||||
@ -119,8 +120,14 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
index = set_parameter_index(_values, index);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
std::tuple<detail::insert_column<typename Assignments::column_type>...> _columns;
|
std::tuple<detail::insert_column<typename Assignments::column_type>...> _columns;
|
||||||
std::tuple<typename Assignments::value_type...> _values;
|
_parameter_tuple_t _values;
|
||||||
typename detail::serializable_list<Database> _dynamic_columns;
|
typename detail::serializable_list<Database> _dynamic_columns;
|
||||||
typename detail::serializable_list<Database> _dynamic_values;
|
typename detail::serializable_list<Database> _dynamic_values;
|
||||||
};
|
};
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <sqlpp11/detail/basic_operators.h>
|
#include <sqlpp11/detail/basic_operators.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/raw_result_row.h>
|
|
||||||
#include <sqlpp11/exception.h>
|
#include <sqlpp11/exception.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
@ -46,23 +45,107 @@ namespace sqlpp
|
|||||||
using _is_integral = std::true_type;
|
using _is_integral = std::true_type;
|
||||||
using _is_value = std::true_type;
|
using _is_value = std::true_type;
|
||||||
using _is_expression = std::true_type;
|
using _is_expression = std::true_type;
|
||||||
|
using _cpp_value_type = int64_t;
|
||||||
|
|
||||||
template<size_t index>
|
struct _parameter_t
|
||||||
|
{
|
||||||
|
using _value_type = integral;
|
||||||
|
|
||||||
|
_parameter_t(const std::true_type&):
|
||||||
|
_trivial_value_is_null(true),
|
||||||
|
_value(0),
|
||||||
|
_is_null(_trivial_value_is_null and _is_trivial())
|
||||||
|
{}
|
||||||
|
|
||||||
|
_parameter_t(const std::false_type&):
|
||||||
|
_trivial_value_is_null(false),
|
||||||
|
_value(0),
|
||||||
|
_is_null(_trivial_value_is_null and _is_trivial())
|
||||||
|
{}
|
||||||
|
|
||||||
|
explicit _parameter_t(const _cpp_value_type& value):
|
||||||
|
_value(value),
|
||||||
|
_is_null(_trivial_value_is_null and _is_trivial())
|
||||||
|
{}
|
||||||
|
|
||||||
|
_parameter_t& operator=(const _cpp_value_type& value)
|
||||||
|
{
|
||||||
|
_value = value;
|
||||||
|
_is_null = (_trivial_value_is_null and _is_trivial());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_null()
|
||||||
|
{
|
||||||
|
_value = 0;
|
||||||
|
_is_null = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Db>
|
||||||
|
void serialize(std::ostream& os, Db& db) const
|
||||||
|
{
|
||||||
|
os << value();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _is_trivial() const { return value() == 0; }
|
||||||
|
|
||||||
|
bool is_null() const
|
||||||
|
{
|
||||||
|
return _is_null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const _cpp_value_type& value() const
|
||||||
|
{
|
||||||
|
return _value;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator _cpp_value_type() const { return _value; }
|
||||||
|
|
||||||
|
template<typename Target>
|
||||||
|
void bind(Target& target, size_t index) const
|
||||||
|
{
|
||||||
|
target.bind_integral_parameter(index, &_value, _is_null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _trivial_value_is_null;
|
||||||
|
_cpp_value_type _value;
|
||||||
|
bool _is_null;
|
||||||
|
};
|
||||||
|
|
||||||
struct _result_entry_t
|
struct _result_entry_t
|
||||||
{
|
{
|
||||||
using _value_type = integral;
|
using _value_type = integral;
|
||||||
_result_entry_t(const raw_result_row_t& row):
|
|
||||||
_is_valid(row.data != nullptr),
|
_result_entry_t():
|
||||||
_is_null(row.data == nullptr or row.data[index] == nullptr),
|
_is_valid(false),
|
||||||
_value(_is_null ? 0 : std::strtoll(row.data[index], nullptr, 10))
|
_is_null(true),
|
||||||
|
_value(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
_result_entry_t& operator=(const raw_result_row_t& row)
|
_result_entry_t(const char* data, size_t):
|
||||||
|
_is_valid(true),
|
||||||
|
_is_null(data == nullptr),
|
||||||
|
_value(_is_null ? 0 : std::strtoll(data, nullptr, 10))
|
||||||
|
{}
|
||||||
|
|
||||||
|
void assign(const char* data, size_t)
|
||||||
{
|
{
|
||||||
_is_valid = (row.data != nullptr);
|
_is_valid = true;
|
||||||
_is_null = row.data == nullptr or row.data[index] == nullptr;
|
_is_null = data == nullptr;
|
||||||
_value = _is_null ? 0 : std::strtoll(row.data[index], nullptr, 10);
|
_value = _is_null ? 0 : std::strtoll(data, nullptr, 10);
|
||||||
return *this;
|
}
|
||||||
|
|
||||||
|
void invalidate()
|
||||||
|
{
|
||||||
|
_is_valid = false;
|
||||||
|
_is_null = true;
|
||||||
|
_value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void validate()
|
||||||
|
{
|
||||||
|
_is_valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
@ -80,19 +163,25 @@ namespace sqlpp
|
|||||||
return _is_null;
|
return _is_null;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t value() const
|
_cpp_value_type value() const
|
||||||
{
|
{
|
||||||
if (not _is_valid)
|
if (not _is_valid)
|
||||||
throw exception("accessing value in non-existing row");
|
throw exception("accessing value in non-existing row");
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator int64_t() const { return value(); }
|
operator _cpp_value_type() const { return value(); }
|
||||||
|
|
||||||
|
template<typename Target>
|
||||||
|
void bind(Target& target, size_t i)
|
||||||
|
{
|
||||||
|
target.bind_integral_result(i, &_value, &_is_null);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _is_valid;
|
bool _is_valid;
|
||||||
bool _is_null;
|
bool _is_null;
|
||||||
int64_t _value;
|
_cpp_value_type _value;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -184,8 +273,7 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template<size_t index>
|
inline std::ostream& operator<<(std::ostream& os, const integral::_result_entry_t& e)
|
||||||
std::ostream& operator<<(std::ostream& os, const integral::_result_entry_t<index>& e)
|
|
||||||
{
|
{
|
||||||
return os << e.value();
|
return os << e.value();
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,9 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
static_assert(is_text_t<Operand>::value, "Operand for like() has to be a text");
|
static_assert(is_text_t<Operand>::value, "Operand for like() has to be a text");
|
||||||
static_assert(is_text_t<Pattern>::value, "Pattern for like() has to be a text");
|
static_assert(is_text_t<Pattern>::value, "Pattern for like() has to be a text");
|
||||||
|
using _parameter_tuple_t = std::tuple<ValueType, Pattern>;
|
||||||
|
|
||||||
struct _value_type: public ValueType::_base_value_type // we requite fully defined boolean here
|
struct _value_type: public ValueType::_base_value_type // we require fully defined boolean here
|
||||||
{
|
{
|
||||||
using _is_named_expression = std::true_type;
|
using _is_named_expression = std::true_type;
|
||||||
};
|
};
|
||||||
@ -73,6 +74,13 @@ namespace sqlpp
|
|||||||
like_t& operator=(like_t&&) = default;
|
like_t& operator=(like_t&&) = default;
|
||||||
~like_t() = default;
|
~like_t() = default;
|
||||||
|
|
||||||
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
index = set_parameter_index(_operand, index);
|
||||||
|
index = set_parameter_index(_pattern, index);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
void serialize(std::ostream& os, Db& db) const
|
void serialize(std::ostream& os, Db& db) const
|
||||||
{
|
{
|
||||||
|
@ -33,19 +33,29 @@
|
|||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
struct limit_t
|
template<typename Limit>
|
||||||
{
|
struct limit_t
|
||||||
using _is_limit = std::true_type;
|
{
|
||||||
|
using _is_limit = std::true_type;
|
||||||
|
using _parameter_tuple_t = std::tuple<Limit>;
|
||||||
|
static_assert(std::is_integral<Limit>::value
|
||||||
|
or (is_parameter_t<Limit>::value and is_numeric_t<Limit>::value), "limit requires an integral value or integral parameter");
|
||||||
|
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
void serialize(std::ostream& os, Db& db) const
|
void serialize(std::ostream& os, Db& db) const
|
||||||
|
{
|
||||||
|
static_assert(Db::_supports_limit, "limit not supported by current database");
|
||||||
|
os << " LIMIT " << _limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t _set_parameter_index(size_t index)
|
||||||
{
|
{
|
||||||
static_assert(Db::_supports_limit, "limit not supported by current database");
|
index = set_parameter_index(_limit, index);
|
||||||
os << " LIMIT " << _limit;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t _limit;
|
Limit _limit;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dynamic_limit_t
|
struct dynamic_limit_t
|
||||||
{
|
{
|
||||||
|
@ -51,6 +51,8 @@ namespace sqlpp
|
|||||||
struct _member_t
|
struct _member_t
|
||||||
{
|
{
|
||||||
T max;
|
T max;
|
||||||
|
T& operator()() { return max; }
|
||||||
|
const T& operator()() const { return max; }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,6 +51,8 @@ namespace sqlpp
|
|||||||
struct _member_t
|
struct _member_t
|
||||||
{
|
{
|
||||||
T min;
|
T min;
|
||||||
|
T& operator()() { return min; }
|
||||||
|
const T& operator()() const { return min; }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -33,18 +33,29 @@
|
|||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
struct offset_t
|
template<typename Offset>
|
||||||
{
|
struct offset_t
|
||||||
using _is_offset = std::true_type;
|
{
|
||||||
|
using _is_offset = std::true_type;
|
||||||
|
using _parameter_tuple_t = std::tuple<Offset>;
|
||||||
|
static_assert(std::is_integral<Offset>::value
|
||||||
|
or (is_parameter_t<Offset>::value and is_numeric_t<Offset>::value), "offset requires an integral value or integral parameter");
|
||||||
|
|
||||||
template<typename Db>
|
|
||||||
void serialize(std::ostream& os, Db& db) const
|
template<typename Db>
|
||||||
|
void serialize(std::ostream& os, Db& db) const
|
||||||
|
{
|
||||||
|
os << " OFFSET " << _offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t _set_parameter_index(size_t index)
|
||||||
{
|
{
|
||||||
os << " OFFSET " << _offset;
|
index = set_parameter_index(_offset, index);
|
||||||
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::size_t _offset;
|
Offset _offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dynamic_offset_t
|
struct dynamic_offset_t
|
||||||
{
|
{
|
||||||
|
@ -41,6 +41,7 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _is_order_by = std::true_type;
|
using _is_order_by = std::true_type;
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
using _parameter_tuple_t = std::tuple<Expr...>;
|
||||||
|
|
||||||
// check for at least one order expression
|
// check for at least one order expression
|
||||||
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one sort-order expression required in order_by()");
|
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one sort-order expression required in order_by()");
|
||||||
@ -71,7 +72,13 @@ namespace sqlpp
|
|||||||
_dynamic_expressions.serialize(os, db, sizeof...(Expr) == 0);
|
_dynamic_expressions.serialize(os, db, sizeof...(Expr) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<Expr...> _expressions;
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
index = set_parameter_index(_expressions, index);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
_parameter_tuple_t _expressions;
|
||||||
detail::serializable_list<Database> _dynamic_expressions;
|
detail::serializable_list<Database> _dynamic_expressions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
88
include/sqlpp11/parameter.h
Normal file
88
include/sqlpp11/parameter.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Roland Bock
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
* other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SQLPP_PARAMETER_H
|
||||||
|
#define SQLPP_PARAMETER_H
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
#include <sqlpp11/select_fwd.h>
|
||||||
|
#include <sqlpp11/type_traits.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
template<typename ValueType, typename NameType, typename TrivialValueIsNull>
|
||||||
|
struct parameter_t
|
||||||
|
{
|
||||||
|
using _value_type = ValueType;
|
||||||
|
using _is_parameter = std::true_type;
|
||||||
|
using _is_expression_t = std::true_type;
|
||||||
|
using _instance_t = typename NameType::_name_t::template _member_t<typename ValueType::_parameter_t>;
|
||||||
|
using _trivial_value_is_null_t = TrivialValueIsNull;
|
||||||
|
|
||||||
|
static_assert(std::is_same<_trivial_value_is_null_t, std::true_type>::value or std::is_same<_trivial_value_is_null_t, std::false_type>::value, "Invalid template parameter TrivialValueIsNull");
|
||||||
|
|
||||||
|
template<typename Db>
|
||||||
|
void serialize(std::ostream& os, Db& db) const
|
||||||
|
{
|
||||||
|
static_assert(Db::_supports_prepared, "prepared statements not supported by current database");
|
||||||
|
static_assert(Db::_use_questionmark_parameter or Db::_use_positional_dollar_parameter, "no known way to serialize parameter placeholders for current database");
|
||||||
|
if (Db::_use_questionmark_parameter)
|
||||||
|
os << '?';
|
||||||
|
else if (Db::_use_positional_dollar_parameter)
|
||||||
|
os << '$' << _index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool _is_trivial() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
_index = index;
|
||||||
|
return index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t _index;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename NamedExpr, typename TrivialValueIsNull = trivial_value_is_null_t<typename std::decay<NamedExpr>::type>>
|
||||||
|
auto parameter(NamedExpr&& namedExpr)
|
||||||
|
-> parameter_t<typename std::decay<NamedExpr>::type::_value_type, typename std::decay<NamedExpr>::type, TrivialValueIsNull>
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename NamedExpr>
|
||||||
|
auto where_parameter(NamedExpr&& namedExpr)
|
||||||
|
-> parameter_t<typename std::decay<NamedExpr>::type::_value_type, typename std::decay<NamedExpr>::type, std::false_type>
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
195
include/sqlpp11/parameter_list.h
Normal file
195
include/sqlpp11/parameter_list.h
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Roland Bock
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
* other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SQLPP_PARAMETER_LIST_H
|
||||||
|
#define SQLPP_PARAMETER_LIST_H
|
||||||
|
|
||||||
|
#include <sqlpp11/detail/wrong.h>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template<typename... T>
|
||||||
|
struct or_t;
|
||||||
|
|
||||||
|
template<typename T, typename... Rest>
|
||||||
|
struct or_t<T, Rest...>
|
||||||
|
{
|
||||||
|
static constexpr bool value = T::value or or_t<Rest...>::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct or_t<>
|
||||||
|
{
|
||||||
|
static constexpr bool value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct parameter_list_t
|
||||||
|
{
|
||||||
|
static_assert(detail::wrong<T>::value, "Template parameter for parameter_list_t has to be a tuple");
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Parameter>
|
||||||
|
struct parameter_list_t<std::tuple<Parameter...>>: public Parameter::_instance_t...
|
||||||
|
{
|
||||||
|
using _member_tuple_t = std::tuple<typename Parameter::_instance_t...>;
|
||||||
|
using size = std::integral_constant<std::size_t, sizeof...(Parameter)>;
|
||||||
|
using _contains_trivial_value_is_null_t = detail::or_t<typename Parameter::_trivial_value_is_null_t...>;
|
||||||
|
|
||||||
|
parameter_list_t():
|
||||||
|
Parameter::_instance_t({typename Parameter::_trivial_value_is_null_t()})...
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<typename Target>
|
||||||
|
void _bind(Target& target) const
|
||||||
|
{
|
||||||
|
_bind_impl(target, index_t<0>());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<size_t> struct index_t {}; // this is just for overloading
|
||||||
|
|
||||||
|
template<typename Target, size_t index>
|
||||||
|
void _bind_impl(Target& target, const index_t<index>&) const
|
||||||
|
{
|
||||||
|
const auto& parameter = static_cast<typename std::tuple_element<index, const _member_tuple_t>::type&>(*this)();
|
||||||
|
parameter.bind(target, index);
|
||||||
|
_bind_impl(target, index_t<index + 1>());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Target>
|
||||||
|
void _bind_impl(Target& target, const index_t<size::value>&) const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template<typename Exp, typename Enable = void>
|
||||||
|
struct get_parameter_tuple
|
||||||
|
{
|
||||||
|
using type = std::tuple<>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Exp>
|
||||||
|
struct get_parameter_tuple<Exp, typename std::enable_if<is_parameter_t<Exp>::value, void>::type>
|
||||||
|
{
|
||||||
|
using type = std::tuple<Exp>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Param>
|
||||||
|
struct get_parameter_tuple<std::tuple<Param...>, void>
|
||||||
|
{
|
||||||
|
// cat together parameter tuples
|
||||||
|
using type = decltype(std::tuple_cat(std::declval<typename get_parameter_tuple<Param>::type>()...));
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Exp>
|
||||||
|
struct get_parameter_tuple<Exp, typename std::enable_if<not std::is_same<typename Exp::_parameter_tuple_t, void>::value, void>::type>
|
||||||
|
{
|
||||||
|
using type = typename get_parameter_tuple<typename Exp::_parameter_tuple_t>::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Exp>
|
||||||
|
struct make_parameter_list_t
|
||||||
|
{
|
||||||
|
using type = parameter_list_t<typename detail::get_parameter_tuple<typename std::decay<Exp>::type>::type>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
size_t set_parameter_index(T& t, size_t index);
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template<typename Exp, typename Enable = void>
|
||||||
|
struct set_parameter_index_t
|
||||||
|
{
|
||||||
|
size_t operator()(Exp& e, size_t index)
|
||||||
|
{
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Exp>
|
||||||
|
struct set_parameter_index_t<Exp, typename std::enable_if<is_parameter_t<Exp>::value, void>::type>
|
||||||
|
{
|
||||||
|
size_t operator()(Exp& e, size_t index)
|
||||||
|
{
|
||||||
|
return e._set_parameter_index(index);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Param>
|
||||||
|
struct set_parameter_index_t<std::tuple<Param...>, void>
|
||||||
|
{
|
||||||
|
template<size_t> struct type{};
|
||||||
|
|
||||||
|
size_t operator()(std::tuple<Param...>& t, size_t index)
|
||||||
|
{
|
||||||
|
return impl(t, index, type<0>());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
template<size_t pos>
|
||||||
|
size_t impl(std::tuple<Param...>& t, size_t index, const type<pos>&)
|
||||||
|
{
|
||||||
|
index = sqlpp::set_parameter_index(std::get<pos>(t), index);
|
||||||
|
return impl(t, index, type<pos + 1>());
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t impl(std::tuple<Param...>& t, size_t index, const type<sizeof...(Param)>&)
|
||||||
|
{
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Exp>
|
||||||
|
struct set_parameter_index_t<Exp, typename std::enable_if<not std::is_same<typename Exp::_parameter_tuple_t, void>::value, void>::type>
|
||||||
|
{
|
||||||
|
size_t operator()(Exp& e, size_t index)
|
||||||
|
{
|
||||||
|
return e._set_parameter_index(index);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
size_t set_parameter_index(T& t, size_t index)
|
||||||
|
{
|
||||||
|
return detail::set_parameter_index_t<T>()(t, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
58
include/sqlpp11/prepared_insert.h
Normal file
58
include/sqlpp11/prepared_insert.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Roland Bock
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
* other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SQLPP_PREPARED_INSERT_H
|
||||||
|
#define SQLPP_PREPARED_INSERT_H
|
||||||
|
|
||||||
|
#include <sqlpp11/parameter_list.h>
|
||||||
|
#include <sqlpp11/result.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
template<typename Db, typename Insert>
|
||||||
|
struct prepared_insert_t
|
||||||
|
{
|
||||||
|
using _parameter_list_t = typename Insert::_parameter_list_t;
|
||||||
|
using _prepared_query_t = typename Db::_prepared_query_t;
|
||||||
|
|
||||||
|
auto run(Db& db) const
|
||||||
|
-> size_t
|
||||||
|
{
|
||||||
|
return db.run_prepared_insert(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _bind_params() const
|
||||||
|
{
|
||||||
|
params._bind(_prepared_query);
|
||||||
|
}
|
||||||
|
|
||||||
|
_parameter_list_t params;
|
||||||
|
mutable _prepared_query_t _prepared_query;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
58
include/sqlpp11/prepared_remove.h
Normal file
58
include/sqlpp11/prepared_remove.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Roland Bock
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
* other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SQLPP_PREPARED_REMOVE_H
|
||||||
|
#define SQLPP_PREPARED_REMOVE_H
|
||||||
|
|
||||||
|
#include <sqlpp11/parameter_list.h>
|
||||||
|
#include <sqlpp11/result.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
template<typename Db, typename Remove>
|
||||||
|
struct prepared_remove_t
|
||||||
|
{
|
||||||
|
using _parameter_list_t = typename Remove::_parameter_list_t;
|
||||||
|
using _prepared_query_t = typename Db::_prepared_query_t;
|
||||||
|
|
||||||
|
auto run(Db& db) const
|
||||||
|
-> size_t
|
||||||
|
{
|
||||||
|
return db.run_prepared_insert(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _bind_params() const
|
||||||
|
{
|
||||||
|
params._bind(_prepared_query);
|
||||||
|
}
|
||||||
|
|
||||||
|
_parameter_list_t params;
|
||||||
|
mutable _prepared_query_t _prepared_query;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
61
include/sqlpp11/prepared_select.h
Normal file
61
include/sqlpp11/prepared_select.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Roland Bock
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
* other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SQLPP_PREPARED_SELECT_H
|
||||||
|
#define SQLPP_PREPARED_SELECT_H
|
||||||
|
|
||||||
|
#include <sqlpp11/parameter_list.h>
|
||||||
|
#include <sqlpp11/result.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
template<typename Db, typename Select>
|
||||||
|
struct prepared_select_t
|
||||||
|
{
|
||||||
|
using _result_row_t = typename Select::_result_row_t;
|
||||||
|
using _parameter_list_t = typename Select::_parameter_list_t;
|
||||||
|
using _dynamic_names_t = typename Select::_dynamic_names_t;
|
||||||
|
using _prepared_query_t = typename Db::_prepared_query_t;
|
||||||
|
|
||||||
|
auto run(Db& db) const
|
||||||
|
-> result_t<decltype(db.run_prepared_select(*this)), _result_row_t>
|
||||||
|
{
|
||||||
|
return {db.run_prepared_select(*this), _dynamic_names};
|
||||||
|
}
|
||||||
|
|
||||||
|
void _bind_params() const
|
||||||
|
{
|
||||||
|
params._bind(_prepared_query);
|
||||||
|
}
|
||||||
|
|
||||||
|
_parameter_list_t params;
|
||||||
|
_dynamic_names_t _dynamic_names;
|
||||||
|
mutable _prepared_query_t _prepared_query;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
58
include/sqlpp11/prepared_update.h
Normal file
58
include/sqlpp11/prepared_update.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Roland Bock
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
* other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SQLPP_PREPARED_UPDATE_H
|
||||||
|
#define SQLPP_PREPARED_UPDATE_H
|
||||||
|
|
||||||
|
#include <sqlpp11/parameter_list.h>
|
||||||
|
#include <sqlpp11/result.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
template<typename Db, typename Update>
|
||||||
|
struct prepared_update_t
|
||||||
|
{
|
||||||
|
using _parameter_list_t = typename Update::_parameter_list_t;
|
||||||
|
using _prepared_query_t = typename Db::_prepared_query_t;
|
||||||
|
|
||||||
|
auto run(Db& db) const
|
||||||
|
-> size_t
|
||||||
|
{
|
||||||
|
return db.run_prepared_insert(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _bind_params() const
|
||||||
|
{
|
||||||
|
params._bind(_prepared_query);
|
||||||
|
}
|
||||||
|
|
||||||
|
_parameter_list_t params;
|
||||||
|
mutable _prepared_query_t _prepared_query;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -32,6 +32,8 @@
|
|||||||
#include <sqlpp11/using.h>
|
#include <sqlpp11/using.h>
|
||||||
#include <sqlpp11/where.h>
|
#include <sqlpp11/where.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
|
#include <sqlpp11/parameter_list.h>
|
||||||
|
#include <sqlpp11/prepared_remove.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -60,6 +62,9 @@ namespace sqlpp
|
|||||||
template<typename WhereT>
|
template<typename WhereT>
|
||||||
using set_where_t = remove_t<Database, Table, Using, WhereT>;
|
using set_where_t = remove_t<Database, Table, Using, WhereT>;
|
||||||
|
|
||||||
|
using _parameter_tuple_t = std::tuple<Table, Using, Where>;
|
||||||
|
using _parameter_list_t = typename make_parameter_list_t<remove_t>::type;
|
||||||
|
|
||||||
template<typename... Tab>
|
template<typename... Tab>
|
||||||
auto using_(Tab&&... tab)
|
auto using_(Tab&&... tab)
|
||||||
-> set_using_t<using_t<void, typename std::decay<Tab>::type...>>
|
-> set_using_t<using_t<void, typename std::decay<Tab>::type...>>
|
||||||
@ -147,14 +152,40 @@ namespace sqlpp
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static constexpr size_t _get_static_no_of_parameters()
|
||||||
|
{
|
||||||
|
return _parameter_list_t::size::value;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t _get_no_of_parameters()
|
||||||
|
{
|
||||||
|
return _parameter_list_t::size::value; // FIXME: Need to add dynamic parameters here
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
std::size_t run(Db& db) const
|
std::size_t run(Db& db) const
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
static_assert(_get_static_no_of_parameters() == 0, "cannot run remove directly with parameters, use prepare instead");
|
||||||
serialize(oss, db);
|
return db.remove(*this);
|
||||||
return db.remove(oss.str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Db>
|
||||||
|
auto prepare(Db& db)
|
||||||
|
-> prepared_remove_t<typename std::decay<Db>::type, remove_t>
|
||||||
|
{
|
||||||
|
_set_parameter_index(0);
|
||||||
|
return {{}, db.prepare_remove(*this)};
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
index = set_parameter_index(_table, index);
|
||||||
|
index = set_parameter_index(_using, index);
|
||||||
|
index = set_parameter_index(_where, index);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Table _table;
|
Table _table;
|
||||||
Using _using;
|
Using _using;
|
||||||
Where _where;
|
Where _where;
|
||||||
|
@ -27,38 +27,31 @@
|
|||||||
#ifndef SQLPP_RESULT_H
|
#ifndef SQLPP_RESULT_H
|
||||||
#define SQLPP_RESULT_H
|
#define SQLPP_RESULT_H
|
||||||
|
|
||||||
#include <sqlpp11/raw_result_row.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
template<typename Db, typename ResultRow, typename DynamicNames>
|
template<typename DbResult, typename ResultRow>
|
||||||
class result_t
|
class result_t
|
||||||
{
|
{
|
||||||
using db_result_t = typename Db::_result_t;
|
using db_result_t = DbResult;
|
||||||
|
using result_row_t = ResultRow;
|
||||||
|
|
||||||
db_result_t _result;
|
db_result_t _result;
|
||||||
raw_result_row_t _raw_result_row;
|
result_row_t _result_row;
|
||||||
raw_result_row_t _end;
|
db_result_t _end;
|
||||||
DynamicNames _dynamic_columns; // only needed in case of dynamic columns in the select
|
result_row_t _end_row;
|
||||||
ResultRow _result_row;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
result_t():
|
result_t() = default;
|
||||||
_raw_result_row({}),
|
|
||||||
_end({}),
|
|
||||||
_dynamic_columns(),
|
|
||||||
_result_row(_raw_result_row, _dynamic_columns)
|
|
||||||
{}
|
|
||||||
|
|
||||||
result_t(db_result_t&& result, DynamicNames dynamic_columns):
|
template<typename DynamicNames>
|
||||||
|
result_t(db_result_t&& result, const DynamicNames& dynamic_names):
|
||||||
_result(std::move(result)),
|
_result(std::move(result)),
|
||||||
_raw_result_row(_result.next()),
|
_result_row(dynamic_names)
|
||||||
_end({}),
|
{
|
||||||
_dynamic_columns(dynamic_columns),
|
_result.next(_result_row);
|
||||||
_result_row(_raw_result_row, _dynamic_columns)
|
}
|
||||||
{}
|
|
||||||
|
|
||||||
result_t(const result_t&) = delete;
|
result_t(const result_t&) = delete;
|
||||||
result_t(result_t&&) = default;
|
result_t(result_t&&) = default;
|
||||||
@ -69,26 +62,25 @@ namespace sqlpp
|
|||||||
class iterator
|
class iterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
iterator(result_t& result, raw_result_row_t& raw_result_row):
|
iterator(db_result_t& result, result_row_t& result_row):
|
||||||
_result(result),
|
_result(result),
|
||||||
_raw_result_row(raw_result_row)
|
_result_row(result_row)
|
||||||
{
|
{
|
||||||
//std::cerr << "result::iterator::constructor" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ResultRow& operator*() const
|
const result_row_t& operator*() const
|
||||||
{
|
{
|
||||||
return _result.front();
|
return _result_row;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ResultRow* operator->() const
|
const result_row_t* operator->() const
|
||||||
{
|
{
|
||||||
return &_result.front();
|
return &_result_row;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const iterator& rhs) const
|
bool operator==(const iterator& rhs) const
|
||||||
{
|
{
|
||||||
return _raw_result_row == rhs._raw_result_row;
|
return _result_row == rhs._result_row;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const iterator& rhs) const
|
bool operator!=(const iterator& rhs) const
|
||||||
@ -98,37 +90,36 @@ namespace sqlpp
|
|||||||
|
|
||||||
void operator++()
|
void operator++()
|
||||||
{
|
{
|
||||||
_result.pop_front();
|
_result.next(_result_row);
|
||||||
}
|
}
|
||||||
|
|
||||||
result_t& _result;
|
db_result_t& _result;
|
||||||
raw_result_row_t& _raw_result_row;
|
result_row_t& _result_row;
|
||||||
};
|
};
|
||||||
|
|
||||||
iterator begin()
|
iterator begin()
|
||||||
{
|
{
|
||||||
return iterator(*this, _raw_result_row);
|
return iterator(_result, _result_row);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator end()
|
iterator end()
|
||||||
{
|
{
|
||||||
return iterator(*this, _end);
|
return iterator(_end, _end_row);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ResultRow& front() const
|
const result_row_t& front() const
|
||||||
{
|
{
|
||||||
return _result_row;
|
return _result_row;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty() const
|
bool empty() const
|
||||||
{
|
{
|
||||||
return _raw_result_row == _end;
|
return _result_row == _end_row;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop_front()
|
void pop_front()
|
||||||
{
|
{
|
||||||
_raw_result_row = _result.next();
|
_result.next(_result_row);
|
||||||
_result_row = _raw_result_row;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#ifndef SQLPP_RESULT_ROW_H
|
#ifndef SQLPP_RESULT_ROW_H
|
||||||
#define SQLPP_RESULT_ROW_H
|
#define SQLPP_RESULT_ROW_H
|
||||||
|
|
||||||
#include <sqlpp11/raw_result_row.h>
|
#include <sqlpp11/char_result_row.h>
|
||||||
#include <sqlpp11/field.h>
|
#include <sqlpp11/field.h>
|
||||||
#include <sqlpp11/text.h>
|
#include <sqlpp11/text.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -37,64 +37,123 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
template<size_t> struct index_t {}; // this is just for overloading
|
||||||
|
|
||||||
template<size_t level, size_t index, typename... NamedExpr>
|
template<size_t level, size_t index, typename... NamedExpr>
|
||||||
struct result_row_impl;
|
struct result_row_impl;
|
||||||
|
|
||||||
template<size_t level, size_t index, typename NamedExpr, typename... Rest>
|
template<size_t level, size_t index, typename NamedExpr, typename... Rest>
|
||||||
struct result_row_impl<level, index, NamedExpr, Rest...>:
|
struct result_row_impl<level, index, NamedExpr, Rest...>:
|
||||||
public NamedExpr::_name_t::template _member_t<typename NamedExpr::_value_type::template _result_entry_t<index>>,
|
public NamedExpr::_name_t::template _member_t<typename NamedExpr::_value_type::_result_entry_t>,
|
||||||
public result_row_impl<level, index + 1, Rest...>
|
public result_row_impl<level, index + 1, Rest...>
|
||||||
{
|
{
|
||||||
using _field = typename NamedExpr::_name_t::template _member_t<typename NamedExpr::_value_type::template _result_entry_t<index>>;
|
using _field = typename NamedExpr::_name_t::template _member_t<typename NamedExpr::_value_type::_result_entry_t>;
|
||||||
using _rest = result_row_impl<level, index + 1, Rest...>;
|
using _rest = result_row_impl<level, index + 1, Rest...>;
|
||||||
static constexpr size_t _last_index = _rest::_last_index;
|
static constexpr size_t _last_index = _rest::_last_index;
|
||||||
|
|
||||||
result_row_impl(const raw_result_row_t& raw_result_row):
|
result_row_impl() = default;
|
||||||
_field({raw_result_row}),
|
result_row_impl(const char_result_row_t& char_result_row_t):
|
||||||
_rest(raw_result_row)
|
_field({{char_result_row_t.data[index], char_result_row_t.len[index]}}),
|
||||||
{}
|
_rest(char_result_row_t)
|
||||||
|
|
||||||
result_row_impl& operator=(const raw_result_row_t& raw_result_row)
|
|
||||||
{
|
{
|
||||||
_field::operator=({raw_result_row});
|
}
|
||||||
_rest::operator=(raw_result_row);
|
|
||||||
|
result_row_impl& operator=(const char_result_row_t& char_result_row_t)
|
||||||
|
{
|
||||||
|
_field::operator()().assign(char_result_row_t.data[index], char_result_row_t.len[index]);
|
||||||
|
_rest::operator=(char_result_row_t);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void validate()
|
||||||
|
{
|
||||||
|
_field::operator()().validate();
|
||||||
|
_rest::validate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void invalidate()
|
||||||
|
{
|
||||||
|
_field::operator()().invalidate();
|
||||||
|
_rest::invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Target>
|
||||||
|
void _bind(Target& target)
|
||||||
|
{
|
||||||
|
_field::operator()().bind(target, index);
|
||||||
|
std::cerr << "binding result " << index << std::endl;
|
||||||
|
_rest::_bind(target);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<size_t level, size_t index, typename AliasProvider, typename... Col, typename... Rest>
|
template<size_t level, size_t index, typename AliasProvider, typename... Col, typename... Rest>
|
||||||
struct result_row_impl<level, index, multi_field_t<AliasProvider, std::tuple<Col...>>, Rest...>:
|
struct result_row_impl<level, index, multi_field_t<AliasProvider, std::tuple<Col...>>, Rest...>:
|
||||||
public AliasProvider::_name_t::template _member_t<result_row_impl<level + 1, index, Col...>>, // level prevents identical closures to be present twice in the inheritance tree
|
public AliasProvider::_name_t::template _member_t<result_row_impl<level, index, Col...>>, // level prevents identical closures to be present twice in the inheritance tree
|
||||||
public result_row_impl<level, index + sizeof...(Col), Rest...>
|
public result_row_impl<level, index + sizeof...(Col), Rest...>
|
||||||
{
|
{
|
||||||
using _multi_field = typename AliasProvider::_name_t::template _member_t<result_row_impl<level + 1, index, Col...>>;
|
using _multi_field = typename AliasProvider::_name_t::template _member_t<result_row_impl<level, index, Col...>>;
|
||||||
using _rest = result_row_impl<level, index + sizeof...(Col), Rest...>;
|
using _rest = result_row_impl<level, index + sizeof...(Col), Rest...>;
|
||||||
static constexpr size_t _last_index = _rest::_last_index;
|
static constexpr size_t _last_index = _rest::_last_index;
|
||||||
|
|
||||||
result_row_impl(const raw_result_row_t& raw_result_row):
|
result_row_impl() = default;
|
||||||
_multi_field({raw_result_row}),
|
result_row_impl(const char_result_row_t& char_result_row_t):
|
||||||
_rest(raw_result_row)
|
_multi_field({char_result_row_t}),
|
||||||
|
_rest(char_result_row_t)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
result_row_impl& operator=(const raw_result_row_t& raw_result_row)
|
result_row_impl& operator=(const char_result_row_t& char_result_row_t)
|
||||||
{
|
{
|
||||||
_multi_field::operator=({raw_result_row});
|
_multi_field::operator()() = char_result_row_t;
|
||||||
_rest::operator=(raw_result_row);
|
_rest::operator=(char_result_row_t);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void validate()
|
||||||
|
{
|
||||||
|
_multi_field::operator()().validate();
|
||||||
|
_rest::validate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void invalidate()
|
||||||
|
{
|
||||||
|
_multi_field::operator()().invalidate();
|
||||||
|
_rest::invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Target>
|
||||||
|
void _bind(const Target& target)
|
||||||
|
{
|
||||||
|
_multi_field::_bind(target);
|
||||||
|
_rest::_bind(target);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<size_t level, size_t index>
|
template<size_t level, size_t index>
|
||||||
struct result_row_impl<level, index>
|
struct result_row_impl<level, index>
|
||||||
{
|
{
|
||||||
static constexpr size_t _last_index = index;
|
static constexpr size_t _last_index = index;
|
||||||
result_row_impl(const raw_result_row_t& raw_result_row)
|
result_row_impl() = default;
|
||||||
{}
|
result_row_impl(const char_result_row_t& char_result_row_t)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
result_row_impl& operator=(const raw_result_row_t& raw_result_row)
|
result_row_impl& operator=(const char_result_row_t& char_result_row_t)
|
||||||
{
|
{
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void validate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void invalidate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Target>
|
||||||
|
void _bind(Target& target)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,93 +161,130 @@ namespace sqlpp
|
|||||||
struct result_row_t: public detail::result_row_impl<0, 0, NamedExpr...>
|
struct result_row_t: public detail::result_row_impl<0, 0, NamedExpr...>
|
||||||
{
|
{
|
||||||
using _impl = detail::result_row_impl<0, 0, NamedExpr...>;
|
using _impl = detail::result_row_impl<0, 0, NamedExpr...>;
|
||||||
bool _is_row;
|
bool _is_valid;
|
||||||
|
static constexpr size_t _last_static_index = _impl::_last_index;
|
||||||
|
|
||||||
template<typename T>
|
result_row_t():
|
||||||
result_row_t(const raw_result_row_t& raw_result_row, const T&):
|
_impl(),
|
||||||
_impl(raw_result_row),
|
_is_valid(false)
|
||||||
_is_row(raw_result_row.data != nullptr)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
result_row_t& operator=(const raw_result_row_t& raw_result_row)
|
template<typename DynamicNames>
|
||||||
|
result_row_t(const DynamicNames&):
|
||||||
|
_impl(),
|
||||||
|
_is_valid(false)
|
||||||
{
|
{
|
||||||
_impl::operator=(raw_result_row);
|
}
|
||||||
_is_row = raw_result_row.data != nullptr;
|
|
||||||
|
result_row_t(const result_row_t&) = delete;
|
||||||
|
result_row_t(result_row_t&&) = default;
|
||||||
|
result_row_t& operator=(const result_row_t&) = delete;
|
||||||
|
result_row_t& operator=(result_row_t&&) = default;
|
||||||
|
|
||||||
|
result_row_t& operator=(const char_result_row_t& char_result_row_t)
|
||||||
|
{
|
||||||
|
_impl::operator=(char_result_row_t);
|
||||||
|
_is_valid = true;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void validate()
|
||||||
|
{
|
||||||
|
_impl::validate();
|
||||||
|
_is_valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void invalidate()
|
||||||
|
{
|
||||||
|
_impl::invalidate();
|
||||||
|
_is_valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const result_row_t& rhs) const
|
||||||
|
{
|
||||||
|
return _is_valid == rhs._is_valid;
|
||||||
|
}
|
||||||
|
|
||||||
explicit operator bool() const
|
explicit operator bool() const
|
||||||
{
|
{
|
||||||
return _is_row;
|
return _is_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static constexpr size_t static_size()
|
||||||
|
{
|
||||||
|
return _last_static_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Target>
|
||||||
|
void bind_result(Target& target)
|
||||||
|
{
|
||||||
|
_impl::_bind(target);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename... NamedExpr>
|
template<typename... NamedExpr>
|
||||||
struct dynamic_result_row_t: public detail::result_row_impl<0, 0, NamedExpr...>
|
struct dynamic_result_row_t: public detail::result_row_impl<0, 0, NamedExpr...>
|
||||||
{
|
{
|
||||||
using _impl = detail::result_row_impl<0, 0, NamedExpr...>;
|
using _impl = detail::result_row_impl<0, 0, NamedExpr...>;
|
||||||
using _field_type = detail::text::_result_entry_t<0>;
|
using _field_type = detail::text::_result_entry_t;
|
||||||
static constexpr size_t _last_static_index = _impl::_last_index;
|
static constexpr size_t _last_static_index = _impl::_last_index;
|
||||||
|
|
||||||
bool _is_row;
|
bool _is_valid;
|
||||||
std::vector<std::string> _dynamic_columns;
|
std::vector<std::string> _dynamic_columns;
|
||||||
std::map<std::string, _field_type> _dynamic_fields;
|
std::map<std::string, _field_type> _dynamic_fields;
|
||||||
|
|
||||||
dynamic_result_row_t(const raw_result_row_t& raw_result_row, std::vector<std::string> dynamic_columns):
|
dynamic_result_row_t():
|
||||||
detail::result_row_impl<0, 0, NamedExpr...>(raw_result_row),
|
_impl(),
|
||||||
_is_row(raw_result_row.data != nullptr)
|
_is_valid(false)
|
||||||
{
|
{
|
||||||
raw_result_row_t dynamic_row = raw_result_row;
|
|
||||||
if (_is_row)
|
|
||||||
{
|
|
||||||
dynamic_row.data += _last_static_index;
|
|
||||||
dynamic_row.len += _last_static_index;
|
|
||||||
for (const auto& column : _dynamic_columns)
|
|
||||||
{
|
|
||||||
_dynamic_fields.insert(std::make_pair(column, _field_type(dynamic_row)));
|
|
||||||
++dynamic_row.data;
|
|
||||||
++dynamic_row.len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (const auto& column : _dynamic_columns)
|
|
||||||
{
|
|
||||||
_dynamic_fields.insert(std::make_pair(column, _field_type(dynamic_row)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic_result_row_t& operator=(const raw_result_row_t& raw_result_row)
|
dynamic_result_row_t(const std::vector<std::string>& dynamic_columns):
|
||||||
|
_impl(),
|
||||||
|
_is_valid(false),
|
||||||
|
_dynamic_columns(dynamic_columns)
|
||||||
{
|
{
|
||||||
detail::result_row_impl<0, 0, NamedExpr...>::operator=(raw_result_row);
|
}
|
||||||
_is_row = raw_result_row.data != nullptr;
|
|
||||||
|
|
||||||
raw_result_row_t dynamic_row = raw_result_row;
|
dynamic_result_row_t(const dynamic_result_row_t&) = delete;
|
||||||
if (_is_row)
|
dynamic_result_row_t(dynamic_result_row_t&&) = default;
|
||||||
{
|
dynamic_result_row_t& operator=(const dynamic_result_row_t&) = delete;
|
||||||
dynamic_row.data += _last_static_index;
|
dynamic_result_row_t& operator=(dynamic_result_row_t&&) = default;
|
||||||
dynamic_row.len += _last_static_index;
|
|
||||||
for (const auto& column : _dynamic_columns)
|
|
||||||
{
|
|
||||||
_dynamic_fields.at(column) = dynamic_row;
|
|
||||||
++dynamic_row.data;
|
|
||||||
++dynamic_row.len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (const auto& column : _dynamic_columns)
|
|
||||||
{
|
|
||||||
_dynamic_fields.at(column) = dynamic_row;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
dynamic_result_row_t& operator=(const char_result_row_t& char_result_row)
|
||||||
|
{
|
||||||
|
_impl::operator=(char_result_row);
|
||||||
|
_is_valid = true;
|
||||||
|
|
||||||
|
char_result_row_t dynamic_row = char_result_row;
|
||||||
|
|
||||||
|
dynamic_row.data += _last_static_index;
|
||||||
|
dynamic_row.len += _last_static_index;
|
||||||
|
for (const auto& column : _dynamic_columns)
|
||||||
|
{
|
||||||
|
_dynamic_fields[column].assign(dynamic_row.data[0], dynamic_row.len[0]);
|
||||||
|
++dynamic_row.data;
|
||||||
|
++dynamic_row.len;
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void invalidate()
|
||||||
|
{
|
||||||
|
_impl::invalidate();
|
||||||
|
_is_valid = false;
|
||||||
|
for (const auto& column : _dynamic_columns)
|
||||||
|
{
|
||||||
|
_dynamic_fields.at(column).invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const dynamic_result_row_t& rhs) const
|
||||||
|
{
|
||||||
|
return _is_valid == rhs._is_valid;
|
||||||
|
}
|
||||||
|
|
||||||
const _field_type& at(const std::string& field_name) const
|
const _field_type& at(const std::string& field_name) const
|
||||||
{
|
{
|
||||||
return _dynamic_fields.at(field_name);
|
return _dynamic_fields.at(field_name);
|
||||||
@ -196,7 +292,7 @@ namespace sqlpp
|
|||||||
|
|
||||||
explicit operator bool() const
|
explicit operator bool() const
|
||||||
{
|
{
|
||||||
return _is_row;
|
return _is_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -40,6 +40,8 @@
|
|||||||
#include <sqlpp11/limit.h>
|
#include <sqlpp11/limit.h>
|
||||||
#include <sqlpp11/offset.h>
|
#include <sqlpp11/offset.h>
|
||||||
#include <sqlpp11/expression.h>
|
#include <sqlpp11/expression.h>
|
||||||
|
#include <sqlpp11/parameter_list.h>
|
||||||
|
#include <sqlpp11/prepared_select.h>
|
||||||
|
|
||||||
#include <sqlpp11/detail/wrong.h>
|
#include <sqlpp11/detail/wrong.h>
|
||||||
#include <sqlpp11/detail/make_flag_tuple.h>
|
#include <sqlpp11/detail/make_flag_tuple.h>
|
||||||
@ -109,6 +111,8 @@ namespace sqlpp
|
|||||||
|
|
||||||
using _result_row_t = typename ExpressionList::_result_row_t;
|
using _result_row_t = typename ExpressionList::_result_row_t;
|
||||||
using _dynamic_names_t = typename ExpressionList::_dynamic_names_t;
|
using _dynamic_names_t = typename ExpressionList::_dynamic_names_t;
|
||||||
|
using _parameter_tuple_t = std::tuple<ExpressionList, Where, GroupBy, Having, OrderBy, Limit, Offset>;
|
||||||
|
using _parameter_list_t = typename make_parameter_list_t<select_t>::type;
|
||||||
|
|
||||||
// Indicators
|
// Indicators
|
||||||
using _value_type = typename std::conditional<
|
using _value_type = typename std::conditional<
|
||||||
@ -135,7 +139,7 @@ namespace sqlpp
|
|||||||
|
|
||||||
// Other constructors
|
// Other constructors
|
||||||
|
|
||||||
constexpr select_t(Flags&& flags, ExpressionList&& expression_list, From&& from,
|
select_t(Flags&& flags, ExpressionList&& expression_list, From&& from,
|
||||||
Where&& where, GroupBy&& group_by, Having&& having,
|
Where&& where, GroupBy&& group_by, Having&& having,
|
||||||
OrderBy&& order_by, Limit&& limit, Offset&& offset):
|
OrderBy&& order_by, Limit&& limit, Offset&& offset):
|
||||||
_flags(std::move(flags)),
|
_flags(std::move(flags)),
|
||||||
@ -150,7 +154,7 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr select_t(const Flags& flags, const ExpressionList& expression_list, const From& from,
|
select_t(const Flags& flags, const ExpressionList& expression_list, const From& from,
|
||||||
const Where& where, const GroupBy& group_by, const Having& having,
|
const Where& where, const GroupBy& group_by, const Having& having,
|
||||||
const OrderBy& order_by, const Limit& limit, const Offset& offset):
|
const OrderBy& order_by, const Limit& limit, const Offset& offset):
|
||||||
_flags(flags),
|
_flags(flags),
|
||||||
@ -436,23 +440,24 @@ namespace sqlpp
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto limit(std::size_t limit)
|
template<typename Expr>
|
||||||
-> set_limit_t<limit_t>
|
auto limit(Expr limit)
|
||||||
{
|
-> set_limit_t<limit_t<typename std::decay<Expr>::type>>
|
||||||
static_assert(not is_noop<From>::value, "cannot call limit() without a from()");
|
{
|
||||||
static_assert(is_noop<Limit>::value, "cannot call limit() twice for a single select");
|
static_assert(not is_noop<From>::value, "cannot call limit() without a from()");
|
||||||
return {
|
static_assert(is_noop<Limit>::value, "cannot call limit() twice for a single select");
|
||||||
|
return {
|
||||||
_flags,
|
_flags,
|
||||||
_expression_list,
|
_expression_list,
|
||||||
_from,
|
_from,
|
||||||
_where,
|
_where,
|
||||||
_group_by,
|
_group_by,
|
||||||
_having,
|
_having,
|
||||||
_order_by,
|
_order_by,
|
||||||
{limit},
|
{limit},
|
||||||
_offset,
|
_offset,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto dynamic_limit(std::size_t limit = 0)
|
auto dynamic_limit(std::size_t limit = 0)
|
||||||
->set_limit_t<dynamic_limit_t>
|
->set_limit_t<dynamic_limit_t>
|
||||||
@ -481,8 +486,9 @@ namespace sqlpp
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto offset(std::size_t offset)
|
template<typename Expr>
|
||||||
-> set_offset_t<offset_t>
|
auto offset(Expr offset)
|
||||||
|
-> set_offset_t<offset_t<typename std::decay<Expr>::type>>
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<Limit>::value, "cannot call offset() without a limit");
|
static_assert(not is_noop<Limit>::value, "cannot call offset() without a limit");
|
||||||
static_assert(is_noop<Offset>::value, "cannot call offset() twice for a single select");
|
static_assert(is_noop<Offset>::value, "cannot call offset() twice for a single select");
|
||||||
@ -566,20 +572,66 @@ namespace sqlpp
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const typename ExpressionList::_dynamic_names_t& get_dynamic_names() const
|
||||||
|
{
|
||||||
|
return _expression_list._dynamic_expressions._dynamic_expression_names;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr size_t _get_static_no_of_parameters()
|
||||||
|
{
|
||||||
|
return _parameter_list_t::size::value;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t _get_no_of_parameters()
|
||||||
|
{
|
||||||
|
return _parameter_list_t::size::value; // FIXME: Need to add dynamic parameters here
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t get_no_of_result_columns() const
|
||||||
|
{
|
||||||
|
return _result_row_t::static_size(); // FIXME: Need to add the size of dynamic columns
|
||||||
|
}
|
||||||
|
|
||||||
// Execute
|
// Execute
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
result_t<Db, _result_row_t, _dynamic_names_t> run(Db& db) const
|
auto run(Db& db) const
|
||||||
|
-> result_t<decltype(db.select(*this)), _result_row_t>
|
||||||
|
{
|
||||||
|
static_assert(not is_noop<ExpressionList>::value, "cannot run select without having selected anything");
|
||||||
|
static_assert(is_from_t<From>::value, "cannot run select without a from()");
|
||||||
|
static_assert(_get_static_no_of_parameters() == 0, "cannot run select directly with parameters, use prepare instead");
|
||||||
|
// FIXME: Check for missing aliases (if references are used)
|
||||||
|
// FIXME: Check for missing tables, well, actually, check for missing tables at the where(), order_by(), etc.
|
||||||
|
|
||||||
|
return {db.select(*this), get_dynamic_names()};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare
|
||||||
|
template<typename Db>
|
||||||
|
auto prepare(Db& db)
|
||||||
|
-> prepared_select_t<typename std::decay<Db>::type, select_t>
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<ExpressionList>::value, "cannot run select without having selected anything");
|
static_assert(not is_noop<ExpressionList>::value, "cannot run select without having selected anything");
|
||||||
static_assert(is_from_t<From>::value, "cannot run select without a from()");
|
static_assert(is_from_t<From>::value, "cannot run select without a from()");
|
||||||
// FIXME: Check for missing aliases (if references are used)
|
// FIXME: Check for missing aliases (if references are used)
|
||||||
// FIXME: Check for missing tables, well, actually, check for missing tables at the where(), order_by(), etc.
|
// FIXME: Check for missing tables, well, actually, check for missing tables at the where(), order_by(), etc.
|
||||||
|
|
||||||
std::ostringstream oss;
|
_set_parameter_index(0);
|
||||||
serialize(oss, db);
|
return {{}, get_dynamic_names(), db.prepare_select(*this)};
|
||||||
return {db.select(oss.str()), _expression_list._dynamic_expressions._dynamic_expression_names};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
index = set_parameter_index(_expression_list, index);
|
||||||
|
index = set_parameter_index(_where, index);
|
||||||
|
index = set_parameter_index(_group_by, index);
|
||||||
|
index = set_parameter_index(_having, index);
|
||||||
|
index = set_parameter_index(_order_by, index);
|
||||||
|
index = set_parameter_index(_limit, index);
|
||||||
|
index = set_parameter_index(_offset, index);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
Flags _flags;
|
Flags _flags;
|
||||||
ExpressionList _expression_list;
|
ExpressionList _expression_list;
|
||||||
From _from;
|
From _from;
|
||||||
|
@ -107,6 +107,7 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _is_select_expression_list = std::true_type;
|
using _is_select_expression_list = std::true_type;
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
using _parameter_tuple_t = std::tuple<NamedExpr...>;
|
||||||
|
|
||||||
// check for duplicate select expressions
|
// check for duplicate select expressions
|
||||||
static_assert(not detail::has_duplicates<NamedExpr...>::value, "at least one duplicate argument detected");
|
static_assert(not detail::has_duplicates<NamedExpr...>::value, "at least one duplicate argument detected");
|
||||||
@ -160,7 +161,13 @@ namespace sqlpp
|
|||||||
_dynamic_expressions.serialize(os, db, sizeof...(NamedExpr) == 0);
|
_dynamic_expressions.serialize(os, db, sizeof...(NamedExpr) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<NamedExpr...> _expressions;
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
index = set_parameter_index(_expressions, index);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
_parameter_tuple_t _expressions;
|
||||||
detail::dynamic_select_expression_list<Database> _dynamic_expressions;
|
detail::dynamic_select_expression_list<Database> _dynamic_expressions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -50,8 +50,10 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename Database, typename... Expr> struct order_by_t;
|
template<typename Database, typename... Expr> struct order_by_t;
|
||||||
|
|
||||||
|
template<typename Limit>
|
||||||
struct limit_t;
|
struct limit_t;
|
||||||
|
|
||||||
|
template<typename Offset>
|
||||||
struct offset_t;
|
struct offset_t;
|
||||||
|
|
||||||
template<
|
template<
|
||||||
|
@ -52,6 +52,8 @@ namespace sqlpp
|
|||||||
struct _member_t
|
struct _member_t
|
||||||
{
|
{
|
||||||
T some;
|
T some;
|
||||||
|
T& operator()() { return some; }
|
||||||
|
const T& operator()() const { return some; }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,6 +51,8 @@ namespace sqlpp
|
|||||||
struct _member_t
|
struct _member_t
|
||||||
{
|
{
|
||||||
T sum;
|
T sum;
|
||||||
|
T& operator()() { return sum; }
|
||||||
|
const T& operator()() const { return sum; }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <sqlpp11/detail/basic_operators.h>
|
#include <sqlpp11/detail/basic_operators.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/raw_result_row.h>
|
|
||||||
#include <sqlpp11/exception.h>
|
#include <sqlpp11/exception.h>
|
||||||
#include <sqlpp11/concat.h>
|
#include <sqlpp11/concat.h>
|
||||||
#include <sqlpp11/like.h>
|
#include <sqlpp11/like.h>
|
||||||
@ -46,21 +45,40 @@ namespace sqlpp
|
|||||||
using _is_text = std::true_type;
|
using _is_text = std::true_type;
|
||||||
using _is_value = std::true_type;
|
using _is_value = std::true_type;
|
||||||
using _is_expression = std::true_type;
|
using _is_expression = std::true_type;
|
||||||
|
using _cpp_value_type = std::string;
|
||||||
|
|
||||||
template<size_t index>
|
struct _parameter_t
|
||||||
struct _result_entry_t
|
|
||||||
{
|
{
|
||||||
_result_entry_t(const raw_result_row_t& row):
|
using _value_type = integral;
|
||||||
_is_valid(row.data != nullptr),
|
|
||||||
_is_null(row.data == nullptr or row.data[index] == nullptr),
|
_parameter_t(const std::true_type&):
|
||||||
_value(_is_null ? "" : std::string(row.data[index], row.data[index] + row.len[index]))
|
_trivial_value_is_null(true),
|
||||||
|
_value(""),
|
||||||
|
_is_null(_trivial_value_is_null and _is_trivial())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
_result_entry_t& operator=(const raw_result_row_t& row)
|
_parameter_t(const std::false_type&):
|
||||||
|
_trivial_value_is_null(false),
|
||||||
|
_value(""),
|
||||||
|
_is_null(_trivial_value_is_null and _is_trivial())
|
||||||
|
{}
|
||||||
|
|
||||||
|
_parameter_t(const _cpp_value_type& value):
|
||||||
|
_value(value),
|
||||||
|
_is_null(_trivial_value_is_null and _is_trivial())
|
||||||
|
{}
|
||||||
|
|
||||||
|
_parameter_t& operator=(const _cpp_value_type& value)
|
||||||
{
|
{
|
||||||
_is_valid = (row.data != nullptr);
|
_value = value;
|
||||||
_is_null = row.data == nullptr or row.data[index] == nullptr;
|
_is_null = (_trivial_value_is_null and _is_trivial());
|
||||||
_value = _is_null ? "" : std::string(row.data[index], row.data[index] + row.len[index]);
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
_parameter_t& operator=(const std::nullptr_t&)
|
||||||
|
{
|
||||||
|
_value = "";
|
||||||
|
_is_null = true;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,31 +88,105 @@ namespace sqlpp
|
|||||||
os << value();
|
os << value();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _is_trivial() const { return value().empty(); }
|
bool _is_trivial() const { return value() == ""; }
|
||||||
|
|
||||||
bool operator==(const std::string& rhs) const { return value() == rhs; }
|
bool is_null() const
|
||||||
bool operator!=(const std::string& rhs) const { return not operator==(rhs); }
|
{
|
||||||
|
return _is_null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_cpp_value_type value() const
|
||||||
|
{
|
||||||
|
return _value;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator _cpp_value_type() const { return value(); }
|
||||||
|
|
||||||
|
template<typename Target>
|
||||||
|
void bind(Target& target, size_t index) const
|
||||||
|
{
|
||||||
|
target.bind_text_parameter(index, &_value, _is_null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _trivial_value_is_null;
|
||||||
|
_cpp_value_type _value;
|
||||||
|
bool _is_null;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _result_entry_t
|
||||||
|
{
|
||||||
|
_result_entry_t():
|
||||||
|
_is_valid(false),
|
||||||
|
_value_ptr(nullptr),
|
||||||
|
_len(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
_result_entry_t(char* data, size_t len):
|
||||||
|
_is_valid(true),
|
||||||
|
_value_ptr(data),
|
||||||
|
_len(_value_ptr ? 0 : len)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void assign(char* data, size_t len)
|
||||||
|
{
|
||||||
|
_is_valid = true;
|
||||||
|
_value_ptr = data;
|
||||||
|
_len = _value_ptr ? 0 : len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void validate()
|
||||||
|
{
|
||||||
|
_is_valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void invalidate()
|
||||||
|
{
|
||||||
|
_is_valid = false;
|
||||||
|
_value_ptr = nullptr;
|
||||||
|
_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Db>
|
||||||
|
void serialize(std::ostream& os, Db& db) const
|
||||||
|
{
|
||||||
|
os << value();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _is_trivial() const { return _len == 0; }
|
||||||
|
|
||||||
|
bool operator==(const _cpp_value_type& rhs) const { return value() == rhs; }
|
||||||
|
bool operator!=(const _cpp_value_type& rhs) const { return not operator==(rhs); }
|
||||||
|
|
||||||
bool is_null() const
|
bool is_null() const
|
||||||
{
|
{
|
||||||
if (not _is_valid)
|
if (not _is_valid)
|
||||||
throw exception("accessing is_null in non-existing row");
|
throw exception("accessing is_null in non-existing row");
|
||||||
return _is_null;
|
return _value_ptr == nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string value() const
|
_cpp_value_type value() const
|
||||||
{
|
{
|
||||||
if (not _is_valid)
|
if (not _is_valid)
|
||||||
throw exception("accessing value in non-existing row");
|
throw exception("accessing value in non-existing row");
|
||||||
return _value;
|
if (_value_ptr)
|
||||||
|
return std::string(_value_ptr, _value_ptr + _len);
|
||||||
|
else
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
operator std::string() const { return value(); }
|
operator _cpp_value_type() const { return value(); }
|
||||||
|
|
||||||
|
template<typename Target>
|
||||||
|
void bind(Target& target, size_t i)
|
||||||
|
{
|
||||||
|
target.bind_text_result(i, &_value_ptr, &_len);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _is_valid;
|
bool _is_valid;
|
||||||
bool _is_null;
|
char* _value_ptr;
|
||||||
std::string _value;
|
size_t _len;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -120,8 +212,7 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template<size_t index>
|
inline std::ostream& operator<<(std::ostream& os, const text::_result_entry_t& e)
|
||||||
std::ostream& operator<<(std::ostream& os, const text::_result_entry_t<index>& e)
|
|
||||||
{
|
{
|
||||||
return os << e.value();
|
return os << e.value();
|
||||||
}
|
}
|
||||||
|
@ -47,12 +47,12 @@ namespace sqlpp
|
|||||||
namespace detail\
|
namespace detail\
|
||||||
{\
|
{\
|
||||||
template<typename T, typename Enable = void>\
|
template<typename T, typename Enable = void>\
|
||||||
struct name##_impl: std::false_type {};\
|
struct name##_impl { using type = std::false_type; };\
|
||||||
template<typename T>\
|
template<typename T>\
|
||||||
struct name##_impl<T, typename std::enable_if<std::is_same<typename T::_column_type::_##name, std::true_type>::value>::type>: std::true_type {};\
|
struct name##_impl<T, typename std::enable_if<std::is_same<typename T::_column_type::_##name, std::true_type>::value>::type> { using type = std::true_type; };\
|
||||||
}\
|
}\
|
||||||
template<typename T>\
|
template<typename T>\
|
||||||
struct name##_t: detail::name##_impl<T> {};
|
using name##_t = typename detail::name##_impl<T>::type;
|
||||||
|
|
||||||
#define SQLPP_TYPE_TRAIT_GENERATOR(name) \
|
#define SQLPP_TYPE_TRAIT_GENERATOR(name) \
|
||||||
namespace detail\
|
namespace detail\
|
||||||
@ -116,6 +116,7 @@ namespace sqlpp
|
|||||||
SQLPP_TYPE_TRAIT_GENERATOR(is_insert_list);
|
SQLPP_TYPE_TRAIT_GENERATOR(is_insert_list);
|
||||||
SQLPP_TYPE_TRAIT_GENERATOR(is_sort_order);
|
SQLPP_TYPE_TRAIT_GENERATOR(is_sort_order);
|
||||||
SQLPP_TYPE_TRAIT_GENERATOR(requires_braces);
|
SQLPP_TYPE_TRAIT_GENERATOR(requires_braces);
|
||||||
|
SQLPP_TYPE_TRAIT_GENERATOR(is_parameter);
|
||||||
|
|
||||||
SQLPP_CONNECTOR_TRAIT_GENERATOR(has_empty_list_insert);
|
SQLPP_CONNECTOR_TRAIT_GENERATOR(has_empty_list_insert);
|
||||||
|
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
#include <sqlpp11/assignment_list.h>
|
#include <sqlpp11/assignment_list.h>
|
||||||
#include <sqlpp11/where.h>
|
#include <sqlpp11/where.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
|
#include <sqlpp11/parameter_list.h>
|
||||||
|
#include <sqlpp11/prepared_update.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -60,6 +62,9 @@ namespace sqlpp
|
|||||||
template<typename WhereT>
|
template<typename WhereT>
|
||||||
using set_where_t = update_t<Database, Table, Assignments, WhereT>;
|
using set_where_t = update_t<Database, Table, Assignments, WhereT>;
|
||||||
|
|
||||||
|
using _parameter_tuple_t = std::tuple<Table, Assignments, Where>;
|
||||||
|
using _parameter_list_t = typename make_parameter_list_t<update_t>::type;
|
||||||
|
|
||||||
template<typename... Assignment>
|
template<typename... Assignment>
|
||||||
auto set(Assignment&&... assignment)
|
auto set(Assignment&&... assignment)
|
||||||
-> set_assignments_t<assignment_list_t<void, must_not_update_t, typename std::decay<Assignment>::type...>>
|
-> set_assignments_t<assignment_list_t<void, must_not_update_t, typename std::decay<Assignment>::type...>>
|
||||||
@ -147,14 +152,41 @@ namespace sqlpp
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static constexpr size_t _get_static_no_of_parameters()
|
||||||
|
{
|
||||||
|
return _parameter_list_t::size::value;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t _get_no_of_parameters()
|
||||||
|
{
|
||||||
|
return _parameter_list_t::size::value; // FIXME: Need to add dynamic parameters here
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
std::size_t run(Db& db) const
|
std::size_t run(Db& db) const
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
static_assert(not is_noop<Assignments>::value, "calling set() required before running update");
|
||||||
serialize(oss, db);
|
static_assert(_get_static_no_of_parameters() == 0, "cannot run update directly with parameters, use prepare instead");
|
||||||
return db.update(oss.str());
|
return db.update(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Db>
|
||||||
|
auto prepare(Db& db)
|
||||||
|
-> prepared_update_t<typename std::decay<Db>::type, update_t>
|
||||||
|
{
|
||||||
|
static_assert(not is_noop<Assignments>::value, "calling set() required before running update");
|
||||||
|
|
||||||
|
_set_parameter_index(0);
|
||||||
|
return {{}, db.prepare_update(*this)};
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
index = set_parameter_index(_table, index);
|
||||||
|
index = set_parameter_index(_assignments, index);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
Table _table;
|
Table _table;
|
||||||
Assignments _assignments;
|
Assignments _assignments;
|
||||||
Where _where;
|
Where _where;
|
||||||
|
@ -40,6 +40,7 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _is_using = std::true_type;
|
using _is_using = std::true_type;
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
using _parameter_tuple_t = std::tuple<Table...>;
|
||||||
|
|
||||||
static_assert(_is_dynamic::value or sizeof...(Table), "at least one table argument required in using()");
|
static_assert(_is_dynamic::value or sizeof...(Table), "at least one table argument required in using()");
|
||||||
|
|
||||||
@ -68,7 +69,13 @@ namespace sqlpp
|
|||||||
_dynamic_tables.serialize(os, db, sizeof...(Table) == 0);
|
_dynamic_tables.serialize(os, db, sizeof...(Table) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<Table...> _tables;
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
index = set_parameter_index(_tables, index);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
_parameter_tuple_t _tables;
|
||||||
detail::serializable_list<Database> _dynamic_tables;
|
detail::serializable_list<Database> _dynamic_tables;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include <sqlpp11/detail/set.h>
|
#include <sqlpp11/detail/set.h>
|
||||||
#include <sqlpp11/detail/serialize_tuple.h>
|
#include <sqlpp11/detail/serialize_tuple.h>
|
||||||
#include <sqlpp11/detail/serializable_list.h>
|
#include <sqlpp11/detail/serializable_list.h>
|
||||||
|
#include <sqlpp11/parameter_list.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -42,11 +43,15 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _is_where = std::true_type;
|
using _is_where = std::true_type;
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
using _parameter_tuple_t = std::tuple<Expr...>;
|
||||||
|
|
||||||
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in where()");
|
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in where()");
|
||||||
using _valid_expressions = typename detail::make_set_if<is_expression_t, Expr...>::type;
|
using _valid_expressions = typename detail::make_set_if<is_expression_t, Expr...>::type;
|
||||||
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in where()");
|
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in where()");
|
||||||
|
|
||||||
|
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
|
||||||
|
static_assert(not _parameter_list_t::_contains_trivial_value_is_null_t::value, "must not use trivial_value_is_null in parameters of where expression, use where_parameter() instead of parameter() to turn off automatic conversion");
|
||||||
|
|
||||||
template<typename E>
|
template<typename E>
|
||||||
void add(E&& expr)
|
void add(E&& expr)
|
||||||
{
|
{
|
||||||
@ -64,7 +69,13 @@ namespace sqlpp
|
|||||||
_dynamic_expressions.serialize(os, db, " AND ", sizeof...(Expr) == 0);
|
_dynamic_expressions.serialize(os, db, " AND ", sizeof...(Expr) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<Expr...> _expressions;
|
size_t _set_parameter_index(size_t index)
|
||||||
|
{
|
||||||
|
index = set_parameter_index(_expressions, index);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
_parameter_tuple_t _expressions;
|
||||||
detail::serializable_list<Database> _dynamic_expressions;
|
detail::serializable_list<Database> _dynamic_expressions;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -8,4 +8,5 @@ build_and_run(RemoveTest)
|
|||||||
build_and_run(UpdateTest)
|
build_and_run(UpdateTest)
|
||||||
build_and_run(SelectTest)
|
build_and_run(SelectTest)
|
||||||
build_and_run(FunctionTest)
|
build_and_run(FunctionTest)
|
||||||
|
build_and_run(PreparedTest)
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
DbMock db = {};
|
DbMock db = {};
|
||||||
|
SQLPP_ALIAS_PROVIDER_GENERATOR(kaesekuchen);
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@ -374,7 +375,6 @@ int main()
|
|||||||
|
|
||||||
// test verbatim_table alias
|
// test verbatim_table alias
|
||||||
{
|
{
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(kaesekuchen);
|
|
||||||
using T = decltype(sqlpp::verbatim_table("cheesecake").as(kaesekuchen));
|
using T = decltype(sqlpp::verbatim_table("cheesecake").as(kaesekuchen));
|
||||||
static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement");
|
static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||||
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
||||||
|
108
tests/PreparedTest.cpp
Normal file
108
tests/PreparedTest.cpp
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Roland Bock
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TabSample.h"
|
||||||
|
#include "MockDb.h"
|
||||||
|
#include "is_regular.h"
|
||||||
|
#include <sqlpp11/functions.h>
|
||||||
|
#include <sqlpp11/select.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
DbMock db = {};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
TabSample t;
|
||||||
|
TabFoo f;
|
||||||
|
|
||||||
|
// empty parameter lists
|
||||||
|
{
|
||||||
|
using T = typename sqlpp::detail::get_parameter_tuple<decltype(t.alpha)>::type;
|
||||||
|
static_assert(std::is_same<T, std::tuple<>>::value, "type requirement");
|
||||||
|
}
|
||||||
|
|
||||||
|
// single parameter
|
||||||
|
{
|
||||||
|
using T = typename sqlpp::detail::get_parameter_tuple<decltype(parameter(t.alpha))>::type;
|
||||||
|
static_assert(std::is_same<T, std::tuple<decltype(parameter(t.alpha))>>::value, "type requirement");
|
||||||
|
}
|
||||||
|
|
||||||
|
// single parameter
|
||||||
|
{
|
||||||
|
using T = typename sqlpp::detail::get_parameter_tuple<decltype(parameter(t.alpha))>::type;
|
||||||
|
static_assert(std::is_same<T, std::tuple<decltype(parameter(t.alpha))>>::value, "type requirement");
|
||||||
|
}
|
||||||
|
|
||||||
|
// single parameter in expression
|
||||||
|
{
|
||||||
|
using T = typename sqlpp::detail::get_parameter_tuple<decltype(t.alpha == parameter(t.alpha))>::type;
|
||||||
|
static_assert(std::is_same<T, std::tuple<decltype(parameter(t.alpha))>>::value, "type requirement");
|
||||||
|
}
|
||||||
|
|
||||||
|
// single parameter in larger expression
|
||||||
|
{
|
||||||
|
using T = typename sqlpp::detail::get_parameter_tuple<decltype(t.beta.like("%") and t.alpha == parameter(t.alpha) or t.gamma != false)>::type;
|
||||||
|
static_assert(std::is_same<T, std::tuple<decltype(parameter(t.alpha))>>::value, "type requirement");
|
||||||
|
}
|
||||||
|
|
||||||
|
// three parameters in expression
|
||||||
|
{
|
||||||
|
using T = typename sqlpp::detail::get_parameter_tuple<decltype(t.beta.like(parameter(t.beta)) and t.alpha == parameter(t.alpha) or t.gamma != parameter(t.gamma))>::type;
|
||||||
|
static_assert(std::tuple_size<T>::value == 3, "type requirement");
|
||||||
|
static_assert(std::is_same<T, std::tuple<decltype(parameter(t.beta)), decltype(parameter(t.alpha)),decltype(parameter(t.gamma))>>::value, "type requirement");
|
||||||
|
}
|
||||||
|
|
||||||
|
// OK, fine, now create a named parameter list from an expression
|
||||||
|
{
|
||||||
|
using Exp = decltype(t.beta.like(parameter(t.beta)) and t.alpha == parameter(t.alpha) or t.gamma != parameter(t.gamma));
|
||||||
|
using T = sqlpp::make_parameter_list_t<Exp>::type;
|
||||||
|
T npl;
|
||||||
|
static_assert(std::is_same<typename decltype(t.alpha)::_value_type::_parameter_t, decltype(npl.alpha)>::value, "type requirement");
|
||||||
|
static_assert(std::is_same<typename decltype(t.beta)::_value_type::_parameter_t, decltype(npl.beta)>::value, "type requirement");
|
||||||
|
static_assert(std::is_same<typename decltype(t.gamma)::_value_type::_parameter_t, decltype(npl.gamma)>::value, "type requirement");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wonderful, now take a look at the parameter list of a select
|
||||||
|
{
|
||||||
|
auto s = select(all_of(t)).from(t).where(t.beta.like(where_parameter(t.beta)) and t.alpha == where_parameter(t.alpha) or t.gamma != parameter(t.gamma));
|
||||||
|
using S = decltype(s);
|
||||||
|
using T = sqlpp::make_parameter_list_t<S>::type;
|
||||||
|
T npl;
|
||||||
|
|
||||||
|
static_assert(std::is_same<typename decltype(t.alpha)::_value_type::_parameter_t, decltype(npl.alpha)>::value, "type requirement");
|
||||||
|
static_assert(std::is_same<typename decltype(t.beta)::_value_type::_parameter_t, decltype(npl.beta)>::value, "type requirement");
|
||||||
|
static_assert(std::is_same<typename decltype(t.gamma)::_value_type::_parameter_t, decltype(npl.gamma)>::value, "type requirement");
|
||||||
|
npl.alpha = 7;
|
||||||
|
auto x = npl;
|
||||||
|
x = npl;
|
||||||
|
std::cerr << x.alpha << std::endl;
|
||||||
|
x = decltype(npl)();
|
||||||
|
std::cerr << x.alpha << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -298,8 +298,6 @@ int main()
|
|||||||
decltype(t.alpha)::_value_type::_base_value_type,
|
decltype(t.alpha)::_value_type::_base_value_type,
|
||||||
decltype(f.epsilon)::_value_type::_base_value_type>::value, "Two bigint columns must have identical base_value_type");
|
decltype(f.epsilon)::_value_type::_base_value_type>::value, "Two bigint columns must have identical base_value_type");
|
||||||
static_assert(std::is_same<A, B>::value, "select with identical columns(name/value_type) need to have identical result_types");
|
static_assert(std::is_same<A, B>::value, "select with identical columns(name/value_type) need to have identical result_types");
|
||||||
static_assert(sqlpp::is_regular<A>::value, "type requirement");
|
|
||||||
static_assert(sqlpp::is_regular<B>::value, "type requirement");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -42,6 +42,8 @@ namespace TabFoo_
|
|||||||
struct _member_t
|
struct _member_t
|
||||||
{
|
{
|
||||||
T epsilon;
|
T epsilon;
|
||||||
|
T& operator()() { return epsilon; }
|
||||||
|
const T& operator()() const { return epsilon; }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
using _value_type = sqlpp::bigint;
|
using _value_type = sqlpp::bigint;
|
||||||
@ -59,6 +61,8 @@ namespace TabFoo_
|
|||||||
struct _member_t
|
struct _member_t
|
||||||
{
|
{
|
||||||
T omega;
|
T omega;
|
||||||
|
T& operator()() { return omega; }
|
||||||
|
const T& operator()() const { return omega; }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
using _value_type = sqlpp::floating_point;
|
using _value_type = sqlpp::floating_point;
|
||||||
@ -83,6 +87,8 @@ struct TabFoo: sqlpp::table_base_t<
|
|||||||
struct _member_t
|
struct _member_t
|
||||||
{
|
{
|
||||||
T tabFoo;
|
T tabFoo;
|
||||||
|
T& operator()() { return tabFoo; }
|
||||||
|
const T& operator()() const { return tabFoo; }
|
||||||
};
|
};
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
void serialize_impl(std::ostream& os, Db& db) const
|
void serialize_impl(std::ostream& os, Db& db) const
|
||||||
@ -102,6 +108,8 @@ namespace TabSample_
|
|||||||
struct _member_t
|
struct _member_t
|
||||||
{
|
{
|
||||||
T alpha;
|
T alpha;
|
||||||
|
T& operator()() { return alpha; }
|
||||||
|
const T& operator()() const { return alpha; }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
using _value_type = sqlpp::bigint;
|
using _value_type = sqlpp::bigint;
|
||||||
@ -124,6 +132,8 @@ namespace TabSample_
|
|||||||
struct _member_t
|
struct _member_t
|
||||||
{
|
{
|
||||||
T beta;
|
T beta;
|
||||||
|
T& operator()() { return beta; }
|
||||||
|
const T& operator()() const { return beta; }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
using _value_type = sqlpp::varchar;
|
using _value_type = sqlpp::varchar;
|
||||||
@ -144,6 +154,8 @@ namespace TabSample_
|
|||||||
struct _member_t
|
struct _member_t
|
||||||
{
|
{
|
||||||
T gamma;
|
T gamma;
|
||||||
|
T& operator()() { return gamma; }
|
||||||
|
const T& operator()() const { return gamma; }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
using _value_type = sqlpp::boolean;
|
using _value_type = sqlpp::boolean;
|
||||||
@ -169,6 +181,8 @@ struct TabSample: sqlpp::table_base_t<
|
|||||||
struct _member_t
|
struct _member_t
|
||||||
{
|
{
|
||||||
T tabSample;
|
T tabSample;
|
||||||
|
T& operator()() { return tabSample; }
|
||||||
|
const T& operator()() const { return tabSample; }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
|
Loading…
Reference in New Issue
Block a user