mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-15 20:31:16 +08:00
Merge branch 'release/0.30'
Conflicts: CMakeLists.txt examples/CMakeLists.txt examples/select.cpp include/sqlpp11/interpret_tuple.h include/sqlpp11/type_traits.h
This commit is contained in:
commit
67b86a7554
53
.clang-format
Normal file
53
.clang-format
Normal file
@ -0,0 +1,53 @@
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -2
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
AlignEscapedNewlinesLeft: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
BreakBeforeBinaryOperators: false
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BinPackParameters: false
|
||||
ColumnLimit: 160
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
DerivePointerAlignment: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
IndentCaseLabels: true
|
||||
IndentWrappedFunctionNames: false
|
||||
IndentFunctionDeclarationAfterType: false
|
||||
MaxEmptyLinesToKeep: 1
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
NamespaceIndentation: All
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: false
|
||||
PenaltyBreakBeforeFirstCallParameter: 1
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 200
|
||||
PointerAlignment: Left
|
||||
SpacesBeforeTrailingComments: 2
|
||||
Cpp11BracedListStyle: true
|
||||
Standard: Cpp11
|
||||
IndentWidth: 2
|
||||
TabWidth: 2
|
||||
UseTab: Never
|
||||
BreakBeforeBraces: Allman
|
||||
SpacesInParentheses: false
|
||||
SpacesInAngles: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
ContinuationIndentWidth: 4
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
SpaceBeforeParens: ControlStatements
|
||||
DisableFormat: false
|
10
.travis.yml
10
.travis.yml
@ -13,12 +13,20 @@ notifications:
|
||||
on_failure: always
|
||||
|
||||
before_install:
|
||||
# install boost 1.50 (headers only), travis currently offers 1.46 and 1.48
|
||||
- wget http://sourceforge.net/projects/boost/files/boost/1.50.0/boost_1_50_0.tar.bz2/download -O /tmp/boost.tar.bz2
|
||||
- mkdir -p temp
|
||||
- cd temp
|
||||
- tar jxf /tmp/boost.tar.bz2 boost_1_50_0/boost # extract headers only
|
||||
- sudo mkdir -p /usr/local/include/
|
||||
- sudo ln -s $PWD/boost_1_50_0/boost /usr/local/include
|
||||
- cd ..
|
||||
#install g++-4.8
|
||||
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
|
||||
- sudo apt-get update
|
||||
- if [ "$CXX" = "g++" ]; then sudo apt-get install g++-4.8; fi
|
||||
- if [ "$CXX" = "g++" ]; then export CXX="g++-4.8" CC="gcc-4.8"; fi
|
||||
|
||||
|
||||
install:
|
||||
- "mkdir -p $TRAVIS_BUILD_DIR/build/scripts"
|
||||
- "cd $TRAVIS_BUILD_DIR/build/scripts"
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2013-2014, Roland Bock
|
||||
# Copyright (c) 2013-2015, Roland Bock
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -36,7 +36,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall ${CMAKE_CXX_FLAGS}")
|
||||
endif ()
|
||||
set(CMAKE_CXX_FLAGS "-Wconversion -Wpedantic ${CMAKE_CXX_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "-Wconversion -Wpedantic -Wshadow ${CMAKE_CXX_FLAGS}")
|
||||
|
||||
set(include_dir "${PROJECT_SOURCE_DIR}/include")
|
||||
file(GLOB_RECURSE sqlpp_headers "${include_dir}/*.h")
|
||||
|
2
LICENSE
2
LICENSE
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2013-2014, Roland Bock
|
||||
Copyright (c) 2013-2015, Roland Bock
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,9 +1,9 @@
|
||||
|
||||
macro (build arg)
|
||||
# Add headers to sources to enable file browsing in IDEs
|
||||
include_directories("${CMAKE_SOURCE_DIR}/tests")
|
||||
add_executable("Sqlpp11Example${arg}" "${arg}.cpp" ${sqlpp_headers} "${CMAKE_SOURCE_DIR}/tests/MockDb.h" "${CMAKE_CURRENT_LIST_DIR}/Sample.h")
|
||||
add_test("${arg}" "${CMAKE_BINARY_DIR}/examples/Sqlpp11Example${arg}")
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../tests")
|
||||
add_executable("Sqlpp11Example${arg}" "${arg}.cpp" ${sqlpp_headers} "${CMAKE_CURRENT_SOURCE_DIR}/../tests/MockDb.h" "${CMAKE_CURRENT_LIST_DIR}/Sample.h")
|
||||
add_test("${arg}" "Sqlpp11Example${arg}")
|
||||
endmacro ()
|
||||
|
||||
#build(sample)
|
||||
@ -11,6 +11,13 @@ build(insert)
|
||||
build(update)
|
||||
build(remove)
|
||||
build(select)
|
||||
find_package(Boost 1.50)
|
||||
if(Boost_FOUND)
|
||||
MESSAGE(${Boost_INCLUDE_DIRS})
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
build(ppgen)
|
||||
endif()
|
||||
|
||||
|
||||
#find_package(PythonInterp REQUIRED)
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <sqlpp11/table.h>
|
||||
#include <sqlpp11/column_types.h>
|
||||
#include <sqlpp11/char_sequence.h>
|
||||
|
||||
namespace test
|
||||
{
|
||||
@ -10,9 +11,10 @@ namespace test
|
||||
{
|
||||
struct Id
|
||||
{
|
||||
struct _name_t
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "id"; }
|
||||
static constexpr const char _literal[] = "id";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
@ -25,9 +27,10 @@ namespace test
|
||||
};
|
||||
struct Name
|
||||
{
|
||||
struct _name_t
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "name"; }
|
||||
static constexpr const char _literal[] = "name";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
@ -40,9 +43,10 @@ namespace test
|
||||
};
|
||||
struct Feature
|
||||
{
|
||||
struct _name_t
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "feature"; }
|
||||
static constexpr const char _literal[] = "feature";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
@ -60,9 +64,10 @@ namespace test
|
||||
TabPerson_::Name,
|
||||
TabPerson_::Feature>
|
||||
{
|
||||
struct _name_t
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "tab_person"; }
|
||||
static constexpr const char _literal[] = "tab_person";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
@ -76,9 +81,10 @@ namespace test
|
||||
{
|
||||
struct Id
|
||||
{
|
||||
struct _name_t
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "id"; }
|
||||
static constexpr const char _literal[] = "id";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
@ -91,9 +97,10 @@ namespace test
|
||||
};
|
||||
struct Name
|
||||
{
|
||||
struct _name_t
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "name"; }
|
||||
static constexpr const char _literal[] = "name";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
@ -106,9 +113,10 @@ namespace test
|
||||
};
|
||||
struct Fatal
|
||||
{
|
||||
struct _name_t
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "fatal"; }
|
||||
static constexpr const char _literal[] = "fatal";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
@ -126,9 +134,10 @@ namespace test
|
||||
TabFeature_::Name,
|
||||
TabFeature_::Fatal>
|
||||
{
|
||||
struct _name_t
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "tab_feature"; }
|
||||
static constexpr const char _literal[] = "tab_feature";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Roland Bock
|
||||
* Copyright (c) 2014-2015 Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
99
examples/ppgen.cpp
Normal file
99
examples/ppgen.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2015, niXman (i dot nixman dog gmail dot com)
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if 0 // syntax example
|
||||
SQLPP_DECLARE_TABLE(
|
||||
(table, \
|
||||
SQLPP_DROP_IF_EXISTS \
|
||||
,SQLPP_CREATE_IF_NOT_EXISTS \
|
||||
,SQLPP_ENGINE("InnoDB") \
|
||||
,SQLPP_CHARACTER_SET("utf-8") \
|
||||
,SQLPP_COMMENT("table comments") \
|
||||
)
|
||||
,
|
||||
(id, int, SQLPP_NOT_NULL, SQLPP_PRIMARY_KEY, SQLPP_AUTO_INCREMENT)
|
||||
(name, varchar(64), SQLPP_NOT_NULL, SQLPP_INDEX("name_index"), SQLPP_DEFAULT("any name"))
|
||||
(age, int, SQLPP_NOT_NULL, SQLPP_INDEX("age_index"), SQLPP_UNIQUE, SQLPP_COMMENT("some comments"))
|
||||
)
|
||||
#endif
|
||||
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
#include <sqlpp11/ppgen.h>
|
||||
|
||||
#include "MockDb.h"
|
||||
|
||||
SQLPP_DECLARE_TABLE(
|
||||
(tab_person)
|
||||
,
|
||||
(id , int , SQLPP_AUTO_INCREMENT)
|
||||
(name , varchar(255), SQLPP_NOT_NULL )
|
||||
(feature, int , SQLPP_NOT_NULL )
|
||||
)
|
||||
|
||||
SQLPP_DECLARE_TABLE(
|
||||
(tab_feature)
|
||||
,
|
||||
(id , int , SQLPP_AUTO_INCREMENT)
|
||||
(name , varchar(255), SQLPP_NULL )
|
||||
(fatal, bool , SQLPP_NOT_NULL )
|
||||
)
|
||||
|
||||
int main() {
|
||||
MockDb db;
|
||||
tab_person::tab_person p;
|
||||
tab_feature::tab_feature f;
|
||||
|
||||
db(insert_into(f).set(f.name = "loves c++", f.fatal = false));
|
||||
|
||||
//db(insert_into(f).set(f.nahme = "loves c++", f.fatal = false));
|
||||
|
||||
//db(insert_into(f).set(f.name == "loves c++", f.fatal = false));
|
||||
|
||||
//db(insert_into(f).set(f.name = "loves c++", f.fatal = "false"));
|
||||
|
||||
//db(insert_into(p).set(f.name = "loves c++", f.fatal = false));
|
||||
|
||||
//db(insert_into(f).set(f.name = "loves c++", p.feature = 7));
|
||||
|
||||
//db(insert_into(f).set(f.id = 42, f.name = "loves c++", f.fatal = false));
|
||||
|
||||
//db(insert_into(f).set(f.name = "loves c++"));
|
||||
|
||||
|
||||
db(insert_into(f).default_values());
|
||||
|
||||
auto i = insert_into(p).columns(p.name, p.feature);
|
||||
i.values.add(p.name = "Roland", p.feature = 1);
|
||||
i.values.add(p.name = "Zaphod", p.feature = sqlpp::default_value);
|
||||
db(i);
|
||||
|
||||
|
||||
auto pi = db.prepare(insert_into(p).set(p.name = parameter(f.name), p.feature = parameter(p.feature)));
|
||||
pi.params.name = "likes java";
|
||||
pi.params.feature = true;
|
||||
|
||||
db(pi);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Roland Bock
|
||||
* Copyright (c) 2014-2015 Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Roland Bock
|
||||
* Copyright (c) 2014-2015 Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Roland Bock
|
||||
* Copyright (c) 2014-2015 Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -34,6 +34,9 @@
|
||||
#include "MockDb.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
static constexpr bool some_condition = true;
|
||||
static constexpr bool some_other_condition = false;
|
||||
|
||||
SQLPP_ALIAS_PROVIDER(cheesecake)
|
||||
|
||||
MockDb db;
|
||||
@ -91,8 +94,8 @@ int main()
|
||||
|
||||
|
||||
|
||||
#if !0
|
||||
auto s = select(all_of(p))
|
||||
#if 0
|
||||
auto s = select(p.id, p.name, f.id.as(cheesecake))
|
||||
.from(p, f)
|
||||
.where(p.name == any(select(f.name)
|
||||
.from(f)
|
||||
@ -103,12 +106,32 @@ int main()
|
||||
.limit(3).offset(7);
|
||||
|
||||
auto x = s.as(sqlpp::alias::x);
|
||||
for (const auto& row : db(select(p.id, x.name)
|
||||
.from(p.join(x).on(p.feature == x.feature))
|
||||
for (const auto& row : db(select(p.id, p.name, all_of(x).as(x))
|
||||
.from(p.join(x).on(p.feature == x.cheesecake))
|
||||
.where(true)))
|
||||
{
|
||||
int64_t id = row.id;
|
||||
std::string name = row.name;
|
||||
std::string x_name = row.x.name;
|
||||
int cheesecake = row.x.cheesecake;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if !0
|
||||
auto dysel = dynamic_select(db).dynamic_columns(p.name).from(p).dynamic_where();
|
||||
|
||||
if (some_condition)
|
||||
dysel.selected_columns.add(p.feature);
|
||||
|
||||
if (some_other_condition)
|
||||
dysel.where.add(p.id > 17);
|
||||
|
||||
for (const auto& row : db(dysel))
|
||||
{
|
||||
std::string name = row.name;
|
||||
std::string feature = row.at("feature");
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -129,7 +152,5 @@ int main()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Roland Bock
|
||||
* Copyright (c) 2014-2015 Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -36,12 +36,12 @@ namespace sqlpp
|
||||
struct expression_alias_t
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Expression>, tag::is_selectable, tag::is_alias>;
|
||||
using _recursive_traits = make_recursive_traits<Expression>;
|
||||
using _nodes = detail::type_vector<Expression>;
|
||||
|
||||
static_assert(is_expression_t<Expression>::value, "invalid argument for an expression alias");
|
||||
static_assert(not is_alias_t<Expression>::value, "cannot create an alias of an alias");
|
||||
|
||||
using _name_t = typename AliasProvider::_name_t;
|
||||
using _alias_t = typename AliasProvider::_alias_t;
|
||||
|
||||
Expression _expression;
|
||||
};
|
||||
@ -49,14 +49,14 @@ namespace sqlpp
|
||||
template<typename Context, typename Expression, typename AliasProvider>
|
||||
struct serializer_t<Context, expression_alias_t<Expression, AliasProvider>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Expression>;
|
||||
using T = expression_alias_t<Expression, AliasProvider>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << '(';
|
||||
serialize(t._expression, context);
|
||||
context << ") AS ";
|
||||
context << T::_name_t::_get_name();
|
||||
serialize_operand(t._expression, context);
|
||||
context << " AS ";
|
||||
context << name_of<T>::char_ptr();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -28,13 +28,15 @@
|
||||
#define SQLPP_ALIAS_PROVIDER_H
|
||||
|
||||
#include <type_traits>
|
||||
#include <sqlpp11/char_sequence.h>
|
||||
|
||||
#define SQLPP_ALIAS_PROVIDER(name) \
|
||||
struct name##_t\
|
||||
{\
|
||||
struct _name_t\
|
||||
struct _alias_t\
|
||||
{\
|
||||
static constexpr const char* _get_name() { return #name; }\
|
||||
static constexpr const char _literal[] = #name;\
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;\
|
||||
template<typename T>\
|
||||
struct _member_t\
|
||||
{\
|
||||
@ -55,7 +57,7 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_alias_provider_t<T, typename std::enable_if<std::is_class<typename T::_name_t::template _member_t<int>>::value, void>::type>
|
||||
struct is_alias_provider_t<T, typename std::enable_if<std::is_class<typename T::_alias_t::template _member_t<int>>::value, void>::type>
|
||||
{
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -51,14 +51,26 @@ namespace sqlpp
|
||||
return {};
|
||||
}
|
||||
|
||||
struct assert_no_stand_alone_all_of_t
|
||||
{
|
||||
using type = std::false_type;
|
||||
|
||||
template<typename T = void>
|
||||
static void _()
|
||||
{
|
||||
static_assert(wrong_t<T>::value, "all_of(table) seems to be used outside of select");
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context, typename Table>
|
||||
struct serializer_t<Context, all_of_t<Table>>
|
||||
{
|
||||
using _serialize_check = assert_no_stand_alone_all_of_t;
|
||||
using T = all_of_t<Table>;
|
||||
|
||||
static Context& _(const T& t, const Context&)
|
||||
{
|
||||
static_assert(wrong_t<serializer_t>::value, "all_of(table) does not seem to be used in select");
|
||||
_serialize_check::_();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -28,6 +28,7 @@
|
||||
#define SQLPP_ANY_H
|
||||
|
||||
#include <sqlpp11/boolean.h>
|
||||
#include <sqlpp11/char_sequence.h>
|
||||
#include <sqlpp11/detail/type_set.h>
|
||||
|
||||
namespace sqlpp
|
||||
@ -36,11 +37,12 @@ namespace sqlpp
|
||||
struct any_t
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Select>, tag::is_multi_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Select>;
|
||||
using _nodes = detail::type_vector<Select>;
|
||||
|
||||
struct _name_t
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "ANY"; }
|
||||
static constexpr const char _literal[] = "any_";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
@ -66,6 +68,7 @@ namespace sqlpp
|
||||
template<typename Context, typename Select>
|
||||
struct serializer_t<Context, any_t<Select>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Select>;
|
||||
using T = any_t<Select>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -41,7 +41,7 @@ namespace sqlpp
|
||||
struct assignment_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_assignment>;
|
||||
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||
using _nodes = detail::type_vector<Lhs, Rhs>;
|
||||
|
||||
using _lhs_t = Lhs;
|
||||
using _rhs_t = rhs_wrap_t<allow_tvin_t<Rhs>, trivial_value_is_null_t<_lhs_t>::value>;
|
||||
@ -66,13 +66,14 @@ namespace sqlpp
|
||||
template<typename Context, typename Lhs, typename Rhs>
|
||||
struct serializer_t<Context, assignment_t<Lhs, Rhs>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Lhs, Rhs>;
|
||||
using T = assignment_t<Lhs, Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
serialize(simple_column(t._lhs), context);
|
||||
context << "=";
|
||||
serialize(t._rhs, context);
|
||||
serialize_operand(t._rhs, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -28,6 +28,7 @@
|
||||
#define SQLPP_AVG_H
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/char_sequence.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -37,14 +38,15 @@ namespace sqlpp
|
||||
public alias_operators<avg_t<Flag, Expr>>
|
||||
{
|
||||
using _traits = make_traits<floating_point, tag::is_expression, tag::is_selectable>;
|
||||
using _recursive_traits = make_recursive_traits<Expr, aggregate_function>;
|
||||
using _nodes = detail::type_vector<Expr, aggregate_function>;
|
||||
|
||||
static_assert(is_noop<Flag>::value or std::is_same<distinct_t, Flag>::value, "avg() used with flag other than 'distinct'");
|
||||
static_assert(is_numeric_t<Expr>::value, "avg() requires a value expression as argument");
|
||||
|
||||
struct _name_t
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "AVG"; }
|
||||
static constexpr const char _literal[] = "avg_";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
@ -70,6 +72,7 @@ namespace sqlpp
|
||||
template<typename Context, typename Flag, typename Expr>
|
||||
struct serializer_t<Context, avg_t<Flag, Expr>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Flag, Expr>;
|
||||
using T = avg_t<Flag, Expr>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
@ -79,8 +82,12 @@ namespace sqlpp
|
||||
{
|
||||
serialize(Flag(), context);
|
||||
context << ' ';
|
||||
serialize_operand(t._expr, context);
|
||||
}
|
||||
else
|
||||
{
|
||||
serialize(t._expr, context);
|
||||
}
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
|
41
include/sqlpp11/bad_statement.h
Normal file
41
include/sqlpp11/bad_statement.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, 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_BAD_STATEMENT_H
|
||||
#define SQLPP_BAD_STATEMENT_H
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
struct bad_statement
|
||||
{
|
||||
template<typename... T>
|
||||
bad_statement(T&&...) {}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -34,7 +34,7 @@
|
||||
#include <sqlpp11/in_fwd.h>
|
||||
#include <sqlpp11/is_null_fwd.h>
|
||||
#include <sqlpp11/wrap_operand_fwd.h>
|
||||
#include <sqlpp11/detail/logic.h>
|
||||
#include <sqlpp11/logic.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -106,12 +106,12 @@ namespace sqlpp
|
||||
return { *static_cast<const Expr*>(this), rhs{t} };
|
||||
}
|
||||
|
||||
is_null_t<true, Expr> is_null() const
|
||||
is_null_t<Expr> is_null() const
|
||||
{
|
||||
return { *static_cast<const Expr*>(this) };
|
||||
}
|
||||
|
||||
is_null_t<false, Expr> is_not_null() const
|
||||
is_not_null_t<Expr> is_not_null() const
|
||||
{
|
||||
return { *static_cast<const Expr*>(this) };
|
||||
}
|
||||
@ -128,16 +128,16 @@ namespace sqlpp
|
||||
|
||||
// Hint: use value_list wrapper for containers...
|
||||
template<typename... T>
|
||||
in_t<true, Expr, wrap_operand_t<T>...> in(T... t) const
|
||||
in_t<Expr, wrap_operand_t<T>...> in(T... t) const
|
||||
{
|
||||
static_assert(detail::all_t<_is_valid_comparison_operand<wrap_operand_t<T>>::value...>::value, "at least one operand of in() is not valid");
|
||||
static_assert(logic::all_t<_is_valid_comparison_operand<wrap_operand_t<T>>::value...>::value, "at least one operand of in() is not valid");
|
||||
return { *static_cast<const Expr*>(this), wrap_operand_t<T>{t}... };
|
||||
}
|
||||
|
||||
template<typename... T>
|
||||
in_t<false, Expr, wrap_operand_t<T>...> not_in(T... t) const
|
||||
not_in_t<Expr, wrap_operand_t<T>...> not_in(T... t) const
|
||||
{
|
||||
static_assert(detail::all_t<_is_valid_comparison_operand<wrap_operand_t<T>>::value...>::value, "at least one operand of in() is not valid");
|
||||
static_assert(logic::all_t<_is_valid_comparison_operand<wrap_operand_t<T>>::value...>::value, "at least one operand of in() is not valid");
|
||||
return { *static_cast<const Expr*>(this), wrap_operand_t<T>{t}... };
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -36,7 +36,7 @@ namespace sqlpp
|
||||
struct boolean_expression_t: public expression_operators<boolean_expression_t<Database>, boolean>
|
||||
{
|
||||
using _traits = make_traits<boolean, tag::is_expression>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
|
||||
template<typename Expr>
|
||||
boolean_expression_t(Expr expr):
|
||||
@ -71,6 +71,7 @@ namespace sqlpp
|
||||
template<typename Context, typename Database>
|
||||
struct serializer_t<Context, boolean_expression_t<Database>>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using T = boolean_expression_t<Database>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
|
56
include/sqlpp11/char_sequence.h
Normal file
56
include/sqlpp11/char_sequence.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, 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_CHAR_SEQUENCE_H
|
||||
#define SQLPP_CHAR_SEQUENCE_H
|
||||
|
||||
#include <sqlpp11/detail/index_sequence.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<char... Cs> struct char_sequence
|
||||
{
|
||||
static const char* char_ptr()
|
||||
{
|
||||
static char s[] = {Cs...};
|
||||
return s;
|
||||
};
|
||||
};
|
||||
|
||||
template<std::size_t N, const char (&s) [N], typename T>
|
||||
struct make_char_sequence_impl;
|
||||
|
||||
template<std::size_t N, const char (&s) [N], std::size_t... i>
|
||||
struct make_char_sequence_impl<N, s, sqlpp::detail::index_sequence<i...>>
|
||||
{
|
||||
using type = char_sequence<s[i]...>;
|
||||
};
|
||||
|
||||
template<std::size_t N, const char (&Input) [N]>
|
||||
using make_char_sequence = typename make_char_sequence_impl<sizeof(Input), Input, sqlpp::detail::make_index_sequence<sizeof(Input)>>::type;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -52,21 +52,13 @@ namespace sqlpp
|
||||
using _tags = detail::make_joined_set_t<detail::type_set<tag::is_column, tag::is_expression, tag::is_selectable>, typename ColumnSpec::_traits::_tags>;
|
||||
};
|
||||
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _parameters = std::tuple<>;
|
||||
using _provided_tables = detail::type_set<>;
|
||||
using _provided_outer_tables = detail::type_set<>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
using _required_tables = detail::type_set<Table>;
|
||||
using _extra_tables = detail::type_set<>;
|
||||
using _tags = typename std::conditional<column_spec_can_be_null_t<ColumnSpec>::value,
|
||||
detail::type_set<tag::can_be_null>,
|
||||
detail::type_set<>>::type;
|
||||
};
|
||||
using _can_be_null = column_spec_can_be_null_t<ColumnSpec>;
|
||||
|
||||
using _spec_t = ColumnSpec;
|
||||
using _table = Table;
|
||||
using _name_t = typename _spec_t::_name_t;
|
||||
using _alias_t = typename _spec_t::_alias_t;
|
||||
|
||||
template<typename T>
|
||||
using _is_valid_operand = is_valid_operand<value_type_of<ColumnSpec>, T>;
|
||||
@ -78,9 +70,11 @@ namespace sqlpp
|
||||
column_t& operator=(column_t&&) = default;
|
||||
~column_t() = default;
|
||||
|
||||
static constexpr const char* _get_name()
|
||||
template<typename T = _table>
|
||||
auto table() const -> _table
|
||||
{
|
||||
return _name_t::_get_name();
|
||||
static_assert(is_table_t<T>::value, "cannot call get_table for columns of a sub-selects or cte");
|
||||
return _table{};
|
||||
}
|
||||
|
||||
template<typename alias_provider>
|
||||
@ -115,11 +109,12 @@ namespace sqlpp
|
||||
template<typename Context, typename... Args>
|
||||
struct serializer_t<Context, column_t<Args...>>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using T = column_t<Args...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << T::_table::_name_t::_get_name() << '.' << T::_name_t::_get_name();
|
||||
context << name_of<typename T::_table>::char_ptr() << '.' << name_of<T>::char_ptr();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -28,9 +28,10 @@
|
||||
#define SQLPP_CONCAT_H
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/char_sequence.h>
|
||||
#include <sqlpp11/interpret_tuple.h>
|
||||
#include <sqlpp11/basic_expression_operators.h>
|
||||
#include <sqlpp11/detail/logic.h>
|
||||
#include <sqlpp11/logic.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -41,13 +42,14 @@ namespace sqlpp
|
||||
public alias_operators<concat_t<First, Args...>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<First>, tag::is_expression, tag::is_selectable>;
|
||||
using _recursive_traits = make_recursive_traits<First, Args...>;
|
||||
using _nodes = detail::type_vector<First, Args...>;
|
||||
|
||||
static_assert(sizeof...(Args) > 0, "concat requires two arguments at least");
|
||||
static_assert(detail::all_t<is_text_t<First>::value, is_text_t<Args>::value...>::value, "at least one non-text argument detected in concat()");
|
||||
struct _name_t
|
||||
static_assert(logic::all_t<is_text_t<First>::value, is_text_t<Args>::value...>::value, "at least one non-text argument detected in concat()");
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "CONCAT"; }
|
||||
static constexpr const char _literal[] = "concat_";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
@ -71,6 +73,7 @@ namespace sqlpp
|
||||
template<typename Context, typename First, typename... Args>
|
||||
struct serializer_t<Context, concat_t<First, Args...>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, First, Args...>;
|
||||
using T = concat_t<First, Args...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -27,6 +27,7 @@
|
||||
#ifndef SQLPP_COUNT_H
|
||||
#define SQLPP_COUNT_H
|
||||
|
||||
#include <sqlpp11/char_sequence.h>
|
||||
#include <sqlpp11/select_flags.h>
|
||||
#include <sqlpp11/integral.h>
|
||||
|
||||
@ -38,23 +39,16 @@ namespace sqlpp
|
||||
public alias_operators<count_t<Flag, Expr>>
|
||||
{
|
||||
using _traits = make_traits<integral, tag::is_expression, tag::is_selectable>;
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _required_tables = required_tables_of<Expr>;
|
||||
using _provided_tables = provided_tables_of<Expr>;
|
||||
using _provided_outer_tables = provided_outer_tables_of<Expr>;
|
||||
using _extra_tables = extra_tables_of<Expr>;
|
||||
using _parameters = parameters_of<Expr>;
|
||||
using _tags = detail::make_difference_set_t<detail::joined_set_t<recursive_tags_of<Expr>, recursive_tags_of<aggregate_function>>,
|
||||
detail::type_set<tag::can_be_null>>;
|
||||
};
|
||||
|
||||
using _nodes = detail::type_vector<Expr, aggregate_function>;
|
||||
using _can_be_null = std::false_type;
|
||||
|
||||
static_assert(is_noop<Flag>::value or std::is_same<distinct_t, Flag>::value, "count() used with flag other than 'distinct'");
|
||||
|
||||
struct _name_t
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "COUNT"; }
|
||||
static constexpr const char _literal[] = "count_";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
@ -80,6 +74,7 @@ namespace sqlpp
|
||||
template<typename Context, typename Flag, typename Expr>
|
||||
struct serializer_t<Context, count_t<Flag, Expr>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Flag, Expr>;
|
||||
using T = count_t<Flag, Expr>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
@ -89,8 +84,12 @@ namespace sqlpp
|
||||
{
|
||||
serialize(Flag(), context);
|
||||
context << ' ';
|
||||
serialize_operand(t._expr, context);
|
||||
}
|
||||
else
|
||||
{
|
||||
serialize(t._expr, context);
|
||||
}
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
@ -99,6 +98,7 @@ namespace sqlpp
|
||||
template<typename T>
|
||||
auto count(T t) -> count_t<noop, wrap_operand_t<T>>
|
||||
{
|
||||
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value, "count() cannot be used on an aggregate function");
|
||||
static_assert(is_expression_t<wrap_operand_t<T>>::value, "count() requires an expression as argument");
|
||||
return { t };
|
||||
}
|
||||
@ -106,6 +106,7 @@ namespace sqlpp
|
||||
template<typename T>
|
||||
auto count(const distinct_t&, T t) -> count_t<distinct_t, wrap_operand_t<T>>
|
||||
{
|
||||
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value, "count() cannot be used on an aggregate function");
|
||||
static_assert(is_expression_t<wrap_operand_t<T>>::value, "count() requires an expression as argument");
|
||||
return { t };
|
||||
}
|
||||
|
261
include/sqlpp11/cte.h
Normal file
261
include/sqlpp11/cte.h
Normal file
@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, 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_CTE_H
|
||||
#define SQLPP_CTE_H
|
||||
|
||||
#include <sqlpp11/table_ref.h>
|
||||
#include <sqlpp11/select_flags.h>
|
||||
#include <sqlpp11/result_row.h>
|
||||
#include <sqlpp11/statement_fwd.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
#include <sqlpp11/expression.h>
|
||||
#include <sqlpp11/interpret_tuple.h>
|
||||
#include <sqlpp11/interpretable_list.h>
|
||||
#include <sqlpp11/logic.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Flag, typename Lhs, typename Rhs>
|
||||
struct cte_union_t
|
||||
{
|
||||
using _nodes = detail::type_vector<>;
|
||||
using _required_ctes = detail::make_joined_set_t<required_ctes_of<Lhs>, required_ctes_of<Rhs>>;
|
||||
using _parameters = detail::type_vector_cat_t<parameters_of<Lhs>, parameters_of<Rhs>>;
|
||||
|
||||
cte_union_t(Lhs lhs, Rhs rhs):
|
||||
_lhs(lhs),
|
||||
_rhs(rhs)
|
||||
{}
|
||||
|
||||
cte_union_t(const cte_union_t&) = default;
|
||||
cte_union_t(cte_union_t&&) = default;
|
||||
cte_union_t& operator=(const cte_union_t&) = default;
|
||||
cte_union_t& operator=(cte_union_t&&) = default;
|
||||
~cte_union_t() = default;
|
||||
|
||||
Lhs _lhs;
|
||||
Rhs _rhs;
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Flag, typename Lhs, typename Rhs>
|
||||
struct serializer_t<Context, cte_union_t<Flag, Lhs, Rhs>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Lhs, Rhs>;
|
||||
using T = cte_union_t<Flag, Lhs, Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
serialize(t._lhs, context);
|
||||
context << " UNION ";
|
||||
serialize(Flag{}, context);
|
||||
context << " ";
|
||||
serialize(t._rhs, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename AliasProvider, typename Statement, typename... FieldSpecs>
|
||||
struct cte_t;
|
||||
|
||||
template<typename AliasProvider>
|
||||
struct cte_ref_t;
|
||||
|
||||
template<typename AliasProvider, typename Statement, typename... FieldSpecs>
|
||||
auto from_table(cte_t<AliasProvider, Statement, FieldSpecs...> t) -> cte_ref_t<AliasProvider>
|
||||
{
|
||||
return cte_ref_t<AliasProvider>{};
|
||||
}
|
||||
|
||||
template<typename AliasProvider, typename Statement, typename... FieldSpecs>
|
||||
struct from_table_impl<cte_t<AliasProvider, Statement, FieldSpecs...>>
|
||||
{
|
||||
using type = cte_ref_t<AliasProvider>;
|
||||
};
|
||||
|
||||
|
||||
template<typename FieldSpec>
|
||||
struct cte_column_spec_t
|
||||
{
|
||||
using _alias_t = typename FieldSpec::_alias_t;
|
||||
|
||||
using _traits = make_traits<value_type_of<FieldSpec>,
|
||||
tag::must_not_insert,
|
||||
tag::must_not_update,
|
||||
tag_if<tag::can_be_null, column_spec_can_be_null_t<FieldSpec>::value>
|
||||
>;
|
||||
};
|
||||
|
||||
template<typename AliasProvider, typename Statement, typename ResultRow>
|
||||
struct make_cte_impl
|
||||
{
|
||||
using type = void;
|
||||
};
|
||||
|
||||
template<typename AliasProvider, typename Statement, typename... FieldSpecs>
|
||||
struct make_cte_impl<AliasProvider, Statement, result_row_t<void, FieldSpecs...>>
|
||||
{
|
||||
using type = cte_t<AliasProvider, Statement, FieldSpecs...>;
|
||||
};
|
||||
|
||||
template<typename AliasProvider, typename Statement>
|
||||
using make_cte_t = typename make_cte_impl<AliasProvider, Statement, get_result_row_t<Statement>>::type;
|
||||
|
||||
template<typename AliasProvider, typename Statement, typename... FieldSpecs>
|
||||
struct cte_t: public member_t<cte_column_spec_t<FieldSpecs>, column_t<AliasProvider, cte_column_spec_t<FieldSpecs>>>...
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_cte, tag::is_table>; // FIXME: is table? really?
|
||||
using _nodes = detail::type_vector<>;
|
||||
using _required_ctes = detail::make_joined_set_t<required_ctes_of<Statement>, detail::type_set<AliasProvider>>;
|
||||
using _parameters = parameters_of<Statement>;
|
||||
|
||||
using _alias_t = typename AliasProvider::_alias_t;
|
||||
constexpr static bool _is_recursive = detail::is_element_of<AliasProvider, required_ctes_of<Statement>>::value;
|
||||
|
||||
using _column_tuple_t = std::tuple<column_t<AliasProvider, cte_column_spec_t<FieldSpecs>>...>;
|
||||
|
||||
template<typename... T>
|
||||
using _check = logic::all_t<is_statement_t<T>::value...>;
|
||||
|
||||
using _result_row_t = result_row_t<void, FieldSpecs...>;
|
||||
|
||||
template<typename Rhs>
|
||||
auto union_distinct(Rhs rhs) const
|
||||
-> typename std::conditional<_check<Rhs>::value, cte_t<AliasProvider, cte_union_t<distinct_t, Statement, Rhs>, FieldSpecs...>, bad_statement>::type
|
||||
{
|
||||
static_assert(is_statement_t<Rhs>::value, "argument of union call has to be a statement");
|
||||
static_assert(has_policy_t<Rhs, is_select_t>::value, "argument of union call has to be a select");
|
||||
static_assert(has_result_row_t<Rhs>::value, "argument of a union has to be a (complete) select statement");
|
||||
|
||||
static_assert(std::is_same<_result_row_t, get_result_row_t<Rhs>>::value, "both select statements in a union have to have the same result columns (type and name)");
|
||||
|
||||
return _union_impl<void, distinct_t>(_check<Rhs>{}, rhs);
|
||||
}
|
||||
|
||||
template<typename Rhs>
|
||||
auto union_all(Rhs rhs) const
|
||||
-> typename std::conditional<_check<Rhs>::value, cte_t<AliasProvider, cte_union_t<all_t, Statement, Rhs>, FieldSpecs...>, bad_statement>::type
|
||||
{
|
||||
static_assert(is_statement_t<Rhs>::value, "argument of union call has to be a statement");
|
||||
static_assert(has_policy_t<Rhs, is_select_t>::value, "argument of union call has to be a select");
|
||||
static_assert(has_result_row_t<Rhs>::value, "argument of a union has to be a (complete) select statement");
|
||||
|
||||
static_assert(std::is_same<_result_row_t, get_result_row_t<Rhs>>::value, "both select statements in a union have to have the same result columns (type and name)");
|
||||
|
||||
return _union_impl<all_t>(_check<Rhs>{}, rhs);
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Flag, typename Rhs>
|
||||
auto _union_impl(const std::false_type&, Rhs rhs) const
|
||||
-> bad_statement;
|
||||
|
||||
template<typename Flag, typename Rhs>
|
||||
auto _union_impl(const std::true_type&, Rhs rhs) const
|
||||
-> cte_t<AliasProvider, cte_union_t<Flag, Statement, Rhs>, FieldSpecs...>
|
||||
{
|
||||
return cte_union_t<Flag, Statement, Rhs>{_statement, rhs};
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
cte_t(Statement statement): _statement(statement){}
|
||||
cte_t(const cte_t&) = default;
|
||||
cte_t(cte_t&&) = default;
|
||||
cte_t& operator=(const cte_t&) = default;
|
||||
cte_t& operator=(cte_t&&) = default;
|
||||
~cte_t() = default;
|
||||
|
||||
Statement _statement;
|
||||
};
|
||||
|
||||
template<typename Context, typename AliasProvider, typename Statement, typename... ColumnSpecs>
|
||||
struct serializer_t<Context, cte_t<AliasProvider, Statement, ColumnSpecs...>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Statement>;
|
||||
using T = cte_t<AliasProvider, Statement, ColumnSpecs...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << name_of<T>::char_ptr() << " AS (";
|
||||
serialize(t._statement, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// The cte_t is displayed as AliasProviderName except within the with:
|
||||
// - the with needs the
|
||||
// AliasProviderName AS (ColumnNames) (select/union)
|
||||
// The result row of the select should not have dynamic parts
|
||||
template<typename AliasProvider>
|
||||
struct cte_ref_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_alias, tag::is_cte, tag::is_table>; // FIXME: is table? really?
|
||||
using _nodes = detail::type_vector<>;
|
||||
using _required_ctes = detail::make_type_set_t<AliasProvider>;
|
||||
using _provided_tables = detail::type_set<AliasProvider>;
|
||||
|
||||
using _alias_t = typename AliasProvider::_alias_t;
|
||||
|
||||
template<typename Statement>
|
||||
auto as(Statement statement)
|
||||
-> make_cte_t<AliasProvider, Statement>
|
||||
{
|
||||
static_assert(required_tables_of<Statement>::size::value == 0, "common table expression must not use unknown tables");
|
||||
static_assert(not detail::is_element_of<AliasProvider, required_ctes_of<Statement>>::value, "common table expression must not self-reference in the first part, use union_all/union_distinct for recursion");
|
||||
static_assert(is_static_result_row_t<get_result_row_t<Statement>>::value, "ctes must not have dynamically added columns");
|
||||
|
||||
return { statement };
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context, typename AliasProvider>
|
||||
struct serializer_t<Context, cte_ref_t<AliasProvider>>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using T = cte_ref_t<AliasProvider>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << name_of<T>::char_ptr();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename AliasProvider>
|
||||
auto cte(const AliasProvider&)
|
||||
-> cte_ref_t<AliasProvider>
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
144
include/sqlpp11/custom_query.h
Normal file
144
include/sqlpp11/custom_query.h
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, 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_CUSTOM_QUERY_H
|
||||
#define SQLPP_CUSTOM_QUERY_H
|
||||
|
||||
#include <sqlpp11/connection.h>
|
||||
#include <sqlpp11/interpret_tuple.h>
|
||||
#include <sqlpp11/hidden.h>
|
||||
#include <sqlpp11/detail/get_first.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Database, typename... Parts>
|
||||
struct custom_query_t;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename Db, typename... Parts>
|
||||
struct custom_parts_t
|
||||
{
|
||||
using _custom_query_t = custom_query_t<Db, Parts...>;
|
||||
using _result_type_provider = detail::get_first_if<is_return_value_t, noop, Parts...>;
|
||||
using _result_methods_t = typename _result_type_provider::template _result_methods_t<_result_type_provider>;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Database, typename... Parts>
|
||||
struct custom_query_t:
|
||||
private detail::custom_parts_t<Database, Parts...>::_result_methods_t
|
||||
{
|
||||
using _methods_t = typename detail::custom_parts_t<Database, Parts...>::_result_methods_t;
|
||||
using _traits = make_traits<no_value_t, tag::is_statement>;
|
||||
using _nodes = detail::type_vector<Parts...>;
|
||||
|
||||
using _parameter_check = typename std::conditional<detail::type_vector_size<parameters_of<custom_query_t>>::value == 0,
|
||||
consistent_t, assert_no_parameters_t>::type;
|
||||
using _run_check = detail::get_first_if<is_inconsistent_t, consistent_t,
|
||||
_parameter_check>;
|
||||
using _prepare_check = consistent_t;
|
||||
|
||||
custom_query_t(Parts... parts):
|
||||
_parts(parts...)
|
||||
{}
|
||||
|
||||
custom_query_t(std::tuple<Parts...> parts):
|
||||
_parts(parts)
|
||||
{}
|
||||
|
||||
custom_query_t(const custom_query_t&) = default;
|
||||
custom_query_t(custom_query_t&&) = default;
|
||||
custom_query_t& operator=(const custom_query_t&) = default;
|
||||
custom_query_t& operator=(custom_query_t&&) = default;
|
||||
~custom_query_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
auto _run(Db& db) const -> decltype(std::declval<_methods_t>()._run(db, *this))
|
||||
{
|
||||
_run_check::_();
|
||||
return _methods_t::_run(db, *this);
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
auto _prepare(Db& db) const -> decltype(std::declval<_methods_t>()._prepare(db, *this))
|
||||
{
|
||||
_prepare_check::_();
|
||||
return _methods_t::_prepare(db, *this);
|
||||
}
|
||||
|
||||
static constexpr size_t _get_static_no_of_parameters()
|
||||
{
|
||||
return std::tuple_size<parameters_of<custom_query_t>>::value;
|
||||
}
|
||||
|
||||
size_t _get_no_of_parameters() const
|
||||
{
|
||||
return _get_static_no_of_parameters();
|
||||
}
|
||||
|
||||
template<typename Part>
|
||||
auto with_result_type_of(Part part)
|
||||
-> custom_query_t<Database, Part, Parts...>
|
||||
{
|
||||
return {tuple_cat(std::make_tuple(part), _parts)};
|
||||
}
|
||||
|
||||
std::tuple<Parts...> _parts;
|
||||
};
|
||||
|
||||
template<typename Context, typename Database, typename... Parts>
|
||||
struct serializer_t<Context, custom_query_t<Database, Parts...>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Parts...>;
|
||||
using T = custom_query_t<Database, Parts...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
interpret_tuple_without_braces(t._parts, " ", context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename... Parts>
|
||||
auto custom_query(Parts... parts)
|
||||
-> custom_query_t<void, wrap_operand_t<Parts>...>
|
||||
{
|
||||
static_assert(sizeof...(Parts) > 0, "custom query requires at least one argument");
|
||||
return custom_query_t<void, wrap_operand_t<Parts>...>(parts...);
|
||||
}
|
||||
|
||||
template<typename Database, typename... Parts>
|
||||
auto dynamic_custom_query(const Database&, Parts... parts)
|
||||
-> custom_query_t<Database, wrap_operand_t<Parts>...>
|
||||
{
|
||||
static_assert(sizeof...(Parts) > 0, "custom query requires at least one query argument");
|
||||
static_assert(std::is_base_of<connection, Database>::value, "Invalid database parameter");
|
||||
|
||||
return custom_query_t<Database, wrap_operand_t<Parts>...>(parts...);
|
||||
}
|
||||
}
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -34,7 +34,7 @@ namespace sqlpp
|
||||
struct default_value_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_expression>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
|
||||
static constexpr bool _is_trivial() { return false; }
|
||||
};
|
||||
@ -42,6 +42,7 @@ namespace sqlpp
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, default_value_t>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using Operand = default_value_t;
|
||||
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
60
include/sqlpp11/detail/get_first.h
Normal file
60
include/sqlpp11/detail/get_first.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, 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_GET_FIRST_H
|
||||
#define SQLPP_DETAIL_GET_FIRST_H
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<template<typename> class Predicate, typename Default, typename... T>
|
||||
struct get_first_if_impl;
|
||||
|
||||
template<template<typename> class Predicate, typename Default>
|
||||
struct get_first_if_impl<Predicate, Default>
|
||||
{
|
||||
using type = Default;
|
||||
};
|
||||
|
||||
template<template<typename> class Predicate, typename Default, typename T, typename... Rest>
|
||||
struct get_first_if_impl<Predicate, Default, T, Rest...>
|
||||
{
|
||||
using rest = typename get_first_if_impl<Predicate, Default, Rest...>::type;
|
||||
using type = typename std::conditional<Predicate<T>::value,
|
||||
T,
|
||||
rest>::type;
|
||||
};
|
||||
|
||||
template<template<typename> class Predicate, typename Default, typename... T>
|
||||
using get_first_if = typename get_first_if_impl<Predicate, Default, T...>::type;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -27,10 +27,9 @@
|
||||
#ifndef SQLPP_DETAIL_TYPE_SET_H
|
||||
#define SQLPP_DETAIL_TYPE_SET_H
|
||||
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <sqlpp11/wrong.h>
|
||||
#include <sqlpp11/detail/logic.h>
|
||||
#include <sqlpp11/logic.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -40,6 +39,9 @@ namespace sqlpp
|
||||
template<typename... T>
|
||||
struct make_type_set;
|
||||
|
||||
template<typename... T>
|
||||
using make_type_set_t = typename make_type_set<T...>::type;
|
||||
|
||||
template<typename E, typename SET>
|
||||
struct is_element_of;
|
||||
|
||||
@ -50,7 +52,7 @@ namespace sqlpp
|
||||
using size = std::integral_constant<size_t, sizeof...(Elements)>;
|
||||
using _is_type_set = std::true_type;
|
||||
|
||||
static_assert(std::is_same<type_set, typename make_type_set<Elements...>::type>::value, "use make_type_set to construct a set");
|
||||
static_assert(std::is_same<type_set, make_type_set_t<Elements...>>::value, "use make_type_set to construct a typeset");
|
||||
|
||||
template<typename T>
|
||||
struct insert
|
||||
@ -79,7 +81,7 @@ namespace sqlpp
|
||||
template<typename E, typename... Elements>
|
||||
struct is_element_of<E, type_set<Elements...>>
|
||||
{
|
||||
static constexpr bool value = any_t<std::is_same<E, Elements>::value...>::value;
|
||||
static constexpr bool value = ::sqlpp::logic::any_t<std::is_same<E, Elements>::value...>::value;
|
||||
};
|
||||
|
||||
template<typename L, typename R>
|
||||
@ -91,7 +93,7 @@ namespace sqlpp
|
||||
template<typename... LElements, typename... RElements>
|
||||
struct joined_set<type_set<LElements...>, type_set<RElements...>>
|
||||
{
|
||||
using type = typename make_type_set<LElements..., RElements...>::type;
|
||||
using type = make_type_set_t<LElements..., RElements...>;
|
||||
};
|
||||
|
||||
template<typename L, typename R>
|
||||
@ -139,9 +141,6 @@ namespace sqlpp
|
||||
using type = typename make_type_set<Rest...>::type::template insert<T>::type;
|
||||
};
|
||||
|
||||
template<typename... T>
|
||||
using make_type_set_t = typename make_type_set<T...>::type;
|
||||
|
||||
template<template<typename> class Predicate, typename... T>
|
||||
struct make_type_set_if;
|
||||
|
||||
@ -168,8 +167,11 @@ namespace sqlpp
|
||||
using type = typename make_type_set_if<InversePredicate, T...>::type;
|
||||
};
|
||||
|
||||
template<template<typename> class Predicate, typename... T>
|
||||
using make_type_set_if_not_t = typename make_type_set_if_not<Predicate, T...>::type;
|
||||
|
||||
template<typename... T>
|
||||
using has_duplicates = std::integral_constant<bool, make_type_set<T...>::type::size::value != sizeof...(T)>;
|
||||
using has_duplicates = std::integral_constant<bool, make_type_set_t<T...>::size::value != sizeof...(T)>;
|
||||
|
||||
template<typename... T>
|
||||
struct make_joined_set
|
||||
@ -205,7 +207,7 @@ namespace sqlpp
|
||||
{
|
||||
template<typename E>
|
||||
using is_subtrahend = is_element_of<E, type_set<Subtrahends...>>;
|
||||
using type = typename make_type_set_if_not<is_subtrahend, Minuends...>::type;
|
||||
using type = make_type_set_if_not_t<is_subtrahend, Minuends...>;
|
||||
};
|
||||
|
||||
template<typename Minuend, typename Subtrahend>
|
||||
@ -221,8 +223,8 @@ namespace sqlpp
|
||||
struct make_intersect_set<type_set<LhsElements...>, type_set<RhsElements...>>
|
||||
{
|
||||
template<typename E>
|
||||
using is_in_both = all_t<is_element_of<E, type_set<LhsElements...>>::value, is_element_of<E, type_set<RhsElements...>>::value>;
|
||||
using type = typename make_type_set_if<is_in_both, LhsElements...>::type;
|
||||
using is_in_both = ::sqlpp::logic::all_t<is_element_of<E, type_set<LhsElements...>>::value, is_element_of<E, type_set<RhsElements...>>::value>;
|
||||
using type = make_type_set_if_t<is_in_both, LhsElements...>;
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
@ -238,7 +240,7 @@ namespace sqlpp
|
||||
template<template<typename> class Transformation, typename... E>
|
||||
struct transform_set<Transformation, type_set<E...>>
|
||||
{
|
||||
using type = typename make_type_set<Transformation<E>...>::type;
|
||||
using type = make_type_set_t<Transformation<E>...>;
|
||||
};
|
||||
|
||||
template<template<typename> class Transformation, typename T>
|
||||
|
88
include/sqlpp11/detail/type_vector.h
Normal file
88
include/sqlpp11/detail/type_vector.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_DETAIL_TYPE_VECTOR_H
|
||||
#define SQLPP_DETAIL_TYPE_VECTOR_H
|
||||
|
||||
#include <sqlpp11/wrong.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename... T>
|
||||
struct type_vector
|
||||
{};
|
||||
|
||||
template<typename...T>
|
||||
struct type_vector_cat_impl
|
||||
{
|
||||
static_assert(wrong_t<type_vector_cat_impl>::value, "type_vector_cat must be called with type_vector arguments");
|
||||
};
|
||||
|
||||
template<>
|
||||
struct type_vector_cat_impl<>
|
||||
{
|
||||
using type = type_vector<>;
|
||||
};
|
||||
|
||||
template<typename... T>
|
||||
struct type_vector_cat_impl<type_vector<T...>>
|
||||
{
|
||||
using type = type_vector<T...>;
|
||||
};
|
||||
|
||||
template<typename... L, typename... R>
|
||||
struct type_vector_cat_impl<type_vector<L...>, type_vector<R...>>
|
||||
{
|
||||
using type = type_vector<L..., R...>;
|
||||
};
|
||||
|
||||
template<typename... L, typename... Rest>
|
||||
struct type_vector_cat_impl<type_vector<L...>, Rest...>
|
||||
{
|
||||
using type = typename type_vector_cat_impl<type_vector<L...>, typename type_vector_cat_impl<Rest...>::type>::type;
|
||||
};
|
||||
|
||||
template<typename... T>
|
||||
using type_vector_cat_t = typename type_vector_cat_impl<T...>::type;
|
||||
|
||||
template<typename T>
|
||||
struct type_vector_size
|
||||
{
|
||||
static_assert(wrong_t<type_vector_size>::value, "type_vector_size needs to be called with a type_vector argument");
|
||||
};
|
||||
|
||||
template<typename... T>
|
||||
struct type_vector_size<type_vector<T...>>
|
||||
{
|
||||
static constexpr std::size_t value = sizeof...(T);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -40,7 +40,7 @@ namespace sqlpp
|
||||
static_assert(is_database<Db>::value, "Db parameter of eval has to be a database connection");
|
||||
static_assert(is_expression_t<Expr>::value, "Expression parameter of eval has to be an sqlpp expression or a string");
|
||||
static_assert(required_tables_of<Expr>::size::value == 0, "Expression cannot be used in eval because it requires tables");
|
||||
using _name_type = alias::a_t::_name_t;
|
||||
using _name_type = alias::a_t::_alias_t;
|
||||
using _value_type = value_type_of<Expr>;
|
||||
using _field_spec = field_spec_t<_name_type, _value_type, true, false>;
|
||||
using type = result_field_t<_value_type, Db, _field_spec>;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -27,6 +27,7 @@
|
||||
#ifndef SQLPP_EXISTS_H
|
||||
#define SQLPP_EXISTS_H
|
||||
|
||||
#include <sqlpp11/char_sequence.h>
|
||||
#include <sqlpp11/boolean.h>
|
||||
|
||||
namespace sqlpp
|
||||
@ -37,13 +38,14 @@ namespace sqlpp
|
||||
public alias_operators<exists_t<Select>>
|
||||
{
|
||||
using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable>;
|
||||
using _recursive_traits = make_recursive_traits<Select>;
|
||||
using _nodes = detail::type_vector<Select>;
|
||||
|
||||
static_assert(is_select_t<Select>::value, "exists() requires a select expression as argument");
|
||||
|
||||
struct _name_t
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "EXISTS"; }
|
||||
static constexpr const char _literal[] = "exists_";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
@ -69,6 +71,7 @@ namespace sqlpp
|
||||
template<typename Context, typename Select>
|
||||
struct serializer_t<Context, exists_t<Select>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Select>;
|
||||
using T = exists_t<Select>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -44,7 +44,7 @@ namespace sqlpp
|
||||
public alias_operators<binary_expression_t<Lhs, op::equal_to, Rhs>>
|
||||
{
|
||||
using _traits = make_traits<boolean, tag::is_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||
using _nodes = detail::type_vector<Lhs, Rhs>;
|
||||
using _lhs_t = Lhs;
|
||||
using _rhs_t = rhs_wrap_t<allow_tvin_t<Rhs>, trivial_value_is_null_t<_lhs_t>::value>;
|
||||
|
||||
@ -66,12 +66,13 @@ namespace sqlpp
|
||||
template<typename Context, typename Lhs, typename Rhs>
|
||||
struct serializer_t<Context, equal_to_t<Lhs, Rhs>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Lhs, Rhs>;
|
||||
using T = equal_to_t<Lhs, Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
serialize(t._lhs, context);
|
||||
serialize_operand(t._lhs, context);
|
||||
if (t._rhs._is_null())
|
||||
{
|
||||
context << " IS NULL";
|
||||
@ -79,7 +80,7 @@ namespace sqlpp
|
||||
else
|
||||
{
|
||||
context << "=";
|
||||
serialize(t._rhs, context);
|
||||
serialize_operand(t._rhs, context);
|
||||
}
|
||||
context << ")";
|
||||
return context;
|
||||
@ -92,7 +93,7 @@ namespace sqlpp
|
||||
public alias_operators<binary_expression_t<Lhs, op::not_equal_to, Rhs>>
|
||||
{
|
||||
using _traits = make_traits<boolean, tag::is_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||
using _nodes = detail::type_vector<Lhs, Rhs>;
|
||||
using _lhs_t = Lhs;
|
||||
using _rhs_t = rhs_wrap_t<allow_tvin_t<Rhs>, trivial_value_is_null_t<_lhs_t>::value>;
|
||||
|
||||
@ -114,12 +115,13 @@ namespace sqlpp
|
||||
template<typename Context, typename Lhs, typename Rhs>
|
||||
struct serializer_t<Context, not_equal_to_t<Lhs, Rhs>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Lhs, Rhs>;
|
||||
using T = not_equal_to_t<Lhs, Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
serialize(t._lhs, context);
|
||||
serialize_operand(t._lhs, context);
|
||||
if (t._rhs._is_null())
|
||||
{
|
||||
context << " IS NOT NULL";
|
||||
@ -127,7 +129,7 @@ namespace sqlpp
|
||||
else
|
||||
{
|
||||
context << "!=";
|
||||
serialize(t._rhs, context);
|
||||
serialize_operand(t._rhs, context);
|
||||
}
|
||||
context << ")";
|
||||
return context;
|
||||
@ -140,7 +142,7 @@ namespace sqlpp
|
||||
public alias_operators<unary_expression_t<op::logical_not, Rhs>>
|
||||
{
|
||||
using _traits = make_traits<boolean, tag::is_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Rhs>;
|
||||
using _nodes = detail::type_vector<Rhs>;
|
||||
|
||||
unary_expression_t(Rhs rhs):
|
||||
_rhs(rhs)
|
||||
@ -158,6 +160,7 @@ namespace sqlpp
|
||||
template<typename Context, typename Rhs>
|
||||
struct serializer_t<Context, logical_not_t<Rhs>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Rhs>;
|
||||
using T = logical_not_t<Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
@ -165,13 +168,13 @@ namespace sqlpp
|
||||
context << "(";
|
||||
if (trivial_value_is_null_t<Rhs>::value)
|
||||
{
|
||||
serialize(t._rhs, context);
|
||||
serialize_operand(t._rhs, context);
|
||||
context << " IS NULL ";
|
||||
}
|
||||
else
|
||||
{
|
||||
context << "NOT ";
|
||||
serialize(t._rhs, context);
|
||||
serialize_operand(t._rhs, context);
|
||||
}
|
||||
context << ")";
|
||||
|
||||
@ -185,7 +188,7 @@ namespace sqlpp
|
||||
public alias_operators<binary_expression_t<Lhs, O, Rhs>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<O>, tag::is_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||
using _nodes = detail::type_vector<Lhs, Rhs>;
|
||||
|
||||
binary_expression_t(Lhs lhs, Rhs rhs):
|
||||
_lhs(lhs),
|
||||
@ -205,14 +208,15 @@ namespace sqlpp
|
||||
template<typename Context, typename Lhs, typename O, typename Rhs>
|
||||
struct serializer_t<Context, binary_expression_t<Lhs, O, Rhs>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Lhs, Rhs>;
|
||||
using T = binary_expression_t<Lhs, O, Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
serialize(t._lhs, context);
|
||||
serialize_operand(t._lhs, context);
|
||||
context << O::_name;
|
||||
serialize(t._rhs, context);
|
||||
serialize_operand(t._rhs, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
@ -224,7 +228,7 @@ namespace sqlpp
|
||||
public alias_operators<unary_expression_t<O, Rhs>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<O>, tag::is_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Rhs>;
|
||||
using _nodes = detail::type_vector<Rhs>;
|
||||
|
||||
unary_expression_t(Rhs rhs):
|
||||
_rhs(rhs)
|
||||
@ -242,13 +246,14 @@ namespace sqlpp
|
||||
template<typename Context, typename O, typename Rhs>
|
||||
struct serializer_t<Context, unary_expression_t<O, Rhs>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Rhs>;
|
||||
using T = unary_expression_t<O, Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
context << O::_name;
|
||||
serialize(t._rhs, context);
|
||||
serialize_operand(t._rhs, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -28,7 +28,7 @@
|
||||
#define SQLPP_EXTRA_TABLES_H
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/detail/logic.h>
|
||||
#include <sqlpp11/logic.h>
|
||||
#include <sqlpp11/policy_update.h>
|
||||
|
||||
namespace sqlpp
|
||||
@ -52,21 +52,9 @@ namespace sqlpp
|
||||
struct extra_tables_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_extra_tables>;
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _parameters = std::tuple<>;
|
||||
using _required_tables = detail::type_set<>;
|
||||
using _provided_outer_tables = detail::type_set<>;
|
||||
using _provided_tables = detail::type_set<>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
using _required_ctes = detail::make_joined_set_t<required_ctes_of<Tables>...>;
|
||||
using _extra_tables = detail::type_set<Tables...>;
|
||||
using _tags = detail::type_set<>;
|
||||
};
|
||||
|
||||
// FIXME: extra_tables must not require tables!
|
||||
|
||||
static_assert(sizeof...(Tables), "at least one table or join argument required in extra_tables()");
|
||||
static_assert(not detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in extra_tables()");
|
||||
static_assert(detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not a table or join in extra_tables()");
|
||||
|
||||
// Data
|
||||
using _data_t = extra_tables_data_t<Tables...>;
|
||||
@ -78,9 +66,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = extra_tables_data_t<Tables...>;
|
||||
|
||||
@ -93,13 +81,8 @@ namespace sqlpp
|
||||
{
|
||||
return t.extra_tables;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
static void _check_consistency() {}
|
||||
using _consistency_check = consistent_t;
|
||||
};
|
||||
};
|
||||
|
||||
@ -107,7 +90,7 @@ namespace sqlpp
|
||||
struct no_extra_tables_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
@ -119,9 +102,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
@ -134,21 +117,42 @@ namespace sqlpp
|
||||
{
|
||||
return t.no_extra_tables;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
template<typename Check, typename T>
|
||||
using _new_statement_t = new_statement_t<Check::value, Policies, no_extra_tables_t, T>;
|
||||
|
||||
template<typename... T>
|
||||
using _check = logic::all_t<is_table_t<T>::value...>;
|
||||
|
||||
using _consistency_check = consistent_t;
|
||||
|
||||
template<typename... Tables>
|
||||
auto extra_tables(Tables... tables) const
|
||||
-> _new_statement_t<_check<Tables...>, extra_tables_t<Tables...>>
|
||||
{
|
||||
template<typename T>
|
||||
using _new_statement_t = new_statement<Policies, no_extra_tables_t, T>;
|
||||
static_assert(_check<Tables...>::value, "at least one argument is not a table or join in extra_tables()");
|
||||
|
||||
static void _check_consistency() {}
|
||||
return _extra_tables_impl<void>(_check<Tables...>{}, tables...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto extra_tables(Args...) const
|
||||
-> _new_statement_t<extra_tables_t<Args...>>
|
||||
private:
|
||||
template<typename Database, typename... Tables>
|
||||
auto _extra_tables_impl(const std::false_type&, Tables... tables) const
|
||||
-> bad_statement;
|
||||
|
||||
template<typename Database, typename... Tables>
|
||||
auto _extra_tables_impl(const std::true_type&, Tables...) const
|
||||
-> _new_statement_t<std::true_type, extra_tables_t<Tables...>>
|
||||
{
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), extra_tables_data_t<Args...>{} };
|
||||
static_assert(required_tables_of<extra_tables_t<Tables...>>::size::value == 0, "at least one table depends on another table in extra_tables()");
|
||||
|
||||
static constexpr std::size_t _number_of_tables = detail::sum(provided_tables_of<Tables>::size::value...);
|
||||
using _unique_tables = detail::make_joined_set_t<provided_tables_of<Tables>...>;
|
||||
using _unique_table_names = detail::transform_set_t<name_of, _unique_tables>;
|
||||
static_assert(_number_of_tables == _unique_tables::size::value, "at least one duplicate table detected in extra_tables()");
|
||||
static_assert(_number_of_tables == _unique_table_names::size::value, "at least one duplicate table name detected in extra_tables()");
|
||||
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), extra_tables_data_t<Tables...>{} };
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -157,6 +161,7 @@ namespace sqlpp
|
||||
template<typename Context, typename Database, typename... Tables>
|
||||
struct serializer_t<Context, extra_tables_data_t<Database, Tables...>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Tables...>;
|
||||
using T = extra_tables_data_t<Database, Tables...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -38,9 +38,9 @@ namespace sqlpp
|
||||
tag_if<tag::can_be_null, CanBeNull>,
|
||||
tag_if<tag::null_is_trivial_value, NullIsTrivialValue>
|
||||
>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
|
||||
using _name_t = NameType;
|
||||
using _alias_t = NameType;
|
||||
};
|
||||
|
||||
template<typename AliasProvider, typename FieldSpecTuple>
|
||||
@ -56,9 +56,9 @@ namespace sqlpp
|
||||
static constexpr bool _can_be_null = can_be_null_t<NamedExpr>::value;
|
||||
static constexpr bool _depends_on_outer_table = detail::make_intersect_set_t<required_tables_of<NamedExpr>, typename Select::_used_outer_tables>::size::value > 0;
|
||||
|
||||
using type = field_spec_t<typename NamedExpr::_name_t,
|
||||
using type = field_spec_t<typename NamedExpr::_alias_t,
|
||||
value_type_of<NamedExpr>,
|
||||
detail::any_t<_can_be_null, _depends_on_outer_table>::value,
|
||||
logic::any_t<_can_be_null, _depends_on_outer_table>::value,
|
||||
null_is_trivial_value_t<NamedExpr>::value>;
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -27,11 +27,12 @@
|
||||
#ifndef SQLPP_FROM_H
|
||||
#define SQLPP_FROM_H
|
||||
|
||||
#include <sqlpp11/table_ref.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/no_data.h>
|
||||
#include <sqlpp11/interpretable_list.h>
|
||||
#include <sqlpp11/interpret_tuple.h>
|
||||
#include <sqlpp11/detail/logic.h>
|
||||
#include <sqlpp11/logic.h>
|
||||
#include <sqlpp11/detail/sum.h>
|
||||
#include <sqlpp11/policy_update.h>
|
||||
|
||||
@ -60,7 +61,7 @@ namespace sqlpp
|
||||
struct from_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_from>;
|
||||
using _recursive_traits = make_recursive_traits<Tables...>;
|
||||
using _nodes = detail::type_vector<Tables...>;
|
||||
using _is_dynamic = is_database<Database>;
|
||||
|
||||
// Data
|
||||
@ -77,9 +78,11 @@ namespace sqlpp
|
||||
static_assert(is_table_t<Table>::value, "invalid table argument in from::add()");
|
||||
using _known_tables = detail::make_joined_set_t<provided_tables_of<Tables>...>; // Hint: Joins contain more than one table
|
||||
using _known_table_names = detail::transform_set_t<name_of, _known_tables>;
|
||||
static_assert(not detail::is_element_of<typename Table::_name_t, _known_table_names>::value, "Must not use the same table name twice in from()");
|
||||
static_assert(not detail::is_element_of<typename Table::_alias_t, _known_table_names>::value, "Must not use the same table name twice in from()");
|
||||
using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, Table>;
|
||||
_serialize_check::_();
|
||||
|
||||
using ok = detail::all_t<_is_dynamic::value, is_table_t<Table>::value>;
|
||||
using ok = logic::all_t<_is_dynamic::value, is_table_t<Table>::value, _serialize_check::type::value>;
|
||||
|
||||
_add_impl(table, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
@ -88,7 +91,7 @@ namespace sqlpp
|
||||
template<typename Table>
|
||||
void _add_impl(Table table, const std::true_type&)
|
||||
{
|
||||
return _data._dynamic_tables.emplace_back(table);
|
||||
return _data._dynamic_tables.emplace_back(from_table(table));
|
||||
}
|
||||
|
||||
template<typename Table>
|
||||
@ -98,9 +101,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = from_data_t<Database, Tables...>;
|
||||
|
||||
@ -113,20 +116,16 @@ namespace sqlpp
|
||||
{
|
||||
return t.from;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
static void _check_consistency() {}
|
||||
// FIXME: We might want to check if we have too many tables define in the FROM
|
||||
using _consistency_check = consistent_t;
|
||||
};
|
||||
};
|
||||
|
||||
struct no_from_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
@ -138,9 +137,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
@ -153,41 +152,45 @@ namespace sqlpp
|
||||
{
|
||||
return t.no_from;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = new_statement<Policies, no_from_t, T>;
|
||||
|
||||
static void _check_consistency() {}
|
||||
template<typename... T>
|
||||
using _check = logic::all_t<is_table_t<T>::value...>;
|
||||
|
||||
template<typename Check, typename T>
|
||||
using _new_statement_t = new_statement_t<Check::value, Policies, no_from_t, T>;
|
||||
|
||||
using _consistency_check = consistent_t;
|
||||
|
||||
template<typename... Tables>
|
||||
auto from(Tables... tables) const
|
||||
-> _new_statement_t<from_t<void, Tables...>>
|
||||
-> _new_statement_t<_check<Tables...>, from_t<void, from_table_t<Tables>...>>
|
||||
{
|
||||
static_assert(_check<Tables...>::value, "at least one argument is not a table or join in from()");
|
||||
static_assert(sizeof...(Tables), "at least one table or join argument required in from()");
|
||||
return _from_impl<void>(tables...);
|
||||
return _from_impl<void>(_check<Tables...>{}, tables...);
|
||||
}
|
||||
|
||||
template<typename... Tables>
|
||||
auto dynamic_from(Tables... tables) const
|
||||
-> _new_statement_t<from_t<_database_t, Tables...>>
|
||||
-> _new_statement_t<_check<Tables...>, from_t<_database_t, from_table_t<Tables>...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_from must not be called in a static statement");
|
||||
return _from_impl<_database_t>(tables...);
|
||||
static_assert(_check<Tables...>::value, "at least one argument is not a table or join in from()");
|
||||
return _from_impl<_database_t>(_check<Tables...>{}, tables...);
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Database, typename... Tables>
|
||||
auto _from_impl(Tables... tables) const
|
||||
-> _new_statement_t<from_t<Database, Tables...>>
|
||||
auto _from_impl(const std::false_type&, Tables... tables) const
|
||||
-> bad_statement;
|
||||
|
||||
template<typename Database, typename... Tables>
|
||||
auto _from_impl(const std::true_type&, Tables... tables) const
|
||||
-> _new_statement_t<std::true_type, from_t<Database, from_table_t<Tables>...>>
|
||||
{
|
||||
static_assert(detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not a table or join in from()");
|
||||
static_assert(required_tables_of<from_t<Database, Tables...>>::size::value == 0, "at least one table depends on another table");
|
||||
static_assert(required_tables_of<from_t<Database, Tables...>>::size::value == 0, "at least one table depends on another table in from()");
|
||||
|
||||
static constexpr std::size_t _number_of_tables = detail::sum(provided_tables_of<Tables>::size::value...);
|
||||
using _unique_tables = detail::make_joined_set_t<provided_tables_of<Tables>...>;
|
||||
@ -195,7 +198,7 @@ namespace sqlpp
|
||||
static_assert(_number_of_tables == _unique_tables::size::value, "at least one duplicate table detected in from()");
|
||||
static_assert(_number_of_tables == _unique_table_names::size::value, "at least one duplicate table name detected in from()");
|
||||
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), from_data_t<Database, Tables...>{tables...} };
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), from_data_t<Database, from_table_t<Tables>...>{from_table(tables)...} };
|
||||
}
|
||||
|
||||
};
|
||||
@ -205,6 +208,7 @@ namespace sqlpp
|
||||
template<typename Context, typename Database, typename... Tables>
|
||||
struct serializer_t<Context, from_data_t<Database, Tables...>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Tables...>;
|
||||
using T = from_data_t<Database, Tables...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
@ -220,6 +224,11 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<typename... T>
|
||||
auto from(T&&... t) -> decltype(statement_t<void, no_from_t>().from(std::forward<T>(t)...))
|
||||
{
|
||||
return statement_t<void, no_from_t>().from(std::forward<T>(t)...);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -31,7 +31,9 @@
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
#include <sqlpp11/column_types.h>
|
||||
#include <sqlpp11/in.h>
|
||||
#include <sqlpp11/not_in.h>
|
||||
#include <sqlpp11/is_null.h>
|
||||
#include <sqlpp11/is_not_null.h>
|
||||
#include <sqlpp11/value_type.h>
|
||||
#include <sqlpp11/exists.h>
|
||||
#include <sqlpp11/any.h>
|
||||
@ -80,7 +82,7 @@ namespace sqlpp
|
||||
struct value_list_t // to be used in .in() method
|
||||
{
|
||||
using _traits = make_traits<value_type_t<typename Container::value_type>, tag::is_expression>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
|
||||
using _container_t = Container;
|
||||
|
||||
@ -100,10 +102,16 @@ namespace sqlpp
|
||||
template<typename Context, typename Container>
|
||||
struct serializer_t<Context, value_list_t<Container>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, wrap_operand_t<typename Container::value_type>>;
|
||||
using T = value_list_t<Container>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (t._container.size() == 1)
|
||||
{
|
||||
return serialize(value(*begin(t._container)), context);
|
||||
}
|
||||
|
||||
bool first = true;
|
||||
for (const auto& entry: t._container)
|
||||
{
|
||||
@ -112,7 +120,7 @@ namespace sqlpp
|
||||
else
|
||||
context << ',';
|
||||
|
||||
serialize(value(entry), context);
|
||||
serialize_operand(value(entry), context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
@ -128,7 +136,7 @@ namespace sqlpp
|
||||
template<typename T>
|
||||
constexpr const char* get_sql_name(const T&)
|
||||
{
|
||||
return T::_name_t::_get_name();
|
||||
return name_of<T>::char_ptr();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -33,7 +33,7 @@
|
||||
#include <sqlpp11/interpret_tuple.h>
|
||||
#include <sqlpp11/interpretable_list.h>
|
||||
#include <sqlpp11/policy_update.h>
|
||||
#include <sqlpp11/detail/logic.h>
|
||||
#include <sqlpp11/logic.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -55,21 +55,26 @@ namespace sqlpp
|
||||
interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
struct assert_no_unknown_tables_in_group_by_t
|
||||
{
|
||||
using type = std::false_type;
|
||||
|
||||
template<typename T = void>
|
||||
static void _()
|
||||
{
|
||||
static_assert(wrong_t<T>::value, "at least one group-by expression requires a table which is otherwise not known in the statement");
|
||||
}
|
||||
};
|
||||
|
||||
// GROUP BY
|
||||
template<typename Database, typename... Expressions>
|
||||
struct group_by_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_group_by>;
|
||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||
using _nodes = detail::type_vector<Expressions...>;
|
||||
|
||||
using _is_dynamic = is_database<Database>;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression (e.g. a column) required in group_by()");
|
||||
|
||||
static_assert(not detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in group_by()");
|
||||
|
||||
static_assert(detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in group_by()");
|
||||
|
||||
// Data
|
||||
using _data_t = group_by_data_t<Database, Expressions...>;
|
||||
|
||||
@ -89,8 +94,10 @@ namespace sqlpp
|
||||
static_assert(_is_dynamic::value, "add() must not be called for static group_by");
|
||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in group_by::add()");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in group_by::add()");
|
||||
using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, Expression>;
|
||||
_serialize_check::_();
|
||||
|
||||
using ok = detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
||||
using ok = logic::all_t<_is_dynamic::value, is_expression_t<Expression>::value, _serialize_check::type::value>;
|
||||
|
||||
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
@ -108,9 +115,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = group_by_data_t<Database, Expressions...>;
|
||||
|
||||
@ -123,12 +130,10 @@ namespace sqlpp
|
||||
{
|
||||
return t.group_by;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
static void _check_consistency() {}
|
||||
using _consistency_check = typename std::conditional<Policies::template _no_unknown_tables<group_by_t>::value,
|
||||
consistent_t,
|
||||
assert_no_unknown_tables_in_group_by_t>::type;
|
||||
};
|
||||
};
|
||||
|
||||
@ -136,7 +141,7 @@ namespace sqlpp
|
||||
struct no_group_by_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
@ -148,9 +153,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
@ -163,30 +168,49 @@ namespace sqlpp
|
||||
{
|
||||
return t.no_group_by;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = new_statement<Policies, no_group_by_t, T>;
|
||||
|
||||
static void _check_consistency() {}
|
||||
template<typename... T>
|
||||
using _check = logic::all_t<is_expression_t<T>::value...>;
|
||||
|
||||
template<typename... Args>
|
||||
auto group_by(Args... args) const
|
||||
-> _new_statement_t<group_by_t<void, Args...>>
|
||||
template<typename Check, typename T>
|
||||
using _new_statement_t = new_statement_t<Check::value, Policies, no_group_by_t, T>;
|
||||
|
||||
using _consistency_check = consistent_t;
|
||||
|
||||
template<typename... Expressions>
|
||||
auto group_by(Expressions... expressions) const
|
||||
-> _new_statement_t<_check<Expressions...>, group_by_t<void, Expressions...>>
|
||||
{
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), group_by_data_t<void, Args...>{args...} };
|
||||
static_assert(sizeof...(Expressions), "at least one expression (e.g. a column) required in group_by()");
|
||||
static_assert(_check<Expressions...>::value, "at least one argument is not an expression in group_by()");
|
||||
|
||||
return _group_by_impl<void>(_check<Expressions...>{}, expressions...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_group_by(Args... args) const
|
||||
-> _new_statement_t<group_by_t<_database_t, Args...>>
|
||||
template<typename... Expressions>
|
||||
auto dynamic_group_by(Expressions... expressions) const
|
||||
-> _new_statement_t<_check<Expressions...>, group_by_t<_database_t, Expressions...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_group_by must not be called in a static statement");
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), group_by_data_t<_database_t, Args...>{args...} };
|
||||
static_assert(_check<Expressions...>::value, "at least one argument is not an expression in group_by()");
|
||||
|
||||
return _group_by_impl<_database_t>(_check<Expressions...>{}, expressions...);
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Database, typename... Expressions>
|
||||
auto _group_by_impl(const std::false_type&, Expressions... expressions) const
|
||||
-> bad_statement;
|
||||
|
||||
template<typename Database, typename... Expressions>
|
||||
auto _group_by_impl(const std::true_type&, Expressions... expressions) const
|
||||
-> _new_statement_t<std::true_type, group_by_t<_database_t, Expressions...>>
|
||||
{
|
||||
static_assert(not detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in group_by()");
|
||||
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), group_by_data_t<Database, Expressions...>{expressions...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -195,6 +219,7 @@ namespace sqlpp
|
||||
template<typename Context, typename Database, typename... Expressions>
|
||||
struct serializer_t<Context, group_by_data_t<Database, Expressions...>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Expressions...>;
|
||||
using T = group_by_data_t<Database, Expressions...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -32,7 +32,7 @@
|
||||
#include <sqlpp11/interpret_tuple.h>
|
||||
#include <sqlpp11/interpretable_list.h>
|
||||
#include <sqlpp11/policy_update.h>
|
||||
#include <sqlpp11/detail/logic.h>
|
||||
#include <sqlpp11/logic.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -54,18 +54,26 @@ namespace sqlpp
|
||||
interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
struct assert_no_unknown_tables_in_having_t
|
||||
{
|
||||
using type = std::false_type;
|
||||
|
||||
template<typename T = void>
|
||||
static void _()
|
||||
{
|
||||
static_assert(wrong_t<T>::value, "at least one having-expression requires a table which is otherwise not known in the statement");
|
||||
}
|
||||
};
|
||||
|
||||
// HAVING
|
||||
template<typename Database, typename... Expressions>
|
||||
struct having_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_having>;
|
||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||
using _nodes = detail::type_vector<Expressions...>;
|
||||
|
||||
using _is_dynamic = is_database<Database>;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in having()");
|
||||
static_assert(detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in having()");
|
||||
|
||||
// Data
|
||||
using _data_t = having_data_t<Database, Expressions...>;
|
||||
|
||||
@ -85,8 +93,10 @@ namespace sqlpp
|
||||
static_assert(_is_dynamic::value, "having::add() can only be called for dynamic_having");
|
||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in having::add()");
|
||||
static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in having::add()");
|
||||
using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, Expression>;
|
||||
_serialize_check::_();
|
||||
|
||||
using ok = detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
||||
using ok = logic::all_t<_is_dynamic::value, is_expression_t<Expression>::value, _serialize_check::type::value>;
|
||||
|
||||
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
@ -105,9 +115,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = having_data_t<Database, Expressions...>;
|
||||
|
||||
@ -120,13 +130,10 @@ namespace sqlpp
|
||||
{
|
||||
return t.having;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
static void _check_consistency() {}
|
||||
using _consistency_check = typename std::conditional<Policies::template _no_unknown_tables<having_t>::value,
|
||||
consistent_t,
|
||||
assert_no_unknown_tables_in_having_t>::type;
|
||||
};
|
||||
};
|
||||
|
||||
@ -134,7 +141,7 @@ namespace sqlpp
|
||||
struct no_having_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
@ -146,9 +153,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
@ -161,31 +168,48 @@ namespace sqlpp
|
||||
{
|
||||
return t.no_having;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = new_statement<Policies, no_having_t, T>;
|
||||
|
||||
static void _check_consistency() {}
|
||||
template<typename... T>
|
||||
using _check = logic::all_t<is_expression_t<T>::value...>;
|
||||
|
||||
template<typename... Args>
|
||||
auto having(Args... args) const
|
||||
-> _new_statement_t<having_t<void, Args...>>
|
||||
template<typename Check, typename T>
|
||||
using _new_statement_t = new_statement_t<Check::value, Policies, no_having_t, T>;
|
||||
|
||||
using _consistency_check = consistent_t;
|
||||
|
||||
template<typename... Expressions>
|
||||
auto having(Expressions... expressions) const
|
||||
-> _new_statement_t<_check<Expressions...>, having_t<void, Expressions...>>
|
||||
{
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), having_data_t<void, Args...>{args...} };
|
||||
static_assert(_check<Expressions...>::value, "at least one argument is not an expression in having()");
|
||||
static_assert(sizeof...(Expressions), "at least one expression argument required in having()");
|
||||
|
||||
return _having_impl<void>(_check<Expressions...>{}, expressions...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_having(Args... args) const
|
||||
-> _new_statement_t<having_t<_database_t, Args...>>
|
||||
template<typename... Expressions>
|
||||
auto dynamic_having(Expressions... expressions) const
|
||||
-> _new_statement_t<_check<Expressions...>, having_t<_database_t, Expressions...>>
|
||||
{
|
||||
static_assert(_check<Expressions...>::value, "at least one argument is not an expression in having()");
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_having must not be called in a static statement");
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), having_data_t<_database_t, Args...>{args...} };
|
||||
return _having_impl<_database_t>(_check<Expressions...>{}, expressions...);
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Database, typename... Expressions>
|
||||
auto _having_impl(const std::false_type&, Expressions... expressions) const
|
||||
-> bad_statement;
|
||||
|
||||
template<typename Database, typename... Expressions>
|
||||
auto _having_impl(const std::true_type&, Expressions... expressions) const
|
||||
-> _new_statement_t<std::true_type, having_t<Database, Expressions...>>
|
||||
{
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), having_data_t<_database_t, Expressions...>{expressions...} };
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
@ -193,6 +217,7 @@ namespace sqlpp
|
||||
template<typename Context, typename Database, typename... Expressions>
|
||||
struct serializer_t<Context, having_data_t<Database, Expressions...>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Expressions...>;
|
||||
using T = having_data_t<Database, Expressions...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
|
66
include/sqlpp11/hidden.h
Normal file
66
include/sqlpp11/hidden.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, 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_HIDDEN_H
|
||||
#define SQLPP_HIDDEN_H
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Part>
|
||||
struct hidden_t:
|
||||
public Part
|
||||
{
|
||||
hidden_t(Part part):
|
||||
Part(part)
|
||||
{}
|
||||
|
||||
hidden_t(const hidden_t&) = default;
|
||||
hidden_t(hidden_t&&) = default;
|
||||
hidden_t& operator=(const hidden_t&) = default;
|
||||
hidden_t& operator=(hidden_t&&) = default;
|
||||
~hidden_t() = default;
|
||||
};
|
||||
|
||||
template<typename Context, typename Part>
|
||||
struct serializer_t<Context, hidden_t<Part>>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using T = hidden_t<Part>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Part>
|
||||
auto hidden(Part part)
|
||||
-> hidden_t<Part>
|
||||
{
|
||||
return {part};
|
||||
}
|
||||
}
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -28,26 +28,27 @@
|
||||
#define SQLPP_IN_H
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/char_sequence.h>
|
||||
#include <sqlpp11/boolean.h>
|
||||
#include <sqlpp11/in_fwd.h>
|
||||
#include <sqlpp11/detail/type_set.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<bool NotInverted, typename Operand, typename... Args>
|
||||
template<typename Operand, typename... Args>
|
||||
struct in_t:
|
||||
public expression_operators<in_t<NotInverted, Operand, Args...>, boolean>,
|
||||
public alias_operators<in_t<NotInverted, Operand, Args...>>
|
||||
public expression_operators<in_t<Operand, Args...>, boolean>,
|
||||
public alias_operators<in_t<Operand, Args...>>
|
||||
{
|
||||
using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable>;
|
||||
using _recursive_traits = make_recursive_traits<Operand, Args...>;
|
||||
using _nodes = detail::type_vector<Operand, Args...>;
|
||||
|
||||
static constexpr bool _inverted = not NotInverted;
|
||||
static_assert(sizeof...(Args) > 0, "in() requires at least one argument");
|
||||
|
||||
struct _name_t
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return _inverted ? "NOT IN" : "IN"; }
|
||||
static constexpr const char _literal[] = "in_";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
@ -70,18 +71,18 @@ namespace sqlpp
|
||||
std::tuple<Args...> _args;
|
||||
};
|
||||
|
||||
template<typename Context, bool NotInverted, typename Operand, typename... Args>
|
||||
struct serializer_t<Context, in_t<NotInverted, Operand, Args...>>
|
||||
template<typename Context, typename Operand, typename... Args>
|
||||
struct serializer_t<Context, in_t<Operand, Args...>>
|
||||
{
|
||||
using T = in_t<NotInverted, Operand, Args...>;
|
||||
using _serialize_check = serialize_check_of<Context, Args...>;
|
||||
using T = in_t<Operand, Args...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
serialize(t._operand, context);
|
||||
context << (t._inverted ? " NOT IN(" : " IN(");
|
||||
context << " IN(";
|
||||
if (sizeof...(Args) == 1)
|
||||
serialize(std::get<0>(t._args), context); // FIXME: this is a bit of a hack until there is a better overall strategy for using braces
|
||||
// see https://github.com/rbock/sqlpp11/issues/18
|
||||
serialize(std::get<0>(t._args), context);
|
||||
else
|
||||
interpret_tuple(t._args, ',', context);
|
||||
context << ')';
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -29,8 +29,10 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<bool NotInverted, typename Operand, typename... Args>
|
||||
template<typename Operand, typename... Args>
|
||||
struct in_t;
|
||||
template<typename Operand, typename... Args>
|
||||
struct not_in_t;
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -44,33 +44,44 @@ namespace sqlpp
|
||||
struct insert_t: public statement_name_t<insert_name_t>
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_return_value>;
|
||||
struct _name_t {};
|
||||
struct _alias_t {};
|
||||
|
||||
template<typename Policies>
|
||||
template<typename Statement>
|
||||
struct _result_methods_t
|
||||
{
|
||||
using _statement_t = derived_statement_t<Policies>;
|
||||
using _statement_t = Statement;
|
||||
|
||||
const _statement_t& _get_statement() const
|
||||
{
|
||||
return static_cast<const _statement_t&>(*this);
|
||||
}
|
||||
|
||||
// Execute
|
||||
template<typename Db, typename Composite>
|
||||
auto _run(Db& db, const Composite& composite) const
|
||||
-> decltype(db.insert(composite))
|
||||
{
|
||||
return db.insert(composite);
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
auto _run(Db& db) const -> decltype(db.insert(this->_get_statement()))
|
||||
{
|
||||
_statement_t::_check_consistency();
|
||||
|
||||
static_assert(_statement_t::_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead");
|
||||
return db.insert(_get_statement());
|
||||
}
|
||||
|
||||
// Prepare
|
||||
template<typename Db, typename Composite>
|
||||
auto _prepare(Db& db, const Composite& composite) const
|
||||
-> prepared_insert_t<Db, Composite>
|
||||
{
|
||||
return {{}, db.prepare_insert(composite)};
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
auto _prepare(Db& db) const
|
||||
-> prepared_insert_t<Db, _statement_t>
|
||||
{
|
||||
_statement_t::_check_consistency();
|
||||
|
||||
return {{}, db.prepare_insert(_get_statement())};
|
||||
}
|
||||
};
|
||||
@ -79,6 +90,7 @@ namespace sqlpp
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, insert_name_t>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using T = insert_name_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -50,7 +50,7 @@ namespace sqlpp
|
||||
struct type
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
};
|
||||
};
|
||||
}
|
||||
@ -103,6 +103,7 @@ namespace sqlpp
|
||||
template<typename Context, typename ValueType>
|
||||
struct serializer_t<Context, insert_value_t<ValueType>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, ValueType>;
|
||||
using T = insert_value_t<ValueType>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
@ -115,7 +116,7 @@ namespace sqlpp
|
||||
else if (t._is_default)
|
||||
context << "DEFAULT";
|
||||
else
|
||||
serialize(t._value, context);
|
||||
serialize_operand(t._value, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -28,7 +28,7 @@
|
||||
#define SQLPP_INSERT_VALUE_LIST_H
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/detail/logic.h>
|
||||
#include <sqlpp11/logic.h>
|
||||
#include <sqlpp11/assignment.h>
|
||||
#include <sqlpp11/interpretable_list.h>
|
||||
#include <sqlpp11/interpret_tuple.h>
|
||||
@ -41,20 +41,20 @@ namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename... Args>
|
||||
struct first_arg_impl
|
||||
template<typename... Columns>
|
||||
struct have_all_required_columns
|
||||
{
|
||||
static_assert(wrong_t<first_arg_impl>::value, "At least one argument required");
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
template<typename T, typename... Args>
|
||||
struct first_arg_impl<T, Args...>
|
||||
template<typename First, typename... Columns>
|
||||
struct have_all_required_columns<First, Columns...>
|
||||
{
|
||||
using type = T;
|
||||
using _table = typename First::_table;
|
||||
using required_columns = typename _table::_required_insert_columns;
|
||||
using set_columns = detail::make_type_set_t<First, Columns...>;
|
||||
static constexpr bool value = detail::is_subset_of<required_columns, set_columns>::value;
|
||||
};
|
||||
|
||||
template<typename... Args>
|
||||
using first_arg_t = typename first_arg_impl<Args...>::type;
|
||||
}
|
||||
|
||||
struct insert_default_values_data_t
|
||||
@ -64,7 +64,7 @@ namespace sqlpp
|
||||
struct insert_default_values_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
|
||||
// Data
|
||||
using _data_t = insert_default_values_data_t;
|
||||
@ -76,9 +76,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = insert_default_values_data_t;
|
||||
|
||||
@ -91,12 +91,8 @@ namespace sqlpp
|
||||
{
|
||||
return t.default_values;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
static void _check_consistency() {}
|
||||
using _consistency_check = consistent_t;
|
||||
};
|
||||
};
|
||||
|
||||
@ -122,11 +118,22 @@ namespace sqlpp
|
||||
interpretable_list_t<Database> _dynamic_values;
|
||||
};
|
||||
|
||||
struct assert_no_unknown_tables_in_insert_assignments_t
|
||||
{
|
||||
using type = std::false_type;
|
||||
|
||||
template<typename T = void>
|
||||
static void _()
|
||||
{
|
||||
static_assert(wrong_t<T>::value, "at least one insert assignment requires a table which is otherwise not known in the statement");
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Database, typename... Assignments>
|
||||
struct insert_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_insert_list>;
|
||||
using _recursive_traits = make_recursive_traits<lhs_t<Assignments>..., rhs_t<Assignments>...>;
|
||||
using _nodes = detail::type_vector<lhs_t<Assignments>..., rhs_t<Assignments>...>;
|
||||
|
||||
using _is_dynamic = is_database<Database>;
|
||||
|
||||
@ -157,10 +164,13 @@ namespace sqlpp
|
||||
static_assert(not detail::is_element_of<lhs_t<Assignment>, _assigned_columns>::value, "Must not assign value to column twice");
|
||||
static_assert(not must_not_insert_t<lhs_t<Assignment>>::value, "add() argument must not be used in insert");
|
||||
static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables<Assignment>::value, "add() contains a column from a foreign table");
|
||||
using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, Assignment>;
|
||||
_serialize_check::_();
|
||||
|
||||
using ok = detail::all_t<
|
||||
using ok = logic::all_t<
|
||||
_is_dynamic::value,
|
||||
is_assignment_t<Assignment>::value>;
|
||||
is_assignment_t<Assignment>::value,
|
||||
_serialize_check::type::value>;
|
||||
|
||||
_add_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
@ -179,9 +189,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = insert_list_data_t<Database, Assignments...>;
|
||||
|
||||
@ -194,13 +204,10 @@ namespace sqlpp
|
||||
{
|
||||
return t.insert_list;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
static void _check_consistency() {}
|
||||
using _consistency_check = typename std::conditional<Policies::template _no_unknown_tables<insert_list_t>::value,
|
||||
consistent_t,
|
||||
assert_no_unknown_tables_in_insert_assignments_t>::type;
|
||||
};
|
||||
|
||||
};
|
||||
@ -223,11 +230,22 @@ namespace sqlpp
|
||||
std::vector<_value_tuple_t> _insert_values;
|
||||
};
|
||||
|
||||
struct assert_no_unknown_tables_in_column_list_t
|
||||
{
|
||||
using type = std::false_type;
|
||||
|
||||
template<typename T = void>
|
||||
static void _()
|
||||
{
|
||||
static_assert(wrong_t<T>::value, "at least one column requires a table which is otherwise not known in the statement");
|
||||
}
|
||||
};
|
||||
|
||||
template<typename... Columns>
|
||||
struct column_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_column_list>;
|
||||
using _recursive_traits = make_recursive_traits<Columns...>;
|
||||
using _nodes = detail::type_vector<Columns...>;
|
||||
|
||||
using _value_tuple_t = typename column_list_data_t<Columns...>::_value_tuple_t;
|
||||
|
||||
@ -242,13 +260,13 @@ namespace sqlpp
|
||||
template<typename... Assignments>
|
||||
void add(Assignments... assignments)
|
||||
{
|
||||
static_assert(detail::all_t<is_assignment_t<Assignments>::value...>::value, "add_values() arguments have to be assignments");
|
||||
static_assert(logic::all_t<is_assignment_t<Assignments>::value...>::value, "add_values() arguments have to be assignments");
|
||||
using _arg_value_tuple = std::tuple<insert_value_t<lhs_t<Assignments>>...>;
|
||||
using _args_correct = std::is_same<_arg_value_tuple, _value_tuple_t>;
|
||||
static_assert(_args_correct::value, "add_values() arguments do not match columns() arguments");
|
||||
|
||||
using ok = detail::all_t<
|
||||
detail::all_t<is_assignment_t<Assignments>::value...>::value,
|
||||
using ok = logic::all_t<
|
||||
logic::all_t<is_assignment_t<Assignments>::value...>::value,
|
||||
_args_correct::value>;
|
||||
|
||||
_add_impl(ok(), assignments...); // dispatch to prevent compile messages after the static_assert
|
||||
@ -267,9 +285,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = column_list_data_t<Columns...>;
|
||||
|
||||
@ -282,21 +300,29 @@ namespace sqlpp
|
||||
{
|
||||
return t.values;
|
||||
}
|
||||
|
||||
using _consistency_check = typename std::conditional<Policies::template _no_unknown_tables<column_list_t>::value,
|
||||
consistent_t,
|
||||
assert_no_unknown_tables_in_column_list_t>::type;
|
||||
};
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
struct assert_insert_values_t
|
||||
{
|
||||
static void _check_consistency() {}
|
||||
};
|
||||
using type = std::false_type;
|
||||
|
||||
template<typename T = void>
|
||||
static void _()
|
||||
{
|
||||
static_assert(wrong_t<T>::value, "insert values required, e.g. set(...) or default_values()");
|
||||
}
|
||||
};
|
||||
|
||||
// NO INSERT COLUMNS/VALUES YET
|
||||
struct no_insert_value_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
@ -308,9 +334,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
@ -323,78 +349,90 @@ namespace sqlpp
|
||||
{
|
||||
return t.no_insert_values;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = new_statement<Policies, no_insert_value_list_t, T>;
|
||||
|
||||
static void _check_consistency()
|
||||
{
|
||||
static_assert(wrong_t<_methods_t>::value, "insert values required, e.g. set(...) or default_values()");
|
||||
}
|
||||
template<typename... T>
|
||||
using _column_check = logic::all_t<is_column_t<T>::value...>;
|
||||
|
||||
template<typename... T>
|
||||
using _assignment_check = logic::all_t<is_assignment_t<T>::value...>;
|
||||
|
||||
template<typename Check, typename T>
|
||||
using _new_statement_t = new_statement_t<Check::value, Policies, no_insert_value_list_t, T>;
|
||||
|
||||
using _consistency_check = assert_insert_values_t;
|
||||
|
||||
auto default_values() const
|
||||
-> _new_statement_t<insert_default_values_t>
|
||||
-> _new_statement_t<std::true_type, insert_default_values_t>
|
||||
{
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), insert_default_values_data_t{} };
|
||||
}
|
||||
|
||||
template<typename... Columns>
|
||||
auto columns(Columns... columns) const
|
||||
-> _new_statement_t<column_list_t<Columns...>>
|
||||
-> _new_statement_t<_column_check<Columns...>, column_list_t<Columns...>>
|
||||
{
|
||||
static_assert(logic::all_t<is_column_t<Columns>::value...>::value, "at least one argument is not a column in columns()");
|
||||
static_assert(sizeof...(Columns), "at least one column required in columns()");
|
||||
static_assert(not detail::has_duplicates<Columns...>::value, "at least one duplicate argument detected in columns()");
|
||||
static_assert(detail::all_t<is_column_t<Columns>::value...>::value, "at least one argument is not a column in columns()");
|
||||
static_assert(detail::none_t<must_not_insert_t<Columns>::value...>::value, "at least one column argument has a must_not_insert tag in its definition");
|
||||
using _column_required_tables = detail::make_joined_set_t<required_tables_of<Columns>...>;
|
||||
static_assert(_column_required_tables::size::value == 1, "columns() contains columns from several tables");
|
||||
|
||||
using _table = typename detail::first_arg_t<Columns...>::_table;
|
||||
using required_columns = typename _table::_required_insert_columns;
|
||||
using set_columns = detail::make_type_set_t<Columns...>;
|
||||
static_assert(detail::is_subset_of<required_columns, set_columns>::value, "At least one required column is missing in columns()");
|
||||
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), column_list_data_t<Columns...>{columns...} };
|
||||
return _columns_impl(_column_check<Columns...>{}, columns...);
|
||||
}
|
||||
|
||||
template<typename... Assignments>
|
||||
auto set(Assignments... assignments) const
|
||||
-> _new_statement_t<insert_list_t<void, Assignments...>>
|
||||
-> _new_statement_t<_assignment_check<Assignments...>, insert_list_t<void, Assignments...>>
|
||||
{
|
||||
static_assert(_assignment_check<Assignments...>::value, "at least one argument is not an assignment in set()");
|
||||
static_assert(sizeof...(Assignments), "at least one assignment expression required in set()");
|
||||
static_assert(detail::all_t<is_assignment_t<Assignments>::value...>::value, "at least one argument is not an assignment in set()");
|
||||
|
||||
using _table = typename lhs_t<detail::first_arg_t<Assignments...>>::_table;
|
||||
using required_columns = typename _table::_required_insert_columns;
|
||||
using columns = detail::make_type_set_t<lhs_t<Assignments>...>;
|
||||
static_assert(detail::is_subset_of<required_columns, columns>::value, "At least one required column is missing in set()");
|
||||
return _set_impl<void>(assignments...);
|
||||
return _set_impl<void>(_assignment_check<Assignments...>{}, assignments...);
|
||||
}
|
||||
|
||||
template<typename... Assignments>
|
||||
auto dynamic_set(Assignments... assignments) const
|
||||
-> _new_statement_t<insert_list_t<_database_t, Assignments...>>
|
||||
-> _new_statement_t<_assignment_check<Assignments...>, insert_list_t<_database_t, Assignments...>>
|
||||
{
|
||||
static_assert(_assignment_check<Assignments...>::value, "at least one argument is not an assignment in set()");
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_set must not be called in a static statement");
|
||||
static_assert(detail::all_t<is_assignment_t<Assignments>::value...>::value, "at least one argument is not an assignment in set()");
|
||||
return _set_impl<_database_t>(assignments...);
|
||||
|
||||
return _set_impl<_database_t>(_assignment_check<Assignments...>{}, assignments...);
|
||||
}
|
||||
private:
|
||||
template<typename... Columns>
|
||||
auto _columns_impl(const std::false_type&, Columns... columns) const
|
||||
-> bad_statement;
|
||||
|
||||
template<typename... Columns>
|
||||
auto _columns_impl(const std::true_type&, Columns... columns) const
|
||||
-> _new_statement_t<std::true_type, column_list_t<Columns...>>
|
||||
{
|
||||
static_assert(not detail::has_duplicates<Columns...>::value, "at least one duplicate argument detected in columns()");
|
||||
static_assert(logic::none_t<must_not_insert_t<Columns>::value...>::value, "at least one column argument has a must_not_insert tag in its definition");
|
||||
using _column_required_tables = detail::make_joined_set_t<required_tables_of<Columns>...>;
|
||||
static_assert(_column_required_tables::size::value == 1, "columns() contains columns from several tables");
|
||||
|
||||
static_assert(detail::have_all_required_columns<Columns...>::value, "At least one required column is missing in columns()");
|
||||
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), column_list_data_t<Columns...>{columns...} };
|
||||
}
|
||||
|
||||
template<typename Database, typename... Assignments>
|
||||
auto _set_impl(Assignments... assignments) const
|
||||
-> _new_statement_t<insert_list_t<Database, Assignments...>>
|
||||
auto _set_impl(const std::false_type&, Assignments... assignments) const
|
||||
-> bad_statement;
|
||||
|
||||
template<typename Database, typename... Assignments>
|
||||
auto _set_impl(const std::true_type&, Assignments... assignments) const
|
||||
-> _new_statement_t<std::true_type, insert_list_t<Database, Assignments...>>
|
||||
{
|
||||
static_assert(not detail::has_duplicates<lhs_t<Assignments>...>::value, "at least one duplicate column detected in set()");
|
||||
static_assert(detail::none_t<must_not_insert_t<lhs_t<Assignments>>::value...>::value, "at least one assignment is prohibited by its column definition in set()");
|
||||
static_assert(logic::none_t<must_not_insert_t<lhs_t<Assignments>>::value...>::value, "at least one assignment is prohibited by its column definition in set()");
|
||||
|
||||
using _column_required_tables = detail::make_joined_set_t<required_tables_of<lhs_t<Assignments>>...>;
|
||||
static_assert(sizeof...(Assignments) ? (_column_required_tables::size::value == 1) : true, "set() contains assignments for columns from several tables");
|
||||
|
||||
static_assert(not std::is_same<_database_t, void>::value or detail::have_all_required_columns<lhs_t<Assignments>...>::value, "At least one required column is missing in set()");
|
||||
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), insert_list_data_t<Database, Assignments...>{assignments...} };
|
||||
}
|
||||
};
|
||||
@ -404,6 +442,7 @@ namespace sqlpp
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, insert_default_values_data_t>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using T = insert_default_values_data_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
@ -416,6 +455,7 @@ namespace sqlpp
|
||||
template<typename Context, typename... Columns>
|
||||
struct serializer_t<Context, column_list_data_t<Columns...>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Columns...>;
|
||||
using T = column_list_data_t<Columns...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
@ -443,6 +483,7 @@ namespace sqlpp
|
||||
template<typename Context, typename Database, typename... Assignments>
|
||||
struct serializer_t<Context, insert_list_data_t<Database, Assignments...>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Assignments...>;
|
||||
using T = insert_list_data_t<Database, Assignments...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -34,20 +34,19 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Element, typename Separator, typename Context>
|
||||
static void interpret_tuple_element(const Element& element, const Separator& separator, Context& context, size_t index)
|
||||
template<typename Element, typename Separator, typename Context, typename UseBraces>
|
||||
static void interpret_tuple_element(const Element& element, const Separator& separator, Context& context, const UseBraces&, size_t index)
|
||||
{
|
||||
if (index)
|
||||
context << separator;
|
||||
if (requires_braces_t<Element>::value)
|
||||
context << "(";
|
||||
if (UseBraces::value)
|
||||
serialize_operand(element, context);
|
||||
else
|
||||
serialize(element, context);
|
||||
if (requires_braces_t<Element>::value)
|
||||
context << ")";
|
||||
}
|
||||
|
||||
template<typename Tuple, typename Separator, typename Context, size_t... Is>
|
||||
auto interpret_tuple_impl(const Tuple& t, const Separator& separator, Context& context, const detail::index_sequence<Is...>&)
|
||||
template<typename Tuple, typename Separator, typename Context, typename UseBraces, size_t... Is>
|
||||
auto interpret_tuple_impl(const Tuple& t, const Separator& separator, Context& context, const UseBraces& useBraces, const detail::index_sequence<Is...>&)
|
||||
-> Context&
|
||||
{
|
||||
// Note: A braced-init-list does guarantee the order of evaluation according to 12.6.1 [class.explicit.init] paragraph 2 and 8.5.4 [dcl.init.list] paragraph 4.
|
||||
@ -57,7 +56,7 @@ namespace sqlpp
|
||||
using swallow = int[];
|
||||
(void) swallow{
|
||||
0, //workaround against -Wpedantic GCC warning "zero-size array 'int [0]'"
|
||||
(interpret_tuple_element(std::get<Is>(t), separator, context, Is), 0)...};
|
||||
(interpret_tuple_element(std::get<Is>(t), separator, context, useBraces, Is), 0)...};
|
||||
return context;
|
||||
}
|
||||
|
||||
@ -65,7 +64,14 @@ namespace sqlpp
|
||||
auto interpret_tuple(const Tuple& t, const Separator& separator, Context& context)
|
||||
-> Context&
|
||||
{
|
||||
return interpret_tuple_impl(t, separator, context, detail::make_index_sequence<std::tuple_size<Tuple>::value>{});
|
||||
return interpret_tuple_impl(t, separator, context, std::true_type{}, detail::make_index_sequence<std::tuple_size<Tuple>::value>{});
|
||||
}
|
||||
|
||||
template<typename Tuple, typename Separator, typename Context>
|
||||
auto interpret_tuple_without_braces(const Tuple& t, const Separator& separator, Context& context)
|
||||
-> Context&
|
||||
{
|
||||
return interpret_tuple_impl(t, separator, context, std::false_type{}, detail::make_index_sequence<std::tuple_size<Tuple>::value>{});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -43,6 +43,7 @@ namespace sqlpp
|
||||
|
||||
template<typename T>
|
||||
interpretable_t(T t):
|
||||
_requires_braces(requires_braces_t<T>::value),
|
||||
_impl(std::make_shared<_impl_t<T>>(t))
|
||||
{}
|
||||
|
||||
@ -71,6 +72,8 @@ namespace sqlpp
|
||||
return _impl->interpret(context);
|
||||
}
|
||||
|
||||
bool _requires_braces;
|
||||
|
||||
private:
|
||||
struct _impl_base
|
||||
{
|
||||
@ -114,11 +117,20 @@ namespace sqlpp
|
||||
template<typename Context, typename Database>
|
||||
struct serializer_t<Context, interpretable_t<Database>>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using T = interpretable_t<Database>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (t._requires_braces)
|
||||
{
|
||||
context << '(';
|
||||
t.serialize(context);
|
||||
context << ')';
|
||||
}
|
||||
else
|
||||
t.serialize(context);
|
||||
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -27,6 +27,7 @@
|
||||
#ifndef SQLPP_INTO_H
|
||||
#define SQLPP_INTO_H
|
||||
|
||||
#include <sqlpp11/statement_fwd.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/no_value.h>
|
||||
#include <sqlpp11/no_data.h>
|
||||
@ -58,14 +59,11 @@ namespace sqlpp
|
||||
struct into_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_into>;
|
||||
using _recursive_traits = make_recursive_traits<Table>;
|
||||
|
||||
static_assert(is_table_t<Table>::value, "argument has to be a table");
|
||||
static_assert(required_tables_of<Table>::size::value == 0, "table depends on another table");
|
||||
using _nodes = detail::type_vector<Table>;
|
||||
|
||||
using _data_t = into_data_t<Database, Table>;
|
||||
|
||||
struct _name_t {};
|
||||
struct _alias_t {};
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
@ -74,9 +72,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = into_data_t<Database, Table>;
|
||||
|
||||
@ -89,22 +87,28 @@ namespace sqlpp
|
||||
{
|
||||
return t.into;
|
||||
}
|
||||
|
||||
using _consistency_check = consistent_t;
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
};
|
||||
|
||||
struct assert_into_t
|
||||
{
|
||||
static void _check_consistency() {}
|
||||
};
|
||||
using type = std::false_type;
|
||||
|
||||
template<typename T = void>
|
||||
static void _()
|
||||
{
|
||||
static_assert(wrong_t<T>::value, "into() required");
|
||||
}
|
||||
};
|
||||
|
||||
// NO INTO YET
|
||||
struct no_into_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
@ -116,9 +120,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
@ -131,25 +135,37 @@ namespace sqlpp
|
||||
{
|
||||
return t.no_into;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = new_statement<Policies, no_into_t, T>;
|
||||
|
||||
static void _check_consistency()
|
||||
template<typename T>
|
||||
using _check = logic::all_t<is_table_t<T>::value>;
|
||||
|
||||
template<typename Check, typename T>
|
||||
using _new_statement_t = new_statement_t<Check::value, Policies, no_into_t, T>;
|
||||
|
||||
using _consistency_check = assert_into_t;
|
||||
|
||||
template<typename Table>
|
||||
auto into(Table table) const
|
||||
-> _new_statement_t<_check<Table>, into_t<void, Table>>
|
||||
{
|
||||
static_assert(wrong_t<_methods_t>::value, "into() required");
|
||||
static_assert(_check<Table>::value, "argument is not a table in into()");
|
||||
return _into_impl<void>(_check<Table>{}, table);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto into(Args... args) const
|
||||
-> _new_statement_t<into_t<void, Args...>>
|
||||
private:
|
||||
template<typename Database, typename Table>
|
||||
auto _into_impl(const std::false_type&, Table table) const
|
||||
-> bad_statement;
|
||||
|
||||
template<typename Database, typename Table>
|
||||
auto _into_impl(const std::true_type&, Table table) const
|
||||
-> _new_statement_t<std::true_type, into_t<Database, Table>>
|
||||
{
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), into_data_t<void, Args...>{args...} };
|
||||
static_assert(required_tables_of<into_t<Database, Table>>::size::value == 0, "argument depends on another table in into()");
|
||||
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), into_data_t<Database, Table>{table} };
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -158,6 +174,7 @@ namespace sqlpp
|
||||
template<typename Context, typename Database, typename Table>
|
||||
struct serializer_t<Context, into_data_t<Database, Table>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Table>;
|
||||
using T = into_data_t<Database, Table>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
@ -168,6 +185,11 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
auto into(T&& t) -> decltype(statement_t<void, no_into_t>().into(std::forward<T>(t)))
|
||||
{
|
||||
return statement_t<void, no_into_t>().into(std::forward<T>(t));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
85
include/sqlpp11/is_not_null.h
Normal file
85
include/sqlpp11/is_not_null.h
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, 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_IS_NOT_NULL_H
|
||||
#define SQLPP_IS_NOT_NULL_H
|
||||
|
||||
#include <sqlpp11/boolean.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/char_sequence.h>
|
||||
#include <sqlpp11/detail/type_set.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Operand>
|
||||
struct is_not_null_t:
|
||||
public expression_operators<is_not_null_t<Operand>, boolean>,
|
||||
public alias_operators<is_not_null_t<Operand>>
|
||||
{
|
||||
using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable>;
|
||||
using _nodes = detail::type_vector<Operand>;
|
||||
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char _literal[] = "is_not_null_";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T is_not_null;
|
||||
};
|
||||
};
|
||||
|
||||
is_not_null_t(Operand operand):
|
||||
_operand(operand)
|
||||
{}
|
||||
|
||||
is_not_null_t(const is_not_null_t&) = default;
|
||||
is_not_null_t(is_not_null_t&&) = default;
|
||||
is_not_null_t& operator=(const is_not_null_t&) = default;
|
||||
is_not_null_t& operator=(is_not_null_t&&) = default;
|
||||
~is_not_null_t() = default;
|
||||
|
||||
Operand _operand;
|
||||
};
|
||||
|
||||
template<typename Context, typename Operand>
|
||||
struct serializer_t<Context, is_not_null_t<Operand>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Operand>;
|
||||
using T = is_not_null_t<Operand>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
serialize_operand(t._operand, context);
|
||||
context << " IS NOT NULL";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -29,27 +29,27 @@
|
||||
|
||||
#include <sqlpp11/boolean.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/char_sequence.h>
|
||||
#include <sqlpp11/detail/type_set.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<bool NotInverted, typename Operand>
|
||||
template<typename Operand>
|
||||
struct is_null_t:
|
||||
public expression_operators<is_null_t<NotInverted, Operand>, boolean>,
|
||||
public alias_operators<is_null_t<NotInverted, Operand>>
|
||||
public expression_operators<is_null_t<Operand>, boolean>,
|
||||
public alias_operators<is_null_t<Operand>>
|
||||
{
|
||||
using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable>;
|
||||
using _recursive_traits = make_recursive_traits<Operand>;
|
||||
using _nodes = detail::type_vector<Operand>;
|
||||
|
||||
static constexpr bool _inverted = not NotInverted;
|
||||
|
||||
struct _name_t
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return _inverted ? "IS NOT NULL" : "IS NULL"; }
|
||||
static constexpr const char _literal[] = "is_nnull_";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T in;
|
||||
T is_null;
|
||||
};
|
||||
};
|
||||
|
||||
@ -66,15 +66,16 @@ namespace sqlpp
|
||||
Operand _operand;
|
||||
};
|
||||
|
||||
template<typename Context, bool NotInverted, typename Operand>
|
||||
struct serializer_t<Context, is_null_t<NotInverted, Operand>>
|
||||
template<typename Context, typename Operand>
|
||||
struct serializer_t<Context, is_null_t<Operand>>
|
||||
{
|
||||
using T = is_null_t<NotInverted, Operand>;
|
||||
using _serialize_check = serialize_check_of<Context, Operand>;
|
||||
using T = is_null_t<Operand>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
serialize(t._operand, context);
|
||||
context << (t._inverted ? " IS NOT NULL" : " IS NULL");
|
||||
serialize_operand(t._operand, context);
|
||||
context << " IS NULL";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -29,8 +29,10 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<bool NotInverted, typename Operand>
|
||||
template<typename Operand>
|
||||
struct is_null_t;
|
||||
template<typename Operand>
|
||||
struct is_not_null_t;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -66,16 +66,8 @@ namespace sqlpp
|
||||
struct join_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_table, tag::is_join>;
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _required_tables = detail::make_joined_set_t<required_tables_of<Lhs>, required_tables_of<Rhs>>;
|
||||
using _provided_tables = detail::make_joined_set_t<provided_tables_of<Lhs>, provided_tables_of<Rhs>>;
|
||||
using _provided_outer_tables = typename JoinType::template _provided_outer_tables<Lhs, Rhs>;
|
||||
using _extra_tables = detail::make_joined_set_t<extra_tables_of<Lhs>, extra_tables_of<Rhs>>;
|
||||
using _parameters = detail::make_parameter_tuple_t<parameters_of<Lhs>, parameters_of<Rhs>>;
|
||||
using _tags = detail::type_set<>;
|
||||
};
|
||||
|
||||
using _nodes = detail::type_vector<Lhs, Rhs>;
|
||||
using _can_be_null = std::false_type;
|
||||
|
||||
static_assert(is_table_t<Lhs>::value, "lhs argument for join() has to be a table or join");
|
||||
static_assert(is_table_t<Rhs>::value, "rhs argument for join() has to be a table");
|
||||
@ -84,7 +76,7 @@ namespace sqlpp
|
||||
|
||||
static_assert(detail::is_disjunct_from<provided_tables_of<Lhs>, provided_tables_of<Rhs>>::value, "joined tables must not be identical");
|
||||
|
||||
static_assert(_recursive_traits::_required_tables::size::value == 0, "joined tables must not depend on other tables");
|
||||
static_assert(required_tables_of<join_t>::size::value == 0, "joined tables must not depend on other tables");
|
||||
|
||||
template<typename OnT>
|
||||
using set_on_t = join_t<JoinType, Lhs, Rhs, OnT>;
|
||||
@ -94,7 +86,7 @@ namespace sqlpp
|
||||
-> set_on_t<on_t<void, Expr...>>
|
||||
{
|
||||
static_assert(is_noop<On>::value, "cannot call on() twice for a single join()");
|
||||
static_assert(detail::all_t<is_expression_t<Expr>::value...>::value, "at least one argument is not an expression in on()");
|
||||
static_assert(logic::all_t<is_expression_t<Expr>::value...>::value, "at least one argument is not an expression in on()");
|
||||
|
||||
return { _lhs,
|
||||
_rhs,
|
||||
@ -145,6 +137,7 @@ namespace sqlpp
|
||||
template<typename Context, typename JoinType, typename Lhs, typename Rhs, typename On>
|
||||
struct serializer_t<Context, join_t<JoinType, Lhs, Rhs, On>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Lhs, Rhs, On>;
|
||||
using T = join_t<JoinType, Lhs, Rhs, On>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -29,6 +29,7 @@
|
||||
|
||||
#include <sqlpp11/boolean.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/char_sequence.h>
|
||||
#include <sqlpp11/detail/type_set.h>
|
||||
|
||||
namespace sqlpp
|
||||
@ -39,11 +40,12 @@ namespace sqlpp
|
||||
public alias_operators<like_t<Operand, Pattern>>
|
||||
{
|
||||
using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable>;
|
||||
using _recursive_traits = make_recursive_traits<Operand, Pattern>;
|
||||
using _nodes = detail::type_vector<Operand, Pattern>;
|
||||
|
||||
struct _name_t
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "LIKE"; }
|
||||
static constexpr const char _literal[] = "like_";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
@ -71,11 +73,12 @@ namespace sqlpp
|
||||
template<typename Context, typename Operand, typename Pattern>
|
||||
struct serializer_t<Context, like_t<Operand, Pattern>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Operand, Pattern>;
|
||||
using T = like_t<Operand, Pattern>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
serialize(t._operand, context);
|
||||
serialize_operand(t._operand, context);
|
||||
context << " LIKE(";
|
||||
serialize(t._pattern, context);
|
||||
context << ")";
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -55,9 +55,7 @@ namespace sqlpp
|
||||
struct limit_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_limit>;
|
||||
using _recursive_traits = make_recursive_traits<Limit>;
|
||||
|
||||
static_assert(is_integral_t<Limit>::value, "limit requires an integral value or integral parameter");
|
||||
using _nodes = detail::type_vector<Limit>;
|
||||
|
||||
// Data
|
||||
using _data_t = limit_data_t<Limit>;
|
||||
@ -69,9 +67,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = limit_data_t<Limit>;
|
||||
|
||||
@ -84,12 +82,8 @@ namespace sqlpp
|
||||
{
|
||||
return t.limit;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
static void _check_consistency() {}
|
||||
using _consistency_check = consistent_t;
|
||||
};
|
||||
};
|
||||
|
||||
@ -124,7 +118,7 @@ namespace sqlpp
|
||||
struct dynamic_limit_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_limit>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
|
||||
// Data
|
||||
using _data_t = dynamic_limit_data_t<Database>;
|
||||
@ -138,6 +132,7 @@ namespace sqlpp
|
||||
{
|
||||
// FIXME: Make sure that Limit does not require external tables? Need to read up on SQL
|
||||
using arg_t = wrap_operand_t<Limit>;
|
||||
static_assert(is_integral_t<arg_t>::value, "limit requires an integral value or integral parameter");
|
||||
_data._value = arg_t{value};
|
||||
_data._initialized = true;
|
||||
}
|
||||
@ -145,9 +140,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = dynamic_limit_data_t<Database>;
|
||||
|
||||
@ -160,20 +155,15 @@ namespace sqlpp
|
||||
{
|
||||
return t.limit;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
static void _check_consistency() {}
|
||||
using _consistency_check = consistent_t;
|
||||
};
|
||||
};
|
||||
|
||||
struct no_limit_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
@ -185,9 +175,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
@ -200,30 +190,43 @@ namespace sqlpp
|
||||
{
|
||||
return t.no_limit;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = new_statement<Policies, no_limit_t, T>;
|
||||
|
||||
static void _check_consistency() {}
|
||||
template<typename T>
|
||||
using _check = is_integral_t<wrap_operand_t<T>>;
|
||||
|
||||
template<typename Check, typename T>
|
||||
using _new_statement_t = new_statement_t<Check::value, Policies, no_limit_t, T>;
|
||||
|
||||
using _consistency_check = consistent_t;
|
||||
|
||||
template<typename Arg>
|
||||
auto limit(Arg arg) const
|
||||
-> _new_statement_t<limit_t<wrap_operand_t<Arg>>>
|
||||
-> _new_statement_t<_check<Arg>, limit_t<wrap_operand_t<Arg>>>
|
||||
{
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), limit_data_t<wrap_operand_t<Arg>>{{arg}} };
|
||||
static_assert(_check<Arg>::value, "limit requires an integral value or integral parameter");
|
||||
return _limit_impl(_check<Arg>{}, wrap_operand_t<Arg>{arg});
|
||||
}
|
||||
|
||||
auto dynamic_limit() const
|
||||
-> _new_statement_t<dynamic_limit_t<_database_t>>
|
||||
-> _new_statement_t<std::true_type, dynamic_limit_t<_database_t>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_limit must not be called in a static statement");
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), dynamic_limit_data_t<_database_t>{} };
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Arg>
|
||||
auto _limit_impl(const std::false_type&, Arg arg) const
|
||||
-> bad_statement;
|
||||
|
||||
template<typename Arg>
|
||||
auto _limit_impl(const std::true_type&, Arg arg) const
|
||||
-> _new_statement_t<std::true_type, limit_t<Arg>>
|
||||
{
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), limit_data_t<Arg>{arg} };
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
@ -231,6 +234,7 @@ namespace sqlpp
|
||||
template<typename Context, typename Database>
|
||||
struct serializer_t<Context, dynamic_limit_data_t<Database>>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using T = dynamic_limit_data_t<Database>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
@ -247,12 +251,13 @@ namespace sqlpp
|
||||
template<typename Context, typename Limit>
|
||||
struct serializer_t<Context, limit_data_t<Limit>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Limit>;
|
||||
using T = limit_data_t<Limit>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << " LIMIT ";
|
||||
serialize(t._value, context);
|
||||
serialize_operand(t._value, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -32,7 +32,7 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
namespace logic
|
||||
{
|
||||
template<bool... B>
|
||||
struct logic_helper;
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -28,6 +28,7 @@
|
||||
#define SQLPP_MAX_H
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/char_sequence.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -37,11 +38,12 @@ namespace sqlpp
|
||||
public alias_operators<max_t<Expr>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Expr>, tag::is_expression, tag::is_selectable>;
|
||||
using _recursive_traits = make_recursive_traits<Expr, aggregate_function>;
|
||||
using _nodes = detail::type_vector<Expr, aggregate_function>;
|
||||
|
||||
struct _name_t
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "MAX"; }
|
||||
static constexpr const char _literal[] = "max_";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
@ -67,6 +69,7 @@ namespace sqlpp
|
||||
template<typename Context, typename Expr>
|
||||
struct serializer_t<Context, max_t<Expr>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Expr>;
|
||||
using T = max_t<Expr>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
@ -81,6 +84,7 @@ namespace sqlpp
|
||||
template<typename T>
|
||||
auto max(T t) -> max_t<wrap_operand_t<T>>
|
||||
{
|
||||
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value, "max() cannot be used on an aggregate function");
|
||||
static_assert(is_expression_t<wrap_operand_t<T>>::value, "max() requires an expression as argument");
|
||||
return { t };
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -28,6 +28,7 @@
|
||||
#define SQLPP_MIN_H
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/char_sequence.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -37,11 +38,12 @@ namespace sqlpp
|
||||
public alias_operators<min_t<Expr>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Expr>, tag::is_expression, tag::is_selectable>;
|
||||
using _recursive_traits = make_recursive_traits<Expr, aggregate_function>;
|
||||
using _nodes = detail::type_vector<Expr, aggregate_function>;
|
||||
|
||||
struct _name_t
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char* _get_name() { return "MIN"; }
|
||||
static constexpr const char _literal[] = "min_";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
@ -67,6 +69,7 @@ namespace sqlpp
|
||||
template<typename Context, typename Expr>
|
||||
struct serializer_t<Context, min_t<Expr>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Expr>;
|
||||
using T = min_t<Expr>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
@ -81,6 +84,7 @@ namespace sqlpp
|
||||
template<typename T>
|
||||
auto min(T t) -> min_t<wrap_operand_t<T>>
|
||||
{
|
||||
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value, "min() cannot be used on an aggregate function");
|
||||
static_assert(is_expression_t<wrap_operand_t<T>>::value, "min() requires an expression as argument");
|
||||
return { t };
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -28,7 +28,7 @@
|
||||
#define SQLPP_MULTI_COLUMN_H
|
||||
|
||||
#include <sqlpp11/no_value.h>
|
||||
#include <sqlpp11/detail/logic.h>
|
||||
#include <sqlpp11/logic.h>
|
||||
#include <sqlpp11/detail/type_set.h>
|
||||
|
||||
#include <sqlpp11/detail/copy_tuple_args.h>
|
||||
@ -42,9 +42,9 @@ namespace sqlpp
|
||||
struct multi_column_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t>;
|
||||
using _recursive_traits = make_recursive_traits<Columns...>;
|
||||
using _nodes = detail::type_vector<Columns...>;
|
||||
|
||||
static_assert(detail::all_t<is_selectable_t<Columns>::value...>::value, "multi_column parameters need to be named expressions");
|
||||
static_assert(logic::all_t<is_selectable_t<Columns>::value...>::value, "multi_column parameters need to be named expressions");
|
||||
|
||||
multi_column_t(std::tuple<Columns...> columns):
|
||||
_columns(columns)
|
||||
@ -73,11 +73,11 @@ namespace sqlpp
|
||||
struct multi_column_alias_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_alias, tag::is_multi_column, tag::is_selectable>;
|
||||
using _recursive_traits = make_recursive_traits<Columns...>;
|
||||
using _nodes = detail::type_vector<Columns...>;
|
||||
|
||||
static_assert(detail::all_t<is_selectable_t<Columns>::value...>::value, "multi_column parameters need to be named expressions");
|
||||
static_assert(logic::all_t<is_selectable_t<Columns>::value...>::value, "multi_column parameters need to be named expressions");
|
||||
|
||||
using _name_t = typename AliasProvider::_name_t;
|
||||
using _alias_t = typename AliasProvider::_alias_t;
|
||||
|
||||
multi_column_alias_t(multi_column_t<void, Columns...> multi_column):
|
||||
_columns(multi_column._columns)
|
||||
@ -103,6 +103,7 @@ namespace sqlpp
|
||||
template<typename Context, typename... Columns>
|
||||
struct serializer_t<Context, multi_column_t<void, Columns...>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Columns...>;
|
||||
using T = multi_column_t<void, Columns...>;
|
||||
|
||||
static void _(const T& t, Context& context)
|
||||
@ -114,6 +115,7 @@ namespace sqlpp
|
||||
template<typename Context, typename AliasProvider, typename... Columns>
|
||||
struct serializer_t<Context, multi_column_alias_t<AliasProvider, Columns...>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Columns...>;
|
||||
using T = multi_column_alias_t<AliasProvider, Columns...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -30,6 +30,7 @@
|
||||
#include <memory>
|
||||
#include <sqlpp11/serializer_context.h>
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
#include <sqlpp11/char_sequence.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -41,6 +42,7 @@ namespace sqlpp
|
||||
|
||||
template<typename T>
|
||||
named_interpretable_t(T t):
|
||||
_requires_braces(requires_braces_t<T>::value),
|
||||
_impl(std::make_shared<_impl_t<T>>(t))
|
||||
{}
|
||||
|
||||
@ -74,6 +76,8 @@ namespace sqlpp
|
||||
return _impl->_get_name();
|
||||
}
|
||||
|
||||
bool _requires_braces;
|
||||
|
||||
private:
|
||||
struct _impl_base
|
||||
{
|
||||
@ -111,7 +115,7 @@ namespace sqlpp
|
||||
|
||||
std::string _get_name() const
|
||||
{
|
||||
return T::_name_t::_get_name();
|
||||
return name_of<T>::char_ptr();
|
||||
}
|
||||
|
||||
T _t;
|
||||
@ -123,11 +127,20 @@ namespace sqlpp
|
||||
template<typename Context, typename Database>
|
||||
struct serializer_t<Context, named_interpretable_t<Database>>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using T = named_interpretable_t<Database>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (t._requires_braces)
|
||||
{
|
||||
context << '(';
|
||||
t.serialize(context);
|
||||
context << ')';
|
||||
}
|
||||
else
|
||||
t.serialize(context);
|
||||
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -37,6 +37,7 @@ namespace sqlpp
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, no_data_t>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using T = no_data_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -30,24 +30,61 @@
|
||||
#include <type_traits>
|
||||
#include <sqlpp11/no_value.h>
|
||||
#include <sqlpp11/serializer.h>
|
||||
#include <sqlpp11/prepared_execute.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
struct noop
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
|
||||
struct _name_t {};
|
||||
struct _alias_t {};
|
||||
|
||||
template<typename Policies>
|
||||
template<typename Statement>
|
||||
struct _result_methods_t
|
||||
{};
|
||||
{
|
||||
using _statement_t = Statement;
|
||||
|
||||
const _statement_t& _get_statement() const
|
||||
{
|
||||
return static_cast<const _statement_t&>(*this);
|
||||
}
|
||||
|
||||
// Execute
|
||||
template<typename Db, typename Composite>
|
||||
auto _run(Db& db, const Composite& composite) const -> void
|
||||
{
|
||||
return db.execute(composite);
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
auto _run(Db& db) const -> void
|
||||
{
|
||||
return db.execute(_get_statement());
|
||||
}
|
||||
|
||||
// Prepare
|
||||
template<typename Db, typename Composite>
|
||||
auto _prepare(Db& db, const Composite& composite) const
|
||||
-> prepared_execute_t<Db, Composite>
|
||||
{
|
||||
return {{}, db.prepare_execute(composite)};
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
auto _prepare(Db& db) const
|
||||
-> prepared_execute_t<Db, _statement_t>
|
||||
{
|
||||
return {{}, db.prepare_execute(_get_statement())};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, noop>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using T = noop;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
|
95
include/sqlpp11/not_in.h
Normal file
95
include/sqlpp11/not_in.h
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, 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_NOT_IN_H
|
||||
#define SQLPP_NOT_IN_H
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/char_sequence.h>
|
||||
#include <sqlpp11/boolean.h>
|
||||
#include <sqlpp11/in_fwd.h>
|
||||
#include <sqlpp11/detail/type_set.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Operand, typename... Args>
|
||||
struct not_in_t:
|
||||
public expression_operators<not_in_t<Operand, Args...>, boolean>,
|
||||
public alias_operators<not_in_t<Operand, Args...>>
|
||||
{
|
||||
using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable>;
|
||||
using _nodes = detail::type_vector<Operand, Args...>;
|
||||
|
||||
static_assert(sizeof...(Args) > 0, "not_in() requires at least one argument");
|
||||
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char _literal[] = "not_in_";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T not_in;
|
||||
};
|
||||
};
|
||||
|
||||
not_in_t(Operand operand, Args... args):
|
||||
_operand(operand),
|
||||
_args(args...)
|
||||
{}
|
||||
|
||||
not_in_t(const not_in_t&) = default;
|
||||
not_in_t(not_in_t&&) = default;
|
||||
not_in_t& operator=(const not_in_t&) = default;
|
||||
not_in_t& operator=(not_in_t&&) = default;
|
||||
~not_in_t() = default;
|
||||
|
||||
Operand _operand;
|
||||
std::tuple<Args...> _args;
|
||||
};
|
||||
|
||||
template<typename Context, typename Operand, typename... Args>
|
||||
struct serializer_t<Context, not_in_t<Operand, Args...>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Args...>;
|
||||
using T = not_in_t<Operand, Args...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
serialize_operand(t._operand, context);
|
||||
context << " NOT IN(";
|
||||
if (sizeof...(Args) == 1)
|
||||
serialize(std::get<0>(t._args), context);
|
||||
else
|
||||
interpret_tuple(t._args, ',', context);
|
||||
context << ')';
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -34,12 +34,13 @@ namespace sqlpp
|
||||
struct null_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_expression, tag::is_sql_null>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, null_t>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using Operand = null_t;
|
||||
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -55,7 +55,7 @@ namespace sqlpp
|
||||
struct offset_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_offset>;
|
||||
using _recursive_traits = make_recursive_traits<Offset>;
|
||||
using _nodes = detail::type_vector<Offset>;
|
||||
|
||||
static_assert(is_integral_t<Offset>::value, "offset requires an integral value or integral parameter");
|
||||
|
||||
@ -69,9 +69,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = offset_data_t<Offset>;
|
||||
|
||||
@ -84,12 +84,8 @@ namespace sqlpp
|
||||
{
|
||||
return t.offset;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
static void _check_consistency() {}
|
||||
using _consistency_check = consistent_t;
|
||||
};
|
||||
};
|
||||
|
||||
@ -124,7 +120,7 @@ namespace sqlpp
|
||||
struct dynamic_offset_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_offset>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
|
||||
// Data
|
||||
using _data_t = dynamic_offset_data_t<Database>;
|
||||
@ -138,6 +134,7 @@ namespace sqlpp
|
||||
{
|
||||
// FIXME: Make sure that Offset does not require external tables? Need to read up on SQL
|
||||
using arg_t = wrap_operand_t<Offset>;
|
||||
static_assert(is_integral_t<arg_t>::value, "offset requires an integral value or integral parameter");
|
||||
_data._value = arg_t{value};
|
||||
_data._initialized = true;
|
||||
}
|
||||
@ -145,9 +142,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = dynamic_offset_data_t<Database>;
|
||||
|
||||
@ -160,12 +157,8 @@ namespace sqlpp
|
||||
{
|
||||
return t.offset;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
static void _check_consistency() {}
|
||||
using _consistency_check = consistent_t;
|
||||
|
||||
template<typename Offset>
|
||||
void set_offset(Offset value)
|
||||
@ -184,7 +177,7 @@ namespace sqlpp
|
||||
struct no_offset_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
@ -196,9 +189,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
@ -211,30 +204,44 @@ namespace sqlpp
|
||||
{
|
||||
return t.no_offset;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = new_statement<Policies, no_offset_t, T>;
|
||||
|
||||
static void _check_consistency() {}
|
||||
template<typename T>
|
||||
using _check = is_integral_t<wrap_operand_t<T>>;
|
||||
|
||||
template<typename Check, typename T>
|
||||
using _new_statement_t = new_statement_t<Check::value, Policies, no_offset_t, T>;
|
||||
|
||||
using _consistency_check = consistent_t;
|
||||
|
||||
template<typename Arg>
|
||||
auto offset(Arg arg) const
|
||||
-> _new_statement_t<offset_t<wrap_operand_t<Arg>>>
|
||||
-> _new_statement_t<_check<Arg>, offset_t<wrap_operand_t<Arg>>>
|
||||
{
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), offset_data_t<wrap_operand_t<Arg>>{{arg}} };
|
||||
static_assert(_check<Arg>::value, "offset requires an integral value or integral parameter");
|
||||
return _offset_impl(_check<Arg>{}, wrap_operand_t<Arg>{arg});
|
||||
}
|
||||
|
||||
auto dynamic_offset() const
|
||||
-> _new_statement_t<dynamic_offset_t<_database_t>>
|
||||
-> _new_statement_t<std::true_type, dynamic_offset_t<_database_t>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_offset must not be called in a static statement");
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), dynamic_offset_data_t<_database_t>{} };
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Arg>
|
||||
auto _offset_impl(const std::false_type&, Arg arg) const
|
||||
-> bad_statement;
|
||||
|
||||
template<typename Arg>
|
||||
auto _offset_impl(const std::true_type&, Arg arg) const
|
||||
-> _new_statement_t<std::true_type, offset_t<Arg>>
|
||||
{
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), offset_data_t<Arg>{arg} };
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
@ -242,12 +249,13 @@ namespace sqlpp
|
||||
template<typename Context, typename Offset>
|
||||
struct serializer_t<Context, offset_data_t<Offset>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Offset>;
|
||||
using T = offset_data_t<Offset>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << " OFFSET ";
|
||||
serialize(t._value, context);
|
||||
serialize_operand(t._value, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
@ -255,6 +263,7 @@ namespace sqlpp
|
||||
template<typename Context, typename Database>
|
||||
struct serializer_t<Context, dynamic_offset_data_t<Database>>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using T = dynamic_offset_data_t<Database>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -30,43 +30,61 @@
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/interpret_tuple.h>
|
||||
#include <sqlpp11/interpretable_list.h>
|
||||
#include <sqlpp11/detail/logic.h>
|
||||
#include <sqlpp11/logic.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Database, typename... Expr>
|
||||
template<typename Database, typename... Expressions>
|
||||
struct on_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_on>;
|
||||
using _recursive_traits = make_recursive_traits<Expr...>;
|
||||
using _nodes = detail::type_vector<Expressions...>;
|
||||
|
||||
using _is_dynamic = is_database<Database>;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in on()");
|
||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in on()");
|
||||
|
||||
template<typename E>
|
||||
void add(E expr)
|
||||
template<typename Expr>
|
||||
void add(Expr expr)
|
||||
{
|
||||
static_assert(is_expression_t<E>::value, "invalid expression argument in add_on()");
|
||||
_dynamic_expressions.emplace_back(expr);
|
||||
static_assert(_is_dynamic::value, "on::add() must not be called for static on()");
|
||||
static_assert(is_expression_t<Expr>::value, "invalid expression argument in on::add()");
|
||||
using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, Expr>;
|
||||
_serialize_check::_();
|
||||
|
||||
using ok = logic::all_t<_is_dynamic::value, is_expression_t<Expr>::value, _serialize_check::type::value>;
|
||||
|
||||
_add_impl(expr, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
std::tuple<Expr...> _expressions;
|
||||
private:
|
||||
template<typename Expr>
|
||||
void _add_impl(Expr expr, const std::true_type&)
|
||||
{
|
||||
return _dynamic_expressions.emplace_back(expr);
|
||||
}
|
||||
|
||||
template<typename Expr>
|
||||
void _add_impl(Expr expr, const std::false_type&);
|
||||
|
||||
public:
|
||||
std::tuple<Expressions...> _expressions;
|
||||
interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
template<typename Context, typename Database, typename... Expr>
|
||||
struct serializer_t<Context, on_t<Database, Expr...>>
|
||||
template<typename Context, typename Database, typename... Expressions>
|
||||
struct serializer_t<Context, on_t<Database, Expressions...>>
|
||||
{
|
||||
using T = on_t<Database, Expr...>;
|
||||
using _serialize_check = serialize_check_of<Context, Expressions...>;
|
||||
using T = on_t<Database, Expressions...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty())
|
||||
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
||||
return context;
|
||||
context << " ON ";
|
||||
interpret_tuple(t._expressions, " AND ", context);
|
||||
if (sizeof...(Expr) and not t._dynamic_expressions.empty())
|
||||
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
||||
context << " AND ";
|
||||
interpret_list(t._dynamic_expressions, " AND ", context);
|
||||
return context;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -32,7 +32,7 @@
|
||||
#include <sqlpp11/interpret_tuple.h>
|
||||
#include <sqlpp11/interpretable.h>
|
||||
#include <sqlpp11/policy_update.h>
|
||||
#include <sqlpp11/detail/logic.h>
|
||||
#include <sqlpp11/logic.h>
|
||||
#include <sqlpp11/detail/type_set.h>
|
||||
|
||||
namespace sqlpp
|
||||
@ -55,21 +55,26 @@ namespace sqlpp
|
||||
interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
struct assert_no_unknown_tables_in_order_by_t
|
||||
{
|
||||
using type = std::false_type;
|
||||
|
||||
template<typename T = void>
|
||||
static void _()
|
||||
{
|
||||
static_assert(wrong_t<T>::value, "at least one order-by expression requires a table which is otherwise not known in the statement");
|
||||
}
|
||||
};
|
||||
|
||||
// ORDER BY
|
||||
template<typename Database, typename... Expressions>
|
||||
struct order_by_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_order_by>;
|
||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||
using _nodes = detail::type_vector<Expressions...>;
|
||||
|
||||
using _is_dynamic = is_database<Database>;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression (e.g. a column) required in order_by()");
|
||||
|
||||
static_assert(not detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in order_by()");
|
||||
|
||||
static_assert(detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in order_by()");
|
||||
|
||||
// Data
|
||||
using _data_t = order_by_data_t<Database, Expressions...>;
|
||||
|
||||
@ -87,10 +92,12 @@ namespace sqlpp
|
||||
void add(Expression expression)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add() must not be called for static order_by");
|
||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in order_by::add()");
|
||||
static_assert(is_sort_order_t<Expression>::value, "invalid expression argument in order_by::add()");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in order_by::add()");
|
||||
using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, Expression>;
|
||||
_serialize_check::_();
|
||||
|
||||
using ok = detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
||||
using ok = logic::all_t<_is_dynamic::value, is_sort_order_t<Expression>::value, _serialize_check::type::value>;
|
||||
|
||||
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
@ -108,9 +115,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = order_by_data_t<Database, Expressions...>;
|
||||
|
||||
@ -123,12 +130,10 @@ namespace sqlpp
|
||||
{
|
||||
return t.order_by;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
static void _check_consistency() {}
|
||||
using _consistency_check = typename std::conditional<Policies::template _no_unknown_tables<order_by_t>::value,
|
||||
consistent_t,
|
||||
assert_no_unknown_tables_in_order_by_t>::type;
|
||||
};
|
||||
};
|
||||
|
||||
@ -136,7 +141,7 @@ namespace sqlpp
|
||||
struct no_order_by_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
using _nodes = detail::type_vector<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
@ -148,9 +153,9 @@ namespace sqlpp
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
// Base template to be inherited by the statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
struct _base_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
@ -163,30 +168,49 @@ namespace sqlpp
|
||||
{
|
||||
return t.no_order_by;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = new_statement<Policies, no_order_by_t, T>;
|
||||
|
||||
static void _check_consistency() {}
|
||||
template<typename... T>
|
||||
using _check = logic::all_t<is_sort_order_t<T>::value...>;
|
||||
|
||||
template<typename... Args>
|
||||
auto order_by(Args... args) const
|
||||
-> _new_statement_t<order_by_t<void, Args...>>
|
||||
template<typename Check, typename T>
|
||||
using _new_statement_t = new_statement_t<Check::value, Policies, no_order_by_t, T>;
|
||||
|
||||
using _consistency_check = consistent_t;
|
||||
|
||||
template<typename... Expressions>
|
||||
auto order_by(Expressions... expressions) const
|
||||
-> _new_statement_t<_check<Expressions...>, order_by_t<void, Expressions...>>
|
||||
{
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), order_by_data_t<void, Args...>{args...} };
|
||||
static_assert(sizeof...(Expressions), "at least one expression (e.g. a column) required in order_by()");
|
||||
static_assert(_check<Expressions...>::value, "at least one argument is not a sort order in order_by()");
|
||||
|
||||
return _order_by_impl<void>(_check<Expressions...>{}, expressions...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_order_by(Args... args) const
|
||||
-> _new_statement_t<order_by_t<_database_t, Args...>>
|
||||
template<typename... Expressions>
|
||||
auto dynamic_order_by(Expressions... expressions) const
|
||||
-> _new_statement_t<_check<Expressions...>, order_by_t<_database_t, Expressions...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_order_by must not be called in a static statement");
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), order_by_data_t<_database_t, Args...>{args...} };
|
||||
static_assert(_check<Expressions...>::value, "at least one argument is not a sort order in order_by()");
|
||||
|
||||
return _order_by_impl<_database_t>(_check<Expressions...>{}, expressions...);
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Database, typename... Expressions>
|
||||
auto _order_by_impl(const std::false_type&, Expressions... expressions) const
|
||||
-> bad_statement;
|
||||
|
||||
template<typename Database, typename... Expressions>
|
||||
auto _order_by_impl(const std::true_type&, Expressions... expressions) const
|
||||
-> _new_statement_t<std::true_type, order_by_t<_database_t, Expressions...>>
|
||||
{
|
||||
static_assert(not detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in order_by()");
|
||||
|
||||
return { static_cast<const derived_statement_t<Policies>&>(*this), order_by_data_t<Database, Expressions...>{expressions...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -195,6 +219,7 @@ namespace sqlpp
|
||||
template<typename Context, typename Database, typename... Expressions>
|
||||
struct serializer_t<Context, order_by_data_t<Database, Expressions...>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Expressions...>;
|
||||
using T = order_by_data_t<Database, Expressions...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -38,15 +38,10 @@ namespace sqlpp
|
||||
public expression_operators<parameter_t<ValueType, NameType>, ValueType>
|
||||
{
|
||||
using _traits = make_traits<ValueType, tag::is_parameter, tag::is_expression>;
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _parameters = std::tuple<parameter_t>;
|
||||
using _provided_tables = detail::type_set<>;
|
||||
using _provided_outer_tables = detail::type_set<>;
|
||||
using _required_tables = detail::type_set<>;
|
||||
using _extra_tables = detail::type_set<>;
|
||||
using _tags = detail::type_set<tag::can_be_null>;
|
||||
};
|
||||
|
||||
using _nodes = detail::type_vector<>;
|
||||
using _parameters = detail::type_vector<parameter_t>;
|
||||
using _can_be_null = std::true_type;
|
||||
|
||||
using _instance_t = member_t<NameType, parameter_value_t<ValueType>>;
|
||||
|
||||
@ -63,6 +58,7 @@ namespace sqlpp
|
||||
template<typename Context, typename ValueType, typename NameType>
|
||||
struct serializer_t<Context, parameter_t<ValueType, NameType>>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using T = parameter_t<ValueType, NameType>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -37,11 +37,11 @@ namespace sqlpp
|
||||
template<typename T>
|
||||
struct parameter_list_t
|
||||
{
|
||||
static_assert(wrong_t<parameter_list_t>::value, "Template parameter for parameter_list_t has to be a tuple");
|
||||
static_assert(wrong_t<parameter_list_t>::value, "Template parameter for parameter_list_t has to be a type_vector");
|
||||
};
|
||||
|
||||
template<typename... Parameter>
|
||||
struct parameter_list_t<std::tuple<Parameter...>>: public Parameter::_instance_t...
|
||||
struct parameter_list_t<detail::type_vector<Parameter...>>: public Parameter::_instance_t...
|
||||
{
|
||||
using _member_tuple_t = std::tuple<typename Parameter::_instance_t...>;
|
||||
using size = std::integral_constant<std::size_t, sizeof...(Parameter)>;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -28,6 +28,7 @@
|
||||
#define SQLPP_POLICY_UPDATE_H
|
||||
|
||||
#include <sqlpp11/wrong.h>
|
||||
#include <sqlpp11/bad_statement.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -53,6 +54,21 @@ namespace sqlpp
|
||||
template<typename Policies, typename Needle, typename Replacement>
|
||||
using new_statement = typename Policies::template _new_statement_t<Needle, Replacement>;
|
||||
|
||||
template<bool, typename Policies, typename Needle, typename Replacement>
|
||||
struct new_statement_impl
|
||||
{
|
||||
using type = typename Policies::template _new_statement_t<Needle, Replacement>;
|
||||
};
|
||||
|
||||
template<typename Policies, typename Needle, typename Replacement>
|
||||
struct new_statement_impl<false, Policies, Needle, Replacement>
|
||||
{
|
||||
using type = bad_statement;
|
||||
};
|
||||
|
||||
template<bool Check, typename Policies, typename Needle, typename Replacement>
|
||||
using new_statement_t = typename new_statement_impl<Check, Policies, Needle, Replacement>::type;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
206
include/sqlpp11/ppgen.h
Normal file
206
include/sqlpp11/ppgen.h
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2015, niXman (i dot nixman dog gmail dot com)
|
||||
* 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__ppgen_h
|
||||
#define _sqlpp__ppgen_h
|
||||
|
||||
#include <boost/preprocessor/config/config.hpp>
|
||||
|
||||
// enable the Clang support
|
||||
#if defined(__clang__) && !BOOST_PP_VARIADICS
|
||||
# undef BOOST_PP_VARIADICS
|
||||
# define BOOST_PP_VARIADICS 1
|
||||
#endif // defined(__clang__)
|
||||
|
||||
// tools
|
||||
#include <sqlpp11/ppgen/tools/wrap_seq.h>
|
||||
#include <sqlpp11/ppgen/tools/tuple_pop_front.h>
|
||||
|
||||
// table props
|
||||
#include <sqlpp11/ppgen/tblops/engine.h>
|
||||
#include <sqlpp11/ppgen/tblops/character_set.h>
|
||||
|
||||
// col props
|
||||
#include <sqlpp11/ppgen/colops/auto_increment.h>
|
||||
#include <sqlpp11/ppgen/colops/blob.h>
|
||||
#include <sqlpp11/ppgen/colops/bool.h>
|
||||
#include <sqlpp11/ppgen/colops/comment.h>
|
||||
#include <sqlpp11/ppgen/colops/datetime.h>
|
||||
#include <sqlpp11/ppgen/colops/default.h>
|
||||
#include <sqlpp11/ppgen/colops/floating_point.h>
|
||||
#include <sqlpp11/ppgen/colops/index.h>
|
||||
#include <sqlpp11/ppgen/colops/integer.h>
|
||||
#include <sqlpp11/ppgen/colops/not_null.h>
|
||||
#include <sqlpp11/ppgen/colops/null.h>
|
||||
#include <sqlpp11/ppgen/colops/primary_key.h>
|
||||
#include <sqlpp11/ppgen/colops/text.h>
|
||||
#include <sqlpp11/ppgen/colops/timestamp.h>
|
||||
#include <sqlpp11/ppgen/colops/unique.h>
|
||||
#include <sqlpp11/ppgen/colops/varchar.h>
|
||||
|
||||
// boost.preprocessor
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/facilities/expand.hpp>
|
||||
#include <boost/preprocessor/punctuation/comma_if.hpp>
|
||||
#include <boost/preprocessor/comparison/less.hpp>
|
||||
#include <boost/preprocessor/arithmetic/add.hpp>
|
||||
#include <boost/preprocessor/seq/for_each.hpp>
|
||||
#include <boost/preprocessor/seq/for_each_i.hpp>
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
#include <boost/preprocessor/tuple/elem.hpp>
|
||||
#include <boost/preprocessor/tuple/size.hpp>
|
||||
#include <boost/preprocessor/tuple/to_seq.hpp>
|
||||
|
||||
/***************************************************************************/
|
||||
// tools
|
||||
|
||||
#define SQLPP_DECLARE_TABLE_GET_TABLE_NAME(table) \
|
||||
BOOST_PP_TUPLE_ELEM(0, BOOST_PP_EXPAND table)
|
||||
|
||||
#define SQLPP_DECLARE_TABLE_GET_TABLE_PROPS(table) \
|
||||
SQLPP_BOOST_PP_TUPLE_POP_FRONT(BOOST_PP_EXPAND table)
|
||||
|
||||
#define SQLPP_DECLARE_COLUMN_GET_COLUMN_NAME(col) \
|
||||
BOOST_PP_TUPLE_ELEM(0, col)
|
||||
|
||||
#define SQLPP_DECLARE_TABLE_ENUM_COLUMNS(unused, table, elem) \
|
||||
,table::SQLPP_DECLARE_COLUMN_GET_COLUMN_NAME(elem)
|
||||
|
||||
/***************************************************************************/
|
||||
// columns
|
||||
|
||||
#define SQLPP_DECLARE_COLUMN_GEN_TRAITS_AUX(unused, size, idx, elem) \
|
||||
BOOST_PP_CAT( \
|
||||
SQLPP_DECLARE_COLUMN_GEN_TRAITS_ \
|
||||
,BOOST_PP_CAT(SQLPP_DECLARE_COLUMN_GET_TRAITS_LAZY_, elem) \
|
||||
)(elem) \
|
||||
BOOST_PP_COMMA_IF(BOOST_PP_LESS(BOOST_PP_ADD(idx, 1), size))
|
||||
|
||||
#define SQLPP_DECLARE_COLUMN_GEN_TRAITS(props) \
|
||||
BOOST_PP_SEQ_FOR_EACH_I( \
|
||||
SQLPP_DECLARE_COLUMN_GEN_TRAITS_AUX \
|
||||
,BOOST_PP_TUPLE_SIZE(props) \
|
||||
,BOOST_PP_TUPLE_TO_SEQ(props) \
|
||||
)
|
||||
|
||||
#define SQLPP_DECLARE_COLUMN(unused, data, elem) \
|
||||
struct SQLPP_DECLARE_COLUMN_GET_COLUMN_NAME(elem) { \
|
||||
struct _alias_t { \
|
||||
static constexpr const char _literal[] = \
|
||||
BOOST_PP_STRINGIZE(SQLPP_DECLARE_COLUMN_GET_COLUMN_NAME(elem)); \
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>; \
|
||||
\
|
||||
template<typename T> \
|
||||
struct _member_t { \
|
||||
T SQLPP_DECLARE_COLUMN_GET_COLUMN_NAME(elem); \
|
||||
\
|
||||
T& operator()() { return SQLPP_DECLARE_COLUMN_GET_COLUMN_NAME(elem); } \
|
||||
const T& operator()() const { return SQLPP_DECLARE_COLUMN_GET_COLUMN_NAME(elem); } \
|
||||
}; /* struct _member_t */ \
|
||||
}; /* struct _alias_t */ \
|
||||
\
|
||||
using _traits = sqlpp::make_traits< \
|
||||
SQLPP_DECLARE_COLUMN_GEN_TRAITS(SQLPP_BOOST_PP_TUPLE_POP_FRONT(elem)) \
|
||||
>; \
|
||||
\
|
||||
}; /* struct SQLPP_DECLARE_COLUMN_GET_COLUMN_NAME(elem) */
|
||||
|
||||
/***************************************************************************/
|
||||
// table props
|
||||
|
||||
#define SQLPP_DECLARE_TABLE_GEN_PROPS_AUX(unused1, unused2, elem) \
|
||||
BOOST_PP_CAT( \
|
||||
SQLPP_DECLARE_TABLE_GEN_ \
|
||||
,BOOST_PP_CAT(SQLPP_DECLARE_TABLE_GET_PROC_LAZY_, elem) \
|
||||
)(elem)
|
||||
|
||||
#define SQLPP_DECLARE_TABLE_GEN_PROPS(table) \
|
||||
BOOST_PP_SEQ_FOR_EACH( \
|
||||
SQLPP_DECLARE_TABLE_GEN_PROPS_AUX \
|
||||
,~ \
|
||||
,BOOST_PP_TUPLE_TO_SEQ(SQLPP_BOOST_PP_TUPLE_POP_FRONT(table)) \
|
||||
)
|
||||
|
||||
/***************************************************************************/
|
||||
// main
|
||||
|
||||
#define SQLPP_DECLARE_TABLE_IMPL(table, cols) \
|
||||
namespace SQLPP_DECLARE_TABLE_GET_TABLE_NAME(table) { \
|
||||
namespace BOOST_PP_CAT(SQLPP_DECLARE_TABLE_GET_TABLE_NAME(table), _) { \
|
||||
BOOST_PP_SEQ_FOR_EACH( \
|
||||
SQLPP_DECLARE_COLUMN \
|
||||
,~ \
|
||||
,cols \
|
||||
) \
|
||||
} /* namespace BOOST_PP_CAT(SQLPP_DECLARE_TABLE_GET_TABLE_NAME(table), _) */ \
|
||||
\
|
||||
struct SQLPP_DECLARE_TABLE_GET_TABLE_NAME(table) \
|
||||
: sqlpp::table_t< \
|
||||
SQLPP_DECLARE_TABLE_GET_TABLE_NAME(table) \
|
||||
BOOST_PP_SEQ_FOR_EACH( \
|
||||
SQLPP_DECLARE_TABLE_ENUM_COLUMNS \
|
||||
,BOOST_PP_CAT(SQLPP_DECLARE_TABLE_GET_TABLE_NAME(table), _) \
|
||||
,cols \
|
||||
) \
|
||||
> \
|
||||
{ \
|
||||
BOOST_PP_IF( \
|
||||
BOOST_PP_LESS(BOOST_PP_TUPLE_SIZE(table), 2) \
|
||||
,BOOST_PP_TUPLE_EAT() \
|
||||
,SQLPP_DECLARE_TABLE_GEN_PROPS \
|
||||
)(BOOST_PP_EXPAND table) \
|
||||
\
|
||||
struct _alias_t { \
|
||||
static constexpr const char _literal[] = \
|
||||
BOOST_PP_STRINGIZE(SQLPP_DECLARE_TABLE_GET_TABLE_NAME(table)); \
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>; \
|
||||
\
|
||||
template<typename T> \
|
||||
struct _member_t { \
|
||||
T SQLPP_DECLARE_TABLE_GET_TABLE_NAME(table); \
|
||||
\
|
||||
T& operator()() { return SQLPP_DECLARE_TABLE_GET_TABLE_NAME(table); } \
|
||||
const T& operator()() const { return SQLPP_DECLARE_TABLE_GET_TABLE_NAME(table); } \
|
||||
\
|
||||
}; /* struct _member_t */ \
|
||||
\
|
||||
}; /* struct _alias_t */ \
|
||||
\
|
||||
}; /* struct SQLPP_DECLARE_TABLE_GET_TABLE_NAME(table) */ \
|
||||
\
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#define SQLPP_DECLARE_TABLE(table, cols) \
|
||||
SQLPP_DECLARE_TABLE_IMPL( \
|
||||
BOOST_PP_CAT(SQLPP_WRAP_SEQUENCE_X table, 0) \
|
||||
,BOOST_PP_CAT(SQLPP_WRAP_SEQUENCE_X cols, 0) \
|
||||
)
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#endif // _sqlpp__ppgen_h
|
35
include/sqlpp11/ppgen/colops/auto_increment.h
Normal file
35
include/sqlpp11/ppgen/colops/auto_increment.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2015, niXman (i dot nixman dog gmail dot com)
|
||||
* 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__ppgen__colops__auto_increment_h
|
||||
#define _sqlpp__ppgen__colops__auto_increment_h
|
||||
|
||||
#define SQLPP_DECLARE_COLUMN_GET_TRAITS_LAZY_SQLPP_AUTO_INCREMENT \
|
||||
PROC_SQLPP_AUTO_INCREMENT
|
||||
#define SQLPP_DECLARE_COLUMN_GEN_TRAITS_PROC_SQLPP_AUTO_INCREMENT(...) \
|
||||
sqlpp::tag::must_not_update
|
||||
|
||||
#endif // _sqlpp__ppgen__colops__auto_increment_h
|
50
include/sqlpp11/ppgen/colops/blob.h
Normal file
50
include/sqlpp11/ppgen/colops/blob.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2015, niXman (i dot nixman dog gmail dot com)
|
||||
* 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__ppgen__colops__blob_h
|
||||
#define _sqlpp__ppgen__colops__blob_h
|
||||
|
||||
#define SQLPP_DECLARE_COLUMN_GET_TRAITS_LAZY_tinyblob \
|
||||
PROC_tinyblob
|
||||
#define SQLPP_DECLARE_COLUMN_GEN_TRAITS_PROC_tinyblob(...) \
|
||||
sqlpp::blob
|
||||
|
||||
#define SQLPP_DECLARE_COLUMN_GET_TRAITS_LAZY_blob \
|
||||
PROC_blob
|
||||
#define SQLPP_DECLARE_COLUMN_GEN_TRAITS_PROC_blob(...) \
|
||||
sqlpp::blob
|
||||
|
||||
#define SQLPP_DECLARE_COLUMN_GET_TRAITS_LAZY_mediumblob \
|
||||
PROC_mediumblob
|
||||
#define SQLPP_DECLARE_COLUMN_GEN_TRAITS_PROC_mediumblob(...) \
|
||||
sqlpp::blob
|
||||
|
||||
#define SQLPP_DECLARE_COLUMN_GET_TRAITS_LAZY_longblob \
|
||||
PROC_longblob
|
||||
#define SQLPP_DECLARE_COLUMN_GEN_TRAITS_PROC_longblob(...) \
|
||||
sqlpp::blob
|
||||
|
||||
#endif // _sqlpp__ppgen__colops__blob_h
|
35
include/sqlpp11/ppgen/colops/bool.h
Normal file
35
include/sqlpp11/ppgen/colops/bool.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2015, niXman (i dot nixman dog gmail dot com)
|
||||
* 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__ppgen__colops__bool_h
|
||||
#define _sqlpp__ppgen__colops__bool_h
|
||||
|
||||
#define SQLPP_DECLARE_COLUMN_GET_TRAITS_LAZY_bool \
|
||||
PROC_bool
|
||||
#define SQLPP_DECLARE_COLUMN_GEN_TRAITS_PROC_bool(...) \
|
||||
sqlpp::boolean
|
||||
|
||||
#endif // _sqlpp__ppgen__colops__bool_h
|
35
include/sqlpp11/ppgen/colops/comment.h
Normal file
35
include/sqlpp11/ppgen/colops/comment.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2015, niXman (i dot nixman dog gmail dot com)
|
||||
* 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__ppgen__colops__comment_h
|
||||
#define _sqlpp__ppgen__colops__comment_h
|
||||
|
||||
#define SQLPP_DECLARE_COLUMN_GET_TRAITS_LAZY_SQLPP_COMMENT(str) \
|
||||
PROC_SQLPP_COMMENT
|
||||
#define SQLPP_DECLARE_COLUMN_GEN_TRAITS_PROC_SQLPP_COMMENT(str) \
|
||||
[COMMENT is not implemented]
|
||||
|
||||
#endif // _sqlpp__ppgen__colops__comment_h
|
35
include/sqlpp11/ppgen/colops/datetime.h
Normal file
35
include/sqlpp11/ppgen/colops/datetime.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2015, niXman (i dot nixman dog gmail dot com)
|
||||
* 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__ppgen__colops__datetime_h
|
||||
#define _sqlpp__ppgen__colops__datetime_h
|
||||
|
||||
#define SQLPP_DECLARE_COLUMN_GET_TRAITS_LAZY_datetime \
|
||||
PROC_datetime
|
||||
#define SQLPP_DECLARE_COLUMN_GEN_TRAITS_PROC_datetime(...) \
|
||||
[datetime is not implemented]
|
||||
|
||||
#endif // _sqlpp__ppgen__colops__datetime_h
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user