Moved sqlite3 over here.

This commit is contained in:
Roland Bock
2021-08-01 20:37:36 +02:00
parent d0a8ea21af
commit 2e683a4b69
101 changed files with 4963 additions and 61 deletions

View File

@@ -0,0 +1,75 @@
/*
* Copyright (c) 2015 - 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 "TabSample.h"
#include <cassert>
#include <sqlpp11/sqlite3/connection.h>
#include <sqlpp11/sqlpp11.h>
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <iostream>
#include <vector>
namespace sql = sqlpp::sqlite3;
int main()
{
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = true;
// Opening a connection to an in-memory database and creating a table in it
sql::connection db(config);
db.execute(R"(CREATE TABLE tab_sample (
alpha INTEGER PRIMARY KEY,
beta varchar(255) DEFAULT NULL,
gamma bool DEFAULT NULL
))");
// Attaching another in-memory database and creating the same table in it
auto other = db.attach(config, "other");
db.execute(R"(CREATE TABLE other.tab_sample (
alpha INTEGER PRIMARY KEY,
beta varchar(255) DEFAULT NULL,
gamma bool DEFAULT NULL
))");
auto left = TabSample{};
auto right =
schema_qualified_table(other, TabSample{}).as(sqlpp::alias::right); // this is a table in the attached database
// inserting in one tab_sample
db(insert_into(left).default_values());
// selecting from the other tab_sample
assert(db(select(all_of(right)).from(right).unconditionally()).empty());
return 0;
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 2015 - 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 "TabSample.h"
#include <sqlpp11/custom_query.h>
#include <sqlpp11/sqlite3/sqlite3.h>
#include <sqlpp11/sqlpp11.h>
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <cassert>
#include <iostream>
#include <set>
namespace sql = sqlpp::sqlite3;
int main()
{
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = true;
sql::connection db(config);
db.execute(R"(CREATE TABLE tab_sample (
alpha INTEGER PRIMARY KEY AUTOINCREMENT,
beta bool DEFAULT NULL,
gamma varchar(255) DEFAULT NULL
))");
const auto tab = TabSample{};
db(insert_into(tab).default_values());
db(insert_into(tab).default_values());
db(insert_into(tab).default_values());
std::set<int64_t> results;
for (const auto& row : db(select(all_of(tab)).from(tab).unconditionally()))
{
results.insert(row.alpha);
};
const auto expected = std::set<int64_t>{1, 2, 3};
assert(results == expected);
return 0;
}

View File

@@ -0,0 +1,78 @@
// generated by ../../sqlpp11/scripts/ddl2cpp -fail-on-parse BlobSample.sql BlobSample blob
#ifndef BLOB_BLOBSAMPLE_H
#define BLOB_BLOBSAMPLE_H
#include <sqlpp11/char_sequence.h>
#include <sqlpp11/data_types.h>
#include <sqlpp11/table.h>
namespace BlobSample_
{
struct Id
{
struct _alias_t
{
static constexpr const char _literal[] = "id";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T id;
T& operator()()
{
return id;
}
const T& operator()() const
{
return id;
}
};
};
using _traits = sqlpp::make_traits<sqlpp::integer, sqlpp::tag::can_be_null>;
};
struct Data
{
struct _alias_t
{
static constexpr const char _literal[] = "data";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T data;
T& operator()()
{
return data;
}
const T& operator()() const
{
return data;
}
};
};
using _traits = sqlpp::make_traits<sqlpp::blob, sqlpp::tag::can_be_null>;
};
} // namespace BlobSample_
struct BlobSample : sqlpp::table_t<BlobSample, BlobSample_::Id, BlobSample_::Data>
{
struct _alias_t
{
static constexpr const char _literal[] = "blob_sample";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T blobSample;
T& operator()()
{
return blobSample;
}
const T& operator()() const
{
return blobSample;
}
};
};
};
#endif

View File

@@ -0,0 +1,4 @@
CREATE TABLE blob_sample (
id INTEGER PRIMARY KEY,
data blob
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

View File

@@ -0,0 +1,102 @@
#include "BlobSample.h"
#include <sqlpp11/sqlite3/connection.h>
#include <sqlpp11/sqlpp11.h>
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <functional>
#include <iostream>
#include <random>
namespace sql = sqlpp::sqlite3;
const auto blob = BlobSample{};
/*
* max default blob/text is 1,000,000,000
* But 999,999,993 is the biggest one SQLITE will accept
* without throwing SQLITE_TOOBIG
* But it takes too long (over 5s) to generate and check
*/
constexpr size_t blob_size = 1000 * 1000ul;
constexpr size_t blob_small_size = 999;
void verify_blob(sql::connection& db, const std::vector<uint8_t>& data, uint64_t id)
{
auto result = db(select(blob.data).from(blob).where(blob.id == id));
const auto& result_row = result.front();
std::cerr << "Insert size: " << data.size() << std::endl;
std::cerr << "Select size: " << result_row.data.len << std::endl;
if (data.size() != result_row.data.len)
{
std::cerr << "Size mismatch" << std::endl;
throw std::runtime_error("Size mismatch " + std::to_string(data.size()) +
" != " + std::to_string(result_row.data.len));
}
std::cerr << "Verifying content" << std::endl;
std::vector<uint8_t> result_blob(result_row.data.blob, result_row.data.blob + result_row.data.len);
if (data != result_blob)
{
std::cout << "Content mismatch ([row] original -> received)" << std::endl;
for (size_t i = 0; i < data.size(); i++)
{
if (data[i] != result_row.data.blob[i])
{
std::cerr << "[" << i << "] " << static_cast<int>(data.at(i)) << " -> " << static_cast<int>(result_blob.at(i))
<< std::endl;
}
}
throw std::runtime_error("Content mismatch");
}
}
int main()
{
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = true;
sql::connection db(config);
db.execute(R"(CREATE TABLE blob_sample (
id INTEGER PRIMARY KEY,
data blob
))");
std::cerr << "Generating data " << blob_size << std::endl;
std::vector<uint8_t> data(blob_size);
std::uniform_int_distribution<unsigned short> distribution(0, 255);
std::mt19937 engine;
auto generator = std::bind(distribution, engine);
std::generate_n(data.begin(), blob_size, generator);
std::vector<uint8_t> data_smaller(blob_small_size);
std::generate_n(data_smaller.begin(), blob_small_size, generator);
// If we use the bigger blob it will trigger SQLITE_TOOBIG for the query
auto id = db(insert_into(blob).set(blob.data = data_smaller));
auto prepared_insert = db.prepare(insert_into(blob).set(blob.data = parameter(blob.data)));
prepared_insert.params.data = data;
auto prep_id = db(prepared_insert);
prepared_insert.params.data.set_null();
auto null_id = db(prepared_insert);
verify_blob(db, data_smaller, id);
verify_blob(db, data, prep_id);
{
auto result = db(select(blob.data).from(blob).where(blob.id == null_id));
const auto& result_row = result.front();
std::cerr << "Null blob is_null:\t" << std::boolalpha << result_row.data.is_null() << std::endl;
std::cerr << "Null blob len == 0:\t" << std::boolalpha << (result_row.data.len == 0) << std::endl;
std::cerr << "Null blob blob == nullptr:\t" << std::boolalpha << (result_row.data.blob == nullptr) << std::endl;
if (!result_row.data.is_null() || result_row.data.len != 0 || result_row.data.blob != nullptr)
{
throw std::runtime_error("Null blob has incorrect values");
}
}
return 0;
}

View File

@@ -0,0 +1,60 @@
# 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.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
macro (build_and_run arg)
# Add headers to sources to enable file browsing in IDEs
add_executable(Sqlpp11Sqlite3${arg} ${arg}.cpp)
target_link_libraries(Sqlpp11Sqlite3${arg} PRIVATE sqlpp11-connector-sqlite3)
if (NOT MSVC)
target_compile_options(Sqlpp11Sqlite3${arg} INTERFACE -Wall -Wextra -pedantic)
endif ()
add_test(NAME Sqlpp11Sqlite3${arg} COMMAND Sqlpp11Sqlite3${arg})
endmacro ()
build_and_run(DateTimeTest)
build_and_run(SampleTest)
build_and_run(SelectTest)
build_and_run(UnionTest)
build_and_run(WithTest)
build_and_run(AttachTest)
build_and_run(DynamicSelectTest)
build_and_run(AutoIncrementTest)
build_and_run(TransactionTest)
build_and_run(FloatingPointTest)
build_and_run(IntegralTest)
build_and_run(BlobTest)
# the dynamic loading test needs the extra option "SQLPP_DYNAMIC_LOADING" and does NOT link the sqlite libs
if (SQLPP_DYNAMIC_LOADING)
add_executable(Sqlpp11Sqlite3DynamicLoadingTest "DynamicLoadingTest.cpp" ${sqlpp_headers})
target_link_libraries(Sqlpp11Sqlite3DynamicLoadingTest sqlpp11-connector-sqlite3-dynamic)
if (NOT MSVC)
target_link_libraries(Sqlpp11Sqlite3DynamicLoadingTest dl)
target_compile_options(Sqlpp11Sqlite3DynamicLoadingTest INTERFACE -Wall -Wextra -pedantic)
endif ()
add_test(NAME Sqlpp11Sqlite3DynamicLoadingTest COMMAND Sqlpp11Sqlite3DynamicLoadingTest)
endif()

View File

@@ -0,0 +1,130 @@
/*
* 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 "TabSample.h"
#include <sqlpp11/custom_query.h>
#include <sqlpp11/sqlite3/sqlite3.h>
#include <sqlpp11/sqlpp11.h>
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <cassert>
#include <iostream>
#include <vector>
namespace
{
const auto now = ::sqlpp::chrono::floor<::std::chrono::milliseconds>(std::chrono::system_clock::now());
const auto today = ::sqlpp::chrono::floor<::sqlpp::chrono::days>(now);
const auto yesterday = today - ::sqlpp::chrono::days{1};
template <typename L, typename R>
auto require_equal(int line, const L& l, const R& r) -> void
{
if (l != r)
{
std::cerr << line << ": ";
serialize(::sqlpp::wrap_operand_t<L>{l}, std::cerr);
std::cerr << " != ";
serialize(::sqlpp::wrap_operand_t<R>{r}, std::cerr);
throw std::runtime_error("Unexpected result");
}
}
} // namespace
namespace sql = sqlpp::sqlite3;
int main()
{
try
{
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = true;
sql::connection db(config);
db.execute(R"(CREATE TABLE tab_date_time (
col_day_point DATE,
col_time_point DATETIME
))");
const auto tab = TabDateTime{};
db(insert_into(tab).default_values());
for (const auto& row : db(select(all_of(tab)).from(tab).unconditionally()))
{
require_equal(__LINE__, row.colDayPoint.is_null(), true);
require_equal(__LINE__, row.colDayPoint.value(), ::sqlpp::chrono::day_point{});
require_equal(__LINE__, row.colTimePoint.is_null(), true);
require_equal(__LINE__, row.colTimePoint.value(), ::sqlpp::chrono::microsecond_point{});
}
db(update(tab).set(tab.colDayPoint = today, tab.colTimePoint = now).unconditionally());
for (const auto& row : db(select(all_of(tab)).from(tab).unconditionally()))
{
require_equal(__LINE__, row.colDayPoint.value(), today);
require_equal(__LINE__, row.colTimePoint.value(), now);
}
db(update(tab).set(tab.colDayPoint = yesterday, tab.colTimePoint = today).unconditionally());
for (const auto& row : db(select(all_of(tab)).from(tab).unconditionally()))
{
require_equal(__LINE__, row.colDayPoint.value(), yesterday);
require_equal(__LINE__, row.colTimePoint.value(), today);
}
auto prepared_update = db.prepare(
update(tab)
.set(tab.colDayPoint = parameter(tab.colDayPoint), tab.colTimePoint = parameter(tab.colTimePoint))
.unconditionally());
prepared_update.params.colDayPoint = today;
prepared_update.params.colTimePoint = now;
std::cout << "---- running prepared update ----" << std::endl;
db(prepared_update);
std::cout << "---- finished prepared update ----" << std::endl;
for (const auto& row : db(select(all_of(tab)).from(tab).unconditionally()))
{
require_equal(__LINE__, row.colDayPoint.value(), today);
require_equal(__LINE__, row.colTimePoint.value(), now);
}
}
catch (const std::exception& e)
{
std::cerr << "Exception: " << e.what() << std::endl;
return 1;
}
catch (...)
{
std::cerr << "Unknown exception: " << std::endl;
return 1;
}
return 0;
}

View File

@@ -0,0 +1,88 @@
/*
* 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 "TabSample.h"
#include <sqlpp11/alias_provider.h>
#include <sqlpp11/functions.h>
#include <sqlpp11/insert.h>
#include <sqlpp11/remove.h>
#include <sqlpp11/select.h>
#include <sqlpp11/sqlite3/connection.h>
#include <sqlpp11/transaction.h>
#include <sqlpp11/update.h>
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <iostream>
#include <vector>
#include <sqlpp11/sqlite3/dynamic_libsqlite3.h>
SQLPP_ALIAS_PROVIDER(left)
namespace sql = sqlpp::sqlite3;
int main()
{
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = true;
sql::connection db(config);
db.execute("CREATE TABLE tab_sample (\
alpha bigint(20) DEFAULT NULL,\
beta varchar(255) DEFAULT NULL,\
gamma bool DEFAULT NULL\
)");
const auto tab = TabSample{};
auto i = insert_into(tab).columns(tab.beta, tab.gamma);
i.values.add(tab.beta = "rhabarbertorte", tab.gamma = false);
// i.values.add(tab.beta = "cheesecake", tab.gamma = false)
// i.values.add(tab.beta = "kaesekuchen", tab.gamma = true)
auto last_insert_rowid = db(i);
std::cerr << "last insert rowid: " << last_insert_rowid << std::endl;
// Just to demonstrate that you can call basically any function
std::cerr << "last insert rowid: "
<< db(select(sqlpp::verbatim<sqlpp::integer>("last_insert_rowid()").as(tab.alpha))).front().alpha
<< std::endl;
// select a static (alpha) and a dynamic column (beta)
auto s = dynamic_select(db).dynamic_columns(tab.alpha.as(left)).from(tab).unconditionally();
s.selected_columns.add(tab.beta);
s.selected_columns.add(tab.gamma);
for (const auto& row : db(s))
{
std::cerr << "row.alpha: " << row.left << ", row.beta: " << row.at("beta") << ", row.gamma: " << row.at("gamma")
<< std::endl;
};
return 0;
}

View File

@@ -0,0 +1,86 @@
/*
* 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 "TabSample.h"
#include <sqlpp11/alias_provider.h>
#include <sqlpp11/functions.h>
#include <sqlpp11/insert.h>
#include <sqlpp11/remove.h>
#include <sqlpp11/select.h>
#include <sqlpp11/sqlite3/connection.h>
#include <sqlpp11/transaction.h>
#include <sqlpp11/update.h>
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <iostream>
#include <vector>
SQLPP_ALIAS_PROVIDER(left)
namespace sql = sqlpp::sqlite3;
int main()
{
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = true;
sql::connection db(config);
db.execute("CREATE TABLE tab_sample (\
alpha bigint(20) DEFAULT NULL,\
beta varchar(255) DEFAULT NULL,\
gamma bool DEFAULT NULL\
)");
const auto tab = TabSample{};
auto i = insert_into(tab).columns(tab.beta, tab.gamma);
i.values.add(tab.beta = "rhabarbertorte", tab.gamma = false);
// i.values.add(tab.beta = "cheesecake", tab.gamma = false)
// i.values.add(tab.beta = "kaesekuchen", tab.gamma = true)
auto last_insert_rowid = db(i);
std::cerr << "last insert rowid: " << last_insert_rowid << std::endl;
// Just to demonstrate that you can call basically any function
std::cerr << "last insert rowid: "
<< db(select(sqlpp::verbatim<sqlpp::integer>("last_insert_rowid()").as(tab.alpha))).front().alpha
<< std::endl;
// select a static (alpha) and a dynamic column (beta)
auto s = dynamic_select(db).dynamic_columns(tab.alpha.as(left)).from(tab).unconditionally();
s.selected_columns.add(tab.beta);
s.selected_columns.add(tab.gamma);
for (const auto& row : db(s))
{
std::cerr << "row.alpha: " << row.left << ", row.beta: " << row.at("beta") << ", row.gamma: " << row.at("gamma")
<< std::endl;
};
return 0;
}

View File

@@ -0,0 +1,126 @@
/*
* 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/sqlite3/connection.h>
#include <sqlpp11/sqlpp11.h>
#include "FpSample.h"
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <iostream>
#include <limits>
namespace sql = sqlpp::sqlite3;
const auto fp = FpSample{};
template <typename L, typename R>
auto require_equal(int line, const L& l, const R& r) -> void
{
if (l != r)
{
std::cerr << line << ": ";
serialize(::sqlpp::wrap_operand_t<L>{l}, std::cerr);
std::cerr << " != ";
serialize(::sqlpp::wrap_operand_t<R>{r}, std::cerr);
throw std::runtime_error("Unexpected result");
}
}
static auto require(int line, bool condition) -> void
{
if (!condition)
{
std::cerr << line << " condition violated";
throw std::runtime_error("Unexpected result");
}
}
int main()
{
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = true;
sql::connection db(config);
db.execute(R"(CREATE TABLE fp_sample (
id INTEGER PRIMARY KEY AUTOINCREMENT,
fp REAL
))");
db.execute("INSERT into fp_sample (id, fp) values(NULL, 1.0)");
db.execute("INSERT into fp_sample (id, fp) values(NULL, 'Inf')");
db.execute("INSERT into fp_sample (id, fp) values(NULL, 'Nan')");
db.execute("INSERT into fp_sample (id, fp) values(NULL, 'SomeString')");
db(insert_into(fp).set(fp.fp = std::numeric_limits<double>::quiet_NaN()));
db(insert_into(fp).set(fp.fp = std::numeric_limits<double>::infinity()));
db(insert_into(fp).set(fp.fp = -std::numeric_limits<double>::infinity()));
auto prepared_insert = db.prepare(insert_into(fp).set(fp.fp = parameter(fp.fp)));
prepared_insert.params.fp = std::numeric_limits<double>::quiet_NaN();
db(prepared_insert);
prepared_insert.params.fp = std::numeric_limits<double>::infinity();
db(prepared_insert);
prepared_insert.params.fp = -std::numeric_limits<double>::infinity();
db(prepared_insert);
auto q = select(fp.fp).from(fp).unconditionally();
auto rows = db(q);
// raw string inserts
require_equal(__LINE__, rows.front().fp, 1.0);
rows.pop_front();
require(__LINE__, std::isinf(rows.front().fp.value()));
rows.pop_front();
require(__LINE__, std::isnan(rows.front().fp.value()));
rows.pop_front();
require_equal(__LINE__, rows.front().fp, 0.0);
rows.pop_front();
// dsl inserts
require(__LINE__, std::isnan(rows.front().fp.value()));
rows.pop_front();
require(__LINE__, std::isinf(rows.front().fp.value()));
require(__LINE__, rows.front().fp.value() > std::numeric_limits<double>::max());
rows.pop_front();
require(__LINE__, std::isinf(rows.front().fp.value()));
require(__LINE__, rows.front().fp.value() < std::numeric_limits<double>::lowest());
// prepared dsl inserts
rows.pop_front();
require(__LINE__, std::isnan(rows.front().fp.value()));
rows.pop_front();
require(__LINE__, std::isinf(rows.front().fp.value()));
require(__LINE__, rows.front().fp.value() > std::numeric_limits<double>::max());
rows.pop_front();
require(__LINE__, std::isinf(rows.front().fp.value()));
require(__LINE__, rows.front().fp.value() < std::numeric_limits<double>::lowest());
return 0;
}

View File

@@ -0,0 +1,79 @@
// generated by ../../sqlpp11/scripts/ddl2cpp -fail-on-parse FpSample.sql FpSample fp
#ifndef FP_FPSAMPLE_H
#define FP_FPSAMPLE_H
#include <sqlpp11/table.h>
#include <sqlpp11/data_types.h>
#include <sqlpp11/char_sequence.h>
namespace FpSample_
{
struct Id
{
struct _alias_t
{
static constexpr const char _literal[] = "id";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T id;
T& operator()()
{
return id;
}
const T& operator()() const
{
return id;
}
};
};
using _traits = sqlpp::make_traits<sqlpp::integer, sqlpp::tag::can_be_null>;
};
struct Fp
{
struct _alias_t
{
static constexpr const char _literal[] = "fp";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T fp;
T& operator()()
{
return fp;
}
const T& operator()() const
{
return fp;
}
};
};
using _traits = sqlpp::make_traits<sqlpp::floating_point, sqlpp::tag::can_be_null>;
};
}
struct FpSample : sqlpp::table_t<FpSample, FpSample_::Id, FpSample_::Fp>
{
struct _alias_t
{
static constexpr const char _literal[] = "fp_sample";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T fpSample;
T& operator()()
{
return fpSample;
}
const T& operator()() const
{
return fpSample;
}
};
};
};
#endif

View File

@@ -0,0 +1,4 @@
CREATE TABLE fp_sample (
id INTEGER PRIMARY KEY,
fp DOUBLE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

View File

@@ -0,0 +1,79 @@
#ifndef INTEGRAL_SAMPLE_H
#define INTEGRAL_SAMPLE_H
#include <sqlpp11/char_sequence.h>
#include <sqlpp11/data_types.h>
#include <sqlpp11/table.h>
namespace IntegralSample_
{
struct SignedValue
{
struct _alias_t
{
static constexpr const char _literal[] = "signed_value";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T signedValue;
T& operator()()
{
return signedValue;
}
const T& operator()() const
{
return signedValue;
}
};
};
using _traits = sqlpp::make_traits<sqlpp::integer, sqlpp::tag::can_be_null>;
};
struct UnsignedValue
{
struct _alias_t
{
static constexpr const char _literal[] = "unsigned_value";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T unsignedValue;
T& operator()()
{
return unsignedValue;
}
const T& operator()() const
{
return unsignedValue;
}
};
};
using _traits = sqlpp::make_traits<sqlpp::integer_unsigned, sqlpp::tag::can_be_null>;
};
} // namespace IntegralSample_
struct IntegralSample : sqlpp::table_t<IntegralSample, IntegralSample_::SignedValue, IntegralSample_::UnsignedValue>
{
struct _alias_t
{
static constexpr const char _literal[] = "integral_sample";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T fpSample;
T& operator()()
{
return fpSample;
}
const T& operator()() const
{
return fpSample;
}
};
};
};
#endif

View File

@@ -0,0 +1,119 @@
/*
* 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/sqlite3/connection.h>
#include <sqlpp11/sqlpp11.h>
#include "IntegralSample.h"
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <iostream>
#include <limits>
namespace sql = sqlpp::sqlite3;
const auto intSample = IntegralSample{};
template <typename L, typename R>
auto require_equal(int line, const L& l, const R& r) -> void
{
if (l != r)
{
std::cerr << line << ": ";
serialize(::sqlpp::wrap_operand_t<L>{l}, std::cerr);
std::cerr << " != ";
serialize(::sqlpp::wrap_operand_t<R>{r}, std::cerr);
throw std::runtime_error("Unexpected result");
}
}
int main()
{
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = true;
sql::connection db(config);
db.execute(R"(CREATE TABLE integral_sample (
signed_value INTEGER,
unsigned_value INTEGER
))");
// The connector supports uint64_t values and will always retrieve the correct value from the database.
// Sqlite3 stores the values as int64_t internally though, so big uint64_t values will be converted
// and the library has to intepret the int64_t values correctly as uint64_t.
// Therefore, we test uint64_t values in an out of the range of int64_t and test if they are retrieved
// correctly from the database in both cases.
uint64_t uint64_t_value_supported = std::numeric_limits<int64_t>::max();
int64_t int64_t_value_max = std::numeric_limits<int64_t>::max();
uint64_t uint64_t_value_unsupported = std::numeric_limits<uint64_t>::max();
int64_t int64_t_value_min = std::numeric_limits<int64_t>::min();
std::size_t size_t_value_max = std::numeric_limits<std::size_t>::max();
std::size_t size_t_value_min = std::numeric_limits<std::size_t>::min();
uint32_t uint32_t_value = std::numeric_limits<uint32_t>::max();
int32_t int32_t_value = std::numeric_limits<int32_t>::max();
db(insert_into(intSample).set(intSample.signedValue = int64_t_value_max,
intSample.unsignedValue = uint64_t_value_supported));
auto prepared_insert =
db.prepare(insert_into(intSample).set(intSample.signedValue = parameter(intSample.signedValue),
intSample.unsignedValue = parameter(intSample.unsignedValue)));
prepared_insert.params.signedValue = int64_t_value_min;
prepared_insert.params.unsignedValue = uint64_t_value_unsupported;
db(prepared_insert);
db(insert_into(intSample).set(intSample.signedValue = size_t_value_min, intSample.unsignedValue = size_t_value_max));
db(insert_into(intSample).set(intSample.signedValue = int32_t_value, intSample.unsignedValue = uint32_t_value));
auto q = select(intSample.signedValue, intSample.unsignedValue).from(intSample).unconditionally();
auto rows = db(q);
require_equal(__LINE__, rows.front().signedValue.value(), int64_t_value_max);
require_equal(__LINE__, rows.front().unsignedValue.value(), uint64_t_value_supported);
rows.pop_front();
require_equal(__LINE__, rows.front().signedValue.value(), int64_t_value_min);
require_equal(__LINE__, rows.front().unsignedValue.value(), uint64_t_value_unsupported);
rows.pop_front();
require_equal(__LINE__, rows.front().signedValue.value(), size_t_value_min);
require_equal(__LINE__, rows.front().unsignedValue.value(), size_t_value_max);
rows.pop_front();
require_equal(__LINE__, rows.front().signedValue.value(), int32_t_value);
require_equal(__LINE__, rows.front().unsignedValue.value(), uint32_t_value);
rows.pop_front();
return 0;
}

View File

@@ -0,0 +1,210 @@
/*
* 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 "TabSample.h"
#include <sqlpp11/custom_query.h>
#include <sqlpp11/sqlite3/sqlite3.h>
#include <sqlpp11/sqlpp11.h>
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <cassert>
#include <iostream>
#include <vector>
SQLPP_ALIAS_PROVIDER(left)
SQLPP_ALIAS_PROVIDER(pragma)
SQLPP_ALIAS_PROVIDER(sub)
namespace sql = sqlpp::sqlite3;
int main()
{
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = true;
sql::connection db(config);
db.execute(R"(CREATE TABLE tab_sample (
alpha INTEGER PRIMARY KEY,
beta varchar(255) DEFAULT NULL,
gamma bool DEFAULT NULL
))");
db.execute(R"(CREATE TABLE tab_foo (
omega bigint(20) DEFAULT NULL
))");
const auto tab = TabSample{};
// clear the table
db(remove_from(tab).unconditionally());
// explicit all_of(tab)
for (const auto& row : db(select(all_of(tab)).from(tab).unconditionally()))
{
std::cerr << "row.alpha: " << row.alpha << ", row.beta: " << row.beta << ", row.gamma: " << row.gamma << std::endl;
};
std::cerr << __FILE__ << ": " << __LINE__ << std::endl;
// selecting a table implicitly expands to all_of(tab)
for (const auto& row : db(select(all_of(tab)).from(tab).unconditionally()))
{
std::cerr << "row.alpha: " << row.alpha << ", row.beta: " << row.beta << ", row.gamma: " << row.gamma << std::endl;
};
// insert
std::cerr << "no of required columns: " << TabSample::_required_insert_columns::size::value << std::endl;
db(insert_into(tab).default_values());
std::cout << "Last Insert ID: " << db.last_insert_id() << "\n";
db(insert_into(tab).set(tab.gamma = true));
std::cout << "Last Insert ID: " << db.last_insert_id() << "\n";
auto di = dynamic_insert_into(db, tab).dynamic_set(tab.gamma = true);
di.insert_list.add(tab.beta = "");
db(di);
// update
db(update(tab).set(tab.gamma = false).where(tab.alpha.in(1)));
db(update(tab).set(tab.gamma = false).where(tab.alpha.in(sqlpp::value_list(std::vector<int>{1, 2, 3, 4}))));
// remove
db(remove_from(tab).where(tab.alpha == tab.alpha + 3));
auto result = db(select(all_of(tab)).from(tab).unconditionally());
std::cerr << "Accessing a field directly from the result (using the current row): " << result.begin()->alpha
<< std::endl;
std::cerr << "Can do that again, no problem: " << result.begin()->alpha << std::endl;
auto tx = start_transaction(db);
TabFoo foo;
for (const auto& row : db(select(all_of(tab), select(max(foo.omega)).from(foo).where(foo.omega > tab.alpha))
.from(tab)
.unconditionally()))
{
int x = row.alpha;
int a = row.max;
std::cout << x << ", " << a << std::endl;
}
tx.commit();
for (const auto& row : db(select(tab.alpha).from(tab.join(foo).on(tab.alpha == foo.omega)).unconditionally()))
{
std::cerr << row.alpha << std::endl;
}
for (const auto& row :
db(select(tab.alpha).from(tab.left_outer_join(foo).on(tab.alpha == foo.omega)).unconditionally()))
{
std::cerr << row.alpha << std::endl;
}
auto ps = db.prepare(select(all_of(tab))
.from(tab)
.where(tab.alpha != parameter(tab.alpha) and tab.beta != parameter(tab.beta) and
tab.gamma != parameter(tab.gamma)));
ps.params.alpha = 7;
ps.params.beta = "wurzelbrunft";
ps.params.gamma = true;
for (const auto& row : db(ps))
{
std::cerr << "bound result: alpha: " << row.alpha << std::endl;
std::cerr << "bound result: beta: " << row.beta << std::endl;
std::cerr << "bound result: gamma: " << row.gamma << std::endl;
}
std::cerr << "--------" << std::endl;
ps.params.alpha = sqlpp::eval<sqlpp::integer>(db, "last_insert_rowid()");
ps.params.gamma = "false";
for (const auto& row : db(ps))
{
std::cerr << "bound result: alpha: " << row.alpha << std::endl;
std::cerr << "bound result: beta: " << row.beta << std::endl;
std::cerr << "bound result: gamma: " << row.gamma << std::endl;
}
std::cerr << "--------" << std::endl;
ps.params.beta = "kaesekuchen";
for (const auto& row : db(ps))
{
std::cerr << "bound result: alpha: " << row.alpha << std::endl;
std::cerr << "bound result: beta: " << row.beta << std::endl;
std::cerr << "bound result: gamma: " << row.gamma << std::endl;
}
auto pi = db.prepare(insert_into(tab).set(tab.beta = parameter(tab.beta), tab.gamma = true));
pi.params.beta = "prepared cake";
std::cerr << "Inserted: " << db(pi) << std::endl;
auto pu = db.prepare(update(tab).set(tab.gamma = parameter(tab.gamma)).where(tab.beta == "prepared cake"));
pu.params.gamma = false;
std::cerr << "Updated: " << db(pu) << std::endl;
auto pr = db.prepare(remove_from(tab).where(tab.beta != parameter(tab.beta)));
pr.params.beta = "prepared cake";
std::cerr << "Deleted lines: " << db(pr) << std::endl;
// Check that a prepared select is default-constructible
{
auto s = select(all_of(tab))
.from(tab)
.where((tab.beta.like(parameter(tab.beta)) and tab.alpha == parameter(tab.alpha)) or
tab.gamma != parameter(tab.gamma));
using P = decltype(db.prepare(s));
P p; // You must not use this one yet!
p = db.prepare(s);
}
auto i = db(sqlpp::sqlite3::insert_or_replace_into(tab).set(tab.beta = "test", tab.gamma = true));
std::cerr << i << std::endl;
i = db(sqlpp::sqlite3::insert_or_ignore_into(tab).set(tab.beta = "test", tab.gamma = true));
std::cerr << i << std::endl;
assert(db(select(count(tab.alpha)).from(tab).unconditionally()).begin()->count);
assert(
db(select(all_of(tab)).from(tab).where(tab.alpha.not_in(select(tab.alpha).from(tab).unconditionally()))).empty());
auto x = custom_query(sqlpp::verbatim("PRAGMA user_version = "), 1);
db(x);
int pragmaValue =
db(custom_query(sqlpp::verbatim("PRAGMA user_version")).with_result_type_of(select(sqlpp::value(1).as(pragma))))
.front()
.pragma;
std::cerr << pragmaValue << std::endl;
// Testing sub select tables and unconditional joins
const auto subQuery = select(tab.alpha).from(tab).unconditionally().as(sub);
for (const auto& row : db(select(subQuery.alpha).from(subQuery).unconditionally()))
{
std::cerr << row.alpha;
}
for (const auto& row : db(select(subQuery.alpha).from(tab.inner_join(subQuery).unconditionally()).unconditionally()))
{
std::cerr << row.alpha;
}
return 0;
}

View File

@@ -0,0 +1,173 @@
/*
* Copyright (c) 2013 - 2016, Roland Bock
* Copyright (c) 2017, Juan Dent
* 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 "TabSample.h"
#include <cassert>
#include <sqlpp11/alias_provider.h>
#include <sqlpp11/functions.h>
#include <sqlpp11/insert.h>
#include <sqlpp11/remove.h>
#include <sqlpp11/select.h>
#include <sqlpp11/sqlite3/connection.h>
#include <sqlpp11/transaction.h>
#include <sqlpp11/update.h>
#include <iostream>
#include <vector>
SQLPP_ALIAS_PROVIDER(left)
namespace sql = sqlpp::sqlite3;
const auto tab = TabSample{};
void testSelectAll(sql::connection& db, size_t expectedRowCount)
{
std::cerr << "--------------------------------------" << std::endl;
size_t i = 0;
for (const auto& row : db(sqlpp::select(all_of(tab)).from(tab).unconditionally()))
{
++i;
std::cerr << ">>> row.alpha: " << row.alpha << ", row.beta: " << row.beta << ", row.gamma: " << row.gamma
<< std::endl;
assert(static_cast<size_t>(row.alpha) == i);
};
assert(i == expectedRowCount);
auto preparedSelectAll = db.prepare(sqlpp::select(all_of(tab)).from(tab).unconditionally());
i = 0;
for (const auto& row : db(preparedSelectAll))
{
++i;
std::cerr << ">>> row.alpha: " << row.alpha << ", row.beta: " << row.beta << ", row.gamma: " << row.gamma
<< std::endl;
assert(static_cast<size_t>(row.alpha) == i);
};
assert(i == expectedRowCount);
std::cerr << "--------------------------------------" << std::endl;
}
namespace string_util
{
std::string ltrim(std::string str, const std::string& chars = "\t\n\v\f\r ")
{
str.erase(0, str.find_first_not_of(chars));
return str;
}
std::string rtrim(std::string str, const std::string& chars = "\t\n\v\f\r ")
{
str.erase(str.find_last_not_of(chars) + 1);
return str;
}
std::string trim(std::string str, const std::string& chars = "\t\n\v\f\r ")
{
return ltrim(rtrim(str, chars), chars);
}
}
int main()
{
sql::connection db({":memory:", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, "", true});
db.execute(R"(CREATE TABLE tab_sample (
alpha INTEGER PRIMARY KEY,
beta varchar(255) DEFAULT NULL,
gamma bool DEFAULT NULL
))");
testSelectAll(db, 0);
db(insert_into(tab).default_values());
testSelectAll(db, 1);
db(insert_into(tab).set(tab.gamma = true, tab.beta = " cheesecake "));
testSelectAll(db, 2);
db(insert_into(tab).set(tab.gamma = true, tab.beta = " cheesecake "));
testSelectAll(db, 3);
// test functions and operators
db(select(all_of(tab)).from(tab).where(tab.alpha.is_null()));
db(select(all_of(tab)).from(tab).where(tab.alpha.is_not_null()));
db(select(all_of(tab)).from(tab).where(tab.alpha.in(1, 2, 3)));
db(select(all_of(tab)).from(tab).where(tab.alpha.in(sqlpp::value_list(std::vector<int>{1, 2, 3, 4}))));
db(select(all_of(tab)).from(tab).where(tab.alpha.not_in(1, 2, 3)));
db(select(all_of(tab)).from(tab).where(tab.alpha.not_in(sqlpp::value_list(std::vector<int>{1, 2, 3, 4}))));
db(select(count(tab.alpha)).from(tab).unconditionally());
db(select(avg(tab.alpha)).from(tab).unconditionally());
db(select(max(tab.alpha)).from(tab).unconditionally());
db(select(min(tab.alpha)).from(tab).unconditionally());
db(select(exists(select(tab.alpha).from(tab).where(tab.alpha > 7))).from(tab).unconditionally());
db(select(trim(tab.beta)).from(tab).unconditionally());
// db(select(not_exists(select(tab.alpha).from(tab).where(tab.alpha > 7))).from(tab));
// db(select(all_of(tab)).from(tab).where(tab.alpha == any(select(tab.alpha).from(tab).where(tab.alpha < 3))));
db(select(all_of(tab)).from(tab).where((tab.alpha + tab.alpha) > 3));
db(select(all_of(tab)).from(tab).where((tab.beta + tab.beta) == ""));
db(select(all_of(tab)).from(tab).where((tab.beta + tab.beta).like(R"(%'\"%)")));
// update
db(update(tab).set(tab.gamma = false).where(tab.alpha.in(1)));
db(update(tab).set(tab.gamma = false).where(tab.alpha.in(sqlpp::value_list(std::vector<int>{1, 2, 3, 4}))));
// remove
db(remove_from(tab).where(tab.alpha == tab.alpha + 3));
auto result = db(select(all_of(tab)).from(tab).unconditionally());
std::cerr << "Accessing a field directly from the result (using the current row): " << result.begin()->alpha
<< std::endl;
std::cerr << "Can do that again, no problem: " << result.begin()->alpha << std::endl;
std::cerr << "--------------------------------------" << std::endl;
auto tx = start_transaction(db);
for (const auto& row : db(select(all_of(tab), select(max(tab.alpha)).from(tab)).from(tab).unconditionally()))
{
int x = row.alpha;
int a = row.max;
std::cout << ">>>" << x << ", " << a << std::endl;
}
for (const auto& row :
db(select(tab.alpha, tab.beta, tab.gamma, trim(tab.beta))
.from(tab)
.unconditionally()))
{
std::cerr << ">>> row.alpha: " << row.alpha << ", row.beta: " << row.beta << ", row.gamma: " << row.gamma
<< ", row.trim: '" << row.trim << "'" << std::endl;
// check trim
assert(string_util::trim(row.beta.value()) == row.trim.value());
// end
};
for (const auto& row : db(select(all_of(tab), select(trim(tab.beta)).from(tab)).from(tab).unconditionally()))
{
int x = row.alpha;
std::string a = row.trim;
std::cout << ">>>" << x << ", " << a << std::endl;
}
tx.commit();
std::cerr << "--------------------------------------" << std::endl;
return 0;
}

View File

@@ -0,0 +1,250 @@
/*
* Copyright (c) 2013 - 2015, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SQLPP_TAB_SAMPLE_H
#define SQLPP_TAB_SAMPLE_H
#include <sqlpp11/table.h>
#include <sqlpp11/char_sequence.h>
#include <sqlpp11/column_types.h>
namespace TabFoo_
{
struct Omega
{
struct _alias_t
{
static constexpr const char _literal[] = "omega";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T omega;
T& operator()()
{
return omega;
}
const T& operator()() const
{
return omega;
}
};
};
using _traits = ::sqlpp::make_traits<::sqlpp::bigint>;
};
}
struct TabFoo : sqlpp::table_t<TabFoo, TabFoo_::Omega>
{
using _value_type = sqlpp::no_value_t;
struct _alias_t
{
static constexpr const char _literal[] = "tab_foo";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T tabFoo;
T& operator()()
{
return tabFoo;
}
const T& operator()() const
{
return tabFoo;
}
};
};
};
namespace TabSample_
{
struct Alpha
{
struct _alias_t
{
static constexpr const char _literal[] = "alpha";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T alpha;
T& operator()()
{
return alpha;
}
const T& operator()() const
{
return alpha;
}
};
};
using _traits = ::sqlpp::make_traits<::sqlpp::bigint,
::sqlpp::tag::must_not_insert,
::sqlpp::tag::must_not_update,
::sqlpp::tag::can_be_null>;
};
struct Beta
{
struct _alias_t
{
static constexpr const char _literal[] = "beta";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T beta;
T& operator()()
{
return beta;
}
const T& operator()() const
{
return beta;
}
};
};
using _traits = ::sqlpp::make_traits<::sqlpp::varchar, ::sqlpp::tag::must_not_update, ::sqlpp::tag::can_be_null>;
};
struct Gamma
{
struct _alias_t
{
static constexpr const char _literal[] = "gamma";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T gamma;
T& operator()()
{
return gamma;
}
const T& operator()() const
{
return gamma;
}
};
};
using _traits = ::sqlpp::make_traits<::sqlpp::boolean>;
};
}
struct TabSample : sqlpp::table_t<TabSample, TabSample_::Alpha, TabSample_::Beta, TabSample_::Gamma>
{
using _value_type = sqlpp::no_value_t;
struct _alias_t
{
static constexpr const char _literal[] = "tab_sample";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T tabSample;
T& operator()()
{
return tabSample;
}
const T& operator()() const
{
return tabSample;
}
};
};
};
namespace TabDateTime_
{
struct ColDayPoint
{
struct _alias_t
{
static constexpr const char _literal[] = "col_day_point";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T colDayPoint;
T& operator()()
{
return colDayPoint;
}
const T& operator()() const
{
return colDayPoint;
}
};
};
using _traits = sqlpp::make_traits<sqlpp::day_point, sqlpp::tag::can_be_null>;
};
struct ColTimePoint
{
struct _alias_t
{
static constexpr const char _literal[] = "col_time_point";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T colTimePoint;
T& operator()()
{
return colTimePoint;
}
const T& operator()() const
{
return colTimePoint;
}
};
};
using _traits = sqlpp::make_traits<sqlpp::time_point, sqlpp::tag::can_be_null>;
};
}
struct TabDateTime : sqlpp::table_t<TabDateTime, TabDateTime_::ColDayPoint, TabDateTime_::ColTimePoint>
{
struct _alias_t
{
static constexpr const char _literal[] = "tab_date_time";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T tabDateTime;
T& operator()()
{
return tabDateTime;
}
const T& operator()() const
{
return tabDateTime;
}
};
};
};
#endif

View File

@@ -0,0 +1,5 @@
CREATE TABLE tab_sample (
alpha bigint(20) DEFAULT NULL,
beta tinyint(1) DEFAULT NULL,
gamma varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

View File

@@ -0,0 +1,84 @@
/*
* 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 "TabSample.h"
#include <cassert>
#include <sqlpp11/alias_provider.h>
#include <sqlpp11/custom_query.h>
#include <sqlpp11/functions.h>
#include <sqlpp11/insert.h>
#include <sqlpp11/remove.h>
#include <sqlpp11/select.h>
#include <sqlpp11/sqlite3/connection.h>
#include <sqlpp11/transaction.h>
#include <sqlpp11/update.h>
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <iostream>
#include <vector>
namespace sql = sqlpp::sqlite3;
SQLPP_ALIAS_PROVIDER(pragma)
int main()
{
sql::connection db({":memory:", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, "", true});
std::cerr << "--------------------------------------" << std::endl;
auto current_level = db.get_default_isolation_level();
std::cout << "Expecting default isolation level = 1, is " << static_cast<int>(current_level) << std::endl;
assert(current_level == sqlpp::isolation_level::serializable);
int pragmaValue = db(custom_query(sqlpp::verbatim("PRAGMA read_uncommitted"))
.with_result_type_of(select(sqlpp::value(1).as(pragma))))
.front()
.pragma;
assert(pragmaValue == 0);
std::cerr << "Expecting read_uncommitted = 0, is: " << pragmaValue << std::endl;
db.set_default_isolation_level(sqlpp::isolation_level::read_uncommitted);
auto tx = start_transaction(db);
pragmaValue = db(custom_query(sqlpp::verbatim("PRAGMA read_uncommitted"))
.with_result_type_of(select(sqlpp::value(1).as(pragma))))
.front()
.pragma;
std::cerr << "Now expecting read_uncommitted = 1, is: " << pragmaValue << std::endl;
assert(pragmaValue == 1);
current_level = db.get_default_isolation_level();
std::cout << "Now expecting default isolation level = 4, is " << static_cast<int>(current_level) << std::endl;
assert(current_level == sqlpp::isolation_level::read_uncommitted);
tx.commit();
std::cerr << "--------------------------------------" << std::endl;
return 0;
}

View File

@@ -0,0 +1,67 @@
/*
* 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 "TabSample.h"
#include <sqlpp11/sqlite3/connection.h>
#include <sqlpp11/sqlpp11.h>
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <iostream>
namespace sql = sqlpp::sqlite3;
const auto tab = TabSample{};
int main()
{
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = true;
sql::connection db(config);
db.execute(R"(CREATE TABLE tab_sample (
alpha INTEGER PRIMARY KEY,
beta varchar(255) DEFAULT NULL,
gamma bool DEFAULT NULL
))");
auto u = select(all_of(tab)).from(tab).unconditionally().union_all(select(all_of(tab)).from(tab).unconditionally());
for (const auto& row : db(u))
{
std::cout << row.alpha << row.beta << row.gamma << std::endl;
}
for (const auto& row : db(u.union_distinct(select(all_of(tab)).from(tab).unconditionally())))
{
std::cout << row.alpha << row.beta << row.gamma << std::endl;
}
return 0;
}

View File

@@ -0,0 +1,71 @@
/*
* 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 "TabSample.h"
#include <cassert>
#include <sqlpp11/sqlite3/connection.h>
#include <sqlpp11/sqlpp11.h>
#ifdef SQLPP_USE_SQLCIPHER
#include <sqlcipher/sqlite3.h>
#else
#include <sqlite3.h>
#endif
#include <iostream>
#include <vector>
namespace sql = sqlpp::sqlite3;
const auto tab = TabSample{};
int main()
{
#if SQLITE_VERSION_NUMBER >= 3008003
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = true;
sql::connection db(config);
db.execute(R"(CREATE TABLE tab_sample (
alpha INTEGER PRIMARY KEY,
beta varchar(255) DEFAULT NULL,
gamma bool DEFAULT NULL
))");
auto a = sqlpp::cte(sqlpp::alias::a).as(select(all_of(tab)).from(tab).where(tab.alpha > 3));
for (const auto& row : db(with(a)(select(a.alpha).from(a)).unconditionally()))
{
std::cout << row.alpha << std::endl;
}
for (const auto& row :
db(with(a.union_all(select(all_of(a)).from(a).unconditionally()))(select(all_of(a)).from(a)).unconditionally()))
{
std::cout << row.alpha << row.beta << row.gamma << std::endl;
}
#endif
return 0;
}