Start a new 3.x branch requiring C++11 and CMake 3.1

- Remove support for Visual Studio < 2015
- Remove Statement::isOk() deprecated in 2.2.0 and renamed to Statement::hasRow()
This commit is contained in:
Sébastien Rombauts 2019-12-26 18:47:06 +01:00
parent 8e0bd6b3fe
commit da4d692c13
20 changed files with 341 additions and 532 deletions

View File

@ -1,157 +1,164 @@
Mar 30 2012 Mar 30 2012
- Start of a new thin C++ SQLite wrapper - Start of a new thin C++ SQLite wrapper
Apr 2 2012 Apr 2 2012
- The wrapper is functionnal - The wrapper is functionnal
- Added documentation and examples - Added documentation and examples
- Publication on GitHub - Publication on GitHub
Version 0.1.0 - Apr 4 2012 Version 0.1.0 - Apr 4 2012
- Added a Database::exec() methode to execute simple SQL statement - Added a Database::exec() methode to execute simple SQL statement
- Added a version number like in sqlite3.h, starting with 0.1.0 - Added a version number like in sqlite3.h, starting with 0.1.0
Version 0.2.0 - Apr 11 2012 Version 0.2.0 - Apr 11 2012
- Added getLastInsertId() and setBusyTimout() - Added getLastInsertId() and setBusyTimout()
- Added bind() by name methods - Added bind() by name methods
Version 0.3.0 - Apr 16 2012 Version 0.3.0 - Apr 16 2012
- Added an easy wrapper Database::execAngGet() - Added an easy wrapper Database::execAngGet()
Version 0.4.0 - Apr 23 2012 Version 0.4.0 - Apr 23 2012
- Added a Database::tableExists() easy to use function - Added a Database::tableExists() easy to use function
Dec 10 2012 Dec 10 2012
- Added a Statement::exec() method to execute a one-step query with no expected result - Added a Statement::exec() method to execute a one-step query with no expected result
Version 0.5.0 - March 9 2013 Version 0.5.0 - March 9 2013
- Added assert() on errors on destructors - Added assert() on errors on destructors
- Added getBytes() - Added getBytes()
- Added getBlob(), getType() and isInteger/isFloat/isText/isBlob/isNull - Added getBlob(), getType() and isInteger/isFloat/isText/isBlob/isNull
- Added bind() for binary blob data - Added bind() for binary blob data
Version 0.5.1 - April 7 2013 Version 0.5.1 - April 7 2013
- Added Column::getName() - Added Column::getName()
Version 0.6.0 - November 22 2013 Version 0.6.0 - November 22 2013
- Renamed Column::getName() to Column::getOriginName() - Renamed Column::getName() to Column::getOriginName()
- Added Column::getName() - Added Column::getName()
Version 0.7.0 - January 9 2014 Version 0.7.0 - January 9 2014
- Added Database::createFunction() - Added Database::createFunction()
- Added std::string version of existing APIs - Added std::string version of existing APIs
- Improved CMake with more build options and Doxygen auto-detection - Improved CMake with more build options and Doxygen auto-detection
Version 0.8.0 - February 26 2014 Version 0.8.0 - February 26 2014
- Database constructor support opening a database with a custom VFS (default to NULL) - Database constructor support opening a database with a custom VFS (default to NULL)
- Changed Column::getText() to return empty string "" by default instead of NULL pointer (to handle std::string conversion) - Changed Column::getText() to return empty string "" by default instead of NULL pointer (to handle std::string conversion)
Version 1.0.0 - May 3 2015 Version 1.0.0 - May 3 2015
- Public headers file moved to include/ dir - Public headers file moved to include/ dir
- Added support to biicode in CMakeLists.txt - Added support to biicode in CMakeLists.txt
- Added Unit Tests - Added Unit Tests
- Added aBusyTimeoutMs parameter to Database() constructors - Added aBusyTimeoutMs parameter to Database() constructors
- Added Database::getTotalChanges() - Added Database::getTotalChanges()
- Added Database::getErrorCode() - Added Database::getErrorCode()
- Added Statement::clearBindings() - Added Statement::clearBindings()
- Added Statement::getColumn(aName) - Added Statement::getColumn(aName)
- Added Statement::getErrorCode() - Added Statement::getErrorCode()
- Added Statement::getColumnName(aIndex) - Added Statement::getColumnName(aIndex)
- Added Statement::getColumnOriginName(aIndex) - Added Statement::getColumnOriginName(aIndex)
Version 1.1.0 - May 18 2015 Version 1.1.0 - May 18 2015
- Fixed valgrind error on Database destructor - Fixed valgrind error on Database destructor
- Added Database::loadExtension - Added Database::loadExtension
Version 1.2.0 - September 9 2015 Version 1.2.0 - September 9 2015
- Fixed build with GCC 5.1.0 - Fixed build with GCC 5.1.0
- Fixed MSVC release build warning - Fixed MSVC release build warning
- Fixed CppDepends warnings - Fixed CppDepends warnings
- Updated documentation on installation - Updated documentation on installation
- Added Database::getHandle() - Added Database::getHandle()
Version 1.3.0 - November 1 2015 Version 1.3.0 - November 1 2015
- Fixed build with Visual Studio 2015 - Fixed build with Visual Studio 2015
- Further improvements to README - Further improvements to README
- Added Backup class - Added Backup class
Version 1.3.1 - February 10 2016 Version 1.3.1 - February 10 2016
- Swith Linux/Mac build to the provided SQLite3 C library - Swith Linux/Mac build to the provided SQLite3 C library
- Update SQLite3 from 3.8.8.3 to latest 3.10.2 (2016-01-20) - Update SQLite3 from 3.8.8.3 to latest 3.10.2 (2016-01-20)
- Remove warnings - Remove warnings
- Remove biicode support (defunct service, servers will shutdown the 16th of February 2016) - Remove biicode support (defunct service, servers will shutdown the 16th of February 2016)
Version 2.0.0 - July 25 2016 Version 2.0.0 - July 25 2016
- Update SQLite3 from 3.10.2 to latest 3.13 (2016-05-18) - Update SQLite3 from 3.10.2 to latest 3.13 (2016-05-18)
- Move #include <sqlite3.h> from headers to .cpp files only using forward declarations - Move #include <sqlite3.h> from headers to .cpp files only using forward declarations
- Add Database::VERSION to reach SQLITE_VERSION without including sqlite3.h in application code - Add Database::VERSION to reach SQLITE_VERSION without including sqlite3.h in application code
- Add getLibVersion() and getLibVersionNumber() to get runtime version of the library - Add getLibVersion() and getLibVersionNumber() to get runtime version of the library
- Better exception messages when Statements fail PR #84 - Better exception messages when Statements fail PR #84
- Variadic templates for bind() (C++14) PR #85 - Variadic templates for bind() (C++14) PR #85
- Add Statement::bindNoCopy() methods for strings, using SQLITE_STATIC to avoid internal copy by SQLite3 PR #86 - Add Statement::bindNoCopy() methods for strings, using SQLITE_STATIC to avoid internal copy by SQLite3 PR #86
- Add Statement::bind() overload for uint32_t, and Column::getUint() and cast operator to uint32_t PR #86 - Add Statement::bind() overload for uint32_t, and Column::getUint() and cast operator to uint32_t PR #86
- Use the new SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION from SQLite 3.13 for security reason - Use the new SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION from SQLite 3.13 for security reason
- Rename Backup::remainingPageCount()/totalPageCount() to Backup::getRemainingPageCount()/getTotalPageCount() - Rename Backup::remainingPageCount()/totalPageCount() to Backup::getRemainingPageCount()/getTotalPageCount()
- Remove Column::errmsg() method : use Database or Statement equivalents - Remove Column::errmsg() method : use Database or Statement equivalents
- More unit tests, with code coverage status on the GitHub page - More unit tests, with code coverage status on the GitHub page
- Do not force MSVC to use static runtime if unit-tests are not build - Do not force MSVC to use static runtime if unit-tests are not build
Version 2.1.0 - July 18 2017 Version 2.1.0 - July 18 2017
- Update SQLite3 from 3.13 to latest 3.19.3 (2017-06-08) - Update SQLite3 from 3.13 to latest 3.19.3 (2017-06-08)
- Fixed Incompatibility in 3.19.0 (to use older SQLite version set the CMake variable SQLITE_USE_LEGACY_STRUCT) #125 - Fixed Incompatibility in 3.19.0 (to use older SQLite version set the CMake variable SQLITE_USE_LEGACY_STRUCT) #125
- Fixed link error (inline in cpp) and compiler warnings (unused variable...) #96 - Fixed link error (inline in cpp) and compiler warnings (unused variable...) #96
- Added ability to open encrypted databases (using SQLCipher, eg. libsqlcipher-dev) #107 - Added ability to open encrypted databases (using SQLCipher, eg. libsqlcipher-dev) #107
- Added convenience functions for constructing objects from a row #114 - Added convenience functions for constructing objects from a row #114
- Added CMake install step #118 - Added CMake install step #118
- Fix warnings #119 - Fix warnings #119
- Make cpplint.py Python-3 compatible #120 - Make cpplint.py Python-3 compatible #120
- Link libssp when targeted #100 - Link libssp when targeted #100
- Removed redundant const #102 - Removed redundant const #102
Version 2.2.0 - Sept 19 2017 Version 2.2.0 - Sept 19 2017
- Update SQLite3 from 3.19.3 to latest 3.20.1 (2017-08-24) #143 - Update SQLite3 from 3.19.3 to latest 3.20.1 (2017-08-24) #143
- Added tryExecuteStep and tryReset #142 - Added tryExecuteStep and tryReset #142
- Removed virtual keywords from destructors #140 - Removed virtual keywords from destructors #140
- Removed misplaced noexcept keyword #139 - Removed misplaced noexcept keyword #139
- Improved Exception class C++ conformance #138 - Improved Exception class C++ conformance #138
- Fix warnings #134 - Fix warnings #134
- Deprecated Statement::IsOk() to Statement::HasRow() - Deprecated Statement::isOk() to Statement::hasRow()
Version 2.3.0 - March 3 2019 Version 2.3.0 - March 3 2019
- Update SQLite3 from 3.20.1 to latest 3.27.2 (2019-02-25) #183 #187 - Update SQLite3 from 3.20.1 to latest 3.27.2 (2019-02-25) #183 #187
- Add Statement binding for long int values #147 - Add Statement binding for long int values #147
- Allows long int for bind when used with name #148 - Allows long int for bind when used with name #148
- More cmake instructions for Linux #151 - More cmake instructions for Linux #151
- Add comparison with sqlite_orm #141 - Add comparison with sqlite_orm #141
- Fix Statement::bind truncates long integer to 32 bits on x86_64 Linux #155 - Fix Statement::bind truncates long integer to 32 bits on x86_64 Linux #155
- Add a move constructor to Database #157 - Add a move constructor to Database #157
- Added tests for all MSVC compilers available on AppVeyor (2013, 2015, 2017) #169 - Added tests for all MSVC compilers available on AppVeyor (2013, 2015, 2017) #169
- Update VariadicBind.h #172 - Update VariadicBind.h #172
- Better CMake compatibility #170 - Better CMake compatibility #170
- Add implicit cast operator to char and short types #179 #180 - Add implicit cast operator to char and short types #179 #180
Version 2.4.0 - August 25 2019 Version 2.4.0 - August 25 2019
- Update SQLite3 from 3.27.2 to 3.29.0 (2019-07-10) #217 - Update SQLite3 from 3.27.2 to 3.29.0 (2019-07-10) #217
- #191 CMake Warning line 299 - #191 CMake Warning line 299
- #190 Implement move constructors - #190 Implement move constructors
- #192 Add wrapper for bind parameter count - #192 Add wrapper for bind parameter count
- #197 Add tuple_bind and execute_many (requested by #24) - #197 Add tuple_bind and execute_many (requested by #24)
- #199 Fix #156 misleading error message in exception from Statement::exec - #199 Fix #156 misleading error message in exception from Statement::exec
- #201 Add Statement::getExpandedSQL() to get the SQL text of prepared statement with bound parameters expanded - #201 Add Statement::getExpandedSQL() to get the SQL text of prepared statement with bound parameters expanded
- #211 Implement Database::backup() - #211 Implement Database::backup()
- #215 Disable implicit fallthrough warning when building internal sqlite3 - #215 Disable implicit fallthrough warning when building internal sqlite3
- #216 Set PROJECT_VERSION to fix CMP0048 Policy warnings - #216 Set PROJECT_VERSION to fix CMP0048 Policy warnings
Version 2.5.0 - December 31 2019 Version 2.5.0 - December 31 2019
- Update SQLite3 from 3.29.0 to 3.30.1 (2019-10-10) - Update SQLite3 from 3.29.0 to 3.30.1 (2019-10-10)
- 100% Unit Test coverage - 100% Unit Test coverage
- #212 fix sqlite3 compile properties (jzt) - #212 fix sqlite3 compile properties (jzt)
- #219 Disable cast-function-type warning when building internal sqlite (zxey) - #219 Disable cast-function-type warning when building internal sqlite (zxey)
- #230 Fixed installation on other than Ubuntu GNU/Linux distributions (xvitaly) - #230 Fixed installation on other than Ubuntu GNU/Linux distributions (xvitaly)
- #228 use transitive compile definitions via cmake (BioDataAnalysis/emmenlau) - #228 use transitive compile definitions via cmake (BioDataAnalysis/emmenlau)
- #232 Added support of packaged GTest for running unit tests (xvitaly) - #232 Added support of packaged GTest for running unit tests (xvitaly)
- #231 Added SOVERSION field for shared library (xvitaly) - #231 Added SOVERSION field for shared library (xvitaly)
- #229 Explicitly find and link against system sqlite library (xvitaly) - #229 Explicitly find and link against system sqlite library (xvitaly)
- #235 Added support for cmake dependencies and version information (BioDataAnalysis/emmenlau) - #235 Added support for cmake dependencies and version information (BioDataAnalysis/emmenlau)
- #249 Added SQLite header parsing functionality and associated tests (patrick--) - #249 Added SQLite header parsing functionality and associated tests (patrick--)
- #251 Added example for getHeaderInfo() - #251 Added example for getHeaderInfo()
Version 3.0.0 - January 1 2020
- C++11 minimum
- CMake 3.1 minimum
- Visual Studio 2015 minimum
- Googletest 1.10
- Remove Statement::isOk() deprecated in 2.2.0 when renamed to Statement::hasRow()

View File

@ -4,19 +4,15 @@
# #
# 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 3.1) # for "CMAKE_CXX_STANDARD" version
if (CMAKE_VERSION VERSION_LESS 3.0) project(SQLiteCpp VERSION "2.99")
project(SQLiteCpp)
set(PROJECT_VERSION_MAJOR 2) # SQLiteC++ 3.x now requires C++11 compiler
set(PROJECT_VERSION_MINOR 5) set(CMAKE_CXX_STANDARD 11)
set(PROJECT_VERSION_PATCH 0) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(PROJECT_VERSION "2.5.0")
else()
cmake_policy(SET CMP0048 NEW)
project(SQLiteCpp VERSION "2.5.0")
endif()
message (STATUS "CMake version: ${CMAKE_VERSION}") message (STATUS "CMake version: ${CMAKE_VERSION}")
message (STATUS "Project version: ${PROJECT_VERSION}")
# Define useful variables to handle OS differences: # Define useful variables to handle OS differences:
if (WIN32) if (WIN32)
@ -39,9 +35,9 @@ if (MSVC)
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 # MSVC versions prior to 2015 are not supported anymore by SQLiteC++ 3.x
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(ERROR "Visual Studio prior to 2015 is not supported anymore.")
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")
@ -111,7 +107,6 @@ set(SQLITECPP_INC
${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/VariadicBind.h ${PROJECT_SOURCE_DIR}/include/SQLiteCpp/VariadicBind.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/ExecuteMany.h ${PROJECT_SOURCE_DIR}/include/SQLiteCpp/ExecuteMany.h
) )
@ -145,9 +140,13 @@ set(SQLITECPP_DOC
) )
source_group(doc FILES ${SQLITECPP_DOC}) source_group(doc FILES ${SQLITECPP_DOC})
# list of script files of the library # list of config & script files of the library
set(SQLITECPP_SCRIPT set(SQLITECPP_SCRIPT
.editorconfig
.gitbugtraq
.github/workflows/actions.yml .github/workflows/actions.yml
.gitignore
.gitmodules
.travis.yml .travis.yml
appveyor.yml appveyor.yml
build.bat build.bat

View File

@ -38,7 +38,7 @@ PROJECT_NAME = SQLiteC++
# could be handy for archiving the generated documentation or if some version # could be handy for archiving the generated documentation or if some version
# control system is used. # control system is used.
PROJECT_NUMBER = 2.5.0 PROJECT_NUMBER = 3.0.0
# Using the PROJECT_BRIEF tag one can provide an optional one line description # Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a # for a project that appears at the top of each page and should give viewer a

View File

@ -45,8 +45,8 @@ http://www.sqlite.org/about.html
### The goals of SQLiteC++ are: ### The goals of SQLiteC++ are:
- to offer the best of the existing simple C++ SQLite wrappers - to offer the best of the existing simple C++ SQLite wrappers
- to be elegantly written with good C++ design, STL, exceptions and RAII idiom - to be elegantly written with good C++11 design, STL, exceptions and RAII idiom
- to keep dependencies to a minimum (STL and SQLite3) - to keep dependencies to a minimum (C++11 STL and SQLite3)
- to be portable - to be portable
- to be light and fast - to be light and fast
- to be thread-safe only as much as SQLite "Multi-thread" mode (see below) - to be thread-safe only as much as SQLite "Multi-thread" mode (see below)
@ -58,29 +58,32 @@ http://www.sqlite.org/about.html
It is designed using the Resource Acquisition Is Initialization (RAII) idiom It is designed using the Resource Acquisition Is Initialization (RAII) idiom
(see http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization), (see http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization),
and throwing exceptions in case of SQLite errors (exept in destructors, and throwing exceptions in case of SQLite errors (except in destructors,
where assert() are used instead). where assert() are used instead).
Each SQLiteC++ object must be constructed with a valid SQLite database connection, Each SQLiteC++ object must be constructed with a valid SQLite database connection,
and then is always valid until destroyed. and then is always valid until destroyed.
### Supported platforms: ### Supported platforms:
Developements and tests are done under the following OSs: Now requires a C++11 compiler. Use branch [sqlitecpp-2.x](https://github.com/SRombauts/SQLiteCpp/tree/sqlitecpp-2.x) for latest pre-C++11 developments.
- Ubuntu 14.04 (Travis CI)
Developments and tests are done under the following OSs:
- Ubuntu 14.04, 16.04 and 18.04 (Travis CI)
- Windows 10, and Windows Server 2012 R2 & Windows Server 2016 (AppVeyor) - Windows 10, and Windows Server 2012 R2 & Windows Server 2016 (AppVeyor)
- OS X 10.11 (Travis CI) - OS X 10.11 (Travis CI)
- Github Actions
And the following IDEs/Compilers And the following IDEs/Compilers
- GCC 4.8.4, 4.9.3, 5.3.0 and 6.1.1 (C++03, C++11, C++14, C++1z) - GCC 4.8.4, 5.3.0 and 7.1.1 (C++11, C++14, C++17)
- Clang 3.5 and 3.8 - Clang 5
- Xcode 8 - Xcode 8 & 9
- Visual Studio Community 2019, 2017, and 2015 (AppVeyor) - Visual Studio Community 2019, 2017, and 2015 (AppVeyor)
### Dependencies ### Dependencies
- an STL implementation (even an old one, like the one provided with VC6 should work) - a modern C++11 STL implementation with GCC, Clang, or Visual Studio 2015
- exception support (the class Exception inherits from std::runtime_error) - exception support (the class Exception inherits from std::runtime_error)
- the SQLite library (3.7.15 minimum from 2012-12-12) either by linking to it dynamicaly or statically (install the libsqlite3-dev package under Debian/Ubuntu/Mint Linux), - the SQLite library (3.7.15 minimum from 2012-12-12) either by linking to it dynamically or statically (install the libsqlite3-dev package under Debian/Ubuntu/Mint Linux),
or by adding its source file in your project code base (source code provided in src/sqlite3 for Windows), or by adding its source file in your project code base (source code provided in src/sqlite3 for Windows),
with the SQLITE_ENABLE_COLUMN_METADATA macro defined (see http://www.sqlite.org/compile.html#enable_column_metadata). with the SQLITE_ENABLE_COLUMN_METADATA macro defined (see http://www.sqlite.org/compile.html#enable_column_metadata).
@ -111,7 +114,7 @@ target_link_libraries(main
dl dl
) )
``` ```
Thus this SQLiteCpp repository can be directly used as a Git submoldule. Thus this SQLiteCpp repository can be directly used as a Git submodule.
See the [SQLiteCpp_Example](https://github.com/SRombauts/SQLiteCpp_Example) side repository for a standalone "from scratch" example. See the [SQLiteCpp_Example](https://github.com/SRombauts/SQLiteCpp_Example) side repository for a standalone "from scratch" example.
Under Debian/Ubuntu/Mint Linux, you can install the libsqlite3-dev package if you don't want to use the embedded sqlite3 library. Under Debian/Ubuntu/Mint Linux, you can install the libsqlite3-dev package if you don't want to use the embedded sqlite3 library.
@ -128,7 +131,7 @@ git submodule update
``` ```
#### CMake and tests #### CMake and tests
A CMake configuration file is also provided for multiplatform support and testing. A CMake configuration file is also provided for multi-platform support and testing.
Typical generic build for MS Visual Studio under Windows (from [build.bat](build.bat)): Typical generic build for MS Visual Studio under Windows (from [build.bat](build.bat)):
@ -136,7 +139,7 @@ Typical generic build for MS Visual Studio under Windows (from [build.bat](build
mkdir build mkdir build
cd build cd build
cmake .. # cmake .. -G "Visual Studio 10" # for Visual Studio 2010 cmake .. # cmake .. -G "Visual Studio 16 2019" # for Visual Studio 2019
@REM Generate a Visual Studio solution for latest version found @REM Generate a Visual Studio solution for latest version found
cmake -DSQLITECPP_BUILD_EXAMPLES=ON -DSQLITECPP_BUILD_TESTS=ON .. cmake -DSQLITECPP_BUILD_EXAMPLES=ON -DSQLITECPP_BUILD_TESTS=ON ..
@ -169,7 +172,7 @@ ctest --output-on-failure
#### Troubleshooting #### Troubleshooting
Under Linux, if you get muliple linker errors like "undefined reference to sqlite3_xxx", Under Linux, if you get multiple linker errors like "undefined reference to sqlite3_xxx",
it's that you lack the "sqlite3" library: install the libsqlite3-dev package. it's that you lack the "sqlite3" library: install the libsqlite3-dev package.
If you get a single linker error "Column.cpp: undefined reference to sqlite3_column_origin_name", If you get a single linker error "Column.cpp: undefined reference to sqlite3_column_origin_name",
@ -186,7 +189,7 @@ You can either recompile it yourself (seek help online) or you can comment out t
This project is continuously tested under Ubuntu Linux with the gcc and clang compilers This project is continuously tested under Ubuntu Linux with the gcc and clang compilers
using the Travis CI community service with the above CMake building and testing procedure. using the Travis CI community service with the above CMake building and testing procedure.
It is also tested in the same way under Windows Server 2012 R2 with Visual Studio 2013 compiler It is also tested in the same way under Windows Server 2012 R2 with Visual Studio 2013 compiler
using the AppVeyor countinuous integration service. using the AppVeyor continuous integration service.
Detailed results can be seen online: Detailed results can be seen online:
- https://travis-ci.org/SRombauts/SQLiteCpp - https://travis-ci.org/SRombauts/SQLiteCpp

View File

@ -7,11 +7,10 @@ Improve Github Wiki pages with the FAQ: Installation, Examples, Tutorial, How to
Publish the Doxygen Documentation in the Github Pages (gh-pages branch) Publish the Doxygen Documentation in the Github Pages (gh-pages branch)
Missing features in v2.0.0: Missing features in v2.0.0:
- #24: executemany() like in Python https://docs.python.org/2/library/sqlite3.html#sqlite3.Connection.executemany
- #34: Better type for getColumn - #34: Better type for getColumn
Missing documentation in v2.0.0: Missing documentation in v2.0.0:
- explain the noncopyable property for RAII design - explain the non-copyable property for RAII design
- comment on returning error code instead of exception that shall not be thrown when expected (!?) - comment on returning error code instead of exception that shall not be thrown when expected (!?)
Missing unit tests in v2.0.0: Missing unit tests in v2.0.0:
@ -21,7 +20,7 @@ Advanced missing features:
- #39: SAVEPOINT https://www.sqlite.org/lang_savepoint.html - #39: SAVEPOINT https://www.sqlite.org/lang_savepoint.html
- Add optional usage of experimental sqlite3_trace() function to enable statistics - Add optional usage of experimental sqlite3_trace() function to enable statistics
- Agregate ? - Aggregate ?
- support for different transaction mode ? NO: too specific - support for different transaction mode ? NO: too specific
- operator<< binding ? NO: redundant with bind() - operator<< binding ? NO: redundant with bind()

View File

@ -99,6 +99,10 @@ public:
Backup(Database& aDestDatabase, Backup(Database& aDestDatabase,
Database& aSrcDatabase); Database& aSrcDatabase);
// Backup is non-copyable
Backup(const Backup&) = delete;
Backup& operator=(const Backup&) = delete;
/// Release the SQLite Backup resource. /// Release the SQLite Backup resource.
~Backup(); ~Backup();
@ -124,13 +128,8 @@ public:
int getTotalPageCount(); int getTotalPageCount();
private: private:
/// @{ Backup must be non-copyable // TODO: use std::unique_ptr with a custom deleter to call sqlite3_backup_finish()
Backup(const Backup&); sqlite3_backup* mpSQLiteBackup = nullptr; ///< Pointer to SQLite Database Backup Handle
Backup& operator=(const Backup&);
/// @}
private:
sqlite3_backup* mpSQLiteBackup; ///< Pointer to SQLite Database Backup Handle
}; };
} // namespace SQLite } // namespace SQLite

View File

@ -52,26 +52,18 @@ public:
* @param[in] aStmtPtr Shared pointer to the prepared SQLite Statement Object. * @param[in] aStmtPtr Shared pointer to the prepared SQLite Statement Object.
* @param[in] aIndex Index of the column in the row of result, starting at 0 * @param[in] aIndex Index of the column in the row of result, starting at 0
*/ */
Column(Statement::Ptr& aStmtPtr, int aIndex) noexcept; // nothrow Column(Statement::Ptr& aStmtPtr, int aIndex) noexcept;
/// Simple destructor
~Column();
// default destructor: the finalization will be done by the destructor of the last shared pointer
// default copy constructor and assignment operator are perfectly suited : // default copy constructor and assignment operator are perfectly suited :
// they copy the Statement::Ptr which in turn increments the reference counter. // they copy the Statement::Ptr which in turn increments the reference counter.
/// Make clang happy by explicitly implementing the copy-constructor:
Column(const Column & aOther) :
mStmtPtr(aOther.mStmtPtr),
mIndex(aOther.mIndex)
{
}
/** /**
* @brief Return a pointer to the named assigned to this result column (potentially aliased) * @brief Return a pointer to the named assigned to this result column (potentially aliased)
* *
* @see getOriginName() to get original column name (not aliased) * @see getOriginName() to get original column name (not aliased)
*/ */
const char* getName() const noexcept; // nothrow const char* getName() const noexcept;
#ifdef SQLITE_ENABLE_COLUMN_METADATA #ifdef SQLITE_ENABLE_COLUMN_METADATA
/** /**
@ -81,31 +73,31 @@ public:
* - when building the SQLite library itself (which is the case for the Debian libsqlite3 binary for instance), * - when building the SQLite library itself (which is the case for the Debian libsqlite3 binary for instance),
* - and also when compiling this wrapper. * - and also when compiling this wrapper.
*/ */
const char* getOriginName() const noexcept; // nothrow const char* getOriginName() const noexcept;
#endif #endif
/// Return the integer value of the column. /// Return the integer value of the column.
int getInt() const noexcept; // nothrow int getInt() const noexcept;
/// Return the 32bits unsigned integer value of the column (note that SQLite3 does not support unsigned 64bits). /// Return the 32bits unsigned integer value of the column (note that SQLite3 does not support unsigned 64bits).
unsigned getUInt() const noexcept; // nothrow unsigned getUInt() const noexcept;
/// Return the 64bits integer value of the column (note that SQLite3 does not support unsigned 64bits). /// Return the 64bits integer value of the column (note that SQLite3 does not support unsigned 64bits).
long long getInt64() const noexcept; // nothrow long long getInt64() const noexcept;
/// Return the double (64bits float) value of the column /// Return the double (64bits float) value of the column
double getDouble() const noexcept; // nothrow double getDouble() const noexcept;
/** /**
* @brief Return a pointer to the text value (NULL terminated string) of the column. * @brief Return a pointer to the text value (NULL terminated string) of the column.
* *
* @warning The value pointed at is only valid while the statement is valid (ie. not finalized), * @warning The value pointed at is only valid while the statement is valid (ie. not finalized),
* thus you must copy it before using it beyond its scope (to a std::string for instance). * thus you must copy it before using it beyond its scope (to a std::string for instance).
*/ */
const char* getText(const char* apDefaultValue = "") const noexcept; // nothrow const char* getText(const char* apDefaultValue = "") const noexcept;
/** /**
* @brief Return a pointer to the binary blob value of the column. * @brief Return a pointer to the binary blob value of the column.
* *
* @warning The value pointed at is only valid while the statement is valid (ie. not finalized), * @warning The value pointed at is only valid while the statement is valid (ie. not finalized),
* thus you must copy it before using it beyond its scope (to a std::string for instance). * thus you must copy it before using it beyond its scope (to a std::string for instance).
*/ */
const void* getBlob() const noexcept; // nothrow const void* getBlob() const noexcept;
/** /**
* @brief Return a std::string for a TEXT or BLOB column. * @brief Return a std::string for a TEXT or BLOB column.
* *
@ -121,30 +113,30 @@ public:
* @warning After a type conversion (by a call to a getXxx on a Column of a Yyy type), * @warning After a type conversion (by a call to a getXxx on a Column of a Yyy type),
* the value returned by sqlite3_column_type() is undefined. * the value returned by sqlite3_column_type() is undefined.
*/ */
int getType() const noexcept; // nothrow int getType() const noexcept;
/// Test if the column is an integer type value (meaningful only before any conversion) /// Test if the column is an integer type value (meaningful only before any conversion)
inline bool isInteger() const noexcept // nothrow bool isInteger() const noexcept
{ {
return (SQLite::INTEGER == getType()); return (SQLite::INTEGER == getType());
} }
/// Test if the column is a floating point type value (meaningful only before any conversion) /// Test if the column is a floating point type value (meaningful only before any conversion)
inline bool isFloat() const noexcept // nothrow bool isFloat() const noexcept
{ {
return (SQLite::FLOAT == getType()); return (SQLite::FLOAT == getType());
} }
/// Test if the column is a text type value (meaningful only before any conversion) /// Test if the column is a text type value (meaningful only before any conversion)
inline bool isText() const noexcept // nothrow bool isText() const noexcept
{ {
return (SQLite::TEXT == getType()); return (SQLite::TEXT == getType());
} }
/// Test if the column is a binary blob type value (meaningful only before any conversion) /// Test if the column is a binary blob type value (meaningful only before any conversion)
inline bool isBlob() const noexcept // nothrow bool isBlob() const noexcept
{ {
return (SQLite::BLOB == getType()); return (SQLite::BLOB == getType());
} }
/// Test if the column is NULL (meaningful only before any conversion) /// Test if the column is NULL (meaningful only before any conversion)
inline bool isNull() const noexcept // nothrow bool isNull() const noexcept
{ {
return (SQLite::Null == getType()); return (SQLite::Null == getType());
} }
@ -161,68 +153,68 @@ public:
int getBytes() const noexcept; int getBytes() const noexcept;
/// Alias returning the number of bytes used by the text (or blob) value of the column /// Alias returning the number of bytes used by the text (or blob) value of the column
inline int size() const noexcept int size() const noexcept
{ {
return getBytes (); return getBytes ();
} }
/// Inline cast operator to char /// Inline cast operator to char
inline operator char() const operator char() const
{ {
return static_cast<char>(getInt()); return static_cast<char>(getInt());
} }
/// Inline cast operator to unsigned char /// Inline cast operator to unsigned char
inline operator unsigned char() const operator unsigned char() const
{ {
return static_cast<unsigned char>(getInt()); return static_cast<unsigned char>(getInt());
} }
/// Inline cast operator to short /// Inline cast operator to short
inline operator short() const operator short() const
{ {
return static_cast<short>(getInt()); return static_cast<short>(getInt());
} }
/// Inline cast operator to unsigned short /// Inline cast operator to unsigned short
inline operator unsigned short() const operator unsigned short() const
{ {
return static_cast<unsigned short>(getInt()); return static_cast<unsigned short>(getInt());
} }
/// Inline cast operator to int /// Inline cast operator to int
inline operator int() const operator int() const
{ {
return getInt(); return getInt();
} }
/// Inline cast operator to 32bits unsigned integer /// Inline cast operator to 32bits unsigned integer
inline operator unsigned int() const operator unsigned int() const
{ {
return getUInt(); return getUInt();
} }
#if (LONG_MAX == INT_MAX) // 4 bytes "long" type means the data model is ILP32 or LLP64 (Win64 Visual C++ and MinGW) #if (LONG_MAX == INT_MAX) // 4 bytes "long" type means the data model is ILP32 or LLP64 (Win64 Visual C++ and MinGW)
/// Inline cast operator to 32bits long /// Inline cast operator to 32bits long
inline operator long() const operator long() const
{ {
return getInt(); return getInt();
} }
/// Inline cast operator to 32bits unsigned long /// Inline cast operator to 32bits unsigned long
inline operator unsigned long() const operator unsigned long() const
{ {
return getUInt(); return getUInt();
} }
#else // 8 bytes "long" type means the data model is LP64 (Most Unix-like, Windows when using Cygwin; z/OS) #else // 8 bytes "long" type means the data model is LP64 (Most Unix-like, Windows when using Cygwin; z/OS)
/// Inline cast operator to 64bits long when the data model of the system is LP64 (Linux 64 bits...) /// Inline cast operator to 64bits long when the data model of the system is LP64 (Linux 64 bits...)
inline operator long() const operator long() const
{ {
return getInt64(); return getInt64();
} }
#endif #endif
/// Inline cast operator to 64bits integer /// Inline cast operator to 64bits integer
inline operator long long() const operator long long() const
{ {
return getInt64(); return getInt64();
} }
/// Inline cast operator to double /// Inline cast operator to double
inline operator double() const operator double() const
{ {
return getDouble(); return getDouble();
} }
@ -231,7 +223,7 @@ public:
* *
* @see getText * @see getText
*/ */
inline operator const char*() const operator const char*() const
{ {
return getText(); return getText();
} }
@ -240,21 +232,11 @@ public:
* *
* @see getBlob * @see getBlob
*/ */
inline operator const void*() const operator const void*() const
{ {
return getBlob(); return getBlob();
} }
#if !defined(_MSC_VER) || _MSC_VER >= 1900
// NOTE : the following is required by GCC and Clang to cast a Column result in a std::string
// (error: conversion from SQLite::Column to non-scalar type std::string {aka std::basic_string<char>})
// and also required for Microsoft Visual Studio 2015 and newer
// but is not working under Microsoft Visual Studio 2010, 2012 and 2013
// (error C2440: 'initializing' : cannot convert from 'SQLite::Column' to 'std::basic_string<_Elem,_Traits,_Ax>'
// [...] constructor overload resolution was ambiguous)
// WARNING: without it, trying to access a binary blob with implicit cast to string
// ends up converting it to a C-style char*, damaging the data by truncating it to the first null character!
// (see https://github.com/SRombauts/SQLiteCpp/issues/189 Visual Studio 2013: unit test "Column.basis" failing)
/** /**
* @brief Inline cast operator to std::string * @brief Inline cast operator to std::string
* *
@ -262,11 +244,10 @@ public:
* *
* @see getString * @see getString
*/ */
inline operator std::string() const operator std::string() const
{ {
return getString(); return getString();
} }
#endif
private: private:
Statement::Ptr mStmtPtr; ///< Shared Pointer to the prepared SQLite Statement Object Statement::Ptr mStmtPtr; ///< Shared Pointer to the prepared SQLite Statement Object
@ -285,7 +266,7 @@ private:
*/ */
std::ostream& operator<<(std::ostream& aStream, const Column& aColumn); std::ostream& operator<<(std::ostream& aStream, const Column& aColumn);
#if __cplusplus >= 201402L || (defined(_MSC_VER) && _MSC_VER >= 1900) #if __cplusplus >= 201402L || (defined(_MSC_VER) && _MSC_VER >= 1900) // c++14: Visual Studio 2015
// Create an instance of T from the first N columns, see declaration in Statement.h for full details // Create an instance of T from the first N columns, see declaration in Statement.h for full details
template<typename T, int N> template<typename T, int N>

View File

@ -11,7 +11,6 @@
#pragma once #pragma once
#include <SQLiteCpp/Column.h> #include <SQLiteCpp/Column.h>
#include <SQLiteCpp/Utils.h> // definition of nullptr for C++98/C++03 compilers
#include <string.h> #include <string.h>
// Forward declarations to avoid inclusion of <sqlite3.h> in a header // Forward declarations to avoid inclusion of <sqlite3.h> in a header
@ -42,15 +41,15 @@ extern const int OPEN_CREATE; // SQLITE_OPEN_CREATE
/// Enable URI filename interpretation, parsed according to RFC 3986 (ex. "file:data.db?mode=ro&cache=private") /// Enable URI filename interpretation, parsed according to RFC 3986 (ex. "file:data.db?mode=ro&cache=private")
extern const int OPEN_URI; // SQLITE_OPEN_URI extern const int OPEN_URI; // SQLITE_OPEN_URI
extern const int OK; ///< SQLITE_OK (used by inline check() bellow) extern const int OK; ///< SQLITE_OK (used by check() bellow)
extern const char* VERSION; ///< SQLITE_VERSION string from the sqlite3.h used at compile time extern const char* VERSION; ///< SQLITE_VERSION string from the sqlite3.h used at compile time
extern const int VERSION_NUMBER; ///< SQLITE_VERSION_NUMBER from the sqlite3.h used at compile time extern const int VERSION_NUMBER; ///< SQLITE_VERSION_NUMBER from the sqlite3.h used at compile time
/// 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;
/// 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;
// Public structure for representing all fields contained within the SQLite header. // Public structure for representing all fields contained within the SQLite header.
// Official documentation for fields: https://www.sqlite.org/fileformat.html#the_database_header // Official documentation for fields: https://www.sqlite.org/fileformat.html#the_database_header
@ -143,21 +142,26 @@ public:
Database(const std::string& aFilename, 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 = "") :
Database(aFilename.c_str(), aFlags, aBusyTimeoutMs, aVfs.empty() ? nullptr : aVfs.c_str())
{
}
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)
/** /**
* @brief Move an SQLite database connection. * @brief Move an SQLite database connection.
* *
* @param[in] aDatabase Database to move * @param[in] aDatabase Database to move
*/ */
inline Database(Database&& aDatabase) noexcept : Database(Database&& aDatabase) noexcept :
mpSQLite(aDatabase.mpSQLite), mpSQLite(aDatabase.mpSQLite),
mFilename(std::move(aDatabase.mFilename)) mFilename(std::move(aDatabase.mFilename))
{ {
aDatabase.mpSQLite = nullptr; aDatabase.mpSQLite = nullptr;
} }
#endif
// Database is non-copyable
Database(const Database&) = delete;
Database& operator=(const Database&) = delete;
/** /**
* @brief Close the SQLite database connection. * @brief Close the SQLite database connection.
@ -165,6 +169,8 @@ public:
* All SQLite statements must have been finalized before, * All SQLite statements must have been finalized before,
* so all Statement objects must have been unregistered. * so all Statement objects must have been unregistered.
* *
* TODO: revisit this design, to perhaps switch to having Statement sharing a pointer to the Database?
*
* @warning assert in case of error * @warning assert in case of error
*/ */
~Database(); ~Database();
@ -222,7 +228,7 @@ public:
* *
* @throw SQLite::Exception in case of error * @throw SQLite::Exception in case of error
*/ */
inline int exec(const std::string& aQueries) int exec(const std::string& aQueries)
{ {
return exec(aQueries.c_str()); return exec(aQueries.c_str());
} }
@ -267,7 +273,7 @@ public:
* *
* @throw SQLite::Exception in case of error * @throw SQLite::Exception in case of error
*/ */
inline Column execAndGet(const std::string& aQuery) Column execAndGet(const std::string& aQuery)
{ {
return execAndGet(aQuery.c_str()); return execAndGet(aQuery.c_str());
} }
@ -296,7 +302,7 @@ public:
* *
* @throw SQLite::Exception in case of error * @throw SQLite::Exception in case of error
*/ */
inline bool tableExists(const std::string& aTableName) bool tableExists(const std::string& aTableName)
{ {
return tableExists(aTableName.c_str()); return tableExists(aTableName.c_str());
} }
@ -309,20 +315,20 @@ public:
* *
* @return Rowid of the most recent successful INSERT into the database, or 0 if there was none. * @return Rowid of the most recent successful INSERT into the database, or 0 if there was none.
*/ */
long long getLastInsertRowid() const noexcept; // nothrow long long getLastInsertRowid() const noexcept;
/// Get total number of rows modified by all INSERT, UPDATE or DELETE statement since connection (not DROP table). /// Get total number of rows modified by all INSERT, UPDATE or DELETE statement since connection (not DROP table).
int getTotalChanges() const noexcept; // nothrow int getTotalChanges() const noexcept;
/// 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 getErrorCode() const noexcept; // nothrow int getErrorCode() const noexcept;
/// 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 getExtendedErrorCode() const noexcept; // nothrow int getExtendedErrorCode() const noexcept;
/// 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* getErrorMsg() const noexcept; // nothrow const char* getErrorMsg() const noexcept;
/// Return the filename used to open the database. /// Return the filename used to open the database.
const std::string& getFilename() const noexcept // nothrow const std::string& getFilename() const noexcept
{ {
return mFilename; return mFilename;
} }
@ -332,7 +338,7 @@ public:
* *
* This is often needed to mix this wrapper with other libraries or for advance usage not supported by SQLiteCpp. * This is often needed to mix this wrapper with other libraries or for advance usage not supported by SQLiteCpp.
*/ */
inline sqlite3* getHandle() const noexcept // nothrow sqlite3* getHandle() const noexcept
{ {
return mpSQLite; return mpSQLite;
} }
@ -384,7 +390,7 @@ public:
* *
* @throw SQLite::Exception in case of error * @throw SQLite::Exception in case of error
*/ */
inline void createFunction(const std::string& aFuncName, void createFunction(const std::string& aFuncName,
int aNbArg, int aNbArg,
bool abDeterministic, bool abDeterministic,
void* apApp, void* apApp,
@ -490,16 +496,10 @@ public:
*/ */
int backup(const char* zFilename, BackupType type); int backup(const char* zFilename, BackupType type);
private:
/// @{ Database must be non-copyable
Database(const Database&);
Database& operator=(const Database&);
/// @}
/** /**
* @brief Check if aRet equal SQLITE_OK, else throw a SQLite::Exception with the SQLite error message * @brief Check if aRet equal SQLITE_OK, else throw a SQLite::Exception with the SQLite error message
*/ */
inline void check(const int aRet) const void check(const int aRet) const
{ {
if (SQLite::OK != aRet) if (SQLite::OK != aRet)
{ {
@ -508,6 +508,7 @@ private:
} }
private: private:
// TODO: use std::unique_ptr with a custom deleter to call sqlite3_close()
sqlite3* mpSQLite; ///< Pointer to SQLite Database Connection Handle sqlite3* mpSQLite; ///< Pointer to SQLite Database Connection Handle
std::string mFilename; ///< UTF-8 filename used to open the database std::string mFilename; ///< UTF-8 filename used to open the database
}; };

View File

@ -16,25 +16,6 @@
// Forward declaration to avoid inclusion of <sqlite3.h> in a header // Forward declaration to avoid inclusion of <sqlite3.h> in a header
struct sqlite3; struct sqlite3;
/// Compatibility with non-clang compilers.
#ifndef __has_feature
#define __has_feature(x) 0
#endif
// Detect whether the compiler supports C++11 noexcept exception specifications.
#if ( defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || (__GNUC__ > 4)) \
&& defined(__GXX_EXPERIMENTAL_CXX0X__))
// GCC 4.7 and following have noexcept
#elif defined(__clang__) && __has_feature(cxx_noexcept)
// Clang 3.0 and above have noexcept
#elif defined(_MSC_VER) && _MSC_VER > 1800
// Visual Studio 2015 and above have noexcept
#else
// Visual Studio 2013 does not support noexcept, and "throw()" is deprecated by C++11
#define noexcept
#endif
namespace SQLite namespace SQLite
{ {
@ -49,18 +30,28 @@ public:
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error. * @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
* *
* @param[in] aErrorMessage The string message describing the SQLite error * @param[in] aErrorMessage The string message describing the SQLite error
* @param[in] ret Return value from function call that failed.
*/ */
explicit Exception(const char* aErrorMessage); Exception(const char* aErrorMessage, int ret);
explicit Exception(const std::string& aErrorMessage);
Exception(const std::string& aErrorMessage, int ret) :
Exception(aErrorMessage.c_str(), ret)
{
}
/** /**
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error. * @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
* *
* @param[in] aErrorMessage The string message describing the SQLite error * @param[in] aErrorMessage The string message describing the SQLite error
* @param[in] ret Return value from function call that failed.
*/ */
Exception(const char* aErrorMessage, int ret); explicit Exception(const char* aErrorMessage) :
Exception(const std::string& aErrorMessage, int ret); Exception(aErrorMessage, -1) // 0 would be SQLITE_OK, which doesn't make sense
{
}
explicit Exception(const std::string& aErrorMessage) :
Exception(aErrorMessage.c_str(), -1) // 0 would be SQLITE_OK, which doesn't make sense
{
}
/** /**
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error. * @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
@ -78,19 +69,19 @@ public:
Exception(sqlite3* apSQLite, int ret); Exception(sqlite3* apSQLite, int ret);
/// Return the result code (if any, otherwise -1). /// Return the result code (if any, otherwise -1).
inline int getErrorCode() const noexcept // nothrow int getErrorCode() const noexcept
{ {
return mErrcode; return mErrcode;
} }
/// Return the extended numeric result code (if any, otherwise -1). /// Return the extended numeric result code (if any, otherwise -1).
inline int getExtendedErrorCode() const noexcept // nothrow int getExtendedErrorCode() const noexcept
{ {
return mExtendedErrcode; return mExtendedErrcode;
} }
/// Return a string, solely based on the error code /// Return a string, solely based on the error code
const char* getErrorStr() const noexcept; // nothrow const char* getErrorStr() const noexcept;
private: private:
int mErrcode; ///< Error code value int mErrcode; ///< Error code value

View File

@ -40,5 +40,5 @@
* *
* WARNING: shall always be updated in sync with PROJECT_VERSION in CMakeLists.txt * WARNING: shall always be updated in sync with PROJECT_VERSION in CMakeLists.txt
*/ */
#define SQLITECPP_VERSION "2.05.00" // 2.5.0 #define SQLITECPP_VERSION "3.00.00" // 3.0.0
#define SQLITECPP_VERSION_NUMBER 2005000 // 2.5.0 #define SQLITECPP_VERSION_NUMBER 3000000 // 3.0.0

View File

@ -71,19 +71,24 @@ public:
* *
* Exception is thrown in case of error, then the Statement object is NOT constructed. * Exception is thrown in case of error, then the Statement object is NOT constructed.
*/ */
Statement(Database& aDatabase, const std::string& aQuery); Statement(Database &aDatabase, const std::string& aQuery) :
Statement(aDatabase, aQuery.c_str())
{}
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)
/** /**
* @brief Move an SQLite statement. * @brief Move an SQLite statement.
* *
* @param[in] aStatement Statement to move * @param[in] aStatement Statement to move
*/ */
Statement(Statement&& aStatement) noexcept; Statement(Statement&& aStatement) noexcept;
#endif
// Statement is non-copyable
Statement(const Statement&) = delete;
Statement& operator=(const Statement&) = delete;
/// Finalize and unregister the SQL query from the SQLite Database Connection. /// Finalize and unregister the SQL query from the SQLite Database Connection.
~Statement(); /// The finalization will be done by the destructor of the last shared pointer
~Statement() = default;
/// Reset the statement to make it ready for a new execution. Throws an exception on error. /// Reset the statement to make it ready for a new execution. Throws an exception on error.
void reset(); void reset();
@ -283,14 +288,14 @@ public:
/** /**
* @brief Bind an int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) * @brief Bind an int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/ */
inline void bind(const std::string& aName, const int aValue) void bind(const std::string& aName, const int aValue)
{ {
bind(aName.c_str(), aValue); bind(aName.c_str(), aValue);
} }
/** /**
* @brief Bind a 32bits unsigned int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) * @brief Bind a 32bits unsigned int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/ */
inline void bind(const std::string& aName, const unsigned aValue) void bind(const std::string& aName, const unsigned aValue)
{ {
bind(aName.c_str(), aValue); bind(aName.c_str(), aValue);
} }
@ -315,14 +320,14 @@ public:
/** /**
* @brief Bind a 64bits int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) * @brief Bind a 64bits int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/ */
inline void bind(const std::string& aName, const long long aValue) void bind(const std::string& aName, const long long aValue)
{ {
bind(aName.c_str(), aValue); bind(aName.c_str(), aValue);
} }
/** /**
* @brief Bind a double (64bits float) value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1) * @brief Bind a double (64bits float) value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/ */
inline void bind(const std::string& aName, const double aValue) void bind(const std::string& aName, const double aValue)
{ {
bind(aName.c_str(), aValue); bind(aName.c_str(), aValue);
} }
@ -331,7 +336,7 @@ public:
* *
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use * @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
*/ */
inline void bind(const std::string& aName, const std::string& aValue) void bind(const std::string& aName, const std::string& aValue)
{ {
bind(aName.c_str(), aValue); bind(aName.c_str(), aValue);
} }
@ -340,7 +345,7 @@ public:
* *
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use * @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
*/ */
inline void bind(const std::string& aName, const char* apValue) void bind(const std::string& aName, const char* apValue)
{ {
bind(aName.c_str(), apValue); bind(aName.c_str(), apValue);
} }
@ -349,7 +354,7 @@ public:
* *
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use * @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
*/ */
inline void bind(const std::string& aName, const void* apValue, const int aSize) void bind(const std::string& aName, const void* apValue, const int aSize)
{ {
bind(aName.c_str(), apValue, aSize); bind(aName.c_str(), apValue, aSize);
} }
@ -360,7 +365,7 @@ public:
* *
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement. * @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
*/ */
inline void bindNoCopy(const std::string& aName, const std::string& aValue) void bindNoCopy(const std::string& aName, const std::string& aValue)
{ {
bindNoCopy(aName.c_str(), aValue); bindNoCopy(aName.c_str(), aValue);
} }
@ -371,7 +376,7 @@ public:
* *
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement. * @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
*/ */
inline void bindNoCopy(const std::string& aName, const char* apValue) void bindNoCopy(const std::string& aName, const char* apValue)
{ {
bindNoCopy(aName.c_str(), apValue); bindNoCopy(aName.c_str(), apValue);
} }
@ -380,7 +385,7 @@ public:
* *
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement. * @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
*/ */
inline void bindNoCopy(const std::string& aName, const void* apValue, const int aSize) void bindNoCopy(const std::string& aName, const void* apValue, const int aSize)
{ {
bindNoCopy(aName.c_str(), apValue, aSize); bindNoCopy(aName.c_str(), apValue, aSize);
} }
@ -389,7 +394,7 @@ public:
* *
* @see clearBindings() to set all bound parameters to NULL. * @see clearBindings() to set all bound parameters to NULL.
*/ */
inline void bind(const std::string& aName) // bind NULL value void bind(const std::string& aName) // bind NULL value
{ {
bind(aName.c_str()); bind(aName.c_str());
} }
@ -400,7 +405,7 @@ public:
* @brief Execute a step of the prepared query to fetch one row of results. * @brief Execute a step of the prepared query to fetch one row of results.
* *
* While true is returned, a row of results is available, and can be accessed * While true is returned, a row of results is available, and can be accessed
* thru the getColumn() method * through the getColumn() method
* *
* @see exec() execute a one-step prepared statement with no expected result * @see exec() execute a one-step prepared statement with no expected result
* @see tryExecuteStep() try to execute a step of the prepared query to fetch one row of results, returning the sqlite result code. * @see tryExecuteStep() try to execute a step of the prepared query to fetch one row of results, returning the sqlite result code.
@ -510,7 +515,7 @@ public:
*/ */
Column getColumn(const char* apName); Column getColumn(const char* apName);
#if __cplusplus >= 201402L || (defined(_MSC_VER) && _MSC_VER >= 1900) #if __cplusplus >= 201402L || (defined(_MSC_VER) && _MSC_VER >= 1900) // c++14: Visual Studio 2015
/** /**
* @brief Return an instance of T constructed from copies of the first N columns * @brief Return an instance of T constructed from copies of the first N columns
* *
@ -622,11 +627,6 @@ public:
{ {
return mbHasRow; return mbHasRow;
} }
/// @deprecated, use #hasRow()
inline bool isOk() const
{
return hasRow();
}
/// true when the last executeStep() had no more row to fetch /// true when the last executeStep() had no more row to fetch
inline bool isDone() const inline bool isDone() const
{ {
@ -637,11 +637,11 @@ public:
int getBindParameterCount() const noexcept; int getBindParameterCount() const noexcept;
/// 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 getErrorCode() const noexcept; // nothrow int getErrorCode() const noexcept;
/// 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 getExtendedErrorCode() const noexcept; // nothrow int getExtendedErrorCode() const noexcept;
/// 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* getErrorMsg() const noexcept; // nothrow const char* getErrorMsg() const noexcept;
private: private:
/** /**
@ -651,6 +651,7 @@ private:
* *
* This is a internal class, not part of the API (hence full documentation is in the cpp). * This is a internal class, not part of the API (hence full documentation is in the cpp).
*/ */
// TODO Convert this whole custom pointer to a C++11 std::shared_ptr with a custom deleter
class Ptr class Ptr
{ {
public: public:
@ -659,10 +660,8 @@ private:
// Copy constructor increments the ref counter // Copy constructor increments the ref counter
Ptr(const Ptr& aPtr); Ptr(const Ptr& aPtr);
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)
// Move constructor // Move constructor
Ptr(Ptr&& aPtr); Ptr(Ptr&& aPtr);
#endif
// Decrement the ref counter and finalize the sqlite3_stmt when it reaches 0 // Decrement the ref counter and finalize the sqlite3_stmt when it reaches 0
~Ptr(); ~Ptr();
@ -692,11 +691,6 @@ private:
}; };
private: private:
/// @{ Statement must be non-copyable
Statement(const Statement&);
Statement& operator=(const Statement&);
/// @}
/** /**
* @brief Check if a return code equals SQLITE_OK, else throw a SQLite::Exception with the SQLite error message * @brief Check if a return code equals SQLITE_OK, else throw a SQLite::Exception with the SQLite error message
* *

View File

@ -52,6 +52,10 @@ public:
*/ */
explicit Transaction(Database& aDatabase); explicit Transaction(Database& aDatabase);
// Transaction is non-copyable
Transaction(const Transaction&) = delete;
Transaction& operator=(const Transaction&) = delete;
/** /**
* @brief Safely rollback the transaction if it has not been committed. * @brief Safely rollback the transaction if it has not been committed.
*/ */
@ -62,12 +66,6 @@ public:
*/ */
void commit(); void commit();
private:
// Transaction must be non-copyable
Transaction(const Transaction&);
Transaction& operator=(const Transaction&);
/// @}
private: private:
Database& mDatabase; ///< Reference to the SQLite Database Connection Database& mDatabase; ///< Reference to the SQLite Database Connection
bool mbCommited; ///< True when commit has been called bool mbCommited; ///< True when commit has been called

View File

@ -1,69 +0,0 @@
/**
* @file Utils.h
* @ingroup SQLiteCpp
* @brief Shared utility macros and functions.
*
* Copyright (c) 2013-2020 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#pragma once
#include <cstddef>
/**
* @brief A macro to disallow the copy constructor and operator= functions.
*
* This should be used in the private: declarations for a class
*
* @param[in] TypeName Class name to protect
*/
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
#ifdef _MSC_VER
#if _MSC_VER < 1600
/// A macro to enable the use of the nullptr keyword (NULL on older MSVC compilers, as they do not accept "nullptr_t")
#ifndef nullptr
#define nullptr NULL
#endif // nullptr
#endif // _MSC_VER < 1600
#elif defined(__APPLE__) // AppleClang
#elif defined(__clang__) && __has_feature(cxx_nullptr) // Clang 3.0+
#else // GCC or older Clang
#if (__cplusplus < 201103L) && !defined(__GXX_EXPERIMENTAL_CXX0X__) // before C++11 on GCC4.7 and Visual Studio 2010
#ifndef HAVE_NULLPTR
#define HAVE_NULLPTR ///< A macro to avoid double definition of nullptr
/**
* @brief nullptr_t is the type of the null pointer literal, nullptr.
*/
class nullptr_t {
public:
template<typename T>
inline operator T* () const { ///< convertible to any type of null non-member pointer...
return 0;
}
template<typename C, typename T>
inline operator T C::* () const { ///< convertible to any type of null member pointer...
return 0;
}
private:
void operator&() const; ///< Can't take address of nullptr NOLINT
};
/**
* @brief Better way to enable nullptr on older GCC/Clang compilers
*/
const nullptr_t nullptr = {};
#endif // HAVE_NULLPTR
#endif // (__cplusplus < 201103L) && !defined(__GXX_EXPERIMENTAL_CXX0X__)
#endif // _MSC_VER
// A macro for snprintf support in Visual Studio
#if defined(_MSC_VER) && _MSC_VER < 1500
#define snprintf _snprintf
#endif

View File

@ -12,8 +12,6 @@
*/ */
#pragma once #pragma once
#if (__cplusplus >= 201103L) || ( defined(_MSC_VER) && (_MSC_VER >= 1800) ) // c++11: Visual Studio 2013
#include <SQLiteCpp/Statement.h> #include <SQLiteCpp/Statement.h>
#if (__cplusplus >= 201402L) || ( defined(_MSC_VER) && (_MSC_VER >= 1900) ) // c++14: Visual Studio 2015 #if (__cplusplus >= 201402L) || ( defined(_MSC_VER) && (_MSC_VER >= 1900) ) // c++14: Visual Studio 2015
@ -98,5 +96,3 @@ void bind(SQLite::Statement& query, const std::tuple<Types...> &tuple, std::inde
#endif // c++14 #endif // c++14
} // namespace SQLite } // namespace SQLite
#endif // c++11

View File

@ -22,57 +22,36 @@ namespace SQLite
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 = sqlite3_backup_init(aDestDatabase.getHandle(), mpSQLiteBackup = sqlite3_backup_init(aDestDatabase.getHandle(),
apDestDatabaseName, apDestDatabaseName,
aSrcDatabase.getHandle(), aSrcDatabase.getHandle(),
apSrcDatabaseName); apSrcDatabaseName);
if (NULL == mpSQLiteBackup) if (nullptr == 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
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) Backup(aDestDatabase, aDestDatabaseName.c_str(), aSrcDatabase, aSrcDatabaseName.c_str())
{ {
mpSQLiteBackup = sqlite3_backup_init(aDestDatabase.getHandle(),
aDestDatabaseName.c_str(),
aSrcDatabase.getHandle(),
aSrcDatabaseName.c_str());
if (NULL == mpSQLiteBackup)
{
// If an error occurs, the error code and message are attached to the destination database connection.
throw SQLite::Exception(aDestDatabase.getHandle());
}
} }
// Initialize resource for SQLite database backup
Backup::Backup(Database &aDestDatabase, Database &aSrcDatabase) : Backup::Backup(Database &aDestDatabase, Database &aSrcDatabase) :
mpSQLiteBackup(NULL) Backup(aDestDatabase, "main", aSrcDatabase, "main")
{ {
mpSQLiteBackup = sqlite3_backup_init(aDestDatabase.getHandle(),
"main",
aSrcDatabase.getHandle(),
"main");
if (NULL == mpSQLiteBackup)
{
// If an error occurs, the error code and message are attached to the destination database connection.
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 (mpSQLiteBackup)
{ {
sqlite3_backup_finish(mpSQLiteBackup); sqlite3_backup_finish(mpSQLiteBackup);
} }

View File

@ -26,65 +26,59 @@ 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), mStmtPtr(aStmtPtr),
mIndex(aIndex) mIndex(aIndex)
{ {
} }
// Finalize and unregister the SQL query from the SQLite Database Connection.
Column::~Column()
{
// 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
{ {
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
{ {
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
{ {
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
{ {
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
{ {
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
{ {
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
{ {
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
{ {
return sqlite3_column_blob(mStmtPtr, mIndex); return sqlite3_column_blob(mStmtPtr, mIndex);
} }
@ -102,13 +96,13 @@ std::string Column::getString() const
} }
// 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
{ {
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
{ {
return sqlite3_column_bytes(mStmtPtr, mIndex); return sqlite3_column_bytes(mStmtPtr, mIndex);
} }

View File

@ -37,13 +37,13 @@ const char* VERSION = SQLITE_VERSION;
const int VERSION_NUMBER = SQLITE_VERSION_NUMBER; 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
{ {
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
{ {
return sqlite3_libversion_number(); return sqlite3_libversion_number();
} }
@ -70,27 +70,6 @@ Database::Database(const char* apFilename,
} }
} }
// Open the provided database UTF-8 filename with SQLite::OPEN_xxx provided flags.
Database::Database(const std::string& aFilename,
const int aFlags /* = SQLite::OPEN_READONLY*/,
const int aBusyTimeoutMs /* = 0 */,
const std::string& aVfs /* = "" */) :
mpSQLite(nullptr),
mFilename(aFilename)
{
const int ret = sqlite3_open_v2(aFilename.c_str(), &mpSQLite, aFlags, aVfs.empty() ? nullptr : aVfs.c_str());
if (SQLITE_OK != ret)
{
const SQLite::Exception exception(mpSQLite, ret); // must create before closing
sqlite3_close(mpSQLite); // close is required even in case of error on opening
throw exception;
}
if (aBusyTimeoutMs > 0)
{
setBusyTimeout(aBusyTimeoutMs);
}
}
// Close the SQLite database connection. // Close the SQLite database connection.
Database::~Database() Database::~Database()
{ {
@ -156,31 +135,31 @@ bool Database::tableExists(const char* apTableName)
} }
// 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
{ {
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
{ {
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
{ {
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
{ {
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
{ {
return sqlite3_errmsg(mpSQLite); return sqlite3_errmsg(mpSQLite);
} }

View File

@ -16,19 +16,6 @@
namespace SQLite namespace SQLite
{ {
Exception::Exception(const char* aErrorMessage) :
std::runtime_error(aErrorMessage),
mErrcode(-1), // 0 would be SQLITE_OK, which doesn't make sense
mExtendedErrcode(-1)
{
}
Exception::Exception(const std::string& aErrorMessage) :
std::runtime_error(aErrorMessage),
mErrcode(-1), // 0 would be SQLITE_OK, which doesn't make sense
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),
@ -36,13 +23,6 @@ Exception::Exception(const char* aErrorMessage, int ret) :
{ {
} }
Exception::Exception(const std::string& aErrorMessage, int ret) :
std::runtime_error(aErrorMessage),
mErrcode(ret),
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)),
@ -58,7 +38,7 @@ Exception::Exception(sqlite3* apSQLite, int ret) :
} }
// 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
{ {
return sqlite3_errstr(mErrcode); return sqlite3_errstr(mErrcode);
} }

View File

@ -20,7 +20,6 @@
namespace SQLite namespace SQLite
{ {
// 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), mQuery(apQuery),
mStmtPtr(aDatabase.mpSQLite, mQuery), // prepare the SQL query, and ref count (needs Database friendship) mStmtPtr(aDatabase.mpSQLite, mQuery), // prepare the SQL query, and ref count (needs Database friendship)
@ -31,18 +30,6 @@ Statement::Statement(Database &aDatabase, const char* apQuery) :
mColumnCount = sqlite3_column_count(mStmtPtr); mColumnCount = sqlite3_column_count(mStmtPtr);
} }
// Compile and register the SQL query for the provided SQLite Database Connection
Statement::Statement(Database &aDatabase, const std::string& aQuery) :
mQuery(aQuery),
mStmtPtr(aDatabase.mpSQLite, mQuery), // prepare the SQL query, and ref count (needs Database friendship)
mColumnCount(0),
mbHasRow(false),
mbDone(false)
{
mColumnCount = sqlite3_column_count(mStmtPtr);
}
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)
Statement::Statement(Statement&& aStatement) noexcept : Statement::Statement(Statement&& aStatement) noexcept :
mQuery(std::move(aStatement.mQuery)), mQuery(std::move(aStatement.mQuery)),
mStmtPtr(std::move(aStatement.mStmtPtr)), mStmtPtr(std::move(aStatement.mStmtPtr)),
@ -54,13 +41,6 @@ Statement::Statement(Statement&& aStatement) noexcept :
aStatement.mbHasRow = false; aStatement.mbHasRow = false;
aStatement.mbDone = false; aStatement.mbDone = false;
} }
#endif
// Finalize and unregister the SQL query from the SQLite Database Connection.
Statement::~Statement()
{
// 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()
@ -408,19 +388,19 @@ int Statement::getBindParameterCount() const noexcept
} }
// 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
{ {
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
{ {
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
{ {
return sqlite3_errmsg(mStmtPtr); return sqlite3_errmsg(mStmtPtr);
} }
@ -477,7 +457,6 @@ Statement::Ptr::Ptr(const Statement::Ptr& aPtr) :
++(*mpRefCount); ++(*mpRefCount);
} }
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)
Statement::Ptr::Ptr(Ptr&& aPtr) : Statement::Ptr::Ptr(Ptr&& aPtr) :
mpSQLite(aPtr.mpSQLite), mpSQLite(aPtr.mpSQLite),
mpStmt(aPtr.mpStmt), mpStmt(aPtr.mpStmt),
@ -487,7 +466,6 @@ Statement::Ptr::Ptr(Ptr&& aPtr) :
aPtr.mpStmt = NULL; aPtr.mpStmt = NULL;
aPtr.mpRefCount = NULL; aPtr.mpRefCount = NULL;
} }
#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

View File

@ -3,7 +3,7 @@
* @ingroup SQLiteCpp * @ingroup SQLiteCpp
* @brief A Transaction is way to group multiple SQL statements into an atomic secured operation. * @brief A Transaction is way to group multiple SQL statements into an atomic secured operation.
* *
* Copyright (c) 2012-2013 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)