Compare commits

..

2 Commits

Author SHA1 Message Date
TinyAtoms
4294d4e68c Ya boi came through 2019-06-27 00:55:27 -03:00
TinyAtoms
6be7af0933 using lf instead crlf to decrease errors 2019-06-27 00:32:09 -03:00
10 changed files with 582 additions and 678 deletions

View File

@ -1,19 +1,32 @@
cmake_minimum_required(VERSION 3.14) cmake_minimum_required(VERSION 3.14)
project(park) project(park)
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/thirdparty/SQLiteCpp) add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/thirdparty/SQLiteCpp)
include_directories( include_directories(
${CMAKE_CURRENT_LIST_DIR}/thirdparty/SQLiteCpp/include ${CMAKE_CURRENT_LIST_DIR}/thirdparty/SQLiteCpp/include
) )
add_executable(park main.cpp data.cpp headers/data.h Customer.cpp headers/Customer.h Park_spot.cpp headers/Park_spot.h Park_time.cpp headers/Park_time.h) add_executable(park main.cpp data.cpp headers/data.h Customer.cpp headers/Customer.h Park_spot.cpp headers/Park_spot.h Park_time.cpp headers/Park_time.h)
target_link_libraries(park
SQLiteCpp
sqlite3
pthread if (UNIX)
dl target_link_libraries(park
) SQLiteCpp
sqlite3
pthread
dl
)
elseif (MSYS OR MINGW)
target_link_libraries(park
SQLiteCpp
sqlite3
pthread
ssp
)
endif()

View File

@ -1,39 +1,40 @@
#include "headers/Park_spot.h" #include "headers/Park_spot.h"
#include "headers/data.h" #include "headers/data.h"
#include <iostream> #include <iostream>
#include <thread> // to make pausing work, not sure if i need chrono, or this, or both #include <thread> // to make pausing work, not sure if i need chrono, or this, or both
#include <vector> #include <vector>
/* /*
Code strucure like this: Code strucure like this:
class declarations zijn in /headers/class_naam.h, en definitions van de member class declarations zijn in /headers/class_naam.h, en definitions van de member
functs in /class_naam.cpp elke klas in zn eigen file omdat ik incomplete class functs in /class_naam.cpp elke klas in zn eigen file omdat ik incomplete class
declarations wilt tegengaan, omdat ik ze niet goed begrijp. En header/source declarations wilt tegengaan, omdat ik ze niet goed begrijp. En header/source
split om multiple definition errors tegen te gaan. split om multiple definition errors tegen te gaan.
Park_spot representeert een parkeermeter bij elke parkeer spot. Park_spot representeert een parkeermeter bij elke parkeer spot.
Een customer is een customer. Een customer is een customer.
Park time is een object die reffereert naar parkspot en customer, basically een Park time is een object die reffereert naar parkspot en customer, basically een
record die zegt dat een customer voor x tijd geparkeert heeft bij spot x, enz. record die zegt dat een customer voor x tijd geparkeert heeft bij spot x, enz.
De client clockt in en uit bij een spot. De client clockt in en uit bij een spot.
*/ */
void Wait(int sec) void Wait(int sec)
/* /*
a wait function where 1 sec represents 1 hour irl. a wait function where 1 sec represents 1 hour irl.
*/ */
{ {
std::this_thread::sleep_for(seconds{sec}); std::this_thread::sleep_for(seconds{sec});
} }
using std::cout; using std::cout;
int main() { int main() {
SQLite::Database db = data::start_db(); SQLite::Database db = data::start_db();
// see implementation of update_db, save_db and delete_db of customer to see how queries and statements work // see implementation of update_db, save_db and delete_db of customer to see how queries and statements work
Customer sagar{"Ramsaransing", Verhicle_type::medium, db}; Customer sagar{"Sagar Winston Ramsaransing", Verhicle_type::medium, db};
sagar.update_db(db); sagar.update_db(db);
sagar.delete_db(db); cout << "THIS WRKS";
} // sagar.delete_db(db);
}

BIN
test.db3

Binary file not shown.

View File

@ -1,338 +1,338 @@
# Main CMake file for compiling the library itself, examples and tests. # Main CMake file for compiling the library itself, examples and tests.
# #
# Copyright (c) 2012-2019 Sebastien Rombauts (sebastien.rombauts@gmail.com) # Copyright (c) 2012-2019 Sebastien Rombauts (sebastien.rombauts@gmail.com)
# #
# Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt # Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
# or copy at http://opensource.org/licenses/MIT) # or copy at http://opensource.org/licenses/MIT)
cmake_minimum_required(VERSION 2.8.12) # first version with add_compile_options() cmake_minimum_required(VERSION 2.8.12) # first version with add_compile_options()
project(SQLiteCpp) project(SQLiteCpp)
message (STATUS "CMake version: ${CMAKE_VERSION}") message (STATUS "CMake version: ${CMAKE_VERSION}")
# Define useful variables to handle OS differences: # Define useful variables to handle OS differences:
if (WIN32) if (WIN32)
set(DEV_NULL "NUL") set(DEV_NULL "NUL")
else (WIN32) # UNIX else (WIN32) # UNIX
set(DEV_NULL "/dev/null") set(DEV_NULL "/dev/null")
endif (WIN32) endif (WIN32)
# then Compiler/IDE differences: # then Compiler/IDE differences:
if (MSVC) if (MSVC)
set(CPPLINT_ARG_OUTPUT "--output=vs7") set(CPPLINT_ARG_OUTPUT "--output=vs7")
set(CPPCHECK_ARG_TEMPLATE "--template=vs") set(CPPCHECK_ARG_TEMPLATE "--template=vs")
# disable Visual Studio warnings for fopen() used in the example # disable Visual Studio warnings for fopen() used in the example
add_definitions(-D_CRT_SECURE_NO_WARNINGS) add_definitions(-D_CRT_SECURE_NO_WARNINGS)
# Flags for linking with multithread static C++ runtime, required by googletest # Flags for linking with multithread static C++ runtime, required by googletest
if (SQLITECPP_BUILD_TESTS) if (SQLITECPP_BUILD_TESTS)
message(STATUS "Linking against multithread static C++ runtime for unit tests with googletest") message(STATUS "Linking against multithread static C++ runtime for unit tests with googletest")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
endif (SQLITECPP_BUILD_TESTS) endif (SQLITECPP_BUILD_TESTS)
# Handle the (partly supported) MSVC versions prior to 2015 # Handle the (partly supported) MSVC versions prior to 2015
if (MSVC_VERSION LESS 1900) # OR MSVC_TOOLSET_VERSION LESS 140) if (MSVC_VERSION LESS 1900) # OR MSVC_TOOLSET_VERSION LESS 140)
message(WARNING "MSVC < 2015 detected: Visual Studio prior to 2015 is not fully supported. BLOB storage seems to be corrupted.") message(WARNING "MSVC < 2015 detected: Visual Studio prior to 2015 is not fully supported. BLOB storage seems to be corrupted.")
endif (MSVC_VERSION LESS 1900) endif (MSVC_VERSION LESS 1900)
else (MSVC) else (MSVC)
set(CPPLINT_ARG_OUTPUT "--output=eclipse") set(CPPLINT_ARG_OUTPUT "--output=eclipse")
set(CPPCHECK_ARG_TEMPLATE "--template=gcc") set(CPPCHECK_ARG_TEMPLATE "--template=gcc")
# Useful compile flags and extra warnings # Useful compile flags and extra warnings
add_compile_options(-fstack-protector -Wall -Wextra -Wpedantic -Wno-long-long -Wswitch-enum -Wshadow -Winline) add_compile_options(-fstack-protector -Wall -Wextra -Wpedantic -Wno-long-long -Wswitch-enum -Wshadow -Winline)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-c++0x-compat") # C++ only set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-c++0x-compat") # C++ only
if (CMAKE_COMPILER_IS_GNUCXX) if (CMAKE_COMPILER_IS_GNUCXX)
# GCC flags # GCC flags
option(SQLITECPP_USE_GCOV "USE GCov instrumentation." OFF) option(SQLITECPP_USE_GCOV "USE GCov instrumentation." OFF)
if (SQLITECPP_USE_GCOV) if (SQLITECPP_USE_GCOV)
message (STATUS "Using GCov instrumentation") message (STATUS "Using GCov instrumentation")
add_compile_options (-coverage) # NOTE -fkeep-inline-functions would be usefull but not working with current google test and gcc 4.8 add_compile_options (-coverage) # NOTE -fkeep-inline-functions would be usefull but not working with current google test and gcc 4.8
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -coverage") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -coverage")
endif () endif ()
endif (CMAKE_COMPILER_IS_GNUCXX) endif (CMAKE_COMPILER_IS_GNUCXX)
endif (MSVC) endif (MSVC)
# and then common variables # and then common variables
set(CPPLINT_ARG_VERBOSE "--verbose=3") set(CPPLINT_ARG_VERBOSE "--verbose=3")
set(CPPLINT_ARG_LINELENGTH "--linelength=120") set(CPPLINT_ARG_LINELENGTH "--linelength=120")
# Print CXX compiler information # Print CXX compiler information
message (STATUS "CMAKE_CXX_COMPILER '${CMAKE_CXX_COMPILER}' '${CMAKE_CXX_COMPILER_ID}' '${CMAKE_CXX_COMPILER_VERSION}'") message (STATUS "CMAKE_CXX_COMPILER '${CMAKE_CXX_COMPILER}' '${CMAKE_CXX_COMPILER_ID}' '${CMAKE_CXX_COMPILER_VERSION}'")
# Print CXX FLAGS # Print CXX FLAGS
message (STATUS "CMAKE_CXX_FLAGS '${CMAKE_CXX_FLAGS}'") message (STATUS "CMAKE_CXX_FLAGS '${CMAKE_CXX_FLAGS}'")
if (MSVC) if (MSVC)
message (STATUS "CMAKE_CXX_FLAGS_DEBUG '${CMAKE_CXX_FLAGS_DEBUG}'") message (STATUS "CMAKE_CXX_FLAGS_DEBUG '${CMAKE_CXX_FLAGS_DEBUG}'")
message (STATUS "CMAKE_CXX_FLAGS_RELEASE '${CMAKE_CXX_FLAGS_RELEASE}'") message (STATUS "CMAKE_CXX_FLAGS_RELEASE '${CMAKE_CXX_FLAGS_RELEASE}'")
message (STATUS "CMAKE_CXX_FLAGS_RELWITHDEBINFO '${CMAKE_CXX_FLAGS_RELWITHDEBINFO}'") message (STATUS "CMAKE_CXX_FLAGS_RELWITHDEBINFO '${CMAKE_CXX_FLAGS_RELWITHDEBINFO}'")
message (STATUS "CMAKE_CXX_FLAGS_MINSIZEREL '${CMAKE_CXX_FLAGS_MINSIZEREL}'") message (STATUS "CMAKE_CXX_FLAGS_MINSIZEREL '${CMAKE_CXX_FLAGS_MINSIZEREL}'")
else (NOT MSVC) else (NOT MSVC)
if (CMAKE_BUILD_TYPE STREQUAL Debug) if (CMAKE_BUILD_TYPE STREQUAL Debug)
message (STATUS "CMAKE_CXX_FLAGS_DEBUG '${CMAKE_CXX_FLAGS_DEBUG}'") message (STATUS "CMAKE_CXX_FLAGS_DEBUG '${CMAKE_CXX_FLAGS_DEBUG}'")
elseif (CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo) elseif (CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo)
message (STATUS "CMAKE_CXX_FLAGS_RELWITHDEBINFO '${CMAKE_CXX_FLAGS_RELWITHDEBINFO}'") message (STATUS "CMAKE_CXX_FLAGS_RELWITHDEBINFO '${CMAKE_CXX_FLAGS_RELWITHDEBINFO}'")
elseif (CMAKE_BUILD_TYPE STREQUAL MinSizeRel) elseif (CMAKE_BUILD_TYPE STREQUAL MinSizeRel)
message (STATUS "CMAKE_CXX_FLAGS_MINSIZEREL '${CMAKE_CXX_FLAGS_MINSIZEREL}'") message (STATUS "CMAKE_CXX_FLAGS_MINSIZEREL '${CMAKE_CXX_FLAGS_MINSIZEREL}'")
else () else ()
message (STATUS "CMAKE_CXX_FLAGS_RELEASE '${CMAKE_CXX_FLAGS_RELEASE}'") message (STATUS "CMAKE_CXX_FLAGS_RELEASE '${CMAKE_CXX_FLAGS_RELEASE}'")
endif () endif ()
endif () endif ()
# Options relative to SQLite and SQLiteC++ functions # Options relative to SQLite and SQLiteC++ functions
option(SQLITE_ENABLE_COLUMN_METADATA "Enable Column::getColumnOriginName(). Require support from sqlite3 library." ON) option(SQLITE_ENABLE_COLUMN_METADATA "Enable Column::getColumnOriginName(). Require support from sqlite3 library." ON)
if (SQLITE_ENABLE_COLUMN_METADATA) if (SQLITE_ENABLE_COLUMN_METADATA)
# Enable the use of SQLite column metadata and Column::getColumnOriginName() method, # Enable the use of SQLite column metadata and Column::getColumnOriginName() method,
# Require that the sqlite3 library is also compiled with this flag (default under Debian/Ubuntu, but not on Mac OS X). # Require that the sqlite3 library is also compiled with this flag (default under Debian/Ubuntu, but not on Mac OS X).
add_definitions(-DSQLITE_ENABLE_COLUMN_METADATA) add_definitions(-DSQLITE_ENABLE_COLUMN_METADATA)
endif (SQLITE_ENABLE_COLUMN_METADATA) endif (SQLITE_ENABLE_COLUMN_METADATA)
option(SQLITE_ENABLE_ASSERT_HANDLER "Enable the user defintion of a assertion_failed() handler." OFF) option(SQLITE_ENABLE_ASSERT_HANDLER "Enable the user defintion of a assertion_failed() handler." OFF)
if (SQLITE_ENABLE_ASSERT_HANDLER) if (SQLITE_ENABLE_ASSERT_HANDLER)
# Enable the user defintion of a assertion_failed() handler (default to false, easier to handler for begginers). # Enable the user defintion of a assertion_failed() handler (default to false, easier to handler for begginers).
add_definitions(-DSQLITECPP_ENABLE_ASSERT_HANDLER) add_definitions(-DSQLITECPP_ENABLE_ASSERT_HANDLER)
endif (SQLITE_ENABLE_ASSERT_HANDLER) endif (SQLITE_ENABLE_ASSERT_HANDLER)
option(SQLITE_USE_LEGACY_STRUCT "Fallback to forward declaration of legacy struct sqlite3_value (pre SQLite 3.19)" OFF) option(SQLITE_USE_LEGACY_STRUCT "Fallback to forward declaration of legacy struct sqlite3_value (pre SQLite 3.19)" OFF)
if (SQLITE_USE_LEGACY_STRUCT) if (SQLITE_USE_LEGACY_STRUCT)
# Force forward declaration of legacy struct sqlite3_value (pre SQLite 3.19) # Force forward declaration of legacy struct sqlite3_value (pre SQLite 3.19)
add_definitions(-DSQLITE_USE_LEGACY_STRUCT) add_definitions(-DSQLITE_USE_LEGACY_STRUCT)
endif (SQLITE_USE_LEGACY_STRUCT) endif (SQLITE_USE_LEGACY_STRUCT)
## Build the C++ Wrapper ## ## Build the C++ Wrapper ##
# adding a new file require explicittly modifing the CMakeLists.txt # adding a new file require explicittly modifing the CMakeLists.txt
# so that CMake knows that it should rebuild the project (it is best practice) # so that CMake knows that it should rebuild the project (it is best practice)
# list of sources files of the library # list of sources files of the library
set(SQLITECPP_SRC set(SQLITECPP_SRC
${PROJECT_SOURCE_DIR}/src/Backup.cpp ${PROJECT_SOURCE_DIR}/src/Backup.cpp
${PROJECT_SOURCE_DIR}/src/Column.cpp ${PROJECT_SOURCE_DIR}/src/Column.cpp
${PROJECT_SOURCE_DIR}/src/Database.cpp ${PROJECT_SOURCE_DIR}/src/Database.cpp
${PROJECT_SOURCE_DIR}/src/Exception.cpp ${PROJECT_SOURCE_DIR}/src/Exception.cpp
${PROJECT_SOURCE_DIR}/src/Statement.cpp ${PROJECT_SOURCE_DIR}/src/Statement.cpp
${PROJECT_SOURCE_DIR}/src/Transaction.cpp ${PROJECT_SOURCE_DIR}/src/Transaction.cpp
) )
source_group(src FILES ${SQLITECPP_SRC}) source_group(src FILES ${SQLITECPP_SRC})
# list of header files of the library # list of header files of the library
set(SQLITECPP_INC set(SQLITECPP_INC
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/SQLiteCpp.h ${PROJECT_SOURCE_DIR}/include/SQLiteCpp/SQLiteCpp.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Assertion.h ${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Assertion.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Backup.h ${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Backup.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Column.h ${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Column.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Database.h ${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Database.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Exception.h ${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Exception.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Statement.h ${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Statement.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Transaction.h ${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Transaction.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Utils.h ${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Utils.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/VariadicBind.h ${PROJECT_SOURCE_DIR}/include/SQLiteCpp/VariadicBind.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/ExecuteMany.h ${PROJECT_SOURCE_DIR}/include/SQLiteCpp/ExecuteMany.h
) )
source_group(include FILES ${SQLITECPP_INC}) source_group(include FILES ${SQLITECPP_INC})
# list of test files of the library # list of test files of the library
set(SQLITECPP_TESTS set(SQLITECPP_TESTS
tests/Column_test.cpp tests/Column_test.cpp
tests/Database_test.cpp tests/Database_test.cpp
tests/Statement_test.cpp tests/Statement_test.cpp
tests/Backup_test.cpp tests/Backup_test.cpp
tests/Transaction_test.cpp tests/Transaction_test.cpp
tests/VariadicBind_test.cpp tests/VariadicBind_test.cpp
tests/Exception_test.cpp tests/Exception_test.cpp
tests/ExecuteMany_test.cpp tests/ExecuteMany_test.cpp
) )
source_group(tests FILES ${SQLITECPP_TESTS}) source_group(tests FILES ${SQLITECPP_TESTS})
# list of example files of the library # list of example files of the library
set(SQLITECPP_EXAMPLES set(SQLITECPP_EXAMPLES
examples/example1/main.cpp examples/example1/main.cpp
) )
source_group(example1 FILES ${SQLITECPP_EXAMPLES}) source_group(example1 FILES ${SQLITECPP_EXAMPLES})
# list of doc files of the library # list of doc files of the library
set(SQLITECPP_DOC set(SQLITECPP_DOC
README.md README.md
LICENSE.txt LICENSE.txt
CHANGELOG.md CHANGELOG.md
TODO.txt TODO.txt
) )
source_group(doc FILES ${SQLITECPP_DOC}) source_group(doc FILES ${SQLITECPP_DOC})
# list of script files of the library # list of script files of the library
set(SQLITECPP_SCRIPT set(SQLITECPP_SCRIPT
.travis.yml .travis.yml
appveyor.yml appveyor.yml
build.bat build.bat
build.sh build.sh
cpplint.py cpplint.py
Doxyfile Doxyfile
FindSQLiteCpp.cmake FindSQLiteCpp.cmake
) )
source_group(scripts FILES ${SQLITECPP_SCRIPT}) source_group(scripts FILES ${SQLITECPP_SCRIPT})
# All includes are relative to the "include" directory # All includes are relative to the "include" directory
include_directories("${PROJECT_SOURCE_DIR}/include") include_directories("${PROJECT_SOURCE_DIR}/include")
# add sources of the wrapper as a "SQLiteCpp" static library # add sources of the wrapper as a "SQLiteCpp" static library
add_library(SQLiteCpp ${SQLITECPP_SRC} ${SQLITECPP_INC} ${SQLITECPP_DOC} ${SQLITECPP_SCRIPT}) add_library(SQLiteCpp ${SQLITECPP_SRC} ${SQLITECPP_INC} ${SQLITECPP_DOC} ${SQLITECPP_SCRIPT})
# make the sqlite3 library part of the interface of the SQLiteCpp wrapper itself (the client app does not need to link to sqlite3) # make the sqlite3 library part of the interface of the SQLiteCpp wrapper itself (the client app does not need to link to sqlite3)
# PR https://github.com/SRombauts/SQLiteCpp/pull/111 "linked SQLiteCpp to sqlite3" commented out since it breaks install step from PR #118 # PR https://github.com/SRombauts/SQLiteCpp/pull/111 "linked SQLiteCpp to sqlite3" commented out since it breaks install step from PR #118
#target_link_libraries(SQLiteCpp PUBLIC sqlite3) #target_link_libraries(SQLiteCpp PUBLIC sqlite3)
if (UNIX AND (CMAKE_COMPILER_IS_GNUCXX OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")) if (UNIX AND (CMAKE_COMPILER_IS_GNUCXX OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang"))
set_target_properties(SQLiteCpp PROPERTIES COMPILE_FLAGS "-fPIC") set_target_properties(SQLiteCpp PROPERTIES COMPILE_FLAGS "-fPIC")
endif (UNIX AND (CMAKE_COMPILER_IS_GNUCXX OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")) endif (UNIX AND (CMAKE_COMPILER_IS_GNUCXX OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang"))
# Allow the library to be installed via "make install" and found with "find_package" # Allow the library to be installed via "make install" and found with "find_package"
install(TARGETS SQLiteCpp install(TARGETS SQLiteCpp
EXPORT ${PROJECT_NAME}Config EXPORT ${PROJECT_NAME}Config
LIBRARY DESTINATION lib LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib ARCHIVE DESTINATION lib
COMPONENT libraries) COMPONENT libraries)
target_include_directories(SQLiteCpp PUBLIC target_include_directories(SQLiteCpp PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include/>) $<INSTALL_INTERFACE:include/>)
install(DIRECTORY include/ DESTINATION include COMPONENT headers FILES_MATCHING REGEX ".*\\.(hpp|h)$") install(DIRECTORY include/ DESTINATION include COMPONENT headers FILES_MATCHING REGEX ".*\\.(hpp|h)$")
install(EXPORT ${PROJECT_NAME}Config DESTINATION lib/cmake/${PROJECT_NAME}) install(EXPORT ${PROJECT_NAME}Config DESTINATION lib/cmake/${PROJECT_NAME})
## Build provided copy of SQLite3 C library ## ## Build provided copy of SQLite3 C library ##
# TODO # TODO
#find_package(sqlite3) #find_package(sqlite3)
#if(sqlite3_VERSION VERSION_LESS "3.19") #if(sqlite3_VERSION VERSION_LESS "3.19")
# set_target_properties(SQLiteCpp PROPERTIES COMPILE_FLAGS "-DSQLITECPP_HAS_MEM_STRUCT") # set_target_properties(SQLiteCpp PROPERTIES COMPILE_FLAGS "-DSQLITECPP_HAS_MEM_STRUCT")
#endif() #endif()
option(SQLITECPP_USE_ASAN "Use Address Sanitizer." OFF) option(SQLITECPP_USE_ASAN "Use Address Sanitizer." OFF)
if (SQLITECPP_USE_ASAN) if (SQLITECPP_USE_ASAN)
if ((CMAKE_CXX_COMPILER_VERSION GREATER_EQUAL 6) OR ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")) if ((CMAKE_CXX_COMPILER_VERSION GREATER_EQUAL 6) OR ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang"))
message (STATUS "Using Address Sanitizer") message (STATUS "Using Address Sanitizer")
set_target_properties(SQLiteCpp PROPERTIES COMPILE_FLAGS "-fsanitize=address -fno-omit-frame-pointer") set_target_properties(SQLiteCpp PROPERTIES COMPILE_FLAGS "-fsanitize=address -fno-omit-frame-pointer")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
if (CMAKE_COMPILER_IS_GNUCXX) if (CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")
endif () endif ()
endif () endif ()
endif (SQLITECPP_USE_ASAN) endif (SQLITECPP_USE_ASAN)
option(SQLITECPP_INTERNAL_SQLITE "Add the internal SQLite3 source to the project." ON) option(SQLITECPP_INTERNAL_SQLITE "Add the internal SQLite3 source to the project." ON)
if (SQLITECPP_INTERNAL_SQLITE) if (SQLITECPP_INTERNAL_SQLITE)
# build the SQLite3 C library (for ease of use/compatibility) versus Linux sqlite3-dev package # build the SQLite3 C library (for ease of use/compatibility) versus Linux sqlite3-dev package
add_subdirectory(sqlite3) add_subdirectory(sqlite3)
target_include_directories(sqlite3 PUBLIC "${PROJECT_SOURCE_DIR}/sqlite3") target_include_directories(sqlite3 PUBLIC "${PROJECT_SOURCE_DIR}/sqlite3")
target_include_directories(SQLiteCpp PRIVATE "${PROJECT_SOURCE_DIR}/sqlite3") target_include_directories(SQLiteCpp PRIVATE "${PROJECT_SOURCE_DIR}/sqlite3")
endif (SQLITECPP_INTERNAL_SQLITE) endif (SQLITECPP_INTERNAL_SQLITE)
# Optional additional targets: # Optional additional targets:
option(SQLITECPP_RUN_CPPLINT "Run cpplint.py tool for Google C++ StyleGuide." ON) option(SQLITECPP_RUN_CPPLINT "Run cpplint.py tool for Google C++ StyleGuide." ON)
if (SQLITECPP_RUN_CPPLINT) if (SQLITECPP_RUN_CPPLINT)
find_package(PythonInterp) find_package(PythonInterp)
if (PYTHONINTERP_FOUND) if (PYTHONINTERP_FOUND)
# add a cpplint target to the "all" target # add a cpplint target to the "all" target
add_custom_target(SQLiteCpp_cpplint add_custom_target(SQLiteCpp_cpplint
ALL ALL
COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/cpplint.py ${CPPLINT_ARG_OUTPUT} ${CPPLINT_ARG_VERBOSE} ${CPPLINT_ARG_LINELENGTH} ${SQLITECPP_SRC} ${SQLITECPP_INC} COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/cpplint.py ${CPPLINT_ARG_OUTPUT} ${CPPLINT_ARG_VERBOSE} ${CPPLINT_ARG_LINELENGTH} ${SQLITECPP_SRC} ${SQLITECPP_INC}
) )
endif (PYTHONINTERP_FOUND) endif (PYTHONINTERP_FOUND)
else (SQLITECPP_RUN_CPPLINT) else (SQLITECPP_RUN_CPPLINT)
message(STATUS "SQLITECPP_RUN_CPPLINT OFF") message(STATUS "SQLITECPP_RUN_CPPLINT OFF")
endif (SQLITECPP_RUN_CPPLINT) endif (SQLITECPP_RUN_CPPLINT)
option(SQLITECPP_RUN_CPPCHECK "Run cppcheck C++ static analysis tool." ON) option(SQLITECPP_RUN_CPPCHECK "Run cppcheck C++ static analysis tool." ON)
if (SQLITECPP_RUN_CPPCHECK) if (SQLITECPP_RUN_CPPCHECK)
find_program(CPPCHECK_EXECUTABLE NAMES cppcheck) find_program(CPPCHECK_EXECUTABLE NAMES cppcheck)
if (CPPCHECK_EXECUTABLE) if (CPPCHECK_EXECUTABLE)
# add a cppcheck target to the "all" target # add a cppcheck target to the "all" target
add_custom_target(SQLiteCpp_cppcheck add_custom_target(SQLiteCpp_cppcheck
ALL ALL
COMMAND ${CPPCHECK_EXECUTABLE} -j 8 cppcheck --enable=style --quiet ${CPPCHECK_ARG_TEMPLATE} ${PROJECT_SOURCE_DIR}/src COMMAND ${CPPCHECK_EXECUTABLE} -j 8 cppcheck --enable=style --quiet ${CPPCHECK_ARG_TEMPLATE} ${PROJECT_SOURCE_DIR}/src
) )
execute_process(COMMAND "${CPPCHECK_EXECUTABLE}" --version OUTPUT_VARIABLE CPPCHECK_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process(COMMAND "${CPPCHECK_EXECUTABLE}" --version OUTPUT_VARIABLE CPPCHECK_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Found Cppcheck: ${CPPCHECK_EXECUTABLE} ${CPPCHECK_VERSION}") message(STATUS "Found Cppcheck: ${CPPCHECK_EXECUTABLE} ${CPPCHECK_VERSION}")
else (CPPCHECK_EXECUTABLE) else (CPPCHECK_EXECUTABLE)
message(STATUS "Could NOT find cppcheck") message(STATUS "Could NOT find cppcheck")
endif (CPPCHECK_EXECUTABLE) endif (CPPCHECK_EXECUTABLE)
else (SQLITECPP_RUN_CPPCHECK) else (SQLITECPP_RUN_CPPCHECK)
message(STATUS "SQLITECPP_RUN_CPPCHECK OFF") message(STATUS "SQLITECPP_RUN_CPPCHECK OFF")
endif (SQLITECPP_RUN_CPPCHECK) endif (SQLITECPP_RUN_CPPCHECK)
option(SQLITECPP_RUN_DOXYGEN "Run Doxygen C++ documentation tool." OFF) option(SQLITECPP_RUN_DOXYGEN "Run Doxygen C++ documentation tool." OFF)
if (SQLITECPP_RUN_DOXYGEN) if (SQLITECPP_RUN_DOXYGEN)
find_package(Doxygen) find_package(Doxygen)
if (DOXYGEN_FOUND) if (DOXYGEN_FOUND)
# add a Doxygen target to the "all" target # add a Doxygen target to the "all" target
add_custom_target(SQLiteCpp_doxygen add_custom_target(SQLiteCpp_doxygen
ALL ALL
COMMAND doxygen Doxyfile > ${DEV_NULL} COMMAND doxygen Doxyfile > ${DEV_NULL}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
) )
endif (DOXYGEN_FOUND) endif (DOXYGEN_FOUND)
else (SQLITECPP_RUN_DOXYGEN) else (SQLITECPP_RUN_DOXYGEN)
message(STATUS "SQLITECPP_RUN_DOXYGEN OFF") message(STATUS "SQLITECPP_RUN_DOXYGEN OFF")
endif (SQLITECPP_RUN_DOXYGEN) endif (SQLITECPP_RUN_DOXYGEN)
option(SQLITECPP_BUILD_EXAMPLES "Build examples." OFF) option(SQLITECPP_BUILD_EXAMPLES "Build examples." OFF)
if (SQLITECPP_BUILD_EXAMPLES) if (SQLITECPP_BUILD_EXAMPLES)
# add the basic example executable # add the basic example executable
add_executable(SQLiteCpp_example1 ${SQLITECPP_EXAMPLES}) add_executable(SQLiteCpp_example1 ${SQLITECPP_EXAMPLES})
target_link_libraries(SQLiteCpp_example1 SQLiteCpp sqlite3) target_link_libraries(SQLiteCpp_example1 SQLiteCpp sqlite3)
# Link target with pthread and dl for linux # Link target with pthread and dl for linux
if (UNIX) if (UNIX)
target_link_libraries(SQLiteCpp_example1 pthread) target_link_libraries(SQLiteCpp_example1 pthread)
if (NOT APPLE) if (NOT APPLE)
target_link_libraries(SQLiteCpp_example1 dl) target_link_libraries(SQLiteCpp_example1 dl)
endif () endif ()
elseif (MSYS OR MINGW) elseif (MSYS OR MINGW)
target_link_libraries(SQLiteCpp_example1 ssp) target_link_libraries(SQLiteCpp_example1 ssp)
endif () endif ()
else (SQLITECPP_BUILD_EXAMPLES) else (SQLITECPP_BUILD_EXAMPLES)
message(STATUS "SQLITECPP_BUILD_EXAMPLES OFF") message(STATUS "SQLITECPP_BUILD_EXAMPLES OFF")
endif (SQLITECPP_BUILD_EXAMPLES) endif (SQLITECPP_BUILD_EXAMPLES)
option(SQLITECPP_BUILD_TESTS "Build and run tests." OFF) option(SQLITECPP_BUILD_TESTS "Build and run tests." OFF)
if (SQLITECPP_BUILD_TESTS) if (SQLITECPP_BUILD_TESTS)
# deactivate some warnings for compiling the gtest library # deactivate some warnings for compiling the gtest library
if (NOT MSVC) if (NOT MSVC)
add_compile_options(-Wno-variadic-macros -Wno-long-long -Wno-switch-enum -Wno-float-equal -Wno-conversion-null -Wno-switch-default -Wno-pedantic) add_compile_options(-Wno-variadic-macros -Wno-long-long -Wno-switch-enum -Wno-float-equal -Wno-conversion-null -Wno-switch-default -Wno-pedantic)
endif (NOT MSVC) endif (NOT MSVC)
# add the subdirectory containing the CMakeLists.txt for the gtest library # add the subdirectory containing the CMakeLists.txt for the gtest library
# TODO: under Linux, uses libgtest-dev if found # TODO: under Linux, uses libgtest-dev if found
if (NOT EXISTS "${PROJECT_SOURCE_DIR}/googletest/CMakeLists.txt") if (NOT EXISTS "${PROJECT_SOURCE_DIR}/googletest/CMakeLists.txt")
message(FATAL_ERROR "Missing 'googletest' submodule! Either use 'git submodule init' and 'git submodule update' to get googletest according to the README, or deactivate unit tests with -DSQLITECPP_BUILD_TESTS=OFF") message(FATAL_ERROR "Missing 'googletest' submodule! Either use 'git submodule init' and 'git submodule update' to get googletest according to the README, or deactivate unit tests with -DSQLITECPP_BUILD_TESTS=OFF")
endif () endif ()
add_subdirectory(googletest) add_subdirectory(googletest)
include_directories("${PROJECT_SOURCE_DIR}/googletest/googletest/include") include_directories("${PROJECT_SOURCE_DIR}/googletest/googletest/include")
# Add definitions to keep googletest from making the compilation fail # Add definitions to keep googletest from making the compilation fail
if (MSVC) if (MSVC)
if (MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS_EQUAL 1919) # OR MSVC_TOOLSET_VERSION EQUAL 141) if (MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS_EQUAL 1919) # OR MSVC_TOOLSET_VERSION EQUAL 141)
target_compile_definitions(gtest PUBLIC _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING) target_compile_definitions(gtest PUBLIC _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING)
target_compile_definitions(gtest_main PUBLIC _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING) target_compile_definitions(gtest_main PUBLIC _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING)
target_compile_definitions(gmock PUBLIC _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING) target_compile_definitions(gmock PUBLIC _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING)
target_compile_definitions(gmock_main PUBLIC _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING) target_compile_definitions(gmock_main PUBLIC _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING)
endif (MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS_EQUAL 1919) endif (MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS_EQUAL 1919)
endif (MSVC) endif (MSVC)
# add the unit test executable # add the unit test executable
add_executable(SQLiteCpp_tests ${SQLITECPP_TESTS}) add_executable(SQLiteCpp_tests ${SQLITECPP_TESTS})
target_link_libraries(SQLiteCpp_tests gtest_main SQLiteCpp sqlite3) target_link_libraries(SQLiteCpp_tests gtest_main SQLiteCpp sqlite3)
# Link target with dl for linux # Link target with dl for linux
if (UNIX AND NOT APPLE) if (UNIX AND NOT APPLE)
target_link_libraries(SQLiteCpp_tests dl) target_link_libraries(SQLiteCpp_tests dl)
endif () endif ()
# add a "test" target: # add a "test" target:
enable_testing() enable_testing()
# does the tests pass? # does the tests pass?
add_test(UnitTests SQLiteCpp_tests) add_test(UnitTests SQLiteCpp_tests)
if (SQLITECPP_BUILD_EXAMPLES) if (SQLITECPP_BUILD_EXAMPLES)
# does the example1 runs successfully? # does the example1 runs successfully?
add_test(Example1Run SQLiteCpp_example1) add_test(Example1Run SQLiteCpp_example1)
endif (SQLITECPP_BUILD_EXAMPLES) endif (SQLITECPP_BUILD_EXAMPLES)
else (SQLITECPP_BUILD_TESTS) else (SQLITECPP_BUILD_TESTS)
message(STATUS "SQLITECPP_BUILD_TESTS OFF") message(STATUS "SQLITECPP_BUILD_TESTS OFF")
endif (SQLITECPP_BUILD_TESTS) endif (SQLITECPP_BUILD_TESTS)

View File

@ -10,95 +10,78 @@
* or copy at http://opensource.org/licenses/MIT) * or copy at http://opensource.org/licenses/MIT)
*/ */
#include <SQLiteCpp/Backup.h> #include <SQLiteCpp/Backup.h>
#include <SQLiteCpp/Exception.h> #include <SQLiteCpp/Exception.h>
#include <sqlite3.h> #include <sqlite3.h>
namespace SQLite {
namespace SQLite
{
// Initialize resource for SQLite database backup // Initialize resource for SQLite database backup
Backup::Backup(Database& aDestDatabase, Backup::Backup(Database& aDestDatabase,
const char* apDestDatabaseName, const char* apDestDatabaseName,
Database& aSrcDatabase, Database& aSrcDatabase,
const char* apSrcDatabaseName) : const char* apSrcDatabaseName)
mpSQLiteBackup(NULL) : mpSQLiteBackup(NULL)
{ {
mpSQLiteBackup = sqlite3_backup_init(aDestDatabase.getHandle(), mpSQLiteBackup = sqlite3_backup_init(aDestDatabase.getHandle(),
apDestDatabaseName, apDestDatabaseName,
aSrcDatabase.getHandle(), aSrcDatabase.getHandle(),
apSrcDatabaseName); apSrcDatabaseName);
if (NULL == mpSQLiteBackup) if (NULL == mpSQLiteBackup) {
{
// If an error occurs, the error code and message are attached to the destination database connection. // If an error occurs, the error code and message are attached to the destination database connection.
throw SQLite::Exception(aDestDatabase.getHandle()); throw SQLite::Exception(aDestDatabase.getHandle());
} }
} }
// Initialize resource for SQLite database backup // Initialize resource for SQLite database backup
Backup::Backup(Database& aDestDatabase, Backup::Backup(Database& aDestDatabase,
const std::string& aDestDatabaseName, const std::string& aDestDatabaseName,
Database& aSrcDatabase, Database& aSrcDatabase,
const std::string& aSrcDatabaseName) : const std::string& aSrcDatabaseName)
mpSQLiteBackup(NULL) : mpSQLiteBackup(NULL)
{ {
mpSQLiteBackup = sqlite3_backup_init(aDestDatabase.getHandle(), mpSQLiteBackup = sqlite3_backup_init(aDestDatabase.getHandle(),
aDestDatabaseName.c_str(), aDestDatabaseName.c_str(),
aSrcDatabase.getHandle(), aSrcDatabase.getHandle(),
aSrcDatabaseName.c_str()); aSrcDatabaseName.c_str());
if (NULL == mpSQLiteBackup) if (NULL == mpSQLiteBackup) {
{
// If an error occurs, the error code and message are attached to the destination database connection. // If an error occurs, the error code and message are attached to the destination database connection.
throw SQLite::Exception(aDestDatabase.getHandle()); throw SQLite::Exception(aDestDatabase.getHandle());
} }
} }
// Initialize resource for SQLite database backup // Initialize resource for SQLite database backup
Backup::Backup(Database &aDestDatabase, Database &aSrcDatabase) : Backup::Backup(Database& aDestDatabase, Database& aSrcDatabase)
mpSQLiteBackup(NULL) : mpSQLiteBackup(NULL)
{ {
mpSQLiteBackup = sqlite3_backup_init(aDestDatabase.getHandle(), mpSQLiteBackup = sqlite3_backup_init(aDestDatabase.getHandle(),
"main", "main",
aSrcDatabase.getHandle(), aSrcDatabase.getHandle(),
"main"); "main");
if (NULL == mpSQLiteBackup) if (NULL == mpSQLiteBackup) {
{
// If an error occurs, the error code and message are attached to the destination database connection. // If an error occurs, the error code and message are attached to the destination database connection.
throw SQLite::Exception(aDestDatabase.getHandle()); throw SQLite::Exception(aDestDatabase.getHandle());
} }
} }
// Release resource for SQLite database backup // Release resource for SQLite database backup
Backup::~Backup() Backup::~Backup()
{ {
if (NULL != mpSQLiteBackup) if (NULL != mpSQLiteBackup) {
{
sqlite3_backup_finish(mpSQLiteBackup); sqlite3_backup_finish(mpSQLiteBackup);
} }
} }
// Execute backup step with a given number of source pages to be copied // Execute backup step with a given number of source pages to be copied
int Backup::executeStep(const int aNumPage /* = -1 */) int Backup::executeStep(const int aNumPage /* = -1 */)
{ {
const int res = sqlite3_backup_step(mpSQLiteBackup, aNumPage); const int res = sqlite3_backup_step(mpSQLiteBackup, aNumPage);
if (SQLITE_OK != res && SQLITE_DONE != res && SQLITE_BUSY != res && SQLITE_LOCKED != res) if (SQLITE_OK != res && SQLITE_DONE != res && SQLITE_BUSY != res && SQLITE_LOCKED != res) {
{
throw SQLite::Exception(sqlite3_errstr(res), res); throw SQLite::Exception(sqlite3_errstr(res), res);
} }
return res; return res;
} }
// Get the number of remaining source pages to be copied in this backup process // Get the number of remaining source pages to be copied in this backup process
int Backup::getRemainingPageCount() int Backup::getRemainingPageCount()
{ {
return sqlite3_backup_remaining(mpSQLiteBackup); return sqlite3_backup_remaining(mpSQLiteBackup);
} }
// Get the number of total source pages to be copied in this backup process // Get the number of total source pages to be copied in this backup process
int Backup::getTotalPageCount() int Backup::getTotalPageCount()
{ {
return sqlite3_backup_pagecount(mpSQLiteBackup); return sqlite3_backup_pagecount(mpSQLiteBackup);
} }
} // namespace SQLite
} // namespace SQLite

View File

@ -9,41 +9,33 @@
* or copy at http://opensource.org/licenses/MIT) * or copy at http://opensource.org/licenses/MIT)
*/ */
#include <SQLiteCpp/Column.h> #include <SQLiteCpp/Column.h>
#include <sqlite3.h> #include <sqlite3.h>
#include <iostream> #include <iostream>
namespace SQLite namespace SQLite
{ {
const int INTEGER = SQLITE_INTEGER;
const int INTEGER = SQLITE_INTEGER; const int FLOAT = SQLITE_FLOAT;
const int FLOAT = SQLITE_FLOAT; const int TEXT = SQLITE_TEXT;
const int TEXT = SQLITE_TEXT; const int BLOB = SQLITE_BLOB;
const int BLOB = SQLITE_BLOB; const int Null = SQLITE_NULL;
const int Null = SQLITE_NULL;
// Encapsulation of a Column in a row of the result pointed by the prepared Statement. // Encapsulation of a Column in a row of the result pointed by the prepared Statement.
Column::Column(Statement::Ptr& aStmtPtr, int aIndex) noexcept : // nothrow Column::Column(Statement::Ptr& aStmtPtr, int aIndex) noexcept
mStmtPtr(aStmtPtr), : // nothrow
mStmtPtr(aStmtPtr)
,
mIndex(aIndex) mIndex(aIndex)
{ {
} }
// Finalize and unregister the SQL query from the SQLite Database Connection. // Finalize and unregister the SQL query from the SQLite Database Connection.
Column::~Column() Column::~Column()
{ {
// the finalization will be done by the destructor of the last shared pointer // the finalization will be done by the destructor of the last shared pointer
} }
// Return the named assigned to this result column (potentially aliased) // Return the named assigned to this result column (potentially aliased)
const char* Column::getName() const noexcept // nothrow const char* Column::getName() const noexcept // nothrow
{ {
return sqlite3_column_name(mStmtPtr, mIndex); return sqlite3_column_name(mStmtPtr, mIndex);
} }
#ifdef SQLITE_ENABLE_COLUMN_METADATA #ifdef SQLITE_ENABLE_COLUMN_METADATA
// Return the name of the table column that is the origin of this result column // Return the name of the table column that is the origin of this result column
const char* Column::getOriginName() const noexcept // nothrow const char* Column::getOriginName() const noexcept // nothrow
@ -51,74 +43,61 @@ const char* Column::getOriginName() const noexcept // nothrow
return sqlite3_column_origin_name(mStmtPtr, mIndex); return sqlite3_column_origin_name(mStmtPtr, mIndex);
} }
#endif #endif
// Return the integer value of the column specified by its index starting at 0 // Return the integer value of the column specified by its index starting at 0
int Column::getInt() const noexcept // nothrow int Column::getInt() const noexcept // nothrow
{ {
return sqlite3_column_int(mStmtPtr, mIndex); return sqlite3_column_int(mStmtPtr, mIndex);
} }
// Return the unsigned integer value of the column specified by its index starting at 0 // Return the unsigned integer value of the column specified by its index starting at 0
unsigned Column::getUInt() const noexcept // nothrow unsigned Column::getUInt() const noexcept // nothrow
{ {
return static_cast<unsigned>(getInt64()); return static_cast<unsigned>(getInt64());
} }
// Return the 64bits integer value of the column specified by its index starting at 0 // Return the 64bits integer value of the column specified by its index starting at 0
long long Column::getInt64() const noexcept // nothrow long long Column::getInt64() const noexcept // nothrow
{ {
return sqlite3_column_int64(mStmtPtr, mIndex); return sqlite3_column_int64(mStmtPtr, mIndex);
} }
// Return the double value of the column specified by its index starting at 0 // Return the double value of the column specified by its index starting at 0
double Column::getDouble() const noexcept // nothrow double Column::getDouble() const noexcept // nothrow
{ {
return sqlite3_column_double(mStmtPtr, mIndex); return sqlite3_column_double(mStmtPtr, mIndex);
} }
// Return a pointer to the text value (NULL terminated string) of the column specified by its index starting at 0 // Return a pointer to the text value (NULL terminated string) of the column specified by its index starting at 0
const char* Column::getText(const char* apDefaultValue /* = "" */) const noexcept // nothrow const char* Column::getText(const char* apDefaultValue /* = "" */) const noexcept // nothrow
{ {
const char* pText = reinterpret_cast<const char*>(sqlite3_column_text(mStmtPtr, mIndex)); const char* pText = reinterpret_cast<const char*>(sqlite3_column_text(mStmtPtr, mIndex));
return (pText?pText:apDefaultValue); return (pText ? pText : apDefaultValue);
} }
// Return a pointer to the blob value (*not* NULL terminated) of the column specified by its index starting at 0 // Return a pointer to the blob value (*not* NULL terminated) of the column specified by its index starting at 0
const void* Column::getBlob() const noexcept // nothrow const void* Column::getBlob() const noexcept // nothrow
{ {
return sqlite3_column_blob(mStmtPtr, mIndex); return sqlite3_column_blob(mStmtPtr, mIndex);
} }
// Return a std::string to a TEXT or BLOB column // Return a std::string to a TEXT or BLOB column
std::string Column::getString() const std::string Column::getString() const
{ {
// Note: using sqlite3_column_blob and not sqlite3_column_text // Note: using sqlite3_column_blob and not sqlite3_column_text
// - no need for sqlite3_column_text to add a \0 on the end, as we're getting the bytes length directly // - no need for sqlite3_column_text to add a \0 on the end, as we're getting the bytes length directly
const char *data = static_cast<const char *>(sqlite3_column_blob(mStmtPtr, mIndex)); const char* data = static_cast<const char*>(sqlite3_column_blob(mStmtPtr, mIndex));
// SQLite docs: "The safest policy is to invoke… sqlite3_column_blob() followed by sqlite3_column_bytes()" // SQLite docs: "The safest policy is to invoke… sqlite3_column_blob() followed by sqlite3_column_bytes()"
// Note: std::string is ok to pass nullptr as first arg, if length is 0 // Note: std::string is ok to pass nullptr as first arg, if length is 0
return std::string(data, sqlite3_column_bytes(mStmtPtr, mIndex)); return std::string(data, sqlite3_column_bytes(mStmtPtr, mIndex));
} }
// Return the type of the value of the column // Return the type of the value of the column
int Column::getType() const noexcept // nothrow int Column::getType() const noexcept // nothrow
{ {
return sqlite3_column_type(mStmtPtr, mIndex); return sqlite3_column_type(mStmtPtr, mIndex);
} }
// Return the number of bytes used by the text value of the column // Return the number of bytes used by the text value of the column
int Column::getBytes() const noexcept // nothrow int Column::getBytes() const noexcept // nothrow
{ {
return sqlite3_column_bytes(mStmtPtr, mIndex); return sqlite3_column_bytes(mStmtPtr, mIndex);
} }
// Standard std::ostream inserter // Standard std::ostream inserter
std::ostream& operator<<(std::ostream& aStream, const Column& aColumn) std::ostream& operator<<(std::ostream& aStream, const Column& aColumn)
{ {
aStream.write(aColumn.getText(), aColumn.getBytes()); aStream.write(aColumn.getText(), aColumn.getBytes());
return aStream; return aStream;
} }
} // namespace SQLite
} // namespace SQLite

View File

@ -9,52 +9,42 @@
* or copy at http://opensource.org/licenses/MIT) * or copy at http://opensource.org/licenses/MIT)
*/ */
#include <SQLiteCpp/Database.h> #include <SQLiteCpp/Database.h>
#include <SQLiteCpp/Statement.h> #include <SQLiteCpp/Statement.h>
#include <SQLiteCpp/Assertion.h> #include <SQLiteCpp/Assertion.h>
#include <SQLiteCpp/Exception.h> #include <SQLiteCpp/Exception.h>
#include <sqlite3.h> #include <sqlite3.h>
#include <fstream> #include <fstream>
#include <string.h> #include <string.h>
#ifndef SQLITE_DETERMINISTIC #ifndef SQLITE_DETERMINISTIC
#define SQLITE_DETERMINISTIC 0x800 #define SQLITE_DETERMINISTIC 0x800
#endif // SQLITE_DETERMINISTIC #endif // SQLITE_DETERMINISTIC
namespace SQLite namespace SQLite
{ {
const int OPEN_READONLY = SQLITE_OPEN_READONLY;
const int OPEN_READONLY = SQLITE_OPEN_READONLY; const int OPEN_READWRITE = SQLITE_OPEN_READWRITE;
const int OPEN_READWRITE = SQLITE_OPEN_READWRITE; const int OPEN_CREATE = SQLITE_OPEN_CREATE;
const int OPEN_CREATE = SQLITE_OPEN_CREATE; const int OPEN_URI = SQLITE_OPEN_URI;
const int OPEN_URI = SQLITE_OPEN_URI; const int OK = SQLITE_OK;
const char* VERSION = SQLITE_VERSION;
const int OK = SQLITE_OK; const int VERSION_NUMBER = SQLITE_VERSION_NUMBER;
const char* VERSION = SQLITE_VERSION;
const int VERSION_NUMBER = SQLITE_VERSION_NUMBER;
// Return SQLite version string using runtime call to the compiled library // Return SQLite version string using runtime call to the compiled library
const char* getLibVersion() noexcept // nothrow const char* getLibVersion() noexcept // nothrow
{ {
return sqlite3_libversion(); return sqlite3_libversion();
} }
// Return SQLite version number using runtime call to the compiled library // Return SQLite version number using runtime call to the compiled library
int getLibVersionNumber() noexcept // nothrow int getLibVersionNumber() noexcept // nothrow
{ {
return sqlite3_libversion_number(); return sqlite3_libversion_number();
} }
// Open the provided database UTF-8 filename with SQLite::OPEN_xxx provided flags. // Open the provided database UTF-8 filename with SQLite::OPEN_xxx provided flags.
Database::Database(const char* apFilename, Database::Database(const char* apFilename,
const int aFlags /* = SQLite::OPEN_READONLY*/, const int aFlags /* = SQLite::OPEN_READONLY*/,
const int aBusyTimeoutMs /* = 0 */, const int aBusyTimeoutMs /* = 0 */,
const char* apVfs /* = nullptr*/) : const char* apVfs /* = nullptr*/)
mpSQLite(nullptr), :
mpSQLite(nullptr)
,
mFilename(apFilename) mFilename(apFilename)
{ {
const int ret = sqlite3_open_v2(apFilename, &mpSQLite, aFlags, apVfs); const int ret = sqlite3_open_v2(apFilename, &mpSQLite, aFlags, apVfs);
@ -69,13 +59,14 @@ Database::Database(const char* apFilename,
setBusyTimeout(aBusyTimeoutMs); setBusyTimeout(aBusyTimeoutMs);
} }
} }
// Open the provided database UTF-8 filename with SQLite::OPEN_xxx provided flags. // Open the provided database UTF-8 filename with SQLite::OPEN_xxx provided flags.
Database::Database(const std::string& aFilename, Database::Database(const std::string& aFilename,
const int aFlags /* = SQLite::OPEN_READONLY*/, const int aFlags /* = SQLite::OPEN_READONLY*/,
const int aBusyTimeoutMs /* = 0 */, const int aBusyTimeoutMs /* = 0 */,
const std::string& aVfs /* = "" */) : const std::string& aVfs /* = "" */)
mpSQLite(nullptr), :
mpSQLite(nullptr)
,
mFilename(aFilename) mFilename(aFilename)
{ {
const int ret = sqlite3_open_v2(aFilename.c_str(), &mpSQLite, aFlags, aVfs.empty() ? nullptr : aVfs.c_str()); const int ret = sqlite3_open_v2(aFilename.c_str(), &mpSQLite, aFlags, aVfs.empty() ? nullptr : aVfs.c_str());
@ -90,20 +81,16 @@ Database::Database(const std::string& aFilename,
setBusyTimeout(aBusyTimeoutMs); setBusyTimeout(aBusyTimeoutMs);
} }
} }
// Close the SQLite database connection. // Close the SQLite database connection.
Database::~Database() Database::~Database()
{ {
const int ret = sqlite3_close(mpSQLite); const int ret = sqlite3_close(mpSQLite);
// Avoid unreferenced variable warning when build in release mode // Avoid unreferenced variable warning when build in release mode
(void) ret; (void)ret;
// Only case of error is SQLITE_BUSY: "database is locked" (some statements are not finalized) // Only case of error is SQLITE_BUSY: "database is locked" (some statements are not finalized)
// Never throw an exception in a destructor : // Never throw an exception in a destructor :
SQLITECPP_ASSERT(SQLITE_OK == ret, "database is locked"); // See SQLITECPP_ENABLE_ASSERT_HANDLER SQLITECPP_ASSERT(SQLITE_OK == ret, "database is locked"); // See SQLITECPP_ENABLE_ASSERT_HANDLER
} }
/** /**
* @brief Set a busy handler that sleeps for a specified amount of time when a table is locked. * @brief Set a busy handler that sleeps for a specified amount of time when a table is locked.
* *
@ -122,17 +109,14 @@ void Database::setBusyTimeout(const int aBusyTimeoutMs)
const int ret = sqlite3_busy_timeout(mpSQLite, aBusyTimeoutMs); const int ret = sqlite3_busy_timeout(mpSQLite, aBusyTimeoutMs);
check(ret); check(ret);
} }
// Shortcut to execute one or multiple SQL statements without results (UPDATE, INSERT, ALTER, COMMIT, CREATE...). // Shortcut to execute one or multiple SQL statements without results (UPDATE, INSERT, ALTER, COMMIT, CREATE...).
int Database::exec(const char* apQueries) int Database::exec(const char* apQueries)
{ {
const int ret = sqlite3_exec(mpSQLite, apQueries, nullptr, nullptr, nullptr); const int ret = sqlite3_exec(mpSQLite, apQueries, nullptr, nullptr, nullptr);
check(ret); check(ret);
// Return the number of rows modified by those SQL statements (INSERT, UPDATE or DELETE only) // Return the number of rows modified by those SQL statements (INSERT, UPDATE or DELETE only)
return sqlite3_changes(mpSQLite); return sqlite3_changes(mpSQLite);
} }
// Shortcut to execute a one step query and fetch the first column of the result. // Shortcut to execute a one step query and fetch the first column of the result.
// WARNING: Be very careful with this dangerous method: you have to // WARNING: Be very careful with this dangerous method: you have to
// make a COPY OF THE result, else it will be destroy before the next line // make a COPY OF THE result, else it will be destroy before the next line
@ -145,7 +129,6 @@ Column Database::execAndGet(const char* apQuery)
(void)query.executeStep(); // Can return false if no result, which will throw next line in getColumn() (void)query.executeStep(); // Can return false if no result, which will throw next line in getColumn()
return query.getColumn(0); return query.getColumn(0);
} }
// Shortcut to test if a table exists. // Shortcut to test if a table exists.
bool Database::tableExists(const char* apTableName) bool Database::tableExists(const char* apTableName)
{ {
@ -154,68 +137,60 @@ bool Database::tableExists(const char* apTableName)
(void)query.executeStep(); // Cannot return false, as the above query always return a result (void)query.executeStep(); // Cannot return false, as the above query always return a result
return (1 == query.getColumn(0).getInt()); return (1 == query.getColumn(0).getInt());
} }
// Get the rowid of the most recent successful INSERT into the database from the current connection. // Get the rowid of the most recent successful INSERT into the database from the current connection.
long long Database::getLastInsertRowid() const noexcept // nothrow long long Database::getLastInsertRowid() const noexcept // nothrow
{ {
return sqlite3_last_insert_rowid(mpSQLite); return sqlite3_last_insert_rowid(mpSQLite);
} }
// Get total number of rows modified by all INSERT, UPDATE or DELETE statement since connection. // Get total number of rows modified by all INSERT, UPDATE or DELETE statement since connection.
int Database::getTotalChanges() const noexcept // nothrow int Database::getTotalChanges() const noexcept // nothrow
{ {
return sqlite3_total_changes(mpSQLite); return sqlite3_total_changes(mpSQLite);
} }
// Return the numeric result code for the most recent failed API call (if any). // Return the numeric result code for the most recent failed API call (if any).
int Database::getErrorCode() const noexcept // nothrow int Database::getErrorCode() const noexcept // nothrow
{ {
return sqlite3_errcode(mpSQLite); return sqlite3_errcode(mpSQLite);
} }
// Return the extended numeric result code for the most recent failed API call (if any). // Return the extended numeric result code for the most recent failed API call (if any).
int Database::getExtendedErrorCode() const noexcept // nothrow int Database::getExtendedErrorCode() const noexcept // nothrow
{ {
return sqlite3_extended_errcode(mpSQLite); return sqlite3_extended_errcode(mpSQLite);
} }
// Return UTF-8 encoded English language explanation of the most recent failed API call (if any). // Return UTF-8 encoded English language explanation of the most recent failed API call (if any).
const char* Database::getErrorMsg() const noexcept // nothrow const char* Database::getErrorMsg() const noexcept // nothrow
{ {
return sqlite3_errmsg(mpSQLite); return sqlite3_errmsg(mpSQLite);
} }
// Attach a custom function to your sqlite database. Assumes UTF8 text representation. // Attach a custom function to your sqlite database. Assumes UTF8 text representation.
// Parameter details can be found here: http://www.sqlite.org/c3ref/create_function.html // Parameter details can be found here: http://www.sqlite.org/c3ref/create_function.html
void Database::createFunction(const char* apFuncName, void Database::createFunction(const char* apFuncName,
int aNbArg, int aNbArg,
bool abDeterministic, bool abDeterministic,
void* apApp, void* apApp,
void (*apFunc)(sqlite3_context *, int, sqlite3_value **), void (*apFunc)(sqlite3_context*, int, sqlite3_value**),
void (*apStep)(sqlite3_context *, int, sqlite3_value **), void (*apStep)(sqlite3_context*, int, sqlite3_value**),
void (*apFinal)(sqlite3_context *), // NOLINT(readability/casting) void (*apFinal)(sqlite3_context*), // NOLINT(readability/casting)
void (*apDestroy)(void *)) void (*apDestroy)(void*))
{ {
int TextRep = SQLITE_UTF8; int TextRep = SQLITE_UTF8;
// optimization if deterministic function (e.g. of nondeterministic function random()) // optimization if deterministic function (e.g. of nondeterministic function random())
if (abDeterministic) if (abDeterministic)
{ {
TextRep = TextRep|SQLITE_DETERMINISTIC; TextRep = TextRep | SQLITE_DETERMINISTIC;
} }
const int ret = sqlite3_create_function_v2(mpSQLite, apFuncName, aNbArg, TextRep, const int ret = sqlite3_create_function_v2(mpSQLite, apFuncName, aNbArg, TextRep,
apApp, apFunc, apStep, apFinal, apDestroy); apApp, apFunc, apStep, apFinal, apDestroy);
check(ret); check(ret);
} }
// Load an extension into the sqlite database. Only affects the current connection. // Load an extension into the sqlite database. Only affects the current connection.
// Parameter details can be found here: http://www.sqlite.org/c3ref/load_extension.html // Parameter details can be found here: http://www.sqlite.org/c3ref/load_extension.html
void Database::loadExtension(const char* apExtensionName, const char *apEntryPointName) void Database::loadExtension(const char* apExtensionName, const char* apEntryPointName)
{ {
#ifdef SQLITE_OMIT_LOAD_EXTENSION #ifdef SQLITE_OMIT_LOAD_EXTENSION
// Unused // Unused
(void)apExtensionName; (void)apExtensionName;
(void)apEntryPointName; (void)apEntryPointName;
throw std::runtime_error("sqlite extensions are disabled"); throw std::runtime_error("sqlite extensions are disabled");
#else #else
#ifdef SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION // Since SQLite 3.13 (2016-05-18): #ifdef SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION // Since SQLite 3.13 (2016-05-18):
@ -229,12 +204,10 @@ void Database::loadExtension(const char* apExtensionName, const char *apEntryPoi
int ret = sqlite3_enable_load_extension(mpSQLite, 1); int ret = sqlite3_enable_load_extension(mpSQLite, 1);
#endif #endif
check(ret); check(ret);
ret = sqlite3_load_extension(mpSQLite, apExtensionName, apEntryPointName, 0); ret = sqlite3_load_extension(mpSQLite, apExtensionName, apEntryPointName, 0);
check(ret); check(ret);
#endif #endif
} }
// Set the key for the current sqlite database instance. // Set the key for the current sqlite database instance.
void Database::key(const std::string& aKey) const void Database::key(const std::string& aKey) const
{ {
@ -253,7 +226,6 @@ void Database::key(const std::string& aKey) const
} }
#endif // SQLITE_HAS_CODEC #endif // SQLITE_HAS_CODEC
} }
// Reset the key for the current sqlite database instance. // Reset the key for the current sqlite database instance.
void Database::rekey(const std::string& aNewKey) const void Database::rekey(const std::string& aNewKey) const
{ {
@ -275,7 +247,6 @@ void Database::rekey(const std::string& aNewKey) const
throw exception; throw exception;
#endif // SQLITE_HAS_CODEC #endif // SQLITE_HAS_CODEC
} }
// Test if a file contains an unencrypted database. // Test if a file contains an unencrypted database.
bool Database::isUnencrypted(const std::string& aFilename) bool Database::isUnencrypted(const std::string& aFilename)
{ {
@ -299,5 +270,4 @@ bool Database::isUnencrypted(const std::string& aFilename)
const SQLite::Exception exception("Could not open database, the aFilename parameter was empty."); const SQLite::Exception exception("Could not open database, the aFilename parameter was empty.");
throw exception; throw exception;
} }
} // namespace SQLite
} // namespace SQLite

View File

@ -9,59 +9,66 @@
* or copy at http://opensource.org/licenses/MIT) * or copy at http://opensource.org/licenses/MIT)
*/ */
#include <SQLiteCpp/Exception.h> #include <SQLiteCpp/Exception.h>
#include <sqlite3.h> #include <sqlite3.h>
namespace SQLite namespace SQLite
{ {
Exception::Exception(const char* aErrorMessage)
Exception::Exception(const char* aErrorMessage) : :
std::runtime_error(aErrorMessage), std::runtime_error(aErrorMessage)
mErrcode(-1), // 0 would be SQLITE_OK, which doesn't make sense ,
mErrcode(-1)
, // 0 would be SQLITE_OK, which doesn't make sense
mExtendedErrcode(-1) mExtendedErrcode(-1)
{ {
} }
Exception::Exception(const std::string& aErrorMessage) : Exception::Exception(const std::string& aErrorMessage)
std::runtime_error(aErrorMessage), :
mErrcode(-1), // 0 would be SQLITE_OK, which doesn't make sense std::runtime_error(aErrorMessage)
,
mErrcode(-1)
, // 0 would be SQLITE_OK, which doesn't make sense
mExtendedErrcode(-1) mExtendedErrcode(-1)
{ {
} }
Exception::Exception(const char* aErrorMessage, int ret)
Exception::Exception(const char* aErrorMessage, int ret) : :
std::runtime_error(aErrorMessage), std::runtime_error(aErrorMessage)
mErrcode(ret), ,
mErrcode(ret)
,
mExtendedErrcode(-1) mExtendedErrcode(-1)
{ {
} }
Exception::Exception(const std::string& aErrorMessage, int ret)
Exception::Exception(const std::string& aErrorMessage, int ret) : :
std::runtime_error(aErrorMessage), std::runtime_error(aErrorMessage)
mErrcode(ret), ,
mErrcode(ret)
,
mExtendedErrcode(-1) mExtendedErrcode(-1)
{ {
} }
Exception::Exception(sqlite3* apSQLite)
Exception::Exception(sqlite3* apSQLite) : :
std::runtime_error(sqlite3_errmsg(apSQLite)), std::runtime_error(sqlite3_errmsg(apSQLite))
mErrcode(sqlite3_errcode(apSQLite)), ,
mErrcode(sqlite3_errcode(apSQLite))
,
mExtendedErrcode(sqlite3_extended_errcode(apSQLite)) mExtendedErrcode(sqlite3_extended_errcode(apSQLite))
{ {
} }
Exception::Exception(sqlite3* apSQLite, int ret)
Exception::Exception(sqlite3* apSQLite, int ret) : :
std::runtime_error(sqlite3_errmsg(apSQLite)), std::runtime_error(sqlite3_errmsg(apSQLite))
mErrcode(ret), ,
mErrcode(ret)
,
mExtendedErrcode(sqlite3_extended_errcode(apSQLite)) mExtendedErrcode(sqlite3_extended_errcode(apSQLite))
{ {
} }
// Return a string, solely based on the error code // Return a string, solely based on the error code
const char* Exception::getErrorStr() const noexcept // nothrow const char* Exception::getErrorStr() const noexcept // nothrow
{ {
return sqlite3_errstr(mErrcode); return sqlite3_errstr(mErrcode);
} }
} // namespace SQLite
} // namespace SQLite

View File

@ -9,45 +9,54 @@
* or copy at http://opensource.org/licenses/MIT) * or copy at http://opensource.org/licenses/MIT)
*/ */
#include <SQLiteCpp/Statement.h> #include <SQLiteCpp/Statement.h>
#include <SQLiteCpp/Database.h> #include <SQLiteCpp/Database.h>
#include <SQLiteCpp/Column.h> #include <SQLiteCpp/Column.h>
#include <SQLiteCpp/Assertion.h> #include <SQLiteCpp/Assertion.h>
#include <SQLiteCpp/Exception.h> #include <SQLiteCpp/Exception.h>
#include <sqlite3.h> #include <sqlite3.h>
namespace SQLite namespace SQLite
{ {
// Compile and register the SQL query for the provided SQLite Database Connection // Compile and register the SQL query for the provided SQLite Database Connection
Statement::Statement(Database &aDatabase, const char* apQuery) : Statement::Statement(Database& aDatabase, const char* apQuery)
mQuery(apQuery), :
mStmtPtr(aDatabase.mpSQLite, mQuery), // prepare the SQL query, and ref count (needs Database friendship) mQuery(apQuery)
mColumnCount(0), ,
mbHasRow(false), mStmtPtr(aDatabase.mpSQLite, mQuery)
, // prepare the SQL query, and ref count (needs Database friendship)
mColumnCount(0)
,
mbHasRow(false)
,
mbDone(false) mbDone(false)
{ {
mColumnCount = sqlite3_column_count(mStmtPtr); mColumnCount = sqlite3_column_count(mStmtPtr);
} }
// Compile and register the SQL query for the provided SQLite Database Connection // Compile and register the SQL query for the provided SQLite Database Connection
Statement::Statement(Database &aDatabase, const std::string& aQuery) : Statement::Statement(Database& aDatabase, const std::string& aQuery)
mQuery(aQuery), :
mStmtPtr(aDatabase.mpSQLite, mQuery), // prepare the SQL query, and ref count (needs Database friendship) mQuery(aQuery)
mColumnCount(0), ,
mbHasRow(false), mStmtPtr(aDatabase.mpSQLite, mQuery)
, // prepare the SQL query, and ref count (needs Database friendship)
mColumnCount(0)
,
mbHasRow(false)
,
mbDone(false) mbDone(false)
{ {
mColumnCount = sqlite3_column_count(mStmtPtr); mColumnCount = sqlite3_column_count(mStmtPtr);
} }
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600) #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)
Statement::Statement(Statement&& aStatement) noexcept : Statement::Statement(Statement&& aStatement) noexcept
mQuery(std::move(aStatement.mQuery)), :
mStmtPtr(std::move(aStatement.mStmtPtr)), mQuery(std::move(aStatement.mQuery))
mColumnCount(aStatement.mColumnCount), ,
mbHasRow(aStatement.mbHasRow), mStmtPtr(std::move(aStatement.mStmtPtr))
,
mColumnCount(aStatement.mColumnCount)
,
mbHasRow(aStatement.mbHasRow)
,
mbDone(aStatement.mbDone) mbDone(aStatement.mbDone)
{ {
aStatement.mColumnCount = 0; aStatement.mColumnCount = 0;
@ -55,114 +64,97 @@ Statement::Statement(Statement&& aStatement) noexcept :
aStatement.mbDone = false; aStatement.mbDone = false;
} }
#endif #endif
// Finalize and unregister the SQL query from the SQLite Database Connection. // Finalize and unregister the SQL query from the SQLite Database Connection.
Statement::~Statement() Statement::~Statement()
{ {
// the finalization will be done by the destructor of the last shared pointer // the finalization will be done by the destructor of the last shared pointer
} }
// Reset the statement to make it ready for a new execution (see also #clearBindings() bellow) // Reset the statement to make it ready for a new execution (see also #clearBindings() bellow)
void Statement::reset() void Statement::reset()
{ {
const int ret = tryReset(); const int ret = tryReset();
check(ret); check(ret);
} }
int Statement::tryReset() noexcept int Statement::tryReset() noexcept
{ {
mbHasRow = false; mbHasRow = false;
mbDone = false; mbDone = false;
return sqlite3_reset(mStmtPtr); return sqlite3_reset(mStmtPtr);
} }
// Clears away all the bindings of a prepared statement (can be associated with #reset() above). // Clears away all the bindings of a prepared statement (can be associated with #reset() above).
void Statement::clearBindings() void Statement::clearBindings()
{ {
const int ret = sqlite3_clear_bindings(mStmtPtr); const int ret = sqlite3_clear_bindings(mStmtPtr);
check(ret); check(ret);
} }
// Bind an int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind an int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const int aIndex, const int aValue) void Statement::bind(const int aIndex, const int aValue)
{ {
const int ret = sqlite3_bind_int(mStmtPtr, aIndex, aValue); const int ret = sqlite3_bind_int(mStmtPtr, aIndex, aValue);
check(ret); check(ret);
} }
// Bind a 32bits unsigned int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind a 32bits unsigned int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const int aIndex, const unsigned aValue) void Statement::bind(const int aIndex, const unsigned aValue)
{ {
const int ret = sqlite3_bind_int64(mStmtPtr, aIndex, aValue); const int ret = sqlite3_bind_int64(mStmtPtr, aIndex, aValue);
check(ret); check(ret);
} }
// Bind a 64bits int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind a 64bits int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const int aIndex, const long long aValue) void Statement::bind(const int aIndex, const long long aValue)
{ {
const int ret = sqlite3_bind_int64(mStmtPtr, aIndex, aValue); const int ret = sqlite3_bind_int64(mStmtPtr, aIndex, aValue);
check(ret); check(ret);
} }
// Bind a double (64bits float) value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind a double (64bits float) value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const int aIndex, const double aValue) void Statement::bind(const int aIndex, const double aValue)
{ {
const int ret = sqlite3_bind_double(mStmtPtr, aIndex, aValue); const int ret = sqlite3_bind_double(mStmtPtr, aIndex, aValue);
check(ret); check(ret);
} }
// Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const int aIndex, const std::string& aValue) void Statement::bind(const int aIndex, const std::string& aValue)
{ {
const int ret = sqlite3_bind_text(mStmtPtr, aIndex, aValue.c_str(), const int ret = sqlite3_bind_text(mStmtPtr, aIndex, aValue.c_str(),
static_cast<int>(aValue.size()), SQLITE_TRANSIENT); static_cast<int>(aValue.size()), SQLITE_TRANSIENT);
check(ret); check(ret);
} }
// Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const int aIndex, const char* apValue) void Statement::bind(const int aIndex, const char* apValue)
{ {
const int ret = sqlite3_bind_text(mStmtPtr, aIndex, apValue, -1, SQLITE_TRANSIENT); const int ret = sqlite3_bind_text(mStmtPtr, aIndex, apValue, -1, SQLITE_TRANSIENT);
check(ret); check(ret);
} }
// Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const int aIndex, const void* apValue, const int aSize) void Statement::bind(const int aIndex, const void* apValue, const int aSize)
{ {
const int ret = sqlite3_bind_blob(mStmtPtr, aIndex, apValue, aSize, SQLITE_TRANSIENT); const int ret = sqlite3_bind_blob(mStmtPtr, aIndex, apValue, aSize, SQLITE_TRANSIENT);
check(ret); check(ret);
} }
// Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bindNoCopy(const int aIndex, const std::string& aValue) void Statement::bindNoCopy(const int aIndex, const std::string& aValue)
{ {
const int ret = sqlite3_bind_text(mStmtPtr, aIndex, aValue.c_str(), const int ret = sqlite3_bind_text(mStmtPtr, aIndex, aValue.c_str(),
static_cast<int>(aValue.size()), SQLITE_STATIC); static_cast<int>(aValue.size()), SQLITE_STATIC);
check(ret); check(ret);
} }
// Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bindNoCopy(const int aIndex, const char* apValue) void Statement::bindNoCopy(const int aIndex, const char* apValue)
{ {
const int ret = sqlite3_bind_text(mStmtPtr, aIndex, apValue, -1, SQLITE_STATIC); const int ret = sqlite3_bind_text(mStmtPtr, aIndex, apValue, -1, SQLITE_STATIC);
check(ret); check(ret);
} }
// Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bindNoCopy(const int aIndex, const void* apValue, const int aSize) void Statement::bindNoCopy(const int aIndex, const void* apValue, const int aSize)
{ {
const int ret = sqlite3_bind_blob(mStmtPtr, aIndex, apValue, aSize, SQLITE_STATIC); const int ret = sqlite3_bind_blob(mStmtPtr, aIndex, apValue, aSize, SQLITE_STATIC);
check(ret); check(ret);
} }
// Bind a NULL value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind a NULL value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const int aIndex) void Statement::bind(const int aIndex)
{ {
const int ret = sqlite3_bind_null(mStmtPtr, aIndex); const int ret = sqlite3_bind_null(mStmtPtr, aIndex);
check(ret); check(ret);
} }
// Bind an int value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind an int value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const char* apName, const int aValue) void Statement::bind(const char* apName, const int aValue)
{ {
@ -170,7 +162,6 @@ void Statement::bind(const char* apName, const int aValue)
const int ret = sqlite3_bind_int(mStmtPtr, index, aValue); const int ret = sqlite3_bind_int(mStmtPtr, index, aValue);
check(ret); check(ret);
} }
// Bind a 32bits unsigned int value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind a 32bits unsigned int value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const char* apName, const unsigned aValue) void Statement::bind(const char* apName, const unsigned aValue)
{ {
@ -178,7 +169,6 @@ void Statement::bind(const char* apName, const unsigned aValue)
const int ret = sqlite3_bind_int64(mStmtPtr, index, aValue); const int ret = sqlite3_bind_int64(mStmtPtr, index, aValue);
check(ret); check(ret);
} }
// Bind a 64bits int value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind a 64bits int value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const char* apName, const long long aValue) void Statement::bind(const char* apName, const long long aValue)
{ {
@ -186,7 +176,6 @@ void Statement::bind(const char* apName, const long long aValue)
const int ret = sqlite3_bind_int64(mStmtPtr, index, aValue); const int ret = sqlite3_bind_int64(mStmtPtr, index, aValue);
check(ret); check(ret);
} }
// Bind a double (64bits float) value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind a double (64bits float) value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const char* apName, const double aValue) void Statement::bind(const char* apName, const double aValue)
{ {
@ -194,16 +183,14 @@ void Statement::bind(const char* apName, const double aValue)
const int ret = sqlite3_bind_double(mStmtPtr, index, aValue); const int ret = sqlite3_bind_double(mStmtPtr, index, aValue);
check(ret); check(ret);
} }
// Bind a string value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind a string value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const char* apName, const std::string& aValue) void Statement::bind(const char* apName, const std::string& aValue)
{ {
const int index = sqlite3_bind_parameter_index(mStmtPtr, apName); const int index = sqlite3_bind_parameter_index(mStmtPtr, apName);
const int ret = sqlite3_bind_text(mStmtPtr, index, aValue.c_str(), const int ret = sqlite3_bind_text(mStmtPtr, index, aValue.c_str(),
static_cast<int>(aValue.size()), SQLITE_TRANSIENT); static_cast<int>(aValue.size()), SQLITE_TRANSIENT);
check(ret); check(ret);
} }
// Bind a text value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind a text value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const char* apName, const char* apValue) void Statement::bind(const char* apName, const char* apValue)
{ {
@ -211,7 +198,6 @@ void Statement::bind(const char* apName, const char* apValue)
const int ret = sqlite3_bind_text(mStmtPtr, index, apValue, -1, SQLITE_TRANSIENT); const int ret = sqlite3_bind_text(mStmtPtr, index, apValue, -1, SQLITE_TRANSIENT);
check(ret); check(ret);
} }
// Bind a binary blob value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind a binary blob value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const char* apName, const void* apValue, const int aSize) void Statement::bind(const char* apName, const void* apValue, const int aSize)
{ {
@ -219,16 +205,14 @@ void Statement::bind(const char* apName, const void* apValue, const int aSize)
const int ret = sqlite3_bind_blob(mStmtPtr, index, apValue, aSize, SQLITE_TRANSIENT); const int ret = sqlite3_bind_blob(mStmtPtr, index, apValue, aSize, SQLITE_TRANSIENT);
check(ret); check(ret);
} }
// Bind a string value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind a string value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bindNoCopy(const char* apName, const std::string& aValue) void Statement::bindNoCopy(const char* apName, const std::string& aValue)
{ {
const int index = sqlite3_bind_parameter_index(mStmtPtr, apName); const int index = sqlite3_bind_parameter_index(mStmtPtr, apName);
const int ret = sqlite3_bind_text(mStmtPtr, index, aValue.c_str(), const int ret = sqlite3_bind_text(mStmtPtr, index, aValue.c_str(),
static_cast<int>(aValue.size()), SQLITE_STATIC); static_cast<int>(aValue.size()), SQLITE_STATIC);
check(ret); check(ret);
} }
// Bind a text value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind a text value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bindNoCopy(const char* apName, const char* apValue) void Statement::bindNoCopy(const char* apName, const char* apValue)
{ {
@ -236,7 +220,6 @@ void Statement::bindNoCopy(const char* apName, const char* apValue)
const int ret = sqlite3_bind_text(mStmtPtr, index, apValue, -1, SQLITE_STATIC); const int ret = sqlite3_bind_text(mStmtPtr, index, apValue, -1, SQLITE_STATIC);
check(ret); check(ret);
} }
// Bind a binary blob value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind a binary blob value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bindNoCopy(const char* apName, const void* apValue, const int aSize) void Statement::bindNoCopy(const char* apName, const void* apValue, const int aSize)
{ {
@ -244,7 +227,6 @@ void Statement::bindNoCopy(const char* apName, const void* apValue, const int aS
const int ret = sqlite3_bind_blob(mStmtPtr, index, apValue, aSize, SQLITE_STATIC); const int ret = sqlite3_bind_blob(mStmtPtr, index, apValue, aSize, SQLITE_STATIC);
check(ret); check(ret);
} }
// Bind a NULL value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind a NULL value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const char* apName) void Statement::bind(const char* apName)
{ {
@ -252,8 +234,6 @@ void Statement::bind(const char* apName)
const int ret = sqlite3_bind_null(mStmtPtr, index); const int ret = sqlite3_bind_null(mStmtPtr, index);
check(ret); check(ret);
} }
// Execute a step of the query to fetch one row of results // Execute a step of the query to fetch one row of results
bool Statement::executeStep() bool Statement::executeStep()
{ {
@ -269,10 +249,8 @@ bool Statement::executeStep()
throw SQLite::Exception("Statement needs to be reseted", ret); throw SQLite::Exception("Statement needs to be reseted", ret);
} }
} }
return mbHasRow; // true only if one row is accessible by getColumn(N) return mbHasRow; // true only if one row is accessible by getColumn(N)
} }
// Execute a one-step query with no expected result // Execute a one-step query with no expected result
int Statement::exec() int Statement::exec()
{ {
@ -292,11 +270,9 @@ int Statement::exec()
throw SQLite::Exception("Statement needs to be reseted", ret); throw SQLite::Exception("Statement needs to be reseted", ret);
} }
} }
// Return the number of rows modified by those SQL statements (INSERT, UPDATE or DELETE) // Return the number of rows modified by those SQL statements (INSERT, UPDATE or DELETE)
return sqlite3_changes(mStmtPtr); return sqlite3_changes(mStmtPtr);
} }
int Statement::tryExecuteStep() noexcept int Statement::tryExecuteStep() noexcept
{ {
if (false == mbDone) if (false == mbDone)
@ -316,7 +292,6 @@ int Statement::tryExecuteStep() noexcept
mbHasRow = false; mbHasRow = false;
mbDone = false; mbDone = false;
} }
return ret; return ret;
} }
else else
@ -325,30 +300,24 @@ int Statement::tryExecuteStep() noexcept
return SQLITE_MISUSE; return SQLITE_MISUSE;
} }
} }
// Return a copy of the column data specified by its index starting at 0 // Return a copy of the column data specified by its index starting at 0
// (use the Column copy-constructor) // (use the Column copy-constructor)
Column Statement::getColumn(const int aIndex) Column Statement::getColumn(const int aIndex)
{ {
checkRow(); checkRow();
checkIndex(aIndex); checkIndex(aIndex);
// Share the Statement Object handle with the new Column created // Share the Statement Object handle with the new Column created
return Column(mStmtPtr, aIndex); return Column(mStmtPtr, aIndex);
} }
// Return a copy of the column data specified by its column name starting at 0 // Return a copy of the column data specified by its column name starting at 0
// (use the Column copy-constructor) // (use the Column copy-constructor)
Column Statement::getColumn(const char* apName) Column Statement::getColumn(const char* apName)
{ {
checkRow(); checkRow();
const int index = getColumnIndex(apName); const int index = getColumnIndex(apName);
// Share the Statement Object handle with the new Column created // Share the Statement Object handle with the new Column created
return Column(mStmtPtr, index); return Column(mStmtPtr, index);
} }
// Test if the column is NULL // Test if the column is NULL
bool Statement::isColumnNull(const int aIndex) const bool Statement::isColumnNull(const int aIndex) const
{ {
@ -356,21 +325,18 @@ bool Statement::isColumnNull(const int aIndex) const
checkIndex(aIndex); checkIndex(aIndex);
return (SQLITE_NULL == sqlite3_column_type(mStmtPtr, aIndex)); return (SQLITE_NULL == sqlite3_column_type(mStmtPtr, aIndex));
} }
bool Statement::isColumnNull(const char* apName) const bool Statement::isColumnNull(const char* apName) const
{ {
checkRow(); checkRow();
const int index = getColumnIndex(apName); const int index = getColumnIndex(apName);
return (SQLITE_NULL == sqlite3_column_type(mStmtPtr, index)); return (SQLITE_NULL == sqlite3_column_type(mStmtPtr, index));
} }
// Return the named assigned to the specified result column (potentially aliased) // Return the named assigned to the specified result column (potentially aliased)
const char* Statement::getColumnName(const int aIndex) const const char* Statement::getColumnName(const int aIndex) const
{ {
checkIndex(aIndex); checkIndex(aIndex);
return sqlite3_column_name(mStmtPtr, aIndex); return sqlite3_column_name(mStmtPtr, aIndex);
} }
#ifdef SQLITE_ENABLE_COLUMN_METADATA #ifdef SQLITE_ENABLE_COLUMN_METADATA
// Return the named assigned to the specified result column (potentially aliased) // Return the named assigned to the specified result column (potentially aliased)
const char* Statement::getColumnOriginName(const int aIndex) const const char* Statement::getColumnOriginName(const int aIndex) const
@ -379,7 +345,6 @@ const char* Statement::getColumnOriginName(const int aIndex) const
return sqlite3_column_origin_name(mStmtPtr, aIndex); return sqlite3_column_origin_name(mStmtPtr, aIndex);
} }
#endif #endif
// Return the index of the specified (potentially aliased) column name // Return the index of the specified (potentially aliased) column name
int Statement::getColumnIndex(const char* apName) const int Statement::getColumnIndex(const char* apName) const
{ {
@ -392,60 +357,55 @@ int Statement::getColumnIndex(const char* apName) const
mColumnNames[pName] = i; mColumnNames[pName] = i;
} }
} }
const TColumnNames::const_iterator iIndex = mColumnNames.find(apName); const TColumnNames::const_iterator iIndex = mColumnNames.find(apName);
if (iIndex == mColumnNames.end()) if (iIndex == mColumnNames.end())
{ {
throw SQLite::Exception("Unknown column name."); throw SQLite::Exception("Unknown column name.");
} }
return (*iIndex).second; return (*iIndex).second;
} }
int Statement::getBindParameterCount() const noexcept int Statement::getBindParameterCount() const noexcept
{ {
return sqlite3_bind_parameter_count(mStmtPtr); return sqlite3_bind_parameter_count(mStmtPtr);
} }
// Return the numeric result code for the most recent failed API call (if any). // Return the numeric result code for the most recent failed API call (if any).
int Statement::getErrorCode() const noexcept // nothrow int Statement::getErrorCode() const noexcept // nothrow
{ {
return sqlite3_errcode(mStmtPtr); return sqlite3_errcode(mStmtPtr);
} }
// Return the extended numeric result code for the most recent failed API call (if any). // Return the extended numeric result code for the most recent failed API call (if any).
int Statement::getExtendedErrorCode() const noexcept // nothrow int Statement::getExtendedErrorCode() const noexcept // nothrow
{ {
return sqlite3_extended_errcode(mStmtPtr); return sqlite3_extended_errcode(mStmtPtr);
} }
// Return UTF-8 encoded English language explanation of the most recent failed API call (if any). // Return UTF-8 encoded English language explanation of the most recent failed API call (if any).
const char* Statement::getErrorMsg() const noexcept // nothrow const char* Statement::getErrorMsg() const noexcept // nothrow
{ {
return sqlite3_errmsg(mStmtPtr); return sqlite3_errmsg(mStmtPtr);
} }
// Return a UTF-8 string containing the SQL text of prepared statement with bound parameters expanded. // Return a UTF-8 string containing the SQL text of prepared statement with bound parameters expanded.
std::string Statement::getExpandedSQL() { std::string Statement::getExpandedSQL()
{
char* expanded = sqlite3_expanded_sql(mStmtPtr); char* expanded = sqlite3_expanded_sql(mStmtPtr);
std::string expandedString(expanded); std::string expandedString(expanded);
sqlite3_free(expanded); sqlite3_free(expanded);
return expandedString; return expandedString;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Internal class : shared pointer to the sqlite3_stmt SQLite Statement Object // Internal class : shared pointer to the sqlite3_stmt SQLite Statement Object
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/** /**
* @brief Prepare the statement and initialize its reference counter * @brief Prepare the statement and initialize its reference counter
* *
* @param[in] apSQLite The sqlite3 database connexion * @param[in] apSQLite The sqlite3 database connexion
* @param[in] aQuery The SQL query string to prepare * @param[in] aQuery The SQL query string to prepare
*/ */
Statement::Ptr::Ptr(sqlite3* apSQLite, std::string& aQuery) : Statement::Ptr::Ptr(sqlite3* apSQLite, std::string& aQuery)
mpSQLite(apSQLite), :
mpStmt(NULL), mpSQLite(apSQLite)
,
mpStmt(NULL)
,
mpRefCount(NULL) mpRefCount(NULL)
{ {
const int ret = sqlite3_prepare_v2(apSQLite, aQuery.c_str(), static_cast<int>(aQuery.size()), &mpStmt, NULL); const int ret = sqlite3_prepare_v2(apSQLite, aQuery.c_str(), static_cast<int>(aQuery.size()), &mpStmt, NULL);
@ -456,31 +416,34 @@ Statement::Ptr::Ptr(sqlite3* apSQLite, std::string& aQuery) :
// Initialize the reference counter of the sqlite3_stmt : // Initialize the reference counter of the sqlite3_stmt :
// used to share the mStmtPtr between Statement and Column objects; // used to share the mStmtPtr between Statement and Column objects;
// This is needed to enable Column objects to live longer than the Statement objet it refers to. // This is needed to enable Column objects to live longer than the Statement objet it refers to.
mpRefCount = new unsigned int(1); // NOLINT(readability/casting) mpRefCount = new unsigned int(1); // NOLINT(readability/casting)
} }
/** /**
* @brief Copy constructor increments the ref counter * @brief Copy constructor increments the ref counter
* *
* @param[in] aPtr Pointer to copy * @param[in] aPtr Pointer to copy
*/ */
Statement::Ptr::Ptr(const Statement::Ptr& aPtr) : Statement::Ptr::Ptr(const Statement::Ptr& aPtr)
mpSQLite(aPtr.mpSQLite), :
mpStmt(aPtr.mpStmt), mpSQLite(aPtr.mpSQLite)
,
mpStmt(aPtr.mpStmt)
,
mpRefCount(aPtr.mpRefCount) mpRefCount(aPtr.mpRefCount)
{ {
assert(NULL != mpRefCount); assert(NULL != mpRefCount);
assert(0 != *mpRefCount); assert(0 != *mpRefCount);
// Increment the reference counter of the sqlite3_stmt, // Increment the reference counter of the sqlite3_stmt,
// asking not to finalize the sqlite3_stmt during the lifetime of the new objet // asking not to finalize the sqlite3_stmt during the lifetime of the new objet
++(*mpRefCount); ++(*mpRefCount);
} }
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600) #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)
Statement::Ptr::Ptr(Ptr&& aPtr) : Statement::Ptr::Ptr(Ptr&& aPtr)
mpSQLite(aPtr.mpSQLite), :
mpStmt(aPtr.mpStmt), mpSQLite(aPtr.mpSQLite)
,
mpStmt(aPtr.mpStmt)
,
mpRefCount(aPtr.mpRefCount) mpRefCount(aPtr.mpRefCount)
{ {
aPtr.mpSQLite = NULL; aPtr.mpSQLite = NULL;
@ -488,7 +451,6 @@ Statement::Ptr::Ptr(Ptr&& aPtr) :
aPtr.mpRefCount = NULL; aPtr.mpRefCount = NULL;
} }
#endif #endif
/** /**
* @brief Decrement the ref counter and finalize the sqlite3_stmt when it reaches 0 * @brief Decrement the ref counter and finalize the sqlite3_stmt when it reaches 0
*/ */
@ -497,7 +459,6 @@ Statement::Ptr::~Ptr()
if (NULL != mpRefCount) if (NULL != mpRefCount)
{ {
assert(0 != *mpRefCount); assert(0 != *mpRefCount);
// Decrement and check the reference counter of the sqlite3_stmt // Decrement and check the reference counter of the sqlite3_stmt
--(*mpRefCount); --(*mpRefCount);
if (0 == *mpRefCount) if (0 == *mpRefCount)
@ -505,7 +466,6 @@ Statement::Ptr::~Ptr()
// If count reaches zero, finalize the sqlite3_stmt, as no Statement nor Column objet use it anymore. // If count reaches zero, finalize the sqlite3_stmt, as no Statement nor Column objet use it anymore.
// No need to check the return code, as it is the same as the last statement evaluation. // No need to check the return code, as it is the same as the last statement evaluation.
sqlite3_finalize(mpStmt); sqlite3_finalize(mpStmt);
// and delete the reference counter // and delete the reference counter
delete mpRefCount; delete mpRefCount;
mpRefCount = NULL; mpRefCount = NULL;
@ -514,6 +474,4 @@ Statement::Ptr::~Ptr()
// else, the finalization will be done later, by the last object // else, the finalization will be done later, by the last object
} }
} }
} // namespace SQLite
} // namespace SQLite

View File

@ -9,23 +9,19 @@
* or copy at http://opensource.org/licenses/MIT) * or copy at http://opensource.org/licenses/MIT)
*/ */
#include <SQLiteCpp/Transaction.h> #include <SQLiteCpp/Transaction.h>
#include <SQLiteCpp/Database.h> #include <SQLiteCpp/Database.h>
#include <SQLiteCpp/Assertion.h> #include <SQLiteCpp/Assertion.h>
namespace SQLite namespace SQLite
{ {
// Begins the SQLite transaction // Begins the SQLite transaction
Transaction::Transaction(Database& aDatabase) : Transaction::Transaction(Database& aDatabase)
mDatabase(aDatabase), :
mDatabase(aDatabase)
,
mbCommited(false) mbCommited(false)
{ {
mDatabase.exec("BEGIN"); mDatabase.exec("BEGIN");
} }
// Safely rollback the transaction if it has not been committed. // Safely rollback the transaction if it has not been committed.
Transaction::~Transaction() Transaction::~Transaction()
{ {
@ -41,7 +37,6 @@ Transaction::~Transaction()
} }
} }
} }
// Commit the transaction. // Commit the transaction.
void Transaction::commit() void Transaction::commit()
{ {
@ -55,6 +50,4 @@ void Transaction::commit()
throw SQLite::Exception("Transaction already commited."); throw SQLite::Exception("Transaction already commited.");
} }
} }
} // namespace SQLite
} // namespace SQLite