mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-15 20:31:16 +08:00
Merge branch 'release/0.59'
This commit is contained in:
commit
2b5f8d7666
@ -4,7 +4,7 @@ os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
dist: trusty
|
||||
dist: xenial
|
||||
sudo: required
|
||||
|
||||
compiler:
|
||||
@ -23,6 +23,7 @@ notifications:
|
||||
|
||||
install:
|
||||
- g++ --version
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew upgrade cmake; fi
|
||||
- cmake --version
|
||||
- git clone https://github.com/HowardHinnant/date
|
||||
- cd date
|
||||
|
18
README.md
18
README.md
@ -165,6 +165,24 @@ brew install marvin182/zapfhahn/sqlpp11
|
||||
|
||||
Some connectors can be installed with the formula. See `brew info marvin182/zapfhahn/sqlpp11` for available options.
|
||||
|
||||
__Build via vcpkg:__
|
||||
|
||||
You can download and install sqlpp11 using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/Microsoft/vcpkg.git
|
||||
cd vcpkg
|
||||
./bootstrap-vcpkg.sh
|
||||
./vcpkg integrate install
|
||||
vcpkg install sqlpp11
|
||||
```
|
||||
|
||||
The sqlpp11 port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
|
||||
|
||||
The following connector libraries for sqlpp11 are maintained as a separate package in vcpkg:
|
||||
|
||||
* [sqlpp11-connector-sqlite3](https://github.com/microsoft/vcpkg/tree/master/ports/sqlpp11-connector-sqlite3)
|
||||
* [sqlpp11-connector-mysql](https://github.com/microsoft/vcpkg/tree/master/ports/sqlpp11-connector-mysql)
|
||||
|
||||
Basic usage:
|
||||
-------------
|
||||
|
@ -31,15 +31,14 @@ find_dependency(HinnantDate REQUIRED)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/Sqlpp11Targets.cmake")
|
||||
|
||||
# Import "ddl2cpp" script
|
||||
if(TARGET sqlpp11::ddl2cpp)
|
||||
message(FATAL_ERROR "Target sqlpp11::ddl2cpp already defined")
|
||||
if(NOT TARGET sqlpp11::ddl2cpp)
|
||||
get_filename_component(sqlpp11_ddl2cpp_location "${CMAKE_CURRENT_LIST_DIR}/../../../bin/sqlpp11-ddl2cpp" REALPATH)
|
||||
if(NOT EXISTS "${sqlpp11_ddl2cpp_location}")
|
||||
message(FATAL_ERROR "The imported target sqlpp11::ddl2cpp references the file '${sqlpp11_ddl2cpp_location}' but this file does not exists.")
|
||||
endif()
|
||||
add_executable(sqlpp11::ddl2cpp IMPORTED)
|
||||
set_target_properties(sqlpp11::ddl2cpp PROPERTIES
|
||||
IMPORTED_LOCATION "${sqlpp11_ddl2cpp_location}"
|
||||
)
|
||||
unset(sqlpp11_ddl2cpp_location)
|
||||
endif()
|
||||
get_filename_component(sqlpp11_ddl2cpp_location "${CMAKE_CURRENT_LIST_DIR}/../../../bin/sqlpp11-ddl2cpp" REALPATH)
|
||||
if(NOT EXISTS "${sqlpp11_ddl2cpp_location}")
|
||||
message(FATAL_ERROR "The imported target sqlpp11::ddl2cpp references the file '${sqlpp11_ddl2cpp_location}' but this file does not exists.")
|
||||
endif()
|
||||
add_executable(sqlpp11::ddl2cpp IMPORTED)
|
||||
set_target_properties(sqlpp11::ddl2cpp PROPERTIES
|
||||
IMPORTED_LOCATION "${sqlpp11_ddl2cpp_location}"
|
||||
)
|
||||
unset(sqlpp11_ddl2cpp_location)
|
||||
|
42
include/sqlpp11/aggregate_function_operators.h
Normal file
42
include/sqlpp11/aggregate_function_operators.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2020, Roland Bock, MacDue
|
||||
* 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 SQLPP11_AGGREGATE_FUNCTION_OPERATORS_H
|
||||
#define SQLPP11_AGGREGATE_FUNCTION_OPERATORS_H
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template <typename Expr>
|
||||
struct aggregate_function_operators
|
||||
{
|
||||
over_t<Expr> over() const
|
||||
{
|
||||
return {*static_cast<const Expr*>(this)};
|
||||
}
|
||||
};
|
||||
} // namespace sqlpp
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Roland Bock
|
||||
* Copyright (c) 2013-2020, Roland Bock, MacDue
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -56,6 +56,7 @@ namespace sqlpp
|
||||
|
||||
template <typename Flag, typename Expr>
|
||||
struct avg_t : public expression_operators<avg_t<Flag, Expr>, floating_point>,
|
||||
public aggregate_function_operators<avg_t<Flag, Expr>>,
|
||||
public alias_operators<avg_t<Flag, Expr>>
|
||||
{
|
||||
using _traits = make_traits<floating_point, tag::is_expression, tag::is_selectable>;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* Copyright (c) 2013-2020, Roland Bock, MacDue
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -27,8 +27,10 @@
|
||||
#ifndef SQLPP11_AGGREGATE_FUNCTIONS_COUNT_H
|
||||
#define SQLPP11_AGGREGATE_FUNCTIONS_COUNT_H
|
||||
|
||||
#include <sqlpp11/over.h>
|
||||
#include <sqlpp11/char_sequence.h>
|
||||
#include <sqlpp11/select_flags.h>
|
||||
#include <sqlpp11/aggregate_function_operators.h>
|
||||
#include <sqlpp11/data_types/integral/data_type.h>
|
||||
|
||||
namespace sqlpp
|
||||
@ -57,6 +59,7 @@ namespace sqlpp
|
||||
|
||||
template <typename Flag, typename Expr>
|
||||
struct count_t : public expression_operators<count_t<Flag, Expr>, integral>,
|
||||
public aggregate_function_operators<count_t<Flag, Expr>>,
|
||||
public alias_operators<count_t<Flag, Expr>>
|
||||
{
|
||||
using _traits = make_traits<integral, tag::is_expression /*, tag::is_selectable*/>;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* Copyright (c) 2013-2020, Roland Bock, MacDue
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -55,7 +55,9 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template <typename Expr>
|
||||
struct max_t : public expression_operators<max_t<Expr>, value_type_of<Expr>>, public alias_operators<max_t<Expr>>
|
||||
struct max_t : public expression_operators<max_t<Expr>, value_type_of<Expr>>,
|
||||
public aggregate_function_operators<max_t<Expr>>,
|
||||
public alias_operators<max_t<Expr>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Expr>, tag::is_expression, tag::is_selectable>;
|
||||
using _nodes = detail::type_vector<Expr, aggregate_function>;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* Copyright (c) 2013-2020, Roland Bock, MacDue
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -55,7 +55,9 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template <typename Expr>
|
||||
struct min_t : public expression_operators<min_t<Expr>, value_type_of<Expr>>, public alias_operators<min_t<Expr>>
|
||||
struct min_t : public expression_operators<min_t<Expr>, value_type_of<Expr>>,
|
||||
public aggregate_function_operators<min_t<Expr>>,
|
||||
public alias_operators<min_t<Expr>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Expr>, tag::is_expression, tag::is_selectable>;
|
||||
using _nodes = detail::type_vector<Expr, aggregate_function>;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* Copyright (c) 2013-2020, Roland Bock, MacDue
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -56,6 +56,7 @@ namespace sqlpp
|
||||
|
||||
template <typename Flag, typename Expr>
|
||||
struct sum_t : public expression_operators<sum_t<Flag, Expr>, value_type_of<Expr>>,
|
||||
public aggregate_function_operators<sum_t<Flag, Expr>>,
|
||||
public alias_operators<sum_t<Flag, Expr>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Expr>, tag::is_expression, tag::is_selectable>;
|
||||
|
@ -183,7 +183,7 @@ namespace sqlpp
|
||||
|
||||
try
|
||||
{
|
||||
auto c = std::unique_ptr<Connection>(new Connection(*(config.get())));
|
||||
auto c = std::unique_ptr<Connection>(new Connection(config));
|
||||
return pool_connection<Connection_config, Reconnect_policy, Connection>(c, this);
|
||||
}
|
||||
catch (const sqlpp::exception& e)
|
||||
|
@ -163,6 +163,7 @@ namespace sqlpp
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_cte, tag::is_table>; // FIXME: is table? really?
|
||||
using _nodes = detail::type_vector<>;
|
||||
using _provided_tables = detail::type_set<cte_t>;
|
||||
using _required_ctes = detail::make_joined_set_t<required_ctes_of<Statement>, detail::type_set<AliasProvider>>;
|
||||
using _parameters = parameters_of<Statement>;
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#define SQLPP_BLOB_DATA_TYPE_H
|
||||
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/logic.h>
|
||||
|
@ -48,14 +48,14 @@ namespace sqlpp
|
||||
struct return_type_plus<L, R, binary_operand_check_t<L, is_unsigned_integral_t, R, is_numeric_t>>
|
||||
{
|
||||
using check = consistent_t;
|
||||
using type = value_type_of<wrap_operand_t<R>>;
|
||||
using type = plus_t<wrap_operand_t<L>, value_type_of<wrap_operand_t<R>>, wrap_operand_t<R>>;
|
||||
};
|
||||
|
||||
template <typename L, typename R>
|
||||
struct return_type_minus<L, R, binary_operand_check_t<L, is_unsigned_integral_t, R, is_numeric_not_unsigned_t>>
|
||||
{
|
||||
using check = consistent_t;
|
||||
using type = value_type_of<wrap_operand_t<R>>;
|
||||
using type = minus_t<wrap_operand_t<L>, value_type_of<wrap_operand_t<R>>, wrap_operand_t<R>>;
|
||||
};
|
||||
|
||||
template <typename L, typename R>
|
||||
@ -69,14 +69,14 @@ namespace sqlpp
|
||||
struct return_type_multiplies<L, R, binary_operand_check_t<L, is_unsigned_integral_t, R, is_numeric_t>>
|
||||
{
|
||||
using check = consistent_t;
|
||||
using type = value_type_of<wrap_operand_t<R>>;
|
||||
using type = multiplies_t<wrap_operand_t<L>, value_type_of<wrap_operand_t<R>>, wrap_operand_t<R>>;
|
||||
};
|
||||
|
||||
template <typename L, typename R>
|
||||
struct return_type_divides<L, R, binary_operand_check_t<L, is_unsigned_integral_t, R, is_numeric_t>>
|
||||
{
|
||||
using check = consistent_t;
|
||||
using type = value_type_of<wrap_operand_t<R>>;
|
||||
using type = divides_t<wrap_operand_t<L>, wrap_operand_t<R>>;
|
||||
};
|
||||
|
||||
template <typename L, typename R>
|
||||
|
@ -28,6 +28,7 @@
|
||||
#define SQLPP11_DETAIL_TYPE_SET_H
|
||||
|
||||
#include <type_traits>
|
||||
#include <stddef.h>
|
||||
#include <sqlpp11/wrong.h>
|
||||
#include <sqlpp11/logic.h>
|
||||
|
||||
|
@ -98,7 +98,17 @@ namespace sqlpp
|
||||
struct minus
|
||||
{
|
||||
using _traits = make_traits<ValueType>;
|
||||
static constexpr const char* _name = "-";
|
||||
// The trailing space is necessary to prevent
|
||||
// ```
|
||||
// t.id - -1
|
||||
// ```
|
||||
// from turning into
|
||||
// ```
|
||||
// tab_sample.id--1
|
||||
// ```
|
||||
// (-- starts a comment in SQL)
|
||||
// See https://github.com/rbock/sqlpp11/issues/294
|
||||
static constexpr const char* _name = " - ";
|
||||
};
|
||||
|
||||
template <typename ValueType>
|
||||
|
73
include/sqlpp11/over.h
Normal file
73
include/sqlpp11/over.h
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2020, Roland Bock, MacDue
|
||||
* 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 SQLPP11_OVER_H
|
||||
#define SQLPP11_OVER_H
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/serializer.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template <typename AggregateExpr>
|
||||
struct over_t : public expression_operators<over_t<AggregateExpr>, integral>,
|
||||
public alias_operators<over_t<AggregateExpr>>
|
||||
{
|
||||
using _traits = make_traits<integral, tag::is_expression>;
|
||||
using _nodes = detail::type_vector<AggregateExpr, aggregate_function>;
|
||||
|
||||
using _auto_alias_t = typename AggregateExpr::_auto_alias_t;
|
||||
|
||||
over_t(AggregateExpr aggregate_expression)
|
||||
: _aggregate_expression(aggregate_expression)
|
||||
{
|
||||
}
|
||||
|
||||
over_t(const over_t&) = default;
|
||||
over_t(over_t&&) = default;
|
||||
over_t& operator=(const over_t&) = default;
|
||||
over_t& operator=(over_t&&) = default;
|
||||
~over_t() = default;
|
||||
|
||||
AggregateExpr _aggregate_expression;
|
||||
};
|
||||
|
||||
template <typename Context, typename AggregateExpr>
|
||||
struct serializer_t<Context, over_t<AggregateExpr>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, AggregateExpr>;
|
||||
using T = over_t<AggregateExpr>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
serialize_operand(t._aggregate_expression, context);
|
||||
context << " OVER()";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
} // namespace sqlpp
|
||||
|
||||
#endif
|
@ -30,6 +30,7 @@
|
||||
#include <sqlpp11/join_types.h>
|
||||
#include <sqlpp11/noop.h>
|
||||
#include <sqlpp11/on.h>
|
||||
#include <sqlpp11/table_ref.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -154,7 +155,7 @@ namespace sqlpp
|
||||
auto join_impl(Check, Lhs lhs, Rhs rhs) -> inconsistent<Check>;
|
||||
|
||||
template <typename JoinType, typename Lhs, typename Rhs>
|
||||
auto join_impl(consistent_t, Lhs lhs, Rhs rhs) -> pre_join_t<JoinType, Lhs, Rhs>;
|
||||
auto join_impl(consistent_t, Lhs lhs, Rhs rhs) -> pre_join_t<JoinType, from_table_t<Lhs>, from_table_t<Rhs>>;
|
||||
|
||||
template <typename JoinType, typename Lhs, typename Rhs>
|
||||
auto join_impl(Lhs lhs, Rhs rhs) -> decltype(join_impl<JoinType>(check_pre_join_t<Lhs, Rhs>{}, lhs, rhs));
|
||||
@ -163,19 +164,19 @@ namespace sqlpp
|
||||
template <typename Lhs, typename Rhs>
|
||||
auto join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl<inner_join_t>(lhs, rhs))
|
||||
{
|
||||
return {lhs, rhs};
|
||||
return {from_table(lhs), from_table(rhs)};
|
||||
}
|
||||
|
||||
template <typename Lhs, typename Rhs>
|
||||
auto inner_join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl<inner_join_t>(lhs, rhs))
|
||||
{
|
||||
return {lhs, rhs};
|
||||
return {from_table(lhs), from_table(rhs)};
|
||||
}
|
||||
|
||||
template <typename Lhs, typename Rhs>
|
||||
auto left_outer_join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl<left_outer_join_t>(lhs, rhs))
|
||||
{
|
||||
return {lhs, rhs};
|
||||
return {from_table(lhs), from_table(rhs)};
|
||||
}
|
||||
|
||||
template <typename Lhs, typename Rhs>
|
||||
@ -183,13 +184,13 @@ namespace sqlpp
|
||||
{
|
||||
check_pre_join_t<Lhs, Rhs>{};
|
||||
|
||||
return {lhs, rhs};
|
||||
return {from_table(lhs), from_table(rhs)};
|
||||
}
|
||||
|
||||
template <typename Lhs, typename Rhs>
|
||||
auto outer_join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl<outer_join_t>(lhs, rhs))
|
||||
{
|
||||
return {lhs, rhs};
|
||||
return {from_table(lhs), from_table(rhs)};
|
||||
}
|
||||
|
||||
namespace detail
|
||||
@ -202,13 +203,14 @@ namespace sqlpp
|
||||
-> join_t<pre_join_t<cross_join_t, Lhs, Rhs>, on_t<unconditional_t>>;
|
||||
|
||||
template <typename Lhs, typename Rhs>
|
||||
auto cross_join_impl(Lhs lhs, Rhs rhs) -> decltype(cross_join_impl(check_pre_join_t<Lhs, Rhs>{}, lhs, rhs));
|
||||
auto cross_join_impl(Lhs lhs, Rhs rhs)
|
||||
-> decltype(cross_join_impl(check_pre_join_t<from_table_t<Lhs>, from_table_t<Rhs>>{}, lhs, rhs));
|
||||
} // namespace detail
|
||||
|
||||
template <typename Lhs, typename Rhs>
|
||||
auto cross_join(Lhs lhs, Rhs rhs) -> decltype(detail::cross_join_impl(lhs, rhs))
|
||||
{
|
||||
return {pre_join_t<cross_join_t, Lhs, Rhs>{lhs, rhs}, {}};
|
||||
return {pre_join_t<cross_join_t, from_table_t<Lhs>, from_table_t<Rhs>>{from_table(lhs), from_table(rhs)}, {}};
|
||||
}
|
||||
} // namespace sqlpp
|
||||
|
||||
|
@ -57,12 +57,11 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template <typename Flag, typename Expr>
|
||||
struct trim_t : public expression_operators<trim_t<Flag, Expr>, text>,
|
||||
public alias_operators<trim_t<Flag, Expr>>
|
||||
struct trim_t : public expression_operators<trim_t<Flag, Expr>, text>, public alias_operators<trim_t<Flag, Expr>>
|
||||
{
|
||||
using _traits = make_traits<text, tag::is_expression, tag::is_selectable>;
|
||||
|
||||
using _nodes = detail::type_vector<Expr, aggregate_function>;
|
||||
using _nodes = detail::type_vector<Expr>;
|
||||
using _can_be_null = can_be_null_t<Expr>;
|
||||
using _is_aggregate_expression = std::false_type;
|
||||
|
||||
@ -94,7 +93,6 @@ namespace sqlpp
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
@ -256,6 +256,10 @@ namespace sqlpp
|
||||
static_check_t<not std::is_same<Database, void>::value, assert_where_dynamic_used_with_dynamic_statement_t>,
|
||||
check_where_t<Expression>>;
|
||||
|
||||
template <typename Database>
|
||||
using check_where_empty_dynamic_t = static_combined_check_t<
|
||||
static_check_t<not std::is_same<Database, void>::value, assert_where_dynamic_used_with_dynamic_statement_t>>;
|
||||
|
||||
// NO WHERE YET
|
||||
template <bool WhereRequired>
|
||||
struct no_where_t
|
||||
@ -338,10 +342,11 @@ namespace sqlpp
|
||||
return _where_impl<_database_t>(Check{}, expression);
|
||||
}
|
||||
|
||||
auto dynamic_where() const -> _new_statement_t<check_where_dynamic_t<_database_t, boolean_operand>,
|
||||
where_t<_database_t, boolean_operand>>
|
||||
auto dynamic_where() const
|
||||
-> _new_statement_t<check_where_empty_dynamic_t<_database_t>, where_t<_database_t, unconditional_t>>
|
||||
{
|
||||
return dynamic_where(::sqlpp::value(true));
|
||||
return {static_cast<const derived_statement_t<Policies>&>(*this),
|
||||
where_data_t<_database_t, unconditional_t>{unconditional_t{}}};
|
||||
}
|
||||
|
||||
private:
|
||||
@ -378,6 +383,24 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Context, typename Database>
|
||||
struct serializer_t<Context, where_data_t<Database, unconditional_t>>
|
||||
{
|
||||
using _serialize_check = consistent_t;
|
||||
using T = where_data_t<Database, unconditional_t>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (t._dynamic_expressions.empty())
|
||||
{
|
||||
return context;
|
||||
}
|
||||
context << " WHERE ";
|
||||
interpret_list(t._dynamic_expressions, " AND ", context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Context>
|
||||
struct serializer_t<Context, where_data_t<void, unconditional_t>>
|
||||
{
|
||||
@ -403,6 +426,13 @@ namespace sqlpp
|
||||
return statement_t<Database, no_where_t<false>>().dynamic_where(std::forward<T>(t));
|
||||
}
|
||||
|
||||
template <typename Database>
|
||||
auto dynamic_where(const Database & /*unused*/)
|
||||
-> decltype(statement_t<Database, no_where_t<false>>().dynamic_where())
|
||||
{
|
||||
return statement_t<Database, no_where_t<false>>().dynamic_where();
|
||||
}
|
||||
|
||||
inline auto unconditionally() -> decltype(statement_t<void, no_where_t<false>>().unconditionally())
|
||||
{
|
||||
return statement_t<void, no_where_t<false>>().unconditionally();
|
||||
|
@ -273,6 +273,7 @@ types = {
|
||||
'numeric': 'floating_point', # PostgreSQL
|
||||
'date': 'day_point',
|
||||
'datetime': 'time_point',
|
||||
'time': 'time_of_day',
|
||||
'time without time zone': 'time_point', # PostgreSQL
|
||||
'time with time zone': 'time_point', # PostgreSQL
|
||||
'timestamp': 'time_point',
|
||||
@ -311,6 +312,8 @@ nsList = namespace.split('::')
|
||||
|
||||
def escape_if_reserved(name):
|
||||
reserved_names = [
|
||||
'BEGIN',
|
||||
'END',
|
||||
'GROUP',
|
||||
'ORDER',
|
||||
]
|
||||
|
@ -48,6 +48,11 @@ def main():
|
||||
parser.add_argument('ddl', help='path to ddl')
|
||||
parser.add_argument('target', help='path to target')
|
||||
parser.add_argument('namespace', help='namespace')
|
||||
parser.add_argument('-identity-naming',
|
||||
help='Use table and column names from the ddl '
|
||||
'(defaults to UpperCamelCase for tables and '
|
||||
'lowerCamelCase for columns)',
|
||||
action='store_true')
|
||||
args = parser.parse_args()
|
||||
|
||||
pathToHeader = args.target + '.h'
|
||||
@ -57,8 +62,8 @@ def main():
|
||||
conn.executescript(open(args.ddl).read())
|
||||
|
||||
# set vars
|
||||
toClassName = class_name_naming_func
|
||||
toMemberName = member_name_naming_func
|
||||
toClassName = identity_naming_func if args.identity_naming else class_name_naming_func
|
||||
toMemberName = identity_naming_func if args.identity_naming else member_name_naming_func
|
||||
DataTypeError = False
|
||||
|
||||
header = open(pathToHeader, 'w')
|
||||
@ -173,6 +178,9 @@ def get_include_guard_name(namespace, inputfile):
|
||||
val = re.sub("[^A-Za-z0-9]+", "_", namespace + '_' + os.path.basename(inputfile))
|
||||
return val.upper()
|
||||
|
||||
def identity_naming_func(s):
|
||||
return s
|
||||
|
||||
def repl_camel_case_func(m):
|
||||
if m.group(1) == '_':
|
||||
return m.group(2).upper()
|
||||
|
@ -22,11 +22,11 @@
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
include(FindPythonInterp)
|
||||
include(FindPython3)
|
||||
|
||||
if (${PYTHONINTERP_FOUND})
|
||||
if (${Python3_Interpreter_FOUND})
|
||||
execute_process(
|
||||
COMMAND ${PYTHON_EXECUTABLE} -c "import pyparsing"
|
||||
COMMAND ${Python3_EXECUTABLE} -c "import pyparsing"
|
||||
RESULT_VARIABLE PythonRESULT
|
||||
OUTPUT_VARIABLE PythonOUTPUT
|
||||
ERROR_VARIABLE PythonERROR
|
||||
@ -39,21 +39,21 @@ if (${PYTHONINTERP_FOUND})
|
||||
message(STATUS "Pyparsing is installed: Enabling ddl2cpp tests.")
|
||||
|
||||
add_test(NAME sqlpp11.test.ddl2cpp.bad_will_fail
|
||||
COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_LIST_DIR}/../scripts/ddl2cpp" -fail-on-parse
|
||||
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_LIST_DIR}/../scripts/ddl2cpp" -fail-on-parse
|
||||
"${CMAKE_CURRENT_LIST_DIR}/ddl2cpp_sample_bad.sql"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/fail"
|
||||
test)
|
||||
set_tests_properties(sqlpp11.test.ddl2cpp.bad_will_fail PROPERTIES WILL_FAIL 1)
|
||||
|
||||
add_test(NAME sqlpp11.test.ddl2cpp.bad_has_parse_error
|
||||
COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_LIST_DIR}/../scripts/ddl2cpp" -fail-on-parse
|
||||
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_LIST_DIR}/../scripts/ddl2cpp" -fail-on-parse
|
||||
"${CMAKE_CURRENT_LIST_DIR}/ddl2cpp_sample_bad.sql"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/fail"
|
||||
test)
|
||||
set_tests_properties(sqlpp11.test.ddl2cpp.bad_has_parse_error PROPERTIES PASS_REGULAR_EXPRESSION "Parsing error,.*")
|
||||
|
||||
add_test(NAME sqlpp11.test.ddl2cpp.good_succeeds
|
||||
COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_LIST_DIR}/../scripts/ddl2cpp" -fail-on-parse
|
||||
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_LIST_DIR}/../scripts/ddl2cpp" -fail-on-parse
|
||||
"${CMAKE_CURRENT_LIST_DIR}/ddl2cpp_sample_good.sql"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/fail"
|
||||
test)
|
||||
@ -67,7 +67,7 @@ if (${PYTHONINTERP_FOUND})
|
||||
endif()
|
||||
add_custom_command(
|
||||
OUTPUT "${sqlpp.test.generated.sample.include}.h"
|
||||
COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_LIST_DIR}/../scripts/ddl2cpp"
|
||||
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_LIST_DIR}/../scripts/ddl2cpp"
|
||||
${use_identity_naming}
|
||||
"${CMAKE_CURRENT_LIST_DIR}/ddl2cpp_sample_good.sql"
|
||||
"${sqlpp.test.generated.sample.include}"
|
||||
|
@ -31,18 +31,18 @@
|
||||
|
||||
SQLPP_ALIAS_PROVIDER(cheese)
|
||||
|
||||
int As(int, char* [])
|
||||
int As(int, char*[])
|
||||
{
|
||||
const auto foo = test::TabFoo{};
|
||||
const auto bar = test::TabBar{};
|
||||
|
||||
compare(__LINE__, foo.omega.as(cheese), "tab_foo.omega AS cheese");
|
||||
compare(__LINE__, (foo.omega + 17).as(cheese), "(tab_foo.omega+17) AS cheese");
|
||||
compare(__LINE__, (foo.omega - 17).as(cheese), "(tab_foo.omega-17) AS cheese");
|
||||
compare(__LINE__, (foo.omega - uint32_t(17)).as(cheese), "(tab_foo.omega-17) AS cheese");
|
||||
compare(__LINE__, (foo.omega - bar.alpha).as(cheese), "(tab_foo.omega-tab_bar.alpha) AS cheese");
|
||||
compare(__LINE__, (count(foo.omega) - bar.alpha).as(cheese), "(COUNT(tab_foo.omega)-tab_bar.alpha) AS cheese");
|
||||
compare(__LINE__, (count(foo.omega) - uint32_t(17)).as(cheese), "(COUNT(tab_foo.omega)-17) AS cheese");
|
||||
compare(__LINE__, (foo.omega - 17).as(cheese), "(tab_foo.omega - 17) AS cheese");
|
||||
compare(__LINE__, (foo.omega - uint32_t(17)).as(cheese), "(tab_foo.omega - 17) AS cheese");
|
||||
compare(__LINE__, (foo.omega - bar.alpha).as(cheese), "(tab_foo.omega - tab_bar.alpha) AS cheese");
|
||||
compare(__LINE__, (count(foo.omega) - bar.alpha).as(cheese), "(COUNT(tab_foo.omega) - tab_bar.alpha) AS cheese");
|
||||
compare(__LINE__, (count(foo.omega) - uint32_t(17)).as(cheese), "(COUNT(tab_foo.omega) - 17) AS cheese");
|
||||
|
||||
// Auto alias
|
||||
compare(__LINE__, select(max(bar.alpha)), "SELECT MAX(tab_bar.alpha) AS max_");
|
||||
|
@ -26,11 +26,13 @@ set(test_serializer_names
|
||||
As
|
||||
Blob
|
||||
CustomQuery
|
||||
DynamicWhere
|
||||
ForUpdate
|
||||
From
|
||||
In
|
||||
Insert
|
||||
TableAlias
|
||||
Over
|
||||
TableAlias
|
||||
Where
|
||||
)
|
||||
|
||||
@ -44,7 +46,7 @@ if (SQLPP11_TESTS_CXX_STD)
|
||||
set_property(TARGET sqlpp11_test_serializer PROPERTY CXX_STANDARD_REQUIRED yes)
|
||||
set_property(TARGET sqlpp11_test_serializer PROPERTY CXX_EXTENSIONS no)
|
||||
endif()
|
||||
|
||||
|
||||
foreach(test_serializer IN LISTS test_serializer_names)
|
||||
add_test(NAME sqlpp11.test_serializer.${test_serializer}
|
||||
COMMAND sqlpp11_test_serializer ${test_serializer}
|
||||
|
53
test_serializer/DynamicWhere.cpp
Normal file
53
test_serializer/DynamicWhere.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2019, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "compare.h"
|
||||
#include "Sample.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int DynamicWhere(int, char*[])
|
||||
{
|
||||
const auto bar = test::TabBar{};
|
||||
auto db = MockDb{};
|
||||
|
||||
compare(__LINE__, dynamic_where(db), "");
|
||||
compare(__LINE__, dynamic_where(db, bar.gamma), " WHERE tab_bar.gamma");
|
||||
|
||||
{
|
||||
auto statement = sqlpp::dynamic_where(db);
|
||||
statement.where.add(without_table_check(bar.gamma));
|
||||
compare(__LINE__, statement, " WHERE tab_bar.gamma");
|
||||
}
|
||||
|
||||
{
|
||||
auto statement = dynamic_where(db, bar.gamma);
|
||||
statement.where.add(without_table_check(bar.gamma));
|
||||
compare(__LINE__, statement, " WHERE tab_bar.gamma AND tab_bar.gamma");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
50
test_serializer/Over.cpp
Normal file
50
test_serializer/Over.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Roland Bock, MacDue
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "Sample.h"
|
||||
#include "compare.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
SQLPP_ALIAS_PROVIDER(dueutil)
|
||||
|
||||
int Over(int, char* []) {
|
||||
auto const foo = test::TabFoo{};
|
||||
|
||||
// no/auto alias (wrapped in select so alias is applied)
|
||||
compare(__LINE__, select(avg(foo.omega).over()), "SELECT AVG(tab_foo.omega) OVER() AS avg_");
|
||||
compare(__LINE__, select(count(foo.omega).over()), "SELECT COUNT(tab_foo.omega) OVER() AS count_");
|
||||
compare(__LINE__, select(max(foo.omega).over()), "SELECT MAX(tab_foo.omega) OVER() AS max_");
|
||||
compare(__LINE__, select(min(foo.omega).over()), "SELECT MIN(tab_foo.omega) OVER() AS min_");
|
||||
compare(__LINE__, select(sum(foo.omega).over()), "SELECT SUM(tab_foo.omega) OVER() AS sum_");
|
||||
|
||||
// alias
|
||||
compare(__LINE__, avg(foo.omega).over().as(dueutil), "AVG(tab_foo.omega) OVER() AS dueutil");
|
||||
compare(__LINE__, count(foo.omega).over().as(dueutil), "COUNT(tab_foo.omega) OVER() AS dueutil");
|
||||
compare(__LINE__, max(foo.omega).over().as(dueutil), "MAX(tab_foo.omega) OVER() AS dueutil");
|
||||
compare(__LINE__, min(foo.omega).over().as(dueutil), "MIN(tab_foo.omega) OVER() AS dueutil");
|
||||
compare(__LINE__, sum(foo.omega).over().as(dueutil), "SUM(tab_foo.omega) OVER() AS dueutil");
|
||||
|
||||
return 0;
|
||||
}
|
@ -42,9 +42,9 @@ namespace
|
||||
MockDb::_serializer_context_t printer = {};
|
||||
return serialize(sqlpp::value(false), printer).str();
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int Where(int, char* [])
|
||||
int Where(int, char*[])
|
||||
{
|
||||
const auto foo = test::TabFoo{};
|
||||
const auto bar = test::TabBar{};
|
||||
@ -53,6 +53,8 @@ int Where(int, char* [])
|
||||
compare(__LINE__, select(foo.omega).from(foo).unconditionally(), "SELECT tab_foo.omega FROM tab_foo");
|
||||
compare(__LINE__, remove_from(foo).unconditionally(), "DELETE FROM tab_foo");
|
||||
compare(__LINE__, update(foo).set(foo.omega = 42).unconditionally(), "UPDATE tab_foo SET omega=42");
|
||||
compare(__LINE__, update(foo).set(foo.omega = foo.omega - -1).unconditionally(),
|
||||
"UPDATE tab_foo SET omega=(tab_foo.omega - -1)");
|
||||
compare(__LINE__, where(sqlpp::value(true)), " WHERE " + getTrue());
|
||||
|
||||
// Never
|
||||
|
@ -256,7 +256,6 @@ namespace test
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
namespace TabDateTime_
|
||||
{
|
||||
struct ColDayPoint
|
||||
@ -303,7 +302,6 @@ namespace test
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::time_point, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
|
||||
struct ColTimeOfDay
|
||||
{
|
||||
struct _alias_t
|
||||
@ -333,7 +331,7 @@ namespace test
|
||||
{
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char _literal[] = "tab_time_point";
|
||||
static constexpr const char _literal[] = "tab_date_time";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template <typename T>
|
||||
struct _member_t
|
||||
|
@ -61,7 +61,7 @@ void print_row(Row const& row)
|
||||
std::cout << a << ", " << b << std::endl;
|
||||
}
|
||||
|
||||
int Select(int, char* [])
|
||||
int Select(int, char*[])
|
||||
{
|
||||
MockDb db = {};
|
||||
MockDb::_serializer_context_t printer = {};
|
||||
@ -107,11 +107,12 @@ int Select(int, char* [])
|
||||
std::cout << a << ", " << b << ", " << g << std::endl;
|
||||
}
|
||||
|
||||
for (const auto& row : db(select(all_of(t).as(t), t.gamma).from(t).where(t.alpha > 7).for_update()))
|
||||
for (const auto& row :
|
||||
db(select(all_of(t), t.gamma.as(t)).from(t).where(t.alpha > 7 and trim(t.beta) == "test").for_update()))
|
||||
{
|
||||
int64_t a = row.tabBar.alpha;
|
||||
const std::string b = row.tabBar.beta;
|
||||
const bool g = row.gamma;
|
||||
int64_t a = row.alpha;
|
||||
const std::string b = row.beta;
|
||||
const bool g = row.tabBar;
|
||||
std::cout << a << ", " << b << ", " << g << std::endl;
|
||||
}
|
||||
|
||||
@ -208,20 +209,19 @@ int Select(int, char* [])
|
||||
}
|
||||
|
||||
{
|
||||
auto transaction = start_transaction(db, sqlpp::isolation_level::read_committed);
|
||||
if (db._mock_data._last_isolation_level != sqlpp::isolation_level::read_committed)
|
||||
{
|
||||
std::cout << "Error: transaction isolation level does not match expected level" << std::endl;
|
||||
}
|
||||
|
||||
auto transaction = start_transaction(db, sqlpp::isolation_level::read_committed);
|
||||
if (db._mock_data._last_isolation_level != sqlpp::isolation_level::read_committed)
|
||||
{
|
||||
std::cout << "Error: transaction isolation level does not match expected level" << std::endl;
|
||||
}
|
||||
}
|
||||
db.set_default_isolation_level(sqlpp::isolation_level::read_uncommitted);
|
||||
{
|
||||
auto transaction = start_transaction(db);
|
||||
if (db._mock_data._last_isolation_level != sqlpp::isolation_level::read_uncommitted)
|
||||
{
|
||||
std::cout << "Error: transaction isolation level does not match default level" << std::endl;
|
||||
}
|
||||
auto transaction = start_transaction(db);
|
||||
if (db._mock_data._last_isolation_level != sqlpp::isolation_level::read_uncommitted)
|
||||
{
|
||||
std::cout << "Error: transaction isolation level does not match default level" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -39,9 +39,9 @@ namespace alias
|
||||
SQLPP_ALIAS_PROVIDER(b)
|
||||
SQLPP_ALIAS_PROVIDER(left)
|
||||
SQLPP_ALIAS_PROVIDER(right)
|
||||
}
|
||||
} // namespace alias
|
||||
|
||||
int SelectType(int, char* [])
|
||||
int SelectType(int, char*[])
|
||||
{
|
||||
MockDb db = {};
|
||||
MockDb::_serializer_context_t printer = {};
|
||||
@ -163,7 +163,8 @@ int SelectType(int, char* [])
|
||||
static_assert(sqlpp::is_integral_t<sqlpp::return_type_minus_t<T, sqlpp::integral>>::value, "type requirement");
|
||||
static_assert(sqlpp::is_integral_t<sqlpp::return_type_plus_t<T, sqlpp::integral>>::value, "type requirement");
|
||||
static_assert(sqlpp::is_integral_t<sqlpp::return_type_multiplies_t<T, sqlpp::integral>>::value, "type requirement");
|
||||
static_assert(sqlpp::is_integral_t<sqlpp::return_type_divides_t<T, sqlpp::integral>>::value, "type requirement");
|
||||
static_assert(sqlpp::is_floating_point_t<sqlpp::return_type_divides_t<T, sqlpp::integral>>::value,
|
||||
"type requirement");
|
||||
static_assert(sqlpp::is_integral_t<sqlpp::return_type_minus_t<sqlpp::integral, T>>::value, "type requirement");
|
||||
static_assert(sqlpp::is_integral_t<sqlpp::return_type_plus_t<sqlpp::integral, T>>::value, "type requirement");
|
||||
static_assert(sqlpp::is_integral_t<sqlpp::return_type_multiplies_t<sqlpp::integral, T>>::value, "type requirement");
|
||||
|
@ -66,6 +66,9 @@ int Update(int, char*[])
|
||||
auto values = [&t]() { return std::make_tuple(t.delta += t.alpha, t.beta = "no cake this time"); };
|
||||
|
||||
db(update(t).set(t.delta = sqlpp::verbatim<sqlpp::integer>("17+4")).unconditionally());
|
||||
db(update(t)
|
||||
.set(t.delta = sqlpp::verbatim<sqlpp::integer>("17+4"))
|
||||
.where(sqlpp::verbatim<sqlpp::text>("'hansi'") == "hansi"));
|
||||
db(update(t).set(t.delta = sqlpp::null).unconditionally());
|
||||
db(update(t).set(t.delta = sqlpp::default_value).unconditionally());
|
||||
|
||||
|
@ -55,5 +55,24 @@ int With(int, char*[])
|
||||
sqlpp::cte(b).as(select(t.alpha.as(a)).from(t).unconditionally().union_all(select(sqlpp::value(123).as(a))));
|
||||
db(with(c)(select(all_of(c)).from(c).unconditionally()));
|
||||
|
||||
// recursive CTE with join
|
||||
{
|
||||
const auto selectBase = select(t.alpha, t.delta).from(t).where(t.alpha > 17);
|
||||
const auto initialCte = ::sqlpp::cte(sqlpp::alias::a).as(selectBase);
|
||||
const auto recursiveCte = initialCte.union_all(
|
||||
select(t.alpha, t.delta).from(t.join(initialCte).on(t.alpha == initialCte.delta)).unconditionally());
|
||||
const auto query = with(recursiveCte)(select(recursiveCte.alpha).from(recursiveCte).unconditionally());
|
||||
|
||||
::MockDb::_serializer_context_t printer = {};
|
||||
const auto serializedQuery = serialize(query, printer).str();
|
||||
std::cout << serializedQuery << '\n';
|
||||
|
||||
auto db = MockDb{};
|
||||
for (const auto& row : db(query))
|
||||
{
|
||||
std::cout << row.alpha;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,10 +26,11 @@
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tab_foo
|
||||
(
|
||||
delta varchar(255),
|
||||
delta varchar(255) NOT NULL DEFAULT "",
|
||||
epsilon bigint,
|
||||
omega double,
|
||||
psi bigint UNSIGNED
|
||||
psi bigint UNSIGNED,
|
||||
book BLOB
|
||||
);
|
||||
|
||||
CREATE TABLE tab_bar
|
||||
@ -40,3 +41,10 @@ CREATE TABLE tab_bar
|
||||
delta int
|
||||
);
|
||||
|
||||
CREATE TABLE tab_date_time
|
||||
(
|
||||
col_day_point date,
|
||||
col_time_point datetime,
|
||||
col_time_of_day time
|
||||
);
|
||||
|
||||
|
73
wishlist.md
Normal file
73
wishlist.md
Normal file
@ -0,0 +1,73 @@
|
||||
If you want to help with the development of the library, you might want to consider one of these items:
|
||||
|
||||
# Better documentation
|
||||
The documentation in the Wiki is incomplete and outdated. It is also not part of source control, which makes it a bit harder to contribute.
|
||||
It might make sense to write a couple of markdown files here.
|
||||
|
||||
Throw in chapters of how to add features and how to write connector libraries.
|
||||
|
||||
## Better tests and examples
|
||||
Many of the current tests were born when the library was in infant state. Often they test implementation details. And they often just print stuff, instead of checking said stuff.
|
||||
|
||||
# Connectors
|
||||
## Merge stable connectors into sqlpp11
|
||||
Having all connector libraries in place, makes maintenance considerably simpler, see #174.
|
||||
It would also reduce the cognitive overhead for newcomers.
|
||||
|
||||
## New connectors
|
||||
There are a couple of connector libraries already. Here are some that have been requested in the past
|
||||
|
||||
- Sybase
|
||||
- Oracle
|
||||
- SQL Server
|
||||
- Google Spanner
|
||||
|
||||
## More special functions and types for connectors
|
||||
GROUP CONCAT or JSON support for mysql, for instance
|
||||
INSERT OR UPDATE for postgresl and mysql
|
||||
INSERT INTO ... SELECT ... for postgresql
|
||||
CREATE TABLE for all of them, including PPGEN
|
||||
|
||||
Exception types that carry more specific error information, e.g. the native error code, see #227
|
||||
|
||||
Find a way to handle column names that are keywords in the vendor's dialect, see #199
|
||||
|
||||
Handle specific data types, including JSON for the connectors.
|
||||
|
||||
More test cases for DDL files.
|
||||
|
||||
# EDSL features
|
||||
Multi-line insert in prepared statements, see #68
|
||||
|
||||
## optional std::optional support
|
||||
Instead of sqlpp::value_or_null, std::optional would be nice, see #238
|
||||
|
||||
## Converter to and from SQL to C++ structs, to allow for more ORM like code
|
||||
Assuming that you have converter functions from struct to sqlpp11 and back, we could have something like this:
|
||||
```C++
|
||||
struct Person;
|
||||
insert_into(tab).set(Person{});
|
||||
update(tab).set(Person{});
|
||||
for (const auto& person : db(select(Person{}).from(tab).unconditionally()))
|
||||
{
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
# Runtime improvements
|
||||
## Connection pools and caching interface
|
||||
In order to support high load scenarios,
|
||||
- connection pools (to avoid creating and destroying connections)
|
||||
- caching (hash the query and answer it from the cache for some time), see #86
|
||||
|
||||
## Async support
|
||||
Obtain results in an asynchronous fashion, see #35, for instance.
|
||||
|
||||
# Compile time improvements
|
||||
## Simplify code
|
||||
See Seventeenification talk. Some of the simplifications can be ported back easily.
|
||||
|
||||
## Suppress export of symbols
|
||||
Some compilers tend to export all the generated symbols, which is a bit annoying in case of template-heavy libraries like sqlpp11 (leads to larger files and longer compile/link/startup times, I believe).
|
||||
There are ways to suppress this in most compilers, afaik.
|
||||
|
Loading…
Reference in New Issue
Block a user