From d1042307a667cc356b0766b0c48f7f28bba97f90 Mon Sep 17 00:00:00 2001 From: Saood Karim Date: Sun, 24 Aug 2025 03:55:41 -0500 Subject: [PATCH] Finalize build, Put support behing LLAMA_SERVER_SQLITE3: command not found build option, and update error message to include the build option is not passed situation --- common/CMakeLists.txt | 1 - common/sqlite_modern_cpp/.gitignore | 9 - common/sqlite_modern_cpp/.travis.yml | 26 - common/sqlite_modern_cpp/.ycm_extra_conf.py | 100 ---- common/sqlite_modern_cpp/CMakeLists.txt | 56 -- common/sqlite_modern_cpp/README.md | 482 ---------------- common/sqlite_modern_cpp/cmake/Catch.cmake | 175 ------ .../cmake/CatchAddTests.cmake | 77 --- .../sqlite_modern_cpp/cmake/HunterGate.cmake | 542 ------------------ .../cmake/ParseAndAddCatchTests.cmake | 185 ------ .../sqlite_modern_cpp/tests/blob_example.cc | 36 -- common/sqlite_modern_cpp/tests/error_log.cc | 63 -- .../tests/exception_dont_execute.cc | 23 - .../tests/exception_dont_execute_nested.cc | 31 - common/sqlite_modern_cpp/tests/exceptions.cc | 51 -- common/sqlite_modern_cpp/tests/flags.cc | 80 --- common/sqlite_modern_cpp/tests/functions.cc | 51 -- common/sqlite_modern_cpp/tests/functors.cc | 39 -- .../sqlite_modern_cpp/tests/lvalue_functor.cc | 52 -- common/sqlite_modern_cpp/tests/mov_ctor.cc | 31 - common/sqlite_modern_cpp/tests/named.cc | 20 - .../tests/nullptr_uniqueptr.cc | 27 - .../tests/prepared_statment.cc | 102 ---- .../sqlite_modern_cpp/tests/readme_example.cc | 64 --- .../tests/shared_connection.cc | 27 - .../tests/simple_examples.cc | 36 -- common/sqlite_modern_cpp/tests/sqlcipher.cc | 56 -- .../sqlite_modern_cpp/tests/std_optional.cc | 31 - common/sqlite_modern_cpp/tests/string_view.cc | 23 - .../sqlite_modern_cpp/tests/trycatchblocks.cc | 80 --- common/sqlite_modern_cpp/tests/variant.cc | 57 -- examples/server/CMakeLists.txt | 10 +- examples/server/public_mikupad/index.html | 2 +- examples/server/server.cpp | 34 +- .../server}/sqlite_modern_cpp/License.txt | 0 .../sqlite_modern_cpp/hdr/sqlite_modern_cpp.h | 0 .../hdr/sqlite_modern_cpp/errors.h | 0 .../hdr/sqlite_modern_cpp/lists/error_codes.h | 0 .../hdr/sqlite_modern_cpp/log.h | 0 .../hdr/sqlite_modern_cpp/sqlcipher.h | 0 .../hdr/sqlite_modern_cpp/type_wrapper.h | 0 .../utility/function_traits.h | 0 .../utility/uncaught_exceptions.h | 0 .../sqlite_modern_cpp/utility/utf16_utf8.h | 0 44 files changed, 41 insertions(+), 2638 deletions(-) delete mode 100644 common/sqlite_modern_cpp/.gitignore delete mode 100644 common/sqlite_modern_cpp/.travis.yml delete mode 100644 common/sqlite_modern_cpp/.ycm_extra_conf.py delete mode 100644 common/sqlite_modern_cpp/CMakeLists.txt delete mode 100644 common/sqlite_modern_cpp/README.md delete mode 100644 common/sqlite_modern_cpp/cmake/Catch.cmake delete mode 100644 common/sqlite_modern_cpp/cmake/CatchAddTests.cmake delete mode 100644 common/sqlite_modern_cpp/cmake/HunterGate.cmake delete mode 100644 common/sqlite_modern_cpp/cmake/ParseAndAddCatchTests.cmake delete mode 100644 common/sqlite_modern_cpp/tests/blob_example.cc delete mode 100644 common/sqlite_modern_cpp/tests/error_log.cc delete mode 100644 common/sqlite_modern_cpp/tests/exception_dont_execute.cc delete mode 100644 common/sqlite_modern_cpp/tests/exception_dont_execute_nested.cc delete mode 100644 common/sqlite_modern_cpp/tests/exceptions.cc delete mode 100644 common/sqlite_modern_cpp/tests/flags.cc delete mode 100644 common/sqlite_modern_cpp/tests/functions.cc delete mode 100644 common/sqlite_modern_cpp/tests/functors.cc delete mode 100644 common/sqlite_modern_cpp/tests/lvalue_functor.cc delete mode 100644 common/sqlite_modern_cpp/tests/mov_ctor.cc delete mode 100644 common/sqlite_modern_cpp/tests/named.cc delete mode 100644 common/sqlite_modern_cpp/tests/nullptr_uniqueptr.cc delete mode 100644 common/sqlite_modern_cpp/tests/prepared_statment.cc delete mode 100644 common/sqlite_modern_cpp/tests/readme_example.cc delete mode 100644 common/sqlite_modern_cpp/tests/shared_connection.cc delete mode 100644 common/sqlite_modern_cpp/tests/simple_examples.cc delete mode 100644 common/sqlite_modern_cpp/tests/sqlcipher.cc delete mode 100644 common/sqlite_modern_cpp/tests/std_optional.cc delete mode 100644 common/sqlite_modern_cpp/tests/string_view.cc delete mode 100644 common/sqlite_modern_cpp/tests/trycatchblocks.cc delete mode 100644 common/sqlite_modern_cpp/tests/variant.cc rename {common => examples/server}/sqlite_modern_cpp/License.txt (100%) rename {common => examples/server}/sqlite_modern_cpp/hdr/sqlite_modern_cpp.h (100%) rename {common => examples/server}/sqlite_modern_cpp/hdr/sqlite_modern_cpp/errors.h (100%) rename {common => examples/server}/sqlite_modern_cpp/hdr/sqlite_modern_cpp/lists/error_codes.h (100%) rename {common => examples/server}/sqlite_modern_cpp/hdr/sqlite_modern_cpp/log.h (100%) rename {common => examples/server}/sqlite_modern_cpp/hdr/sqlite_modern_cpp/sqlcipher.h (100%) rename {common => examples/server}/sqlite_modern_cpp/hdr/sqlite_modern_cpp/type_wrapper.h (100%) rename {common => examples/server}/sqlite_modern_cpp/hdr/sqlite_modern_cpp/utility/function_traits.h (100%) rename {common => examples/server}/sqlite_modern_cpp/hdr/sqlite_modern_cpp/utility/uncaught_exceptions.h (100%) rename {common => examples/server}/sqlite_modern_cpp/hdr/sqlite_modern_cpp/utility/utf16_utf8.h (100%) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index eb09ec23..77fe2b34 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -95,6 +95,5 @@ if (LLAMA_CURL) endif () target_include_directories(${TARGET} PUBLIC .) -target_include_directories(${TARGET} PUBLIC ./sqlite_modern_cpp/hdr) target_compile_features (${TARGET} PUBLIC cxx_std_11) target_link_libraries (${TARGET} PRIVATE ${LLAMA_COMMON_EXTRA_LIBS} PUBLIC llama Threads::Threads) diff --git a/common/sqlite_modern_cpp/.gitignore b/common/sqlite_modern_cpp/.gitignore deleted file mode 100644 index a1e26fa7..00000000 --- a/common/sqlite_modern_cpp/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ - -.deps - -config.log - -config.status -compile_commands.json -build/ - diff --git a/common/sqlite_modern_cpp/.travis.yml b/common/sqlite_modern_cpp/.travis.yml deleted file mode 100644 index 00a58193..00000000 --- a/common/sqlite_modern_cpp/.travis.yml +++ /dev/null @@ -1,26 +0,0 @@ -language: cpp -sudo: required -dist: trusty - -cache: - apt: true - directories: - - /home/travis/.hunter/ - -addons: - apt: - sources: - - ubuntu-toolchain-r-test - - george-edison55-precise-backports - packages: - - g++-5 - - libsqlcipher-dev - - cmake - -before_install: - - export CXX="g++-5" CC="gcc-5" - -script: mkdir build && cd ./build && cmake .. && cmake --build . && ctest . - -# TODO: fix sqlcipher test -# script: mkdir build && cd ./build && cmake -DENABLE_SQLCIPHER_TESTS=ON .. && make && ./tests diff --git a/common/sqlite_modern_cpp/.ycm_extra_conf.py b/common/sqlite_modern_cpp/.ycm_extra_conf.py deleted file mode 100644 index 8a71764c..00000000 --- a/common/sqlite_modern_cpp/.ycm_extra_conf.py +++ /dev/null @@ -1,100 +0,0 @@ -import os -import ycm_core - -from clang_helpers import PrepareClangFlags - -def DirectoryOfThisScript(): - return os.path.dirname(os.path.abspath(__file__)) - -# This is the single most important line in this script. Everything else is just nice to have but -# not strictly necessary. -compilation_database_folder = DirectoryOfThisScript() - -# This provides a safe fall-back if no compilation commands are available. You could also add a -# includes relative to your project directory, for example. -flags = [ - '-Wall', - '-std=c++14', - '-x', - 'c++', - '-isystem', '/usr/local/include', - '-isystem', '/usr/include', - '-I.', -] - -database = ycm_core.CompilationDatabase(compilation_database_folder) - -SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ] - -def MakeRelativePathsInFlagsAbsolute( flags, working_directory ): - if not working_directory: - return list( flags ) - new_flags = [] - make_next_absolute = False - path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ] - for flag in flags: - new_flag = flag - - if make_next_absolute: - make_next_absolute = False - if not flag.startswith( '/' ): - new_flag = os.path.join( working_directory, flag ) - - for path_flag in path_flags: - if flag == path_flag: - make_next_absolute = True - break - - if flag.startswith( path_flag ): - path = flag[ len( path_flag ): ] - new_flag = path_flag + os.path.join( working_directory, path ) - break - - if new_flag: - new_flags.append( new_flag ) - return new_flags - - -def IsHeaderFile( filename ): - extension = os.path.splitext( filename )[ 1 ] - return extension in [ '.h', '.hxx', '.hpp', '.hh' ] - - -def GetCompilationInfoForFile( filename ): - # The compilation_commands.json file generated by CMake does not have entries - # for header files. So we do our best by asking the db for flags for a - # corresponding source file, if any. If one exists, the flags for that file - # should be good enough. - if IsHeaderFile( filename ): - basename = os.path.splitext( filename )[ 0 ] - for extension in SOURCE_EXTENSIONS: - replacement_file = basename + extension - if os.path.exists( replacement_file ): - compilation_info = database.GetCompilationInfoForFile( - replacement_file ) - if compilation_info.compiler_flags_: - return compilation_info - return None - return database.GetCompilationInfoForFile( filename ) - - -def FlagsForFile( filename, **kwargs ): - if database: - # Bear in mind that compilation_info.compiler_flags_ does NOT return a - # python list, but a "list-like" StringVec object - compilation_info = GetCompilationInfoForFile( filename ) - if not compilation_info: - return None - - final_flags = MakeRelativePathsInFlagsAbsolute( - compilation_info.compiler_flags_, - compilation_info.compiler_working_dir_ ) - - else: - relative_to = DirectoryOfThisScript() - final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to ) - - return { - 'flags': final_flags, - 'do_cache': True - } diff --git a/common/sqlite_modern_cpp/CMakeLists.txt b/common/sqlite_modern_cpp/CMakeLists.txt deleted file mode 100644 index f18d59b4..00000000 --- a/common/sqlite_modern_cpp/CMakeLists.txt +++ /dev/null @@ -1,56 +0,0 @@ -cmake_minimum_required(VERSION 3.0) -option(ENABLE_SQLCIPHER_TESTS "enable sqlchipher test") - -# Creates the file compile_commands.json in the build directory. -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -set(CMAKE_CXX_STANDARD 17) - -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") -set(HUNTER_TLS_VERIFY ON) -include("cmake/HunterGate.cmake") -include("cmake/Catch.cmake") - -HunterGate( - URL "https://github.com/cpp-pm/hunter/archive/v0.24.15.tar.gz" - SHA1 "8010d63d5ae611c564889d5fe12d3cb7a45703ac" -) - -project(SqliteModernCpp) - -hunter_add_package(Catch) -hunter_add_package(sqlite3) - -find_package(Catch2 CONFIG REQUIRED) -find_package(sqlite3 CONFIG REQUIRED) - -set(TEST_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/tests) -file(GLOB TEST_SOURCES ${TEST_SOURCE_DIR}/*.cc) - -IF(NOT ENABLE_SQLCIPHER_TESTS) - list(REMOVE_ITEM TEST_SOURCES ${TEST_SOURCE_DIR}/sqlcipher.cc) -ENDIF(NOT ENABLE_SQLCIPHER_TESTS) - -enable_testing() - -add_library (sqlite_modern_cpp INTERFACE) -target_include_directories(sqlite_modern_cpp INTERFACE hdr/) - -add_executable(tests_runner ${TEST_SOURCES}) -target_include_directories(tests_runner INTERFACE ${SQLITE3_INCLUDE_DIRS}) -if(ENABLE_SQLCIPHER_TESTS) - target_link_libraries(tests_runner Catch2::Catch2 sqlite_modern_cpp sqlite3::sqlite3 -lsqlcipher) -else() - target_link_libraries(tests_runner Catch2::Catch2 sqlite_modern_cpp sqlite3::sqlite3) -endif() - -catch_discover_tests(tests_runner) -target_compile_options(tests_runner PUBLIC $<$:/Zc:__cplusplus> ) - -# Place the file in the source directory, permitting us to place a single configuration file for YCM there. -# YCM is the code-completion engine for (neo)vim https://github.com/Valloric/YouCompleteMe -IF(EXISTS "${CMAKE_BINARY_DIR}/compile_commands.json") - EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${CMAKE_BINARY_DIR}/compile_commands.json - ${CMAKE_SOURCE_DIR}/compile_commands.json - ) -ENDIF() diff --git a/common/sqlite_modern_cpp/README.md b/common/sqlite_modern_cpp/README.md deleted file mode 100644 index cd94069a..00000000 --- a/common/sqlite_modern_cpp/README.md +++ /dev/null @@ -1,482 +0,0 @@ -[![Build Status](https://drone.io/github.com/aminroosta/sqlite_modern_cpp/status.png)](https://drone.io/github.com/aminroosta/sqlite_modern_cpp/latest) - -sqlite modern cpp wrapper -==== - -This library is a lightweight modern wrapper around sqlite C api . - -```c++ -#include -#include -using namespace sqlite; -using namespace std; - -int main() { - - try { - // creates a database file 'dbfile.db' if it does not exists. - database db("dbfile.db"); - - // executes the query and creates a 'user' table - db << - "create table if not exists user (" - " _id integer primary key autoincrement not null," - " age int," - " name text," - " weight real" - ");"; - - // inserts a new user record. - // binds the fields to '?' . - // note that only types allowed for bindings are : - // int ,long, long long, float, double - // string, u16string - // sqlite3 only supports utf8 and utf16 strings, you should use std::string for utf8 and std::u16string for utf16. - // If you're using C++17, `std::string_view` and `std::u16string_view` can be used as string types. - // note that u"my text" is a utf16 string literal of type char16_t * . - db << "insert into user (age,name,weight) values (?,?,?);" - << 20 - << u"bob" - << 83.25; - - int age = 21; - float weight = 68.5; - string name = "jack"; - db << u"insert into user (age,name,weight) values (?,?,?);" // utf16 query string - << age - << name - << weight; - - cout << "The new record got assigned id " << db.last_insert_rowid() << endl; - - // selects from user table on a condition ( age > 18 ) and executes - // the lambda for each row returned . - db << "select age,name,weight from user where age > ? ;" - << 18 - >> [&](int age, string name, double weight) { - cout << age << ' ' << name << ' ' << weight << endl; - }; - - // a for loop can be used too: - // with named variables - for(auto &&row : db << "select age,name,weight from user where age > ? ;" << 18) { - int age; string name; double weight; - row >> age >> name >> weight; - cout << age << ' ' << name << ' ' << weight << endl; - } - // or with a tuple - for(tuple row : db << "select age,name,weight from user where age > ? ;" << 18) { - cout << get<0>(row) << ' ' << get<1>(row) << ' ' << get<2>(row) << endl; - } - - // selects the count(*) from user table - // note that you can extract a single column single row result only to : int,long,long long,float,double,string,u16string - int count = 0; - db << "select count(*) from user" >> count; - cout << "cout : " << count << endl; - - // you can also extract multiple column rows - db << "select age, name from user where _id=1;" >> tie(age, name); - cout << "Age = " << age << ", name = " << name << endl; - - // this also works and the returned value will be automatically converted to string - string str_count; - db << "select count(*) from user" >> str_count; - cout << "scount : " << str_count << endl; - } - catch (const exception& e) { - cout << e.what() << endl; - } -} -``` - -You can not execute multiple statements separated by semicolons in one go. - -Additional flags ----- -You can pass additional open flags to SQLite by using a config object: - -```c++ -sqlite_config config; -config.flags = OpenFlags::READONLY -database db("some_db", config); -int a; -// Now you can only read from db -auto ps = db << "select a from table where something = ? and anotherthing = ?" >> a; -config.flags = OpenFlags::READWRITE | OpenFlags::CREATE; // This is the default -config.encoding = Encoding::UTF16; // The encoding is respected only if you create a new database -database db2("some_db2", config); -// If some_db2 didn't exists before, it will be created with UTF-16 encoding. -``` - -Prepared Statements ----- -It is possible to retain and reuse statments this will keep the query plan and in case of an complex query or many uses might increase the performance significantly. - -```c++ -database db(":memory:"); - -// if you use << on a sqlite::database you get a prepared statment back -// this will not be executed till it gets destroyed or you execute it explicitly -auto ps = db << "select a,b from table where something = ? and anotherthing = ?"; // get a prepared parsed and ready statment - -// first if needed bind values to it -ps << 5; -int tmp = 8; -ps << tmp; - -// now you can execute it with `operator>>` or `execute()`. -// If the statement was executed once it will not be executed again when it goes out of scope. -// But beware that it will execute on destruction if it wasn't executed! -ps >> [&](int a,int b){ ... }; - -// after a successfull execution the statment can be executed again, but the bound values are resetted. -// If you dont need the returned values you can execute it like this -ps.execute(); -// or like this -ps++; - -// To disable the execution of a statment when it goes out of scope and wasn't used -ps.used(true); // or false if you want it to execute even if it was used - -// Usage Example: - -auto ps = db << "insert into complex_table_with_lots_of_indices values (?,?,?)"; -int i = 0; -while( i < 100000 ){ - ps << long_list[i++] << long_list[i++] << long_list[i++]; - ps++; -} -``` - -Shared Connections ----- -If you need the handle to the database connection to execute sqlite3 commands directly you can get a managed shared_ptr to it, so it will not close as long as you have a referenc to it. - -Take this example on how to deal with a database backup using SQLITEs own functions in a safe and modern way. -```c++ -try { - database backup("backup"); //Open the database file we want to backup to - - auto con = db.connection(); // get a handle to the DB we want to backup in our scope - // this way we are sure the DB is open and ok while we backup - - // Init Backup and make sure its freed on exit or exceptions! - auto state = - std::unique_ptr( - sqlite3_backup_init(backup.connection().get(), "main", con.get(), "main"), - sqlite3_backup_finish - ); - - if(state) { - int rc; - // Each iteration of this loop copies 500 database pages from database db to the backup database. - do { - rc = sqlite3_backup_step(state.get(), 500); - std::cout << "Remaining " << sqlite3_backup_remaining(state.get()) << "/" << sqlite3_backup_pagecount(state.get()) << "\n"; - } while(rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED); - } -} // Release allocated resources. -``` - -Transactions ----- -You can use transactions with `begin;`, `commit;` and `rollback;` commands. - -```c++ -db << "begin;"; // begin a transaction ... -db << "insert into user (age,name,weight) values (?,?,?);" - << 20 - << u"bob" - << 83.25f; -db << "insert into user (age,name,weight) values (?,?,?);" // utf16 string - << 21 - << u"jack" - << 68.5; -db << "commit;"; // commit all the changes. - -db << "begin;"; // begin another transaction .... -db << "insert into user (age,name,weight) values (?,?,?);" // utf16 string - << 19 - << u"chirs" - << 82.7; -db << "rollback;"; // cancel this transaction ... - -``` - -Blob ----- -Use `std::vector` to store and retrieve blob data. -`T` could be `char,short,int,long,long long, float or double`. - -```c++ -db << "CREATE TABLE person (name TEXT, numbers BLOB);"; -db << "INSERT INTO person VALUES (?, ?)" << "bob" << vector { 1, 2, 3, 4}; -db << "INSERT INTO person VALUES (?, ?)" << "sara" << vector { 1.0, 2.0, 3.0, 4.0}; - -vector numbers_bob; -db << "SELECT numbers from person where name = ?;" << "bob" >> numbers_bob; - -db << "SELECT numbers from person where name = ?;" << "sara" >> [](vector numbers_sara){ - for(auto e : numbers_sara) cout << e << ' '; cout << endl; -}; -``` - -NULL values ----- -If you have databases where some rows may be null, you can use `std::unique_ptr` to retain the NULL values between C++ variables and the database. - -```c++ -db << "CREATE TABLE tbl (id integer,age integer, name string, img blob);"; -db << "INSERT INTO tbl VALUES (?, ?, ?, ?);" << 1 << 24 << "bob" << vector { 1, 2 , 3}; -unique_ptr ptr_null; // you can even bind empty unique_ptr -db << "INSERT INTO tbl VALUES (?, ?, ?, ?);" << 2 << nullptr << ptr_null << nullptr; - -db << "select age,name,img from tbl where id = 1" - >> [](unique_ptr age_p, unique_ptr name_p, unique_ptr> img_p) { - if(age_p == nullptr || name_p == nullptr || img_p == nullptr) { - cerr << "ERROR: values should not be null" << std::endl; - } - - cout << "age:" << *age_p << " name:" << *name_p << " img:"; - for(auto i : *img_p) cout << i << ","; cout << endl; - }; - -db << "select age,name,img from tbl where id = 2" - >> [](unique_ptr age_p, unique_ptr name_p, unique_ptr> img_p) { - if(age_p != nullptr || name_p != nullptr || img_p != nullptr) { - cerr << "ERROR: values should be nullptr" << std::endl; - exit(EXIT_FAILURE); - } - - cout << "OK all three values are nullptr" << endl; - }; -``` - -SQLCipher ----- - -We have native support for [SQLCipher](https://www.zetetic.net/sqlcipher/). -If you want to use encrypted databases, include the `sqlite_moder_cpp/sqlcipher.h` header. -Then create a `sqlcipher_database` instead. - -```c++ -#include -#include -using namespace sqlite; -using namespace std; - -int main() { - try { - // creates a database file 'dbfile.db' if it does not exists with password 'secret' - sqlcipher_config config; - config.key = secret; - sqlcipher_database db("dbfile.db", config); - - // executes the query and creates a 'user' table - db << - "create table if not exists user (" - " _id integer primary key autoincrement not null," - " age int," - " name text," - " weight real" - ");"; - - // More queries ... - db.rekey("new_secret"); // Change the password of the already encrypted database. - - // Even more queries .. - } - catch (const exception& e) { cout << e.what() << endl; } -} -``` - -NULL values (C++17) ----- -You can use `std::optional` as an alternative for `std::unique_ptr` to work with NULL values. - -```c++ -#include - -struct User { - long long _id; - std::optional age; - std::optional name; - std::optional weight; -}; - -int main() { - User user; - user.name = "bob"; - - // Same database as above - database db("dbfile.db"); - - // Here, age and weight will be inserted as NULL in the database. - db << "insert into user (age,name,weight) values (?,?,?);" - << user.age - << user.name - << user.weight; - user._id = db.last_insert_rowid(); - - // Here, the User instance will retain the NULL value(s) from the database. - db << "select _id,age,name,weight from user where age > ? ;" - << 18 - >> [&](long long id, - std::optional age, - std::optional name - std::optional weight) { - - cout << "id=" << _id - << " age = " << (age ? to_string(*age) ? string("NULL")) - << " name = " << (name ? *name : string("NULL")) - << " weight = " << (weight ? to_string(*weight) : string(NULL)) - << endl; - }; -} -``` -If the optional library is not available, the experimental/optional one will be used instead. - -Variant type support (C++17) ----- -If your columns may have flexible types, you can use C++17's `std::variant` to extract the value. - -```c++ -db << "CREATE TABLE tbl (id integer, data);"; -db << "INSERT INTO tbl VALUES (?, ?);" << 1 << vector { 1, 2, 3}; -db << "INSERT INTO tbl VALUES (?, ?);" << 2 << 2.5; - -db << "select data from tbl where id = 1" - >> [](std::variant, double> data) { - if(data.index() != 1) { - cerr << "ERROR: we expected a blob" << std::endl; - } - - for(auto i : get>(data)) cout << i << ","; cout << endl; - }; - -db << "select data from tbl where id = 2" - >> [](std::variant, double> data) { - if(data.index() != 2) { - cerr << "ERROR: we expected a real number" << std::endl; - } - - cout << get(data) << endl; - }; -``` - -If you read a specific type and this type does not match the actual type in the SQlite database, yor data will be converted. -This does not happen if you use a `variant`. -If the `variant` does an alternative of the same value type, an `mismatch` exception will be thrown. -The value types are NULL, integer, real number, text and BLOB. -To support all possible values, you can use `variant`. -It is also possible to use a variant with `std::monostate` in order to catch null values. - -Errors ----- - -On error, the library throws an error class indicating the type of error. The error classes are derived from the SQLITE3 error names, so if the error code is SQLITE_CONSTRAINT, the error class thrown is sqlite::errors::constraint. SQLite3 extended error names are supported too. So there is e.g. a class sqlite::errors::constraint_primarykey derived from sqlite::errors::constraint. Note that all errors are derived from sqlite::sqlite_exception and that itself is derived from std::runtime_exception. -sqlite::sqlite_exception has a `get_code()` member function to get the SQLITE3 error code or `get_extended_code()` to get the extended error code. -Additionally you can use `get_sql()` to see the SQL statement leading to the error. - -```c++ -database db(":memory:"); -db << "create table person (id integer primary key not null, name text);"; - -try { - db << "insert into person (id, name) values (?,?)" << 1 << "jack"; - // inserting again to produce error - db << "insert into person (id, name) values (?,?)" << 1 << "jack"; -} -/* if you are trying to catch all sqlite related exceptions - * make sure to catch them by reference */ -catch (const sqlite_exception& e) { - cerr << e.get_code() << ": " << e.what() << " during " - << e.get_sql() << endl; -} -/* you can catch specific exceptions as well, - catch(const sqlite::errors::constraint &e) { } */ -/* and even more specific exceptions - catch(const sqlite::errors::constraint_primarykey &e) { } */ -``` - -You can also register a error logging function with `sqlite::error_log`. -The `` header has to be included to make this function available. -The call to `sqlite::error_log` has to be the first call to any `sqlite_modern_cpp` function by your program. - -```c++ -error_log( - [&](sqlite_exception& e) { - cerr << e.get_code() << ": " << e.what() << endl; - }, - [&](errors::misuse& e) { - /* You can behave differently to specific errors */ - } -); -database db(":memory:"); -db << "create table person (id integer primary key not null, name text);"; - -try { - db << "insert into person (id, name) values (?,?)" << 1 << "jack"; - // inserting again to produce error - db << "insert into person (id, name) values (?,?)" << 1 << "jack"; -} -catch (const sqlite_exception& e) {} -``` - -Custom SQL functions ----- - -To extend SQLite with custom functions, you just implement them in C++: - -```c++ -database db(":memory:"); -db.define("tgamma", [](double i) {return std::tgamma(i);}); -db << "CREATE TABLE numbers (number INTEGER);"; - -for(auto i=0; i!=10; ++i) - db << "INSERT INTO numbers VALUES (?);" << i; - -db << "SELECT number, tgamma(number+1) FROM numbers;" >> [](double number, double factorial) { - cout << number << "! = " << factorial << '\n'; -}; -``` - -NDK support ----- -Just Make sure you are using the full path of your database file : -`sqlite::database db("/data/data/com.your.package/dbfile.db")`. - -Installation ----- -The project is header only. -Simply point your compiler at the hdr/ directory. - -Contributing ----- -Install cmake and build the project. -Dependencies will be installed automatically (using hunter). - -```bash -mkdir build -cd ./build -cmake .. -make -``` - -Breaking Changes ----- -See breaking changes documented in each [Release](https://github.com/aminroosta/sqlite_modern_cpp/releases). - -Package managers ----- -Pull requests are welcome :wink: -- [AUR](https://aur.archlinux.org/packages/sqlite_modern_cpp/) Arch Linux - - maintainer [Nissar Chababy](https://github.com/funilrys) -- Nuget (TODO [nuget.org](https://www.nuget.org/)) -- Conan (TODO [conan.io](https://conan.io/)) -- [vcpkg](https://github.com/Microsoft/vcpkg) - -## License - -MIT license - [http://www.opensource.org/licenses/mit-license.php](http://www.opensource.org/licenses/mit-license.php) diff --git a/common/sqlite_modern_cpp/cmake/Catch.cmake b/common/sqlite_modern_cpp/cmake/Catch.cmake deleted file mode 100644 index 486e3233..00000000 --- a/common/sqlite_modern_cpp/cmake/Catch.cmake +++ /dev/null @@ -1,175 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -Catch ------ - -This module defines a function to help use the Catch test framework. - -The :command:`catch_discover_tests` discovers tests by asking the compiled test -executable to enumerate its tests. This does not require CMake to be re-run -when tests change. However, it may not work in a cross-compiling environment, -and setting test properties is less convenient. - -This command is intended to replace use of :command:`add_test` to register -tests, and will create a separate CTest test for each Catch test case. Note -that this is in some cases less efficient, as common set-up and tear-down logic -cannot be shared by multiple test cases executing in the same instance. -However, it provides more fine-grained pass/fail information to CTest, which is -usually considered as more beneficial. By default, the CTest test name is the -same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``. - -.. command:: catch_discover_tests - - Automatically add tests with CTest by querying the compiled test executable - for available tests:: - - catch_discover_tests(target - [TEST_SPEC arg1...] - [EXTRA_ARGS arg1...] - [WORKING_DIRECTORY dir] - [TEST_PREFIX prefix] - [TEST_SUFFIX suffix] - [PROPERTIES name1 value1...] - [TEST_LIST var] - ) - - ``catch_discover_tests`` sets up a post-build command on the test executable - that generates the list of tests by parsing the output from running the test - with the ``--list-test-names-only`` argument. This ensures that the full - list of tests is obtained. Since test discovery occurs at build time, it is - not necessary to re-run CMake when the list of tests changes. - However, it requires that :prop_tgt:`CROSSCOMPILING_EMULATOR` is properly set - in order to function in a cross-compiling environment. - - Additionally, setting properties on tests is somewhat less convenient, since - the tests are not available at CMake time. Additional test properties may be - assigned to the set of tests as a whole using the ``PROPERTIES`` option. If - more fine-grained test control is needed, custom content may be provided - through an external CTest script using the :prop_dir:`TEST_INCLUDE_FILES` - directory property. The set of discovered tests is made accessible to such a - script via the ``_TESTS`` variable. - - The options are: - - ``target`` - Specifies the Catch executable, which must be a known CMake executable - target. CMake will substitute the location of the built executable when - running the test. - - ``TEST_SPEC arg1...`` - Specifies test cases, wildcarded test cases, tags and tag expressions to - pass to the Catch executable with the ``--list-test-names-only`` argument. - - ``EXTRA_ARGS arg1...`` - Any extra arguments to pass on the command line to each test case. - - ``WORKING_DIRECTORY dir`` - Specifies the directory in which to run the discovered test cases. If this - option is not provided, the current binary directory is used. - - ``TEST_PREFIX prefix`` - Specifies a ``prefix`` to be prepended to the name of each discovered test - case. This can be useful when the same test executable is being used in - multiple calls to ``catch_discover_tests()`` but with different - ``TEST_SPEC`` or ``EXTRA_ARGS``. - - ``TEST_SUFFIX suffix`` - Similar to ``TEST_PREFIX`` except the ``suffix`` is appended to the name of - every discovered test case. Both ``TEST_PREFIX`` and ``TEST_SUFFIX`` may - be specified. - - ``PROPERTIES name1 value1...`` - Specifies additional properties to be set on all tests discovered by this - invocation of ``catch_discover_tests``. - - ``TEST_LIST var`` - Make the list of tests available in the variable ``var``, rather than the - default ``_TESTS``. This can be useful when the same test - executable is being used in multiple calls to ``catch_discover_tests()``. - Note that this variable is only available in CTest. - -#]=======================================================================] - -#------------------------------------------------------------------------------ -function(catch_discover_tests TARGET) - cmake_parse_arguments( - "" - "" - "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST" - "TEST_SPEC;EXTRA_ARGS;PROPERTIES" - ${ARGN} - ) - - if(NOT _WORKING_DIRECTORY) - set(_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") - endif() - if(NOT _TEST_LIST) - set(_TEST_LIST ${TARGET}_TESTS) - endif() - - ## Generate a unique name based on the extra arguments - string(SHA1 args_hash "${_TEST_SPEC} ${_EXTRA_ARGS}") - string(SUBSTRING ${args_hash} 0 7 args_hash) - - # Define rule to generate test list for aforementioned test executable - set(ctest_include_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_include-${args_hash}.cmake") - set(ctest_tests_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_tests-${args_hash}.cmake") - get_property(crosscompiling_emulator - TARGET ${TARGET} - PROPERTY CROSSCOMPILING_EMULATOR - ) - add_custom_command( - TARGET ${TARGET} POST_BUILD - BYPRODUCTS "${ctest_tests_file}" - COMMAND "${CMAKE_COMMAND}" - -D "TEST_TARGET=${TARGET}" - -D "TEST_EXECUTABLE=$" - -D "TEST_EXECUTOR=${crosscompiling_emulator}" - -D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}" - -D "TEST_SPEC=${_TEST_SPEC}" - -D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}" - -D "TEST_PROPERTIES=${_PROPERTIES}" - -D "TEST_PREFIX=${_TEST_PREFIX}" - -D "TEST_SUFFIX=${_TEST_SUFFIX}" - -D "TEST_LIST=${_TEST_LIST}" - -D "CTEST_FILE=${ctest_tests_file}" - -P "${_CATCH_DISCOVER_TESTS_SCRIPT}" - VERBATIM - ) - - file(WRITE "${ctest_include_file}" - "if(EXISTS \"${ctest_tests_file}\")\n" - " include(\"${ctest_tests_file}\")\n" - "else()\n" - " add_test(${TARGET}_NOT_BUILT-${args_hash} ${TARGET}_NOT_BUILT-${args_hash})\n" - "endif()\n" - ) - - if(NOT ${CMAKE_VERSION} VERSION_LESS "3.10.0") - # Add discovered tests to directory TEST_INCLUDE_FILES - set_property(DIRECTORY - APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}" - ) - else() - # Add discovered tests as directory TEST_INCLUDE_FILE if possible - get_property(test_include_file_set DIRECTORY PROPERTY TEST_INCLUDE_FILE SET) - if (NOT ${test_include_file_set}) - set_property(DIRECTORY - PROPERTY TEST_INCLUDE_FILE "${ctest_include_file}" - ) - else() - message(FATAL_ERROR - "Cannot set more than one TEST_INCLUDE_FILE" - ) - endif() - endif() - -endfunction() - -############################################################################### - -set(_CATCH_DISCOVER_TESTS_SCRIPT - ${CMAKE_CURRENT_LIST_DIR}/CatchAddTests.cmake -) diff --git a/common/sqlite_modern_cpp/cmake/CatchAddTests.cmake b/common/sqlite_modern_cpp/cmake/CatchAddTests.cmake deleted file mode 100644 index 81d50b8b..00000000 --- a/common/sqlite_modern_cpp/cmake/CatchAddTests.cmake +++ /dev/null @@ -1,77 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -set(prefix "${TEST_PREFIX}") -set(suffix "${TEST_SUFFIX}") -set(spec ${TEST_SPEC}) -set(extra_args ${TEST_EXTRA_ARGS}) -set(properties ${TEST_PROPERTIES}) -set(script) -set(suite) -set(tests) - -function(add_command NAME) - set(_args "") - foreach(_arg ${ARGN}) - if(_arg MATCHES "[^-./:a-zA-Z0-9_]") - set(_args "${_args} [==[${_arg}]==]") # form a bracket_argument - else() - set(_args "${_args} ${_arg}") - endif() - endforeach() - set(script "${script}${NAME}(${_args})\n" PARENT_SCOPE) -endfunction() - -# Run test executable to get list of available tests -if(NOT EXISTS "${TEST_EXECUTABLE}") - message(FATAL_ERROR - "Specified test executable '${TEST_EXECUTABLE}' does not exist" - ) -endif() -execute_process( - COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-test-names-only - OUTPUT_VARIABLE output - RESULT_VARIABLE result -) -# Catch --list-test-names-only reports the number of tests, so 0 is... surprising -if(${result} EQUAL 0) - message(WARNING - "Test executable '${TEST_EXECUTABLE}' contains no tests!\n" - ) -elseif(${result} LESS 0) - message(FATAL_ERROR - "Error running test executable '${TEST_EXECUTABLE}':\n" - " Result: ${result}\n" - " Output: ${output}\n" - ) -endif() - -string(REPLACE "\n" ";" output "${output}") - -# Parse output -foreach(line ${output}) - # Test name; strip spaces to get just the name... - string(REGEX REPLACE "^ +" "" test "${line}") - # ...and add to script - add_command(add_test - "${prefix}${test}${suffix}" - ${TEST_EXECUTOR} - "${TEST_EXECUTABLE}" - "${test}" - ${extra_args} - ) - add_command(set_tests_properties - "${prefix}${test}${suffix}" - PROPERTIES - WORKING_DIRECTORY "${TEST_WORKING_DIR}" - ${properties} - ) - list(APPEND tests "${prefix}${test}${suffix}") -endforeach() - -# Create a list of all discovered tests, which users may use to e.g. set -# properties on the tests -add_command(set ${TEST_LIST} ${tests}) - -# Write CTest script -file(WRITE "${CTEST_FILE}" "${script}") diff --git a/common/sqlite_modern_cpp/cmake/HunterGate.cmake b/common/sqlite_modern_cpp/cmake/HunterGate.cmake deleted file mode 100644 index 45438f11..00000000 --- a/common/sqlite_modern_cpp/cmake/HunterGate.cmake +++ /dev/null @@ -1,542 +0,0 @@ -# Copyright (c) 2013-2017, Ruslan Baratov -# 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. - -# This is a gate file to Hunter package manager. -# Include this file using `include` command and add package you need, example: -# -# cmake_minimum_required(VERSION 3.0) -# -# include("cmake/HunterGate.cmake") -# HunterGate( -# URL "https://github.com/path/to/hunter/archive.tar.gz" -# SHA1 "798501e983f14b28b10cda16afa4de69eee1da1d" -# ) -# -# project(MyProject) -# -# hunter_add_package(Foo) -# hunter_add_package(Boo COMPONENTS Bar Baz) -# -# Projects: -# * https://github.com/hunter-packages/gate/ -# * https://github.com/ruslo/hunter - -option(HUNTER_ENABLED "Enable Hunter package manager support" ON) -if(HUNTER_ENABLED) - if(CMAKE_VERSION VERSION_LESS "3.0") - message(FATAL_ERROR "At least CMake version 3.0 required for hunter dependency management." - " Update CMake or set HUNTER_ENABLED to OFF.") - endif() -endif() - -include(CMakeParseArguments) # cmake_parse_arguments - -option(HUNTER_STATUS_PRINT "Print working status" ON) -option(HUNTER_STATUS_DEBUG "Print a lot info" OFF) - -set(HUNTER_WIKI "https://github.com/ruslo/hunter/wiki") - -function(hunter_gate_status_print) - foreach(print_message ${ARGV}) - if(HUNTER_STATUS_PRINT OR HUNTER_STATUS_DEBUG) - message(STATUS "[hunter] ${print_message}") - endif() - endforeach() -endfunction() - -function(hunter_gate_status_debug) - foreach(print_message ${ARGV}) - if(HUNTER_STATUS_DEBUG) - string(TIMESTAMP timestamp) - message(STATUS "[hunter *** DEBUG *** ${timestamp}] ${print_message}") - endif() - endforeach() -endfunction() - -function(hunter_gate_wiki wiki_page) - message("------------------------------ WIKI -------------------------------") - message(" ${HUNTER_WIKI}/${wiki_page}") - message("-------------------------------------------------------------------") - message("") - message(FATAL_ERROR "") -endfunction() - -function(hunter_gate_internal_error) - message("") - foreach(print_message ${ARGV}) - message("[hunter ** INTERNAL **] ${print_message}") - endforeach() - message("[hunter ** INTERNAL **] [Directory:${CMAKE_CURRENT_LIST_DIR}]") - message("") - hunter_gate_wiki("error.internal") -endfunction() - -function(hunter_gate_fatal_error) - cmake_parse_arguments(hunter "" "WIKI" "" "${ARGV}") - string(COMPARE EQUAL "${hunter_WIKI}" "" have_no_wiki) - if(have_no_wiki) - hunter_gate_internal_error("Expected wiki") - endif() - message("") - foreach(x ${hunter_UNPARSED_ARGUMENTS}) - message("[hunter ** FATAL ERROR **] ${x}") - endforeach() - message("[hunter ** FATAL ERROR **] [Directory:${CMAKE_CURRENT_LIST_DIR}]") - message("") - hunter_gate_wiki("${hunter_WIKI}") -endfunction() - -function(hunter_gate_user_error) - hunter_gate_fatal_error(${ARGV} WIKI "error.incorrect.input.data") -endfunction() - -function(hunter_gate_self root version sha1 result) - string(COMPARE EQUAL "${root}" "" is_bad) - if(is_bad) - hunter_gate_internal_error("root is empty") - endif() - - string(COMPARE EQUAL "${version}" "" is_bad) - if(is_bad) - hunter_gate_internal_error("version is empty") - endif() - - string(COMPARE EQUAL "${sha1}" "" is_bad) - if(is_bad) - hunter_gate_internal_error("sha1 is empty") - endif() - - string(SUBSTRING "${sha1}" 0 7 archive_id) - - if(EXISTS "${root}/cmake/Hunter") - set(hunter_self "${root}") - else() - set( - hunter_self - "${root}/_Base/Download/Hunter/${version}/${archive_id}/Unpacked" - ) - endif() - - set("${result}" "${hunter_self}" PARENT_SCOPE) -endfunction() - -# Set HUNTER_GATE_ROOT cmake variable to suitable value. -function(hunter_gate_detect_root) - # Check CMake variable - string(COMPARE NOTEQUAL "${HUNTER_ROOT}" "" not_empty) - if(not_empty) - set(HUNTER_GATE_ROOT "${HUNTER_ROOT}" PARENT_SCOPE) - hunter_gate_status_debug("HUNTER_ROOT detected by cmake variable") - return() - endif() - - # Check environment variable - string(COMPARE NOTEQUAL "$ENV{HUNTER_ROOT}" "" not_empty) - if(not_empty) - set(HUNTER_GATE_ROOT "$ENV{HUNTER_ROOT}" PARENT_SCOPE) - hunter_gate_status_debug("HUNTER_ROOT detected by environment variable") - return() - endif() - - # Check HOME environment variable - string(COMPARE NOTEQUAL "$ENV{HOME}" "" result) - if(result) - set(HUNTER_GATE_ROOT "$ENV{HOME}/.hunter" PARENT_SCOPE) - hunter_gate_status_debug("HUNTER_ROOT set using HOME environment variable") - return() - endif() - - # Check SYSTEMDRIVE and USERPROFILE environment variable (windows only) - if(WIN32) - string(COMPARE NOTEQUAL "$ENV{SYSTEMDRIVE}" "" result) - if(result) - set(HUNTER_GATE_ROOT "$ENV{SYSTEMDRIVE}/.hunter" PARENT_SCOPE) - hunter_gate_status_debug( - "HUNTER_ROOT set using SYSTEMDRIVE environment variable" - ) - return() - endif() - - string(COMPARE NOTEQUAL "$ENV{USERPROFILE}" "" result) - if(result) - set(HUNTER_GATE_ROOT "$ENV{USERPROFILE}/.hunter" PARENT_SCOPE) - hunter_gate_status_debug( - "HUNTER_ROOT set using USERPROFILE environment variable" - ) - return() - endif() - endif() - - hunter_gate_fatal_error( - "Can't detect HUNTER_ROOT" - WIKI "error.detect.hunter.root" - ) -endfunction() - -macro(hunter_gate_lock dir) - if(NOT HUNTER_SKIP_LOCK) - if("${CMAKE_VERSION}" VERSION_LESS "3.2") - hunter_gate_fatal_error( - "Can't lock, upgrade to CMake 3.2 or use HUNTER_SKIP_LOCK" - WIKI "error.can.not.lock" - ) - endif() - hunter_gate_status_debug("Locking directory: ${dir}") - file(LOCK "${dir}" DIRECTORY GUARD FUNCTION) - hunter_gate_status_debug("Lock done") - endif() -endmacro() - -function(hunter_gate_download dir) - string( - COMPARE - NOTEQUAL - "$ENV{HUNTER_DISABLE_AUTOINSTALL}" - "" - disable_autoinstall - ) - if(disable_autoinstall AND NOT HUNTER_RUN_INSTALL) - hunter_gate_fatal_error( - "Hunter not found in '${dir}'" - "Set HUNTER_RUN_INSTALL=ON to auto-install it from '${HUNTER_GATE_URL}'" - "Settings:" - " HUNTER_ROOT: ${HUNTER_GATE_ROOT}" - " HUNTER_SHA1: ${HUNTER_GATE_SHA1}" - WIKI "error.run.install" - ) - endif() - string(COMPARE EQUAL "${dir}" "" is_bad) - if(is_bad) - hunter_gate_internal_error("Empty 'dir' argument") - endif() - - string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" is_bad) - if(is_bad) - hunter_gate_internal_error("HUNTER_GATE_SHA1 empty") - endif() - - string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" is_bad) - if(is_bad) - hunter_gate_internal_error("HUNTER_GATE_URL empty") - endif() - - set(done_location "${dir}/DONE") - set(sha1_location "${dir}/SHA1") - - set(build_dir "${dir}/Build") - set(cmakelists "${dir}/CMakeLists.txt") - - hunter_gate_lock("${dir}") - if(EXISTS "${done_location}") - # while waiting for lock other instance can do all the job - hunter_gate_status_debug("File '${done_location}' found, skip install") - return() - endif() - - file(REMOVE_RECURSE "${build_dir}") - file(REMOVE_RECURSE "${cmakelists}") - - file(MAKE_DIRECTORY "${build_dir}") # check directory permissions - - # Disabling languages speeds up a little bit, reduces noise in the output - # and avoids path too long windows error - file( - WRITE - "${cmakelists}" - "cmake_minimum_required(VERSION 3.0)\n" - "project(HunterDownload LANGUAGES NONE)\n" - "include(ExternalProject)\n" - "ExternalProject_Add(\n" - " Hunter\n" - " URL\n" - " \"${HUNTER_GATE_URL}\"\n" - " URL_HASH\n" - " SHA1=${HUNTER_GATE_SHA1}\n" - " DOWNLOAD_DIR\n" - " \"${dir}\"\n" - " TLS_VERIFY\n" - " ON\n" - " SOURCE_DIR\n" - " \"${dir}/Unpacked\"\n" - " CONFIGURE_COMMAND\n" - " \"\"\n" - " BUILD_COMMAND\n" - " \"\"\n" - " INSTALL_COMMAND\n" - " \"\"\n" - ")\n" - ) - - if(HUNTER_STATUS_DEBUG) - set(logging_params "") - else() - set(logging_params OUTPUT_QUIET) - endif() - - hunter_gate_status_debug("Run generate") - - # Need to add toolchain file too. - # Otherwise on Visual Studio + MDD this will fail with error: - # "Could not find an appropriate version of the Windows 10 SDK installed on this machine" - if(EXISTS "${CMAKE_TOOLCHAIN_FILE}") - get_filename_component(absolute_CMAKE_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}" ABSOLUTE) - set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=${absolute_CMAKE_TOOLCHAIN_FILE}") - else() - # 'toolchain_arg' can't be empty - set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=") - endif() - - string(COMPARE EQUAL "${CMAKE_MAKE_PROGRAM}" "" no_make) - if(no_make) - set(make_arg "") - else() - # Test case: remove Ninja from PATH but set it via CMAKE_MAKE_PROGRAM - set(make_arg "-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}") - endif() - - execute_process( - COMMAND - "${CMAKE_COMMAND}" - "-H${dir}" - "-B${build_dir}" - "-G${CMAKE_GENERATOR}" - "${toolchain_arg}" - ${make_arg} - WORKING_DIRECTORY "${dir}" - RESULT_VARIABLE download_result - ${logging_params} - ) - - if(NOT download_result EQUAL 0) - hunter_gate_internal_error("Configure project failed") - endif() - - hunter_gate_status_print( - "Initializing Hunter workspace (${HUNTER_GATE_SHA1})" - " ${HUNTER_GATE_URL}" - " -> ${dir}" - ) - execute_process( - COMMAND "${CMAKE_COMMAND}" --build "${build_dir}" - WORKING_DIRECTORY "${dir}" - RESULT_VARIABLE download_result - ${logging_params} - ) - - if(NOT download_result EQUAL 0) - hunter_gate_internal_error("Build project failed") - endif() - - file(REMOVE_RECURSE "${build_dir}") - file(REMOVE_RECURSE "${cmakelists}") - - file(WRITE "${sha1_location}" "${HUNTER_GATE_SHA1}") - file(WRITE "${done_location}" "DONE") - - hunter_gate_status_debug("Finished") -endfunction() - -# Must be a macro so master file 'cmake/Hunter' can -# apply all variables easily just by 'include' command -# (otherwise PARENT_SCOPE magic needed) -macro(HunterGate) - if(HUNTER_GATE_DONE) - # variable HUNTER_GATE_DONE set explicitly for external project - # (see `hunter_download`) - set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES) - endif() - - # First HunterGate command will init Hunter, others will be ignored - get_property(_hunter_gate_done GLOBAL PROPERTY HUNTER_GATE_DONE SET) - - if(NOT HUNTER_ENABLED) - # Empty function to avoid error "unknown function" - function(hunter_add_package) - endfunction() - - set( - _hunter_gate_disabled_mode_dir - "${CMAKE_CURRENT_LIST_DIR}/cmake/Hunter/disabled-mode" - ) - if(EXISTS "${_hunter_gate_disabled_mode_dir}") - hunter_gate_status_debug( - "Adding \"disabled-mode\" modules: ${_hunter_gate_disabled_mode_dir}" - ) - list(APPEND CMAKE_PREFIX_PATH "${_hunter_gate_disabled_mode_dir}") - endif() - elseif(_hunter_gate_done) - hunter_gate_status_debug("Secondary HunterGate (use old settings)") - hunter_gate_self( - "${HUNTER_CACHED_ROOT}" - "${HUNTER_VERSION}" - "${HUNTER_SHA1}" - _hunter_self - ) - include("${_hunter_self}/cmake/Hunter") - else() - set(HUNTER_GATE_LOCATION "${CMAKE_CURRENT_LIST_DIR}") - - string(COMPARE NOTEQUAL "${PROJECT_NAME}" "" _have_project_name) - if(_have_project_name) - hunter_gate_fatal_error( - "Please set HunterGate *before* 'project' command. " - "Detected project: ${PROJECT_NAME}" - WIKI "error.huntergate.before.project" - ) - endif() - - cmake_parse_arguments( - HUNTER_GATE "LOCAL" "URL;SHA1;GLOBAL;FILEPATH" "" ${ARGV} - ) - - string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" _empty_sha1) - string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" _empty_url) - string( - COMPARE - NOTEQUAL - "${HUNTER_GATE_UNPARSED_ARGUMENTS}" - "" - _have_unparsed - ) - string(COMPARE NOTEQUAL "${HUNTER_GATE_GLOBAL}" "" _have_global) - string(COMPARE NOTEQUAL "${HUNTER_GATE_FILEPATH}" "" _have_filepath) - - if(_have_unparsed) - hunter_gate_user_error( - "HunterGate unparsed arguments: ${HUNTER_GATE_UNPARSED_ARGUMENTS}" - ) - endif() - if(_empty_sha1) - hunter_gate_user_error("SHA1 suboption of HunterGate is mandatory") - endif() - if(_empty_url) - hunter_gate_user_error("URL suboption of HunterGate is mandatory") - endif() - if(_have_global) - if(HUNTER_GATE_LOCAL) - hunter_gate_user_error("Unexpected LOCAL (already has GLOBAL)") - endif() - if(_have_filepath) - hunter_gate_user_error("Unexpected FILEPATH (already has GLOBAL)") - endif() - endif() - if(HUNTER_GATE_LOCAL) - if(_have_global) - hunter_gate_user_error("Unexpected GLOBAL (already has LOCAL)") - endif() - if(_have_filepath) - hunter_gate_user_error("Unexpected FILEPATH (already has LOCAL)") - endif() - endif() - if(_have_filepath) - if(_have_global) - hunter_gate_user_error("Unexpected GLOBAL (already has FILEPATH)") - endif() - if(HUNTER_GATE_LOCAL) - hunter_gate_user_error("Unexpected LOCAL (already has FILEPATH)") - endif() - endif() - - hunter_gate_detect_root() # set HUNTER_GATE_ROOT - - # Beautify path, fix probable problems with windows path slashes - get_filename_component( - HUNTER_GATE_ROOT "${HUNTER_GATE_ROOT}" ABSOLUTE - ) - hunter_gate_status_debug("HUNTER_ROOT: ${HUNTER_GATE_ROOT}") - if(NOT HUNTER_ALLOW_SPACES_IN_PATH) - string(FIND "${HUNTER_GATE_ROOT}" " " _contain_spaces) - if(NOT _contain_spaces EQUAL -1) - hunter_gate_fatal_error( - "HUNTER_ROOT (${HUNTER_GATE_ROOT}) contains spaces." - "Set HUNTER_ALLOW_SPACES_IN_PATH=ON to skip this error" - "(Use at your own risk!)" - WIKI "error.spaces.in.hunter.root" - ) - endif() - endif() - - string( - REGEX - MATCH - "[0-9]+\\.[0-9]+\\.[0-9]+[-_a-z0-9]*" - HUNTER_GATE_VERSION - "${HUNTER_GATE_URL}" - ) - string(COMPARE EQUAL "${HUNTER_GATE_VERSION}" "" _is_empty) - if(_is_empty) - set(HUNTER_GATE_VERSION "unknown") - endif() - - hunter_gate_self( - "${HUNTER_GATE_ROOT}" - "${HUNTER_GATE_VERSION}" - "${HUNTER_GATE_SHA1}" - _hunter_self - ) - - set(_master_location "${_hunter_self}/cmake/Hunter") - if(EXISTS "${HUNTER_GATE_ROOT}/cmake/Hunter") - # Hunter downloaded manually (e.g. by 'git clone') - set(_unused "xxxxxxxxxx") - set(HUNTER_GATE_SHA1 "${_unused}") - set(HUNTER_GATE_VERSION "${_unused}") - else() - get_filename_component(_archive_id_location "${_hunter_self}/.." ABSOLUTE) - set(_done_location "${_archive_id_location}/DONE") - set(_sha1_location "${_archive_id_location}/SHA1") - - # Check Hunter already downloaded by HunterGate - if(NOT EXISTS "${_done_location}") - hunter_gate_download("${_archive_id_location}") - endif() - - if(NOT EXISTS "${_done_location}") - hunter_gate_internal_error("hunter_gate_download failed") - endif() - - if(NOT EXISTS "${_sha1_location}") - hunter_gate_internal_error("${_sha1_location} not found") - endif() - file(READ "${_sha1_location}" _sha1_value) - string(COMPARE EQUAL "${_sha1_value}" "${HUNTER_GATE_SHA1}" _is_equal) - if(NOT _is_equal) - hunter_gate_internal_error( - "Short SHA1 collision:" - " ${_sha1_value} (from ${_sha1_location})" - " ${HUNTER_GATE_SHA1} (HunterGate)" - ) - endif() - if(NOT EXISTS "${_master_location}") - hunter_gate_user_error( - "Master file not found:" - " ${_master_location}" - "try to update Hunter/HunterGate" - ) - endif() - endif() - include("${_master_location}") - set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES) - endif() -endmacro() diff --git a/common/sqlite_modern_cpp/cmake/ParseAndAddCatchTests.cmake b/common/sqlite_modern_cpp/cmake/ParseAndAddCatchTests.cmake deleted file mode 100644 index cb2846d0..00000000 --- a/common/sqlite_modern_cpp/cmake/ParseAndAddCatchTests.cmake +++ /dev/null @@ -1,185 +0,0 @@ -#==================================================================================================# -# supported macros # -# - TEST_CASE, # -# - SCENARIO, # -# - TEST_CASE_METHOD, # -# - CATCH_TEST_CASE, # -# - CATCH_SCENARIO, # -# - CATCH_TEST_CASE_METHOD. # -# # -# Usage # -# 1. make sure this module is in the path or add this otherwise: # -# set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake.modules/") # -# 2. make sure that you've enabled testing option for the project by the call: # -# enable_testing() # -# 3. add the lines to the script for testing target (sample CMakeLists.txt): # -# project(testing_target) # -# set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake.modules/") # -# enable_testing() # -# # -# find_path(CATCH_INCLUDE_DIR "catch.hpp") # -# include_directories(${INCLUDE_DIRECTORIES} ${CATCH_INCLUDE_DIR}) # -# # -# file(GLOB SOURCE_FILES "*.cpp") # -# add_executable(${PROJECT_NAME} ${SOURCE_FILES}) # -# # -# include(ParseAndAddCatchTests) # -# ParseAndAddCatchTests(${PROJECT_NAME}) # -# # -# The following variables affect the behavior of the script: # -# # -# PARSE_CATCH_TESTS_VERBOSE (Default OFF) # -# -- enables debug messages # -# PARSE_CATCH_TESTS_NO_HIDDEN_TESTS (Default OFF) # -# -- excludes tests marked with [!hide], [.] or [.foo] tags # -# PARSE_CATCH_TESTS_ADD_FIXTURE_IN_TEST_NAME (Default ON) # -# -- adds fixture class name to the test name # -# PARSE_CATCH_TESTS_ADD_TARGET_IN_TEST_NAME (Default ON) # -# -- adds cmake target name to the test name # -# PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS (Default OFF) # -# -- causes CMake to rerun when file with tests changes so that new tests will be discovered # -# # -#==================================================================================================# - -cmake_minimum_required(VERSION 2.8.8) - -option(PARSE_CATCH_TESTS_VERBOSE "Print Catch to CTest parser debug messages" OFF) -option(PARSE_CATCH_TESTS_NO_HIDDEN_TESTS "Exclude tests with [!hide], [.] or [.foo] tags" OFF) -option(PARSE_CATCH_TESTS_ADD_FIXTURE_IN_TEST_NAME "Add fixture class name to the test name" ON) -option(PARSE_CATCH_TESTS_ADD_TARGET_IN_TEST_NAME "Add target name to the test name" ON) -option(PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS "Add test file to CMAKE_CONFIGURE_DEPENDS property" OFF) - -function(PrintDebugMessage) - if(PARSE_CATCH_TESTS_VERBOSE) - message(STATUS "ParseAndAddCatchTests: ${ARGV}") - endif() -endfunction() - -# This removes the contents between -# - block comments (i.e. /* ... */) -# - full line comments (i.e. // ... ) -# contents have been read into '${CppCode}'. -# !keep partial line comments -function(RemoveComments CppCode) - string(ASCII 2 CMakeBeginBlockComment) - string(ASCII 3 CMakeEndBlockComment) - string(REGEX REPLACE "/\\*" "${CMakeBeginBlockComment}" ${CppCode} "${${CppCode}}") - string(REGEX REPLACE "\\*/" "${CMakeEndBlockComment}" ${CppCode} "${${CppCode}}") - string(REGEX REPLACE "${CMakeBeginBlockComment}[^${CMakeEndBlockComment}]*${CMakeEndBlockComment}" "" ${CppCode} "${${CppCode}}") - string(REGEX REPLACE "\n[ \t]*//+[^\n]+" "\n" ${CppCode} "${${CppCode}}") - - set(${CppCode} "${${CppCode}}" PARENT_SCOPE) -endfunction() - -# Worker function -function(ParseFile SourceFile TestTarget) - # According to CMake docs EXISTS behavior is well-defined only for full paths. - get_filename_component(SourceFile ${SourceFile} ABSOLUTE) - if(NOT EXISTS ${SourceFile}) - message(WARNING "Cannot find source file: ${SourceFile}") - return() - endif() - PrintDebugMessage("parsing ${SourceFile}") - file(STRINGS ${SourceFile} Contents NEWLINE_CONSUME) - - # Remove block and fullline comments - RemoveComments(Contents) - - # Find definition of test names - string(REGEX MATCHALL "[ \t]*(CATCH_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)[ \t]*\\([^\)]+\\)+[ \t\n]*{+[ \t]*(//[^\n]*[Tt][Ii][Mm][Ee][Oo][Uu][Tt][ \t]*[0-9]+)*" Tests "${Contents}") - - if(PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS AND Tests) - PrintDebugMessage("Adding ${SourceFile} to CMAKE_CONFIGURE_DEPENDS property") - set_property( - DIRECTORY - APPEND - PROPERTY CMAKE_CONFIGURE_DEPENDS ${SourceFile} - ) - endif() - - foreach(TestName ${Tests}) - # Strip newlines - string(REGEX REPLACE "\\\\\n|\n" "" TestName "${TestName}") - - # Get test type and fixture if applicable - string(REGEX MATCH "(CATCH_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)[ \t]*\\([^,^\"]*" TestTypeAndFixture "${TestName}") - string(REGEX MATCH "(CATCH_)?(TEST_CASE_METHOD|SCENARIO|TEST_CASE)" TestType "${TestTypeAndFixture}") - string(REPLACE "${TestType}(" "" TestFixture "${TestTypeAndFixture}") - - # Get string parts of test definition - string(REGEX MATCHALL "\"+([^\\^\"]|\\\\\")+\"+" TestStrings "${TestName}") - - # Strip wrapping quotation marks - string(REGEX REPLACE "^\"(.*)\"$" "\\1" TestStrings "${TestStrings}") - string(REPLACE "\";\"" ";" TestStrings "${TestStrings}") - - # Validate that a test name and tags have been provided - list(LENGTH TestStrings TestStringsLength) - if(TestStringsLength GREATER 2 OR TestStringsLength LESS 1) - message(FATAL_ERROR "You must provide a valid test name and tags for all tests in ${SourceFile}") - endif() - - # Assign name and tags - list(GET TestStrings 0 Name) - if("${TestType}" STREQUAL "SCENARIO") - set(Name "Scenario: ${Name}") - endif() - if(PARSE_CATCH_TESTS_ADD_FIXTURE_IN_TEST_NAME AND TestFixture) - set(CTestName "${TestFixture}:${Name}") - else() - set(CTestName "${Name}") - endif() - if(PARSE_CATCH_TESTS_ADD_TARGET_IN_TEST_NAME) - set(CTestName "${TestTarget}:${CTestName}") - endif() - # add target to labels to enable running all tests added from this target - set(Labels ${TestTarget}) - if(TestStringsLength EQUAL 2) - list(GET TestStrings 1 Tags) - string(TOLOWER "${Tags}" Tags) - # remove target from labels if the test is hidden - if("${Tags}" MATCHES ".*\\[!?(hide|\\.)\\].*") - list(REMOVE_ITEM Labels ${TestTarget}) - endif() - string(REPLACE "]" ";" Tags "${Tags}") - string(REPLACE "[" "" Tags "${Tags}") - endif() - - list(APPEND Labels ${Tags}) - - list(FIND Labels "!hide" IndexOfHideLabel) - set(HiddenTagFound OFF) - foreach(label ${Labels}) - string(REGEX MATCH "^!hide|^\\." result ${label}) - if(result) - set(HiddenTagFound ON) - break() - endif(result) - endforeach(label) - if(PARSE_CATCH_TESTS_NO_HIDDEN_TESTS AND ${HiddenTagFound}) - PrintDebugMessage("Skipping test \"${CTestName}\" as it has [!hide], [.] or [.foo] label") - else() - PrintDebugMessage("Adding test \"${CTestName}\"") - if(Labels) - PrintDebugMessage("Setting labels to ${Labels}") - endif() - - # Add the test and set its properties - add_test(NAME "\"${CTestName}\"" COMMAND ${TestTarget} ${Name} ${AdditionalCatchParameters}) - set_tests_properties("\"${CTestName}\"" PROPERTIES FAIL_REGULAR_EXPRESSION "No tests ran" - LABELS "${Labels}") - endif() - - endforeach() -endfunction() - -# entry point -function(ParseAndAddCatchTests TestTarget) - PrintDebugMessage("Started parsing ${TestTarget}") - get_target_property(SourceFiles ${TestTarget} SOURCES) - PrintDebugMessage("Found the following sources: ${SourceFiles}") - foreach(SourceFile ${SourceFiles}) - ParseFile(${SourceFile} ${TestTarget}) - endforeach() - PrintDebugMessage("Finished parsing ${TestTarget}") -endfunction() diff --git a/common/sqlite_modern_cpp/tests/blob_example.cc b/common/sqlite_modern_cpp/tests/blob_example.cc deleted file mode 100644 index f019eb55..00000000 --- a/common/sqlite_modern_cpp/tests/blob_example.cc +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include -#include -#include -#include -#include -using namespace sqlite; -using namespace std; - -TEST_CASE("Blob does work", "[blob]") { - database db(":memory:"); - - db << "CREATE TABLE person (name TEXT, numbers BLOB);"; - db << "INSERT INTO person VALUES (?, ?)" << "bob" << vector { 1, 2, 3, 4}; - db << "INSERT INTO person VALUES (?, ?)" << "jack" << vector { '1', '2', '3', '4'}; - db << "INSERT INTO person VALUES (?, ?)" << "sara" << vector { 1.0, 2.0, 3.0, 4.0}; - - vector numbers_bob; - db << "SELECT numbers from person where name = ?;" << "bob" >> numbers_bob; - - REQUIRE(numbers_bob.size() == 4); - REQUIRE((numbers_bob[0] == 1 && numbers_bob[1] == 2 && numbers_bob[2] == 3 && numbers_bob[3] == 4)); - - vector numbers_jack; - db << "SELECT numbers from person where name = ?;" << "jack" >> numbers_jack; - - REQUIRE(numbers_jack.size() == 4); - REQUIRE((numbers_jack[0] == '1' && numbers_jack[1] == '2' && numbers_jack[2] == '3' && numbers_jack[3] == '4')); - - - vector numbers_sara; - db << "SELECT numbers from person where name = ?;" << "sara" >> numbers_sara; - - REQUIRE(numbers_sara.size() == 4); - REQUIRE((numbers_sara[0] == 1.0 && numbers_sara[1] == 2.0 && numbers_sara[2] == 3.0 && numbers_sara[3] == 4.0)); -} diff --git a/common/sqlite_modern_cpp/tests/error_log.cc b/common/sqlite_modern_cpp/tests/error_log.cc deleted file mode 100644 index 3c5606bd..00000000 --- a/common/sqlite_modern_cpp/tests/error_log.cc +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -using namespace sqlite; -using namespace std; - -struct TrackErrors { - TrackErrors() - : constraint_called{false}, primarykey_called{false} - { - error_log( - [this](errors::constraint) { - constraint_called = true; - }, - [this](errors::constraint_primarykey e) { - primarykey_called = true; - } - // We are not registering the unique key constraint: - // For a unique key error the first handler (errors::constraint) will be called instead. - ); - } - - bool constraint_called; - bool primarykey_called; - /* bool unique_called; */ -}; - -// Run before main, before any other sqlite function. -static TrackErrors track; - - -TEST_CASE("error_log works", "[log]") { - database db(":memory:"); - db << "CREATE TABLE person (id integer primary key not null, name TEXT unique);"; - - SECTION("An extended error code gets called when registered") { - try { - db << "INSERT INTO person (id,name) VALUES (?,?)" << 1 << "jack"; - // triger primarykey constraint of 'id' - db << "INSERT INTO person (id,name) VALUES (?,?)" << 1 << "bob"; - } catch (const errors::constraint& e) { } - REQUIRE(track.primarykey_called == true); - REQUIRE(track.constraint_called == false); - track.primarykey_called = false; - } - - SECTION("Parent gets called when the exact error code is not registered") { - try { - db << "INSERT INTO person (id,name) VALUES (?,?)" << 1 << "jack"; - // trigger unique constraint of 'name' - db << "INSERT INTO person (id,name) VALUES (?,?)" << 2 << "jack"; - } catch (const errors::constraint& e) { } - - REQUIRE(track.primarykey_called == false); - REQUIRE(track.constraint_called == true); - track.constraint_called = false; - } -} diff --git a/common/sqlite_modern_cpp/tests/exception_dont_execute.cc b/common/sqlite_modern_cpp/tests/exception_dont_execute.cc deleted file mode 100644 index 156ac315..00000000 --- a/common/sqlite_modern_cpp/tests/exception_dont_execute.cc +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include -#include -#include -#include -#include -using namespace sqlite; -using namespace std; - - -TEST_CASE("Prepared statement will not execute on exceptions", "[prepared_statements]") { - database db(":memory:"); - db << "CREATE TABLE person (id integer primary key not null, name TEXT not null);"; - - try { - auto stmt = db << "INSERT INTO person (id,name) VALUES (?,?)"; - throw 1; - } catch (int) { } - - int count; - db << "select count(*) from person" >> count; - REQUIRE(count == 0); -} diff --git a/common/sqlite_modern_cpp/tests/exception_dont_execute_nested.cc b/common/sqlite_modern_cpp/tests/exception_dont_execute_nested.cc deleted file mode 100644 index a416829d..00000000 --- a/common/sqlite_modern_cpp/tests/exception_dont_execute_nested.cc +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include -#include -#include -#include -#include -using namespace sqlite; -using namespace std; - -struct A { - ~A() { - database db(":memory:"); - db << "CREATE TABLE person (id integer primary key not null, name TEXT not null);"; - - try { - auto stmt = db << "INSERT INTO person (id,name) VALUES (?,?)"; - throw 1; - } catch (int) { - } - } -}; - -TEST_CASE("Nested prepered statements wont execute", "[nested_prepared_statements]") { -#ifdef MODERN_SQLITE_UNCAUGHT_EXCEPTIONS_SUPPORT - try { - A a; - throw 1; - } catch(int) { } -#else -#endif -} diff --git a/common/sqlite_modern_cpp/tests/exceptions.cc b/common/sqlite_modern_cpp/tests/exceptions.cc deleted file mode 100644 index 5905e047..00000000 --- a/common/sqlite_modern_cpp/tests/exceptions.cc +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -using namespace sqlite; -using namespace std; - - -TEST_CASE("exceptions are thrown", "[exceptions]") { - database db(":memory:"); - db << "CREATE TABLE person (id integer primary key not null, name TEXT);"; - bool expception_thrown = false; - std::string get_sql_result; - -#if SQLITE_VERSION_NUMBER >= 3014000 - std::string expedted_sql = "INSERT INTO person (id,name) VALUES (1,'jack')"; -#else - std::string expedted_sql = "INSERT INTO person (id,name) VALUES (?,?)"; -#endif - - SECTION("Parent exception works") { - try { - db << "INSERT INTO person (id,name) VALUES (?,?)" << 1 << "jack"; - // inserting again to produce error - db << "INSERT INTO person (id,name) VALUES (?,?)" << 1 << "jack"; - } catch (errors::constraint& e) { - expception_thrown = true; - get_sql_result = e.get_sql(); - } - - REQUIRE(expception_thrown == true); - REQUIRE(get_sql_result == expedted_sql); - } - - SECTION("Extended exception works") { - try { - db << "INSERT INTO person (id,name) VALUES (?,?)" << 1 << "jack"; - // inserting again to produce error - db << "INSERT INTO person (id,name) VALUES (?,?)" << 1 << "jack"; - } catch (errors::constraint_primarykey& e) { - expception_thrown = true; - get_sql_result = e.get_sql(); - } - - REQUIRE(expception_thrown == true); - REQUIRE(get_sql_result == expedted_sql); - } -} diff --git a/common/sqlite_modern_cpp/tests/flags.cc b/common/sqlite_modern_cpp/tests/flags.cc deleted file mode 100644 index e1af2b70..00000000 --- a/common/sqlite_modern_cpp/tests/flags.cc +++ /dev/null @@ -1,80 +0,0 @@ -#include -#include -#include -#include -#include -#include -using namespace sqlite; -using namespace std; - -struct TmpFile { - string fname; - - TmpFile(): fname("./flags.db") { } - ~TmpFile() { remove(fname.c_str()); } -}; -#ifdef _WIN32 -#define OUR_UTF16 "UTF-16le" -#elif BYTE_ORDER == BIG_ENDIAN -#define OUR_UTF16 "UTF-16be" -#else -#define OUR_UTF16 "UTF-16le" -#endif - -TEST_CASE("flags work", "[flags]") { - TmpFile file; - sqlite::sqlite_config cfg; - std::string enc; - SECTION("PRAGMA endcoding is UTF-8 for string literals") { - database db(":memory:", cfg); - db << "PRAGMA encoding;" >> enc; - REQUIRE(enc == "UTF-8"); - } - SECTION("encoding is UTF-16 for u"" prefixed string literals") { - database db(u":memory:", cfg); - db << "PRAGMA encoding;" >> enc; - REQUIRE(enc == OUR_UTF16); - } - SECTION("we can set encoding to UTF-8 with flags") { - cfg.encoding = Encoding::UTF8; - database db(u":memory:", cfg); - db << "PRAGMA encoding;" >> enc; - REQUIRE(enc == "UTF-8"); - } - SECTION("we can set encoding to UTF-16 with flags") { - cfg.encoding = Encoding::UTF16; - database db(u":memory:", cfg); - db << "PRAGMA encoding;" >> enc; - REQUIRE(enc == OUR_UTF16); - } - SECTION("we can set encoding to UTF-16 with flags for on disk databases") { - cfg.encoding = Encoding::UTF16; - database db(file.fname, cfg); - db << "PRAGMA encoding;" >> enc; - REQUIRE(enc == OUR_UTF16); - - } - SECTION("READONLY flag works") { - { - database db(file.fname, cfg); - db << "CREATE TABLE foo (a string);"; - db << "INSERT INTO foo VALUES (?)" << "hello"; - } - - cfg.flags = sqlite::OpenFlags::READONLY; - database db(file.fname, cfg); - - string str; - db << "SELECT a FROM foo;" >> str; - - REQUIRE(str == "hello"); - - bool failed = false; - try { - db << "INSERT INTO foo VALUES (?)" << "invalid"; - } catch(errors::readonly&) { - failed = true; - } - REQUIRE(failed == true); - } -} diff --git a/common/sqlite_modern_cpp/tests/functions.cc b/common/sqlite_modern_cpp/tests/functions.cc deleted file mode 100644 index b7a7badb..00000000 --- a/common/sqlite_modern_cpp/tests/functions.cc +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include -#include -using namespace sqlite; -using namespace std; - -int add_integers(int i, int j) { - return i+j; -} -TEST_CASE("sql functions work", "[functions]") { - database db(":memory:"); - - db.define("my_new_concat", [](std::string i, std::string j) {return i+j;}); - db.define("my_new_concat", [](std::string i, std::string j, std::string k) {return i+j+k;}); - db.define("add_integers", &add_integers); - - std::string test1, test3; - int test2 = 0; - db << "select my_new_concat('Hello ','world!')" >> test1; - db << "select add_integers(1,1)" >> test2; - db << "select my_new_concat('a','b','c')" >> test3; - - REQUIRE(test1 == "Hello world!"); - REQUIRE(test2 == 2); - REQUIRE(test3 == "abc"); - - db.define("my_count", [](int &i, int) {++i;}, [](int &i) {return i;}); - db.define("my_concat_aggregate", [](std::string &stored, std::string current) {stored += current;}, [](std::string &stored) {return stored;}); - - db << "create table countable(i, s)"; - db << "insert into countable values(1, 'a')"; - db << "insert into countable values(2, 'b')"; - db << "insert into countable values(3, 'c')"; - db << "select my_count(i) from countable" >> test2; - db << "select my_concat_aggregate(s) from countable order by i" >> test3; - - REQUIRE(test2 == 3); - REQUIRE(test3 == "abc"); - - db.define("tgamma", [](double i) {return std::tgamma(i);}); - db << "CREATE TABLE numbers (number INTEGER);"; - - for(auto i=0; i!=10; ++i) - db << "INSERT INTO numbers VALUES (?);" << i; - - db << "SELECT number, tgamma(number+1) FROM numbers;" >> [](double number, double factorial) { - /* cout << number << "! = " << factorial << '\n'; */ - }; -} diff --git a/common/sqlite_modern_cpp/tests/functors.cc b/common/sqlite_modern_cpp/tests/functors.cc deleted file mode 100644 index 3c8b5024..00000000 --- a/common/sqlite_modern_cpp/tests/functors.cc +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include -#include -#include -#include -#include - -using namespace sqlite; -using namespace std; - -struct tbl_functor { - explicit tbl_functor(vector > &vec_) : vec(vec_) { } - - void operator() ( int id, string name) { - vec.push_back(make_pair(id, move(name))); - } - vector > &vec; -}; - -TEST_CASE("functors work", "[functors]") { - database db(":memory:"); - db << "CREATE TABLE tbl (id integer, name string);"; - db << "INSERT INTO tbl VALUES (?, ?);" << 1 << "hello"; - db << "INSERT INTO tbl VALUES (?, ?);" << 2 << "world"; - - vector > vec; - db << "select id,name from tbl;" >> tbl_functor(vec); - - REQUIRE(vec.size() == 2); - - vec.clear(); - - tbl_functor functor(vec); - db << "select id,name from tbl;" >> functor; - - REQUIRE(vec.size() == 2); - REQUIRE(vec[0].first == 1); - REQUIRE(vec[0].second == "hello"); -} diff --git a/common/sqlite_modern_cpp/tests/lvalue_functor.cc b/common/sqlite_modern_cpp/tests/lvalue_functor.cc deleted file mode 100644 index ba48995d..00000000 --- a/common/sqlite_modern_cpp/tests/lvalue_functor.cc +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include -#include -#include -#include -using namespace sqlite; -using namespace std; - -template -struct builder { - vector results; - - void operator()(AttrTypes... args) { - results.emplace_back(std::forward(args)...); - }; -}; - - -struct user { - int age; - string name; - double weight; - - user(int age, string name, double weight) : age(age), name(name), weight(weight) { } - - static std::vector all(sqlite::database& db) { - builder person_builder; - db << "SELECT * FROM user;" - >> person_builder; - return std::move(person_builder.results); // move to avoid copying data ;-) - }; -}; - -TEST_CASE("lvalue functors work", "[lvalue_functor]") { - - database db(":memory:"); - - db << - "create table if not exists user (" - " age int," - " name text," - " weight real" - ");"; - - db << "insert into user (age,name,weight) values (?,?,?);" << 20 << u"chandler" << 83.25; - db << "insert into user (age,name,weight) values (?,?,?);" << 21 << u"monika" << 86.25; - db << "insert into user (age,name,weight) values (?,?,?);" << 22 << u"ross" << 88.25; - - auto users = user::all(db); - - REQUIRE(users.size() == 3); -} diff --git a/common/sqlite_modern_cpp/tests/mov_ctor.cc b/common/sqlite_modern_cpp/tests/mov_ctor.cc deleted file mode 100644 index 95389b20..00000000 --- a/common/sqlite_modern_cpp/tests/mov_ctor.cc +++ /dev/null @@ -1,31 +0,0 @@ -// Fixing https://github.com/SqliteModernCpp/sqlite_modern_cpp/issues/63 -#include -#include -#include -#include -#include -using namespace sqlite; -using namespace std; - -struct dbFront { - std::unique_ptr storedProcedure; - database db; - dbFront(): db(":memory:") { - db << "CREATE TABLE tbl (id integer, name string);"; - // the temporary moved object should not run _execute() function on destruction. - storedProcedure = std::make_unique( - db << "INSERT INTO tbl VALUES (?, ?);" - ); - } -}; - - -TEST_CASE("database lifecycle", "move_ctor") { - - bool failed = false; - try { dbFront dbf; } - catch(const sqlite_exception& e) { failed = true; } - catch(...) { failed = true; } - - REQUIRE(failed == false); -} diff --git a/common/sqlite_modern_cpp/tests/named.cc b/common/sqlite_modern_cpp/tests/named.cc deleted file mode 100644 index 2b255c4d..00000000 --- a/common/sqlite_modern_cpp/tests/named.cc +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include -#include -#include -using namespace sqlite; -using namespace std; - - -TEST_CASE("binding named parameters works", "[named]") { - database db(":memory:"); - - db << "CREATE TABLE foo (a,b);"; - - int a = 1; - db << "INSERT INTO foo VALUES (:first,:second)" << named_parameter(":second", 2) << named_parameter(":first", a); - - db << "SELECT b FROM foo WHERE a=?;" << 1 >> a; - - REQUIRE(a == 2); -} \ No newline at end of file diff --git a/common/sqlite_modern_cpp/tests/nullptr_uniqueptr.cc b/common/sqlite_modern_cpp/tests/nullptr_uniqueptr.cc deleted file mode 100644 index f4851920..00000000 --- a/common/sqlite_modern_cpp/tests/nullptr_uniqueptr.cc +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include -#include -using namespace std; -using namespace sqlite; - -TEST_CASE("nullptr & unique_ptr", "[null_ptr_unique_ptr]") { - database db(":memory:"); - db << "CREATE TABLE tbl (id integer,age integer, name string, img blob);"; - db << "INSERT INTO tbl VALUES (?, ?, ?, ?);" << 1 << 24 << "bob" << vector { 1, 2 , 3}; - unique_ptr ptr_null; - db << "INSERT INTO tbl VALUES (?, ?, ?, ?);" << 2 << nullptr << ptr_null << nullptr; - - db << "select age,name,img from tbl where id = 1" >> [](unique_ptr age_p, unique_ptr name_p, unique_ptr> img_p) { - REQUIRE(age_p != nullptr); - REQUIRE(name_p != nullptr); - REQUIRE(img_p != nullptr); - }; - - db << "select age,name,img from tbl where id = 2" >> [](unique_ptr age_p, unique_ptr name_p, unique_ptr> img_p) { - REQUIRE(age_p == nullptr); - REQUIRE(name_p == nullptr); - REQUIRE(img_p == nullptr); - }; -} diff --git a/common/sqlite_modern_cpp/tests/prepared_statment.cc b/common/sqlite_modern_cpp/tests/prepared_statment.cc deleted file mode 100644 index b5aa3028..00000000 --- a/common/sqlite_modern_cpp/tests/prepared_statment.cc +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include -#include -#include -using namespace sqlite; -using namespace std; - -TEST_CASE("prepared statements work", "[prepared_statement]") { - database db(":memory:"); - - auto pps = db << "select ?"; // get a prepared parsed and ready statment - - int test = 4; - pps << test; // set a bound var - - pps >> test; // execute statement - - REQUIRE(test == 4); - - pps << 4; // bind a rvalue - pps++; // and execute - - pps << 8 >> test; - - REQUIRE(test == 8); - - auto pps2 = db << "select 1,2"; // multiple extract test - - pps2 >> [](int a, int b) { - REQUIRE(a == 1); - REQUIRE(b == 2); - }; - - auto pps3 = db << "select ?,?,?"; - - test = 2; - pps3 << 1 << test << 3 >> [](int a, int b, int c) { - REQUIRE(a == 1); - REQUIRE(b == 2); - REQUIRE(c == 3); - }; - - test = 1; - db << "select ?,?" << test << 5 >> test; // and mow everything together - REQUIRE(test == 1); - - test = 2; - db << "select ?,?,?" << 1 << test << 3 >> [](int a, int b, int c) { - REQUIRE(a == 1); - REQUIRE(b == 2); - REQUIRE(c == 3); - }; - - db << "select ?" << test; // noVal - db << "select ?,?" << test << 1; - db << "select ?,?" << 1 << test; - db << "select ?,?" << 1 << 1; - db << "select ?,?" << test << test; - - db << "select ?" << test >> test; // lVal - db << "select ?,?" << test << 1 >> test; - db << "select ?,?" << 1 << test >> test; - db << "select ?,?" << 1 << 1 >> test; - db << "select ?,?" << test << test >> test; - - int q = 0; - test = 1; - db << "select ?" << test >> [&](int t) { q = t; }; // rVal - REQUIRE(q == 1); - - db << "select ?,?" << test << 1 >> [&](int t, int p) { q = t + p; }; - db << "select ?,?" << 1 << test >> [&](int t, int p) { q = t + p; }; - db << "select ?,?" << 1 << 1 >> [&](int t, int p) { q = t + p; }; - db << "select ?,?" << test << test >> [&](int t, int p) { q = t + p; }; - - db << "select ?,?,?" << test << 1 << test; // mix - db << "select ?,?,?" << 1 << test << 1; - db << "select ?,?,?" << 1 << 1 << test; - db << "select ?,?,?" << 1 << 1 << 1; - db << "select ?,?,?" << test << test << test; - - { - auto pps4 = db << "select ?,?,?"; // reuse - - (pps4 << test << 1 << test)++; - (pps4 << 1 << test << 1)++; - (pps4 << 1 << 1 << test)++; - (pps4 << 1 << 1 << 1)++; - (pps4 << test << test << test)++; - } - - { - auto prep = db << "select ?"; - - prep << 5; - prep.execute(); - prep << 6; - prep.execute(); - } - - -} diff --git a/common/sqlite_modern_cpp/tests/readme_example.cc b/common/sqlite_modern_cpp/tests/readme_example.cc deleted file mode 100644 index d5137fc8..00000000 --- a/common/sqlite_modern_cpp/tests/readme_example.cc +++ /dev/null @@ -1,64 +0,0 @@ -#define CATCH_CONFIG_MAIN -#include -#include -#include - -using namespace sqlite; -using namespace std; - -TEST_CASE("README Example Works", "[readme]") { - - database db(":memory:"); - - db << - "create table if not exists user (" - " _id integer primary key autoincrement not null," - " age int," - " name text," - " weight real" - ");"; - - db << "insert into user (age,name,weight) values (?,?,?);" - << 20 - << u"bob" - << 83.25; - - int age = 22; float weight = 68.5; string name = "jack"; - db << u"insert into user (age,name,weight) values (?,?,?);" // utf16 query string - << age - << name - << weight; - - REQUIRE(db.last_insert_rowid() != 0); - - db << "select age,name,weight from user where age > ? ;" - << 21 - >> [&](int _age, string _name, double _weight) { - REQUIRE((_age == age && _name == name)); - }; - - for(auto &&row : db << "select age,name,weight from user where age > ? ;" << 21) { - int _age; - string _name; - double _weight; - row >> _age >> _name >> _weight; - REQUIRE((_age == age && _name == name)); - } - - for(std::tuple row : db << "select age,name,weight from user where age > ? ;" << 21) { - REQUIRE((std::get(row) == age && std::get(row) == name)); - } - - // selects the count(*) from user table - // note that you can extract a single culumn single row result only to : int,long,long,float,double,string,u16string - int count = 0; - db << "select count(*) from user" >> count; - REQUIRE(count == 2); - - db << "select age, name from user where _id=1;" >> tie(age, name); - - // this also works and the returned value will be automatically converted to string - string str_count; - db << "select count(*) from user" >> str_count; - REQUIRE(str_count == string{"2"}); -} diff --git a/common/sqlite_modern_cpp/tests/shared_connection.cc b/common/sqlite_modern_cpp/tests/shared_connection.cc deleted file mode 100644 index 4f270933..00000000 --- a/common/sqlite_modern_cpp/tests/shared_connection.cc +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include -#include - -using namespace sqlite; -using namespace std; - -TEST_CASE("shared connections work fine", "[shared_connection]") { - database db(":memory:"); - - { - auto con = db.connection(); - - { - database db2(con); - int test = 0; - db2 << "select 1" >> test; - REQUIRE(test == 1); - } - - int test = 0; - db << "select 1" >> test; - REQUIRE(test == 1); - } -} diff --git a/common/sqlite_modern_cpp/tests/simple_examples.cc b/common/sqlite_modern_cpp/tests/simple_examples.cc deleted file mode 100644 index d8e684d3..00000000 --- a/common/sqlite_modern_cpp/tests/simple_examples.cc +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include -#include -#include -#include -using namespace sqlite; -using namespace std; - -TEST_CASE("simple examples", "[examples]") { - database db(":memory:"); - - db << "CREATE TABLE foo (a integer, b string);\n"; - db << "INSERT INTO foo VALUES (?, ?)" << 1 << "hello"; - db << "INSERT INTO foo VALUES (?, ?)" << 2 << "world"; - - string str; - db << "SELECT b from FOO where a=?;" << 2L >> str; - - REQUIRE(str == "world"); - - std::string sql("select 1+1"); - long test = 0; - db << sql >> test; - - REQUIRE(test == 2); - - db << "UPDATE foo SET b=? WHERE a=?;" << "hi" << 1L; - db << "SELECT b FROM foo WHERE a=?;" << 1L >> str; - - REQUIRE(str == "hi"); - REQUIRE(db.rows_modified() == 1); - - db << "UPDATE foo SET b=?;" << "hello world"; - - REQUIRE(db.rows_modified() == 2); -} diff --git a/common/sqlite_modern_cpp/tests/sqlcipher.cc b/common/sqlite_modern_cpp/tests/sqlcipher.cc deleted file mode 100644 index 2fc2f10c..00000000 --- a/common/sqlite_modern_cpp/tests/sqlcipher.cc +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include -#include -#include - -#include -using namespace sqlite; -using namespace std; - -struct TmpFile -{ - string fname; - - TmpFile(): fname("./sqlcipher.db") { } - ~TmpFile() { remove(fname.c_str()); } -}; - -TEST_CASE("sqlcipher works", "[sqlcipher]") { - TmpFile file; - sqlcipher_config config; - { - config.key = "DebugKey"; - sqlcipher_database db(file.fname, config); - - db << "CREATE TABLE foo (a integer, b string);"; - db << "INSERT INTO foo VALUES (?, ?)" << 1 << "hello"; - db << "INSERT INTO foo VALUES (?, ?)" << 2 << "world"; - - string str; - db << "SELECT b from FOO where a=?;" << 2 >> str; - - REQUIRE(str == "world"); - } - - bool failed = false; - try { - config.key = "DebugKey2"; - sqlcipher_database db(file.fname, config); - db << "INSERT INTO foo VALUES (?, ?)" << 3 << "fail"; - } catch(const errors::notadb&) { - failed = true; - // Expected, wrong key - } - REQUIRE(failed == true); - - { - config.key = "DebugKey"; - sqlcipher_database db(file.fname, config); - db.rekey("DebugKey2"); - } - { - config.key = "DebugKey2"; - sqlcipher_database db(file.fname, config); - db << "INSERT INTO foo VALUES (?, ?)" << 3 << "fail"; - } -} diff --git a/common/sqlite_modern_cpp/tests/std_optional.cc b/common/sqlite_modern_cpp/tests/std_optional.cc deleted file mode 100644 index c4e6c552..00000000 --- a/common/sqlite_modern_cpp/tests/std_optional.cc +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include -#include - -using namespace sqlite; -using namespace std; - -#ifdef MODERN_SQLITE_STD_OPTIONAL_SUPPORT -TEST_CASE("std::optional works", "[optional]") { - database db(":memory:"); - - db << "drop table if exists test"; - db << - "create table if not exists test (" - " id integer primary key," - " val int" - ");"; - - db << "insert into test(id,val) values(?,?)" << 1 << 5; - db << "select id,val from test" >> [&](long long, sqlite::optional val) { - REQUIRE(val); - }; - - db << "delete from test where id = 1"; - db << "insert into test(id,val) values(?,?)" << 1 << nullptr; - db << "select id,val from test" >> [&](long long, sqlite::optional val) { - REQUIRE(!val); - }; - -} -#endif diff --git a/common/sqlite_modern_cpp/tests/string_view.cc b/common/sqlite_modern_cpp/tests/string_view.cc deleted file mode 100644 index 39b13d80..00000000 --- a/common/sqlite_modern_cpp/tests/string_view.cc +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include - - -#ifdef MODERN_SQLITE_STRINGVIEW_SUPPORT -#include - -using namespace sqlite; -TEST_CASE("std::string_view works", "[string_view]") { - database db(":memory:"); - db << "CREATE TABLE foo (a integer, b string);\n"; - const std::string_view test1 = "null terminated string view"; - db << "INSERT INTO foo VALUES (?, ?)" << 1 << test1; - std::string str; - db << "SELECT b from FOO where a=?;" << 1 >> str; - REQUIRE(test1 == str); - const char s[] = "hello world"; - std::string_view test2(&s[0], 2); - db << "INSERT INTO foo VALUES (?,?)" << 2 << test2; - db << "SELECT b from FOO where a=?" << 2 >> str; - REQUIRE(str == "he"); -} -#endif diff --git a/common/sqlite_modern_cpp/tests/trycatchblocks.cc b/common/sqlite_modern_cpp/tests/trycatchblocks.cc deleted file mode 100644 index 2c0f7620..00000000 --- a/common/sqlite_modern_cpp/tests/trycatchblocks.cc +++ /dev/null @@ -1,80 +0,0 @@ -#include -#include -#include -#include -#include -#include - -using namespace sqlite; -using std::string; - -struct TmpFile { - string fname; - - TmpFile(): fname("./trycatchblocks.db") {} - ~TmpFile() { remove(fname.c_str()); } -}; - - -class DBInterface { - database db; - -public: - DBInterface( const string& fileName ) : db( fileName ) { } - - void LogRequest( const string& username, const string& ip, const string& request ) - { - try { - auto timestamp = std::to_string( time( nullptr ) ); - - db << - "create table if not exists log_request (" - " _id integer primary key autoincrement not null," - " username text," - " timestamp text," - " ip text," - " request text" - ");"; - db << "INSERT INTO log_request (username, timestamp, ip, request) VALUES (?,?,?,?);" - << username - << timestamp - << ip - << request; - } catch ( const std::exception& e ) { - std::cout << e.what() << std::endl; - } - } - - bool TestData( void ) { - try { - string username, timestamp, ip, request; - - db << "select username, timestamp, ip, request from log_request where username = ?" - << "test" - >> std::tie(username, timestamp, ip, request); - - if ( username == "test" && ip == "127.0.0.1" && request == "hello world" ) { - return true; - } - } catch ( const std::exception& e ) { - std::cout << e.what() << std::endl; - } - - return false; - } -}; - -TEST_CASE("try catch blocks", "[trycatchblocks]") { - // -------------------------------------------------------------------------- - // -- Test if writing to disk works properly from within a catch block. - // -------------------------------------------------------------------------- - try { - throw "hello"; - } - catch ( ... ) { - TmpFile tmpF; - DBInterface interf(tmpF.fname); - interf.LogRequest( "test", "127.0.0.1", "hello world" ); - REQUIRE(interf.TestData() == true); - } -} diff --git a/common/sqlite_modern_cpp/tests/variant.cc b/common/sqlite_modern_cpp/tests/variant.cc deleted file mode 100644 index ae755dac..00000000 --- a/common/sqlite_modern_cpp/tests/variant.cc +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include -#include -#include -using namespace sqlite; -using namespace std; - -#ifdef MODERN_SQLITE_STD_VARIANT_SUPPORT -TEST_CASE("std::variant works", "[variant]") { - database db(":memory:"); - - db << "CREATE TABLE foo (a);"; - std::variant> v; - - v = 1; - db << "INSERT INTO foo VALUES (?)" << v; - - v = "a"; - db << "INSERT INTO foo VALUES (?)" << v; - - db << "SELECT a FROM foo WHERE a=?;" << 1 >> v; - - REQUIRE(v.index() == 1); - REQUIRE(std::get<1>(v) == 1); - - db << "SELECT NULL" >> v; - REQUIRE(!std::get<2>(v)); - - db << "SELECT 0.0" >> v; - REQUIRE(std::get<2>(v)); -} - -TEST_CASE("std::monostate is a nullptr substitute", "[monostate]") { - database db(":memory:"); - db << "CREATE TABLE foo (a);"; - - std::variant v; - v=std::monostate(); - db << "INSERT INTO foo VALUES (?)" << v; - db << "INSERT INTO foo VALUES (?)" << "This isn't a monostate!"; - - bool found_null = false, - found_string = false; - - db << "SELECT * FROM foo" - >> [&](std::variant z) { - if(z.index() == 0) { - found_null = true; - } else { - found_string = true; - } - }; - REQUIRE((found_null && found_string)); - db << "SELECT NULL" >> v; - REQUIRE(v.index() == 0); -} -#endif diff --git a/examples/server/CMakeLists.txt b/examples/server/CMakeLists.txt index 78f3bca9..a9d899b0 100644 --- a/examples/server/CMakeLists.txt +++ b/examples/server/CMakeLists.txt @@ -1,6 +1,7 @@ set(TARGET llama-server) option(LLAMA_SERVER_VERBOSE "Build verbose logging option for Server" ON) option(LLAMA_SERVER_SSL "Build SSL support for the server" OFF) +option(LLAMA_SERVER_SQLITE3 "Build SQlite3 support for the server" OFF) include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) @@ -46,7 +47,7 @@ endif() # target_link_libraries(${TARGET} PRIVATE "/STACK:104857600") target_include_directories(${TARGET} PRIVATE ${CMAKE_SOURCE_DIR}) find_package(SQLite3 REQUIRED) -target_link_libraries(${TARGET} PRIVATE common ${CMAKE_THREAD_LIBS_INIT} SQLite::SQLite3) +target_link_libraries(${TARGET} PRIVATE common ${CMAKE_THREAD_LIBS_INIT}) if (LLAMA_SERVER_SSL) find_package(OpenSSL REQUIRED) @@ -54,6 +55,13 @@ if (LLAMA_SERVER_SSL) target_compile_definitions(${TARGET} PRIVATE CPPHTTPLIB_OPENSSL_SUPPORT) endif() +if (LLAMA_SERVER_SQLITE3) + find_package(SQLite3 REQUIRED) + target_link_libraries(${TARGET} PRIVATE SQLite::SQLite3) + target_include_directories(${TARGET} PUBLIC ./sqlite_modern_cpp/hdr) + target_compile_definitions(${TARGET} PRIVATE SQLITE3_MODERN_CPP_SUPPORT) +endif() + if (WIN32) TARGET_LINK_LIBRARIES(${TARGET} PRIVATE ws2_32) endif() diff --git a/examples/server/public_mikupad/index.html b/examples/server/public_mikupad/index.html index 69af753d..0a0e92f1 100644 --- a/examples/server/public_mikupad/index.html +++ b/examples/server/public_mikupad/index.html @@ -4678,7 +4678,7 @@ class ServerDBAdapter { if (version !== 4) throw new Error("Mikupad server version mismatch."); if (!features?.sql) - throw new Error("ik_llama.cpp was launched without providing a sql file.\nAdd \"--sql-save-file [PATH]\" in order to use mikupad.\nIf [PATH] is an existing file it is used, else a new SQL file will be created at [PATH]"); + throw new Error("Either llama-server was launched without providing a sql file.\nWhich can be fixed by adding \"--sql-save-file [PATH]\".\nIf [PATH] is an existing file it is used, else a new SQL file will be created at [PATH].\n Or ik_llama was compiled without '-DLLAMA_SERVER_SQLITE3=ON'"); } diff --git a/examples/server/server.cpp b/examples/server/server.cpp index 793ad09b..3b20827e 100644 --- a/examples/server/server.cpp +++ b/examples/server/server.cpp @@ -38,6 +38,7 @@ #include #include #include +#ifdef SQLITE3_MODERN_CPP_SUPPORT #include struct DatabaseHandle { @@ -49,6 +50,7 @@ struct DatabaseHandle { db << "CREATE TABLE IF NOT EXISTS names (key TEXT PRIMARY KEY, data TEXT)"; } }; +#endif using json = nlohmann::ordered_json; @@ -3449,7 +3451,7 @@ int main(int argc, char ** argv) { // Necessary similarity of prompt for slot selection ctx_server.slot_prompt_similarity = params.slot_prompt_similarity; - +#ifdef SQLITE3_MODERN_CPP_SUPPORT auto db_handle = std::make_shared(params.sql_save_file); bool sqlite_extension_loaded = false; if (!params.sqlite_zstd_ext_file.empty()) { @@ -3472,6 +3474,9 @@ int main(int argc, char ** argv) { } sqlite3_enable_load_extension(conn, 0); } +#else + auto db_handle = false; +#endif // load the model if (!ctx_server.load_model(params)) { state.store(SERVER_STATE_ERROR); @@ -4444,7 +4449,7 @@ int main(int argc, char ** argv) { return false; }; }; - +#ifdef SQLITE3_MODERN_CPP_SUPPORT const auto handle_version = [¶ms, sqlite_extension_loaded](const httplib::Request&, httplib::Response& res) { res.set_content( json{{"version", 4}, @@ -4452,7 +4457,17 @@ int main(int argc, char ** argv) { "application/json" ); }; +#else + const auto handle_version = [](const httplib::Request&, httplib::Response& res)-> void { + res.set_content( + json{{"version", 4}, + {"features", {{"sql", false}, {"zstd_compression", false}}}}.dump(), + "application/json" + ); + }; +#endif +#ifdef SQLITE3_MODERN_CPP_SUPPORT auto db_handler = [db_handle](auto func) { return [func, db_handle](const httplib::Request& req, httplib::Response& res) { res.set_header("Access-Control-Allow-Origin", "*"); @@ -4468,6 +4483,18 @@ int main(int argc, char ** argv) { } }; }; +#else + auto db_handler = [db_handle](auto func) { + return [func, db_handle](const httplib::Request& req, httplib::Response& res) { + res.set_header("Access-Control-Allow-Origin", "*"); + res.status = 500; + res.set_content( + json{{"ok", false}, {"message", "Sqlite3 support was not enabled. Recompile with '-DLLAMA_SERVER_SQLITE3=ON'"}}.dump(), + "application/json" + ); + }; + }; +#endif const auto normalize_store_name = [](const std::string& storeName) { if(storeName.empty()) return std::string("sessions"); @@ -4657,14 +4684,15 @@ int main(int argc, char ** argv) { svr->Post("/delete", handle_delete); //VACUUM is there for the extension but does not require the extension svr->Get ("/vacuum", handle_vacuum); +#ifdef SQLITE3_MODERN_CPP_SUPPORT if (sqlite_extension_loaded) { svr->Get ("/zstd_get_configs", handle_zstd_get_configs); svr->Post("/zstd_incremental_maintenance", handle_zstd_maintenance); svr->Post("/zstd_enable_transparent", handle_zstd_enable); svr->Post("/zstd_update_transparent", handle_zstd_config_update); } +#endif } - // // Start the server // diff --git a/common/sqlite_modern_cpp/License.txt b/examples/server/sqlite_modern_cpp/License.txt similarity index 100% rename from common/sqlite_modern_cpp/License.txt rename to examples/server/sqlite_modern_cpp/License.txt diff --git a/common/sqlite_modern_cpp/hdr/sqlite_modern_cpp.h b/examples/server/sqlite_modern_cpp/hdr/sqlite_modern_cpp.h similarity index 100% rename from common/sqlite_modern_cpp/hdr/sqlite_modern_cpp.h rename to examples/server/sqlite_modern_cpp/hdr/sqlite_modern_cpp.h diff --git a/common/sqlite_modern_cpp/hdr/sqlite_modern_cpp/errors.h b/examples/server/sqlite_modern_cpp/hdr/sqlite_modern_cpp/errors.h similarity index 100% rename from common/sqlite_modern_cpp/hdr/sqlite_modern_cpp/errors.h rename to examples/server/sqlite_modern_cpp/hdr/sqlite_modern_cpp/errors.h diff --git a/common/sqlite_modern_cpp/hdr/sqlite_modern_cpp/lists/error_codes.h b/examples/server/sqlite_modern_cpp/hdr/sqlite_modern_cpp/lists/error_codes.h similarity index 100% rename from common/sqlite_modern_cpp/hdr/sqlite_modern_cpp/lists/error_codes.h rename to examples/server/sqlite_modern_cpp/hdr/sqlite_modern_cpp/lists/error_codes.h diff --git a/common/sqlite_modern_cpp/hdr/sqlite_modern_cpp/log.h b/examples/server/sqlite_modern_cpp/hdr/sqlite_modern_cpp/log.h similarity index 100% rename from common/sqlite_modern_cpp/hdr/sqlite_modern_cpp/log.h rename to examples/server/sqlite_modern_cpp/hdr/sqlite_modern_cpp/log.h diff --git a/common/sqlite_modern_cpp/hdr/sqlite_modern_cpp/sqlcipher.h b/examples/server/sqlite_modern_cpp/hdr/sqlite_modern_cpp/sqlcipher.h similarity index 100% rename from common/sqlite_modern_cpp/hdr/sqlite_modern_cpp/sqlcipher.h rename to examples/server/sqlite_modern_cpp/hdr/sqlite_modern_cpp/sqlcipher.h diff --git a/common/sqlite_modern_cpp/hdr/sqlite_modern_cpp/type_wrapper.h b/examples/server/sqlite_modern_cpp/hdr/sqlite_modern_cpp/type_wrapper.h similarity index 100% rename from common/sqlite_modern_cpp/hdr/sqlite_modern_cpp/type_wrapper.h rename to examples/server/sqlite_modern_cpp/hdr/sqlite_modern_cpp/type_wrapper.h diff --git a/common/sqlite_modern_cpp/hdr/sqlite_modern_cpp/utility/function_traits.h b/examples/server/sqlite_modern_cpp/hdr/sqlite_modern_cpp/utility/function_traits.h similarity index 100% rename from common/sqlite_modern_cpp/hdr/sqlite_modern_cpp/utility/function_traits.h rename to examples/server/sqlite_modern_cpp/hdr/sqlite_modern_cpp/utility/function_traits.h diff --git a/common/sqlite_modern_cpp/hdr/sqlite_modern_cpp/utility/uncaught_exceptions.h b/examples/server/sqlite_modern_cpp/hdr/sqlite_modern_cpp/utility/uncaught_exceptions.h similarity index 100% rename from common/sqlite_modern_cpp/hdr/sqlite_modern_cpp/utility/uncaught_exceptions.h rename to examples/server/sqlite_modern_cpp/hdr/sqlite_modern_cpp/utility/uncaught_exceptions.h diff --git a/common/sqlite_modern_cpp/hdr/sqlite_modern_cpp/utility/utf16_utf8.h b/examples/server/sqlite_modern_cpp/hdr/sqlite_modern_cpp/utility/utf16_utf8.h similarity index 100% rename from common/sqlite_modern_cpp/hdr/sqlite_modern_cpp/utility/utf16_utf8.h rename to examples/server/sqlite_modern_cpp/hdr/sqlite_modern_cpp/utility/utf16_utf8.h