0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-15 20:31:16 +08:00

Merge branch 'release/0.12'

This commit is contained in:
rbock 2014-02-04 08:03:56 +01:00
commit 52aacba14e
34 changed files with 729 additions and 403 deletions

View File

@ -0,0 +1,91 @@
/*
* 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_DATABASE_BIND_RESULT_H
#define SQLPP_DATABASE_BIND_RESULT_H
#include <memory>
namespace sqlpp
{
namespace database
{
/*
* bind_result_t binds values of a sqlpp11 result row
* to the results of a statement
*/
class bind_result_t
{
public:
bind_result_t(); // default constructor for a result that will not yield a valid row
bind_result_t(...);
bind_result_t(const bind_result_t&) = delete;
bind_result_t(bind_result_t&& rhs);
bind_result_t& operator=(const bind_result_t&) = delete;
bind_result_t& operator=(bind_result_t&&);
~bind_result_t();
bool operator==(const bind_result_t& rhs) const;
template<typename ResultRow>
void next(ResultRow& result_row);
// something similar to this:
/*
{
if (!_handle)
{
result_row.invalidate();
return;
}
if (next_impl())
{
if (not result_row)
{
result_row.validate();
}
result_row._bind(*this); // bind result row values to results
}
else
{
if (result_row)
result_row.invalidate();
}
};
*/
// These are called by the result row to bind individual result values
void _bind_boolean_result(size_t index, signed char* value, bool* is_null);
void _bind_integral_result(size_t index, int64_t* value, bool* is_null);
void _bind_text_result(size_t index, const char** text, size_t* len);
...
};
}
}
#endif

View File

@ -0,0 +1,70 @@
/*
* 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_DATABASE_CHAR_RESULT_H
#define SQLPP_DATABASE_CHAR_RESULT_H
#include <sqlpp11/vendor/char_result_row.h>
namespace sqlpp
{
namespace database
{
/*
* char_result_t yields results as
* sqlpp11::vendor::char_result_row_t
*/
class char_result_t
{
::sqlpp11::vendor::char_result_row_t char_result_row;
public:
char_result_t(); // default constructor for a result that will not yield a valid row
char_result_t(...);
char_result_t(const char_result_t&) = delete;
char_result_t(char_result_t&& rhs);
char_result_t& operator=(const char_result_t&) = delete;
char_result_t& operator=(char_result_t&&);
~char_result_t();
bool operator==(const char_result_t& rhs) const;
template<typename ResultRow>
void next(ResultRow& result_row);
// Something like
/*
{
next_impl();
if (_char_result_row.data)
result_row = _char_result_row;
else
result_row.invalidate();
};
*/
}
}
#endif

140
connector_api/connection.h Normal file
View File

@ -0,0 +1,140 @@
/*
* 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_DATABASE_CONNECTION_H
#define SQLPP_DATABASE_CONNECTION_H
#include <string>
#include <sqlpp11/connection.h>
#include <sqlpp11/database/char_result.h> // You may use char result or bind result or both
#include <sqlpp11/database/bind_result.h> // to represent results of select and prepared select
namespace sqlpp
{
namespace database
{
// The context is not a requirement, but if the database requires
// any deviations from the SQL standard, you should use your own
// context in order to specialize the behaviour, see also interpreter.h
struct context_t
{
template<typename T>
std::ostream& operator<<(T t);
std::string escape(std::string arg);
};
class connection: public sqlpp::connection // this inheritance helps with ADL for dynamic_select, for instance
{
public:
using _prepared_statement_t = << handle to a prepared statement of the database >>;
using _context_t = << This context is used to interpret the dynamic parts of dynamic statemtents>>;
connection(...);
~connection();
connection(const connection&) = delete;
connection(connection&&) = delete;
connection& operator=(const connection&) = delete;
connection& operator=(connection&&) = delete;
//! "direct" select
template<typename Select>
<<char_result_t or bind_result_t>> select(const Select& s);
//! prepared select
template<typename Select>
_prepared_statement_t prepare_select(Select& s);
template<typename PreparedSelect>
<<char_result_t or bind_result_t>> run_prepared_select(const PreparedSelect& s); // call s._bind_params()
//! "direct insert
template<typename Insert>
size_t insert(const Insert& i);
//! prepared insert
template<typename Insert>
_prepared_statement_t prepare_insert(Insert& i);
template<typename PreparedInsert>
size_t run_prepared_insert(const PreparedInsert& i); // call i._bind_params()
//! "direct" update
template<typename Update>
size_t update(const Update& u);
//! "prepared" update
template<typename Update>
_prepared_statement_t prepare_update(Update& u);
template<typename PreparedUpdate>
size_t run_prepared_update(const PreparedUpdate& u); // call u._bind_params()
//! "direct" remove
template<typename Remove>
size_t remove(const Remove& r)
//! prepared remove
template<typename Remove>
_prepared_statement_t prepare_remove(Remove& r);
template<typename PreparedRemove>
size_t run_prepared_remove(const PreparedRemove& r); // call r._bind_params()
//! call run on the argument
template<typename T>
auto run(const T& t) -> decltype(t._run(*this))
{
return t._run(*this);
}
//! call prepare on the argument
template<typename T>
auto prepare(const T& t) -> decltype(t._prepare(*this))
{
return t._prepare(*this);
}
//! start transaction
void start_transaction();
//! commit transaction (or throw transaction if the transaction has been finished already)
void commit_transaction();
//! rollback transaction with or without reporting the rollback (or throw if the transaction has been finished already)
void rollback_transaction(bool report);
//! report a rollback failure (will be called by transactions in case of a rollback failure in the destructor)
void report_rollback_failure(const std::string message) noexcept;
};
}
}
#include <sqlpp11/database/interpreter.h>
#endif

View File

@ -0,0 +1,62 @@
/*
* 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_DATABASE_INTERPRETER_H
#define SQLPP_DATABASE_INTERPRETER_H
#include <sqlpp11/vendor/concat.h>
#include <sqlpp11/vendor/insert_list.h>
/*
* sqlpp11 offers an interpreter that can be used to serialize the expression tree
* into a standard SQL string.
*
* The connector library can specialize the interpreter template to partially or
* completely change the way the expression tree is interpreted.
*
* For example, this specialization will produce indexed parameters instead of just '?'
*/
namespace sqlpp
{
namespace vendor
{
template<typename ValueType, typename NameType>
struct interpreter_t<database::context_t, parameter_t<ValueType, NameType>>
{
using T = parameter_t<ValueType, NameType>;
static database::context_t& _(const T& t, database::context_t& context)
{
context << "?" << context.count();
context.pop_count();
return context;
}
};
}
}
#endif

View 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_DATABASE_PREPARED_STATEMENT_H
#define SQLPP_DATABASE_PREPARED_STATEMENT_H
#include <memory>
#include <string>
namespace sqlpp
{
namespace database
{
class prepared_statement_t
{
public:
prepared_statement_t() = delete;
prepared_statement_t(...);
prepared_statement_t(const prepared_statement_t&) = delete;
prepared_statement_t(prepared_statement_t&& rhs);
prepared_statement_t& operator=(const prepared_statement_t&) = delete;
prepared_statement_t& operator=(prepared_statement_t&&);
~prepared_statement_t();
bool operator==(const prepared_statement_t& rhs) const;
// These are called by the sqlpp11::prepared_*_t to bind the individual parameters
void _bind_boolean_parameter(size_t index, const signed char* value, bool is_null);
void _bind_integral_parameter(size_t index, const int64_t* value, bool is_null);
void _bind_text_parameter(size_t index, const std::string* value, bool is_null);
};
}
}
#endif

View File

@ -1,137 +0,0 @@
/*
* 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_DATABASE_API_H
#define SQLPP_DATABASE_API_H
#include <string>
#include <sqlpp11/connection.h>
#include <sqlpp11/raw_result_row.h>
namespace sqlpp
{
namespace connector_name
{
class result
{
public:
result() = default;
result(const result&) = delete;
result(result&& rhs) = default;
result& operator=(const result&) = delete;
result& operator=(result&&) = default;
~result() = default;
bool operator==(const result& rhs) const;
//! return the next row from the result or a "false" row, if there is no next row
sqlpp::raw_result_row_t next();
size_t num_cols() const;
};
class connection: public sqlpp::connection
{
public:
// A bunch of flags telling sqlpp11 which feature is support and which isn't
// join types
static constexpr bool _supports_inner_join = true;
static constexpr bool _supports_outer_join = true;
static constexpr bool _supports_left_outer_join = true;
static constexpr bool _supports_right_outer_join = true;
// functions
static constexpr bool _supports_avg = true;
static constexpr bool _supports_count = true;
static constexpr bool _supports_exists = true;
static constexpr bool _supports_like = true;
static constexpr bool _supports_in = true;
static constexpr bool _supports_is_null = true;
static constexpr bool _supports_is_not_null = true;
static constexpr bool _supports_max = true;
static constexpr bool _supports_min = true;
static constexpr bool _supports_not_in = true;
static constexpr bool _supports_sum = true;
// select
static constexpr bool _supports_group_by = true;
static constexpr bool _supports_having = true;
static constexpr bool _supports_limit = true;
static constexpr bool _supports_order_by = true;
static constexpr bool _supports_select_as_table = true;
static constexpr bool _supports_some = true;
static constexpr bool _supports_any = true;
static constexpr bool _use_concat_operator = false;
static constexpr bool _use_concat_function = true;
connection(/*whatever arguments you need*/);
connection(const connection&) = delete;
connection(connection&&) = delete;
connection& operator=(const connection&) = delete;
connection& operator=(connection&&) = delete;
~connection();
//! select returns a result (which can be iterated row by row)
result select(const std::string& query);
//! insert returns the last auto_incremented id (or zero, if there is none)
size_t insert(const std::string& query);
//! update returns the number of affected rows
size_t update(const std::string& query);
//! remove returns the number of removed rows
size_t remove(const std::string& query);
//! execute arbitrary command (e.g. create a table)
void execute(const std::string& command);
//! escape given string
std::string escape(const std::string& s) const;
//! call run on the argument
template<typename T>
auto run(const T& t) -> decltype(t.run(*this))
{
return t.run(*this);
}
//! start transaction
void start_transaction();
//! commit transaction (or throw transaction if the transaction has been finished already)
void commit_transaction();
//! rollback transaction with or without reporting the rollback (or throw if the transaction has been finished already)
void rollback_transaction(bool report);
//! report a rollback failure (will be called by transactions in case of a rollback failure in the destructor)
void report_rollback_failure(const std::string message) noexcept;
};
}
}
#endif

View File

@ -44,6 +44,7 @@ namespace sqlpp
struct column_t: public ColumnSpec::_value_type::template operators<column_t<Table, ColumnSpec>> struct column_t: public ColumnSpec::_value_type::template operators<column_t<Table, ColumnSpec>>
{ {
using _is_column = std::true_type; using _is_column = std::true_type;
using _spec_t = ColumnSpec;
using _table = Table; using _table = Table;
using _column_type = typename ColumnSpec::_column_type; using _column_type = typename ColumnSpec::_column_type;
struct _value_type: ColumnSpec::_value_type struct _value_type: ColumnSpec::_value_type

View 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_DETAIL_LOGIC_H
#define SQLPP_DETAIL_LOGIC_H
#include <type_traits>
namespace sqlpp
{
namespace detail
{
template<bool... b>
struct and_impl;
template<>
struct and_impl<>
{
static constexpr bool value = true;
};
template<bool... Rest>
struct and_impl<true, Rest...>
{
static constexpr bool value = and_impl<Rest...>::value;
};
template<bool... Rest>
struct and_impl<false, Rest...>
{
static constexpr bool value = false;
};
template<template<typename> class Predicate, typename... T>
using and_t = and_impl<Predicate<T>::value...>;
template<bool... b>
struct or_impl;
template<>
struct or_impl<>
{
static constexpr bool value = false;
};
template<bool... Rest>
struct or_impl<false, Rest...>
{
static constexpr bool value = or_impl<Rest...>::value;
};
template<bool... Rest>
struct or_impl<true, Rest...>
{
static constexpr bool value = true;
};
template<template<typename> class Predicate, typename... T>
using or_t = or_impl<Predicate<T>::value...>;
}
}
#endif

View File

@ -1,201 +0,0 @@
/*
* 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_DETAIL_SET_H
#define SQLPP_DETAIL_SET_H
#include <type_traits>
#include <sqlpp11/vendor/wrong.h>
namespace sqlpp
{
namespace detail
{
template<typename... T>
struct make_set;
template<typename T>
class empty {};
template<typename SET, typename... T>
struct is_superset_of_impl
: std::false_type {};
template<typename SET>
struct is_superset_of_impl<SET>
: std::true_type {};
template<typename SET, typename T, typename... Rest>
struct is_superset_of_impl<SET, T, Rest...>
: std::integral_constant<bool, SET::template contains<T>::value and is_superset_of_impl<SET, Rest...>::value> {};
template<typename SET, typename... T>
struct is_disjunct_from_impl
: std::false_type {};
template<typename SET>
struct is_disjunct_from_impl<SET>
: std::true_type {};
template<typename SET, typename T, typename... Rest>
struct is_disjunct_from_impl<SET, T, Rest...>
: std::integral_constant<bool, not SET::template contains<T>::value and is_disjunct_from_impl<SET, Rest...>::value> {};
template<typename... Element>
struct set: empty<Element>...
{
struct size: std::integral_constant<size_t, sizeof...(Element)> {};
template<typename T>
struct contains
: std::integral_constant<bool, std::is_base_of<empty<T>, set>::value> {};
template<typename T>
struct is_superset_of
{
static_assert(::sqlpp::vendor::wrong_t<T>::value, "invalid argument for is_superset_of");
};
template<typename... T>
struct is_superset_of<set<T...>>
: is_superset_of_impl<set, T...>{};
template<typename T>
struct join
{
static_assert(::sqlpp::vendor::wrong_t<T>::value, "invalid argument for set::join");
};
template<typename... T>
struct join<set<T...>>
: make_set<Element..., T...> {};
template<typename T>
struct is_disjunct_from
{
static_assert(::sqlpp::vendor::wrong_t<T>::value, "invalid argument for is_disjunct_from");
};
template<typename... T>
struct is_disjunct_from<set<T...>>
: is_disjunct_from_impl<set, T...>{};
template<typename T>
struct is_subset_of
{
static_assert(::sqlpp::vendor::wrong_t<T>::value, "invalid argument for is_subset_of");
};
template<typename... T>
struct is_subset_of<set<T...>>
: is_superset_of_impl<set<T...>, Element...>{};
template<typename T>
struct equals
{
static_assert(::sqlpp::vendor::wrong_t<T>::value, "invalid argument for equals");
};
template<typename... T>
struct equals<set<T...>>
: std::integral_constant<bool,
is_superset_of_impl<set<T...>, Element...>::value
and
is_superset_of_impl<set<Element...>, T...>::value> {};
template<typename T, typename Enable = void>
struct insert
{
typedef set type;
};
template<typename T>
struct insert<T, typename std::enable_if<not set::template contains<T>::value>::type>
{
typedef set<Element..., T> type;
};
template<template<typename A> class Predicate, typename T, typename Enable = void>
struct insert_if
{
typedef set type;
};
template<template<typename A> class Predicate, typename T>
struct insert_if<Predicate, T, typename std::enable_if<not set::template contains<T>::value and Predicate<T>::value>::type>
{
typedef set<Element..., T> type;
};
};
template<>
struct make_set<>
{
typedef set<> type;
};
template<typename T, typename... Rest>
struct make_set<T, Rest...>
{
typedef typename make_set<Rest...>::type::template insert<T>::type type;
};
template<template<typename> class Predicate, typename... T>
struct make_set_if;
template<template<typename> class Predicate>
struct make_set_if<Predicate>
{
typedef set<> type;
};
template<template<typename> class Predicate, typename T, typename... Rest>
struct make_set_if<Predicate, T, Rest...>
{
typedef typename make_set_if<Predicate, Rest...>::type::template insert_if<Predicate, T>::type type;
};
template<template<typename> class Predicate, typename... T>
struct make_set_if_not
{
template<typename A>
struct InversePredicate
{
static constexpr bool value = not Predicate<A>::value;
};
using type = typename make_set_if<InversePredicate, T...>::type;
};
template<typename... T>
struct has_duplicates
: std::integral_constant<bool, make_set<T...>::type::size::value != sizeof...(T)> {};
}
}
#endif

View File

@ -0,0 +1,159 @@
/*
* 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_DETAIL_TYPE_SET_H
#define SQLPP_DETAIL_TYPE_SET_H
#include <type_traits>
#include <sqlpp11/vendor/wrong.h>
#include <sqlpp11/detail/logic.h>
namespace sqlpp
{
namespace detail
{
// some forward declarations and helpers
template<typename... T>
struct make_set;
template<typename T>
class type_set_element {};
// A type set
template<typename... Element>
struct type_set: type_set_element<Element>...
{
using size = std::integral_constant<size_t, sizeof...(Element)>;
template<typename T>
using count = std::is_base_of<type_set_element<T>, type_set>;
template<typename T>
struct is_superset_of
{
static_assert(::sqlpp::vendor::wrong_t<T>::value, "invalid argument for is_superset_of");
};
template<typename... T>
struct is_superset_of<type_set<T...>>
: and_t<count, T...> {};
template<typename T>
struct join
{
static_assert(::sqlpp::vendor::wrong_t<T>::value, "invalid argument for type_set::join");
};
template<typename... T>
struct join<type_set<T...>>
: make_set<Element..., T...> {};
template<typename T>
struct is_subset_of
{
static_assert(::sqlpp::vendor::wrong_t<T>::value, "invalid argument for is_subset_of");
};
template<typename... T>
struct is_subset_of<type_set<T...>>
: type_set<T...>::template is_superset_of<type_set>{};
template<typename T>
struct is_disjunct_from
{
static_assert(::sqlpp::vendor::wrong_t<T>::value, "invalid argument for is_disjunct_from");
};
template<typename... T>
struct is_disjunct_from<type_set<T...>>
{
static constexpr bool value = not(or_t<type_set::count, T...>::value or or_t<type_set<T...>::template count, Element...>::value);
};
template<typename T, typename Enable = void>
struct insert
{
using type = type_set;
};
template<typename T>
struct insert<T, typename std::enable_if<not type_set::template count<T>::value>::type>
{
using type = type_set<Element..., T>;
};
template<template<typename A> class Predicate, typename T>
struct insert_if
{
using type = typename std::conditional<Predicate<T>::value,
type_set<Element..., T>,
type_set>::type;
};
};
template<>
struct make_set<>
{
using type = type_set<>;
};
template<typename T, typename... Rest>
struct make_set<T, Rest...>
{
using type = typename make_set<Rest...>::type::template insert<T>::type;
};
template<template<typename> class Predicate, typename... T>
struct make_set_if;
template<template<typename> class Predicate>
struct make_set_if<Predicate>
{
using type = type_set<>;
};
template<template<typename> class Predicate, typename T, typename... Rest>
struct make_set_if<Predicate, T, Rest...>
{
using type = typename make_set_if<Predicate, Rest...>::type::template insert_if<Predicate, T>::type;
};
template<template<typename> class Predicate, typename... T>
struct make_set_if_not
{
template<typename X>
using InversePredicate = std::integral_constant<bool, not Predicate<X>::value>;
using type = typename make_set_if<InversePredicate, T...>::type;
};
template<typename... T>
using has_duplicates = std::integral_constant<bool, make_set<T...>::type::size::value != sizeof...(T)>;
}
}
#endif

View File

@ -30,9 +30,11 @@
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/parameter_list.h> #include <sqlpp11/parameter_list.h>
#include <sqlpp11/prepared_insert.h> #include <sqlpp11/prepared_insert.h>
#include <sqlpp11/default_value.h>
#include <sqlpp11/vendor/column_list.h> #include <sqlpp11/vendor/column_list.h>
#include <sqlpp11/vendor/noop.h> #include <sqlpp11/vendor/noop.h>
#include <sqlpp11/vendor/insert_list.h> #include <sqlpp11/vendor/insert_list.h>
#include <sqlpp11/vendor/assignment.h>
#include <sqlpp11/vendor/insert_value_list.h> #include <sqlpp11/vendor/insert_value_list.h>
namespace sqlpp namespace sqlpp

View File

@ -27,8 +27,9 @@
#ifndef SQLPP_MULTI_COLUMN_H #ifndef SQLPP_MULTI_COLUMN_H
#define SQLPP_MULTI_COLUMN_H #define SQLPP_MULTI_COLUMN_H
#include <sqlpp11/detail/make_expression_tuple.h>
#include <sqlpp11/no_value.h> #include <sqlpp11/no_value.h>
#include <sqlpp11/detail/make_expression_tuple.h>
#include <sqlpp11/detail/logic.h>
namespace sqlpp namespace sqlpp
{ {
@ -41,8 +42,7 @@ namespace sqlpp
template<typename AliasProvider, typename... NamedExpr> template<typename AliasProvider, typename... NamedExpr>
struct multi_column_t<AliasProvider, std::tuple<NamedExpr...>> struct multi_column_t<AliasProvider, std::tuple<NamedExpr...>>
{ {
using _named_expr_set = typename detail::make_set_if<is_named_expression_t, NamedExpr...>::type; static_assert(detail::and_t<is_named_expression_t, NamedExpr...>::value, "multi_column parameters need to be named expressions");
static_assert(_named_expr_set::size::value == sizeof...(NamedExpr), "multi_column parameters need to be named expressions");
using _name_t = typename AliasProvider::_name_t; using _name_t = typename AliasProvider::_name_t;

View File

@ -28,9 +28,9 @@
#define SQLPP_ON_H #define SQLPP_ON_H
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h>
#include <sqlpp11/vendor/interpret_tuple.h> #include <sqlpp11/vendor/interpret_tuple.h>
#include <sqlpp11/vendor/interpretable_list.h> #include <sqlpp11/vendor/interpretable_list.h>
#include <sqlpp11/detail/logic.h>
namespace sqlpp namespace sqlpp
{ {
@ -41,8 +41,7 @@ namespace sqlpp
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;
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in on()"); static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in on()");
using _valid_expressions = typename detail::make_set_if<is_expression_t, Expr...>::type; static_assert(detail::and_t<is_expression_t, Expr...>::value, "at least one argument is not an expression in on()");
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in on()");
template<typename E> template<typename E>
void add(E expr) void add(E expr)

View File

@ -29,7 +29,7 @@
#include <sqlpp11/select_fwd.h> #include <sqlpp11/select_fwd.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/type_set.h>
#include <sqlpp11/vendor/interpret_tuple.h> #include <sqlpp11/vendor/interpret_tuple.h>
#include <tuple> #include <tuple>

View File

@ -30,7 +30,7 @@
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/table_alias.h> #include <sqlpp11/table_alias.h>
#include <sqlpp11/column.h> #include <sqlpp11/column.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/type_set.h>
#include <sqlpp11/join.h> #include <sqlpp11/join.h>
#include <sqlpp11/no_value.h> #include <sqlpp11/no_value.h>
@ -41,7 +41,7 @@ namespace sqlpp
template<typename Table, typename... ColumnSpec> template<typename Table, typename... ColumnSpec>
struct table_t: public table_base_t, public ColumnSpec::_name_t::template _member_t<column_t<Table, ColumnSpec>>... struct table_t: public table_base_t, public ColumnSpec::_name_t::template _member_t<column_t<Table, ColumnSpec>>...
{ {
using _table_set = detail::set<Table>; // Hint need a set here to be similar to a join (which always represents more than one table) using _table_set = detail::type_set<Table>; // Hint need a type_set here to be similar to a join (which always represents more than one table)
using _all_columns = typename detail::make_set<column_t<Table, ColumnSpec>...>::type; using _all_columns = typename detail::make_set<column_t<Table, ColumnSpec>...>::type;
static_assert(_all_columns::size::value, "at least one column required per table"); static_assert(_all_columns::size::value, "at least one column required per table");
using _required_insert_columns = typename detail::make_set_if<require_insert_t, column_t<Table, ColumnSpec>...>::type; using _required_insert_columns = typename detail::make_set_if<require_insert_t, column_t<Table, ColumnSpec>...>::type;

View File

@ -31,7 +31,7 @@
#include <sqlpp11/interpret.h> #include <sqlpp11/interpret.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/alias.h> #include <sqlpp11/alias.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/type_set.h>
namespace sqlpp namespace sqlpp
{ {
@ -42,7 +42,7 @@ namespace sqlpp
{ {
//FIXME: Need to add join functionality //FIXME: Need to add join functionality
using _is_table = std::true_type; using _is_table = std::true_type;
using _table_set = detail::set<table_alias_t>; using _table_set = detail::type_set<table_alias_t>;
struct _value_type: Table::_value_type struct _value_type: Table::_value_type
{ {

View File

@ -28,7 +28,7 @@
#define SQLPP_COLUMN_LIST_H #define SQLPP_COLUMN_LIST_H
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/logic.h>
#include <sqlpp11/vendor/interpret_tuple.h> #include <sqlpp11/vendor/interpret_tuple.h>
#include <sqlpp11/vendor/simple_column.h> #include <sqlpp11/vendor/simple_column.h>
@ -49,12 +49,10 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Columns...>::value, "at least one duplicate argument detected in columns()"); static_assert(not ::sqlpp::detail::has_duplicates<Columns...>::value, "at least one duplicate argument detected in columns()");
// check for invalid columns // check for invalid columns
using _column_set = typename ::sqlpp::detail::make_set_if<is_column_t, Columns...>::type; static_assert(::sqlpp::detail::and_t<is_column_t, Columns...>::value, "at least one argument is not a column in columns()");
static_assert(_column_set::size::value == sizeof...(Columns), "at least one argument is not a column in columns()");
// check for prohibited columns // check for prohibited columns
using _prohibited_column_set = typename ::sqlpp::detail::make_set_if<must_not_insert_t, Columns...>::type; static_assert(not ::sqlpp::detail::or_t<must_not_insert_t, Columns...>::value, "at least one column argument has a must_not_insert flag in its definition");
static_assert(_prohibited_column_set::size::value == 0, "at least one column argument has a must_not_insert flag in its definition");
std::tuple<simple_column_t<Columns>...> _columns; std::tuple<simple_column_t<Columns>...> _columns;
}; };

View File

@ -29,7 +29,7 @@
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/vendor/interpret_tuple.h> #include <sqlpp11/vendor/interpret_tuple.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/logic.h>
namespace sqlpp namespace sqlpp
{ {
@ -39,8 +39,7 @@ namespace sqlpp
struct concat_t: public First::_value_type::template operators<concat_t<First, Args...>> struct concat_t: public First::_value_type::template operators<concat_t<First, Args...>>
{ {
static_assert(sizeof...(Args) > 0, "concat requires two arguments at least"); static_assert(sizeof...(Args) > 0, "concat requires two arguments at least");
using _valid_args = typename ::sqlpp::detail::make_set_if_not<is_text_t, First, Args...>::type; static_assert(sqlpp::detail::and_t<is_text_t, First, Args...>::value, "at least one non-text argument detected in concat()");
static_assert(_valid_args::size::value == 0, "at least one non-text argument detected in concat()");
struct _value_type: public First::_value_type::_base_value_type struct _value_type: public First::_value_type::_base_value_type
{ {

View File

@ -164,10 +164,12 @@ namespace sqlpp
template<typename Lhs, typename O, typename Rhs> template<typename Lhs, typename O, typename Rhs>
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 _lhs_t = Lhs;
using _rhs_t = Rhs;
using _value_type = typename O::_value_type; using _value_type = typename O::_value_type;
using _parameter_tuple_t = std::tuple<Lhs, Rhs>; using _parameter_tuple_t = std::tuple<_lhs_t, _rhs_t>;
binary_expression_t(Lhs lhs, Rhs rhs): binary_expression_t(_lhs_t lhs, _rhs_t rhs):
_lhs(lhs), _lhs(lhs),
_rhs(rhs) _rhs(rhs)
{} {}
@ -178,8 +180,8 @@ namespace sqlpp
binary_expression_t& operator=(binary_expression_t&&) = default; binary_expression_t& operator=(binary_expression_t&&) = default;
~binary_expression_t() = default; ~binary_expression_t() = default;
Lhs _lhs; _lhs_t _lhs;
Rhs _rhs; _rhs_t _rhs;
}; };
template<typename Context, typename Lhs, typename O, typename Rhs> template<typename Context, typename Lhs, typename O, typename Rhs>

View File

@ -27,11 +27,11 @@
#ifndef SQLPP_FROM_H #ifndef SQLPP_FROM_H
#define SQLPP_FROM_H #define SQLPP_FROM_H
#include <ostream>
#include <sqlpp11/select_fwd.h> #include <sqlpp11/select_fwd.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/vendor/interpretable_list.h> #include <sqlpp11/vendor/interpretable_list.h>
#include <sqlpp11/vendor/interpret_tuple.h> #include <sqlpp11/vendor/interpret_tuple.h>
#include <sqlpp11/detail/logic.h>
namespace sqlpp namespace sqlpp
{ {
@ -50,8 +50,7 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<TableOrJoin...>::value, "at least one duplicate argument detected in from()"); static_assert(not ::sqlpp::detail::has_duplicates<TableOrJoin...>::value, "at least one duplicate argument detected in from()");
// check for invalid arguments // check for invalid arguments
using _valid_expressions = typename ::sqlpp::detail::make_set_if<is_table_t, TableOrJoin...>::type; static_assert(::sqlpp::detail::and_t<is_table_t, TableOrJoin...>::value, "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 when looking at duplicates, for instance // FIXME: Joins contain two tables. This is not being dealt with at the moment when looking at duplicates, for instance

View File

@ -32,7 +32,7 @@
#include <sqlpp11/vendor/expression.h> #include <sqlpp11/vendor/expression.h>
#include <sqlpp11/vendor/interpret_tuple.h> #include <sqlpp11/vendor/interpret_tuple.h>
#include <sqlpp11/vendor/interpretable_list.h> #include <sqlpp11/vendor/interpretable_list.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/logic.h>
namespace sqlpp namespace sqlpp
{ {
@ -52,8 +52,7 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Expr...>::value, "at least one duplicate argument detected in group_by()"); static_assert(not ::sqlpp::detail::has_duplicates<Expr...>::value, "at least one duplicate argument detected in group_by()");
// check for invalid expressions // check for invalid expressions
using _valid_expressions = typename ::sqlpp::detail::make_set_if<is_expression_t, Expr...>::type; static_assert(::sqlpp::detail::and_t<is_expression_t, Expr...>::value, "at least one argument is not an expression in group_by()");
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in group_by()");
template<typename E> template<typename E>
void add(E expr) void add(E expr)

View File

@ -31,7 +31,7 @@
#include <sqlpp11/vendor/expression.h> #include <sqlpp11/vendor/expression.h>
#include <sqlpp11/vendor/interpret_tuple.h> #include <sqlpp11/vendor/interpret_tuple.h>
#include <sqlpp11/vendor/interpretable_list.h> #include <sqlpp11/vendor/interpretable_list.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/logic.h>
namespace sqlpp namespace sqlpp
{ {
@ -45,8 +45,7 @@ namespace sqlpp
using _parameter_tuple_t = std::tuple<Expr...>; 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 ::sqlpp::detail::make_set_if<is_expression_t, Expr...>::type; static_assert(::sqlpp::detail::and_t<is_expression_t, Expr...>::value, "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; using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;

View File

@ -30,7 +30,7 @@
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/boolean.h> #include <sqlpp11/boolean.h>
#include <sqlpp11/vendor/in_fwd.h> #include <sqlpp11/vendor/in_fwd.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/type_set.h>
namespace sqlpp namespace sqlpp
{ {

View File

@ -28,10 +28,10 @@
#define SQLPP_INSERT_LIST_H #define SQLPP_INSERT_LIST_H
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h>
#include <sqlpp11/vendor/interpret_tuple.h> #include <sqlpp11/vendor/interpret_tuple.h>
#include <sqlpp11/vendor/interpretable_list.h> #include <sqlpp11/vendor/interpretable_list.h>
#include <sqlpp11/vendor/simple_column.h> #include <sqlpp11/vendor/simple_column.h>
#include <sqlpp11/detail/logic.h>
namespace sqlpp namespace sqlpp
{ {
@ -61,6 +61,10 @@ 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<Assignments...>; using _parameter_tuple_t = std::tuple<Assignments...>;
template<template<typename...> class Target>
using copy_assignments_t = Target<Assignments...>; // FIXME: Nice idea to copy variadic template arguments?
template<template<typename...> class Target, template<typename> class Wrap>
using copy_wrapped_assignments_t = Target<Wrap<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 select expression required in set()"); static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one select expression required in set()");
@ -69,14 +73,13 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()"); static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
// check for invalid assignments // check for invalid assignments
using _assignment_set = typename ::sqlpp::detail::make_set_if<is_assignment_t, Assignments...>::type; static_assert(sqlpp::detail::and_t<is_assignment_t, Assignments...>::value, "at least one argument is not an assignment in set()");
static_assert(_assignment_set::size::value == sizeof...(Assignments), "at least one argument is not an assignment in set()");
// check for prohibited assignments // check for prohibited assignments
using _prohibited_assignment_set = typename ::sqlpp::detail::make_set_if<must_not_insert_t, typename Assignments::_column_t...>::type; static_assert(not sqlpp::detail::or_t<must_not_insert_t, typename Assignments::_column_t...>::value, "at least one assignment is prohibited by its column definition in set()");
static_assert(_prohibited_assignment_set::size::value == 0, "at least one assignment is prohibited by its column definition in set()");
insert_list_t(Assignments... assignment): insert_list_t(Assignments... assignment):
_assignments(assignment...),
_columns({assignment._lhs}...), _columns({assignment._lhs}...),
_values(assignment._rhs...) _values(assignment._rhs...)
{} {}
@ -99,6 +102,7 @@ namespace sqlpp
std::tuple<simple_column_t<typename Assignments::_column_t>...> _columns; std::tuple<simple_column_t<typename Assignments::_column_t>...> _columns;
std::tuple<typename Assignments::value_type...> _values; std::tuple<typename Assignments::value_type...> _values;
std::tuple<Assignments...> _assignments; // FIXME: Need to replace _columns and _values by _assignments (connector-container requires assignments)
typename vendor::interpretable_list_t<Database> _dynamic_columns; typename vendor::interpretable_list_t<Database> _dynamic_columns;
typename vendor::interpretable_list_t<Database> _dynamic_values; typename vendor::interpretable_list_t<Database> _dynamic_values;
}; };

View File

@ -28,7 +28,7 @@
#define SQLPP_INSERT_VALUE_LIST_H #define SQLPP_INSERT_VALUE_LIST_H
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/logic.h>
#include <sqlpp11/vendor/insert_value.h> #include <sqlpp11/vendor/insert_value.h>
#include <sqlpp11/vendor/interpret_tuple.h> #include <sqlpp11/vendor/interpret_tuple.h>
@ -44,8 +44,7 @@ namespace sqlpp
static_assert(sizeof...(InsertValues), "at least one insert value required"); static_assert(sizeof...(InsertValues), "at least one insert value required");
// check for invalid arguments // check for invalid arguments
using _insert_values_set = typename ::sqlpp::detail::make_set_if<is_insert_value_t, InsertValues...>::type; static_assert(::sqlpp::detail::and_t<is_insert_value_t, InsertValues...>::value, "at least one argument is not an insert value");
static_assert(_insert_values_set::size::value == sizeof...(InsertValues), "at least one argument is not an insert value");
using _value_tuple_t = std::tuple<InsertValues...>; using _value_tuple_t = std::tuple<InsertValues...>;

View File

@ -29,7 +29,7 @@
#include <sqlpp11/boolean.h> #include <sqlpp11/boolean.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/type_set.h>
namespace sqlpp namespace sqlpp
{ {

View File

@ -29,7 +29,7 @@
#include <sqlpp11/boolean.h> #include <sqlpp11/boolean.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/type_set.h>
namespace sqlpp namespace sqlpp
{ {

View File

@ -51,8 +51,7 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Expr...>::value, "at least one duplicate argument detected in order_by()"); static_assert(not ::sqlpp::detail::has_duplicates<Expr...>::value, "at least one duplicate argument detected in order_by()");
// check for invalid order expressions // check for invalid order expressions
using _valid_expressions = typename ::sqlpp::detail::make_set_if<is_sort_order_t, Expr...>::type; static_assert(::sqlpp::detail::and_t<is_sort_order_t, Expr...>::value, "at least one argument is not a sort order expression in order_by()");
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not a sort order expression in order_by()");
template<typename E> template<typename E>
void add(E expr) void add(E expr)

View File

@ -31,13 +31,13 @@
#include <sqlpp11/result_row.h> #include <sqlpp11/result_row.h>
#include <sqlpp11/select_fwd.h> #include <sqlpp11/select_fwd.h>
#include <sqlpp11/table.h> #include <sqlpp11/table.h>
#include <sqlpp11/vendor/expression_fwd.h>
#include <sqlpp11/no_value.h> #include <sqlpp11/no_value.h>
#include <sqlpp11/vendor/field.h> #include <sqlpp11/vendor/field.h>
#include <sqlpp11/vendor/expression_fwd.h>
#include <sqlpp11/vendor/select_pseudo_table.h> #include <sqlpp11/vendor/select_pseudo_table.h>
#include <sqlpp11/vendor/named_interpretable.h> #include <sqlpp11/vendor/named_interpretable.h>
#include <sqlpp11/vendor/interpret_tuple.h> #include <sqlpp11/vendor/interpret_tuple.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/type_set.h>
namespace sqlpp namespace sqlpp
{ {
@ -149,9 +149,8 @@ namespace sqlpp
// check for invalid select expressions // check for invalid select expressions
template<typename T> template<typename T>
struct is_valid_expression_t: public std::integral_constant<bool, is_named_expression_t<T>::value or is_multi_column_t<T>::value> {}; using is_valid_expression_t = std::integral_constant<bool, is_named_expression_t<T>::value or is_multi_column_t<T>::value>;
using _valid_expressions = typename ::sqlpp::detail::make_set_if<is_valid_expression_t, NamedExpr...>::type; static_assert(::sqlpp::detail::and_t<is_valid_expression_t, NamedExpr...>::value, "at least one argument is not a named expression");
static_assert(_valid_expressions::size::value == sizeof...(NamedExpr), "at least one argument is not a named expression");
// check for duplicate select expression names // check for duplicate select expression names
static_assert(not ::sqlpp::detail::has_duplicates<typename NamedExpr::_name_t...>::value, "at least one duplicate name detected"); static_assert(not ::sqlpp::detail::has_duplicates<typename NamedExpr::_name_t...>::value, "at least one duplicate name detected");

View File

@ -30,7 +30,7 @@
#include <sqlpp11/select_fwd.h> #include <sqlpp11/select_fwd.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/select_flags.h> #include <sqlpp11/select_flags.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/type_set.h>
#include <sqlpp11/vendor/interpret_tuple.h> #include <sqlpp11/vendor/interpret_tuple.h>
#include <tuple> #include <tuple>
@ -57,8 +57,7 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Flag...>::value, "at least one duplicate argument detected in select flag list"); static_assert(not ::sqlpp::detail::has_duplicates<Flag...>::value, "at least one duplicate argument detected in select flag list");
// check for invalid order expressions // check for invalid order expressions
using _valid_flags = typename ::sqlpp::detail::make_set_if<is_select_flag_t, Flag...>::type; static_assert(::sqlpp::detail::and_t<is_select_flag_t, Flag...>::value, "at least one argument is not a select flag in select flag list");
static_assert(_valid_flags::size::value == sizeof...(Flag), "at least one argument is not a select flag in select flag list");
template<typename E> template<typename E>
void add(E expr) void add(E expr)

View File

@ -28,7 +28,7 @@
#define SQLPP_UPDATE_LIST_H #define SQLPP_UPDATE_LIST_H
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/type_set.h>
#include <sqlpp11/vendor/interpret_tuple.h> #include <sqlpp11/vendor/interpret_tuple.h>
#include <sqlpp11/vendor/interpretable_list.h> #include <sqlpp11/vendor/interpretable_list.h>
@ -50,12 +50,10 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()"); static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
// check for invalid assignments // check for invalid assignments
using _assignment_set = typename ::sqlpp::detail::make_set_if<is_assignment_t, Assignments...>::type; static_assert(::sqlpp::detail::and_t<is_assignment_t, Assignments...>::value, "at least one argument is not an assignment in set()");
static_assert(_assignment_set::size::value == sizeof...(Assignments), "at least one argument is not an assignment in set()");
// check for prohibited assignments // check for prohibited assignments
using _prohibited_assignment_set = typename ::sqlpp::detail::make_set_if<must_not_update_t, typename Assignments::_column_t...>::type; static_assert(not ::sqlpp::detail::or_t<must_not_update_t, typename Assignments::_column_t...>::value, "at least one assignment is prohibited by its column definition in set()");
static_assert(_prohibited_assignment_set::size::value == 0, "at least one assignment is prohibited by its column definition in set()");
template<typename Assignment> template<typename Assignment>
void add(Assignment assignment) void add(Assignment assignment)

View File

@ -28,9 +28,9 @@
#define SQLPP_USING_H #define SQLPP_USING_H
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h>
#include <sqlpp11/vendor/interpretable_list.h> #include <sqlpp11/vendor/interpretable_list.h>
#include <sqlpp11/vendor/interpret_tuple.h> #include <sqlpp11/vendor/interpret_tuple.h>
#include <sqlpp11/detail/type_set.h>
namespace sqlpp namespace sqlpp
{ {
@ -49,8 +49,7 @@ namespace sqlpp
static_assert(not ::sqlpp::detail::has_duplicates<Table...>::value, "at least one duplicate argument detected in using()"); static_assert(not ::sqlpp::detail::has_duplicates<Table...>::value, "at least one duplicate argument detected in using()");
// check for invalid arguments // check for invalid arguments
using _valid_expressions = typename ::sqlpp::detail::make_set_if<is_table_t, Table...>::type; static_assert(::sqlpp::detail::and_t<is_table_t, Table...>::value, "at least one argument is not an table in using()");
static_assert(_valid_expressions::size::value == sizeof...(Table), "at least one argument is not an table in using()");
template<typename T> template<typename T>

View File

@ -31,7 +31,7 @@
#include <sqlpp11/select_fwd.h> #include <sqlpp11/select_fwd.h>
#include <sqlpp11/vendor/expression.h> #include <sqlpp11/vendor/expression.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/logic.h>
#include <sqlpp11/vendor/interpret_tuple.h> #include <sqlpp11/vendor/interpret_tuple.h>
#include <sqlpp11/vendor/interpretable_list.h> #include <sqlpp11/vendor/interpretable_list.h>
#include <sqlpp11/parameter_list.h> #include <sqlpp11/parameter_list.h>
@ -48,8 +48,7 @@ namespace sqlpp
using _parameter_tuple_t = std::tuple<Expr...>; 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 sqlpp::detail::make_set_if<is_expression_t, Expr...>::type; static_assert(sqlpp::detail::and_t<is_expression_t, Expr...>::value, "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; using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;

View File

@ -14,8 +14,10 @@ build_and_run(SelectTest)
build_and_run(FunctionTest) build_and_run(FunctionTest)
build_and_run(PreparedTest) build_and_run(PreparedTest)
find_package(PythonInterp REQUIRED)
add_custom_command( add_custom_command(
OUTPUT ${CMAKE_CURRENT_LIST_DIR}/Sample.h OUTPUT ${CMAKE_CURRENT_LIST_DIR}/Sample.h
COMMAND ${CMAKE_SOURCE_DIR}/scripts/ddl2cpp ${CMAKE_CURRENT_LIST_DIR}/sample.sql Sample test COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripts/ddl2cpp ${CMAKE_CURRENT_LIST_DIR}/sample.sql Sample test
) )