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

Initial commit

This commit is contained in:
Roland Bock 2013-08-13 22:43:10 +02:00
parent 7651d5f204
commit 705f39e379
57 changed files with 5587 additions and 2 deletions

View File

@ -1,4 +1,4 @@
Copyright (c) 2013, rbock
Copyright (c) 2013, Roland Bock
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -20,4 +20,4 @@ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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.
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -2,3 +2,85 @@ sqlpp11
=======
A type safe SQL template library for C++
Motivation:
-----------
SQL and C++ are both strongly typed languages. They should play well together. Still, most C/C++ interface are based on constructing strings for querys and on interpreting arrays or maps of strings as results. Typicaly there are a bunch of helper functions and classes that help to construct queries, to interpret results or to avoid code injection.
sqlpp11 is a templated library representing an embedded domain specific language (EDSL) that allows you to
* define types representing tables and columns
* construct typesafe queries checked at compile time for syntax errors, type errors, name errors and even some semantic errors
* interpret results by iterating over query-specific structs with appropriately named and typed members
Under the hood, it still communicates with the database via strings, but the library user operates on structs and functions. And the compiler will report many kinds of errors long before the code enters unit testing or production.
Examples:
---------
For the examples, lets assume you had a table class representing something like
```SQL
CREATE TABLE foo (
id bigint,
name varchar(50),
hasFun bool
);
```
And we assume to have a database connection object:
```C++
TabFoo foo;
Db db(/* some arguments*/);
// selecting zero or more results, iterating over the results
for (const auto& row: db.run(select(foo.name, foo.hasFun).from(foo).where(foo.id > 17 and foo.name.like("%bar%"))))
{
if (row.name.is_null())
std::cerr << "name is null, will convert to empty string" << std::endl;
std::string name = row.name; // string-like fields are implicitly convertible to string
bool hasFun = hasFun; // bool fields are implicitly convertible to bool
}
// selecting ALL columns of a table
for (const auto& row: db.run(select(all_of(foo)).from(foo).where(hasFun or foo.name == "joker")))
{
int64_t id = row.id; // numeric fields are implicitly convertible to numeric c++ types
}
// selecting zero or one row, showing off with an alias:
SQLPP_ALIAS_PROVIDER_GENERATOR(cheese);
if (const auto& row = db.run(select(foo.name.as(cheese)).from(foo).where(foo.id == 17)))
{
std::cerr << "found: " << row.cheese << std::endl;
}
// selecting exactly one row:
return db.run(select(count(foo.id)).from(foo))->count;
Of course there are joins and subqueries, more functions, order_by, group_by etc.
These will be documented soon.
// A sample insert
db.run(insert_into(foo).set(foo.id = 17, foo.name = "bar", foo.hasFun = true));
// A sample update
db.run(update(foo).set(foo.hasFun = not foo.hasFun).where(foo.name != "nobody");
// A sample delete
db.run(remove_from(tab).where(not tab.hasFun));
```
Requirements:
-------------
sqlpp11 makes heavy use of C++11. It has been developed using
clang-3.2 on Ubuntu-10.4 with matching libc++
It also requires a database library with a matching interface, see database/api.h
Links to sample implementations will follow soon.

110
alias.h Normal file
View File

@ -0,0 +1,110 @@
/*
* 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_ALIAS_H
#define SQLPP_ALIAS_H
#include <sqlpp11/type_traits.h>
namespace sqlpp
{
namespace alias
{
#define SQLPP_ALIAS_PROVIDER_GENERATOR(name) \
struct name##_t\
{\
struct _name_t\
{\
static constexpr const char* _get_name() { return #name; }\
};\
template<typename 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;\
};\
};\
constexpr name##_t name = {};
SQLPP_ALIAS_PROVIDER_GENERATOR(a);
SQLPP_ALIAS_PROVIDER_GENERATOR(b);
SQLPP_ALIAS_PROVIDER_GENERATOR(c);
SQLPP_ALIAS_PROVIDER_GENERATOR(d);
SQLPP_ALIAS_PROVIDER_GENERATOR(e);
SQLPP_ALIAS_PROVIDER_GENERATOR(f);
SQLPP_ALIAS_PROVIDER_GENERATOR(g);
SQLPP_ALIAS_PROVIDER_GENERATOR(h);
SQLPP_ALIAS_PROVIDER_GENERATOR(i);
SQLPP_ALIAS_PROVIDER_GENERATOR(j);
SQLPP_ALIAS_PROVIDER_GENERATOR(k);
SQLPP_ALIAS_PROVIDER_GENERATOR(l);
SQLPP_ALIAS_PROVIDER_GENERATOR(m);
SQLPP_ALIAS_PROVIDER_GENERATOR(n);
SQLPP_ALIAS_PROVIDER_GENERATOR(o);
SQLPP_ALIAS_PROVIDER_GENERATOR(p);
SQLPP_ALIAS_PROVIDER_GENERATOR(q);
SQLPP_ALIAS_PROVIDER_GENERATOR(s);
SQLPP_ALIAS_PROVIDER_GENERATOR(t);
SQLPP_ALIAS_PROVIDER_GENERATOR(u);
SQLPP_ALIAS_PROVIDER_GENERATOR(v);
SQLPP_ALIAS_PROVIDER_GENERATOR(w);
SQLPP_ALIAS_PROVIDER_GENERATOR(x);
SQLPP_ALIAS_PROVIDER_GENERATOR(y);
SQLPP_ALIAS_PROVIDER_GENERATOR(z);
SQLPP_ALIAS_PROVIDER_GENERATOR(left);
SQLPP_ALIAS_PROVIDER_GENERATOR(right);
};
template<typename Expression, typename AliasProvider>
struct expression_alias_t
{
struct _value_type: Expression::_value_type
{
using _is_expression = tag_no;
using _is_named_expression = tag_yes;
using _is_alias = tag_yes;
};
using _name_t = typename AliasProvider::_name_t;
template<typename T>
using _member_t = typename AliasProvider::template _member_t<T>;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << "("; _expression.serialize(os, db); os << ") AS " << _name_t::_get_name();
}
Expression _expression;
};
}
#endif

67
assignment_list.h Normal file
View File

@ -0,0 +1,67 @@
/*
* 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_ASSIGNMENT_LIST_H
#define SQLPP_ASSIGNMENT_LIST_H
#include <sqlpp11/detail/set.h>
#include <sqlpp11/detail/serialize_tuple.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp
{
template<template<typename> class ProhibitPredicate, typename... Assignment>
struct assignment_list_t
{
// check for at least one order expression
static_assert(sizeof...(Assignment), "at least one select expression required in set()");
// check for duplicate assignments
static_assert(not detail::has_duplicates<Assignment...>::value, "at least one duplicate argument detected in set()");
// check for invalid assignments
using _assignment_set = typename detail::make_set_if<is_assignment_t, Assignment...>::type;
static_assert(_assignment_set::size::value == sizeof...(Assignment), "at least one argument is not an assignment in set()");
// check for prohibited assignments
using _prohibited_assignment_set = typename detail::make_set_if<ProhibitPredicate, typename Assignment::column_type...>::type;
static_assert(_prohibited_assignment_set::size::value == 0, "at least one assignment is prohibited by its column definition in set()");
using _is_assignment_list = tag_yes;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << " SET ";
detail::serialize_tuple(os, db, _assignments, ',');
}
std::tuple<Assignment...> _assignments;
};
}
#endif

148
boolean.h Normal file
View File

@ -0,0 +1,148 @@
/*
* 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_BOOLEAN_H
#define SQLPP_BOOLEAN_H
#include <cstdlib>
#include <sqlpp11/detail/basic_operators.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/raw_result_row.h>
#include <sqlpp11/exception.h>
namespace sqlpp
{
// boolean operators
namespace detail
{
struct or_
{
using _value_type = boolean;
static constexpr const char* _name = "OR";
};
struct and_
{
using _value_type = boolean;
static constexpr const char* _name = "AND";
};
struct not_
{
using _value_type = boolean;
static constexpr const char* _name = "NOT";
};
// boolean value type
struct boolean
{
using _base_value_type = boolean;
using _is_boolean = tag_yes;
using _is_value = tag_yes;
using _is_expression = tag_yes;
struct plus_
{
using _value_type = boolean;
static constexpr const char* _name = "+";
};
template<size_t index>
struct _result_entry_t
{
_result_entry_t(const raw_result_row_t& row):
_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)
{
_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);
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; }
bool value() const
{
if (not _is_valid)
throw exception("accessing value in non-existing row");
return _value;
}
operator bool() const { return value(); }
private:
bool _is_valid;
bool _is_null;
bool _value;
};
template<typename T>
using _constraint = operand_t<T, is_boolean_t>;
template<typename Base>
struct operators: public basic_operators<Base, _constraint>
{
template<typename T>
nary_expression_t<Base, and_, typename _constraint<T>::type> operator and(T&& t) const
{
return { *static_cast<const Base*>(this), std::forward<T>(t) };
}
template<typename T>
nary_expression_t<Base, or_, typename _constraint<T>::type> operator or(T&& t) const
{
return { *static_cast<const Base*>(this), std::forward<T>(t) };
}
not_t<Base> operator not() const
{
return { *static_cast<const Base*>(this) };
}
};
};
template<size_t index>
std::ostream& operator<<(std::ostream& os, const boolean::_result_entry_t<index>& e)
{
return os << e.value();
}
}
using boolean = detail::boolean;
}
#endif

77
column.h Normal file
View File

@ -0,0 +1,77 @@
/*
* 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_COLUMN_H
#define SQLPP_COLUMN_H
#include <ostream>
#include <sqlpp11/expression.h>
#include <sqlpp11/alias.h>
#include <sqlpp11/column_fwd.h>
#include <sqlpp11/detail/wrong.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/sort_order.h>
namespace sqlpp
{
template<typename Table, typename ColumnSpec>
struct column_t: public ColumnSpec::_value_type::template operators<column_t<Table, ColumnSpec>>
{
using _table = Table;
using _column_type = typename ColumnSpec::_column_type;
struct _value_type: ColumnSpec::_value_type
{
using _is_expression = tag_yes;
using _is_named_expression = tag_yes;
using _is_alias = tag_no;
};
using _name_t = typename ColumnSpec::_name_t;
template<typename T>
using _member_t = typename ColumnSpec::template _member_t<T>;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << Table::_name_t::_get_name() << '.' << _name_t::_get_name();
}
template<typename alias_provider>
expression_alias_t<column_t, typename std::decay<alias_provider>::type> as(alias_provider&&) const
{
return { *this };
}
template<typename T>
assignment_t<column_t, typename _value_type::template _constraint<T>::type> operator =(T&& t) const
{
return { *this, std::forward<T>(t) };
}
};
}
#endif

37
column_fwd.h Normal file
View File

@ -0,0 +1,37 @@
/*
* 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_COLUMN_FWD_H
#define SQLPP_COLUMN_FWD_H
namespace sqlpp
{
template<typename Table, typename ColumnSpec>
class column_t;
}
#endif

34
column_types.h Normal file
View File

@ -0,0 +1,34 @@
/*
* 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_COLUMN_TYPES_H
#define SQLPP_COLUMN_TYPES_H
#include <sqlpp11/boolean.h>
#include <sqlpp11/numeric.h>
#include <sqlpp11/text.h>
#endif

36
connection.h Normal file
View File

@ -0,0 +1,36 @@
/*
* 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_CONNECTION_H
#define SQLPP_CONNECTION_H
namespace sqlpp
{
struct connection {};
}
#endif

103
database/api.h Normal file
View File

@ -0,0 +1,103 @@
/*
* 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
{
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 nullptr, if there is no next row
sqlpp::raw_result_row_t next();
size_t num_cols() const;
size_t num_rows() const;
};
class connection: public sqlpp::connection
{
public:
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

176
detail/basic_operators.h Normal file
View File

@ -0,0 +1,176 @@
/*
* 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_BASIC_OPERATORS_H
#define SQLPP_DETAIL_BASIC_OPERATORS_H
#include <sqlpp11/expression_fwd.h>
#include <sqlpp11/alias.h>
#include <sqlpp11/sort_order.h>
namespace sqlpp
{
namespace detail
{
struct boolean;
// operators
struct lt_
{
using _value_type = boolean;
static constexpr const char* _name = "<";
};
struct le_
{
using _value_type = boolean;
static constexpr const char* _name = "<=";
};
struct ge_
{
using _value_type = boolean;
static constexpr const char* _name = ">=";
};
struct gt_
{
using _value_type = boolean;
static constexpr const char* _name = ">";
};
struct is_null_
{
using _value_type = boolean;
static constexpr const char* _name = "IS NULL";
};
struct is_not_null_
{
using _value_type = boolean;
static constexpr const char* _name = "IS NOT NULL";
};
struct in_
{
using _value_type = boolean;
static constexpr const char* _name = "IN";
};
struct not_in_
{
using _value_type = boolean;
static constexpr const char* _name = "NOT IN";
};
// basic operators
template<typename Base, template<typename> class Constraint>
struct basic_operators
{
template<typename T>
equal_t<Base, typename Constraint<T>::type> operator==(T&& t) const
{
return { *static_cast<const Base*>(this), std::forward<T>(t) };
}
template<typename T>
not_equal_t<Base, typename Constraint<T>::type> operator!=(T&& t) const
{
return { *static_cast<const Base*>(this), std::forward<T>(t) };
}
template<typename T>
nary_expression_t<Base, lt_, typename Constraint<T>::type> operator<(T&& t) const
{
return { *static_cast<const Base*>(this), std::forward<T>(t) };
}
template<typename T>
nary_expression_t<Base, le_, typename Constraint<T>::type> operator<=(T&& t) const
{
return { *static_cast<const Base*>(this), std::forward<T>(t) };
}
template<typename T>
nary_expression_t<Base, ge_, typename Constraint<T>::type> operator>=(T&& t) const
{
return { *static_cast<const Base*>(this), std::forward<T>(t) };
}
template<typename T>
nary_expression_t<Base, gt_, typename Constraint<T>::type> operator>(T&& t) const
{
return { *static_cast<const Base*>(this), std::forward<T>(t) };
}
nary_expression_t<Base, is_null_> is_null() const
{
return { *static_cast<const Base*>(this) };
}
nary_expression_t<Base, is_not_null_> is_not_null() const
{
return { *static_cast<const Base*>(this) };
}
sort_order_t<Base, sort_type::asc> asc()
{
return { *static_cast<const Base*>(this) };
}
sort_order_t<Base, sort_type::desc> desc()
{
return { *static_cast<const Base*>(this) };
}
// Hint: use wrappers for containers...
template<typename... T>
nary_expression_t<Base, in_, typename Constraint<T>::type...> in(T&&... t) const
{
static_assert(sizeof...(T) > 0, "in() requires at least one argument");
return { *static_cast<const Base*>(this), std::forward<T>(t)... };
}
template<typename... T>
nary_expression_t<Base, not_in_, typename Constraint<T>::type...> not_in(T&&... t) const
{
static_assert(sizeof...(T) > 0, "not_in() requires at least one argument");
return { *static_cast<const Base*>(this), std::forward<T>(t)... };
}
template<typename alias_provider>
expression_alias_t<Base, typename std::decay<alias_provider>::type> as(alias_provider&&)
{
return { *static_cast<const Base*>(this) };
}
constexpr bool _is_trivial() const { return false; }
};
}
}
#endif

View File

@ -0,0 +1,66 @@
/*
* 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_MAKE_EXPRESSION_TUPLE_H
#define SQLPP_DETAIL_MAKE_EXPRESSION_TUPLE_H
namespace sqlpp
{
namespace detail
{
template<typename Expr>
auto make_single_expression_tuple(Expr&& expr) -> typename std::enable_if<is_named_expression_t<typename std::decay<Expr>::type>::value, decltype(std::make_tuple(expr))>::type
{
return std::make_tuple(std::forward<Expr>(expr));
};
template<typename Expr>
auto make_single_expression_tuple(Expr&& expr) -> typename std::enable_if<is_select_flag_t<typename std::decay<Expr>::type>::value, std::tuple<>>::type
{
return {};
};
template<typename Tab>
auto make_single_expression_tuple(Tab&& tab) -> typename std::enable_if<is_table_t<typename std::decay<Tab>::type>::value, typename std::decay<Tab>::type::_all_of_t>::type
{
return {};
};
template<typename... Expr>
auto make_single_expression_tuple(std::tuple<Expr...>&& t) -> std::tuple<Expr...>
{
return t;
};
template<typename... Expr>
auto make_expression_tuple(Expr&&... expr) -> decltype(std::tuple_cat(make_single_expression_tuple(std::forward<Expr>(expr))...))
{
return std::tuple_cat(make_single_expression_tuple(std::forward<Expr>(expr))...);
};
}
}
#endif

70
detail/make_flag_tuple.h Normal file
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_DETAIL_MAKE_FLAG_TUPLE_H
#define SQLPP_DETAIL_MAKE_FLAG_TUPLE_H
namespace sqlpp
{
namespace detail
{
// accept select flags
template<typename Expr>
auto make_single_flag_tuple(Expr&& expr) -> typename std::enable_if<is_select_flag_t<typename std::decay<Expr>::type>::value, decltype(std::make_tuple(expr))>::type
{
return std::make_tuple(std::forward<Expr>(expr));
};
// ignore named expressions
template<typename Expr>
auto make_single_flag_tuple(Expr&& expr) -> typename std::enable_if<is_named_expression_t<typename std::decay<Expr>::type>::value, std::tuple<>>::type
{
return {};
};
// ignore tables
template<typename Tab>
auto make_single_flag_tuple(Tab&& tab) -> typename std::enable_if<is_table_t<typename std::decay<Tab>::type>::value, std::tuple<>>::type
{
return {};
};
// ignore tuples of expressions
template<typename... Expr>
auto make_single_flag_tuple(std::tuple<Expr...>&& t) -> std::tuple<>
{
return {};
};
template<typename... Expr>
auto make_flag_tuple(Expr&&... expr) -> decltype(std::tuple_cat(make_single_flag_tuple(std::forward<Expr>(expr))...))
{
return std::tuple_cat(make_single_flag_tuple(std::forward<Expr>(expr))...);
};
}
}
#endif

73
detail/serialize_tuple.h Normal file
View File

@ -0,0 +1,73 @@
/*
* 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_SERIALIZE_TUPLE_H
#define SQLPP_DETAIL_SERIALIZE_TUPLE_H
#include <tuple>
#include <ostream>
#include <sqlpp11/type_traits.h>
namespace sqlpp
{
namespace detail
{
template<std::size_t begin, std::size_t index, std::size_t end>
struct tuple_serializer_impl
{
template<typename Db, typename Tuple>
static void serialize(std::ostream& os, Db& db, const Tuple& flags_and_columns, char separator)
{
if (index > begin)
os << separator;
const auto& entry = std::get<index>(flags_and_columns);
using entry_type = typename std::tuple_element<index, Tuple>::type;
if (requires_braces_t<entry_type>::value)
os << "(";
entry.serialize(os, db);
if (requires_braces_t<entry_type>::value)
os << ")";
tuple_serializer_impl<begin, index + 1, end>::serialize(os, db, flags_and_columns, separator);
}
};
template<std::size_t begin, std::size_t end>
struct tuple_serializer_impl<begin, end, end>
{
template<typename Db, typename Tuple>
static void serialize(std::ostream& os, Db& db, const Tuple& flags_and_columns, char separator)
{
}
};
template<typename Db, typename Tuple>
static void serialize_tuple(std::ostream& os, Db& db, const Tuple& flags_and_columns, char separator)
{
tuple_serializer_impl<0, 0, std::tuple_size<Tuple>::value>::serialize(os, db, flags_and_columns, separator);
}
}
}
#endif

214
detail/set.h Normal file
View File

@ -0,0 +1,214 @@
/*
* 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/detail/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(wrong<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(wrong<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(wrong<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(wrong<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(wrong<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 = 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)> {};
#if WANT_AUTO_JOIN
template<typename T>
struct begin // FIXME: Should move this into set struct
{
static_assert(wrong<T>::value, "begin template used on invalid type container");
};
template<typename T, typename... Rest>
struct begin<set<T, Rest...>>
{
using type = T;
};
#endif // WANT_AUTO_JOIN
}
}
#endif

40
detail/tag.h Normal file
View File

@ -0,0 +1,40 @@
/*
* 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_TAG_H
#define SQLPP_DETAIL_TAG_H
namespace sqlpp
{
namespace detail
{
struct tag {};
}
using tag_yes = detail::tag;
using tag_no = void;
}
#endif

123
detail/wrap_operand.h Normal file
View File

@ -0,0 +1,123 @@
/*
* 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_WRAP_OPERAND_H
#define SQLPP_DETAIL_WRAP_OPERAND_H
#include <ostream>
#include <type_traits>
namespace sqlpp
{
namespace detail
{
struct boolean;
struct numeric;
struct text;
struct bool_operand
{
static constexpr bool _is_expression = true;
using _value_type = boolean;
bool_operand(bool t): _t(t) {}
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << _t;
}
bool _is_trivial() const { return _t == false; }
const bool _t;
};
template<typename T>
struct numeric_operand
{
static constexpr bool _is_expression = true;
using _value_type = numeric;
numeric_operand(T t): _t(t) {}
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << _t;
}
bool _is_trivial() const { return _t == 0; }
const T _t;
};
template<typename T>
struct text_operand
{
static constexpr bool _is_expression = true;
using _value_type = text;
text_operand(const T& t): _t(t) {}
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << '"' << db.escape(_t) << '"';
}
bool _is_trivial() const { return _t.empty(); }
const std::string _t;
};
template<typename T, typename Enable = void>
struct wrap_operand
{
using type = T;
};
template<>
struct wrap_operand<bool, void>
{
using type = bool_operand;
};
template<typename T>
struct wrap_operand<T, typename std::enable_if<std::is_integral<T>::value>::type>
{
using type = numeric_operand<T>;
};
template<typename T>
struct wrap_operand<T, typename std::enable_if<std::is_convertible<T, std::string>::value>::type>
{
using type = text_operand<T>;
};
}
}
#endif

42
detail/wrong.h Normal file
View File

@ -0,0 +1,42 @@
/*
* 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_WRONG_H
#define SQLPP_DETAIL_WRONG_H
#include <type_traits>
namespace sqlpp
{
namespace detail
{
// A template that always returns false
// To be used with static assert, for instance, to ensure it
// fires only when the template is instantiated.
template<class ...T> struct wrong : std::false_type {};
}
}
#endif

54
examples/InsertTest.cpp Normal file
View File

@ -0,0 +1,54 @@
/*
* 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 <iostream>
#include <sqlpp11/insert.h>
#include <sqlpp11/select.h>
#include <sqlpp11/examples/TabSample.h>
#include <iostream>
class DbMock
{
public:
const std::string& escape(const std::string& text) { return text; }
};
DbMock db;
int main()
{
TabSample t;
auto x = t.alpha = 7;
auto y = t.beta = "kaesekuchen";
auto z = t.gamma = true;
insert_into(t).serialize(std::cerr, db); std::cerr << "\n";
insert_into(t).set(t.beta = "kirschauflauf").serialize(std::cerr, db); std::cerr << "\n";
//insert_into(t).values(7, "wurstwaren", true).serialize(std::cerr, db); std::cerr << "\n";
//insert_into(t).columns(t.alpha, t.beta).values(25, "drei").serialize(std::cerr, db); std::cerr << "\n";
//insert_into(t).columns(t.alpha, t.beta).select(select(t.alpha, t.beta).from(t)).serialize(std::cerr, db);
return 0;
}

55
examples/RemoveTest.cpp Normal file
View File

@ -0,0 +1,55 @@
/*
* 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 <iostream>
#include <sqlpp11/remove.h>
#include <sqlpp11/select.h>
#include <sqlpp11/examples/TabSample.h>
#include <iostream>
class DbMock
{
public:
const std::string& escape(const std::string& text) { return text; }
};
DbMock db;
int main()
{
TabSample t;
auto x = t.alpha = 7;
auto y = t.beta = "kaesekuchen";
auto z = t.gamma = true;
remove_from(t).serialize(std::cerr, db); std::cerr << "\n";
remove_from(t).where(t.beta != "transparent").serialize(std::cerr, db); std::cerr << "\n";
remove_from(t).using_(t).serialize(std::cerr, db); std::cerr << "\n";
//insert_into(t).values(7, "wurstwaren", true).serialize(std::cerr, db); std::cerr << "\n";
//insert_into(t).columns(t.alpha, t.beta).values(25, "drei").serialize(std::cerr, db); std::cerr << "\n";
//insert_into(t).columns(t.alpha, t.beta).select(select(t.alpha, t.beta).from(t)).serialize(std::cerr, db);
return 0;
}

282
examples/SelectTest.cpp Normal file
View File

@ -0,0 +1,282 @@
/*
* 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 <sqlpp11/examples/TabSample.h>
#include <sqlpp11/select.h>
#include <iostream>
class DbMock
{
public:
const std::string& escape(const std::string& text) { return text; }
};
DbMock db;
int main()
{
TabSample t;
// Test a table
{
using T = decltype(t);
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(sqlpp::is_table_t<T>::value, "type requirement");
}
// Test an alias of table
{
using T = decltype(t.as(sqlpp::alias::a));
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(sqlpp::is_table_t<T>::value, "type requirement");
}
// Test a colum of an alias of table
{
using T = decltype(t.as(sqlpp::alias::a).alpha);
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
static_assert(sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(sqlpp::must_not_update_t<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
}
// Test a numeric table column
{
using T = decltype(t.alpha);
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
static_assert(sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(sqlpp::must_not_update_t<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
}
// Test a an alias of a numeric table column
{
using T = decltype(t.alpha.as(sqlpp::alias::a));
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
}
// Test a select of a single column without a from
{
using T = decltype(select(t.alpha)); // Hint: The current rule is pretty crude (a from is required), but certainly better than nothing
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
}
// Test a select of a single numeric table column
{
using T = decltype(select(t.alpha).from(t));
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
}
// Test a select of an alias of a single numeric table column
{
using T = decltype(select(t.alpha.as(sqlpp::alias::a)).from(t));
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
}
// Test an alias of a select of a single numeric table column
{
using T = decltype(select(t.alpha).from(t).as(sqlpp::alias::b));
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean_t<T>::value, "red to not be boolean");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(sqlpp::is_table_t<T>::value, "type requirement");
}
// Test the column of an alias of a select of an alias of a single numeric table column
{
using T = decltype(select(t.alpha.as(sqlpp::alias::a)).from(t).as(sqlpp::alias::b));
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(sqlpp::is_table_t<T>::value, "type requirement");
}
// Test the column of an alias of a select of a single numeric table column
{
using T = decltype(select(t.alpha).from(t).as(sqlpp::alias::b).alpha);
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
}
// Test an alias of a select of an alias of a single numeric table column
{
using T = decltype(select(t.alpha.as(sqlpp::alias::a)).from(t).as(sqlpp::alias::b).a);
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
}
// Test that select(all_of(tab)) is expanded in select
{
auto a = select(all_of(t));
auto b = select(t.alpha, t.beta, t.gamma);
auto c = select(t);
static_assert(std::is_same<decltype(a), decltype(b)>::value, "all_of(t) has to be expanded by select()");
static_assert(std::is_same<decltype(b), decltype(c)>::value, "t has to be expanded by select()");
}
// Test that select(all_of(tab)) is expanded in multi_column
{
auto a = multi_column(sqlpp::alias::a, all_of(t));
auto b = multi_column(sqlpp::alias::a, t.alpha, t.beta, t.gamma);
static_assert(std::is_same<decltype(a), decltype(b)>::value, "all_of(t) has to be expanded by multi_column");
}
// Test that a multicolumn is not a value
{
auto m = multi_column(sqlpp::alias::a, t.alpha, t.beta);
auto a = select(m).from(t).as(sqlpp::alias::b).a;
static_assert(not sqlpp::is_value_t<decltype(a)>::value, "a multi_column is not a value");
}
static_assert(sqlpp::is_select_flag_t<decltype(sqlpp::all)>::value, "sqlpp::all has to be a select_flag");
using T = sqlpp::detail::wrap_operand<int>::type;
static_assert(T::_is_expression, "T has to be an expression");
static_assert(std::is_same<typename T::_value_type::_is_numeric, sqlpp::detail::tag>::value, "T has to be a numeric");
static_assert(sqlpp::is_numeric_t<T>::value, "T has to be a numeric");
static_assert(sqlpp::is_numeric_t<decltype(t.alpha)>::value, "TabSample.alpha has to be a numeric");
((t.alpha + 7) + 4).asc();
static_assert(sqlpp::is_boolean_t<decltype(t.gamma == t.gamma)>::value, "Comparison expression have to be boolean");
auto x = (t.gamma == true) and (t.alpha == 7);
auto y = t.gamma and true and t.gamma;
!t.gamma;
t.beta < "kaesekuchen";
(t.beta + "hallenhalma").serialize(std::cerr, db);
static_assert(sqlpp::must_not_insert_t<decltype(t.alpha)>::value, "alpha must not be inserted");
t.alpha.serialize(std::cerr, db);
std::cerr << "\n" << sizeof(TabSample) << std::endl;
static_assert(std::is_same<typename decltype(t.alpha)::_value_type::_is_named_expression, sqlpp::detail::tag>::value, "alpha should be a named expression");
static_assert(sqlpp::is_named_expression_t<decltype(t.alpha)>::value, "alpha should be a named expression");
static_assert(sqlpp::is_named_expression_t<decltype(t.alpha.as(sqlpp::alias::a))>::value, "an alias of alpha should be a named expression");
static_assert(sqlpp::is_alias_t<decltype(t.alpha.as(sqlpp::alias::a))>::value, "an alias of alpha should be an alias");
auto z = select(t.alpha) == 7;
auto l = t.as(sqlpp::alias::left);
auto r = select(t.gamma.as(sqlpp::alias::a)).from(t).where(t.gamma == true).as(sqlpp::alias::right);
static_assert(sqlpp::is_boolean_t<decltype(select(t.gamma).from(t))>::value, "select(bool) has to be a bool");
select(sqlpp::distinct, sqlpp::straight_join, l.alpha, l.beta, select(r.a).from(r))
.from(l, r)
.where(t.beta == "hello world" and select(t.gamma).from(t))// .as(sqlpp::alias::right))
.group_by(l.gamma, r.a)
.having(r.a != true)
.order_by(l.beta.asc())
.limit(17)
.offset(3)
.as(sqlpp::alias::a)
.serialize(std::cerr, db);
return 0;
}

179
examples/TabSample.h Normal file
View File

@ -0,0 +1,179 @@
/*
* 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_TAB_SAMPLE_H
#define SQLPP_TAB_SAMPLE_H
#include <sqlpp11/table_base.h>
#include <sqlpp11/column_types.h>
namespace TabFoo_
{
struct Omega
{
struct _name_t
{
static constexpr const char* _get_name() { return "omega"; }
};
template<typename T>
struct _member_t
{
/*
template<typename... TT>
_name_t(TT&&... t): omega(std::forward<TT>(t)...) {}
template<typename TT>
_name_t& operator=(TT&& t) { omega = std::forward<TT>(t); return *this; }
*/
T omega;
};
using _value_type = sqlpp::bigint;
struct _column_type
{
};
};
}
struct TabFoo: sqlpp::table_base_t<
TabFoo,
TabFoo_::Omega
>
{
using _value_type = sqlpp::no_value_t;
struct _name_t
{
static constexpr const char* _get_name() { return "tab_foo"; }
};
template<typename T>
struct _member_t
{
T tabFoo;
};
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << _name_t::_get_name();
}
};
namespace TabSample_
{
struct Alpha
{
struct _name_t
{
static constexpr const char* _get_name() { return "alpha"; }
};
template<typename T>
struct _member_t
{
/*
template<typename... TT>
_name_t(TT&&... t): alpha(std::forward<TT>(t)...) {}
template<typename TT>
_name_t& operator=(TT&& t) { alpha = std::forward<TT>(t); return *this; }
*/
T alpha;
};
using _value_type = sqlpp::bigint;
struct _column_type
{
using _must_not_insert = sqlpp::tag_yes;
using _must_not_update = sqlpp::tag_yes;
using _can_be_null = sqlpp::tag_yes;
using _trivial_value_is_null = sqlpp::tag_yes;
using _foreign_key = decltype(TabFoo::omega);
};
};
struct Beta
{
struct _name_t
{
static constexpr const char* _get_name() { return "beta"; }
};
template<typename T>
struct _member_t
{
T beta;
};
using _value_type = sqlpp::varchar;
struct _column_type
{
using _can_be_null = sqlpp::tag_yes;
using _trivial_value_is_null = sqlpp::tag_yes;
using _must_not_update = sqlpp::tag_yes;
};
};
struct Gamma
{
struct _name_t
{
static constexpr const char* _get_name() { return "gamma"; }
};
template<typename T>
struct _member_t
{
T gamma;
};
using _value_type = sqlpp::boolean;
struct _column_type
{
using _require_insert = sqlpp::tag_yes;
};
};
}
struct TabSample: sqlpp::table_base_t<
TabSample,
TabSample_::Alpha,
TabSample_::Beta,
TabSample_::Gamma
>
{
using _value_type = sqlpp::no_value_t;
struct _name_t
{
static constexpr const char* _get_name() { return "tab_sample"; }
};
template<typename T>
struct _member_t
{
T tabSample;
};
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << _name_t::_get_name();
}
};
#endif

55
examples/UpdateTest.cpp Normal file
View File

@ -0,0 +1,55 @@
/*
* 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 <iostream>
#include <sqlpp11/update.h>
#include <sqlpp11/select.h>
#include <sqlpp11/examples/TabSample.h>
#include <iostream>
class DbMock
{
public:
const std::string& escape(const std::string& text) { return text; }
};
DbMock db;
int main()
{
TabSample t;
auto x = t.alpha = 7;
auto y = t.beta = "kaesekuchen";
auto z = t.gamma = true;
update(t).serialize(std::cerr, db); std::cerr << "\n";
update(t).set(t.gamma = false).serialize(std::cerr, db); std::cerr << "\n";
update(t).set(t.gamma = false).where(t.beta != "transparent").serialize(std::cerr, db); std::cerr << "\n";
//insert_into(t).values(7, "wurstwaren", true).serialize(std::cerr, db); std::cerr << "\n";
//insert_into(t).columns(t.alpha, t.beta).values(25, "drei").serialize(std::cerr, db); std::cerr << "\n";
//insert_into(t).columns(t.alpha, t.beta).select(select(t.alpha, t.beta).from(t)).serialize(std::cerr, db);
return 0;
}

3
examples/compile.sh Normal file
View File

@ -0,0 +1,3 @@
# to be called from the sqlpp11 folder
clang++ -std=c++11 -stdlib=libc++ examples/SelectTest.cpp -I..

43
exception.h Normal file
View File

@ -0,0 +1,43 @@
/*
* 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_EXCEPTION_H
#define SQLPP_EXCEPTION_H
#include <stdexcept>
namespace sqlpp
{
class exception: public std::runtime_error
{
public:
exception(const std::string& what_arg): std::runtime_error(what_arg) {}
exception(const char* what_arg): std::runtime_error(what_arg) {}
};
}
#endif

281
expression.h Normal file
View File

@ -0,0 +1,281 @@
/*
* 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_EXPRESSION_H
#define SQLPP_EXPRESSION_H
#include <sqlpp11/detail/wrap_operand.h>
#include <sqlpp11/detail/serialize_tuple.h>
#include <sqlpp11/alias.h>
#include <sqlpp11/noop.h>
namespace sqlpp
{
template<typename Lhs, typename Rhs>
struct assignment_t
{
using _is_assignment = tag_yes;
using column_type = Lhs;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
_lhs.serialize(os, db);
if (trivial_value_is_null_t<Lhs>::value and _rhs._is_trivial())
{
os << "=NULL";
}
else
{
os << "=(";
_rhs.serialize(os, db);
os << ")";
}
}
Lhs _lhs;
Rhs _rhs;
};
template<typename Lhs, typename Rhs, typename ValueType = detail::boolean>
struct equal_t: public ValueType::template operators<equal_t<Lhs, Rhs>>
{
using _value_type = ValueType;
template<typename L, typename R>
equal_t(L&& l, R&& r):
_lhs(std::forward<L>(l)),
_rhs(std::forward<R>(r))
{}
equal_t(const equal_t&) = default;
equal_t(equal_t&&) = default;
equal_t& operator=(const equal_t&) = default;
equal_t& operator=(equal_t&&) = default;
~equal_t() = default;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
_lhs.serialize(os, db);
if (trivial_value_is_null_t<Lhs>::value and _rhs._is_trivial())
{
os << " IS NULL";
}
else
{
os << "=(";
_rhs.serialize(os, db);
os << ")";
}
}
private:
Lhs _lhs;
Rhs _rhs;
};
template<typename Lhs, typename Rhs, typename ValueType = detail::boolean>
struct not_equal_t: public ValueType::template operators<not_equal_t<Lhs, Rhs>>
{
using _value_type = ValueType;
template<typename L, typename R>
not_equal_t(L&& l, R&& r):
_lhs(std::forward<L>(l)),
_rhs(std::forward<R>(r))
{}
not_equal_t(const not_equal_t&) = default;
not_equal_t(not_equal_t&&) = default;
not_equal_t& operator=(const not_equal_t&) = default;
not_equal_t& operator=(not_equal_t&&) = default;
~not_equal_t() = default;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
_lhs.serialize(os, db);
if (trivial_value_is_null_t<Lhs>::value and _rhs._is_trivial())
{
os << " IS NOT NULL";
}
else
{
os << "!=(";
_rhs.serialize(os, db);
os << ")";
}
}
private:
Lhs _lhs;
Rhs _rhs;
};
template<typename Lhs, typename ValueType = detail::boolean>
struct not_t: public ValueType::template operators<not_t<Lhs>>
{
using _value_type = ValueType;
template<typename L>
not_t(L&& l):
_lhs(std::forward<L>(l))
{}
not_t(const not_t&) = default;
not_t(not_t&&) = default;
not_t& operator=(const not_t&) = default;
not_t& operator=(not_t&&) = default;
~not_t() = default;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
if (trivial_value_is_null_t<Lhs>::value and _lhs._is_trivial())
{
_lhs.serialize(os, db);
os << " IS NULL";
}
else
{
os << "NOT(";
_lhs.serialize(os, db);
os << ")";
}
}
private:
Lhs _lhs;
};
template<typename Lhs, typename O, typename... Rhs>
struct nary_expression_t: public O::_value_type::template operators<nary_expression_t<Lhs, O, Rhs...>>
{
using _value_type = typename O::_value_type;
nary_expression_t(Lhs&& l, Rhs&&... r):
_lhs(std::move(l)),
_rhs(std::move(r)...)
{}
nary_expression_t(const Lhs& l, const Rhs&... r):
_lhs(l),
_rhs(r...)
{}
nary_expression_t(const nary_expression_t&) = default;
nary_expression_t(nary_expression_t&&) = default;
nary_expression_t& operator=(const nary_expression_t&) = default;
nary_expression_t& operator=(nary_expression_t&&) = default;
~nary_expression_t() = default;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << "(";
_lhs.serialize(os, db);
os << ")";
os << O::_name;
os << "(";
detail::serialize_tuple(os, db, _rhs, ',');
os << ")";
}
private:
Lhs _lhs;
std::tuple<Rhs...> _rhs;
};
template<typename F, typename... Rhs>
struct nary_function_t: public F::_value_type::template operators<nary_function_t<F, Rhs...>>
{
using _value_type = typename F::_value_type;
nary_function_t(Rhs&&... r):
_rhs(std::move(r)...)
{}
nary_function_t(const Rhs&... r):
_rhs(r...)
{}
nary_function_t(const nary_function_t&) = default;
nary_function_t(nary_function_t&&) = default;
nary_function_t& operator=(const nary_function_t&) = default;
nary_function_t& operator=(nary_function_t&&) = default;
~nary_function_t() = default;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << F::_name;
os << "(";
detail::serialize_tuple(os, db, _rhs, ',');
os << ")";
}
private:
std::tuple<Rhs...> _rhs;
};
template<typename F, typename... Rhs>
struct named_nary_function_t: public F::_value_type::template operators<named_nary_function_t<F, Rhs...>>
{
using _value_type = typename F::_value_type;
using _name_t = typename F::_name_t;
template<typename T>
using _member_t = typename F::template _member_t<T>;
named_nary_function_t(Rhs&&... r):
_rhs(std::move(r)...)
{}
named_nary_function_t(const Rhs&... r):
_rhs(r...)
{}
named_nary_function_t(const named_nary_function_t&) = default;
named_nary_function_t(named_nary_function_t&&) = default;
named_nary_function_t& operator=(const named_nary_function_t&) = default;
named_nary_function_t& operator=(named_nary_function_t&&) = default;
~named_nary_function_t() = default;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << F::_name_t::_get_name();
os << "(";
detail::serialize_tuple(os, db, _rhs, ',');
os << ")";
}
private:
std::tuple<Rhs...> _rhs;
};
}
#endif

39
expression_fwd.h Normal file
View File

@ -0,0 +1,39 @@
/*
* 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_EXPRESSION_FWD_H
#define SQLPP_EXPRESSION_FWD_H
namespace sqlpp
{
template<typename T>
struct is_expression_t;
template<typename T>
struct is_named_expression_t;
}
#endif

59
from.h Normal file
View File

@ -0,0 +1,59 @@
/*
* 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_FROM_H
#define SQLPP_FROM_H
#include <sqlpp11/select_fwd.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/serialize_tuple.h>
#include <ostream>
namespace sqlpp
{
template<typename... TableOrJoin>
struct from_t
{
using _is_from = tag_yes;
static_assert(sizeof...(TableOrJoin), "at least one table or join argument required in from");
//understand joins
//analyze tables and joins for duplicates
//produce a set of tables in this from
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << " FROM ";
detail::serialize_tuple(os, db, _tables_and_joins, ',');
}
std::tuple<TableOrJoin...> _tables_and_joins;
};
}
#endif

166
functions.h Normal file
View File

@ -0,0 +1,166 @@
/*
* 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_FUNCTIONS_H
#define SQLPP_FUNCTIONS_H
#include <sqlpp11/type_traits.h>
#include <sqlpp11/column_types.h>
#include <sstream>
namespace sqlpp
{
#define SQLPP_MAKE_UNARY_TYPED_FUNCTION(NAME, SQL, CONSTRAINT, VALUE_TYPE) \
namespace detail\
{\
template<typename T>\
struct NAME##_t\
{\
using _operand = typename operand_t<T, CONSTRAINT>::type;\
\
struct _op\
{\
struct _value_type: public VALUE_TYPE\
{\
using _is_named_expression = tag_yes;\
};\
struct _name_t\
{\
static constexpr const char* _get_name() { return #SQL; }\
};\
template<typename M>\
struct _member_t\
{\
M NAME;\
};\
};\
\
using type = named_nary_function_t<_op, _operand>;\
};\
}\
template<typename T>\
auto NAME(T&& t) -> typename detail::NAME##_t<T>::type\
{\
return { std::forward<T>(t) };\
}
#define SQLPP_MAKE_UNARY_FUNCTION(NAME, SQL, CONSTRAINT) SQLPP_MAKE_UNARY_TYPED_FUNCTION(NAME, SQL, CONSTRAINT, _operand::_value_type)
SQLPP_MAKE_UNARY_FUNCTION(avg, AVG, is_value_t);
SQLPP_MAKE_UNARY_FUNCTION(min, MIN, is_value_t);
SQLPP_MAKE_UNARY_FUNCTION(max, MAX, is_value_t);
SQLPP_MAKE_UNARY_FUNCTION(sum, SUM, is_value_t);
SQLPP_MAKE_UNARY_FUNCTION(any, ANY, is_select_t);
SQLPP_MAKE_UNARY_FUNCTION(some, SOME, is_select_t);
SQLPP_MAKE_UNARY_TYPED_FUNCTION(count, COUNT, is_expression_t, bigint);
SQLPP_MAKE_UNARY_TYPED_FUNCTION(exists, EXISTS, is_select_t, boolean);
SQLPP_MAKE_UNARY_TYPED_FUNCTION(not_exists, NOT EXISTS, is_select_t, boolean);
template<typename T>
auto value(T&& t) -> typename operand_t<T, is_value_t>::type
{
static_assert(not is_value_t<typename std::decay<T>::type>::value, "value() is to be called with non-sqlpp-type like int, or string");
return { std::forward<T>(t) };
}
template<typename ValueType>
struct verbatim_t: public ValueType::template operators<verbatim_t<ValueType>>
{
using _value_type = ValueType;
template<typename Db>
void serialize(std::ostream& os, const Db& db) const
{
os << _verbatim;
}
verbatim_t(const std::string& verbatim): _verbatim(verbatim) {}
verbatim_t(std::string&& verbatim): _verbatim(std::forward<std::string>(verbatim)) {}
verbatim_t(const verbatim_t&) = default;
verbatim_t(verbatim_t&&) = default;
verbatim_t& operator=(const verbatim_t&) = default;
verbatim_t& operator=(verbatim_t&&) = default;
~verbatim_t() = default;
std::string _verbatim;
};
template<typename ValueType, typename StringType>
auto verbatim(StringType&& s) -> verbatim_t<ValueType>
{
return { std::forward<StringType>(s) };
}
template<typename Expression, typename Db>
auto flatten(const Expression& exp, const Db& db) -> verbatim_t<typename std::decay<Expression>::type::_value_type::_base_value_type>
{
std::ostringstream os;
exp.serialize(os, db);
return { os.str() };
}
template<typename Container>
struct value_list_t // to be used in .in() method
{
using _container_t = Container;
using _value_type = typename operand_t<typename _container_t::value_type, is_value_t>::type::_value_type;
using _iterator = decltype(std::begin(std::declval<_container_t>()));
template<typename Db>
void serialize(std::ostream& os, const Db& db) const
{
bool first = true;
for (const auto& entry: _container)
{
if (first)
first = false;
else
os << ',';
value(entry).serialize(os, db);
}
}
_container_t _container;
};
template<typename Container>
auto value_list(Container&& c) -> value_list_t<typename std::decay<Container>::type>
{
static_assert(not is_value_t<typename std::decay<Container>::type::value_type>::value, "value_list() is to be called with a container of non-sqlpp-type like std::vector<int>, or std::list(string)");
return { std::forward<Container>(c) };
}
template<typename T>
constexpr const char* get_sql_name(const T&)
{
return std::decay<T>::type::_name_t::_get_name();
}
}
#endif

68
group_by.h Normal file
View File

@ -0,0 +1,68 @@
/*
* 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_GROUP_BY_H
#define SQLPP_GROUP_BY_H
#include <tuple>
#include <sqlpp11/select_fwd.h>
#include <sqlpp11/expression.h>
#include <sqlpp11/detail/serialize_tuple.h>
#include <sqlpp11/detail/set.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp
{
template<typename... Expr>
struct group_by_t
{
// ensure one argument at least
static_assert(sizeof...(Expr), "at least one expression (e.g. a column) required in group_by()");
// check for duplicate expressions
static_assert(not detail::has_duplicates<Expr...>::value, "at least one duplicate argument detected in group_by()");
// check for invalid expressions
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 group_by()");
using _is_group_by = tag_yes;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << " GROUP BY ";
detail::serialize_tuple(os, db, _expressions, ',');
}
std::tuple<Expr...> _expressions;
};
}
#endif

54
having.h Normal file
View File

@ -0,0 +1,54 @@
/*
* 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_HAVING_H
#define SQLPP_HAVING_H
#include <sqlpp11/type_traits.h>
#include <sqlpp11/expression.h>
#include <sqlpp11/detail/set.h>
namespace sqlpp
{
template<typename Expr>
struct having_t
{
static_assert(is_expression_t<Expr>::value, "invalid expression argument in having()");
using _is_having = tag_yes;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << " HAVING ";
_expr.serialize(os, db);
}
Expr _expr;
};
}
#endif

114
insert.h Normal file
View File

@ -0,0 +1,114 @@
/*
* 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_INSERT_H
#define SQLPP_INSERT_H
#include <sstream>
#include <sqlpp11/noop.h>
#include <sqlpp11/select_fwd.h>
#include <sqlpp11/assignment_list.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/serialize_tuple.h>
namespace sqlpp
{
// Hint: Columns/Values could be supported by .columns().values().values()...
// values could take values or assignments. The latter would be stripped
// The insert would store a vector of tuples of values.
// Hint: Select could be supported by perfect forwarding to the methods of _select member (always changing the whole type of the
// insert.
template<
typename Table = noop,
typename Assignments = noop
>
struct insert_t;
template<
typename Table,
typename Assignments
>
struct insert_t
{
static_assert(is_noop<Table>::value or is_table_t<Table>::value, "invalid 'Table' argument");
static_assert(is_noop<Assignments>::value or is_assignment_list_t<Assignments>::value, "invalid 'Assignments' arguments");
template<typename... Assignment>
using add_assignments_t = insert_t<Table, assignment_list_t<must_not_insert_t, typename std::decay<Assignment>::type...>>;
template<typename... Assignment>
add_assignments_t<Assignment...> set(Assignment&&... assignment)
{
static_assert(std::is_same<Assignments, noop>::value, "cannot call set() twice");
return {
_table,
{std::forward<Assignment>(assignment)...},
};
}
template<typename Db>
const insert_t& serialize(std::ostream& os, Db& db) const
{
os << "INSERT INTO ";
_table.serialize(os, db);
if (is_noop<Assignments>::value)
os << "() VALUES()";
else
_assignments.serialize(os, db);
return *this;
}
template<typename Db>
insert_t& serialize(std::ostream& os, Db& db)
{
static_cast<const insert_t*>(this)->serialize(os, db);
return *this;
}
template<typename Db>
std::size_t run(Db& db) const
{
constexpr bool calledSet = not is_noop<Assignments>::value;
constexpr bool requireSet = Table::_required_insert_columns::size::value > 0;
static_assert(calledSet or not requireSet, "calling set() required for given table");
std::ostringstream oss;
serialize(oss, db);
return db.insert(oss.str());
}
Table _table;
Assignments _assignments;
};
template<typename Table>
constexpr insert_t<typename std::decay<Table>::type> insert_into(Table&& table)
{
return {std::forward<Table>(table)};
}
}
#endif

100
join.h Normal file
View File

@ -0,0 +1,100 @@
/*
* 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_JOIN_H
#define SQLPP_JOIN_H
#include <sqlpp11/type_traits.h>
namespace sqlpp
{
struct inner_join_t
{
static constexpr const char* _name = "INNER";
};
struct outer_join_t
{
static constexpr const char* _name = "OUTER";
};
struct left_join_t
{
static constexpr const char* _name = "LEFT OUTER";
};
struct right_join_t
{
static constexpr const char* _name = "RIGHT OUTER";
};
template<typename JoinType, typename Lhs, typename Rhs, typename On = noop>
struct join_t
{
static_assert(is_table_t<Lhs>::value, "invalid lhs argument for join()");
static_assert(is_table_t<Rhs>::value, "invalid rhs argument for join()");
static_assert(is_noop<On>::value or is_expression_t<On>::value, "invalid on expression in join().on()");
static_assert(Lhs::_table_set::template is_disjunct_from<typename Rhs::_table_set>::value, "joined tables must not be identical");
using _is_table = typename std::conditional<is_noop<On>::value,
tag_no,
tag_yes>::type;
using _table_set = typename std::conditional<is_noop<On>::value,
void,
typename Lhs::_table_set::template join<typename Rhs::_table_set>::type>::type;
template<typename Expr>
using add_on_t = join_t<JoinType, Lhs, Rhs, typename std::decay<Expr>::type>;
template<typename Expr>
add_on_t<Expr> on(Expr&& expr)
{
return { _lhs, _rhs, std::forward<Expr>(expr) };
}
template<typename T>
join_t<inner_join_t, join_t, typename std::decay<T>::type> join(T&& t)
{
return { *this, std::forward<T>(t) };
}
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << " (";
_lhs.serialize(os, db);
os << ") " << JoinType::_name << " JOIN (";
_rhs.serialize(os, db);
os << ") ON (";
_on.serialize(os, db);
os << ")";
}
Lhs _lhs;
Rhs _rhs;
On _on;
};
}
#endif

64
limit.h Normal file
View File

@ -0,0 +1,64 @@
/*
* 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_LIMIT_H
#define SQLPP_LIMIT_H
#include <ostream>
#include <sqlpp11/select_fwd.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp
{
struct limit_t
{
using _is_limit = tag_yes;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << " LIMIT " << _limit;
}
std::size_t _limit;
};
struct offset_t
{
using _is_offset = tag_yes;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << " OFFSET " << _offset;
}
const std::size_t _offset;
};
}
#endif

81
multi_column.h Normal file
View File

@ -0,0 +1,81 @@
/*
* 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_MULTI_COLUMN_H
#define SQLPP_MULTI_COLUMN_H
#include <sqlpp11/detail/make_expression_tuple.h>
#include <sqlpp11/no_value.h>
namespace sqlpp
{
template<typename AliasProvider, typename T>
struct multi_column_t
{
static_assert(detail::wrong<T>::value, "invalid argument for multicolumn_t");
};
template<typename AliasProvider, typename... 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(_named_expr_set::size::value == sizeof...(NamedExpr), "multi_column parameters need to be named expressions");
using _name_t = typename AliasProvider::_name_t;
template<typename T>
using _member_t = typename AliasProvider::template _member_t<T>;
struct _value_type: public no_value_t
{
using _is_named_expression = tag_yes;
};
using _is_multi_column = tag_yes;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
detail::serialize_tuple(os, db, _columns, ',');
}
std::tuple<NamedExpr...> _columns;
};
namespace detail
{
template<typename AliasProvider, typename... Expr>
using make_multi_column_t =
multi_column_t<typename std::decay<AliasProvider>::type, decltype(make_expression_tuple(std::declval<Expr>()...))>;
}
template<typename AliasProvider, typename... NamedExpr>
detail::make_multi_column_t<AliasProvider, NamedExpr...> multi_column(AliasProvider&& aliasProvider, NamedExpr&&... namedExpr)
{
return { {std::forward<NamedExpr>(namedExpr)...}};
}
}
#endif

47
no_value.h Normal file
View File

@ -0,0 +1,47 @@
/*
* 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_NO_VALUE_H
#define SQLPP_NO_VALUE_H
#include <type_traits>
namespace sqlpp
{
// boolean value type
struct no_value_t
{
template<typename T>
using _constraint = std::false_type;
template<typename Base>
struct operators
{
};
};
}
#endif

45
noop.h Normal file
View File

@ -0,0 +1,45 @@
/*
* 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_NOOP_H
#define SQLPP_NOOP_H
#include <type_traits>
namespace sqlpp
{
struct noop
{
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{}
};
template<typename T>
struct is_noop: std::is_same<T, noop> {};
}
#endif

37
noop_fwd.h Normal file
View File

@ -0,0 +1,37 @@
/*
* 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_NOOP_FWD_H
#define SQLPP_NOOP_FWD_H
namespace sqlpp
{
struct noop;
template<typename T>
struct is_noop;
}
#endif

185
numeric.h Normal file
View File

@ -0,0 +1,185 @@
/*
* 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_NUMERIC_H
#define SQLPP_NUMERIC_H
#include <cstdlib>
#include <sqlpp11/detail/basic_operators.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/raw_result_row.h>
#include <sqlpp11/exception.h>
namespace sqlpp
{
namespace detail
{
// numeric value type
struct numeric
{
using _base_value_type = numeric;
using _is_numeric = tag_yes;
using _is_value = tag_yes;
using _is_expression = tag_yes;
template<size_t index>
struct _result_entry_t
{
using _value_type = numeric;
_result_entry_t(const raw_result_row_t& row):
_is_valid(row.data != nullptr),
_is_null(row.data == nullptr or row.data[index] == nullptr),
_value(_is_null ? 0 : std::strtoll(row.data[index], nullptr, 10))
{}
_result_entry_t& operator=(const raw_result_row_t& row)
{
_is_valid = (row.data != nullptr);
_is_null = row.data == nullptr or row.data[index] == nullptr;
_value = _is_null ? 0 : std::strtoll(row.data[index], nullptr, 10);
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; }
int64_t value() const
{
if (not _is_valid)
throw exception("accessing value in non-existing row");
return _value;
}
operator int64_t() const { return value(); }
private:
bool _is_valid;
bool _is_null;
int64_t _value;
};
struct plus_
{
using _value_type = numeric;
static constexpr const char* _name = "+";
};
struct minus_
{
using _value_type = numeric;
static constexpr const char* _name = "-";
};
struct multiplies_
{
using _value_type = numeric;
static constexpr const char* _name = "*";
};
struct divides_
{
using _value_type = numeric;
static constexpr const char* _name = "/";
};
template<typename T>
using _constraint = operand_t<T, is_numeric_t>;
template<typename Base>
struct operators: public basic_operators<Base, _constraint>
{
template<typename T>
nary_expression_t<Base, plus_, typename _constraint<T>::type> operator +(T&& t) const
{
return { *static_cast<const Base*>(this), std::forward<T>(t) };
}
template<typename T>
nary_expression_t<Base, minus_, typename _constraint<T>::type> operator -(T&& t) const
{
return { *static_cast<const Base*>(this), std::forward<T>(t) };
}
template<typename T>
nary_expression_t<Base, multiplies_, typename _constraint<T>::type> operator *(T&& t) const
{
return { *static_cast<const Base*>(this), std::forward<T>(t) };
}
template<typename T>
nary_expression_t<Base, divides_, typename _constraint<T>::type> operator /(T&& t) const
{
return { *static_cast<const Base*>(this), std::forward<T>(t) };
}
template<typename T>
auto operator +=(T&& t) const -> decltype(std::declval<Base>() = operator +(std::forward<T>(t)))
{
return *static_cast<const Base*>(this) = operator +(std::forward<T>(t));
}
template<typename T>
auto operator -=(T&& t) const -> decltype(std::declval<Base>() = operator -(std::forward<T>(t)))
{
return *static_cast<const Base*>(this) = operator -(std::forward<T>(t));
}
template<typename T>
auto operator /=(T&& t) const -> decltype(std::declval<Base>() = operator /(std::forward<T>(t)))
{
return *static_cast<const Base*>(this) = operator /(std::forward<T>(t));
}
template<typename T>
auto operator *=(T&& t) const -> decltype(std::declval<Base>() = operator *(std::forward<T>(t)))
{
return *static_cast<const Base*>(this) = operator *(std::forward<T>(t));
}
};
};
template<size_t index>
std::ostream& operator<<(std::ostream& os, const numeric::_result_entry_t<index>& e)
{
return os << e.value();
}
}
using tinyint = detail::numeric;
using smallint = detail::numeric;
using integer = detail::numeric;
using bigint = detail::numeric;
}
#endif

64
order_by.h Normal file
View File

@ -0,0 +1,64 @@
/*
* 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_ORDER_BY_H
#define SQLPP_ORDER_BY_H
#include <tuple>
#include <ostream>
#include <sqlpp11/select_fwd.h>
#include <sqlpp11/detail/serialize_tuple.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp
{
template<typename... OrderExpr>
struct order_by_t
{
// check for at least one order expression
static_assert(sizeof...(OrderExpr), "at least one select expression required in order_by()");
// check for duplicate order expressions
static_assert(not detail::has_duplicates<OrderExpr...>::value, "at least one duplicate argument detected in order_by()");
// check for invalid order expressions
using _valid_expressions = typename detail::make_set_if<is_sort_order_t, OrderExpr...>::type;
static_assert(_valid_expressions::size::value == sizeof...(OrderExpr), "at least one argument is not a sort order expression in order_by()");
using _is_order_by = tag_yes;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << " ORDER BY ";
detail::serialize_tuple(os, db, _orderExpressions, ',');
}
std::tuple<OrderExpr...> _orderExpressions;
};
}
#endif

44
raw_result_row.h Normal file
View File

@ -0,0 +1,44 @@
/*
* 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_RAW_RESULT_ROW_H
#define SQLPP_RAW_RESULT_ROW_H
namespace sqlpp
{
struct raw_result_row_t
{
const char** data;
const size_t* len;
bool operator==(const raw_result_row_t& rhs) const
{
return data == rhs.data and len == rhs.len;
}
};
}
#endif

122
remove.h Normal file
View File

@ -0,0 +1,122 @@
/*
* 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_REMOVE_H
#define SQLPP_REMOVE_H
#include <sstream>
#include <sqlpp11/noop.h>
#include <sqlpp11/using.h>
#include <sqlpp11/where.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp
{
template<
typename Table,
typename Using = noop,
typename Where = noop
>
struct remove_t;
template<
typename Table,
typename Using,
typename Where
>
struct remove_t
{
static_assert(is_noop<Table>::value or is_table_t<Table>::value, "invalid 'Table' argument");
static_assert(is_noop<Using>::value or is_using_t<Using>::value, "invalid 'Using' argument");
static_assert(is_noop<Where>::value or is_where_t<Where>::value, "invalid 'Where' argument");
template<typename... Tab>
using add_using_t = remove_t<Table, using_t<typename std::decay<Tab>::type...>, Where>;
template<typename Expr>
using add_where_t = remove_t<Table, Using, where_t<typename std::decay<Expr>::type>>;
template<typename... Tab>
add_using_t<Tab...> using_(Tab&&... tab)
{
static_assert(std::is_same<Using, noop>::value, "cannot call using() twice");
static_assert(std::is_same<Where, noop>::value, "cannot call using() after where()");
return {
_table,
{{std::forward<Tab>(tab)...}},
_where
};
}
template<typename Expr>
add_where_t<Expr> where(Expr&& where)
{
static_assert(std::is_same<Where, noop>::value, "cannot call where() twice");
return {
_table,
_using,
{std::forward<Expr>(where)},
};
}
template<typename Db>
const remove_t& serialize(std::ostream& os, Db& db) const
{
os << "DELETE FROM ";
_table.serialize(os, db);
_using.serialize(os, db);
_where.serialize(os, db);
return *this;
}
template<typename Db>
remove_t& serialize(std::ostream& os, Db& db)
{
static_cast<const remove_t*>(this)->serialize(os, db);
return *this;
}
template<typename Db>
std::size_t run(Db& db) const
{
std::ostringstream oss;
serialize(oss, db);
return db.remove(oss.str());
}
Table _table;
Using _using;
Where _where;
};
template<typename Table>
constexpr remove_t<typename std::decay<Table>::type> remove_from(Table&& table)
{
return {std::forward<Table>(table)};
}
}
#endif

116
result.h Normal file
View File

@ -0,0 +1,116 @@
/*
* 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_RESULT_H
#define SQLPP_RESULT_H
#include <sqlpp11/raw_result_row.h>
#include <iostream>
namespace sqlpp
{
template<typename Db, typename ResultRow>
struct result_t
{
using db_result_t = typename Db::result;
// Iterator
class iterator
{
public:
iterator(db_result_t& result):
_result(result),
_raw_result_row({}),
_result_row(_raw_result_row)
{
std::cerr << "result::iterator::end-constructor" << std::endl;
}
iterator(db_result_t& result, const raw_result_row_t& raw_result_row):
_result(result),
_raw_result_row(raw_result_row),
_result_row(_raw_result_row)
{
std::cerr << "result::iterator::begin-constructor" << std::endl;
}
const ResultRow& operator*() const
{
return _result_row;
}
const ResultRow* operator->() const
{
return &_result_row;
}
bool operator==(const iterator& rhs) const
{
return _result == rhs._result and _raw_result_row == rhs._raw_result_row;
}
bool operator!=(const iterator& rhs) const
{
return not (operator==(rhs));
}
void operator++()
{
_raw_result_row = _result.next();
_result_row = _raw_result_row;
}
db_result_t& _result;
raw_result_row_t _raw_result_row;
ResultRow _result_row;
};
iterator begin()
{
return iterator(_result, _result.next());
}
iterator end()
{
return _result;
}
const ResultRow operator*()
{
return {_result.next()};
}
iterator operator->()
{
return begin();
}
db_result_t _result;
};
}
#endif

119
result_row.h Normal file
View File

@ -0,0 +1,119 @@
/*
* 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_RESULT_ROW_H
#define SQLPP_RESULT_ROW_H
#include <sqlpp11/raw_result_row.h>
#include <sqlpp11/multi_column.h>
#include <iostream>
namespace sqlpp
{
namespace detail
{
template<size_t level, size_t index, typename... NamedExpr>
struct result_row_impl;
template<size_t level, size_t index, typename NamedExpr, typename... Rest>
struct result_row_impl<level, index, NamedExpr, Rest...>:
public NamedExpr::template _member_t<typename NamedExpr::_value_type::template _result_entry_t<index>>,
public result_row_impl<level, index + 1, Rest...>
{
using _field = typename NamedExpr::template _member_t<typename NamedExpr::_value_type::template _result_entry_t<index>>;
using _rest = result_row_impl<level, index + 1, Rest...>;
result_row_impl(const raw_result_row_t& raw_result_row):
_field({raw_result_row}),
_rest(raw_result_row)
{}
result_row_impl& operator=(const raw_result_row_t& raw_result_row)
{
_field::operator=({raw_result_row});
_rest::operator=(raw_result_row);
return *this;
}
};
template<size_t level, size_t index, typename AliasProvider, typename... Col, typename... Rest>
struct result_row_impl<level, index, multi_column_t<AliasProvider, std::tuple<Col...>>, Rest...>:
public AliasProvider::template _member_t<result_row_impl<level + 1, index, Col...>>, // level prevents identical closures to be present twice in the inheritance tree
public result_row_impl<level, index + sizeof...(Col), Rest...>
{
using _multi_field = typename AliasProvider::template _member_t<result_row_impl<level + 1, index, Col...>>;
using _rest = result_row_impl<level, index + sizeof...(Col), Rest...>;
result_row_impl(const raw_result_row_t& raw_result_row):
_multi_field({raw_result_row}),
_rest(raw_result_row)
{}
result_row_impl& operator=(const raw_result_row_t& raw_result_row)
{
_multi_field::operator=({raw_result_row});
_rest::operator=(raw_result_row);
return *this;
}
};
template<size_t level, size_t index>
struct result_row_impl<level, index>
{
result_row_impl(const raw_result_row_t& raw_result_row)
{}
result_row_impl& operator=(const raw_result_row_t& raw_result_row)
{
return *this;
}
};
}
template<typename... NamedExpr>
struct result_row_t: public detail::result_row_impl<0, 0, NamedExpr...>
{
bool _is_row;
result_row_t(const raw_result_row_t& raw_result_row):
detail::result_row_impl<0, 0, NamedExpr...>(raw_result_row),
_is_row(raw_result_row.data != nullptr)
{}
result_row_t& operator=(const raw_result_row_t& raw_result_row)
{
detail::result_row_impl<0, 0, NamedExpr...>::operator=(raw_result_row);
_is_row = raw_result_row.data != nullptr;
return *this;
}
explicit operator bool() const
{
return _is_row;
}
};
}
#endif

437
select.h Normal file
View File

@ -0,0 +1,437 @@
/*
* 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_SELECT_H
#define SQLPP_SELECT_H
#include <sqlpp11/result_row.h>
#include <sqlpp11/result.h>
#include <sqlpp11/select_fwd.h>
#include <sqlpp11/noop.h>
#include <sqlpp11/select_flag_list.h>
#include <sqlpp11/select_expression_list.h>
#include <sqlpp11/select_pseudo_table.h>
#include <sqlpp11/from.h>
#include <sqlpp11/where.h>
#include <sqlpp11/group_by.h>
#include <sqlpp11/having.h>
#include <sqlpp11/order_by.h>
#include <sqlpp11/limit.h>
#include <sqlpp11/expression.h>
#include <sqlpp11/detail/wrong.h>
#include <sqlpp11/detail/make_flag_tuple.h>
#include <sqlpp11/detail/make_expression_tuple.h>
#include <sstream>
namespace sqlpp
{
// select template, to be used as an r_value
template<
typename Flags,
typename... NamedExpr,
typename From,
typename Where,
typename GroupBy,
typename Having,
typename OrderBy,
typename Limit,
typename Offset
>
struct select_t<Flags, select_expression_list_t<std::tuple<NamedExpr...>>, From, Where, GroupBy, Having, OrderBy, Limit, Offset>
: public select_expression_list_t<std::tuple<NamedExpr...>>::_value_type::template operators<select_t<
Flags,
select_expression_list_t<std::tuple<NamedExpr...>>,
From,
Where,
GroupBy,
Having,
OrderBy,
Limit,
Offset>>
{
using ExpressionList = select_expression_list_t<std::tuple<NamedExpr...>>;
static_assert(is_noop<Flags>::value or is_select_flag_list_t<Flags>::value, "invalid list of select flags");
static_assert(is_select_expression_list_t<ExpressionList>::value, "invalid list of select expressions");
static_assert(is_noop<From>::value or is_from_t<From>::value, "invalid 'from' argument");
static_assert(is_noop<Where>::value or is_where_t<Where>::value, "invalid 'where' argument");
static_assert(is_noop<GroupBy>::value or is_group_by_t<GroupBy>::value, "invalid 'group by' arguments");
static_assert(is_noop<Having>::value or is_having_t<Having>::value, "invalid 'having' arguments");
static_assert(is_noop<OrderBy>::value or is_order_by_t<OrderBy>::value, "invalid 'order by' arguments");
static_assert(is_noop<Limit>::value or is_limit_t<Limit>::value, "invalid 'limit' arguments");
static_assert(is_noop<Offset>::value or is_offset_t<Offset>::value, "invalid 'offset' arguments");
using _is_select = tag_yes;
using _requires_braces = tag_yes;
template<typename... Table>
using add_from_t = select_t<Flags, ExpressionList, from_t<typename std::decay<Table>::type...>, Where, GroupBy, Having, OrderBy, Limit, Offset>;
template<typename Expr>
using add_where_t = select_t<Flags, ExpressionList, From, where_t<typename std::decay<Expr>::type>, GroupBy, Having, OrderBy, Limit, Offset>;
template<typename... Col>
using add_group_by_t = select_t<Flags, ExpressionList, From, Where, group_by_t<typename std::decay<Col>::type...>, Having, OrderBy, Limit, Offset>;
template<typename Expr>
using add_having_t = select_t<Flags, ExpressionList, From, Where, GroupBy, having_t<typename std::decay<Expr>::type>, OrderBy, Limit, Offset>;
template<typename... Col>
using add_order_by_t = select_t<Flags, ExpressionList, From, Where, GroupBy, Having, order_by_t<typename std::decay<Col>::type...>, Limit, Offset>;
using add_limit_t = select_t<Flags, ExpressionList, From, Where, GroupBy, Having, OrderBy, limit_t, Offset>;
using add_offset_t = select_t<Flags, ExpressionList, From, Where, GroupBy, Having, OrderBy, Limit, offset_t>;
using result_row_t = result_row_t<NamedExpr...>;
// Indicators
using _value_type = typename std::conditional<
is_noop<From>::value,
no_value_t, // If there is no from, the select is not complete (this logic is a bit simple, but better than nothing)
typename ExpressionList::_value_type>::type;
using _name_t = typename ExpressionList::_name_t;
template<typename T>
using _member_t = typename ExpressionList::template _member_t<T>;
// The standard constructors, assigment operators and destructor
select_t(Flags&& flags, ExpressionList&& expression_list):
_flags(std::move(flags)),
_expression_list(std::move(expression_list))
{
static_assert(std::is_same<select_t, sqlpp::select_t<Flags, ExpressionList>>::value,
"basic constructor only available for select_t<Flags, ExpressionList> (default template parameters)");
}
constexpr select_t(const select_t& rhs):
_flags(rhs._flags),
_expression_list(rhs._expression_list),
_from(rhs._from),
_where(rhs._where),
_group_by(rhs._group_by),
_having(rhs._having),
_order_by(rhs._order_by),
_limit(rhs._limit),
_offset(rhs._offset)
{
}
constexpr select_t(select_t&& rhs):
_flags(std::move(rhs._flags)),
_expression_list(std::move(rhs._expression_list)),
_from(std::move(rhs._from)),
_where(std::move(rhs._where)),
_group_by(std::move(rhs._group_by)),
_having(std::move(rhs._having)),
_order_by(std::move(rhs._order_by)),
_limit(std::move(rhs._limit)),
_offset(std::move(rhs._offset))
{
}
select_t& operator=(const select_t& rhs)
{
_flags = rhs._flags;
_expression_list = rhs._expression_list;
_from = rhs._from;
_where = rhs._where;
_group_by = rhs._group_by;
_having = rhs._having;
_order_by = rhs._order_by;
_offset = rhs._offset;
_limit = rhs._limit;
}
select_t& operator=(select_t&& rhs)
{
_flags = std::move(rhs._flags);
_expression_list = std::move(rhs._expression_list);
_from = std::move(rhs._from);
_where = std::move(rhs._where);
_group_by = std::move(rhs._group_by);
_having = std::move(rhs._having);
_order_by = std::move(rhs._order_by);
_limit = std::move(rhs._limit);
_offset = std::move(rhs._offset);
}
~select_t() = default;
// Other constructors
constexpr select_t(Flags&& flags, ExpressionList&& expression_list, From&& from,
Where&& where, GroupBy&& group_by, Having&& having,
OrderBy&& order_by, Limit&& limit, Offset&& offset):
_flags(std::move(flags)),
_expression_list(std::move(expression_list)),
_from(std::move(from)),
_where(std::move(where)),
_group_by(std::move(group_by)),
_having(std::move(having)),
_order_by(std::move(order_by)),
_limit(std::move(limit)),
_offset(std::move(offset))
{
}
constexpr select_t(const Flags& flags, const ExpressionList& expression_list, const From& from,
const Where& where, const GroupBy& group_by, const Having& having,
const OrderBy& order_by, const Limit& limit, const Offset& offset):
_flags(flags),
_expression_list(expression_list),
_from(from),
_where(where),
_group_by(group_by),
_having(having),
_order_by(order_by),
_limit(limit),
_offset(offset)
{
}
// sqlpp functions
template<typename... Table>
add_from_t<Table...> from(Table&&... table)
{
static_assert(not is_noop<ExpressionList>::value, "cannot call from() without having selected anything");
static_assert(is_noop<From>::value, "cannot call from() twice for a single select");
return {
_flags,
_expression_list,
{{std::forward<Table>(table)...}},
_where,
_group_by,
_having,
_order_by,
_limit,
_offset
};
}
template<typename Expr>
add_where_t<Expr> where(Expr&& expr)
{
static_assert(not is_noop<From>::value, "cannot call where() without a from()");
static_assert(is_noop<Where>::value, "cannot call where() twice for a single select");
return {
_flags,
_expression_list,
_from,
{std::forward<Expr>(expr)},
_group_by,
_having,
_order_by,
_limit,
_offset
};
}
template<typename... Col>
add_group_by_t<Col...> group_by(Col&&... column)
{
static_assert(not is_noop<From>::value, "cannot call group_by() without a from()");
static_assert(is_noop<GroupBy>::value, "cannot call group_by() twice for a single select");
return {
_flags,
_expression_list,
_from,
_where,
{{std::forward<Col>(column)...}},
_having,
_order_by,
_limit,
_offset
};
}
template<typename Expr>
add_having_t<Expr> having(Expr&& expr)
{
static_assert(not is_noop<GroupBy>::value, "cannot call having() without a group_by");
static_assert(is_noop<Having>::value, "cannot call having() twice for a single select");
return {
_flags,
_expression_list,
_from,
_where,
_group_by,
{std::forward<Expr>(expr)},
_order_by,
_limit,
_offset
};
}
template<typename... OrderExpr>
add_order_by_t<OrderExpr...> order_by(OrderExpr&&... expr)
{
static_assert(not is_noop<From>::value, "cannot call order_by() without a from()");
static_assert(is_noop<OrderBy>::value, "cannot call order_by() twice for a single select");
return {
_flags,
_expression_list,
_from,
_where,
_group_by,
_having,
{{std::forward<OrderExpr>(expr)...}},
_limit,
_offset
};
}
add_limit_t limit(std::size_t limit)
{
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");
return {
_flags,
_expression_list,
_from,
_where,
_group_by,
_having,
_order_by,
{limit},
_offset
};
}
add_offset_t offset(std::size_t offset)
{
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");
return {
_flags,
_expression_list,
_from,
_where,
_group_by,
_having,
_order_by,
_limit,
{offset}
};
}
// Turn into pseudo table or named expression
using pseudo_table_t = select_pseudo_table_t<
Flags,
ExpressionList,
From,
Where,
GroupBy,
Having,
OrderBy,
Limit,
Offset,
NamedExpr...>;
template<typename AliasProvider>
using alias_t = typename pseudo_table_t::template alias_t<AliasProvider>;
template<typename AliasProvider>
typename std::enable_if<is_from_t<From>::value, alias_t<AliasProvider>>::type as(const AliasProvider& aliasProvider) const
{
return pseudo_table_t(
_flags,
_expression_list,
_from,
_where,
_group_by,
_having,
_order_by,
_limit,
_offset).as(aliasProvider);
}
// Serialize
template<typename Db>
select_t& serialize(std::ostream& os, Db& db)
{
detail::serialize_select(os, db, *this);
return *this;
}
template<typename Db>
const select_t& serialize(std::ostream& os, Db& db) const
{
detail::serialize_select(os, db, *this);
return *this;
}
// Execute
template<typename Db>
result_t<Db, result_row_t> run(Db& db) const
{
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()");
// FIXME: Check for missing aliases (if references are used)
// FIXME: Check for missing tables
std::ostringstream oss;
serialize(oss, db);
return {db.select(oss.str())};
//serialize using db
//run using db and return result_set
}
Flags _flags;
ExpressionList _expression_list;
From _from;
Where _where;
GroupBy _group_by;
Having _having;
OrderBy _order_by;
Limit _limit;
Offset _offset;
};
// construct select flag list
namespace detail
{
template<typename... Expr>
using make_select_flag_list_t =
select_flag_list_t<decltype(make_flag_tuple(std::declval<Expr>()...))>;
}
// construct select expression list
namespace detail
{
template<typename... Expr>
using make_select_expression_list_t =
select_expression_list_t<decltype(make_expression_tuple(std::declval<Expr>()...))>;
}
template<typename... NamedExpr>
select_t<detail::make_select_flag_list_t<NamedExpr...>, detail::make_select_expression_list_t<NamedExpr...>> select(NamedExpr&&... namedExpr)
{
return {
{ detail::make_flag_tuple(std::forward<NamedExpr>(namedExpr)...) },
{ detail::make_expression_tuple(std::forward<NamedExpr>(namedExpr)...) }
};
}
}
#endif

113
select_expression_list.h Normal file
View File

@ -0,0 +1,113 @@
/*
* 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_SELECT_EXPRESSION_LIST_H
#define SQLPP_SELECT_EXPRESSION_LIST_H
#include <tuple>
#include <ostream>
#include <sqlpp11/select_fwd.h>
#include <sqlpp11/expression_fwd.h>
#include <sqlpp11/no_value.h>
#include <sqlpp11/table_base.h>
#include <sqlpp11/detail/serialize_tuple.h>
#include <sqlpp11/detail/set.h>
namespace sqlpp
{
namespace detail
{
template<typename Db, typename Select>
void serialize_select(std::ostream& os, Db& db, const Select& select)
{
os << "SELECT ";
select._flags.serialize(os, db);
select._expression_list.serialize(os, db);
select._from.serialize(os, db);
select._where.serialize(os, db);
select._group_by.serialize(os, db);
select._having.serialize(os, db);
select._order_by.serialize(os, db);
select._limit.serialize(os, db);
select._offset.serialize(os, db);
};
template<typename T, typename... Rest>
struct get_first_argument
{
using type = T;
};
}
template<typename... NamedExpr>
struct select_expression_list_t<std::tuple<NamedExpr...>>
{
// check for at least one select expression
static_assert(sizeof...(NamedExpr), "at least one select expression required");
// check for duplicate select expressions
static_assert(not detail::has_duplicates<NamedExpr...>::value, "at least one duplicate argument detected");
// check for invalid select expressions
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 _valid_expressions = typename detail::make_set_if<is_valid_expression_t, NamedExpr...>::type;
static_assert(_valid_expressions::size::value == sizeof...(NamedExpr), "at least one argument is not a named expression");
// check for duplicate select expression names
static_assert(not detail::has_duplicates<typename NamedExpr::template _member_t<int>...>::value, "at least one duplicate name detected");
// declare this to be a select expression
using _is_select_expression_list = tag_yes;
// provide type information for sub-selects that are used as expressions
struct _column_type {};
struct _value_type: std::conditional<sizeof...(NamedExpr) == 1, typename detail::get_first_argument<NamedExpr...>::type::_value_type, no_value_t>::type
{
using _is_expression = typename std::conditional<sizeof...(NamedExpr) == 1, tag_yes, tag_no>::type;
using _is_named_expression = typename std::conditional<sizeof...(NamedExpr) == 1, tag_yes, tag_no>::type;
using _is_alias = tag_no;
};
struct _no_name_t {};
using _name_t = typename std::conditional<sizeof...(NamedExpr) == 1, typename detail::get_first_argument<NamedExpr...>::type::_name_t, _no_name_t>::type;
template<typename T>
struct _no_member_t {};
template<typename T>
using _member_t = typename std::conditional<sizeof...(NamedExpr) == 1, typename detail::get_first_argument<NamedExpr...>::type::template _member_t<T>, _no_member_t<T>>::type;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
detail::serialize_tuple(os, db, _expressions, ',');
}
std::tuple<NamedExpr...> _expressions;
};
}
#endif

110
select_flag_list.h Normal file
View File

@ -0,0 +1,110 @@
/*
* 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_SELECT_FLAGS_H
#define SQLPP_SELECT_FLAGS_H
#include <sqlpp11/select_fwd.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h>
#include <sqlpp11/detail/serialize_tuple.h>
#include <tuple>
#include <ostream>
namespace sqlpp
{
// standard select flags
struct all_t
{
struct _value_type
{
using _is_select_flag = tag_yes;
};
template<typename Db>
void serialize(std::ostream& os, const Db&) const
{
os << "ALL";
}
};
static constexpr all_t all = {};
struct distinct_t
{
struct _value_type
{
using _is_select_flag = tag_yes;
};
template<typename Db>
void serialize(std::ostream& os, const Db&) const
{
os << "DISTINCT";
}
};
static constexpr distinct_t distinct = {};
struct straight_join_t
{
struct _value_type
{
using _is_select_flag = tag_yes;
};
template<typename Db>
void serialize(std::ostream& os, const Db&) const
{
os << "STRAIGHT_JOIN";
}
};
static constexpr straight_join_t straight_join = {};
// select_flag_list_t
template<typename... Flag>
struct select_flag_list_t<std::tuple<Flag...>>
{
// check for duplicate order expressions
static_assert(not detail::has_duplicates<Flag...>::value, "at least one duplicate argument detected in select flag list");
// check for invalid order expressions
using _valid_flags = typename detail::make_set_if<is_select_flag_t, Flag...>::type;
static_assert(_valid_flags::size::value == sizeof...(Flag), "at least one argument is not a select flag in select flag list");
using _is_select_flag_list = tag_yes;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
detail::serialize_tuple(os, db, _flags, ' ');
os << ' ';
}
std::tuple<Flag...> _flags;
};
}
#endif

70
select_fwd.h Normal file
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_SELECT_FWD_H
#define SQLPP_SELECT_FWD_H
#include <sqlpp11/noop_fwd.h>
#include <type_traits>
namespace sqlpp
{
// select flags
struct all_t;
struct distinct_t;
struct straight_join_t;
template<typename FlagTuple> struct select_flag_list_t;
template<typename NamedExprTuple> struct select_expression_list_t;
template<typename... TableOrJoin> struct from_t;
template<typename Expr> struct where_t;
template<typename... Expr> struct group_by_t;
template<typename Expr> struct having_t;
template<typename... Expr> struct order_by_t;
struct limit_t;
struct offset_t;
template<
typename Flags = noop,
typename ExpressionList = noop,
typename From = noop,
typename Where = noop,
typename GroupBy = noop,
typename Having = noop,
typename OrderBy = noop,
typename Limit = noop,
typename Offset = noop
>
struct select_t;
}
#endif

123
select_pseudo_table.h Normal file
View File

@ -0,0 +1,123 @@
/*
* 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_SELECT_PSEUDO_TABLE_H
#define SQLPP_SELECT_PSEUDO_TABLE_H
#include <sqlpp11/no_value.h>
namespace sqlpp
{
// provide type information for sub-selects that are used as named expressions or tables
template<typename Expr>
struct select_column_spec_t
{
using _name_t = typename Expr::_name_t;
template<typename T>
using _member_t = typename Expr::template _member_t<T>;
using _value_type = typename Expr::_value_type;
struct _column_type {};
};
template<
typename Flags,
typename ExpressionList,
typename From,
typename Where,
typename GroupBy,
typename Having,
typename OrderBy,
typename Limit,
typename Offset,
typename... NamedExpr
>
struct select_pseudo_table_t: public sqlpp::table_base_t<select_pseudo_table_t<
Flags,
ExpressionList,
From,
Where,
GroupBy,
Having,
OrderBy,
Limit,
Offset,
NamedExpr...>, select_column_spec_t<NamedExpr>...>
{
using _value_type = no_value_t;
select_pseudo_table_t(const Flags& flags, const ExpressionList& expression_list, const From& from,
const Where& where, const GroupBy& group_by, const Having& having,
const OrderBy& order_by, const Limit& limit, const Offset& offset):
_flags(flags),
_expression_list(expression_list),
_from(from),
_where(where),
_group_by(group_by),
_having(having),
_order_by(order_by),
_limit(limit),
_offset(offset)
{
std::cerr << "Copying arguments into pseudo_table" << std::endl;
//std::cerr << _limit._limit << std::endl;
}
select_pseudo_table_t(const select_pseudo_table_t& rhs):
_flags(rhs._flags),
_expression_list(rhs._expression_list),
_from(rhs._from),
_where(rhs._where),
_group_by(rhs._group_by),
_having(rhs._having),
_order_by(rhs._order_by),
_limit(rhs._limit),
_offset(rhs._offset)
{
std::cerr << "Copying pseudo_table" << std::endl;
//std::cerr << _limit._limit << std::endl;
}
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
//std::cerr << "pseudo_table::serialize: " << _limit._limit << std::endl;
detail::serialize_select(os, db, *this);
}
Flags _flags;
ExpressionList _expression_list;
From _from;
Where _where;
GroupBy _group_by;
Having _having;
OrderBy _order_by;
Limit _limit;
Offset _offset;
};
}
#endif

62
sort_order.h Normal file
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_SORT_ORDER_H
#define SQLPP_SORT_ORDER_H
namespace sqlpp
{
enum class sort_type
{
asc,
desc
};
template<typename Expression, sort_type SortType>
struct sort_order_t
{
using _is_sort_order = tag_yes;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
_expression.serialize(os, db);
switch(SortType)
{
case sort_type::asc:
os << " ASC";
break;
default:
os << " DESC";
break;
}
}
Expression _expression;
};
}
#endif

113
table_base.h Normal file
View File

@ -0,0 +1,113 @@
/*
* 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_TABLE_BASE_H
#define SQLPP_TABLE_BASE_H
#include <ostream>
#include <sqlpp11/alias.h>
#include <sqlpp11/no_value.h>
#include <sqlpp11/column.h>
#include <sqlpp11/detail/set.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/join.h>
namespace sqlpp
{
template<typename Table, typename... ColumnSpec>
struct table_base_t: public ColumnSpec::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 _all_columns = typename detail::make_set<column_t<Table, ColumnSpec>...>::type;
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 _all_of_t = std::tuple<column_t<Table, ColumnSpec>...>;
using _is_table = tag_yes;
template<typename T>
join_t<inner_join_t, Table, typename std::decay<T>::type> join(T&& t)
{
return { *static_cast<const Table*>(this), std::forward<T>(t) };
}
template<typename AliasProvider>
struct alias_t: public ColumnSpec::template _member_t<column_t<AliasProvider, ColumnSpec>>...
{
using _is_table = tag_yes;
using _table_set = detail::set<alias_t>;
struct _value_type: Table::_value_type
{
using _is_expression = tag_no;
using _is_named_expression = copy_type_trait<Table, is_value_t>;
using _is_alias = tag_yes;
};
using _name_t = typename AliasProvider::_name_t;
using _all_of_t = std::tuple<column_t<AliasProvider, ColumnSpec>...>;
alias_t(const Table& table):
_table(table)
{}
alias_t(Table&& table):
_table(std::move(table))
{}
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << "("; _table.serialize(os, db); os << ") AS " << _name_t::_get_name();
}
Table _table;
};
template<typename AliasProvider>
alias_t<AliasProvider> as(const AliasProvider&) const
{
return {*static_cast<const Table*>(this)};
}
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
static_cast<const Table*>(this)->serialize(os, db);
}
};
template<typename Table>
auto all_of(Table&& t) -> typename std::decay<Table>::type::_all_of_t
{
return {};
}
}
#endif

138
text.h Normal file
View File

@ -0,0 +1,138 @@
/*
* 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_TEXT_H
#define SQLPP_TEXT_H
#include <cstdlib>
#include <sqlpp11/detail/basic_operators.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/raw_result_row.h>
#include <sqlpp11/exception.h>
namespace sqlpp
{
namespace detail
{
struct text;
struct concat_
{
using _value_type = detail::text;
static constexpr const char* _name = "CONCAT";
};
struct like_
{
using _value_type = boolean;
static constexpr const char* _name = "LIKE";
};
// text value type
struct text
{
using _base_value_type = text;
using _is_text = tag_yes;
using _is_value = tag_yes;
using _is_expression = tag_yes;
template<size_t index>
struct _result_entry_t
{
_result_entry_t(const raw_result_row_t& row):
_is_valid(row.data != nullptr),
_is_null(row.data == nullptr or row.data[index] == nullptr),
_value(_is_null ? "" : std::string(row.data[index], row.data[index] + row.len[index]))
{}
_result_entry_t& operator=(const raw_result_row_t& row)
{
_is_valid = (row.data != nullptr);
_is_null = row.data == nullptr or row.data[index] == nullptr;
_value = _is_null ? "" : std::string(row.data[index], row.data[index] + row.len[index]);
return *this;
}
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << value();
}
bool _is_trivial() const { return value().empty(); }
bool operator==(const std::string& rhs) const { return value() == rhs; }
bool operator!=(const std::string& rhs) const { return not operator==(rhs); }
bool is_null() const { return _is_null; }
std::string value() const
{
if (not _is_valid)
throw exception("accessing value in non-existing row");
return _value;
}
operator std::string() const { return value(); }
private:
bool _is_valid;
bool _is_null;
std::string _value;
};
template<typename T>
using _constraint = operand_t<T, is_text_t>;
struct plus_
{
using _value_type = boolean;
static constexpr const char* _name = "+";
};
template<typename Base>
struct operators: public basic_operators<Base, _constraint>
{
template<typename T>
nary_function_t<concat_, Base, typename _constraint<T>::type> operator+(T&& t) const
{
return { *static_cast<const Base*>(this), std::forward<T>(t) };
}
};
};
template<size_t index>
std::ostream& operator<<(std::ostream& os, const text::_result_entry_t<index>& e)
{
return os << e.value();
}
}
using text = detail::text;
using varchar = detail::text;
using char_ = detail::text;
}
#endif

96
transaction.h Normal file
View File

@ -0,0 +1,96 @@
/*
* 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_TRANSACTION_H
#define SQLPP_TRANSACTION_H
#include <stdexcept>
namespace sqlpp
{
static constexpr bool quiet_auto_rollback = false;
static constexpr bool report_auto_rollback = true;
template<typename Db>
class transaction_t
{
Db& _db;
const bool _report_unfinished_transaction;
bool _finished = false;
public:
transaction_t(Db& db, bool report_unfinished_transaction):
_db(db),
_report_unfinished_transaction(report_unfinished_transaction)
{
_db.start_transaction();
}
transaction_t(const transaction_t&) = delete;
transaction_t(transaction_t&&) = default;
transaction_t& operator=(const transaction_t&) = delete;
transaction_t& operator=(transaction_t&&) = delete;
~transaction_t()
{
if (not _finished)
{
try
{
_db.rollback_transaction(_report_unfinished_transaction);
}
catch(const std::exception& e)
{
_db.report_rollback_failure(std::string("auto rollback failed: ") + e.what());
}
catch(...)
{
_db.report_rollback_failure("auto rollback failed with unknown exception");
}
}
}
void commit()
{
_finished = true;
_db.commit_transaction();
}
void rollback()
{
_finished = true;
_db.rollback_transaction(false);
}
};
template<typename Db>
transaction_t<typename std::decay<Db>::type> start_transaction(Db& db, bool report_unfinished_transaction = report_auto_rollback)
{
return { db, report_unfinished_transaction };
};
}
#endif

117
type_traits.h Normal file
View File

@ -0,0 +1,117 @@
/*
* 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_TYPE_TRAITS_H
#define SQLPP_TYPE_TRAITS_H
#include <sqlpp11/detail/wrap_operand.h>
#include <sqlpp11/detail/tag.h>
namespace sqlpp
{
#define SQLPP_IS_VALUE_TRAIT_GENERATOR(name) \
namespace detail\
{\
template<typename T, typename Enable = void>\
struct is_##name##_impl: std::false_type {};\
template<typename T>\
struct is_##name##_impl<T, typename std::enable_if<std::is_same<typename T::_value_type::_is_##name, tag>::value>::type>: std::true_type {};\
}\
template<typename T>\
struct is_##name##_t: detail::is_##name##_impl<T> {};
#define SQLPP_IS_COLUMN_TRAIT_GENERATOR(name) \
namespace detail\
{\
template<typename T, typename Enable = void>\
struct name##_impl: std::false_type {};\
template<typename T>\
struct name##_impl<T, typename std::enable_if<std::is_same<typename T::_column_type::_##name, tag>::value>::type>: std::true_type {};\
}\
template<typename T>\
struct name##_t: detail::name##_impl<T> {};
#define SQLPP_TYPE_TRAIT_GENERATOR(name) \
namespace detail\
{\
template<typename T, typename Enable = void>\
struct name##_impl: std::false_type {};\
template<typename T>\
struct name##_impl<T, typename std::enable_if<std::is_same<typename T::_##name, tag>::value>::type>: std::true_type {};\
}\
template<typename T>\
struct name##_t: detail::name##_impl<T> {};
SQLPP_IS_VALUE_TRAIT_GENERATOR(boolean);
SQLPP_IS_VALUE_TRAIT_GENERATOR(numeric);
SQLPP_IS_VALUE_TRAIT_GENERATOR(text);
SQLPP_IS_VALUE_TRAIT_GENERATOR(value);
SQLPP_IS_VALUE_TRAIT_GENERATOR(expression);
SQLPP_IS_VALUE_TRAIT_GENERATOR(named_expression);
SQLPP_IS_VALUE_TRAIT_GENERATOR(alias); // FIXME: Is this really part of the value?
SQLPP_IS_VALUE_TRAIT_GENERATOR(select_flag);
SQLPP_IS_COLUMN_TRAIT_GENERATOR(must_not_insert);
SQLPP_IS_COLUMN_TRAIT_GENERATOR(must_not_update);
SQLPP_IS_COLUMN_TRAIT_GENERATOR(require_insert);
SQLPP_IS_COLUMN_TRAIT_GENERATOR(can_be_null);
SQLPP_IS_COLUMN_TRAIT_GENERATOR(trivial_value_is_null);
SQLPP_TYPE_TRAIT_GENERATOR(is_table);
SQLPP_TYPE_TRAIT_GENERATOR(is_select);
SQLPP_TYPE_TRAIT_GENERATOR(is_select_flag_list);
SQLPP_TYPE_TRAIT_GENERATOR(is_select_expression_list);
SQLPP_TYPE_TRAIT_GENERATOR(is_from);
SQLPP_TYPE_TRAIT_GENERATOR(is_where);
SQLPP_TYPE_TRAIT_GENERATOR(is_group_by);
SQLPP_TYPE_TRAIT_GENERATOR(is_having);
SQLPP_TYPE_TRAIT_GENERATOR(is_order_by);
SQLPP_TYPE_TRAIT_GENERATOR(is_limit);
SQLPP_TYPE_TRAIT_GENERATOR(is_offset);
SQLPP_TYPE_TRAIT_GENERATOR(is_using);
SQLPP_TYPE_TRAIT_GENERATOR(is_column_list);
SQLPP_TYPE_TRAIT_GENERATOR(is_multi_column);
SQLPP_TYPE_TRAIT_GENERATOR(is_value_list);
SQLPP_TYPE_TRAIT_GENERATOR(is_assignment);
SQLPP_TYPE_TRAIT_GENERATOR(is_assignment_list);
SQLPP_TYPE_TRAIT_GENERATOR(is_sort_order);
SQLPP_TYPE_TRAIT_GENERATOR(requires_braces);
template<typename T, template<typename> class IsTag>
using copy_type_trait = typename std::conditional<IsTag<T>::value, detail::tag, void>::type;
template<typename T, template<typename> class IsCorrectType>
struct operand_t
{
using type = typename detail::wrap_operand<typename std::decay<T>::type>::type;
static_assert(not is_alias_t<type>::value, "expression operand must not be an alias");
static_assert(is_expression_t<type>::value, "expression required");
static_assert(IsCorrectType<type>::value, "invalid operand type");
};
}
#endif

122
update.h Normal file
View File

@ -0,0 +1,122 @@
/*
* 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_UPDATE_H
#define SQLPP_UPDATE_H
#include <sstream>
#include <sqlpp11/noop.h>
#include <sqlpp11/assignment_list.h>
#include <sqlpp11/where.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp
{
template<
typename Table = noop,
typename Assignments = noop,
typename Where = noop
>
struct update_t;
template<
typename Table,
typename Assignments,
typename Where
>
struct update_t
{
static_assert(is_noop<Table>::value or is_table_t<Table>::value, "invalid 'Table' argument");
static_assert(is_noop<Assignments>::value or is_assignment_list_t<Assignments>::value, "invalid 'Assignments' arguments");
static_assert(is_noop<Where>::value or is_where_t<Where>::value, "invalid 'Where' argument");
template<typename... Assignment>
using add_assignments_t = update_t<Table, assignment_list_t<must_not_update_t, typename std::decay<Assignment>::type...>, Where>;
template<typename Expr>
using add_where_t = update_t<Table, Assignments, where_t<typename std::decay<Expr>::type>>;
template<typename... Assignment>
add_assignments_t<Assignment...> set(Assignment&&... assignment)
{
static_assert(std::is_same<Assignments, noop>::value, "cannot call set() twice");
return {
_table,
{{std::forward<Assignment>(assignment)...}},
_where,
};
}
template<typename Expr>
add_where_t<Expr> where(Expr&& where)
{
static_assert(not std::is_same<Assignments, noop>::value, "cannot call where() if set() hasn't been called yet");
static_assert(std::is_same<Where, noop>::value, "cannot call where() twice");
return {
_table,
_assignments,
{std::forward<Expr>(where)},
};
}
template<typename Db>
const update_t& serialize(std::ostream& os, Db& db) const
{
os << "UPDATE ";
_table.serialize(os, db);
_assignments.serialize(os, db);
_where.serialize(os, db);
return *this;
}
template<typename Db>
update_t& serialize(std::ostream& os, Db& db)
{
static_cast<const update_t*>(this)->serialize(os, db);
return *this;
}
template<typename Db>
std::size_t run(Db& db) const
{
std::ostringstream oss;
serialize(oss, db);
return db.update(oss.str());
}
Table _table;
Assignments _assignments;
Where _where;
};
template<typename Table>
constexpr update_t<typename std::decay<Table>::type> update(Table&& table)
{
return {std::forward<Table>(table)};
}
}
#endif

54
using.h Normal file
View File

@ -0,0 +1,54 @@
/*
* 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_USING_H
#define SQLPP_USING_H
#include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/serialize_tuple.h>
#include <ostream>
namespace sqlpp
{
template<typename... Table>
struct using_t
{
using _is_using = tag_yes;
static_assert(sizeof...(Table), "at least one table argument required in using");
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << " USING ";
detail::serialize_tuple(os, db, _tables, ',');
}
std::tuple<Table...> _tables;
};
}
#endif

56
where.h Normal file
View File

@ -0,0 +1,56 @@
/*
* 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_WHERE_H
#define SQLPP_WHERE_H
#include <sqlpp11/select_fwd.h>
#include <sqlpp11/expression.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h>
namespace sqlpp
{
template<typename Expr>
struct where_t
{
static_assert(is_expression_t<Expr>::value, "invalid expression argument in where()");
using _is_where = tag_yes;
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << " WHERE ";
_expr.serialize(os, db);
}
Expr _expr;
};
}
#endif