diff --git a/CMakeLists.txt b/CMakeLists.txt index d80b6f35..e267a2d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,16 +35,16 @@ enable_testing() add_library (sqlite_modern_cpp INTERFACE) target_include_directories(sqlite_modern_cpp INTERFACE hdr/) -add_executable(tests ${TEST_SOURCES}) -target_include_directories(tests INTERFACE ${SQLITE3_INCLUDE_DIRS}) +add_executable(tests_runner ${TEST_SOURCES}) +target_include_directories(tests_runner INTERFACE ${SQLITE3_INCLUDE_DIRS}) if(ENABLE_SQLCIPHER_TESTS) - target_link_libraries(tests Catch2::Catch2 sqlite_modern_cpp sqlite3::sqlite3 -lsqlcipher) + target_link_libraries(tests_runner Catch2::Catch2 sqlite_modern_cpp sqlite3::sqlite3 -lsqlcipher) else() - target_link_libraries(tests Catch2::Catch2 sqlite_modern_cpp sqlite3::sqlite3) + target_link_libraries(tests_runner Catch2::Catch2 sqlite_modern_cpp sqlite3::sqlite3) endif() -catch_discover_tests(tests) -target_compile_options(tests PUBLIC $<$:/Zc:__cplusplus> ) +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 diff --git a/hdr/sqlite_modern_cpp/type_wrapper.h b/hdr/sqlite_modern_cpp/type_wrapper.h index e9c466df..7bb10c1c 100644 --- a/hdr/sqlite_modern_cpp/type_wrapper.h +++ b/hdr/sqlite_modern_cpp/type_wrapper.h @@ -193,17 +193,25 @@ namespace sqlite { } // Convert char* to string_view to trigger op<<(..., const str_ref ) - template inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const char(&STR)[N]) { - return sqlite3_bind_text(stmt, inx, &STR[0], N-1, SQLITE_TRANSIENT); + template inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const char(&STR)[N]) { + return sqlite3_bind_text(stmt, inx, &STR[0], N-1, SQLITE_TRANSIENT); } inline std::string get_col_from_db(sqlite3_stmt* stmt, int inx, result_type) { - return sqlite3_column_type(stmt, inx) == SQLITE_NULL ? std::string() : - std::string(reinterpret_cast(sqlite3_column_text(stmt, inx)), sqlite3_column_bytes(stmt, inx)); + if ( sqlite3_column_type(stmt, inx) == SQLITE_NULL ) { + return std::string(); + } + char const * ptr = reinterpret_cast(sqlite3_column_text(stmt, inx)); + // call sqlite3_column_text explicitely before sqlite3_column_bytes: it may convert the value to text + return std::string(ptr, sqlite3_column_bytes(stmt, inx)); } - inline std::string get_val_from_db(sqlite3_value *value, result_type) { - return sqlite3_value_type(value) == SQLITE_NULL ? std::string() : - std::string(reinterpret_cast(sqlite3_value_text(value)), sqlite3_value_bytes(value)); + inline std::string get_val_from_db(sqlite3_value *value, result_type) { + if ( sqlite3_value_type(value) == SQLITE_NULL ) { + return std::string(); + } + char const * ptr = reinterpret_cast(sqlite3_value_text(value)); + // call sqlite3_column_text explicitely before sqlite3_column_bytes: it may convert the value to text + return std::string(ptr, sqlite3_value_bytes(value)); } inline void store_result_in_db(sqlite3_context* db, str_ref val) { @@ -222,12 +230,19 @@ namespace sqlite { } inline std::u16string get_col_from_db(sqlite3_stmt* stmt, int inx, result_type) { - return sqlite3_column_type(stmt, inx) == SQLITE_NULL ? std::u16string() : - std::u16string(reinterpret_cast(sqlite3_column_text16(stmt, inx)), sqlite3_column_bytes16(stmt, inx)); + if ( sqlite3_column_type(stmt, inx) == SQLITE_NULL ) { + return std::u16string(); + } + char16_t const * ptr = reinterpret_cast(sqlite3_column_text16(stmt, inx)); + // call sqlite3_column_text16 explicitely before sqlite3_column_bytes16: it may convert the value to text + return std::u16string(ptr, sqlite3_column_bytes16(stmt, inx)); } inline std::u16string get_val_from_db(sqlite3_value *value, result_type) { - return sqlite3_value_type(value) == SQLITE_NULL ? std::u16string() : - std::u16string(reinterpret_cast(sqlite3_value_text16(value)), sqlite3_value_bytes16(value)); + if ( sqlite3_value_type(value) == SQLITE_NULL ) { + return std::u16string(); + } + char16_t const * ptr = reinterpret_cast(sqlite3_value_text16(value)); + return std::u16string(ptr, sqlite3_value_bytes16(value)); } inline void store_result_in_db(sqlite3_context* db, u16str_ref val) { @@ -273,16 +288,16 @@ namespace sqlite { if(sqlite3_column_type(stmt, inx) == SQLITE_NULL) { return {}; } - int bytes = sqlite3_column_bytes(stmt, inx); T const* buf = reinterpret_cast(sqlite3_column_blob(stmt, inx)); + int bytes = sqlite3_column_bytes(stmt, inx); return std::vector(buf, buf + bytes/sizeof(T)); } template inline std::vector get_val_from_db(sqlite3_value *value, result_type>) { if(sqlite3_value_type(value) == SQLITE_NULL) { return {}; } - int bytes = sqlite3_value_bytes(value); T const* buf = reinterpret_cast(sqlite3_value_blob(value)); + int bytes = sqlite3_value_bytes(value); return std::vector(buf, buf + bytes/sizeof(T)); }