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
- Start of a new thin C++ SQLite wrapper
Apr 2 2012
- The wrapper is functionnal
- Added documentation and examples
- Publication on GitHub
Version 0.1.0 - Apr 4 2012
- Added a Database::exec() methode to execute simple SQL statement
- Added a version number like in sqlite3.h, starting with 0.1.0
Version 0.2.0 - Apr 11 2012
- Added getLastInsertId() and setBusyTimout()
- Added bind() by name methods
Version 0.3.0 - Apr 16 2012
- Added an easy wrapper Database::execAngGet()
Version 0.4.0 - Apr 23 2012
- Added a Database::tableExists() easy to use function
Dec 10 2012
- Added a Statement::exec() method to execute a one-step query with no expected result
Version 0.5.0 - March 9 2013
- Added assert() on errors on destructors
- Added getBytes()
- Added getBlob(), getType() and isInteger/isFloat/isText/isBlob/isNull
- Added bind() for binary blob data
Version 0.5.1 - April 7 2013
- Added Column::getName()
Version 0.6.0 - November 22 2013
- Renamed Column::getName() to Column::getOriginName()
- Added Column::getName()
Version 0.7.0 - January 9 2014
- Added Database::createFunction()
- Added std::string version of existing APIs
- Improved CMake with more build options and Doxygen auto-detection
Version 0.8.0 - February 26 2014
- 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)
Version 1.0.0 - May 3 2015
- Public headers file moved to include/ dir
- Added support to biicode in CMakeLists.txt
- Added Unit Tests
- Added aBusyTimeoutMs parameter to Database() constructors
- Added Database::getTotalChanges()
- Added Database::getErrorCode()
- Added Statement::clearBindings()
- Added Statement::getColumn(aName)
- Added Statement::getErrorCode()
- Added Statement::getColumnName(aIndex)
- Added Statement::getColumnOriginName(aIndex)
Version 1.1.0 - May 18 2015
- Fixed valgrind error on Database destructor
- Added Database::loadExtension
Version 1.2.0 - September 9 2015
- Fixed build with GCC 5.1.0
- Fixed MSVC release build warning
- Fixed CppDepends warnings
- Updated documentation on installation
- Added Database::getHandle()
Version 1.3.0 - November 1 2015
- Fixed build with Visual Studio 2015
- Further improvements to README
- Added Backup class
Version 1.3.1 - February 10 2016
- 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)
- Remove warnings
- Remove biicode support (defunct service, servers will shutdown the 16th of February 2016)
Version 2.0.0 - July 25 2016
- 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
- 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
- Better exception messages when Statements fail PR #84
- 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::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
- Rename Backup::remainingPageCount()/totalPageCount() to Backup::getRemainingPageCount()/getTotalPageCount()
- Remove Column::errmsg() method : use Database or Statement equivalents
- 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
Version 2.1.0 - July 18 2017
- 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 link error (inline in cpp) and compiler warnings (unused variable...) #96
- Added ability to open encrypted databases (using SQLCipher, eg. libsqlcipher-dev) #107
- Added convenience functions for constructing objects from a row #114
- Added CMake install step #118
- Fix warnings #119
- Make cpplint.py Python-3 compatible #120
- Link libssp when targeted #100
- Removed redundant const #102
Version 2.2.0 - Sept 19 2017
- Update SQLite3 from 3.19.3 to latest 3.20.1 (2017-08-24) #143
- Added tryExecuteStep and tryReset #142
- Removed virtual keywords from destructors #140
- Removed misplaced noexcept keyword #139
- Improved Exception class C++ conformance #138
- Fix warnings #134
- Deprecated Statement::IsOk() to Statement::HasRow()
Version 2.3.0 - March 3 2019
- Update SQLite3 from 3.20.1 to latest 3.27.2 (2019-02-25) #183 #187
- Add Statement binding for long int values #147
- Allows long int for bind when used with name #148
- More cmake instructions for Linux #151
- Add comparison with sqlite_orm #141
- Fix Statement::bind truncates long integer to 32 bits on x86_64 Linux #155
- Add a move constructor to Database #157
- Added tests for all MSVC compilers available on AppVeyor (2013, 2015, 2017) #169
- Update VariadicBind.h #172
- Better CMake compatibility #170
- Add implicit cast operator to char and short types #179 #180
Version 2.4.0 - August 25 2019
- Update SQLite3 from 3.27.2 to 3.29.0 (2019-07-10) #217
- #191 CMake Warning line 299
- #190 Implement move constructors
- #192 Add wrapper for bind parameter count
- #197 Add tuple_bind and execute_many (requested by #24)
- #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
- #211 Implement Database::backup()
- #215 Disable implicit fallthrough warning when building internal sqlite3
- #216 Set PROJECT_VERSION to fix CMP0048 Policy warnings
Version 2.5.0 - December 31 2019
- Update SQLite3 from 3.29.0 to 3.30.1 (2019-10-10)
- 100% Unit Test coverage
- #212 fix sqlite3 compile properties (jzt)
- #219 Disable cast-function-type warning when building internal sqlite (zxey)
- #230 Fixed installation on other than Ubuntu GNU/Linux distributions (xvitaly)
- #228 use transitive compile definitions via cmake (BioDataAnalysis/emmenlau)
- #232 Added support of packaged GTest for running unit tests (xvitaly)
- #231 Added SOVERSION field for shared library (xvitaly)
- #229 Explicitly find and link against system sqlite library (xvitaly)
- #235 Added support for cmake dependencies and version information (BioDataAnalysis/emmenlau)
- #249 Added SQLite header parsing functionality and associated tests (patrick--)
Mar 30 2012
- Start of a new thin C++ SQLite wrapper
Apr 2 2012
- The wrapper is functionnal
- Added documentation and examples
- Publication on GitHub
Version 0.1.0 - Apr 4 2012
- Added a Database::exec() methode to execute simple SQL statement
- Added a version number like in sqlite3.h, starting with 0.1.0
Version 0.2.0 - Apr 11 2012
- Added getLastInsertId() and setBusyTimout()
- Added bind() by name methods
Version 0.3.0 - Apr 16 2012
- Added an easy wrapper Database::execAngGet()
Version 0.4.0 - Apr 23 2012
- Added a Database::tableExists() easy to use function
Dec 10 2012
- Added a Statement::exec() method to execute a one-step query with no expected result
Version 0.5.0 - March 9 2013
- Added assert() on errors on destructors
- Added getBytes()
- Added getBlob(), getType() and isInteger/isFloat/isText/isBlob/isNull
- Added bind() for binary blob data
Version 0.5.1 - April 7 2013
- Added Column::getName()
Version 0.6.0 - November 22 2013
- Renamed Column::getName() to Column::getOriginName()
- Added Column::getName()
Version 0.7.0 - January 9 2014
- Added Database::createFunction()
- Added std::string version of existing APIs
- Improved CMake with more build options and Doxygen auto-detection
Version 0.8.0 - February 26 2014
- 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)
Version 1.0.0 - May 3 2015
- Public headers file moved to include/ dir
- Added support to biicode in CMakeLists.txt
- Added Unit Tests
- Added aBusyTimeoutMs parameter to Database() constructors
- Added Database::getTotalChanges()
- Added Database::getErrorCode()
- Added Statement::clearBindings()
- Added Statement::getColumn(aName)
- Added Statement::getErrorCode()
- Added Statement::getColumnName(aIndex)
- Added Statement::getColumnOriginName(aIndex)
Version 1.1.0 - May 18 2015
- Fixed valgrind error on Database destructor
- Added Database::loadExtension
Version 1.2.0 - September 9 2015
- Fixed build with GCC 5.1.0
- Fixed MSVC release build warning
- Fixed CppDepends warnings
- Updated documentation on installation
- Added Database::getHandle()
Version 1.3.0 - November 1 2015
- Fixed build with Visual Studio 2015
- Further improvements to README
- Added Backup class
Version 1.3.1 - February 10 2016
- 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)
- Remove warnings
- Remove biicode support (defunct service, servers will shutdown the 16th of February 2016)
Version 2.0.0 - July 25 2016
- 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
- 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
- Better exception messages when Statements fail PR #84
- 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::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
- Rename Backup::remainingPageCount()/totalPageCount() to Backup::getRemainingPageCount()/getTotalPageCount()
- Remove Column::errmsg() method : use Database or Statement equivalents
- 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
Version 2.1.0 - July 18 2017
- 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 link error (inline in cpp) and compiler warnings (unused variable...) #96
- Added ability to open encrypted databases (using SQLCipher, eg. libsqlcipher-dev) #107
- Added convenience functions for constructing objects from a row #114
- Added CMake install step #118
- Fix warnings #119
- Make cpplint.py Python-3 compatible #120
- Link libssp when targeted #100
- Removed redundant const #102
Version 2.2.0 - Sept 19 2017
- Update SQLite3 from 3.19.3 to latest 3.20.1 (2017-08-24) #143
- Added tryExecuteStep and tryReset #142
- Removed virtual keywords from destructors #140
- Removed misplaced noexcept keyword #139
- Improved Exception class C++ conformance #138
- Fix warnings #134
- Deprecated Statement::isOk() to Statement::hasRow()
Version 2.3.0 - March 3 2019
- Update SQLite3 from 3.20.1 to latest 3.27.2 (2019-02-25) #183 #187
- Add Statement binding for long int values #147
- Allows long int for bind when used with name #148
- More cmake instructions for Linux #151
- Add comparison with sqlite_orm #141
- Fix Statement::bind truncates long integer to 32 bits on x86_64 Linux #155
- Add a move constructor to Database #157
- Added tests for all MSVC compilers available on AppVeyor (2013, 2015, 2017) #169
- Update VariadicBind.h #172
- Better CMake compatibility #170
- Add implicit cast operator to char and short types #179 #180
Version 2.4.0 - August 25 2019
- Update SQLite3 from 3.27.2 to 3.29.0 (2019-07-10) #217
- #191 CMake Warning line 299
- #190 Implement move constructors
- #192 Add wrapper for bind parameter count
- #197 Add tuple_bind and execute_many (requested by #24)
- #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
- #211 Implement Database::backup()
- #215 Disable implicit fallthrough warning when building internal sqlite3
- #216 Set PROJECT_VERSION to fix CMP0048 Policy warnings
Version 2.5.0 - December 31 2019
- Update SQLite3 from 3.29.0 to 3.30.1 (2019-10-10)
- 100% Unit Test coverage
- #212 fix sqlite3 compile properties (jzt)
- #219 Disable cast-function-type warning when building internal sqlite (zxey)
- #230 Fixed installation on other than Ubuntu GNU/Linux distributions (xvitaly)
- #228 use transitive compile definitions via cmake (BioDataAnalysis/emmenlau)
- #232 Added support of packaged GTest for running unit tests (xvitaly)
- #231 Added SOVERSION field for shared library (xvitaly)
- #229 Explicitly find and link against system sqlite library (xvitaly)
- #235 Added support for cmake dependencies and version information (BioDataAnalysis/emmenlau)
- #249 Added SQLite header parsing functionality and associated tests (patrick--)
- #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
# or copy at http://opensource.org/licenses/MIT)
cmake_minimum_required(VERSION 2.8.12) # first version with add_compile_options()
if (CMAKE_VERSION VERSION_LESS 3.0)
project(SQLiteCpp)
set(PROJECT_VERSION_MAJOR 2)
set(PROJECT_VERSION_MINOR 5)
set(PROJECT_VERSION_PATCH 0)
set(PROJECT_VERSION "2.5.0")
else()
cmake_policy(SET CMP0048 NEW)
project(SQLiteCpp VERSION "2.5.0")
endif()
cmake_minimum_required(VERSION 3.1) # for "CMAKE_CXX_STANDARD" version
project(SQLiteCpp VERSION "2.99")
# SQLiteC++ 3.x now requires C++11 compiler
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
message (STATUS "CMake version: ${CMAKE_VERSION}")
message (STATUS "Project version: ${PROJECT_VERSION}")
# Define useful variables to handle OS differences:
if (WIN32)
@ -39,9 +35,9 @@ if (MSVC)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
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)
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)
else (MSVC)
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/Statement.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/ExecuteMany.h
)
@ -145,9 +140,13 @@ set(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
.editorconfig
.gitbugtraq
.github/workflows/actions.yml
.gitignore
.gitmodules
.travis.yml
appveyor.yml
build.bat

View File

@ -38,7 +38,7 @@ PROJECT_NAME = SQLiteC++
# could be handy for archiving the generated documentation or if some version
# 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
# 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:
- 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 keep dependencies to a minimum (STL and SQLite3)
- to be elegantly written with good C++11 design, STL, exceptions and RAII idiom
- to keep dependencies to a minimum (C++11 STL and SQLite3)
- to be portable
- to be light and fast
- 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
(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).
Each SQLiteC++ object must be constructed with a valid SQLite database connection,
and then is always valid until destroyed.
### Supported platforms:
Developements and tests are done under the following OSs:
- Ubuntu 14.04 (Travis CI)
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.
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)
- OS X 10.11 (Travis CI)
- Github Actions
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)
- Clang 3.5 and 3.8
- Xcode 8
- GCC 4.8.4, 5.3.0 and 7.1.1 (C++11, C++14, C++17)
- Clang 5
- Xcode 8 & 9
- Visual Studio Community 2019, 2017, and 2015 (AppVeyor)
### 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)
- 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),
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
)
```
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.
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
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)):
@ -136,7 +139,7 @@ Typical generic build for MS Visual Studio under Windows (from [build.bat](build
mkdir 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
cmake -DSQLITECPP_BUILD_EXAMPLES=ON -DSQLITECPP_BUILD_TESTS=ON ..
@ -169,7 +172,7 @@ ctest --output-on-failure
#### 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.
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
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
using the AppVeyor countinuous integration service.
using the AppVeyor continuous integration service.
Detailed results can be seen online:
- 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)
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
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 (!?)
Missing unit tests in v2.0.0:
@ -21,7 +20,7 @@ Advanced missing features:
- #39: SAVEPOINT https://www.sqlite.org/lang_savepoint.html
- Add optional usage of experimental sqlite3_trace() function to enable statistics
- Agregate ?
- Aggregate ?
- support for different transaction mode ? NO: too specific
- operator<< binding ? NO: redundant with bind()

View File

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

View File

@ -52,26 +52,18 @@ public:
* @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
*/
Column(Statement::Ptr& aStmtPtr, int aIndex) noexcept; // nothrow
/// Simple destructor
~Column();
Column(Statement::Ptr& aStmtPtr, int aIndex) noexcept;
// default destructor: the finalization will be done by the destructor of the last shared pointer
// default copy constructor and assignment operator are perfectly suited :
// 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)
*
* @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
/**
@ -81,31 +73,31 @@ public:
* - when building the SQLite library itself (which is the case for the Debian libsqlite3 binary for instance),
* - and also when compiling this wrapper.
*/
const char* getOriginName() const noexcept; // nothrow
const char* getOriginName() const noexcept;
#endif
/// 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).
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).
long long getInt64() const noexcept; // nothrow
long long getInt64() const noexcept;
/// 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.
*
* @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).
*/
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.
*
* @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).
*/
const void* getBlob() const noexcept; // nothrow
const void* getBlob() const noexcept;
/**
* @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),
* 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)
inline bool isInteger() const noexcept // nothrow
bool isInteger() const noexcept
{
return (SQLite::INTEGER == getType());
}
/// 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());
}
/// 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());
}
/// 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());
}
/// 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());
}
@ -161,68 +153,68 @@ public:
int getBytes() const noexcept;
/// 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 ();
}
/// Inline cast operator to char
inline operator char() const
operator char() const
{
return static_cast<char>(getInt());
}
/// Inline cast operator to unsigned char
inline operator unsigned char() const
operator unsigned char() const
{
return static_cast<unsigned char>(getInt());
}
/// Inline cast operator to short
inline operator short() const
operator short() const
{
return static_cast<short>(getInt());
}
/// Inline cast operator to unsigned short
inline operator unsigned short() const
operator unsigned short() const
{
return static_cast<unsigned short>(getInt());
}
/// Inline cast operator to int
inline operator int() const
operator int() const
{
return getInt();
}
/// Inline cast operator to 32bits unsigned integer
inline operator unsigned int() const
operator unsigned int() const
{
return getUInt();
}
#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 operator long() const
operator long() const
{
return getInt();
}
/// Inline cast operator to 32bits unsigned long
inline operator unsigned long() const
operator unsigned long() const
{
return getUInt();
}
#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 operator long() const
operator long() const
{
return getInt64();
}
#endif
/// Inline cast operator to 64bits integer
inline operator long long() const
operator long long() const
{
return getInt64();
}
/// Inline cast operator to double
inline operator double() const
operator double() const
{
return getDouble();
}
@ -231,7 +223,7 @@ public:
*
* @see getText
*/
inline operator const char*() const
operator const char*() const
{
return getText();
}
@ -240,21 +232,11 @@ public:
*
* @see getBlob
*/
inline operator const void*() const
operator const void*() const
{
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
*
@ -262,11 +244,10 @@ public:
*
* @see getString
*/
inline operator std::string() const
operator std::string() const
{
return getString();
}
#endif
private:
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);
#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
template<typename T, int N>

View File

@ -11,7 +11,6 @@
#pragma once
#include <SQLiteCpp/Column.h>
#include <SQLiteCpp/Utils.h> // definition of nullptr for C++98/C++03 compilers
#include <string.h>
// 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")
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 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
const char* getLibVersion() noexcept; // nothrow
const char* getLibVersion() noexcept;
/// 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.
// Official documentation for fields: https://www.sqlite.org/fileformat.html#the_database_header
@ -143,21 +142,26 @@ public:
Database(const std::string& aFilename,
const int aFlags = SQLite::OPEN_READONLY,
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.
*
* @param[in] aDatabase Database to move
*/
inline Database(Database&& aDatabase) noexcept :
Database(Database&& aDatabase) noexcept :
mpSQLite(aDatabase.mpSQLite),
mFilename(std::move(aDatabase.mFilename))
{
aDatabase.mpSQLite = nullptr;
}
#endif
// Database is non-copyable
Database(const Database&) = delete;
Database& operator=(const Database&) = delete;
/**
* @brief Close the SQLite database connection.
@ -165,6 +169,8 @@ public:
* All SQLite statements must have been finalized before,
* 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
*/
~Database();
@ -222,7 +228,7 @@ public:
*
* @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());
}
@ -267,7 +273,7 @@ public:
*
* @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());
}
@ -296,7 +302,7 @@ public:
*
* @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());
}
@ -309,20 +315,20 @@ public:
*
* @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).
int getTotalChanges() const noexcept; // nothrow
int getTotalChanges() const noexcept;
/// 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).
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).
const char* getErrorMsg() const noexcept; // nothrow
const char* getErrorMsg() const noexcept;
/// Return the filename used to open the database.
const std::string& getFilename() const noexcept // nothrow
const std::string& getFilename() const noexcept
{
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.
*/
inline sqlite3* getHandle() const noexcept // nothrow
sqlite3* getHandle() const noexcept
{
return mpSQLite;
}
@ -384,7 +390,7 @@ public:
*
* @throw SQLite::Exception in case of error
*/
inline void createFunction(const std::string& aFuncName,
void createFunction(const std::string& aFuncName,
int aNbArg,
bool abDeterministic,
void* apApp,
@ -490,16 +496,10 @@ public:
*/
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
*/
inline void check(const int aRet) const
void check(const int aRet) const
{
if (SQLite::OK != aRet)
{
@ -508,6 +508,7 @@ private:
}
private:
// TODO: use std::unique_ptr with a custom deleter to call sqlite3_close()
sqlite3* mpSQLite; ///< Pointer to SQLite Database Connection Handle
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
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
{
@ -49,18 +30,28 @@ public:
* @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] ret Return value from function call that failed.
*/
explicit Exception(const char* aErrorMessage);
explicit Exception(const std::string& aErrorMessage);
Exception(const char* aErrorMessage, int ret);
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.
*
* @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);
Exception(const std::string& aErrorMessage, int ret);
explicit Exception(const char* aErrorMessage) :
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.
@ -78,19 +69,19 @@ public:
Exception(sqlite3* apSQLite, int ret);
/// Return the result code (if any, otherwise -1).
inline int getErrorCode() const noexcept // nothrow
int getErrorCode() const noexcept
{
return mErrcode;
}
/// Return the extended numeric result code (if any, otherwise -1).
inline int getExtendedErrorCode() const noexcept // nothrow
int getExtendedErrorCode() const noexcept
{
return mExtendedErrcode;
}
/// Return a string, solely based on the error code
const char* getErrorStr() const noexcept; // nothrow
const char* getErrorStr() const noexcept;
private:
int mErrcode; ///< Error code value

View File

@ -40,5 +40,5 @@
*
* 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_NUMBER 2005000 // 2.5.0
#define SQLITECPP_VERSION "3.00.00" // 3.0.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.
*/
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.
*
* @param[in] aStatement Statement to move
*/
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.
~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.
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)
*/
inline void bind(const std::string& aName, const int aValue)
void bind(const std::string& aName, const int 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)
*/
inline void bind(const std::string& aName, const unsigned aValue)
void bind(const std::string& aName, const unsigned 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)
*/
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);
}
/**
* @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);
}
@ -331,7 +336,7 @@ public:
*
* @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);
}
@ -340,7 +345,7 @@ public:
*
* @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);
}
@ -349,7 +354,7 @@ public:
*
* @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);
}
@ -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.
*/
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);
}
@ -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.
*/
inline void bindNoCopy(const std::string& aName, const char* apValue)
void bindNoCopy(const std::string& aName, const char* 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.
*/
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);
}
@ -389,7 +394,7 @@ public:
*
* @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());
}
@ -400,7 +405,7 @@ public:
* @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
* thru the getColumn() method
* through the getColumn() method
*
* @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.
@ -510,7 +515,7 @@ public:
*/
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
*
@ -622,11 +627,6 @@ public:
{
return mbHasRow;
}
/// @deprecated, use #hasRow()
inline bool isOk() const
{
return hasRow();
}
/// true when the last executeStep() had no more row to fetch
inline bool isDone() const
{
@ -637,11 +637,11 @@ public:
int getBindParameterCount() const noexcept;
/// 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).
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).
const char* getErrorMsg() const noexcept; // nothrow
const char* getErrorMsg() const noexcept;
private:
/**
@ -651,6 +651,7 @@ private:
*
* 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
{
public:
@ -659,10 +660,8 @@ private:
// Copy constructor increments the ref counter
Ptr(const Ptr& aPtr);
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)
// Move constructor
Ptr(Ptr&& aPtr);
#endif
// Decrement the ref counter and finalize the sqlite3_stmt when it reaches 0
~Ptr();
@ -692,11 +691,6 @@ 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
*

View File

@ -52,6 +52,10 @@ public:
*/
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.
*/
@ -62,12 +66,6 @@ public:
*/
void commit();
private:
// Transaction must be non-copyable
Transaction(const Transaction&);
Transaction& operator=(const Transaction&);
/// @}
private:
Database& mDatabase; ///< Reference to the SQLite Database Connection
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
#if (__cplusplus >= 201103L) || ( defined(_MSC_VER) && (_MSC_VER >= 1800) ) // c++11: Visual Studio 2013
#include <SQLiteCpp/Statement.h>
#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
} // namespace SQLite
#endif // c++11

View File

@ -22,57 +22,36 @@ namespace SQLite
Backup::Backup(Database& aDestDatabase,
const char* apDestDatabaseName,
Database& aSrcDatabase,
const char* apSrcDatabaseName) :
mpSQLiteBackup(NULL)
const char* apSrcDatabaseName)
{
mpSQLiteBackup = sqlite3_backup_init(aDestDatabase.getHandle(),
apDestDatabaseName,
aSrcDatabase.getHandle(),
apSrcDatabaseName);
if (NULL == mpSQLiteBackup)
if (nullptr == 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,
const std::string& aDestDatabaseName,
Database& aSrcDatabase,
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) :
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
Backup::~Backup()
{
if (NULL != mpSQLiteBackup)
if (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.
Column::Column(Statement::Ptr& aStmtPtr, int aIndex) noexcept : // nothrow
Column::Column(Statement::Ptr& aStmtPtr, int aIndex) noexcept :
mStmtPtr(aStmtPtr),
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)
const char* Column::getName() const noexcept // nothrow
const char* Column::getName() const noexcept
{
return sqlite3_column_name(mStmtPtr, mIndex);
}
#ifdef SQLITE_ENABLE_COLUMN_METADATA
// 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);
}
#endif
// 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 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 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 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 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));
return (pText?pText:apDefaultValue);
}
// 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);
}
@ -102,13 +96,13 @@ std::string Column::getString() const
}
// 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 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);
}

View File

@ -37,13 +37,13 @@ const char* VERSION = SQLITE_VERSION;
const int VERSION_NUMBER = SQLITE_VERSION_NUMBER;
// Return SQLite version string using runtime call to the compiled library
const char* getLibVersion() noexcept // nothrow
const char* getLibVersion() noexcept
{
return sqlite3_libversion();
}
// Return SQLite version number using runtime call to the compiled library
int getLibVersionNumber() noexcept // nothrow
int getLibVersionNumber() noexcept
{
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.
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.
long long Database::getLastInsertRowid() const noexcept // nothrow
long long Database::getLastInsertRowid() const noexcept
{
return sqlite3_last_insert_rowid(mpSQLite);
}
// 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 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 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 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);
}

View File

@ -16,19 +16,6 @@
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) :
std::runtime_error(aErrorMessage),
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) :
std::runtime_error(sqlite3_errmsg(apSQLite)),
mErrcode(sqlite3_errcode(apSQLite)),
@ -58,7 +38,7 @@ Exception::Exception(sqlite3* apSQLite, int ret) :
}
// 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);
}

View File

@ -20,7 +20,6 @@
namespace SQLite
{
// Compile and register the SQL query for the provided SQLite Database Connection
Statement::Statement(Database &aDatabase, const char* apQuery) :
mQuery(apQuery),
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);
}
// 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 :
mQuery(std::move(aStatement.mQuery)),
mStmtPtr(std::move(aStatement.mStmtPtr)),
@ -54,13 +41,6 @@ Statement::Statement(Statement&& aStatement) noexcept :
aStatement.mbHasRow = 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)
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).
int Statement::getErrorCode() const noexcept // nothrow
int Statement::getErrorCode() const noexcept
{
return sqlite3_errcode(mStmtPtr);
}
// 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 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);
}
@ -477,7 +457,6 @@ Statement::Ptr::Ptr(const Statement::Ptr& aPtr) :
++(*mpRefCount);
}
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)
Statement::Ptr::Ptr(Ptr&& aPtr) :
mpSQLite(aPtr.mpSQLite),
mpStmt(aPtr.mpStmt),
@ -487,7 +466,6 @@ Statement::Ptr::Ptr(Ptr&& aPtr) :
aPtr.mpStmt = NULL;
aPtr.mpRefCount = NULL;
}
#endif
/**
* @brief Decrement the ref counter and finalize the sqlite3_stmt when it reaches 0

View File

@ -3,7 +3,7 @@
* @ingroup SQLiteCpp
* @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
* or copy at http://opensource.org/licenses/MIT)