feat/support_orm (#2)
All checks were successful
rpcrypto-build / build (Release, hisiv510.toolchain.cmake) (push) Successful in 1m24s
rpcrypto-build / build (Debug, himix200.toolchain.cmake) (push) Successful in 1m30s
rpcrypto-build / build (Debug, hisiv510.toolchain.cmake) (push) Successful in 1m43s
linux-mips64-gcc / linux-gcc-mips64el (push) Successful in 1m47s
linux-x64-gcc / linux-gcc (push) Successful in 2m11s
rpcrypto-build / build (Release, himix200.toolchain.cmake) (push) Successful in 3m19s
linux-hisiv500-gcc / linux-gcc-hisiv500 (push) Successful in 3m39s

Co-authored-by: tqcq <99722391+tqcq@users.noreply.github.com>
Reviewed-on: #2
This commit is contained in:
tqcq 2024-01-06 13:56:45 +00:00
parent aba94bb9eb
commit 99c258107b
554 changed files with 52720 additions and 5 deletions

4
.gitmodules vendored
View File

@ -2,7 +2,3 @@
path = 3party/googletest
url = https://code.uocat.com/3party/googletest
branch = release-1.7.0
[submodule "3party/sqlpp11"]
path = 3party/sqlpp11
url = https://code.uocat.com/3party/sqlpp11
branch = 0.64

@ -1 +0,0 @@
Subproject commit 7f04435576036fc3f06d929760b5c7623485f069

View File

@ -0,0 +1,31 @@
os:
- Visual Studio 2015
- Visual Studio 2017
platform:
- x64
configuration:
#- Debug
- Release
matrix:
fast_finish: true
build_script:
- CD
- cd ..
- CD
- git clone https://github.com/HowardHinnant/date
- cd date
- git checkout tags/v2.4
- cd ..
- cd sqlpp11
- CD
- echo %configuration%
- mkdir build
- cd build
- cmake --version
- cmake .. -DCMAKE_CXX_FLAGS="/EHsc /wd4503" -DCMAKE_PREFIX_PATH="C:\projects\date"
- cmake --build . --config %configuration%
- ctest . --build-config %configuration% --output-on-failure

View File

@ -0,0 +1,54 @@
Language: Cpp
AccessModifierOffset: -2
ConstructorInitializerIndentWidth: 4
AlignEscapedNewlinesLeft: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AlwaysBreakTemplateDeclarations: true
AlwaysBreakBeforeMultilineStrings: false
BreakBeforeBinaryOperators: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BinPackParameters: false
ColumnLimit: 120
ConstructorInitializerAllOnOneLineOrOnePerLine: true
DerivePointerAlignment: false
ExperimentalAutoDetectBinPacking: false
IndentCaseLabels: true
IndentWrappedFunctionNames: false
IndentFunctionDeclarationAfterType: false
MaxEmptyLinesToKeep: 1
KeepEmptyLinesAtTheStartOfBlocks: false
NamespaceIndentation: All
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: false
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakString: 1000
PenaltyBreakFirstLessLess: 120
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
SpacesBeforeTrailingComments: 2
Cpp11BracedListStyle: true
Standard: Cpp11
IndentWidth: 2
TabWidth: 2
UseTab: Never
BreakBeforeBraces: Allman
SpacesInParentheses: false
SpacesInAngles: false
SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: true
SpaceBeforeAssignmentOperators: true
ContinuationIndentWidth: 4
CommentPragmas: '^ IWYU pragma:'
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
SpaceBeforeParens: ControlStatements
DisableFormat: false
SortIncludes: false

2
3party/sqlpp11/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.idea
CMakeLists.txt.user

View File

@ -0,0 +1,45 @@
language: cpp
os:
- linux
dist: focal
sudo: required
services:
- mysql
addons:
apt:
packages:
- sqlite3
- libboost-dev
- python-pyparsing
compiler:
- clang
- gcc
env:
- CONFIG=Release
- CONFIG=Release TESTS_CXX_STD=17
#- CONFIG=Debug
notifications:
email:
on_success: change
on_failure: always
before_script:
- mysql --version
- (while ! mysqladmin -u root status ; do sleep 1; done) # wait for mysql to start
- mysqladmin -u root create sqlpp_mysql
- if [[ "$CXX" = "g++" && "$CONFIG" = "Debug" && "$TRAVIS_OS_NAME" = "linux" ]]; then export CXXFLAGS="--coverage"; fi
- cmake -B build -DCMAKE_BUILD_TYPE=$CONFIG -DBUILD_MYSQL_CONNECTOR=ON -DBUILD_SQLITE3_CONNECTOR=ON
script:
- cmake --build . --config $CONFIG
- ctest --output-on-failure
after_script:
- ../coveralls

View File

@ -0,0 +1,166 @@
# Copyright (c) 2013-2021, Roland Bock
# Copyright (c) 2016 Christian Dávid
# 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.
### Preamble
cmake_minimum_required(VERSION 3.14)
project(sqlpp11 VERSION 0.1 LANGUAGES CXX)
### Project Wide Setup
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/modules)
include(GNUInstallDirs)
include(CTest)
option(BUILD_MYSQL_CONNECTOR "Build MySQL Connector" OFF)
option(BUILD_MARIADB_CONNECTOR "Build MariaDB Connector" OFF)
option(BUILD_POSTGRESQL_CONNECTOR "Build PostgreSQL Connector" OFF)
option(BUILD_SQLITE3_CONNECTOR "Build SQLite3 Connector" OFF)
option(BUILD_SQLCIPHER_CONNECTOR "Build SQLite3 Connector with SQLCipher" OFF)
option(DEPENDENCY_CHECK "Check for dependencies of connector and the library" ON)
option(USE_SYSTEM_DATE "\
Use find_package to find installed HowardHinnant's \
date library instead of fetching it from github" OFF
)
set(SQLPP11_INSTALL_CMAKEDIR ${CMAKE_INSTALL_LIBDIR}/cmake/Sqlpp11 CACHE STRING "Path to sqlpp11 cmake files")
### Dependencies
if(DEPENDENCY_CHECK AND BUILD_MYSQL_CONNECTOR)
find_package(MySQL REQUIRED)
endif()
if(DEPENDENCY_CHECK AND BUILD_MARIADB_CONNECTOR)
find_package(MariaDB REQUIRED)
endif()
if(DEPENDENCY_CHECK AND BUILD_POSTGRESQL_CONNECTOR)
find_package(PostgreSQL REQUIRED)
endif()
if(DEPENDENCY_CHECK AND BUILD_SQLITE3_CONNECTOR)
find_package(SQLite3 REQUIRED)
endif()
if(DEPENDENCY_CHECK AND BUILD_SQLCIPHER_CONNECTOR)
find_package(SQLCipher REQUIRED)
endif()
if(DEPENDENCY_CHECK AND USE_SYSTEM_DATE)
find_package(date REQUIRED)
endif()
add_subdirectory(dependencies)
### Core targets
include(Sqlpp11TargetHelper)
add_library(sqlpp11 INTERFACE)
add_library(sqlpp11::sqlpp11 ALIAS sqlpp11)
target_link_libraries(sqlpp11 INTERFACE date::date)
target_include_directories(sqlpp11 INTERFACE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
)
target_compile_features(sqlpp11 INTERFACE cxx_std_11)
if(BUILD_SQLITE3_CONNECTOR)
add_component(NAME sqlite3 DEPENDENCIES SQLite::SQLite3)
endif()
if(BUILD_SQLCIPHER_CONNECTOR)
add_component(NAME sqlcipher DEPENDENCIES SQLCipher::SQLCipher)
target_compile_definitions(sqlpp11_sqlcipher INTERFACE SQLPP_USE_SQLCIPHER)
endif()
if(BUILD_MYSQL_CONNECTOR)
add_component(NAME mysql DEPENDENCIES MySQL::MySQL)
endif()
if(BUILD_MARIADB_CONNECTOR)
add_component(NAME mariadb DEPENDENCIES MariaDB::MariaDB)
endif()
if(BUILD_POSTGRESQL_CONNECTOR)
add_component(NAME postgresql DEPENDENCIES PostgreSQL::PostgreSQL)
endif()
### Packaging
install(PROGRAMS ${PROJECT_SOURCE_DIR}/scripts/ddl2cpp
RENAME sqlpp11-ddl2cpp
DESTINATION ${CMAKE_INSTALL_BINDIR}
)
write_basic_package_version_file(Sqlpp11ConfigVersion.cmake
COMPATIBILITY SameMajorVersion
ARCH_INDEPENDENT
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Sqlpp11ConfigVersion.cmake
DESTINATION ${SQLPP11_INSTALL_CMAKEDIR}
)
install_component(NAME Sqlpp11 TARGETS sqlpp11 DIRECTORY)
if(BUILD_SQLITE3_CONNECTOR)
install_component(NAME Sqlpp11SQLite3 TARGETS sqlpp11_sqlite3 DIRECTORY sqlite3)
endif()
if(BUILD_SQLCIPHER_CONNECTOR)
install_component(NAME Sqlpp11SQLCipher TARGETS sqlpp11_sqlcipher DIRECTORY sqlite3)
install(FILES ${PROJECT_SOURCE_DIR}/cmake/modules/FindSQLCipher.cmake
DESTINATION ${SQLPP11_INSTALL_CMAKEDIR}
)
endif()
if(BUILD_MYSQL_CONNECTOR)
install_component(NAME Sqlpp11MySQL TARGETS sqlpp11_mysql DIRECTORY mysql)
install(FILES ${PROJECT_SOURCE_DIR}/cmake/modules/FindMySQL.cmake
DESTINATION ${SQLPP11_INSTALL_CMAKEDIR}
)
endif()
if(BUILD_MARIADB_CONNECTOR)
install_component(NAME Sqlpp11MariaDB TARGETS sqlpp11_mariadb DIRECTORY mysql)
install(FILES ${PROJECT_SOURCE_DIR}/cmake/modules/FindMariaDB.cmake
DESTINATION ${SQLPP11_INSTALL_CMAKEDIR}
)
endif()
if(BUILD_POSTGRESQL_CONNECTOR)
install_component(NAME Sqlpp11PostgreSQL TARGETS sqlpp11_postgresql DIRECTORY postgresql)
endif()
### Tests
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING)
add_subdirectory(tests)
endif()

19
3party/sqlpp11/CREDITS Normal file
View File

@ -0,0 +1,19 @@
Credits:
========
This library evolved through several stages and would probably not exist without input from other people:
* Michael Gmelin: Interface and requirements discussions
* Paul Körbitz: Feedback and extensions
* Peter Knoblach: Initial ideas
* Ulrich Küttler: Feedback and extensions
* Daniel Pfeifer: Buildsystem, Travis, Coveralls
* Metafeed GmbH: Production code using a forerunner version
* PPRO Financial Ltd: Production code using sqlpp11 and a forerunner version
* The boost community: Invaluable suggestions and critiques
* Meeting C++ Munich: Hosted the first talk about sqlpp11
If you miss your name of this list, please let me know.

109
3party/sqlpp11/ChangeLog.md Normal file
View File

@ -0,0 +1,109 @@
Important changes in sqlpp11
============================
Breaking changes in 0.36:
-------------------------
__Abstract__:
One of the main motivations of sqlpp11 is to prevent SQL programming mistakes at compile time. The following changes prevent reported mishaps.
* `from(a,b)` not allowed anymore, please use explicit joins
* `where(true)` not allowed anymore, please use `.unconditionally()` or sqlpp::value(true)
* `some_sql_expression and true` not allowed anymore, please use `tab.col == sqlpp::value(true)` if you really want to express this.
* `having(expression)` requires `expression` to be made of aggregates, e.g. columns named in `group_by()` or aggregate functions like `count()` or constant values.
* `where()` and `having` accept only one parameter
__Explicit joins required__:
Up until sqlpp11-0.35 you could write something like
```
auto result = db(select(all_of(a), all_of(b))
.from(a,b)
.where(someCondition));
```
Using this syntax in `from()`, it was expected to have the join condition implicitly in the `where()` call.
But there is no reliable way to tell whether or not that condition is there. Or, if there definitely is none, whether
it was omitted on purpose or by accident.
In one case, an accidentally omitted join condition in the `where()` brought a production system to a screeching halt.
In order to prevent this in the future, sqlpp11 now requires you to join table explicitly, including an explicit join condition, e.g.
```
auto result = db(select(all_of(a), all_of(b))
.from(a.join(b).on(a.b == b.id))
.where(someCondition));
```
Most joins, (`join`/`inner_join`, `left_outer_join`, `right_outer_join` and `outer_join`) require a join condition to given via `on()`.
The join condition has to be some sqlpp11 boolean expression.
In those rare cases, when you really need a cross join, you can also use `cross_join()` which has no join condition, of course.
```
auto result = db(select(all_of(a), all_of(b))
.from(a.cross_join(b))
.where(someCondition));
```
__Use `.unconditionally()`__
If you want to select/update/remove all rows, earlier versions of sqlpp11 required the use of `where(true)`. Since version 0.36, use `unconditionally()`, for instance:
```
auto result = db(select(all_of(t)).from(t).unconditionally());
```
__Use `sqlpp::value()` to wrap bool values in boolean expressions__
Lets say you had
```
struct X
{
int a;
int b;
};
auto x = X{};
```
Then earlier versions of sqlpp11 would compile the following expression:
```
select(all_of(t)).from(t).where(x.a == x.a or t.b == t.b);
```
What you probably meant was:
```
select(all_of(t)).from(t).where(t.a == x.a and t.b == x.b);
```
In order to prevent this kind of mistake, boolean operators in sql expressions require sqlpp boolean expressions as operators.
The library also requires the types of the left/right hand side operands of a comparison to be different, so that `t.a < t.a` does not compile any more.
In the rare case you really have a bool value that you want to use a boolean sql expression, you have to wrap it in sqlpp::value(x), e.g.
```
select(all_of(t)).from(t).where(sqlpp::value(x.a == 17) and t.b == x.b);
```
__`having()` requires aggregate expressions__
In older versions, the following code was allowed:
```
select(all_of(t)).from(t).where(t.a > 7).having(t.b != "");
```
As of sqlpp11-0.36, the having argument must be made of aggregate columns or functions, e.g.
```
select(all_of(t)).from(t).unconditionally().group_by(t.b).having(t.b != "", avg(t.c) < 42);
```
__`where()` and `having` accept only one expression__
In older versions, `where()` and `having()` would accept more than one argument and combine those arguments with `and`.
I am not sure this was ever used. So it just made life harder for the compiler.
As of version 0.36, `where()` and `having()` accept only one parameter.

23
3party/sqlpp11/LICENSE Normal file
View File

@ -0,0 +1,23 @@
Copyright (c) 2013-2016, 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:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. 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.

287
3party/sqlpp11/README.md Normal file
View File

@ -0,0 +1,287 @@
sqlpp11
=======
A type safe embedded domain specific language for SQL queries and results in C++.
```diff
!If you are a tenured user of sqlpp11, please note that
! - with 0.61 the connector libraries for mysql/sqlite/postgresql got merged into the main repo.
! - master has been renamed to main and is now the default branch
```
Documentation is found in [docs](docs/Home.md).
So what is this about?
----------------------
SQL and C++ are both strongly typed languages. Still, most C/C++ interfaces to SQL are based on constructing queries as strings and on interpreting arrays or maps of strings as results.
sqlpp11 is a templated library representing an embedded domain specific language (EDSL) that allows you to
* define types representing tables and columns,
* construct type safe queries checked at compile time for syntax errors, type errors, name errors and even some semantic errors,
* interpret results by iterating over query-specific structs with appropriately named and typed members.
This results in several benefits, e.g.
* the library user operates comfortably on structs and functions,
* the compiler reports many kinds of errors long before the code enters unit testing or production,
* the library hides the gory details of string construction for queries and interpreting results returned by select calls.
The library supports both static and dynamic queries. The former offers greater benefit in terms of type and consistency checking. The latter makes it easier to construct queries in flight.
sqlpp11s core is vendor-neutral.
Specific traits of databases (e.g. unsupported or non-standard features) are handled by connector libraries.
Connector libraries can inform the developer of missing features at compile time.
They also interpret expressions specifically where needed.
For example, the connector could use the operator|| or the concat method for string concatenation without the developer being required to change the statement.
Connectors for MariaDB, MySQL, PostgreSQL, sqlite3, sqlcipher are included in this repository.
The library is already used in production but it is certainly not complete yet. Feature requests, bug reports, contributions to code or documentation are most welcome.
Examples:
---------
For the examples, lets assume you have a table class representing something like
```SQL
CREATE TABLE foo (
id bigint,
name varchar(50),
hasFun bool
);
```
And we assume to have a database connection object:
```C++
TabFoo foo;
Db db(/* some arguments*/);
// selecting zero or more results, iterating over the results
for (const auto& row : db(select(foo.name, foo.hasFun).from(foo).where(foo.id > 17 and foo.name.like("%bar%"))))
{
if (row.name.is_null())
std::cerr << "name is null, will convert to empty string" << std::endl;
std::string name = row.name; // string-like fields are implicitly convertible to string
bool hasFun = row.hasFun; // bool fields are implicitly convertible to bool
}
// selecting ALL columns of a table
for (const auto& row : db(select(all_of(foo)).from(foo).where(foo.hasFun or foo.name == "joker")))
{
int64_t id = row.id; // numeric fields are implicitly convertible to numeric c++ types
}
// selecting zero or one row, showing off with an alias:
SQLPP_ALIAS_PROVIDER(cheese);
if (const auto& row = db(select(foo.name.as(cheese)).from(foo).where(foo.id == 17)))
{
std::cerr << "found: " << row.cheese << std::endl;
}
// selecting a single row with a single result:
return db(select(count(foo.id)).from(foo).unconditionally()).front().count;
Of course there are joins and subqueries, more functions, order_by, group_by etc.
These will be documented soon.
// A sample insert
db(insert_into(foo).set(foo.id = 17, foo.name = "bar", foo.hasFun = true));
// A sample update
db(update(foo).set(foo.hasFun = not foo.hasFun).where(foo.name != "nobody"));
// A sample delete
db(remove_from(foo).where(not foo.hasFun));
```
License:
-------------
sqlpp11 is distributed under the [BSD 2-Clause License](https://github.com/rbock/sqlpp11/blob/master/LICENSE).
Status:
-------
Branch / Compiler | clang, gcc | MSVC | Test Coverage
------------------|-------------|--------|---------------
master | [![Build Status](https://travis-ci.com/rbock/sqlpp11.svg?branch=master)](https://travis-ci.com/rbock/sqlpp11?branch=master) | [![Build status](https://ci.appveyor.com/api/projects/status/eid7mwqgavo0h61h/branch/master?svg=true)](https://ci.appveyor.com/project/rbock/sqlpp11/branch/master) | [![Coverage Status](https://coveralls.io/repos/rbock/sqlpp11/badge.svg?branch=master)](https://coveralls.io/r/rbock/sqlpp11?branch=master)
develop | [![Build Status](https://travis-ci.com/rbock/sqlpp11.svg?branch=develop)](https://travis-ci.com/rbock/sqlpp11?branch=develop) | [![Build status](https://ci.appveyor.com/api/projects/status/eid7mwqgavo0h61h/branch/develop?svg=true)](https://ci.appveyor.com/project/rbock/sqlpp11/branch/develop) | [![Coverage Status](https://coveralls.io/repos/rbock/sqlpp11/badge.svg?branch=develop)](https://coveralls.io/r/rbock/sqlpp11?branch=develop)
Additional information available:
---------------------------------
Past talks about sqlpp11 and some coding concepts used within the library:
* [CppCast:](http://cppcast.com)
* 2015-05-07: http://cppcast.com/2015/05/roland-bock/
* [CppCon:](http://cppcon.org)
* 2015-09-24: [Pruning Error Messages From Your C++ Template Code](https://www.youtube.com/watch?v=2ISqFW9fRws), with examples from sqlpp11
* 2014-09-11: [sqlpp11, An SQL Library Worthy Of Modern C++](https://www.youtube.com/watch?v=cJPAjhBm-HQ)
* [Meeting C++:](http://meetingcpp.com)
* 2014-12-05: [sqlpp11, An EDSL For Type-Safe SQL In C++11](https://www.youtube.com/watch?v=9Hjfg9IfzhU)
* [MUC++:](http://www.meetup.com/MUCplusplus/)
* 2014-02-27: [Selected C++11 Template Toffees From sqlpp11, Part1](https://www.youtube.com/watch?v=hXnGFYNbmXg), [Part2](https://www.youtube.com/watch?v=WPCV6dvxZ_U), [Part 3](https://www.youtube.com/watch?v=eB7hd_KjTig), [Part 4](https://www.youtube.com/watch?v=NBfqzcN0_EQ)
Requirements:
-------------
__Compiler:__
sqlpp11 makes heavy use of C++11 and requires a recent compiler and STL. The following compilers are known to compile the test programs:
* clang-3.4+ on Ubuntu-12.4
* g++-4.8+ on Ubuntu-12.4
* g++-4.8+ on cygwin 64bit
* g++-4.9+ on Debian Unstable
* Xcode-7 on OS X
* MSVC 2015 Update 1 on Windows Server 2012
__Database Connector:__
sqlpp11 requires a certain api in order to connect with the database, see database/api.h.
This repository includes the following connectors:
* MySQL
* MariaDB
* SQLite3
* SQLCipher
* PostgreSQL
Other connectors can be found here:
* ODBC: https://github.com/Erroneous1/sqlpp11-connector-odbc (experimental)
__Date Library:__
sqlpp11 requires [Howard Hinnants date library](https://github.com/HowardHinnant/date) for `date` and `date_time` data types. By default, sqlpp11 uses FetchContent to pull the library automatically in the project. If you want to use an already installed version of the library with `find_package`, set `USE_SYSTEM_DATE` option to `ON`.
Build and Install
-----------------
**Note**: Depending on how you use the lib, you might not need to install it (see Basic Usage)
__Build from Source:__
Download and unpack the latest release from https://github.com/rbock/sqlpp11/releases or clone the repository. Inside the directory run the following commands:
```bash
cmake -B build
cmake --build build --target install
```
The last step will build the library and install it system wide, therefore it might need admins rights.
By default only the core library will be installed. To also install connectors set the appropriate variable to `ON`:
* `BUILD_MYSQL_CONNECTOR`
* `BUILD_MARIADB_CONNECTOR`
* `BUILD_POSTGRESQL_CONNECTOR`
* `BUILD_SQLITE3_CONNECTOR`
* `BUILD_SQLCIPHER_CONNECTOR`
The library will check if all required dependencies are installed on the system. If connectors should be installed even if the dependencies are not yet available on the system, set `DEPENDENCY_CHECK` to `OFF`.
Example: Install the core library, sqlite3 connector and postgresql connector. Dont check if the dependencies such as Sqlite3 are installed and dont build any tests:
```bash
cmake -B build -DBUILD_POSTGRESQL_CONNECTOR=ON -DBUILD_SQLITE3_CONNECTOR=ON -DDEPENDENCY_CHECK=OFF -DBUILD_TESTING=OFF
cmake --build build --target install
```
__Install via Homebrew (MacOS):__
```bash
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:
-------------
__Use with cmake__:
The library officially supports two ways how it can be used with cmake.
You can find examples for both methods in the examples folder.
1. FetchContent (Recommended, no installation required)
1. FindPackage (installation required, see above)
Both methods will provide the `sqlpp11::sqlpp11` target as well as targets for each connector:
* sqlpp11::mysql
* sqlpp11::mariadb
* sqlpp11::sqlite3
* sqlpp11::sqlcipher
* sqlpp11::postgresql
These targets will make sure all required dependencies are available and correctly linked and include directories are set correctly.
__Create DDL files__:
```
mysql: 'show create table MyDatabase.MyTable' #or
mysqldump --no-data MyDatabase > MyDatabase.sql
```
Create headers for them with provided Python script:
```
%sqlpp11_dir%/scripts/ddl2cpp ~/temp/MyTable.ddl ~/temp/MyTable %DatabaseNamespaceForExample%
```
In case youre getting notes about unsupported column type consider:
- Take a look at the other datatypes in sqlpp11/data_types. They are not hard to implement.
- Use the `--datatype-file` command line argument as described below.
Include generated header (MyTable.h), thats all.
If you prefer Ruby over Python, you might want to take a look at https://github.com/douyw/sqlpp11gen
Unsupported column types:
-------------
__Map unsupported column types to supported column types with a csv file__:
One can use the `--datatype-file` command line argument for the ddl2cpp script to map unsupported column types to supported column types.
The format of the csv file is:
```
<dataType>, <col_type1>, <col_type2>
<dataType>, <col_type3>
```
Where `<dataType>` is one or more of the following internal types:
- `Boolean`
- `Integer`
- `Serial`
- `FloatingPoint`
- `Text`
- `Blob`
- `Date`
- `DateTime`
- `Time`
Example:
```
Boolean, one_or_zero
Text, url, uuid
```
Contact:
--------
* Issues at https://github.com/rbock/sqlpp11/issues
* email at rbock at eudoxos dot de
* [![Join the chat at https://gitter.im/sqlpp11/Lobby](https://badges.gitter.im/sqlpp11/Lobby.svg)](https://gitter.im/sqlpp11/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

View File

@ -0,0 +1 @@
theme: jekyll-theme-minimal

View File

@ -0,0 +1,65 @@
# Copyright (c) 2021, Leon De Andrade
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# 2. 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(GNUInstallDirs)
include(CMakePackageConfigHelpers)
function(add_component)
set(options)
set(oneValueArgs NAME)
set(multiValueArgs DEPENDENCIES)
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
add_library(sqlpp11_${ARG_NAME} INTERFACE)
add_library(sqlpp11::${ARG_NAME} ALIAS sqlpp11_${ARG_NAME})
set_target_properties(sqlpp11_${ARG_NAME} PROPERTIES EXPORT_NAME ${ARG_NAME})
target_link_libraries(sqlpp11_${ARG_NAME} INTERFACE sqlpp11 ${ARG_DEPENDENCIES})
endfunction()
function(install_component)
set(options)
set(oneValueArgs NAME DIRECTORY)
set(multiValueArgs TARGETS)
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
install(FILES ${PROJECT_SOURCE_DIR}/cmake/configs/${ARG_NAME}Config.cmake
DESTINATION ${SQLPP11_INSTALL_CMAKEDIR}
)
install(TARGETS ${ARG_TARGETS}
EXPORT Sqlpp11Targets
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(EXPORT Sqlpp11Targets
DESTINATION ${SQLPP11_INSTALL_CMAKEDIR}
NAMESPACE sqlpp11::
)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/sqlpp11/${ARG_DIRECTORY}
DESTINATION include/sqlpp11
FILES_MATCHING
PATTERN *.h
)
endfunction()

View File

@ -0,0 +1,71 @@
# Copyright (c) 2016, Christian David
# 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.
# Temporarly prepend CMAKE_MODULE_PATH with current directory to find helper scripts such as FindPackage scripts
set(CMAKE_MODULE_PATH_save ${CMAKE_MODULE_PATH})
list(PREPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
include(CMakeFindDependencyMacro)
find_dependency(Threads)
find_dependency(date REQUIRED)
# Work out the set of components to load
if(${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS)
set(${CMAKE_FIND_PACKAGE_NAME}_comps ${${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS})
endif()
# Check all required components are available before trying to load any
foreach(comp IN LISTS ${CMAKE_FIND_PACKAGE_NAME}_comps)
if(${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED_${comp} AND NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/Sqlpp11${comp}Config.cmake)
set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "Sqlpp11 missing required component: ${comp}")
set(${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)
return()
endif()
endforeach()
# Add the target file
include(${CMAKE_CURRENT_LIST_DIR}/Sqlpp11Targets.cmake)
# Load any optional components
foreach(comp IN LISTS ${CMAKE_FIND_PACKAGE_NAME}_comps)
include(${CMAKE_CURRENT_LIST_DIR}/Sqlpp11${comp}Config.cmake OPTIONAL)
endforeach()
# Import "ddl2cpp" script
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()
# Resture module path
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH_save})
unset(CMAKE_MODULE_PATH_save)

View File

@ -0,0 +1,2 @@
include(CMakeFindDependencyMacro)
find_dependency(MariaDB)

View File

@ -0,0 +1,2 @@
include(CMakeFindDependencyMacro)
find_dependency(MySQL)

View File

@ -0,0 +1,2 @@
include(CMakeFindDependencyMacro)
find_dependency(PostgreSQL)

View File

@ -0,0 +1,2 @@
include(CMakeFindDependencyMacro)
find_dependency(SQLCipher)

View File

@ -0,0 +1,2 @@
include(CMakeFindDependencyMacro)
find_dependency(SQLite3)

View File

@ -0,0 +1,64 @@
# Copyright (c) 2016, Christian David
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
if(DEFINED MSVC)
set(SEARCH_PATHS
"$ENV{ProgramFiles}/MariaDB/*"
"$ENV{ProgramFiles\(x86\)}/MariaDB/*"
)
find_path(MariaDB_INCLUDE_DIR
NAMES mariadb_version.h
PATHS ${SEARCH_PATHS}
PATH_SUFFIXES include
)
find_library(MariaDB_LIBRARY
NAMES libmariadb
PATHS ${SEARCH_PATHS}
PATH_SUFFIXES lib
)
else()
find_path(MariaDB_INCLUDE_DIR
NAMES mariadb_version.h
PATH_SUFFIXES mariadb mysql
)
find_library(MariaDB_LIBRARY NAMES mariadb)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
MariaDB
MariaDB_INCLUDE_DIR
MariaDB_LIBRARY
)
if(MariaDB_FOUND AND NOT TARGET MariaDB::MariaDB)
add_library(MariaDB::MariaDB UNKNOWN IMPORTED)
target_include_directories(MariaDB::MariaDB INTERFACE "${MariaDB_INCLUDE_DIR}")
set_target_properties(MariaDB::MariaDB PROPERTIES
IMPORTED_LOCATION "${MariaDB_LIBRARY}"
IMPORTED_LINK_INTERFACE_LANGUAGES "C")
endif()
mark_as_advanced(MariaDB_INCLUDE_DIR MariaDB_LIBRARY)

View File

@ -0,0 +1,71 @@
# Copyright (c) 2016, Christian David
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
if(DEFINED MSVC)
set(SEARCH_PATHS
"$ENV{ProgramFiles}/MySQL/MySQL Server 8.0"
"$ENV{ProgramFiles}/MySQL/MySQL Server 5.7"
"$ENV{ProgramFiles}/MySQL/MySQL Server 5.6"
"$ENV{ProgramFiles\(x86\)}/MySQL/MySQL Server 8.0"
"$ENV{ProgramFiles\(x86\)}/MySQL/MySQL Server 5.7"
"$ENV{ProgramFiles\(x86\)}/MySQL/MySQL Server 5.6"
)
find_path(MySQL_INCLUDE_DIR
NAMES mysql_version.h
PATHS ${SEARCH_PATHS}
PATH_SUFFIXES include
)
find_library(MySQL_LIBRARY
NAMES libmysql
PATHS ${SEARCH_PATHS}
PATH_SUFFIXES lib
)
else()
find_path(MySQL_INCLUDE_DIR
NAMES mysql_version.h
PATH_SUFFIXES mysql
)
find_library(MySQL_LIBRARY
NAMES mysqlclient mysqlclient_r
PATH_SUFFIXES mysql # for CentOS 7
)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
MySQL
MySQL_INCLUDE_DIR
MySQL_LIBRARY
)
if(MySQL_FOUND AND NOT TARGET MySQL::MySQL)
add_library(MySQL::MySQL UNKNOWN IMPORTED)
target_include_directories(MySQL::MySQL INTERFACE "${MySQL_INCLUDE_DIR}")
set_target_properties(MySQL::MySQL PROPERTIES
IMPORTED_LOCATION "${MySQL_LIBRARY}"
IMPORTED_LINK_INTERFACE_LANGUAGES "C")
endif()
mark_as_advanced(MySQL_INCLUDE_DIR MySQL_LIBRARY)

View File

@ -0,0 +1,115 @@
# - Try to find SQLCipher
# Once done this will define
#
# SQLCIPHER_FOUND - system has SQLCipher
# SQLCIPHER_INCLUDE_DIR - the SQLCipher include directory
# SQLCIPHER_LIBRARIES - Link these to use SQLCipher
# SQLCIPHER_DEFINITIONS - Compiler switches required for using SQLCipher
# SQLCIPHER_VERSION - This is set to major.minor.revision (e.g. 3.4.1)
#
# Hints to find SQLCipher
#
# Set SQLCIPHER_ROOT_DIR to the root directory of a SQLCipher installation
#
# The following variables may be set
#
# SQLCIPHER_USE_OPENSSL - Set to ON/OFF to specify whether to search and use OpenSSL.
# Default is OFF.
# SQLCIPHER_OPENSSL_USE_ZLIB - Set to ON/OFF to specify whether to search and use Zlib in OpenSSL
# Default is OFF.
# Redistribution and use is allowed according to the terms of the BSD license.
# Copyright (c) 2008, Gilles Caulier, <caulier.gilles@gmail.com>
# Copyright (c) 2014, Christian Dávid, <christian-david@web.de>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
# use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
if( NOT WIN32 )
find_package(PkgConfig)
pkg_check_modules(PC_SQLCIPHER QUIET sqlcipher)
set(SQLCIPHER_DEFINITIONS ${PC_SQLCIPHER_CFLAGS_OTHER})
endif( NOT WIN32 )
find_path(SQLCIPHER_INCLUDE_DIR NAMES sqlcipher/sqlite3.h
PATHS
${SQLCIPHER_ROOT_DIR}
${PC_SQLCIPHER_INCLUDEDIR}
${PC_SQLCIPHER_INCLUDE_DIRS}
${CMAKE_INCLUDE_PATH}
PATH_SUFFIXES "include"
)
find_library(SQLCIPHER_LIBRARY NAMES sqlcipher
PATHS
${PC_SQLCIPHER_LIBDIR}
${PC_SQLCIPHER_LIBRARY_DIRS}
${SQLCIPHER_ROOT_DIR}
PATH_SUFFIXES "lib"
)
set(SQLCIPHER_LIBRARIES ${SQLCIPHER_LIBRARY})
set(SQLCIPHER_INCLUDE_DIRS ${SQLCIPHER_INCLUDE_DIR})
if (SQLCIPHER_USE_OPENSSL)
find_package(OpenSSL REQUIRED COMPONENTS Crypto)
if (SQLCIPHER_OPENSSL_USE_ZLIB)
find_package(ZLIB REQUIRED)
# Official FindOpenSSL.cmake does not support Zlib
set_target_properties(OpenSSL::Crypto PROPERTIES INTERFACE_LINK_LIBRARIES ZLIB::ZLIB)
endif()
list(APPEND SQLCIPHER_LIBRARIES ${OPENSSL_LIBRARIES})
list(APPEND SQLCIPHER_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIRS})
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SQLCipher
DEFAULT_MSG SQLCIPHER_INCLUDE_DIR SQLCIPHER_LIBRARY)
# show the SQLCIPHER_INCLUDE_DIR and SQLCIPHER_LIBRARIES variables only in the advanced view
mark_as_advanced(SQLCIPHER_INCLUDE_DIR SQLCIPHER_LIBRARY)
if (NOT TARGET SQLCipher::SQLCipher)
add_library(SQLCipher::SQLCipher UNKNOWN IMPORTED)
set_property(TARGET SQLCipher::SQLCipher PROPERTY INTERFACE_COMPILE_DEFINITIONS SQLITE_HAS_CODEC)
set_property(TARGET SQLCipher::SQLCipher APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS "SQLITE_TEMPSTORE=2")
set_target_properties(SQLCipher::SQLCipher PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${SQLCIPHER_INCLUDE_DIRS}"
IMPORTED_INTERFACE_LINK_LANGUAGES "C"
IMPORTED_LOCATION "${SQLCIPHER_LIBRARY}")
if (SQLCIPHER_USE_OPENSSL)
set_target_properties(SQLCipher::SQLCipher PROPERTIES
INTERFACE_LINK_LIBRARIES OpenSSL::Crypto)
set_property(TARGET SQLCipher::SQLCipher APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS "SQLCIPHER_CRYPTO_OPENSSL")
endif()
endif()

View File

@ -0,0 +1,89 @@
#pragma once
/*
* Copyright (c) 2013-2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <memory>
namespace sqlpp
{
namespace database
{
/*
* bind_result_t binds values of a sqlpp11 result row
* to the results of a statement
*/
class bind_result_t
{
public:
bind_result_t(); // default constructor for a result that will not yield a valid row
bind_result_t(...);
bind_result_t(const bind_result_t&) = delete;
bind_result_t(bind_result_t&& rhs);
bind_result_t& operator=(const bind_result_t&) = delete;
bind_result_t& operator=(bind_result_t&&);
~bind_result_t();
bool operator==(const bind_result_t& rhs) const;
template <typename ResultRow>
void next(ResultRow& result_row);
// something similar to this:
/*
{
if (!_handle)
{
result_row.invalidate();
return;
}
if (next_impl())
{
if (not result_row)
{
result_row.validate();
}
result_row._bind(*this); // bind result row values to results
}
else
{
if (result_row)
result_row.invalidate();
}
};
*/
// These are called by the result row to bind individual result values
// More will be added over time
void _bind_boolean_result(size_t index, signed char* value, bool* is_null);
void _bind_floating_point_result(size_t index, double* value, bool* is_null);
void _bind_integral_result(size_t index, int64_t* value, bool* is_null);
void _bind_text_result(size_t index, const char** text, size_t* len);
...
};
}
}

View File

@ -0,0 +1,227 @@
#pragma once
/*
* Copyright (c) 2013-2015, Roland Bock
* Copyright (c) 2023, Vesselin Atanasov
* 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 <string>
#include <sqlpp11/connection.h>
#include <sqlpp11/transaction.h>
#include <sqlpp11/database/char_result.h> // You may use char result or bind result or both
#include <sqlpp11/database/bind_result.h> // to represent results of select and prepared select
namespace sqlpp
{
namespace database
{
// Connection configuration that is used to create new database connections
struct connection_config
{
// Put the configuration properties here, e.g.
//
// std::string host;
// unsigned port;
// std::string username;
// std::string password;
// std::string db_name;
};
// The connection handle is a low-level representation of a database connection.
// Pre-connected handles are stored in the connection pool and are used to create
// full connection objects on request.
class connection_handle
{
public:
// Connection handles can be created from connection configurations
connection_handle(const std::shared_ptr<const connection_config>& config);
// Connection handles cannot be copied
connection_handle(const connection_handle&) = delete;
connection_handle& operator=(const connection_handle&) = delete;
// Connection handles can be moved
connection_handle(connection_handle&&);
connection_handle& operator=(connection_handle&&);
// Used by the connection pool to check if the connection handle is still
// connected to the database server.
bool is_connected();
// Send a dummy request to the server to check if the connection is still alive
bool ping_server();
// Optional method that returns a native (low-level) database handle.
// Used by the test code to test the connection pool
native_db_handle native_handle();
};
// The context is not a requirement, but if the database requires
// any deviations from the SQL standard, you should use your own
// context in order to specialize the behaviour, see also interpreter.h
struct context_t
{
template <typename T>
std::ostream& operator<<(T t);
std::string escape(std::string arg);
};
// The base database-specific connection class. Non-pooled and pooled connection classes derive from it
class connection_base : public sqlpp::connection // this inheritance helps with ADL for dynamic_select, for instance
{
public:
// Base configuration
using _connection_base_t = connection_base;
// Type of configuration instances
using _config_t = connection_config;
// Shared pointer wrapping a configuration instance
using _config_ptr_t = std::shared_ptr<const _config_t>;
// Type of connection handles
using _handle_t = connection_handle;
// Unique pointer wrapping a connection handle
using _handle_ptr_t = std::unique_ptr<_handle_t>;
using _traits = ::sqlpp::make_traits<
::sqlpp::no_value_t,
::sqlpp::tag::enforce_null_result_treatment // If that is what you really want, leave it out otherwise
>;
using _prepared_statement_t = << handle to a prepared statement of the database >> ;
using _serializer_context_t = << This context is used to serialize a statement >> using _interpreter_context_t =
<< This context is used interpret a statement >>
;
// serializer and interpreter are typically the same for string based connectors
// the types are required for dynamic statement components, see sqlpp11/interpretable.h
//! "direct" select
template <typename Select>
<< bind_result_t >>
select(const Select& s);
//! prepared select
template <typename Select>
_prepared_statement_t prepare_select(Select& s);
template <typename PreparedSelect>
<< bind_result_t >>
run_prepared_select(const PreparedSelect& s); // call s._bind_params()
//! "direct insert
template <typename Insert>
size_t insert(const Insert& i);
//! prepared insert
template <typename Insert>
_prepared_statement_t prepare_insert(Insert& i);
template <typename PreparedInsert>
size_t run_prepared_insert(const PreparedInsert& i); // call i._bind_params()
//! "direct" update
template <typename Update>
size_t update(const Update& u);
//! "prepared" update
template <typename Update>
_prepared_statement_t prepare_update(Update& u);
template <typename PreparedUpdate>
size_t run_prepared_update(const PreparedUpdate& u); // call u._bind_params()
//! "direct" remove
template <typename Remove>
size_t remove(const Remove& r)
//! prepared remove
template <typename Remove>
_prepared_statement_t prepare_remove(Remove& r);
template <typename PreparedRemove>
size_t run_prepared_remove(const PreparedRemove& r); // call r._bind_params()
//! call run on the argument
template <typename T>
auto operator()(const T& t) -> decltype(t._run(*this))
{
return t._run(*this);
}
//! call prepare on the argument
template <typename T>
auto prepare(const T& t) -> decltype(t._prepare(*this))
{
return t._prepare(*this);
}
//! set the transaction isolation level for the current connection
/// time of effect is connector-specific, for most is will only affect new transactions
void set_default_isolation_level(sqlpp::isolation_level);
//! read the default transaction isolation level for the current connection
sqlpp::isolation_level get_default_isolation_level();
//! start transaction
void start_transaction();
//! start transaction with defined isolation level (optional only for connectors that support it)
void start_transaction(isolation_level isolation /* = isolation_level::undefined */);
//! commit transaction (or throw transaction if the transaction has been finished already)
void commit_transaction();
//! rollback transaction with or without reporting the rollback (or throw if the transaction has been finished
// already)
void rollback_transaction(bool report);
//! report a rollback failure (will be called by transactions in case of a rollback failure in the destructor)
void report_rollback_failure(const std::string message) noexcept;
protected:
// Low-level connection handle
_handle_ptr_t _handle;
// The constructors are private because the base class instances are never created directly,
// The constructors are called from the constructors of the derived classes
connection_base() = default;
connection_base(_handle_ptr_t&& handle) : _handle{std::move(handle)}
{
}
};
// Normal non-pooled connections.
using connection = sqlpp::normal_connection<connection_base>;
// Pooled connections that are created by the thread pool
using pooled_connection = sqlpp::pooled_connection<connection_base>;
} // namespace database
} // namespace sqlpp
#include <sqlpp11/database/interpreter.h>

View File

@ -0,0 +1,39 @@
#pragma once
/*
Copyright (c) 2017 - 2018, Roland Bock
Copyright (c) 2023, Vesselin Atanasov
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/connection_pool.h>
#include <sqlpp11/database/connection.h>
namespace sqlpp
{
namespace database
{
using connection_pool = sqlpp::connection_pool<pooled_connection>;
} // namespace database
} // namespace sqlpp

View File

@ -0,0 +1,58 @@
#pragma once
/*
* Copyright (c) 2013-2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/vendor/concat.h>
#include <sqlpp11/vendor/insert_list.h>
/*
* sqlpp11 offers an interpreter that can be used to serialize the expression tree
* into a standard SQL string.
*
* The connector library can specialize the interpreter template to partially or
* completely change the way the expression tree is interpreted.
*
* For example, this specialization will produce indexed parameters instead of just '?'
*/
namespace sqlpp
{
namespace vendor
{
template <typename ValueType, typename NameType>
struct interpreter_t<database::context_t, parameter_t<ValueType, NameType>>
{
using T = parameter_t<ValueType, NameType>;
static database::context_t& _(const T& t, database::context_t& context)
{
context << "?" << context.count();
context.pop_count();
return context;
}
};
}
}

View File

@ -0,0 +1,57 @@
#pragma once
/*
* Copyright (c) 2013-2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <memory>
#include <string>
namespace sqlpp
{
namespace database
{
class prepared_statement_t
{
public:
prepared_statement_t() = delete;
prepared_statement_t(...);
prepared_statement_t(const prepared_statement_t&) = delete;
prepared_statement_t(prepared_statement_t&& rhs);
prepared_statement_t& operator=(const prepared_statement_t&) = delete;
prepared_statement_t& operator=(prepared_statement_t&&);
~prepared_statement_t();
bool operator==(const prepared_statement_t& rhs) const;
// These are called by the sqlpp11::prepared_*_t to bind the individual parameters
// More will be added over time
void _bind_boolean_parameter(size_t index, const signed char* value, bool is_null);
void _bind_floating_point_parameter(size_t index, const double* value, bool is_null);
void _bind_integral_parameter(size_t index, const int64_t* value, bool is_null);
void _bind_text_parameter(size_t index, const std::string* value, bool is_null);
};
}
}

31
3party/sqlpp11/coveralls Executable file
View File

@ -0,0 +1,31 @@
#!/bin/bash
if [ 0 -eq $(find -iname *.gcda | wc -l) ]
then
exit 0
fi
gcov --source-prefix ${TRAVIS_BUILD_DIR} --preserve-paths --relative-only $(find -iname *.gcda) 1>/dev/null || exit 0
cat >coverage.json <<EOF
{
"service_job_id": "${TRAVIS_JOB_ID}",
"service_name": "travis-ci",
"source_files": [
EOF
for file in include*.gcov
do
path=$(echo ${file} | sed -re 's%#%\/%g; s%.gcov$%%')
cat >>coverage.json <<EOF
{
"name": "${path}",
"source_digest": "$(md5sum ${TRAVIS_BUILD_DIR}/${path} | awk '{ print $1 }')",
"coverage": [$(tail -n +3 ${file} | cut -d ':' -f 1 | sed -re 's%^ +%%g; s%-%null%g; s%^[#=]+$%0%;' | tr $'\n' ',' | sed -re 's%,$%%')]
},
EOF
done
mv coverage.json coverage.json.tmp
cat >coverage.json <(head -n -1 coverage.json.tmp) <(echo -e " }\n ]\n}")
curl -F json_file=@coverage.json https://coveralls.io/api/v1/jobs

View File

@ -0,0 +1,36 @@
# Copyright (c) 2020, Leon De Andrade
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice, this
# list of conditions and the following disclaimer in the documentation and/or
# other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if(NOT USE_SYSTEM_DATE AND NOT TARGET date::date)
include(FetchContent)
FetchContent_Declare(date
# GIT_REPOSITORY https://github.com/HowardHinnant/date.git
GIT_REPOSITORY https://code.uocat.com/3party/date.git
GIT_TAG v3.0.0
)
add_subdirectory(hinnant_date)
endif()

View File

@ -0,0 +1,28 @@
# Copyright (c) 2020, Leon De Andrade
# 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.
FetchContent_MakeAvailable(date)
# Make date a system library (no warnings for date headers when compiling)
get_property(date_include_dirs TARGET date PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
set_property(TARGET date PROPERTY INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${date_include_dirs}")

View File

@ -0,0 +1,111 @@
# Introduction
SQLPP11 has support for connection pools which are centralized caches of database connections. When you need a database connection, you can fetch one from the connection pool, use the connection to make SQL
queries and when you no longer need the connection object, destroy it, usually by letting it go out of scope. When a connection object is destroyed, the actual connection to the database server is not closed,
but put in a cache instead and next time when you need a database connection object, you will be handed one that reuses a cached connection. If there are no connections is the cache, then a new connection
will be created, wrapped in a connection object and handed to you.
## Creating connection pools
Each connector has its own connection pool class. Currently we have
* sqlpp::mysql::connection_pool
* sqlpp::postgresql::connection_pool
* sqlpp::sqlite3::connection_pool
The connection pool constructors accept two parameters
* Shared pointer to a configuration object. This is the same configuration as the one that you use when creating regular (non-pooled) database connections.
* An integer specifying the initial size of the connection cache. This cache size grows automatically when necessary, so this value is not very important as pretty much any small positive value will do. In our example below we use 5.
In this example we create a PostgreSQL connection pool:
```
auto config = std::make_shared<sqlpp::postgresql::connection_config>();
config->dbname = "my_database";
config->user = "my_user";
config->password = "my_password";
config->debug = true;
auto pool = sqlpp::postgresql::connection_pool{config, 5};
```
You can also create a pool object without a configuration and initialize it later.
```
auto pool = sqlpp::postgresql::connection_pool{}
....
....
....
auto config = std::make_shared<sqlpp::postgresql::connection_config>();
config->dbname = "my_database";
config->user = "my_user";
config->password = "my_password";
config->debug = true;
pool.initialize(config, 5);
```
## Getting connections from the connection pool
Once the connection pool object is established we can use the _get()_ method to fetch connections
```
auto db = pool.get();
for (row : db(select(....))) {
....
}
```
## Returning connections to the connection pool
We don't really need to do anything to return the connection to the pool. Once the connection object's destructor is called the connection is not really destroyed but instead is returned automatically to the connection
pool's cache. This means that we can use the connection pool in the following way
```
for (row : pool.get()(select(....))) {
....
}
```
In the above example we fetch a connection from the pool, use it to make an SQL query and then return the connection to the pool.
## Ensuring that connections handed out by the connection pool are valid
Connection pools handle out connections that are either newly created or fetched from the connection cache. For connections that are fetched from the cache an optional check can be made to ensure that the connection is still active.
If the cached connection is no longer active, then it is discarded and the user is handed a newly created connection.
The check type is specified as an optional parameter of the _get()_ method. Currently the following check types are supported:
* **sqlpp::connection_check::none** Don't check the connection
* **sqlpp::connection_check::passive** A passive check which does not send anything to the server but just checks if the server side has already closed their side of the connection. This check type is supported only for PostgreSQL, for the other connector types it is treated as _none_.
* **sqlpp::connection_check::ping** Send a dummy request to the server to check if the connection is still alive. For MySQL connections this check uses the `mysql_ping` library function. For the other connector types
this check sends `SELECT 1` to the server.
For example:
```
auto db = pool.get(sqlpp::connection_check::ping);
for (row : db(select(....))) {
....
}
```
## Working around connection thread-safety issues
Connection pools can be used to work around [thread-safety issues](Threads.md) by ensuring that no connection is used simultaneously by multiple threads.
### Getting a new connection for each request
One possible usage pattern is getting a new connection handle for each request. For example:
```
for (row : pool.get()(select(....))) {
....
}
pool.get()(insert_into(mytable)....)
pool.get()(remove_from(mytable)....)
```
This usage pattern works well provided that you don't use transactions. If you use transactions then you must make sure that the transaction object and all queries inside the transaction use the same database connection.
### Using one connection per thread
Another usage pattern that works around the multi-threading problems is keeping a connection handle in a global thread_local object. This global object is not a real connection, but a wrapper which lazily fetches a connection from the
thread pool the first time when it is used to execute a database query. The wrapper will expose all the relevant methods and will forward them to the real connection. This way each thread can use the global wrapper as a database
connection and the thread_local storage class specifier will make sure that each thread accesses its own database connection. You can see examples/connection_pool as an example of this usage pattern.

View File

@ -0,0 +1,16 @@
# Database Connectors
Using sqlpp11 requires of three logical parts:
1. The actual tables of a database are represented structs, usually generated by sql2cpp. These structs contain compile-time information about each colum such as name and data type.
2. The core library provides SQL as embedded language for C++. It allows you to write SQL statements for those tables and analyse results in a compile-time checked manner.
3. The connector library that allows you to connect to an actual database, send queries and obtain results.
Three connector libraries are included in this repository:
* MySQL / MariaDB
* sqlite3 / SQLCipher
* PostgreSQL
If you want to use other databases, you would have to write your own connector. Don't worry, it is not that hard.
The api is documented [here](https://github.com/rbock/sqlpp11/blob/master/connector_api/connection.h).

View File

@ -0,0 +1,33 @@
# Introduction
_This page explains dynamic insert statements. Before studying this page, you should read about [static insert statements](Insert.md)._
If you know the exact structure of your inserts at compile time, statically constructed insert statements are perfect. But if the structure depends on runtime information like user input, you will need dynamic insert statements. For those only provide part fields of table schema, leave others to default value or NULL, dynamic insert statement is a must. Depending on your needs, you can choose the required dosage.
# A Basic Example
So let us construct insert statement with a dynamic part
```C++
auto s = dynamic_insert_into(db, foo).dynamic_set(
foo.name = name,
);
s.insert_list.add(foo.id = runtimeStatement.id);
s.insert_list.add(foo.hasFun = runtimeStatement.hasFun);
const int64_t result = db(s);
```
Admittedly, a rather simplistic example (please suggest nicer ones), but anyway, this is what's happening:
```C++
dynamic_insert_into(db, table)
```
This initializes a dynamic insert. One major difference between `dynamic_insert_into` and `insert_into` is the first argument of `dynamic_insert_into`: a database connection. This is used to evaluate the dynamic parts of the statement as they are added.
```C++
.dynamic_set(...);
...
s.insert_list.add(foo.id = runtimeStatement.id);
s.insert_list.add(foo.hasFun = runtimeStatement.hasFun);
```
The first part creates a new insert object that accepts a dynamically constructed set expression. In this case the user can determine whether to search for a certain id or a certain hasFun, or neither or both.
```C++
const int64_t result = db(s);
```
Finally use `db(s)` to execute the insert statement, and returns a `int64_t` value. If `foo.id` column is a `AUTO INCREMENT` (auto generated) id field, this will returns the auto generated id, for others this will returns 0.

View File

@ -0,0 +1,69 @@
# Introduction
_This page explains dynamic select statements. Before studying this page, you should read about [static select statements](Select.md)._
If you know the exact structure of your queries at compile time, statically constructed select statements are perfect. But if the structure depends on runtime information like user input, you will need dynamic select statements. Depending on your needs, you can choose the required dosage.
# A Basic Example
So let us construct select query with a dynamic part
```C++
auto s = dynamic_select(db, all_of(foo)).from(foo).dynamic_where();
if (runtimeQuery.id)
s.where.add(foo.id == runtimeQuery.id);
if (!runtimeQuery.name.empty())
s.where.add(foo.name == runtimeQuery.name);
```
Admittedly, a rather lame example (please suggest nicer ones), but anyway, this is what's happening:
```C++
dynamic_select(db, ...)
```
This initializes a dynamic select. One major difference between `dynamic_select` and `select` is the first argument of `dynamic_select`: a database connection. This is used to evaluate the dynamic parts of the query as they are added.
```C++
.dynamic_where();
...
s.where.add(foo.name == runtimeQuery.name);
s.where.add(foo.id == runtimeQuery.id);
```
The first part creates a new select object that accepts a dynamically constructed where expression. In this case the user can determine whether to search for a certain name or a certain id, or neither or both.
# Dynamic Select
## Dynamic Columns
If the (some) selected columns are not known at compile time, you can do something like this:
```C++
auto s = dynamic_select(db).dynamic_columns(foo.id).from(foo).unconditionally();
if (someCondition)
s.selected_columns.add(foo.name);
if (someOtherCondition)
s.selected_columns.add(foo.hasFun);
```
In this example, the column id is always selected. The other two columns may or may not be selected. This is determined at runtime. This impacts the way the results are accessed because the type of the result row is not known at the same level of detail as in the static case. The dynamic fields can be accessed via name lookup like in a map:
```C++
for (const auto& row : db(s))
{
long id = row.id;
if (someCondition)
std::string name = row.at("name");
if (someOtherCondition)
std::string hasFun = row.at("hasFun");
}
```
This also shows another difference. Dynamic fields are of text type. It would be possible to add conversion methods for other types as well, but this has not been coded yet. Please let me know you wishes.
## Dynamic From
In a static query the compiler can verify whether the `from()` clause is sufficient to support all other aspects of the query.
With a dynamic from, the compile cannot know tables that going into the `from()`. Such checks would therefore be impossible. But it allows you to add joins at runtime!
```C++
auto s = dynamic_select(db, all_of(foo)).dynamic_from(foo).dynamic_where();
if (someOtherCondition)
s.from.add(dynamic_join(bar).on(foo.barId == bar.id));
```
In this example, the user may want to include `bar` into the query.
## Dynamic Where
As shown in other examples, the where condition can be constructed dynamically using the methods `dynamic_where()` and `where.add()`. The former prepares the select to accept dynamic where conditions, the latter adds a condition. Several calls to add_where will be combined into one condition by `and`.
## Dynamic Having, Group By, OrderBy, Limit and Offset
Similar to the dynamic where, you can use `dynamic_having`, `dynamic_group_by`, `dynamic_order_by`, `dynamic_limit` and `dynamic_offset` to prepare the select statement to accept certain dynamic aspects. Using `having.add`, `group_by.add`, `order_by.add`, `limit.set` and `offset.set` you can then adjust those query parts according to the runtime information.

View File

@ -0,0 +1,10 @@
## When to expect an exception
sqlpp11 connectors throw the majority of `sqlpp::exception`s so check your connector's documentation. Generally, you should expect an exception when:
- Connecting to a database
- Preparing a statement
- Executing a statement
- Retrieving and iterating through result rows
Additionally, the date library used by sqlpp11 may throw `std::runtime_error`. As of 2017-04-08 this only happens when formatting a date using a format string.

View File

@ -0,0 +1,91 @@
sqlpp11 offers equivalents for quite a few SQL functions. It also has some additional functions to make the developer's life easier, see [Misc Functions](#Misc-Functions).
If functions can be used as select columns, the column's name is the name of the function. You can use `.as()` of course to give it another name, see [Select](Select.md). There are just a few exceptions like `any()` which cannot be named.
# Member Functions
## in and not_in
The methods `in()` and `not_in()` can be used are available for pretty much any expression. They take zero or more value expressions. You can make the list dynamic by using a container of values.
```C++
tab.a.in(); // not valid SQL but certainly useful for generic code, evaluates to a false expression (version 0.35 and later).
tab.a.in(x, ...); // x, ... being one or more value expressions
tab.a.in(sub_select); // sub_select being a select expression with one result column of appropriate type.
tab.a.in(sqlpp::value_list(some_container_of_values)); // evaluates to a false expression in case of an empty container
```
## is_null
## like
# Aggregate Functions
The following aggregate functions are supported
* avg
* count
* max
* min
* sum
For example:
```C++
for (const auto& row : db(select(tab.name, avg(tab.value))
.from(tab)
.where(tab.id > 17)
.group_by(tab.name)))
{
std::cerr << row.name << ": " << row.avg << std::endl;
}
```
Use `count(1)` for simply query row count:
```C++
const int64_t n = db(select(count(1)).from(tab).unconditionally()).front().count;
```
# Text Functions
## concat
Just use the + operator :-)
# Sub-Query Functions
## exists
## any
## some
# Misc Functions
sqlpp11 offers a few functions that do not mimic SQL but are there to make your life easier.
## value
The `value` function turns the argument into an unnamed SQL expression, e.g. an `int` into an `sqlpp::integral` or a `std::string` into an `sqlpp::text`. You probably don't need to use this function too often, because in most cases, sqlpp expressions do the conversion themselves. For instance
```C++
tab.foo + 17
```
is a perfectly valid expression if `tab.foo` represents an SQL integral value. But when doing some generic query programming you might get into the situation that you want to select a constant value. For instance:
```C++
for (const auto& row : select(sqlpp::value<sqlpp::bigint>(7).as(sql::alias::a)).from(tab)))
{
int64_t a = row.a;
}
```
##value_list
`value_list` is a helper function that takes a container of values and turns it into an sqlpp11 construct that is understood by the `in()` member function of expressions, see above.
## verbatim
sqlpp11 supports quite a few aspects of SQL. But it does certainly not cover everything, nor will it ever. So what if you need to use something that is not supported? At least for expressions there is an easy way to use unsupported features, the `verbatim()` method. It requires a template parameter to determine the SQL type and a string argument containing the expression, for instance:
```C++
select(all_of(tab)).from(tab).where(tab.foo == 42 and sqlpp::verbatim<sqlpp::boolean>("mighty special feature"));
```
_Use with care_, as sqlpp11 does not bother to look into the string you provide. That means you have to handle type checking, syntax checking, escaping of injected evil data from your users, etc.
## flatten
Say `tab.foo` and `tab.bar` represent two bigint columns. Then the type of `tab.foo` and `tab.bar` is different. Also `tab.foo + 17` and `tab.bar + 17` are expressions of different type. This is because the expression carries information about required tables for instance (and that is going to be used to check if `from()` contains all the required tables.
The expression templates can get in your way though, if you want to create parts of your query dynamically:
```C++
auto e = (tab.foo == 17);
if (userWantsBar)
e = (tab.bar == 17); // won't compile
```
You can use [dynamic select](Dynamic-Select.md), but there is an alternative, the `flatten()` method, which turns the expression into a more generic expression type (it just "remembers" whether it is a text, boolean etc).
```C++
auto e = flatten(tab.foo == 17);
if (userWantsBar)
e = flatten(tab.bar == 17); // will compile
```

View File

@ -0,0 +1,27 @@
# Introduction
Let's see:
* You know C++?
* You know some SQL?
* You want to use SQL in your C++ program?
* You think C++ and SQL should play well together?
* You know which tables you want to use in a database?
* You can cope with a few template error messages in case something is wrong?
You have come to the right place!
sqlpp11 offers you to code SQL in C++ almost naturally. You can use tables, columns and functions. Everything has strong types which allow the compiler to help you a lot. At compile time, it will tell about most of those pesky oversight errors you can make (typos, comparing apples with oranges, forgetting tables in a select statement, etc). And it does not stop at query construction. Results have ranges, and strongly typed members, so that you can browse through results in a type-safe manner, worthy of modern C++.
The following pages will tell you how to use it:
* [Database Connectors](Database.md)
* [Tables](Tables.md)
* [Insert](Insert.md)
* [Select](Select.md) <- You might want to read this first as an appetizer
* [Update](Update.md)
* [Remove](Remove.md)
* [Functions](Functions.md)
* [Prepared Statements](Prepared-Statements.md)
* [Transactions](Transactions.md)
* [Thread Safety](Threads.md)
* [NULL](NULL.md)
* [Connection Pools](Connection-Pools.md)
* [New Features](New-Features.md)

View File

@ -0,0 +1,42 @@
# Introduction
_This page explains insert statements with a static structure. If you want to learn about constructing insert statements at runtime, you should still read this page first and then move on to [dynamic insert statements](Dynamic-Insert.md)._
# A Basic example
Haven't found the time to document this in any detail, yet, but this is an example:
```C++
db(insert_into(tab).set(tab.gamma = true));
db(insert_into(tabDateTime)
.set(tabDateTime.colTimePoint = std::chrono::system_clock::now()));
```
This is how you could insert multiple rows at a time:
```C++
auto multi_insert = insert_into(t).columns(t.gamma, t.beta, t.delta);
multi_insert.values.add(t.gamma = true, t.beta = "cheesecake", t.delta = 1);
multi_insert.values.add(t.gamma = sqlpp::default_value, t.beta = sqlpp::default_value,
t.delta = sqlpp::default_value);
multi_insert.values.add(t.gamma = sqlpp::value_or_null(true),
t.beta = sqlpp::value_or_null("pie"),
t.delta = sqlpp::value_or_null<sqlpp::integer>(sqlpp::null));
db(multi_insert);
```
Note that `add` currently requires precise value types, equal to the respective column's value
type. For instance, time point columns are represented as
`std::chrono::time_point<std::chrono::system_clock, std::chrono::microseconds>`.
Thus, when using such a column in a `multi_insert`, you might have to cast to the right
time point.
```
auto multi_time_insert = insert_into(tabDateTime).columns(tabDateTime.colTimePoint);
multi_time_insert.values.add(tabDateTime.colTimePoint = std::chrono::time_point_cast<std::chrono::microseconds>(
std::chrono::system_clock::now()));
```
Similar for other data types.
See also [dynamic insert statements](Dynamic-Insert.md).

100
3party/sqlpp11/docs/NULL.md Normal file
View File

@ -0,0 +1,100 @@
# Introduction
Database NULL is a strange beast. It can be compared to anything but that comparison never returns true. It also never returns false, it returns NULL. Even
```SQL
NULL != NULL -> NULL
NULL = NULL -> NULL
```
A value like that would be pretty unusual in C++. Especially since fields in a result could be either a decent value or NULL. And this can change from result row to result row.
Also, in `where` or `having` conditions, you have to change the expression (not just parameters) if you want to NULL instead of a value:
```SQL
a = 7
a IS NULL
```
# Obtaining potential NULL values from a select
sqlpp11 can determine whether a result field can be null, based on the columns involved and the structure of your query. If in doubt (for instance due to dynamic parts), it will assume that a field can be NULL.
You can check if a field is NULL by calling the `is_null()` method. That's easy.
When it comes to accessing the value, there are two options, though. These can be controlled by the connection class and the columns of your tables.
## Option 1: No conversion operator
```C++
class connection: public sqlpp::connection
{
public:
using _traits = ::sqlpp::make_traits<::sqlpp::no_value_t,
::sqlpp::tag::enforce_null_result_treatment
>;
```
If this tag is used in the connection's traits and the respective column does not override it, then there is no conversion operator for fields that can be NULL. You have to access the value through the `value()` method.
If the field is NULL, this method will throw an `sqlpp::exception`.
## Option 2: Conversion operator, converting NULL to trivial value
If the `tag::enforce_null_result_treatment` is not used in the connection class or the respective column uses `tag::enforce_null_result_treatment`, then there is a conversion operator. Both the conversion operator and the `value()` method will not throw in case of a NULL value. Instead, the will return the trivial value for the field's type, e.g. 0 for numbers or "" for texts.
## Alternatives:
One often discussed alternative would be boost::optional or (in the future) std::optional. There is one drawbacks (correct me if I am wrong, please):
`optional` cannot be used for binding result values because it is unclear whether there already is a value to bind to.
# Handling NULL in statements
When adding potential NULL values to a statement, you have two options:
## Manually
```C++
auto s = dynamic_select(db, all_of(tab)).from(tab).dynamic_where();
if (i_do_have_a_decent_value_of_alpha)
s.add_where(tab.alpha == alpha);
else
s.add_where(tab.alpha.is_null());
```
## tvin()
`tvin()` is a free function that can be used with `std::string` and build-in types like `int` or `float` or `bool`. `tvin` stands for Trivial Value Is NULL. It is used in combination with `operator==()`, `operator!=()` and `operator=()`. These operators will behave the way they should, e.g.
```C++
select(all_of(tab)).from(tab).where(tab.alpha == sqlpp::tvin(a));
```
This will evaluate to
```SQL
SELECT tab.* FROM tab WHERE alpha = 7;
-- OR
SELECT tab.* FROM tab WHERE alpha IS NULL;
```
Similar with insert:
```C++
insert_into(tab).set(tab.alpha = sqlpp::tvin(a));
```
This will evaluate to
```SQL
INSERT INTO tab (alpha) VALUES(7);
-- OR
INSERT INTO tab (alpha) VALUES(NULL);
```
## Using Column Type
Like to accessing values in select results, setting values can be controlled via the column type:
```C++
struct Alpha
{
struct _name_t;
using _traits = sqlpp::make_traits<sqlpp::bigint,
// ...
sqlpp::tag::trivial_value_is_null>;
};
```
With this tag, you do not need to use `tvin()` for operators `=`, `==`, `!=`. It is used automatically. It translates operator `!` into `IS NULL`.
**Hint**: Please be aware that trivial_value_is_null will not work with parameters in prepared statements.

View File

@ -0,0 +1,58 @@
# New Features
There are a bunch of new features, that are not fully documented yet. If you would like to contribute documentation, please let me know.
## Preprocessor generator for columns/tables
You'll need boost 1.50 or greater to use this feature by niXman:
```C++
#include <sqlpp11/ppgen.h>
SQLPP_DECLARE_TABLE(
(tab_person)
,
(id , int , SQLPP_AUTO_INCREMENT)
(name , varchar(255), SQLPP_NOT_NULL )
(feature, int , SQLPP_NOT_NULL )
)
```
See `examples/ppgen.hpp`.
## Union
Unions are now supported. The arguments need to have the same names and types in their columns.
```C++
db(select(t.alpha).from(t).where(true)
.union_distinct(select(f.epsilon.as(t.alpha)).from(f).where(true)));
db(select(t.alpha).from(t).where(true)
.union_all(select(f.epsilon.as(t.alpha)).from(f).where(true)));
```
## With
sqlpp11 supports common table expressions:
```C++
auto x = sqlpp::cte(sqlpp::alias::x).as(select(all_of(t)).from(t));
db(with(x)(select(x.alpha).from(x).where(true)));
```
## Custom Queries
This allows you to combine building blocks of sqlpp11 into custom queries, for instance a SELECT..INTO which is not supported yet.
```C++
// A custom (select ... into) with adjusted return type
// The first argument with a return type is the select,
// but the custom query is really an insert. Thus, we tell it so.
db(custom_query(select(all_of(t)).from(t), into(f))
.with_result_type_of(insert_into(f)));
```
## Schema-qualified tables
sqlpp11 assumes that you're connection addresses one database, normally. But you can tell it about other databases using the `sqlpp::schema_t` and instantiating schema-qualified tables with it:
```C++
auto schema = db.attach("lorem_ipsum");
auto s = schema_qualified_table(schema, TabSample{}).as(sqlpp::alias::x)
// s now represents "lorem_ipsum.tab_sample as x"
// s can be used like any other table in the code
```

View File

@ -0,0 +1,48 @@
# Introduction
Executing a statement in a database is typically done in two phases: First, the statement is prepared (parsed, compiled, optimized). Then, it is run against the database. Since statements often differ only in parameters, not in structure, many databases offer to store prepared statements. These prepared statements can then be executed repeatedly, typically with some parameters.
sqlpp11 supports prepared statements.
## Parameters
Currently there are two overloads to specify a parameter:
```C++
parameter(const ValueType&, const AliasProvider&);
parameter(const NamedExpression&)
```
Value types are sqlpp::bigint, sqlpp::text, etc., Alias providers can be generated by using the SQLPP_ALIAS_PROVIDER macro, and named expressions are combinations of the former, e.g. columns of a table.
For instance, you could use:
```C++
SQLPP_ALIAS_PROVIDER(cheese);
parameter(sqlpp::bigint(), cheese);
parameter(tab.id);
```
## Prepare and execute statements
insert, update, remove and select statements can be prepared by calling the `prepare()` method of a database connection object.
```C++
auto prepared_statement = db.prepare(some_statement);
```
You can now set the parameters and execute the prepared statement multiple times, e.g.
```C++
auto prepared_insert = db.prepare(
insert_into(tab).set(
tab.alpha = parameter(tab.alpha),
tab.beta = parameter(sqlpp::text(), cheese)
));
for (const auto& input : input_values)
{
prepared_insert.params.alpha = input.first;
prepared_insert.params.cheese = input.second;
db(prepared_insert);
}
```
Note: need nicer examples...

View File

@ -0,0 +1,20 @@
Since `delete` is keyword in C++ that has a different meaning than `delete` in SQL, sqlpp11 calls the method remove. There is no detailed documentation available yet, but here is an example that might help if you have read about [select statements](Select.md) already:
```C++
db(remove_from(tab).where(tab.alpha == tab.alpha + 3));
```
## Removing using multiple tables as condition:
```C++
test_sqlpp::Users usr;
test_sqlpp::UsersForms usr_forms;
test_sqlpp::Forms form_;
db(remove_from(usr_forms).using_(usr, form_, usr_forms).where(
usr_forms.iduser == usr.id
and usr.username == username
and usr_forms.idform == form_.id
and form_.name == form_name
));
```

View File

@ -0,0 +1,242 @@
# Introduction
_This page explains select statements with a static structure. If you want to learn about constructing select statements at runtime, you should still read this page first and then move on to [dynamic select statements](Dynamic-Select.md)._
Lets assume we have a table representing
```SQL
CREATE TABLE foo (
id bigint,
name varchar(50),
hasFun bool
);
```
(This is SQL for brevity, not C++, see [here](Tables.md) for details on how to define types representing the tables and columns you want to work with)
Lets also assume we have an object `db` representing a connection to your [database](Database.md).
# A Basic example
This shows how you can select some data from table and iterate over the results:
```C++
for (const auto& row : db(select(foo.name, foo.hasFun)
.from(foo)
.where(foo.id > 17 and foo.name.like("%bar%"))))
{
if (row.name.is_null())
std::cerr << "name is null" << std::endl;
else
std::string name = row.name; // string-like fields are implicitly convertible to string
bool hasFun = row.hasFun; // bool fields are implicitly convertible to bool
}
```
So, what's happening here? Lets ignore the gory details for a moment. Well, there is a select statement.
```C++
select(foo.name, foo.hasFun)
.from(foo)
.where(foo.id > 17 and foo.name.like("%bar%"))
```
It selects two columns `name` and `hasFun` from table `foo` for rows which match the criteria given in the where condition. That's about as close to _real_ SQL as it can get...
The select expression is fed into the call operator of the connection object `db`. This method sends the select statement to the database and returns an object representing the results. In the case of select statements, the result object represents zero or more rows.
One way of accessing the rows is to iterate over them in a range-based for loop.
```C++
for (const auto& row : ...)
```
Ok, so the variable row is an object that represents a single result row. You really want to use `auto` here, because you don't want to write down the actual type. Trust me. But the wonderful thing about the `row` object is that it has appropriately named and typed members representing the columns you selected. This is one of the utterly cool parts of this library.
# The Select Statement
## Select
The `select` method takes zero or more named expression arguments.
Named expressions are expressions with a name. No surprise there. But what kind of expressions have a name? Table columns, for instance. In our example, that would be `foo.id`, `foo.name` and `foo.hasFun`. Most [function](Functions.md) calls also result in named expressions, like `count(foo.id)`.
So what about unnamed expressions? Results of binary operators like `(foo.id + 17) * 4` have no name. But you can give them a name using the `as(alias)` method. The easiest way is to use a named expression as alias, for instance `((foo.id + 17) * 4).as(foo.id)`, e.g.
```C++
for (const auto& row : db(select(((foo.id + 17) * 4).as(foo.id)).from(tab)))
{
std::cout << row.id << std::endl;
}
```
Another option is to define an alias like this:
```C++
SQLPP_ALIAS_PROVIDER(total);
for (const auto& row : db(select(sum(id).as(total)).as(foo.id)).from(tab)))
{
std::cout << row.total << std::endl;
}
```
Using aliases also comes in handy when you join tables and have several columns of the same name, because no two named expressions in a select must have the same name. So if you want to do something like
```C++
select(foo.id, bar.id); // compile error
```
One of the columns needs an alias.
```C++
SQLPP_ALIAS_PROVIDER(barId);
select(foo.id, bar.id.as(barId));
```
### Select Columns
All examples above called the `select()` function with one or more arguments, but `select()` can also be called with no arguments. In that case, the selected columns have to be added afterwards
```C++
sqlpp::select().columns(foo.id, foo.name);
```
See also [dynamic select statements](Dynamic-Select.md).
### Select Flags
The following flags are currently supported:
* sqlpp::all
* sqlpp::distinct
Flags are added via the `flags()` method:
```C++
sqlpp::select().flags(sqlpp::all).columns(foo.id, foo.name);
```
or
```C++
select(foo.id, foo.name).flags(sqlpp::all);
```
The latter is shorter than the former, but the former is closer to SQL syntax and probably easier to read.
### Sub-Select
A select statement with one column also is named expression. This means you can use one select as a sub-select column of another select. For example:
```
for (const auto& row : db(
select(all_of(foo),
select(sum(bar.value)).from(bar).where(bar.id > foo.id))
.from(foo)))
{
int x = row.id;
int a = row.sum;
}
```
The name of the sub select is the name of the one column. If required, you can rename it using `as()`, as usual.
### Select All Columns
Statements like `SELECT * from foo` is used pretty often in SQL. sqlpp11 offers something similar:
```C++
select(all_of(foo));
```
## From
The `from` method expects one argument. The following subsections expand on the types of valid arguments:
* tables
* tables with an alias (via the `as` method)
* sub-selects with an alias
* joins
### Tables
This is the most simple case.
```C++
select(all_of(foo)).from(foo);
```
### Aliased Tables
Table aliases are useful in self-joins.
```C++
SQLPP_ALIAS_PROVIDER(left);
SQLPP_ALIAS_PROVIDER(right);
auto l = foo.as(left);
auto r = foo.as(right);
select(all_of(l)).from(l.join(r).on(l.x == r.y));
```
Aliased tables might also be used to increase the readability of generated SQL code, for instance if you have very long table names.
### Aliased Sub-Select
A select can be used as a pseudo table in another select. You just have to give it a name.
```C++
SQLPP_ALIAS_PROVIDER(sub);
auto sub_select = select(all_of(foo)).from(foo).as(sub);
```
The variable `sub_select` can be used as a table now.
### Joins
You can join two tables like this:
```C++
foo.join(bar).on(foo.id == bar.foo);
```
If you want to join more tables, you can chain joins.
```C++
foo.join(bar).on(foo.id == bar.foo).left_outer_join(baz).on(bar.id == baz.ref);
```
_Hint_: Omitting the call to `on` will result in mildly horrible error messages...
## Where
The where condition can be set via the `where` method, which takes a boolean expression argument, for instance:
```C++
select(all_of(foo)).from(foo).where(foo.id != 17 and foo.name.like("%cake"));
```
## Group By
The method `group_by` takes one or more expression arguments, for instance:
```C++
select(all_of(foo)).from(foo).group_by(foo.name);
```
## Having
The having condition can be set via the `having` method, just like the `where` method.
## Order By
The `order_by` method takes one of more order expression, which are normal expression adorned with `.asc()` or `.desc()`, e.g.
```C++
select(all_of(foo)).from(foo).order_by(foo.name.asc());
```
## Limit And Offset
The methods `limit` and `offset` take a size_t argument, for instance:
```C++
select(all_of(foo)).from(foo).limit(10u).offset(20u);
```
## For Update
The `for_update` method modifies the query with a simplified "FOR UPDATE" clause without columns.
```C++
select(all_of(foo)).from(foo).where(foo.id != 17).for_update();
```
# Running The Statement
OK, so now we know how to create a select statement. But the statement does not really do anything unless we hand it over to the database:
```C++
db(select(all_of(foo)).from(foo));
```
This call returns a result object of a pretty complex type. Thus, you would normally want to use `auto`:
```C++
auto result = db(select(all_of(foo)).from(foo));
```
# Accessing The Results
The `result` object created by executing a `select` query is a container of result rows.
## Range-based For Loops
Not surprisingly, you can iterate over the rows using a range-based for-loop like this:
```C++
for (const auto& row : db(select(all_of(foo)).from(foo)))
{
std::cerr << row.id << std::endl;
std::cerr << row.name << std::endl;
}
```
Lovely, isn't it? The row objects have types specifically tailored for the select query you wrote. You can access their member by name, and these members have the expected type.
## Function-based Access
If for some reason, you don't want to use range-based for-loops, you can use `front()` and `pop_front()` on the result, like this:
```C++
while(!result.empty())
{
const auto& row = result.front();
std::cerr << row.id << std::endl;
std::cerr << row.name << std::endl;
result.pop_front();
}

View File

@ -0,0 +1,8 @@
# Tables
In order to build meaningful SQL statements with sqlpp11, you need to represent tables and their columns as structs that can be understood by the library.
The default way to do so is by using a code generator to translate DDL to C++. A code generator covering a lot of use cases can be found [here](https://github.com/rbock/sqlpp11/blob/main/scripts/ddl2cpp). There is also a specific one for [sqlite3](https://github.com/rbock/sqlpp11/blob/main/scripts/sqlite2cpp.py).
If you look at the output, you will see why a generator is helpful. Here is a [sample](https://github.com/rbock/sqlpp11/blob/main/tests/core/usage/Sample.h).

View File

@ -0,0 +1,19 @@
# Thread Safety
sqlpp11 aspires to have no influence on thread safety itself, but offers
no particular guarantees (PRs welcome). This means that in the general case
your program may have problems if it does one of the following
* Creates a connection in one thread and then uses it in another thread..
* Uses the same connection simultaneously in multiple threads.
The exact level of thread-safety depends on the underlying client library, for
example with MySQL, PostgreSQL and SQLite3 it is generally safe to create a
connection in one thread and then use it in another thread, but attempting to
use the same connection simultaneously in multiple threads causes crashes,
lock-ups and SQL errors.
The recommendation therefore is to **not share** connections between threads
and to read about thread safety of the underlying database for more
information. You may also look into [Connection Pools](Connection-Pools.md)
as a way to make SQL queries simultaneously in multiple threads.

View File

@ -0,0 +1,44 @@
# Transactions
Transactions are simple in sqlpp11. Assuming you have a connection called `db`,
you can start and commit a transaction just like this:
```C++
auto tx = start_transaction(db);
// do something
tx.commit();
```
If you need to rollback the transaction, you can call it's `rollback()` member,
for instance like this:
```C++
auto tx = start_transaction(db);
try
{
// do something
tx.commit();
}
catch (...)
{
tx.rollback();
}
```
In case you call neither `commit()` nor `rollback()` on a transaction before it
goes out of scope, it will call `rollback()` in its destructor. This automatic
rollback will be reported by the connection.
## More options
You can turn off reporting for automatic rollback in the destructor by passing
`sqlpp::quiet_auto_rollback`.
```C++
auto tx = start_transaction(db, sqlpp::quiet_auto_rollback);
```
You can also specify the isolation level for the transaction:
```C++
auto tx = start_transaction(db, ::sqlpp::isolation_level::repeatable_read);
```

View File

@ -0,0 +1,5 @@
The detailed documentation is still missing here, but here is an example that might help if you have read about [select statements](Select.md).
```C++
db(update(tab).set(tab.gamma = false).where(tab.alpha.in(1)));
```

View File

@ -0,0 +1,48 @@
# Copyright (c) 2023, Vesselin Atanasov
# 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.
cmake_minimum_required(VERSION 3.14)
set (APP_NAME "connection_pool")
project ("${APP_NAME}" CXX)
set (CMAKE_CXX_STANDARD 11)
set (CMAKE_CXX_STANDARD_REQUIRED true)
set (CMAKE_CXX_EXTENSIONS false)
# Executable file and its build settings
add_executable ("${APP_NAME}")
target_include_directories ("${APP_NAME}" PRIVATE "${GEN_HEADERS_DIR}" "${PROJECT_SOURCE_DIR}/src")
# Linked libraries
find_package (Sqlpp11 REQUIRED COMPONENTS PostgreSQL)
target_link_libraries ("${APP_NAME}" PRIVATE sqlpp11::postgresql)
# Project sources
target_sources (
"${APP_NAME}" PRIVATE
"src/db_connection.h"
"src/db_connection.cpp"
"src/db_global.h"
"src/db_global.cpp"
"src/main.cpp"
)

View File

@ -0,0 +1,15 @@
#include <memory>
#include <db_connection.h>
db_connection::pq_conn& db_connection::fetch()
{
if (m_conn_ptr == nullptr)
{
m_conn_ptr = sqlpp::compat::make_unique<pq_conn>(m_pool.get());
}
return *m_conn_ptr;
}
db_connection::db_connection(sqlpp::postgresql::connection_pool& pool) : m_pool{pool}, m_conn_ptr{nullptr}
{
}

View File

@ -0,0 +1,31 @@
#pragma once
#include <sqlpp11/postgresql/postgresql.h>
class db_connection
{
private:
using pq_conn = sqlpp::postgresql::pooled_connection;
sqlpp::postgresql::connection_pool& m_pool;
// For C++17 or newer just use std::optional<pq_conn> m_conn;
std::unique_ptr<pq_conn> m_conn_ptr;
pq_conn& fetch();
public:
db_connection(sqlpp::postgresql::connection_pool& pool);
db_connection(const db_connection&) = delete;
db_connection(db_connection&&) = delete;
db_connection& operator=(const db_connection&) = delete;
db_connection& operator=(db_connection&&) = delete;
// Delegate any methods of sqlpp::postgresql::connection that you may need
template <typename T>
auto operator()(const T& t) -> decltype(fetch()(t))
{
return fetch()(t);
}
};

View File

@ -0,0 +1,12 @@
#include <db_connection.h>
#include <sqlpp11/postgresql/postgresql.h>
static sqlpp::postgresql::connection_pool g_db_pool{};
thread_local db_connection g_dbc{g_db_pool};
void db_global_init(std::shared_ptr<sqlpp::postgresql::connection_config> config)
{
g_db_pool.initialize(config, 5);
}

View File

@ -0,0 +1,7 @@
#pragma once
#include <db_connection.h>
extern thread_local db_connection g_dbc;
void db_global_init(std::shared_ptr<sqlpp::postgresql::connection_config> config);

View File

@ -0,0 +1,38 @@
#include <db_global.h>
#include <sqlpp11/postgresql/postgresql.h>
#include <sqlpp11/sqlpp11.h>
#include <memory>
#include <thread>
int main()
{
// Initialize the global connection variable
auto config = std::make_shared<sqlpp::postgresql::connection_config>();
config->dbname = "my_database";
config->user = "my_username";
config->password = "my_password";
config->debug = false;
db_global_init(config);
// Spawn 10 threads and make them send SQL queries in parallel
int num_threads = 10;
int num_queries = 5;
std::vector<std::thread> threads {};
for (int i = 0; i < num_threads; ++i)
{
threads.push_back(std::thread([&] () {
for (int j = 0; j < num_queries; ++j)
{
g_dbc(select (sqlpp::value (1).as(sqlpp::alias::a)));
}
}));
}
for (auto&& t : threads)
{
t.join();
}
return 0;
}

View File

@ -0,0 +1,38 @@
# Copyright (c) 2020, Leon De Andrade
# 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.
### Preamble ###
cmake_minimum_required(VERSION 3.14)
project(Test VERSION 0.1 LANGUAGES CXX)
##### Project wide setup ####
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
### Dependencies ###
add_subdirectory(dependencies)
### Main Targets ###
add_subdirectory(src)

View File

@ -0,0 +1,32 @@
# Copyright (c) 2020, Leon De Andrade
# 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(FetchContent)
FetchContent_Declare(sqlpp11
GIT_REPOSITORY https://github.com/rbock/sqlpp11
GIT_TAG origin/main
)
add_subdirectory(sqlpp11)

View File

@ -0,0 +1,34 @@
# Copyright (c) 2020, Leon De Andrade
# 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.
# Configure the project here as needed
# set(BUILD_MYSQL_CONNECTOR ON)
# set(BUILD_MARIADB_CONNECTOR ON)
# set(BUILD_POSTGRESQL_CONNECTOR ON)
# set(BUILD_SQLITE3_CONNECTOR ON)
# set(BUILD_SQLCIPHER_CONNECTOR ON)
# set(USE_SYSTEM_DATE ON)
FetchContent_MakeAvailable(sqlpp11)

View File

@ -0,0 +1,40 @@
# Copyright (c) 2020, Leon De Andrade
# 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.
add_executable(Test)
target_link_libraries(Test
PRIVATE
sqlpp11::sqlpp11
# Corresponding targets for the connectors. These connectors need to be enabled in the the dependencies/sqlpp11 folder. These targets automatically link against sqlpp11::sqlpp11 and therefore sqlpp11::sqlpp11 doesn't need to be linked manually again
# sqlpp11::sqlite3
# sqlpp11::sqlcipher
# sqlpp11::mysql
# sqlpp11::mariadb
# sqlpp11::postgresql
)
target_sources(Test
PRIVATE
main.cpp
)

View File

@ -0,0 +1,8 @@
#include <sqlpp11/select.h>
#include <sqlpp11/alias_provider.h>
int main()
{
select(sqlpp::value(false).as(sqlpp::alias::a));
return 0;
}

View File

@ -0,0 +1,42 @@
# Copyright (c) 2020, Leon De Andrade
# 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.
### Preamble ###
cmake_minimum_required(VERSION 3.14)
project(Test VERSION 0.1 LANGUAGES CXX)
##### Project wide setup ####
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
### Dependencies ###
find_package(Sqlpp11
# Optionally specify connectors needed to get corresponding targets. Only possible if connectors have been installed on the system as documented in the README
# COMPONENTS SQLite3 SQLCipher MySQL MariaDB PostgreSQL
REQUIRED
)
### Main Targets ###
add_subdirectory(src)

View File

@ -0,0 +1,39 @@
# Copyright (c) 2020, Leon De Andrade
# 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.
add_executable(Test)
target_link_libraries(Test
PRIVATE
sqlpp11::sqlpp11
# Corresponding targets for the Components specified in the find_package call
# sqlpp11::sqlite3
# sqlpp11::sqlcipher
# sqlpp11::mysql
# sqlpp11::mariadb
# sqlpp11::postgresql
)
target_sources(Test
PRIVATE
main.cpp
)

View File

@ -0,0 +1,8 @@
#include <sqlpp11/select.h>
#include <sqlpp11/alias_provider.h>
int main()
{
select(sqlpp::value(false).as(sqlpp::alias::a));
return 0;
}

View File

@ -0,0 +1,39 @@
#pragma once
/*
* 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.
*/
namespace sqlpp
{
template <typename Expr>
struct aggregate_function_operators
{
over_t<Expr> over() const
{
return {*static_cast<const Expr*>(this)};
}
};
} // namespace sqlpp

View File

@ -0,0 +1,33 @@
#pragma once
/*
* Copyright (c) 2013-2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/aggregate_functions/count.h>
#include <sqlpp11/aggregate_functions/min.h>
#include <sqlpp11/aggregate_functions/max.h>
#include <sqlpp11/aggregate_functions/avg.h>
#include <sqlpp11/aggregate_functions/sum.h>

View File

@ -0,0 +1,116 @@
#pragma once
/*
* 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.
*/
#include <sqlpp11/type_traits.h>
#include <sqlpp11/char_sequence.h>
namespace sqlpp
{
struct avg_alias_t
{
struct _alias_t
{
static constexpr const char _literal[] = "avg_";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T avg;
T& operator()()
{
return avg;
}
const T& operator()() const
{
return avg;
}
};
};
};
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>;
using _nodes = detail::type_vector<Expr, aggregate_function>;
using _can_be_null = std::true_type;
using _is_aggregate_expression = std::true_type;
static_assert(is_noop<Flag>::value or std::is_same<distinct_t, Flag>::value,
"avg() used with flag other than 'distinct'");
static_assert(is_numeric_t<Expr>::value, "avg() requires a value expression as argument");
using _auto_alias_t = avg_alias_t;
avg_t(Expr expr) : _expr(expr)
{
}
avg_t(const avg_t&) = default;
avg_t(avg_t&&) = default;
avg_t& operator=(const avg_t&) = default;
avg_t& operator=(avg_t&&) = default;
~avg_t() = default;
Expr _expr;
};
template <typename Context, typename Flag, typename Expr>
Context& serialize(const avg_t<Flag, Expr>& t, Context& context)
{
context << "AVG(";
if (std::is_same<distinct_t, Flag>::value)
{
serialize(Flag(), context);
context << ' ';
}
serialize_operand(t._expr, context);
context << ")";
return context;
}
template <typename T>
auto avg(T t) -> avg_t<noop, wrap_operand_t<T>>
{
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value,
"avg() cannot be used on an aggregate function");
static_assert(is_numeric_t<wrap_operand_t<T>>::value, "avg() requires a numeric value expression as argument");
return {t};
}
template <typename T>
auto avg(const distinct_t& /*unused*/, T t) -> avg_t<distinct_t, wrap_operand_t<T>>
{
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value,
"avg() cannot be used on an aggregate function");
static_assert(is_numeric_t<wrap_operand_t<T>>::value, "avg() requires a numeric value expression as argument");
return {t};
}
} // namespace sqlpp

View File

@ -0,0 +1,119 @@
#pragma once
/*
* 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.
*/
#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
{
struct count_alias_t
{
struct _alias_t
{
static constexpr const char _literal[] = "count_";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T count;
T& operator()()
{
return count;
}
const T& operator()() const
{
return count;
}
};
};
};
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*/>;
using _nodes = detail::type_vector<Expr, aggregate_function>;
using _can_be_null = std::false_type;
using _is_aggregate_expression = std::true_type;
static_assert(is_noop<Flag>::value or std::is_same<distinct_t, Flag>::value,
"count() used with flag other than 'distinct'");
using _auto_alias_t = count_alias_t;
count_t(const Expr expr) : _expr(expr)
{
}
count_t(const count_t&) = default;
count_t(count_t&&) = default;
count_t& operator=(const count_t&) = default;
count_t& operator=(count_t&&) = default;
~count_t() = default;
Expr _expr;
};
template <typename Context, typename Flag, typename Expr>
Context& serialize(const count_t<Flag, Expr>& t, Context& context)
{
context << "COUNT(";
if (std::is_same<distinct_t, Flag>::value)
{
serialize(Flag(), context);
context << ' ';
}
serialize_operand(t._expr, context);
context << ")";
return context;
}
template <typename T>
auto count(T t) -> count_t<noop, wrap_operand_t<T>>
{
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value,
"count() cannot be used on an aggregate function");
static_assert(is_expression_t<wrap_operand_t<T>>::value, "count() requires an expression as argument");
return {t};
}
template <typename T>
auto count(const distinct_t& /*unused*/, T t) -> count_t<distinct_t, wrap_operand_t<T>>
{
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value,
"count() cannot be used on an aggregate function");
static_assert(is_expression_t<wrap_operand_t<T>>::value, "count() requires an expression as argument");
return {t};
}
} // namespace sqlpp

View File

@ -0,0 +1,112 @@
#pragma once
/*
* 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.
*/
#include <sqlpp11/type_traits.h>
#include <sqlpp11/char_sequence.h>
namespace sqlpp
{
struct max_alias_t
{
struct _alias_t
{
static constexpr const char _literal[] = "max_";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T max;
T& operator()()
{
return max;
}
const T& operator()() const
{
return max;
}
};
};
};
template <typename Flag, typename Expr>
struct max_t : public expression_operators<max_t<Flag, Expr>, value_type_of<Expr>>,
public aggregate_function_operators<max_t<Flag, Expr>>,
public alias_operators<max_t<Flag, Expr>>
{
using _traits = make_traits<value_type_of<Expr>, tag::is_expression, tag::is_selectable>;
using _nodes = detail::type_vector<Expr, aggregate_function>;
using _can_be_null = std::true_type;
using _is_aggregate_expression = std::true_type;
using _auto_alias_t = max_alias_t;
max_t(Expr expr) : _expr(expr)
{
}
max_t(const max_t&) = default;
max_t(max_t&&) = default;
max_t& operator=(const max_t&) = default;
max_t& operator=(max_t&&) = default;
~max_t() = default;
Expr _expr;
};
template <typename Context, typename Flag, typename Expr>
Context& serialize(const max_t<Flag, Expr>& t, Context& context)
{
context << "MAX(";
if (std::is_same<distinct_t, Flag>::value)
{
serialize(Flag(), context);
context << ' ';
}
serialize_operand(t._expr, context);
context << ")";
return context;
}
template <typename T>
auto max(T t) -> max_t<noop, wrap_operand_t<T>>
{
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value,
"max() cannot be used on an aggregate function");
static_assert(is_expression_t<wrap_operand_t<T>>::value, "max() requires an expression as argument");
return {t};
}
template <typename T>
auto max(const distinct_t& /*unused*/, T t) -> max_t<distinct_t, wrap_operand_t<T>>
{
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value,
"max() cannot be used on an aggregate function");
static_assert(is_expression_t<wrap_operand_t<T>>::value, "max() requires an expression as argument");
return {t};
}
} // namespace sqlpp

View File

@ -0,0 +1,112 @@
#pragma once
/*
* 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.
*/
#include <sqlpp11/type_traits.h>
#include <sqlpp11/char_sequence.h>
namespace sqlpp
{
struct min_alias_t
{
struct _alias_t
{
static constexpr const char _literal[] = "min_";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T min;
T& operator()()
{
return min;
}
const T& operator()() const
{
return min;
}
};
};
};
template <typename Flag, typename Expr>
struct min_t : public expression_operators<min_t<Flag, Expr>, value_type_of<Expr>>,
public aggregate_function_operators<min_t<Flag, Expr>>,
public alias_operators<min_t<Flag, Expr>>
{
using _traits = make_traits<value_type_of<Expr>, tag::is_expression, tag::is_selectable>;
using _nodes = detail::type_vector<Expr, aggregate_function>;
using _can_be_null = std::true_type;
using _is_aggregate_expression = std::true_type;
using _auto_alias_t = min_alias_t;
min_t(Expr expr) : _expr(expr)
{
}
min_t(const min_t&) = default;
min_t(min_t&&) = default;
min_t& operator=(const min_t&) = default;
min_t& operator=(min_t&&) = default;
~min_t() = default;
Expr _expr;
};
template <typename Context, typename Flag, typename Expr>
Context& serialize(const min_t<Flag, Expr>& t, Context& context)
{
context << "MIN(";
if (std::is_same<distinct_t, Flag>::value)
{
serialize(Flag(), context);
context << ' ';
}
serialize_operand(t._expr, context);
context << ")";
return context;
}
template <typename T>
auto min(T t) -> min_t<noop, wrap_operand_t<T>>
{
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value,
"min() cannot be used on an aggregate function");
static_assert(is_expression_t<wrap_operand_t<T>>::value, "min() requires an expression as argument");
return {t};
}
template <typename T>
auto min(const distinct_t& /*unused*/, T t) -> min_t<distinct_t, wrap_operand_t<T>>
{
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value,
"min() cannot be used on an aggregate function");
static_assert(is_expression_t<wrap_operand_t<T>>::value, "min() requires an expression as argument");
return {t};
}
} // namespace sqlpp

View File

@ -0,0 +1,116 @@
#pragma once
/*
* 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.
*/
#include <sqlpp11/type_traits.h>
#include <sqlpp11/char_sequence.h>
namespace sqlpp
{
struct sum_alias_t
{
struct _alias_t
{
static constexpr const char _literal[] = "sum_";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T sum;
T& operator()()
{
return sum;
}
const T& operator()() const
{
return sum;
}
};
};
};
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>;
using _nodes = detail::type_vector<Expr, aggregate_function>;
using _can_be_null = std::true_type;
using _is_aggregate_expression = std::true_type;
static_assert(is_noop<Flag>::value or std::is_same<distinct_t, Flag>::value,
"sum() used with flag other than 'distinct'");
static_assert(is_numeric_t<Expr>::value, "sum() requires a numeric expression as argument");
using _auto_alias_t = sum_alias_t;
sum_t(Expr expr) : _expr(expr)
{
}
sum_t(const sum_t&) = default;
sum_t(sum_t&&) = default;
sum_t& operator=(const sum_t&) = default;
sum_t& operator=(sum_t&&) = default;
~sum_t() = default;
Expr _expr;
};
template <typename Context, typename Flag, typename Expr>
Context& serialize(const sum_t<Flag, Expr>& t, Context& context)
{
context << "SUM(";
if (std::is_same<distinct_t, Flag>::value)
{
serialize(Flag(), context);
context << ' ';
}
serialize_operand(t._expr, context);
context << ")";
return context;
}
template <typename T>
auto sum(T t) -> sum_t<noop, wrap_operand_t<T>>
{
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value,
"sum() cannot be used on an aggregate function");
static_assert(is_numeric_t<wrap_operand_t<T>>::value, "sum() requires a numeric expression as argument");
return {t};
}
template <typename T>
auto sum(const distinct_t& /*unused*/, T t) -> sum_t<distinct_t, wrap_operand_t<T>>
{
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value,
"sum() cannot be used on an aggregate function");
static_assert(is_numeric_t<wrap_operand_t<T>>::value, "sum() requires a numeric expression as argument");
return {t};
}
} // namespace sqlpp

View File

@ -0,0 +1,65 @@
#pragma once
/*
* Copyright (c) 2013-2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/type_traits.h>
namespace sqlpp
{
template <typename Expression, typename AliasProvider>
struct expression_alias_t
{
using _traits = make_traits<value_type_of<Expression>, tag::is_selectable, tag::is_alias>;
using _nodes = detail::type_vector<Expression>;
static_assert(is_expression_t<Expression>::value, "invalid argument for an expression alias");
static_assert(not is_alias_t<Expression>::value, "cannot create an alias of an alias");
using _alias_t = typename AliasProvider::_alias_t;
expression_alias_t(Expression expression) : _expression(expression)
{
}
expression_alias_t(const expression_alias_t&) = default;
expression_alias_t(expression_alias_t&&) = default;
expression_alias_t& operator=(const expression_alias_t&) = default;
expression_alias_t& operator=(expression_alias_t&&) = default;
~expression_alias_t() = default;
Expression _expression;
};
template <typename Context, typename Expression, typename AliasProvider>
Context& serialize(const expression_alias_t<Expression, AliasProvider>& t, Context& context)
{
serialize_operand(t._expression, context);
context << " AS ";
context << name_of<expression_alias_t<Expression, AliasProvider>>::template char_ptr<Context>();
return context;
}
} // namespace sqlpp

View File

@ -0,0 +1,42 @@
#pragma once
/*
* Copyright (c) 2013-2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/alias.h>
namespace sqlpp
{
template <typename Expr>
struct alias_operators
{
template <typename alias_provider>
expression_alias_t<Expr, alias_provider> as(const alias_provider& /*unused*/) const
{
return {*static_cast<const Expr*>(this)};
}
};
} // namespace sqlpp

View File

@ -0,0 +1,127 @@
#pragma once
/*
* Copyright (c) 2013-2016, 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 <type_traits>
#include <sqlpp11/char_sequence.h>
#define SQLPP_ALIAS_PROVIDER(name) \
struct name##_t \
{ \
struct _alias_t \
{ \
static constexpr const char _literal[] = #name; \
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>; \
template <typename T> \
struct _member_t \
{ \
T name; \
T& operator()() \
{ \
return name; \
} \
const T& operator()() const \
{ \
return name; \
} \
}; \
}; \
}; \
constexpr name##_t name = {};
#define SQLPP_QUOTED_ALIAS_PROVIDER(name) \
struct name##_t \
{ \
struct _alias_t \
{ \
static constexpr const char _literal[] = "!" #name; \
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>; \
template <typename T> \
struct _member_t \
{ \
T name; \
T& operator()() \
{ \
return name; \
} \
const T& operator()() const \
{ \
return name; \
} \
}; \
}; \
}; \
constexpr name##_t name = {};
namespace sqlpp
{
template <typename T, typename Enable = void>
struct is_alias_provider_t
{
static constexpr bool value = false;
};
template <typename T>
struct is_alias_provider_t<
T,
typename std::enable_if<std::is_class<typename T::_alias_t::template _member_t<int>>::value, void>::type>
{
static constexpr bool value = true;
};
namespace alias
{
SQLPP_ALIAS_PROVIDER(a)
SQLPP_ALIAS_PROVIDER(b)
SQLPP_ALIAS_PROVIDER(c)
SQLPP_ALIAS_PROVIDER(d)
SQLPP_ALIAS_PROVIDER(e)
SQLPP_ALIAS_PROVIDER(f)
SQLPP_ALIAS_PROVIDER(g)
SQLPP_ALIAS_PROVIDER(h)
SQLPP_ALIAS_PROVIDER(i)
SQLPP_ALIAS_PROVIDER(j)
SQLPP_ALIAS_PROVIDER(k)
SQLPP_ALIAS_PROVIDER(l)
SQLPP_ALIAS_PROVIDER(m)
SQLPP_ALIAS_PROVIDER(n)
SQLPP_ALIAS_PROVIDER(o)
SQLPP_ALIAS_PROVIDER(p)
SQLPP_ALIAS_PROVIDER(q)
SQLPP_ALIAS_PROVIDER(r)
SQLPP_ALIAS_PROVIDER(s)
SQLPP_ALIAS_PROVIDER(t)
SQLPP_ALIAS_PROVIDER(u)
SQLPP_ALIAS_PROVIDER(v)
SQLPP_ALIAS_PROVIDER(w)
SQLPP_ALIAS_PROVIDER(x)
SQLPP_ALIAS_PROVIDER(y)
SQLPP_ALIAS_PROVIDER(z)
SQLPP_ALIAS_PROVIDER(left)
SQLPP_ALIAS_PROVIDER(right)
} // namespace alias
} // namespace sqlpp

View File

@ -0,0 +1,36 @@
#pragma once
/*
* Copyright (c) 2013-2021, 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.
*/
namespace sqlpp
{
template <typename Table>
auto all_of(Table /*unused*/) -> typename Table::_column_tuple_t
{
return {};
}
} // namespace sqlpp

View File

@ -0,0 +1,71 @@
#pragma once
/*
* Copyright (c) 2013-2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/data_types/boolean.h>
#include <sqlpp11/char_sequence.h>
#include <sqlpp11/detail/type_set.h>
namespace sqlpp
{
template <typename Select>
struct any_t
{
using _traits = make_traits<value_type_of<Select>, tag::is_multi_expression>;
using _nodes = detail::type_vector<Select>;
any_t(Select select) : _select(select)
{
}
any_t(const any_t&) = default;
any_t(any_t&&) = default;
any_t& operator=(const any_t&) = default;
any_t& operator=(any_t&&) = default;
~any_t() = default;
Select _select;
};
template <typename Context, typename Select>
Context& serialize(const any_t<Select>& t, Context& context)
{
context << "ANY";
serialize_operand(t._select, context);
return context;
}
template <typename T>
auto any(T t) -> any_t<wrap_operand_t<T>>
{
static_assert(is_select_t<wrap_operand_t<T>>::value, "any() requires a select expression as argument");
static_assert(is_expression_t<wrap_operand_t<T>>::value,
"any() requires a single column select expression as argument");
// FIXME: can we accept non-values like NULL here?
return {t};
}
} // namespace sqlpp

View File

@ -0,0 +1,70 @@
#pragma once
/*
* Copyright (c) 2013-2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/default_value.h>
#include <sqlpp11/null.h>
#include <sqlpp11/serialize.h>
#include <sqlpp11/simple_column.h>
namespace sqlpp
{
template <typename Lhs, typename Rhs>
struct assignment_t
{
using _traits = make_traits<no_value_t, tag::is_assignment>;
using _lhs_t = Lhs;
using _rhs_t = Rhs;
using _nodes = detail::type_vector<_lhs_t, _rhs_t>;
static_assert(can_be_null_t<_lhs_t>::value ? true
: not std::is_same<_rhs_t, null_t>::value,
"column must not be null");
assignment_t(_lhs_t lhs, _rhs_t rhs) : _lhs(lhs), _rhs(rhs)
{
}
assignment_t(const assignment_t&) = default;
assignment_t(assignment_t&&) = default;
assignment_t& operator=(const assignment_t&) = default;
assignment_t& operator=(assignment_t&&) = default;
~assignment_t() = default;
_lhs_t _lhs;
_rhs_t _rhs;
};
template <typename Context, typename Lhs, typename Rhs>
Context& serialize(const assignment_t<Lhs, Rhs>& t, Context& context)
{
serialize(simple_column(t._lhs), context);
context << "=";
serialize_operand(t._rhs, context);
return context;
}
} // namespace sqlpp

View File

@ -0,0 +1,62 @@
#pragma once
/*
* Copyright (c) 2013-2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/alias.h>
namespace sqlpp
{
template <typename T, typename Enable = void>
struct has_auto_alias_t
{
static constexpr bool value = false;
};
template <typename T>
struct has_auto_alias_t<T, typename std::enable_if<not wrong_t<typename T::_auto_alias_t>::value>::type>
{
static constexpr bool value = true;
};
namespace detail
{
template <typename T, typename Enable = void>
struct auto_alias_impl
{
using type = T;
};
template <typename T>
struct auto_alias_impl<T, typename std::enable_if<has_auto_alias_t<T>::value>::type>
{
using type = expression_alias_t<T, typename T::_auto_alias_t>;
};
} // namespace detail
template <typename T>
using auto_alias_t = typename detail::auto_alias_impl<T>::type;
} // namespace sqlpp

View File

@ -0,0 +1,49 @@
#pragma once
/*
* Copyright (c) 2013-2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/portable_static_assert.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp
{
SQLPP_PORTABLE_STATIC_ASSERT(assert_valid_operands, "Invalid operand(s)");
template <typename ValueType>
struct bad_expression
{
template <typename... T>
bad_expression(T&&... /*unused*/)
{
}
using _traits = make_traits<ValueType, tag::is_expression>;
using _nodes = detail::type_vector<>;
};
template <typename Context, typename ValueType>
Context serialize(const bad_expression<ValueType>& t, Context& context);
} // namespace sqlpp

View File

@ -0,0 +1,316 @@
#pragma once
/*
* Copyright (c) 2013-2016, Roland Bock
* Copyright (c) 2016, Aaron Bishop
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/value_type_fwd.h>
#include <sqlpp11/bad_expression.h>
#include <sqlpp11/portable_static_assert.h>
#include <sqlpp11/consistent.h>
#include <sqlpp11/alias.h>
#include <sqlpp11/sort_order.h>
#include <sqlpp11/expression_fwd.h>
#include <sqlpp11/in_fwd.h>
#include <sqlpp11/is_null_fwd.h>
#include <sqlpp11/wrap_operand.h>
#include <sqlpp11/logic.h>
#include <sqlpp11/expression_return_types.h>
namespace sqlpp
{
SQLPP_PORTABLE_STATIC_ASSERT(assert_comparison_rhs_is_expression_t, "rhs operand in comparison is not an expression");
SQLPP_PORTABLE_STATIC_ASSERT(assert_comparison_rhs_is_valid_operand_t, "invalid rhs operand in comparison");
SQLPP_PORTABLE_STATIC_ASSERT(assert_comparison_lhs_rhs_differ_t, "identical lhs and rhs operands in comparison");
template <typename LhsType, typename RhsType>
using check_comparison_impl = static_combined_check_t<
static_check_t<logic::any_t<is_expression_t<RhsType>::value, is_multi_expression_t<RhsType>::value>::value,
assert_comparison_rhs_is_expression_t>,
static_check_t<value_type_of<LhsType>::template _is_valid_operand<RhsType>::value,
assert_comparison_rhs_is_valid_operand_t>,
static_check_t<not std::is_same<LhsType, RhsType>::value, assert_comparison_lhs_rhs_differ_t>>;
template <typename LhsType, typename RhsType>
using check_comparison_t = check_comparison_impl<LhsType, wrap_operand_t<RhsType>>;
template <typename LhsType, typename... RhsType>
using check_in_impl = static_combined_check_t<
static_check_t<logic::all_t<is_expression_t<RhsType>::value...>::value, assert_comparison_rhs_is_expression_t>,
static_check_t<logic::all_t<value_type_of<LhsType>::template _is_valid_operand<RhsType>::value...>::value,
assert_comparison_rhs_is_valid_operand_t>,
static_check_t<logic::none_t<std::is_same<LhsType, RhsType>::value...>::value,
assert_comparison_lhs_rhs_differ_t>>;
template <typename LhsType, typename... RhsType>
using check_in_t = check_in_impl<LhsType, typename wrap_operand<RhsType>::type...>;
namespace detail
{
template <bool Enable, template <typename Lhs, typename Rhs> class Expr, typename Lhs, typename Rhs>
struct comparison_expression_impl
{
using type = bad_expression<boolean>;
};
template <template <typename Lhs, typename Rhs> class Expr, typename Lhs, typename Rhs>
struct comparison_expression_impl<true, Expr, Lhs, Rhs>
{
using type = Expr<wrap_operand_t<Lhs>, wrap_operand_t<Rhs>>;
};
} // namespace detail
template <template <typename Lhs, typename Rhs> class Expr, typename Lhs, typename Rhs>
using comparison_expression_t =
typename detail::comparison_expression_impl<check_comparison_t<Lhs, Rhs>::value, Expr, Lhs, Rhs>::type;
namespace detail
{
template <bool Enable, template <typename Lhs, typename... Rhs> class Expr, typename Lhs, typename... Rhs>
struct in_expression_impl
{
using type = bad_expression<boolean>;
};
template <template <typename Lhs, typename... Rhs> class Expr, typename Lhs, typename... Rhs>
struct in_expression_impl<true, Expr, Lhs, Rhs...>
{
using type = Expr<Lhs, Rhs...>;
};
} // namespace detail
template <typename Check, template <typename Lhs, typename... Rhs> class Expr, typename Lhs, typename... Rhs>
using in_expression_t = typename detail::in_expression_impl<Check::value, Expr, Lhs, Rhs...>::type;
// basic operators
template <typename Expr>
struct basic_expression_operators
{
template <template <typename Lhs, typename Rhs> class NewExpr, typename T>
struct _new_binary_expression
{
using type = comparison_expression_t<NewExpr, Expr, T>;
};
template <template <typename Lhs, typename Rhs> class NewExpr, typename T>
using _new_binary_expression_t = typename _new_binary_expression<NewExpr, T>::type;
template <template <typename Lhs, typename... Rhs> class NewExpr, typename... T>
struct _new_nary_expression
{
using _check = check_in_t<Expr, T...>;
using type = in_expression_t<_check, NewExpr, Expr, wrap_operand_t<T>...>;
};
template <typename T>
auto operator==(T t) const -> _new_binary_expression_t<equal_to_t, T>
{
using rhs = wrap_operand_t<T>;
check_comparison_t<Expr, rhs>::verify();
return {*static_cast<const Expr*>(this), rhs{t}};
}
template <typename T>
auto operator!=(T t) const -> _new_binary_expression_t<not_equal_to_t, T>
{
using rhs = wrap_operand_t<T>;
check_comparison_t<Expr, rhs>::verify();
return {*static_cast<const Expr*>(this), rhs{t}};
}
template <typename T>
auto operator<(T t) const -> _new_binary_expression_t<less_than_t, T>
{
using rhs = wrap_operand_t<T>;
check_comparison_t<Expr, rhs>::verify();
return {*static_cast<const Expr*>(this), rhs{t}};
}
template <typename T>
auto operator<=(T t) const -> _new_binary_expression_t<less_equal_t, T>
{
using rhs = wrap_operand_t<T>;
check_comparison_t<Expr, rhs>::verify();
return {*static_cast<const Expr*>(this), rhs{t}};
}
template <typename T>
auto operator>(T t) const -> _new_binary_expression_t<greater_than_t, T>
{
using rhs = wrap_operand_t<T>;
check_comparison_t<Expr, rhs>::verify();
return {*static_cast<const Expr*>(this), rhs{t}};
}
template <typename T>
auto operator>=(T t) const -> _new_binary_expression_t<greater_equal_t, T>
{
using rhs = wrap_operand_t<T>;
check_comparison_t<Expr, rhs>{};
return {*static_cast<const Expr*>(this), rhs{t}};
}
auto is_null() const -> is_null_t<Expr>
{
return {*static_cast<const Expr*>(this)};
}
auto is_not_null() const -> is_not_null_t<Expr>
{
return {*static_cast<const Expr*>(this)};
}
auto asc() const -> sort_order_t<Expr>
{
return {*static_cast<const Expr*>(this), sort_type::asc};
}
auto desc() const -> sort_order_t<Expr>
{
return {*static_cast<const Expr*>(this), sort_type::desc};
}
auto order(sort_type s) const -> sort_order_t<Expr>
{
return {*static_cast<const Expr*>(this), s};
}
template <typename... T>
auto in(T... t) const -> typename _new_nary_expression<in_t, T...>::type
{
check_in_t<Expr, wrap_operand_t<T>...>::verify();
return {*static_cast<const Expr*>(this), typename wrap_operand<T>::type{t}...};
}
template <typename... T>
auto not_in(T... t) const -> typename _new_nary_expression<not_in_t, T...>::type
{
check_in_t<Expr, wrap_operand_t<T>...>::verify();
return {*static_cast<const Expr*>(this), typename wrap_operand<T>::type{t}...};
}
template <typename Defer = void>
auto operator not() const -> return_type_not_t<Expr, Defer>
{
return_type_not<Expr, Defer>::check::verify();
return {*static_cast<const Expr*>(this)};
}
template <typename R>
auto operator and(const R& r) const -> return_type_and_t<Expr, R>
{
return_type_and<Expr, R>::check::verify();
return {*static_cast<const Expr*>(this), wrap_operand_t<R>{r}};
}
template <typename R>
auto operator&(const R& r) const -> return_type_bitwise_and_t<Expr, R>
{
return_type_bitwise_and<Expr, R>::check::verify();
return {*static_cast<const Expr*>(this), wrap_operand_t<R>{r}};
}
template <typename R>
auto operator|(const R& r) const -> return_type_bitwise_or_t<Expr, R>
{
return_type_bitwise_or<Expr, R>::check::verify();
return {*static_cast<const Expr*>(this), wrap_operand_t<R>{r}};
}
template <typename R>
auto operator or(const R& r) const -> return_type_or_t<Expr, R>
{
return_type_or<Expr, R>::check::verify();
return {*static_cast<const Expr*>(this), wrap_operand_t<R>{r}};
}
template <typename R>
auto operator+(const R& r) const -> return_type_plus_t<Expr, R>
{
return_type_plus<Expr, R>::check::verify();
return {*static_cast<const Expr*>(this), wrap_operand_t<R>{r}};
}
template <typename R>
auto operator-(const R& r) const -> return_type_minus_t<Expr, R>
{
return_type_minus<Expr, R>::check::verify();
return {*static_cast<const Expr*>(this), wrap_operand_t<R>{r}};
}
template <typename R>
auto operator*(const R& r) const -> return_type_multiplies_t<Expr, R>
{
return_type_multiplies<Expr, R>::check::verify();
return {*static_cast<const Expr*>(this), wrap_operand_t<R>{r}};
}
template <typename R>
auto operator/(const R& r) const -> return_type_divides_t<Expr, R>
{
return_type_divides<Expr, R>::check::verify();
return {*static_cast<const Expr*>(this), wrap_operand_t<R>{r}};
}
template <typename R>
auto operator%(const R& r) const -> return_type_modulus_t<Expr, R>
{
return_type_modulus<Expr, R>::check::verify();
return {*static_cast<const Expr*>(this), wrap_operand_t<R>{r}};
}
template <typename Defer = void>
auto operator+() const -> return_type_unary_plus_t<Expr, Defer>
{
return_type_unary_plus<Expr, Defer>::check::verify();
return {*static_cast<const Expr*>(this)};
}
template <typename Defer = void>
auto operator-() const -> return_type_unary_minus_t<Expr, Defer>
{
return_type_unary_minus<Expr, Defer>::check::verify();
return {*static_cast<const Expr*>(this)};
}
template <typename R>
auto operator<<(const R& r) const -> return_type_shift_left_t<Expr, R>
{
return_type_shift_left<Expr, R>::check::verify();
return {*static_cast<const Expr*>(this), wrap_operand_t<R>{r}};
}
template <typename R>
auto operator>>(const R& r) const -> return_type_shift_right_t<Expr, R>
{
return_type_shift_right<Expr, R>::check::verify();
return {*static_cast<const Expr*>(this), wrap_operand_t<R>{r}};
}
};
} // namespace sqlpp

View File

@ -0,0 +1,74 @@
#pragma once
/*
* Copyright (c) 2013-2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/type_traits.h>
#include <sqlpp11/interpretable.h>
namespace sqlpp
{
template <typename Database>
struct boolean_expression_t : public expression_operators<boolean_expression_t<Database>, boolean>
{
using _traits = make_traits<boolean, tag::is_expression>;
using _nodes = detail::type_vector<>;
template <typename Expr>
boolean_expression_t(Expr expr) : _expr(expr)
{
static_assert(is_expression_t<Expr>::value, "boolean_expression requires a boolean expression argument");
static_assert(is_boolean_t<Expr>::value, "boolean_expression requires a boolean expression argument");
}
boolean_expression_t(const boolean_expression_t&) = default;
boolean_expression_t(boolean_expression_t&&) = default;
boolean_expression_t& operator=(const boolean_expression_t&) = default;
boolean_expression_t& operator=(boolean_expression_t&&) = default;
~boolean_expression_t() = default;
interpretable_t<Database> _expr;
};
template <typename Database, typename T>
boolean_expression_t<Database> boolean_expression(T t)
{
using Expr = wrap_operand_t<T>;
return {Expr{t}};
}
template <typename Database, typename T>
boolean_expression_t<Database> boolean_expression(const Database& /*unused*/, T t)
{
return boolean_expression<Database>(t);
}
template <typename Context, typename Database>
Context& serialize(const boolean_expression_t<Database>& t, Context& context)
{
return serialize(t._expr, context);
}
} // namespace sqlpp

View File

@ -0,0 +1,182 @@
#pragma once
/*
* Copyright (c) 2015-2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/char_sequence.h>
#include <sqlpp11/data_types/boolean.h>
#include <sqlpp11/detail/type_set.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp
{
SQLPP_PORTABLE_STATIC_ASSERT(assert_case_else_expression_t, "argument is not a value expression in else()");
SQLPP_PORTABLE_STATIC_ASSERT(assert_case_then_else_same_type_t,
"argument of then() and else() are not of the same type");
template <typename Then, typename Else>
using check_case_else_t = static_combined_check_t<
static_check_t<is_expression_t<wrap_operand_t<Else>>::value, assert_case_else_expression_t>,
static_check_t<logic::any_t<is_sql_null_t<Then>::value,
is_sql_null_t<wrap_operand_t<Else>>::value,
std::is_same<value_type_of<Then>, value_type_of<wrap_operand_t<Else>>>::value>::value,
assert_case_then_else_same_type_t>>;
SQLPP_PORTABLE_STATIC_ASSERT(assert_case_then_expression_t, "argument is not a value expression in then()");
template <typename Then>
using check_case_then_t =
static_check_t<logic::all_t<is_expression_t<wrap_operand_t<Then>>::value>::value, assert_case_then_expression_t>;
SQLPP_PORTABLE_STATIC_ASSERT(assert_case_when_boolean_expression_t,
"argument is not a boolean expression in case_when()");
template <typename When>
using check_case_when_t = static_check_t<
logic::all_t<is_boolean_t<wrap_operand_t<When>>::value, is_expression_t<wrap_operand_t<When>>::value>::value,
assert_case_when_boolean_expression_t>;
template <typename When, typename Then, typename Else>
struct case_t
: public expression_operators<
case_t<When, Then, Else>,
typename std::conditional<is_sql_null_t<Then>::value, value_type_of<Else>, value_type_of<Then>>::type>,
public alias_operators<case_t<When, Then, Else>>
{
using _traits = make_traits<value_type_of<Then>, tag::is_expression>;
using _nodes = detail::type_vector<When, Then, Else>;
case_t(When when, Then then, Else else_) : _when(when), _then(then), _else(else_)
{
}
case_t(const case_t&) = default;
case_t(case_t&&) = default;
case_t& operator=(const case_t&) = default;
case_t& operator=(case_t&&) = default;
~case_t() = default;
When _when;
Then _then;
Else _else;
};
template <typename When, typename Then>
class case_then_t
{
template <typename Else>
auto _else_impl(consistent_t /*unused*/, Else else_) -> case_t<When, Then, Else>
{
return {_when, _then, else_};
}
template <typename Check, typename Else>
auto _else_impl(Check, Else else_) -> inconsistent<Check>;
public:
case_then_t(When when, Then then) : _when(when), _then(then)
{
}
case_then_t(const case_then_t&) = default;
case_then_t(case_then_t&&) = default;
case_then_t& operator=(const case_then_t&) = default;
case_then_t& operator=(case_then_t&&) = default;
~case_then_t() = default;
template <typename Else>
auto else_(Else else_) -> decltype(this->_else_impl(check_case_else_t<Then, Else>{}, else_))
{
return _else_impl(check_case_else_t<Then, Else>{}, else_);
}
private:
When _when;
Then _then;
};
template <typename When>
class case_when_t
{
template <typename Then>
auto _then_impl(consistent_t /*unused*/, Then t) -> case_then_t<When, wrap_operand_t<Then>>
{
return {_when, t};
}
template <typename Check, typename Then>
auto _then_impl(Check, Then t) -> inconsistent<Check>;
public:
case_when_t(When when) : _when(when)
{
}
case_when_t(const case_when_t&) = default;
case_when_t(case_when_t&&) = default;
case_when_t& operator=(const case_when_t&) = default;
case_when_t& operator=(case_when_t&&) = default;
~case_when_t() = default;
template <typename Then>
auto then(Then t) -> decltype(this->_then_impl(check_case_then_t<Then>{}, t))
{
return _then_impl(check_case_then_t<Then>{}, t);
}
private:
When _when;
};
template <typename Context, typename When, typename Then, typename Else>
Context& serialize(const case_t<When, Then, Else>& t, Context& context)
{
context << "(CASE WHEN ";
serialize(t._when, context);
context << " THEN ";
serialize(t._then, context);
context << " ELSE ";
serialize(t._else, context);
context << " END)";
return context;
}
namespace detail
{
template <typename When>
auto case_when_impl(consistent_t /*unused*/, When when) -> case_when_t<wrap_operand_t<When>>
{
return {when};
}
template <typename Check, typename When>
auto case_when_impl(Check, When when) -> inconsistent<Check>;
} // namespace detail
template <typename When>
auto case_when(When when) -> decltype(detail::case_when_impl(check_case_when_t<When>{}, when))
{
return detail::case_when_impl(check_case_when_t<When>{}, when);
}
} // namespace sqlpp

View File

@ -0,0 +1,76 @@
#pragma once
/*
* Copyright (c) 2013-2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <type_traits>
#include <sqlpp11/detail/index_sequence.h>
namespace sqlpp
{
template <typename Context>
std::integral_constant<char, '"'> get_quote_left(const Context&);
template <typename Context>
std::integral_constant<char, '"'> get_quote_right(const Context&);
template <char... Cs>
struct char_sequence
{
template <typename Context>
static const char* char_ptr()
{
static char s[] = {Cs..., '\0'};
return s;
}
};
template <char... Cs>
struct char_sequence<'!', Cs...>
{
template <typename Context>
static const char* char_ptr()
{
static char s[] = {decltype(get_quote_left(std::declval<Context>()))::value, Cs...,
decltype(get_quote_right(std::declval<Context>()))::value, '\0'};
return s;
}
};
template <std::size_t N, const char* s, typename T>
struct make_char_sequence_impl;
template <std::size_t N, const char* s, std::size_t... i>
struct make_char_sequence_impl<N, s, sqlpp::detail::index_sequence<i...>>
{
using type = char_sequence<s[i]...>;
};
template <std::size_t N, const char* Input>
using make_char_sequence =
typename make_char_sequence_impl<N, Input, sqlpp::detail::make_index_sequence<N - 1>>::type;
} // namespace sqlpp

View File

@ -0,0 +1,54 @@
#pragma once
/*
* Copyright (c) 2015-2016, Roland Bock, Aaron Bishop
* 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 <date/date.h>
namespace sqlpp
{
namespace chrono
{
using days = std::chrono::duration<int, std::ratio<86400, 1>>;
using day_point = std::chrono::time_point<std::chrono::system_clock, days>;
using microsecond_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::microseconds>;
#if _MSC_FULL_VER >= 190023918
// MSVC Update 2 provides floor, ceil, round, abs in chrono (which is C++17 only...)
using ::std::chrono::floor;
#else
using ::date::floor;
#endif
template <typename T>
std::chrono::microseconds time_of_day(T t)
{
const auto dp = floor<days>(t);
return std::chrono::duration_cast<std::chrono::microseconds>(::date::make_time(t - dp).to_duration());
}
} // namespace chrono
} // namespace sqlpp

View File

@ -0,0 +1,119 @@
#pragma once
/*
* Copyright (c) 2013-2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/alias.h>
#include <sqlpp11/column_fwd.h>
#include <sqlpp11/default_value.h>
#include <sqlpp11/null.h>
#include <sqlpp11/sort_order.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/assignment.h>
#include <sqlpp11/expression.h>
#include <sqlpp11/wrong.h>
#include <sqlpp11/detail/type_set.h>
namespace sqlpp
{
template <typename Table, typename ColumnSpec>
struct column_t : public expression_operators<column_t<Table, ColumnSpec>, value_type_of<ColumnSpec>>,
public column_operators<column_t<Table, ColumnSpec>, value_type_of<ColumnSpec>>
{
struct _traits
{
using _value_type = value_type_of<ColumnSpec>;
using _tags = detail::make_joined_set_t<detail::type_set<tag::is_column, tag::is_expression, tag::is_selectable>,
typename ColumnSpec::_traits::_tags>;
};
using _nodes = detail::type_vector<>;
using _required_tables = detail::type_set<Table>;
using _can_be_null = column_spec_can_be_null_t<ColumnSpec>;
using _spec_t = ColumnSpec;
using _table = Table;
using _alias_t = typename _spec_t::_alias_t;
template <typename T>
using _is_valid_assignment_operand = is_valid_assignment_operand<value_type_of<ColumnSpec>, T>;
// disambiguation for C++20 / clang
// (see https://bugs.llvm.org/show_bug.cgi?id=46508)
using expression_operators<column_t<Table, ColumnSpec>, value_type_of<ColumnSpec>>::operator==;
using expression_operators<column_t<Table, ColumnSpec>, value_type_of<ColumnSpec>>::operator!=;
column_t() = default;
column_t(const column_t&) = default;
column_t(column_t&&) = default;
column_t& operator=(const column_t&) = default;
column_t& operator=(column_t&&) = default;
~column_t() = default;
template <typename T = _table>
auto table() const -> _table
{
static_assert(is_table_t<T>::value, "cannot call get_table for columns of a sub-selects or cte");
return _table{};
}
template <typename alias_provider>
expression_alias_t<column_t, alias_provider> as(const alias_provider& /*unused*/) const
{
return {*this};
}
template <typename T>
auto operator=(T t) const -> assignment_t<column_t, wrap_operand_t<T>>
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_assignment_operand<rhs>::value, "invalid rhs assignment operand");
return {*this, {rhs{t}}};
}
auto operator=(null_t /*unused*/) const -> assignment_t<column_t, null_t>
{
static_assert(can_be_null_t<column_t>::value, "column cannot be null");
return {*this, null_t{}};
}
auto operator=(default_value_t /*unused*/) const -> assignment_t<column_t, default_value_t>
{
return {*this, default_value_t{}};
}
};
template <typename Context, typename Table, typename ColumnSpec>
Context& serialize(const column_t<Table, ColumnSpec>&, Context& context)
{
using T = column_t<Table, ColumnSpec>;
context << name_of<typename T::_table>::template char_ptr<Context>() << '.'
<< name_of<T>::template char_ptr<Context>();
return context;
}
} // namespace sqlpp

View File

@ -0,0 +1,33 @@
#pragma once
/*
* Copyright (c) 2013-2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace sqlpp
{
template <typename Table, typename ColumnSpec>
struct column_t;
} // namespace sqlpp

View File

@ -0,0 +1,29 @@
#pragma once
/*
* Copyright (c) 2013-2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/data_types.h>

View File

@ -0,0 +1,51 @@
#pragma once
/*
* Copyright (c) 2023, Vesselin Atanasov
* 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 <memory>
#ifdef _MSVC_LANG
#define CXX_STD_VER _MSVC_LANG
#else
#define CXX_STD_VER __cplusplus
#endif
namespace sqlpp
{
namespace compat
{
template <typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
#if CXX_STD_VER >= 201402L
return std::make_unique<T>(std::forward<Args>(args)...);
#else
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
#endif
}
} // namespace compat
} // namespace sqlpp

View File

@ -0,0 +1,158 @@
#pragma once
/*
* Copyright (c) 2013-2015, Roland Bock
* Copyright (c) 2023, Vesselin Atanasov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/compat/make_unique.h>
#include <memory>
#include <utility>
namespace sqlpp
{
struct connection
{
};
template <typename ConnectionBase>
class common_connection : public ConnectionBase
{
public:
bool is_connected() const
{
return ConnectionBase::_handle ? ConnectionBase::_handle->is_connected() : false;
}
bool ping_server() const
{
return ConnectionBase::_handle ? ConnectionBase::_handle->ping_server() : false;
}
protected:
using ConnectionBase::ConnectionBase;
};
// Normal (non-pooled) connection
template <typename ConnectionBase>
class normal_connection : public common_connection<ConnectionBase>
{
public:
using _config_t = typename ConnectionBase::_config_t;
using _config_ptr_t = typename ConnectionBase::_config_ptr_t;
// Constructors
normal_connection() = default;
normal_connection(const _config_t& config) : normal_connection{std::make_shared<_config_t>(config)}
{
}
normal_connection(const _config_ptr_t& config)
: common_connection<ConnectionBase>{compat::make_unique<_handle_t>(config)}
{
}
normal_connection(const normal_connection&) = delete;
normal_connection(normal_connection&&) = default;
// Assigment operators
normal_connection& operator=(const normal_connection&) = delete;
normal_connection& operator=(normal_connection&&) = default;
// creates a connection handle and connects to database
void connectUsing(const _config_ptr_t& config) noexcept(false)
{
ConnectionBase::_handle = compat::make_unique<_handle_t>(config);
}
private:
using _handle_t = typename ConnectionBase::_handle_t;
};
// Forward declaration
template <typename ConnectionBase>
class connection_pool;
// Pooled connection
template <typename ConnectionBase>
class pooled_connection : public common_connection<ConnectionBase>
{
friend class connection_pool<ConnectionBase>::pool_core;
public:
using _config_ptr_t = typename ConnectionBase::_config_ptr_t;
using _handle_t = typename ConnectionBase::_handle_t;
using _handle_ptr_t = typename ConnectionBase::_handle_ptr_t;
using _pool_core_ptr_t = std::shared_ptr<typename connection_pool<ConnectionBase>::pool_core>;
// Copy/Move constructors
pooled_connection(const pooled_connection&) = delete;
pooled_connection(pooled_connection&& other) = default;
~pooled_connection()
{
conn_release();
}
// Assigment operators
pooled_connection& operator=(const pooled_connection&) = delete;
pooled_connection& operator=(pooled_connection&& other)
{
if (this != &other)
{
conn_release();
static_cast<ConnectionBase&>(*this) = std::move(static_cast<ConnectionBase&>(other));
_pool_core = std::move(other._pool_core);
}
return *this;
}
private:
_pool_core_ptr_t _pool_core;
// Constructors used by the connection pool
pooled_connection(_handle_ptr_t&& handle, _pool_core_ptr_t pool_core)
: common_connection<ConnectionBase>{std::move(handle)}, _pool_core{pool_core}
{
}
pooled_connection(const _config_ptr_t& config, _pool_core_ptr_t pool_core)
: common_connection<ConnectionBase>{compat::make_unique<_handle_t>(config)}, _pool_core{pool_core}
{
}
void conn_release()
{
if (_pool_core)
{
_pool_core->put(ConnectionBase::_handle);
_pool_core = nullptr;
}
}
};
} // namespace sqlpp

View File

@ -0,0 +1,159 @@
#pragma once
/*
Copyright (c) 2017 - 2018, Roland Bock
Copyright (c) 2023, Vesselin Atanasov
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/detail/circular_buffer.h>
#include <mutex>
#include <stdexcept>
namespace sqlpp
{
enum class connection_check
{
none,
passive,
ping
};
template <typename ConnectionBase>
class connection_pool
{
public:
using _config_ptr_t = typename ConnectionBase::_config_ptr_t;
using _handle_ptr_t = typename ConnectionBase::_handle_ptr_t;
using _pooled_connection_t = sqlpp::pooled_connection<ConnectionBase>;
class pool_core : public std::enable_shared_from_this<pool_core>
{
public:
pool_core(const _config_ptr_t& connection_config, std::size_t capacity)
: _connection_config{connection_config}, _handles{capacity}
{
}
pool_core() = delete;
pool_core(const pool_core&) = delete;
pool_core(pool_core&&) = delete;
pool_core& operator=(const pool_core&) = delete;
pool_core& operator=(pool_core&&) = delete;
_pooled_connection_t get(connection_check check)
{
std::unique_lock<std::mutex> lock{_mutex};
if (_handles.empty())
{
lock.unlock();
return _pooled_connection_t{_connection_config, this->shared_from_this()};
}
auto handle = std::move(_handles.front());
_handles.pop_front();
lock.unlock();
// If the fetched connection is dead, drop it and create a new one on the fly
return
check_connection(handle, check) ?
_pooled_connection_t{std::move(handle), this->shared_from_this()} :
_pooled_connection_t{_connection_config, this->shared_from_this()};
}
void put(_handle_ptr_t& handle)
{
std::unique_lock<std::mutex> lock{_mutex};
if (_handles.full())
{
_handles.set_capacity(_handles.capacity() + 5);
}
_handles.push_back(std::move(handle));
}
// Returns number of connections available in the pool. Only used in tests.
std::size_t available()
{
std::unique_lock<std::mutex> lock{_mutex};
return _handles.size();
}
private:
inline bool check_connection(_handle_ptr_t& handle, connection_check check)
{
switch (check)
{
case connection_check::none:
return true;
case connection_check::passive:
return handle->is_connected();
case connection_check::ping:
return handle->ping_server();
default:
throw std::invalid_argument{"Invalid connection check value"};
}
}
_config_ptr_t _connection_config;
sqlpp::detail::circular_buffer<_handle_ptr_t> _handles;
std::mutex _mutex;
};
connection_pool() = default;
connection_pool(const _config_ptr_t& connection_config, std::size_t capacity)
: _core{std::make_shared<pool_core>(connection_config, capacity)}
{
}
connection_pool(const connection_pool&) = delete;
connection_pool(connection_pool&&) = default;
connection_pool& operator=(const connection_pool&) = delete;
connection_pool& operator=(connection_pool&&) = default;
void initialize(const _config_ptr_t& connection_config, std::size_t capacity)
{
if (_core)
{
throw std::runtime_error{"Connection pool already initialized"};
}
_core = std::make_shared<pool_core>(connection_config, capacity);
}
_pooled_connection_t get(connection_check check = connection_check::passive)
{
return _core->get(check);
}
// Returns number of connections available in the pool. Only used in tests.
std::size_t available()
{
return _core->available();
}
private:
std::shared_ptr<pool_core> _core;
};
} // namespace sqlpp

View File

@ -0,0 +1,40 @@
#pragma once
/*
* Copyright (c) 2013-2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <type_traits>
namespace sqlpp
{
struct consistent_t : std::true_type
{
template <typename... T>
static constexpr void verify(T&&...)
{
}
};
} // namespace sqlpp

View File

@ -0,0 +1,275 @@
#pragma once
/*
* Copyright (c) 2013-2016, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/expression.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable_list.h>
#include <sqlpp11/logic.h>
#include <sqlpp11/parameter_list.h>
#include <sqlpp11/result_row.h>
#include <sqlpp11/select_flags.h>
#include <sqlpp11/statement_fwd.h>
#include <sqlpp11/table_ref.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp
{
template <typename Flag, typename Lhs, typename Rhs>
struct cte_union_t
{
using _nodes = detail::type_vector<>;
using _required_ctes = detail::make_joined_set_t<required_ctes_of<Lhs>, required_ctes_of<Rhs>>;
using _parameters = detail::type_vector_cat_t<parameters_of<Lhs>, parameters_of<Rhs>>;
cte_union_t(Lhs lhs, Rhs rhs) : _lhs(lhs), _rhs(rhs)
{
}
cte_union_t(const cte_union_t&) = default;
cte_union_t(cte_union_t&&) = default;
cte_union_t& operator=(const cte_union_t&) = default;
cte_union_t& operator=(cte_union_t&&) = default;
~cte_union_t() = default;
Lhs _lhs;
Rhs _rhs;
};
// Interpreters
template <typename Context, typename Flag, typename Lhs, typename Rhs>
Context& serialize(const cte_union_t<Flag, Lhs, Rhs>& t, Context& context)
{
serialize(t._lhs, context);
context << " UNION ";
serialize(Flag{}, context);
context << " ";
serialize(t._rhs, context);
return context;
}
template <typename AliasProvider, typename Statement, typename... FieldSpecs>
struct cte_t;
template <typename AliasProvider>
struct cte_ref_t;
template <typename AliasProvider, typename Statement, typename... FieldSpecs>
auto from_table(cte_t<AliasProvider, Statement, FieldSpecs...> /*unused*/) -> cte_ref_t<AliasProvider>
{
return cte_ref_t<AliasProvider>{};
}
template <typename AliasProvider, typename Statement, typename... FieldSpecs>
struct from_table_impl<cte_t<AliasProvider, Statement, FieldSpecs...>>
{
using type = cte_ref_t<AliasProvider>;
};
template <typename FieldSpec>
struct cte_column_spec_t
{
using _alias_t = typename FieldSpec::_alias_t;
using _traits = make_traits<value_type_of<FieldSpec>,
tag::must_not_insert,
tag::must_not_update,
tag_if<tag::can_be_null, column_spec_can_be_null_t<FieldSpec>::value>>;
};
template <typename AliasProvider, typename Statement, typename ResultRow>
struct make_cte_impl
{
using type = void;
};
template <typename AliasProvider, typename Statement, typename... FieldSpecs>
struct make_cte_impl<AliasProvider, Statement, result_row_t<void, FieldSpecs...>>
{
using type = cte_t<AliasProvider, Statement, FieldSpecs...>;
};
template <typename AliasProvider, typename Statement>
using make_cte_t = typename make_cte_impl<AliasProvider, Statement, get_result_row_t<Statement>>::type;
// workaround for msvc unknown internal error
// template <typename AliasProvider, typename Statement, typename... FieldSpecs>
// struct cte_t
// : public member_t<cte_column_spec_t<FieldSpecs>, column_t<AliasProvider, cte_column_spec_t<FieldSpecs>>>...
template <typename AliasProvider, typename FieldSpec>
struct cte_base
{
using type = member_t<cte_column_spec_t<FieldSpec>, column_t<AliasProvider, cte_column_spec_t<FieldSpec>>>;
};
template <typename Check, typename Union>
struct union_cte_impl
{
using type = Check;
};
template <typename Union>
struct union_cte_impl<consistent_t, Union>
{
using type = Union;
};
template <typename Check, typename Union>
using union_cte_impl_t = typename union_cte_impl<Check, Union>::type;
SQLPP_PORTABLE_STATIC_ASSERT(assert_cte_union_args_are_statements_t, "argument for union() must be a statement");
template <typename... T>
struct check_cte_union
{
using type = static_combined_check_t<
static_check_t<logic::all_t<is_statement_t<T>::value...>::value, assert_cte_union_args_are_statements_t>>;
};
template <typename... T>
using check_cte_union_t = typename check_cte_union<T...>::type;
template <typename AliasProvider, typename Statement, typename... FieldSpecs>
struct cte_t : public cte_base<AliasProvider, FieldSpecs>::type...
{
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>;
using _alias_t = typename AliasProvider::_alias_t;
constexpr static bool _is_recursive = required_ctes_of<Statement>::template count<AliasProvider>();
using _column_tuple_t = std::tuple<column_t<AliasProvider, cte_column_spec_t<FieldSpecs>>...>;
using _result_row_t = result_row_t<void, FieldSpecs...>;
template <typename Rhs>
auto union_distinct(Rhs rhs) const
-> union_cte_impl_t<check_cte_union_t<Rhs>,
cte_t<AliasProvider, cte_union_t<distinct_t, Statement, Rhs>, FieldSpecs...>>
{
static_assert(is_statement_t<Rhs>::value, "argument of union call has to be a statement");
static_assert(has_policy_t<Rhs, is_select_t>::value, "argument of union call has to be a select");
static_assert(has_result_row_t<Rhs>::value, "argument of a union has to be a (complete) select statement");
static_assert(std::is_same<_result_row_t, get_result_row_t<Rhs>>::value,
"both select statements in a union have to have the same result columns (type and name)");
return _union_impl<void, distinct_t>(check_cte_union_t<Rhs>{}, rhs);
}
template <typename Rhs>
auto union_all(Rhs rhs) const
-> union_cte_impl_t<check_cte_union_t<Rhs>,
cte_t<AliasProvider, cte_union_t<all_t, Statement, Rhs>, FieldSpecs...>>
{
static_assert(is_statement_t<Rhs>::value, "argument of union call has to be a statement");
static_assert(has_policy_t<Rhs, is_select_t>::value, "argument of union call has to be a select");
static_assert(has_result_row_t<Rhs>::value, "argument of a union has to be a (complete) select statement");
static_assert(std::is_same<_result_row_t, get_result_row_t<Rhs>>::value,
"both select statements in a union have to have the same result columns (type and name)");
return _union_impl<all_t>(check_cte_union_t<Rhs>{}, rhs);
}
private:
template <typename Flag, typename Check, typename Rhs>
auto _union_impl(Check, Rhs rhs) const -> inconsistent<Check>;
template <typename Flag, typename Rhs>
auto _union_impl(consistent_t /*unused*/, Rhs rhs) const
-> cte_t<AliasProvider, cte_union_t<Flag, Statement, Rhs>, FieldSpecs...>
{
return cte_union_t<Flag, Statement, Rhs>{_statement, rhs};
}
public:
cte_t(Statement statement) : _statement(statement)
{
}
cte_t(const cte_t&) = default;
cte_t(cte_t&&) = default;
cte_t& operator=(const cte_t&) = default;
cte_t& operator=(cte_t&&) = default;
~cte_t() = default;
Statement _statement;
};
template <typename Context, typename AliasProvider, typename Statement, typename... ColumnSpecs>
Context& serialize(const cte_t<AliasProvider, Statement, ColumnSpecs...>& t, Context& context)
{
using T = cte_t<AliasProvider, Statement, ColumnSpecs...>;
context << name_of<T>::template char_ptr<Context>() << " AS (";
serialize(t._statement, context);
context << ")";
return context;
}
// The cte_t is displayed as AliasProviderName except within the with:
// - the with needs the
// AliasProviderName AS (ColumnNames) (select/union)
// The result row of the select should not have dynamic parts
template <typename AliasProvider>
struct cte_ref_t
{
using _traits = make_traits<no_value_t, tag::is_alias, tag::is_cte, tag::is_table>; // FIXME: is table? really?
using _nodes = detail::type_vector<>;
using _required_ctes = detail::make_type_set_t<AliasProvider>;
using _provided_tables = detail::type_set<AliasProvider>;
using _alias_t = typename AliasProvider::_alias_t;
template <typename Statement>
auto as(Statement statement) -> make_cte_t<AliasProvider, Statement>
{
static_assert(required_tables_of<Statement>::size::value == 0,
"common table expression must not use unknown tables");
static_assert(not required_ctes_of<Statement>::template count<AliasProvider>(),
"common table expression must not self-reference in the first part, use union_all/union_distinct "
"for recursion");
static_assert(is_static_result_row_t<get_result_row_t<Statement>>::value,
"ctes must not have dynamically added columns");
return {statement};
}
};
template <typename Context, typename AliasProvider>
Context& serialize(const cte_ref_t<AliasProvider>&, Context& context)
{
context << name_of<cte_ref_t<AliasProvider>>::template char_ptr<Context>();
return context;
}
template <typename AliasProvider>
auto cte(const AliasProvider & /*unused*/) -> cte_ref_t<AliasProvider>
{
return {};
}
} // namespace sqlpp

View File

@ -0,0 +1,147 @@
#pragma once
/*
* Copyright (c) 2013-2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/connection.h>
#include <sqlpp11/detail/get_first.h>
#include <sqlpp11/hidden.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/statement.h>
namespace sqlpp
{
template <typename Database, typename... Parts>
struct custom_query_t;
namespace detail
{
template <typename T>
struct unhide
{
using type = T;
};
template <typename Clause>
struct unhide<hidden_t<Clause>>
{
using type = Clause;
};
template <typename Db, typename... Parts>
struct custom_parts_t
{
using _custom_query_t = custom_query_t<Db, Parts...>;
using _maybe_hidden_result_type_provider = detail::get_first_if<is_return_value_t, noop, Parts...>;
using _result_type_provider = typename unhide<_maybe_hidden_result_type_provider>::type;
using _result_methods_t = typename _result_type_provider::template _result_methods_t<_result_type_provider>;
};
} // namespace detail
template <typename Database, typename... Parts>
struct custom_query_t : private detail::custom_parts_t<Database, Parts...>::_result_methods_t
{
using _methods_t = typename detail::custom_parts_t<Database, Parts...>::_result_methods_t;
using _traits = make_traits<no_value_t, tag::is_statement>;
using _nodes = detail::type_vector<Parts...>;
using _parameter_check =
typename std::conditional<detail::type_vector_size<parameters_of<custom_query_t>>::value == 0,
consistent_t,
assert_no_parameters_t>::type;
using _run_check = detail::get_first_if<is_inconsistent_t, consistent_t, _parameter_check>;
using _prepare_check = consistent_t;
custom_query_t(Parts... parts) : _parts(parts...)
{
}
custom_query_t(std::tuple<Parts...> parts) : _parts(parts)
{
}
custom_query_t(const custom_query_t&) = default;
custom_query_t(custom_query_t&&) = default;
custom_query_t& operator=(const custom_query_t&) = default;
custom_query_t& operator=(custom_query_t&&) = default;
~custom_query_t() = default;
template <typename Db>
auto _run(Db& db) const -> decltype(std::declval<_methods_t>()._run(db, *this))
{
_run_check::verify();
return _methods_t::_run(db, *this);
}
template <typename Db>
auto _prepare(Db& db) const -> decltype(std::declval<_methods_t>()._prepare(db, *this))
{
_prepare_check::verify();
return _methods_t::_prepare(db, *this);
}
static constexpr size_t _get_static_no_of_parameters()
{
return std::tuple_size<parameters_of<custom_query_t>>::value;
}
size_t _get_no_of_parameters() const
{
return _get_static_no_of_parameters();
}
template <typename Part>
auto with_result_type_of(Part part) -> custom_query_t<Database, hidden_t<Part>, Parts...>
{
return {tuple_cat(std::make_tuple(hidden(part)), _parts)};
}
std::tuple<Parts...> _parts;
};
template <typename Context, typename Database, typename... Parts>
Context& serialize(const custom_query_t<Database, Parts...>& t, Context& context)
{
interpret_tuple_without_braces(t._parts, " ", context);
return context;
}
template <typename... Parts>
auto custom_query(Parts... parts) -> custom_query_t<void, wrap_operand_t<Parts>...>
{
static_assert(sizeof...(Parts) > 0, "custom query requires at least one argument");
return custom_query_t<void, wrap_operand_t<Parts>...>(parts...);
}
template <typename Database, typename... Parts>
auto dynamic_custom_query(const Database& /*unused*/, Parts... parts)
-> custom_query_t<Database, wrap_operand_t<Parts>...>
{
static_assert(sizeof...(Parts) > 0, "custom query requires at least one query argument");
static_assert(std::is_base_of<connection, Database>::value, "Invalid database parameter");
return custom_query_t<Database, wrap_operand_t<Parts>...>(parts...);
}
} // namespace sqlpp

View File

@ -0,0 +1,38 @@
#pragma once
/*
* Copyright (c) 2013-2017, Roland Bock, Aaron Bishop
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/data_types/blob.h>
#include <sqlpp11/data_types/boolean.h>
#include <sqlpp11/data_types/integral.h>
#include <sqlpp11/data_types/unsigned_integral.h>
#include <sqlpp11/data_types/floating_point.h>
#include <sqlpp11/data_types/text.h>
#include <sqlpp11/data_types/day_point.h>
#include <sqlpp11/data_types/time_of_day.h>
#include <sqlpp11/data_types/time_point.h>
#include <sqlpp11/data_types/no_value.h>

View File

@ -0,0 +1,39 @@
#pragma once
/*
* Copyright (c) 2013-2017, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/data_types/blob/data_type.h>
#include <sqlpp11/data_types/blob/operand.h>
#include <sqlpp11/data_types/blob/wrap_operand.h>
#include <sqlpp11/data_types/blob/expression_operators.h>
#include <sqlpp11/data_types/blob/column_operators.h>
#include <sqlpp11/data_types/blob/parameter_value.h>
#include <sqlpp11/data_types/blob/result_field.h>
// blob specific functions
#include <sqlpp11/data_types/text/like.h>
#include <sqlpp11/data_types/text/concat.h>

View File

@ -0,0 +1,55 @@
#pragma once
/*
* Copyright (c) 2013-2017, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/type_traits.h>
#include <sqlpp11/assignment.h>
#include <sqlpp11/data_types/blob/data_type.h>
#include <sqlpp11/data_types/column_operators.h>
namespace sqlpp
{
template <typename... Args>
struct concat_t;
template <typename Column>
struct column_operators<Column, blob>
{
template <typename T>
using _is_valid_operand = is_valid_operand<blob, T>;
template <typename T>
auto operator+=(T t) const -> assignment_t<Column, concat_t<Column, wrap_operand_t<T>>>
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
return {*static_cast<const Column*>(this),
concat_t<Column, wrap_operand_t<T>>{*static_cast<const Column*>(this), rhs{t}}};
}
};
} // namespace sqlpp

View File

@ -0,0 +1,48 @@
#pragma once
/*
* Copyright (c) 2013-2017, 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 <vector>
#include <cstdint>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/logic.h>
namespace sqlpp
{
struct blob
{
using _traits = make_traits<blob, tag::is_value_type>;
using _cpp_value_type = std::vector<std::uint8_t>;
template <typename T>
using _is_valid_operand = ::sqlpp::logic::any_t<is_blob_t<T>::value, is_text_t<T>::value>;
};
using blob = blob;
using mediumblob = blob;
} // namespace sqlpp

View File

@ -0,0 +1,68 @@
#pragma once
/*
* Copyright (c) 2013-2017, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/operand_check.h>
#include <sqlpp11/expression_operators.h>
#include <sqlpp11/basic_expression_operators.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/data_types/blob/data_type.h>
#include <sqlpp11/data_types/text/return_type_like.h>
namespace sqlpp
{
template <typename Operand, typename Pattern>
struct like_t;
template <typename L, typename R>
struct return_type_like<L, R, binary_operand_check_t<L, is_blob_t, R, is_blob_t>>
{
using check = consistent_t;
using type = like_t<wrap_operand_t<L>, wrap_operand_t<R>>;
};
template <typename L, typename R>
struct return_type_like<L, R, binary_operand_check_t<L, is_blob_t, R, is_text_t>>
{
using check = consistent_t;
using type = like_t<wrap_operand_t<L>, wrap_operand_t<R>>;
};
template <typename Expression>
struct expression_operators<Expression, blob> : public basic_expression_operators<Expression>
{
template <typename T>
using _is_valid_operand = is_valid_operand<blob, T>;
template <typename R>
auto like(const R& r) const -> return_type_like_t<Expression, R>
{
typename return_type_like<Expression, R>::check{};
return {*static_cast<const Expression*>(this), wrap_operand_t<R>{r}};
}
};
} // namespace sqlpp

View File

@ -0,0 +1,80 @@
#pragma once
/*
* Copyright (c) 2013-2017, 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 <vector>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/alias_operators.h>
namespace sqlpp
{
struct blob;
struct blob_operand : public alias_operators<blob_operand>
{
using _traits = make_traits<blob, tag::is_expression, tag::is_wrapped_value>;
using _nodes = detail::type_vector<>;
using _is_literal_expression = std::true_type;
using _value_t = std::vector<std::uint8_t>;
blob_operand() : _t{}
{
}
blob_operand(_value_t t) : _t(t)
{
}
template <std::size_t N>
blob_operand(const std::array<uint8_t, N>& t) : _t(t.begin(), t.end())
{
}
blob_operand(const blob_operand&) = default;
blob_operand(blob_operand&&) = default;
blob_operand& operator=(const blob_operand&) = default;
blob_operand& operator=(blob_operand&&) = default;
~blob_operand() = default;
_value_t _t;
};
template <typename Context>
Context& serialize(const blob_operand& t, Context& context)
{
constexpr char hexChars[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
context << "x'";
for (const auto c : t._t)
{
context << hexChars[c >> 4] << hexChars[c & 0x0F];
}
context << '\'';
return context;
}
} // namespace sqlpp

View File

@ -0,0 +1,50 @@
#pragma once
/*
* Copyright (c) 2013-2017, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/data_types/parameter_value.h>
#include <sqlpp11/data_types/parameter_value_base.h>
#include <sqlpp11/data_types/blob/data_type.h>
#include <sqlpp11/data_types/blob/wrap_operand.h>
#include <sqlpp11/data_types/blob/operand.h>
namespace sqlpp
{
template <>
struct parameter_value_t<blob> : public parameter_value_base<blob>
{
using base = parameter_value_base<blob>;
using base::base;
using base::operator=;
template <typename Target>
void _bind(Target& target, size_t index) const
{
target._bind_blob_parameter(index, &_value, _is_null);
}
};
} // namespace sqlpp

View File

@ -0,0 +1,84 @@
#pragma once
/*
* Copyright (c) 2013-2017, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/basic_expression_operators.h>
#include <sqlpp11/result_field.h>
#include <sqlpp11/result_field_base.h>
#include <sqlpp11/data_types/blob/data_type.h>
#include <sqlpp11/field_spec.h>
#include <ostream>
#include <string>
namespace sqlpp
{
template <typename Db, typename NameType, bool CanBeNull>
struct result_field_t<Db, field_spec_t<NameType, blob, CanBeNull>>
: public result_field_base<Db, field_spec_t<NameType, blob, CanBeNull>>
{
const uint8_t* blob{nullptr}; // Non-owning
size_t len{};
template <typename Target>
void _bind(Target& target, size_t index)
{
target._bind_blob_result(index, &blob, &len);
if (blob)
this->_value.assign(blob, blob + len);
else
this->_value.clear();
this->_is_null = (blob == nullptr);
}
template <typename Target>
void _post_bind(Target& target, size_t index)
{
target._post_bind_blob_result(index, &blob, &len);
if (blob)
this->_value.assign(blob, blob + len);
else
this->_value.clear();
this->_is_null = (blob == nullptr);
}
};
template <typename Db, typename NameType, bool CanBeNull>
inline std::ostream& operator<<(
std::ostream& os, const result_field_t<Db, field_spec_t<NameType, blob, CanBeNull>>& e)
{
if (e.is_null())
{
return os << "NULL";
}
else
{
std::vector<uint8_t> value = e.value();
std::string value_str(value.begin(), value.end());
return os << value_str;
}
}
} // namespace sqlpp

View File

@ -0,0 +1,49 @@
#pragma once
/*
* Copyright (c) 2013-2017, 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 <utility>
#include <vector>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/wrap_operand.h>
namespace sqlpp
{
struct blob_operand;
template <>
struct wrap_operand<std::vector<std::uint8_t>, void>
{
using type = blob_operand;
};
template <std::size_t N>
struct wrap_operand<std::array<std::uint8_t, N>, void>
{
using type = blob_operand;
};
} // namespace sqlpp

View File

@ -0,0 +1,35 @@
#pragma once
/*
* Copyright (c) 2013-2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/data_types/boolean/data_type.h>
#include <sqlpp11/data_types/boolean/operand.h>
#include <sqlpp11/data_types/boolean/wrap_operand.h>
#include <sqlpp11/data_types/boolean/expression_operators.h>
#include <sqlpp11/data_types/boolean/column_operators.h>
#include <sqlpp11/data_types/boolean/parameter_value.h>
#include <sqlpp11/data_types/boolean/result_field.h>

Some files were not shown because too many files have changed in this diff Show More