From daa672e6f0bba749c27b5fc16557c60a8b0425f1 Mon Sep 17 00:00:00 2001 From: rbock Date: Sat, 25 May 2019 14:04:44 +0200 Subject: [PATCH 01/19] Fix joins with CTEs --- include/sqlpp11/cte.h | 1 + include/sqlpp11/pre_join.h | 18 ++++++++++-------- tests/With.cpp | 19 +++++++++++++++++++ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/include/sqlpp11/cte.h b/include/sqlpp11/cte.h index 9b3d40d4..eaa1129e 100644 --- a/include/sqlpp11/cte.h +++ b/include/sqlpp11/cte.h @@ -163,6 +163,7 @@ namespace sqlpp { using _traits = make_traits; // FIXME: is table? really? using _nodes = detail::type_vector<>; + using _provided_tables = detail::type_set; using _required_ctes = detail::make_joined_set_t, detail::type_set>; using _parameters = parameters_of; diff --git a/include/sqlpp11/pre_join.h b/include/sqlpp11/pre_join.h index 15270b09..975b5042 100644 --- a/include/sqlpp11/pre_join.h +++ b/include/sqlpp11/pre_join.h @@ -30,6 +30,7 @@ #include #include #include +#include namespace sqlpp { @@ -154,7 +155,7 @@ namespace sqlpp auto join_impl(Check, Lhs lhs, Rhs rhs) -> inconsistent; template - auto join_impl(consistent_t, Lhs lhs, Rhs rhs) -> pre_join_t; + auto join_impl(consistent_t, Lhs lhs, Rhs rhs) -> pre_join_t, from_table_t>; template auto join_impl(Lhs lhs, Rhs rhs) -> decltype(join_impl(check_pre_join_t{}, lhs, rhs)); @@ -163,19 +164,19 @@ namespace sqlpp template auto join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl(lhs, rhs)) { - return {lhs, rhs}; + return {from_table(lhs), from_table(rhs)}; } template auto inner_join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl(lhs, rhs)) { - return {lhs, rhs}; + return {from_table(lhs), from_table(rhs)}; } template auto left_outer_join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl(lhs, rhs)) { - return {lhs, rhs}; + return {from_table(lhs), from_table(rhs)}; } template @@ -183,13 +184,13 @@ namespace sqlpp { check_pre_join_t{}; - return {lhs, rhs}; + return {from_table(lhs), from_table(rhs)}; } template auto outer_join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl(lhs, rhs)) { - return {lhs, rhs}; + return {from_table(lhs), from_table(rhs)}; } namespace detail @@ -202,13 +203,14 @@ namespace sqlpp -> join_t, on_t>; template - auto cross_join_impl(Lhs lhs, Rhs rhs) -> decltype(cross_join_impl(check_pre_join_t{}, lhs, rhs)); + auto cross_join_impl(Lhs lhs, Rhs rhs) + -> decltype(cross_join_impl(check_pre_join_t, from_table_t>{}, lhs, rhs)); } // namespace detail template auto cross_join(Lhs lhs, Rhs rhs) -> decltype(detail::cross_join_impl(lhs, rhs)) { - return {pre_join_t{lhs, rhs}, {}}; + return {pre_join_t, from_table_t>{from_table(lhs), from_table(rhs)}, {}}; } } // namespace sqlpp diff --git a/tests/With.cpp b/tests/With.cpp index dae27867..fbd2995f 100644 --- a/tests/With.cpp +++ b/tests/With.cpp @@ -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; } From a3970ceae9574abaa359a7a6c75308780007bf16 Mon Sep 17 00:00:00 2001 From: Brett Boston Date: Tue, 9 Jul 2019 16:09:54 -0400 Subject: [PATCH 02/19] Add -identity-naming argument from ddl2cpp to sqlite2cpp.py --- scripts/sqlite2cpp.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/scripts/sqlite2cpp.py b/scripts/sqlite2cpp.py index 71c5c5a8..c6f243c2 100644 --- a/scripts/sqlite2cpp.py +++ b/scripts/sqlite2cpp.py @@ -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() From 43ec2343c3b97ebe15039ea8a88458543c37ed32 Mon Sep 17 00:00:00 2001 From: rbock Date: Tue, 20 Aug 2019 10:31:54 +0200 Subject: [PATCH 03/19] Fix serialization of empty dynamic_where It was serialized with a dummy expression, which turned out to be problematic for some vendors, see #282 --- include/sqlpp11/where.h | 36 ++++++++++++++++++++-- test_serializer/CMakeLists.txt | 11 ++++--- test_serializer/DynamicWhere.cpp | 53 ++++++++++++++++++++++++++++++++ tests/Update.cpp | 3 ++ 4 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 test_serializer/DynamicWhere.cpp diff --git a/include/sqlpp11/where.h b/include/sqlpp11/where.h index d79d390e..2d7298d0 100644 --- a/include/sqlpp11/where.h +++ b/include/sqlpp11/where.h @@ -256,6 +256,10 @@ namespace sqlpp static_check_t::value, assert_where_dynamic_used_with_dynamic_statement_t>, check_where_t>; + template + using check_where_empty_dynamic_t = static_combined_check_t< + static_check_t::value, assert_where_dynamic_used_with_dynamic_statement_t>>; + // NO WHERE YET template struct no_where_t @@ -338,10 +342,11 @@ namespace sqlpp return _where_impl<_database_t>(Check{}, expression); } - auto dynamic_where() const -> _new_statement_t, - where_t<_database_t, boolean_operand>> + auto dynamic_where() const + -> _new_statement_t, where_t<_database_t, unconditional_t>> { - return dynamic_where(::sqlpp::value(true)); + return {static_cast&>(*this), + where_data_t<_database_t, unconditional_t>{unconditional_t{}}}; } private: @@ -378,6 +383,24 @@ namespace sqlpp } }; + template + struct serializer_t> + { + using _serialize_check = consistent_t; + using T = where_data_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 struct serializer_t> { @@ -403,6 +426,13 @@ namespace sqlpp return statement_t>().dynamic_where(std::forward(t)); } + template + auto dynamic_where(const Database & /*unused*/) + -> decltype(statement_t>().dynamic_where()) + { + return statement_t>().dynamic_where(); + } + inline auto unconditionally() -> decltype(statement_t>().unconditionally()) { return statement_t>().unconditionally(); diff --git a/test_serializer/CMakeLists.txt b/test_serializer/CMakeLists.txt index 2e20950c..0db89df9 100644 --- a/test_serializer/CMakeLists.txt +++ b/test_serializer/CMakeLists.txt @@ -26,12 +26,13 @@ set(test_serializer_names As Blob CustomQuery - ForUpdate - From - In - Insert + DynamicWhere + ForUpdate + From + In + Insert TableAlias - Where + Where ) create_test_sourcelist(test_serializer_sources test_serializer_main.cpp ${test_serializer_names}) diff --git a/test_serializer/DynamicWhere.cpp b/test_serializer/DynamicWhere.cpp new file mode 100644 index 00000000..3fa9b0dc --- /dev/null +++ b/test_serializer/DynamicWhere.cpp @@ -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 + +#include + +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; +} diff --git a/tests/Update.cpp b/tests/Update.cpp index 5f9a6345..fb4c522e 100644 --- a/tests/Update.cpp +++ b/tests/Update.cpp @@ -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("17+4")).unconditionally()); + db(update(t) + .set(t.delta = sqlpp::verbatim("17+4")) + .where(sqlpp::verbatim("'hansi'") == "hansi")); db(update(t).set(t.delta = sqlpp::null).unconditionally()); db(update(t).set(t.delta = sqlpp::default_value).unconditionally()); From 7f29a0b126d2b746359690ecaad4ac8c76175e0e Mon Sep 17 00:00:00 2001 From: rbock Date: Tue, 20 Aug 2019 18:32:16 +0200 Subject: [PATCH 04/19] Fix expressions for unsigned integral as suggested by @fraillt --- .../data_types/unsigned_integral/expression_operators.h | 8 ++++---- tests/SelectType.cpp | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/include/sqlpp11/data_types/unsigned_integral/expression_operators.h b/include/sqlpp11/data_types/unsigned_integral/expression_operators.h index b72ce3cb..49f2a2f4 100644 --- a/include/sqlpp11/data_types/unsigned_integral/expression_operators.h +++ b/include/sqlpp11/data_types/unsigned_integral/expression_operators.h @@ -48,14 +48,14 @@ namespace sqlpp struct return_type_plus> { using check = consistent_t; - using type = value_type_of>; + using type = plus_t, value_type_of>, wrap_operand_t>; }; template struct return_type_minus> { using check = consistent_t; - using type = value_type_of>; + using type = minus_t, value_type_of>, wrap_operand_t>; }; template @@ -69,14 +69,14 @@ namespace sqlpp struct return_type_multiplies> { using check = consistent_t; - using type = value_type_of>; + using type = multiplies_t, value_type_of>, wrap_operand_t>; }; template struct return_type_divides> { using check = consistent_t; - using type = value_type_of>; + using type = divides_t, wrap_operand_t>; }; template diff --git a/tests/SelectType.cpp b/tests/SelectType.cpp index f783ce15..e98febbb 100644 --- a/tests/SelectType.cpp +++ b/tests/SelectType.cpp @@ -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>::value, "type requirement"); static_assert(sqlpp::is_integral_t>::value, "type requirement"); static_assert(sqlpp::is_integral_t>::value, "type requirement"); - static_assert(sqlpp::is_integral_t>::value, "type requirement"); + static_assert(sqlpp::is_floating_point_t>::value, + "type requirement"); static_assert(sqlpp::is_integral_t>::value, "type requirement"); static_assert(sqlpp::is_integral_t>::value, "type requirement"); static_assert(sqlpp::is_integral_t>::value, "type requirement"); From 5f5d6117034aad8f0f513c160881a88107faf92e Mon Sep 17 00:00:00 2001 From: rbock Date: Tue, 20 Aug 2019 18:53:49 +0200 Subject: [PATCH 05/19] Add wishlist.md --- wishlist.md | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 wishlist.md diff --git a/wishlist.md b/wishlist.md new file mode 100644 index 00000000..45b5b5bf --- /dev/null +++ b/wishlist.md @@ -0,0 +1,70 @@ +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 +struct A; +insert_into(tab).set(A{}); +update(tab).set(A{}); +for (const auto& a : db(select(A{}).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. + From 4f9f001fbd692d3b1c045280f309b61d046e7783 Mon Sep 17 00:00:00 2001 From: Roland Bock Date: Tue, 20 Aug 2019 18:58:24 +0200 Subject: [PATCH 06/19] Fix some formatting in wish list --- wishlist.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/wishlist.md b/wishlist.md index 45b5b5bf..3d13d474 100644 --- a/wishlist.md +++ b/wishlist.md @@ -43,13 +43,16 @@ Multi-line insert in prepared statements, see #68 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 -struct A; -insert_into(tab).set(A{}); -update(tab).set(A{}); -for (const auto& a : db(select(A{}).from(tab).unconditionally())) +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 From 5b2b175b21ea64206aaf1295768c8b38f0ec57ab Mon Sep 17 00:00:00 2001 From: rbock Date: Wed, 28 Aug 2019 09:42:48 +0200 Subject: [PATCH 07/19] Remove aggregate attribute from `trim()` --- include/sqlpp11/trim.h | 6 ++---- tests/Select.cpp | 32 ++++++++++++++++---------------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/include/sqlpp11/trim.h b/include/sqlpp11/trim.h index 32c7a1e5..43b009a7 100644 --- a/include/sqlpp11/trim.h +++ b/include/sqlpp11/trim.h @@ -57,12 +57,11 @@ namespace sqlpp }; template - struct trim_t : public expression_operators, text>, - public alias_operators> + struct trim_t : public expression_operators, text>, public alias_operators> { using _traits = make_traits; - using _nodes = detail::type_vector; + using _nodes = detail::type_vector; using _can_be_null = can_be_null_t; using _is_aggregate_expression = std::false_type; @@ -94,7 +93,6 @@ namespace sqlpp context << ")"; return context; } - }; template diff --git a/tests/Select.cpp b/tests/Select.cpp index 90f25f70..0860479e 100644 --- a/tests/Select.cpp +++ b/tests/Select.cpp @@ -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; From 268c176d8a7668073a3f8e62b93c92782b60114e Mon Sep 17 00:00:00 2001 From: rbock Date: Sat, 5 Oct 2019 10:20:15 +0200 Subject: [PATCH 08/19] Adjust sample.sql and ddl2cpp to match Sample.h --- scripts/ddl2cpp | 1 + tests/Sample.h | 4 +--- tests/sample.sql | 12 ++++++++++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/scripts/ddl2cpp b/scripts/ddl2cpp index f4762a83..b7f7f84b 100755 --- a/scripts/ddl2cpp +++ b/scripts/ddl2cpp @@ -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', diff --git a/tests/Sample.h b/tests/Sample.h index cbb738fa..d0119149 100644 --- a/tests/Sample.h +++ b/tests/Sample.h @@ -256,7 +256,6 @@ namespace test }; }; }; - namespace TabDateTime_ { struct ColDayPoint @@ -303,7 +302,6 @@ namespace test }; using _traits = sqlpp::make_traits; }; - 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; template struct _member_t diff --git a/tests/sample.sql b/tests/sample.sql index f46f7dd7..5cdacab2 100644 --- a/tests/sample.sql +++ b/tests/sample.sql @@ -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 +); + From bb77cc14591c8f2dc4b40d09def57eb76ec95ae8 Mon Sep 17 00:00:00 2001 From: rbock Date: Wed, 9 Oct 2019 07:25:24 +0200 Subject: [PATCH 09/19] Fix missing space for operator- --- include/sqlpp11/expression_fwd.h | 12 +++++++++++- test_serializer/As.cpp | 12 ++++++------ test_serializer/Where.cpp | 6 ++++-- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/include/sqlpp11/expression_fwd.h b/include/sqlpp11/expression_fwd.h index 220ab439..a4b55700 100644 --- a/include/sqlpp11/expression_fwd.h +++ b/include/sqlpp11/expression_fwd.h @@ -98,7 +98,17 @@ namespace sqlpp struct minus { using _traits = make_traits; - 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 diff --git a/test_serializer/As.cpp b/test_serializer/As.cpp index 86352257..25f6783f 100644 --- a/test_serializer/As.cpp +++ b/test_serializer/As.cpp @@ -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_"); diff --git a/test_serializer/Where.cpp b/test_serializer/Where.cpp index ff369a99..6e568196 100644 --- a/test_serializer/Where.cpp +++ b/test_serializer/Where.cpp @@ -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 From c021c49b0b1eeafc09718c7d3facb3b713eb47e4 Mon Sep 17 00:00:00 2001 From: Uy Ha <8091245+uyha@users.noreply.github.com> Date: Mon, 14 Oct 2019 12:09:18 +0200 Subject: [PATCH 10/19] Use Python3 for test_scripts (#298) * Use Python3 for test_scripts * Update travis and cmake --- .travis.yml | 3 ++- test_scripts/CMakeLists.txt | 14 +++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9ec66b3f..07242b86 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 diff --git a/test_scripts/CMakeLists.txt b/test_scripts/CMakeLists.txt index f2f4c34f..0a8c2b46 100644 --- a/test_scripts/CMakeLists.txt +++ b/test_scripts/CMakeLists.txt @@ -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}" From 183a05156a4cd78fb8a418f8afd2fcea7f5c8b4e Mon Sep 17 00:00:00 2001 From: Sylvain Joubert Date: Thu, 6 Feb 2020 10:58:53 +0100 Subject: [PATCH 11/19] Add begin and end keywords in the reserved names to be escaped (#310) --- scripts/ddl2cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/ddl2cpp b/scripts/ddl2cpp index b7f7f84b..113a80a7 100755 --- a/scripts/ddl2cpp +++ b/scripts/ddl2cpp @@ -312,6 +312,8 @@ nsList = namespace.split('::') def escape_if_reserved(name): reserved_names = [ + 'BEGIN', + 'END', 'GROUP', 'ORDER', ] From c1c1626242acb4607136d458975e1a8b28a3d7df Mon Sep 17 00:00:00 2001 From: Sylvain Joubert Date: Sat, 8 Feb 2020 08:38:41 +0100 Subject: [PATCH 12/19] Make sure find_package(Sqlpp11) can be done multiple times (#306) It is expected that CMake packages can be found multiple times without errors. The target generated and defined by CMake, e.g. in a *Targets.cmake file have a similar guard. --- cmake/Sqlpp11Config.cmake | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/cmake/Sqlpp11Config.cmake b/cmake/Sqlpp11Config.cmake index 720fef2d..18ea9b1b 100644 --- a/cmake/Sqlpp11Config.cmake +++ b/cmake/Sqlpp11Config.cmake @@ -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) From e35785cab2dc0c1ac41e728730efc4534b94ecc8 Mon Sep 17 00:00:00 2001 From: NancyLi1013 Date: Wed, 12 Feb 2020 01:03:17 -0800 Subject: [PATCH 13/19] Add vcpkg installation instructions --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 6f7b64d3..5e04773c 100644 --- a/README.md +++ b/README.md @@ -165,6 +165,19 @@ 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. Basic usage: ------------- From 6d2b64eff9ecbed300cf8c7d2a50c5dd87ca7d71 Mon Sep 17 00:00:00 2001 From: NancyLi1013 <46708020+NancyLi1013@users.noreply.github.com> Date: Thu, 13 Feb 2020 23:16:26 +0800 Subject: [PATCH 14/19] Update vcpkg installation instructions (#314) * Update vcpkg installation instructions * Update --- README.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 5e04773c..a2ae3ffd 100644 --- a/README.md +++ b/README.md @@ -169,16 +169,21 @@ __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 - ``` +```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: ------------- From a51b6da3bdb90f031741dc82ea1a3f69b07501c5 Mon Sep 17 00:00:00 2001 From: MacDue <11597044+MacDue@users.noreply.github.com> Date: Sat, 15 Feb 2020 06:54:22 +0000 Subject: [PATCH 15/19] Minimal over() implementation for aggregate functions (#316) * Minimal over() implementation for aggregate functions * auto_alias support for over() * add missing typename * Test .over() serialization * Add missing return to test * Fix testing over auto alias Co-authored-by: Ben Maxwell <42680490+MaciumDue@users.noreply.github.com> --- .../sqlpp11/aggregate_function_operators.h | 42 +++++++++++ include/sqlpp11/aggregate_functions/avg.h | 3 +- include/sqlpp11/aggregate_functions/count.h | 5 +- include/sqlpp11/aggregate_functions/max.h | 6 +- include/sqlpp11/aggregate_functions/min.h | 6 +- include/sqlpp11/aggregate_functions/sum.h | 3 +- include/sqlpp11/over.h | 73 +++++++++++++++++++ test_serializer/CMakeLists.txt | 15 ++-- test_serializer/Over.cpp | 50 +++++++++++++ 9 files changed, 189 insertions(+), 14 deletions(-) create mode 100644 include/sqlpp11/aggregate_function_operators.h create mode 100644 include/sqlpp11/over.h create mode 100644 test_serializer/Over.cpp diff --git a/include/sqlpp11/aggregate_function_operators.h b/include/sqlpp11/aggregate_function_operators.h new file mode 100644 index 00000000..6e92ad4c --- /dev/null +++ b/include/sqlpp11/aggregate_function_operators.h @@ -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 + struct aggregate_function_operators + { + over_t over() const + { + return {*static_cast(this)}; + } + }; +} // namespace sqlpp + +#endif + diff --git a/include/sqlpp11/aggregate_functions/avg.h b/include/sqlpp11/aggregate_functions/avg.h index a9df9e62..f34ac297 100644 --- a/include/sqlpp11/aggregate_functions/avg.h +++ b/include/sqlpp11/aggregate_functions/avg.h @@ -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 struct avg_t : public expression_operators, floating_point>, + public aggregate_function_operators>, public alias_operators> { using _traits = make_traits; diff --git a/include/sqlpp11/aggregate_functions/count.h b/include/sqlpp11/aggregate_functions/count.h index 79d96e52..91f7a830 100644 --- a/include/sqlpp11/aggregate_functions/count.h +++ b/include/sqlpp11/aggregate_functions/count.h @@ -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 #include #include +#include #include namespace sqlpp @@ -57,6 +59,7 @@ namespace sqlpp template struct count_t : public expression_operators, integral>, + public aggregate_function_operators>, public alias_operators> { using _traits = make_traits; diff --git a/include/sqlpp11/aggregate_functions/max.h b/include/sqlpp11/aggregate_functions/max.h index 16faaa47..1c601809 100644 --- a/include/sqlpp11/aggregate_functions/max.h +++ b/include/sqlpp11/aggregate_functions/max.h @@ -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 - struct max_t : public expression_operators, value_type_of>, public alias_operators> + struct max_t : public expression_operators, value_type_of>, + public aggregate_function_operators>, + public alias_operators> { using _traits = make_traits, tag::is_expression, tag::is_selectable>; using _nodes = detail::type_vector; diff --git a/include/sqlpp11/aggregate_functions/min.h b/include/sqlpp11/aggregate_functions/min.h index 37604e03..54b663c8 100644 --- a/include/sqlpp11/aggregate_functions/min.h +++ b/include/sqlpp11/aggregate_functions/min.h @@ -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 - struct min_t : public expression_operators, value_type_of>, public alias_operators> + struct min_t : public expression_operators, value_type_of>, + public aggregate_function_operators>, + public alias_operators> { using _traits = make_traits, tag::is_expression, tag::is_selectable>; using _nodes = detail::type_vector; diff --git a/include/sqlpp11/aggregate_functions/sum.h b/include/sqlpp11/aggregate_functions/sum.h index 67428472..33396c28 100644 --- a/include/sqlpp11/aggregate_functions/sum.h +++ b/include/sqlpp11/aggregate_functions/sum.h @@ -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 struct sum_t : public expression_operators, value_type_of>, + public aggregate_function_operators>, public alias_operators> { using _traits = make_traits, tag::is_expression, tag::is_selectable>; diff --git a/include/sqlpp11/over.h b/include/sqlpp11/over.h new file mode 100644 index 00000000..6a598e1e --- /dev/null +++ b/include/sqlpp11/over.h @@ -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 +#include + +namespace sqlpp +{ + template + struct over_t : public expression_operators, integral>, + public alias_operators> + { + using _traits = make_traits; + using _nodes = detail::type_vector; + + 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 + struct serializer_t> + { + using _serialize_check = serialize_check_of; + using T = over_t; + + static Context& _(const T& t, Context& context) + { + serialize_operand(t._aggregate_expression, context); + context << " OVER()"; + return context; + } + }; +} // namespace sqlpp + +#endif diff --git a/test_serializer/CMakeLists.txt b/test_serializer/CMakeLists.txt index 0db89df9..b17c83ef 100644 --- a/test_serializer/CMakeLists.txt +++ b/test_serializer/CMakeLists.txt @@ -27,12 +27,13 @@ set(test_serializer_names Blob CustomQuery DynamicWhere - ForUpdate - From - In - Insert - TableAlias - Where + ForUpdate + From + In + Insert + Over + TableAlias + Where ) create_test_sourcelist(test_serializer_sources test_serializer_main.cpp ${test_serializer_names}) @@ -45,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} diff --git a/test_serializer/Over.cpp b/test_serializer/Over.cpp new file mode 100644 index 00000000..c1afb69e --- /dev/null +++ b/test_serializer/Over.cpp @@ -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 + +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; +} From 73df6df867d3f4d0657c1262fb9ecada7b22684a Mon Sep 17 00:00:00 2001 From: MacDue Date: Tue, 14 Jan 2020 12:50:53 +0000 Subject: [PATCH 16/19] Make connection pool useable --- include/sqlpp11/connection_pool.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/sqlpp11/connection_pool.h b/include/sqlpp11/connection_pool.h index c63141ba..14e4e81b 100644 --- a/include/sqlpp11/connection_pool.h +++ b/include/sqlpp11/connection_pool.h @@ -183,7 +183,7 @@ namespace sqlpp try { - auto c = std::unique_ptr(new Connection(*(config.get()))); + auto c = std::unique_ptr(new Connection(config)); return pool_connection(c, this); } catch (const sqlpp::exception& e) From cd20805b3e7c2fc7bae5cb173cf2649fa53776b1 Mon Sep 17 00:00:00 2001 From: faizol Date: Tue, 5 May 2020 14:58:56 +0800 Subject: [PATCH 17/19] update for gcc10 compilation --- include/sqlpp11/data_types/blob/data_type.h | 1 + include/sqlpp11/detail/type_set.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/sqlpp11/data_types/blob/data_type.h b/include/sqlpp11/data_types/blob/data_type.h index c0137507..2758a761 100644 --- a/include/sqlpp11/data_types/blob/data_type.h +++ b/include/sqlpp11/data_types/blob/data_type.h @@ -28,6 +28,7 @@ #define SQLPP_BLOB_DATA_TYPE_H #include +#include #include #include diff --git a/include/sqlpp11/detail/type_set.h b/include/sqlpp11/detail/type_set.h index f5788354..20672678 100644 --- a/include/sqlpp11/detail/type_set.h +++ b/include/sqlpp11/detail/type_set.h @@ -60,7 +60,7 @@ namespace sqlpp }; public: - using size = std::integral_constant; + using size = std::integral_constant; using _is_type_set = std::true_type; template From b336346467ab6fc0ca8e132300d9cc61ed6eb00b Mon Sep 17 00:00:00 2001 From: faizol Date: Wed, 6 May 2020 02:09:33 +0800 Subject: [PATCH 18/19] changed type_set.h to use cstddef so that size_t would be consistent across the library --- include/sqlpp11/detail/type_set.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/sqlpp11/detail/type_set.h b/include/sqlpp11/detail/type_set.h index 20672678..efab4da5 100644 --- a/include/sqlpp11/detail/type_set.h +++ b/include/sqlpp11/detail/type_set.h @@ -28,6 +28,7 @@ #define SQLPP11_DETAIL_TYPE_SET_H #include +#include #include #include @@ -60,7 +61,7 @@ namespace sqlpp }; public: - using size = std::integral_constant; + using size = std::integral_constant; using _is_type_set = std::true_type; template From 23cb8f4c869fbf961e50ca1c5be007cd074ee91a Mon Sep 17 00:00:00 2001 From: faizol Date: Wed, 6 May 2020 03:27:15 +0800 Subject: [PATCH 19/19] changed header to use stddef.h --- include/sqlpp11/detail/type_set.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/sqlpp11/detail/type_set.h b/include/sqlpp11/detail/type_set.h index efab4da5..343f3bcd 100644 --- a/include/sqlpp11/detail/type_set.h +++ b/include/sqlpp11/detail/type_set.h @@ -28,7 +28,7 @@ #define SQLPP11_DETAIL_TYPE_SET_H #include -#include +#include #include #include