mirror of
https://github.com/cuberite/SQLiteCpp.git
synced 2025-08-04 09:46:02 -04:00
Merge pull request #252 Run Valgrind memcheck on Travis CI from SRombauts/travis-valgrind
Run Valgrind memcheck on Travis CI
This commit is contained in:
commit
d4bafc0e68
@ -11,4 +11,4 @@ end_of_line = lf
|
||||
# 2 space indentation for CI configuration
|
||||
[*.yml]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
indent_size = 2
|
||||
|
66
.travis.yml
66
.travis.yml
@ -16,25 +16,38 @@ matrix:
|
||||
# GCC on Linux
|
||||
##########################################################################
|
||||
|
||||
# GCC Debug build with GCov for coverage build
|
||||
- dist: bionic
|
||||
env:
|
||||
- cc=gcc
|
||||
- cxx=g++
|
||||
- CXXFLAGS=""
|
||||
- cc=gcc cxx=g++
|
||||
- BUILD_TYPE=Debug
|
||||
- ASAN=ON GCOV=ON
|
||||
- COVERALLS=true
|
||||
|
||||
# GCC Debug build with Valgrind instead of Address Sanitizer
|
||||
- dist: bionic
|
||||
env:
|
||||
- cc=gcc cxx=g++
|
||||
- BUILD_TYPE=Debug
|
||||
- VALGRIND=true
|
||||
|
||||
# GCC Release build
|
||||
- dist: bionic
|
||||
env:
|
||||
- cc=gcc cxx=g++
|
||||
- BUILD_TYPE=Release
|
||||
|
||||
- dist: xenial
|
||||
env:
|
||||
- cc=gcc
|
||||
- cxx=g++
|
||||
- CXXFLAGS=""
|
||||
- cc=gcc cxx=g++
|
||||
- BUILD_TYPE=Debug
|
||||
- ASAN=ON
|
||||
|
||||
- dist: trusty
|
||||
env:
|
||||
- cc=gcc
|
||||
- cxx=g++
|
||||
- CXXFLAGS=""
|
||||
- cc=gcc cxx=g++
|
||||
- BUILD_TYPE=Debug
|
||||
- ASAN=ON
|
||||
|
||||
##########################################################################
|
||||
# Clang on Linux
|
||||
@ -42,21 +55,21 @@ matrix:
|
||||
|
||||
- dist: bionic
|
||||
env:
|
||||
- cc=clang
|
||||
- cxx=clang++
|
||||
- CXXFLAGS=""
|
||||
- cc=clang cxx=clang++
|
||||
- BUILD_TYPE=Debug
|
||||
- ASAN=ON
|
||||
|
||||
- dist: xenial
|
||||
env:
|
||||
- cc=clang
|
||||
- cxx=clang++
|
||||
- CXXFLAGS=""
|
||||
- cc=clang cxx=clang++
|
||||
- BUILD_TYPE=Debug
|
||||
- ASAN=ON
|
||||
|
||||
- dist: trusty
|
||||
env:
|
||||
- cc=clang
|
||||
- cxx=clang++
|
||||
- CXXFLAGS=""
|
||||
- cc=clang cxx=clang++
|
||||
- BUILD_TYPE=Debug
|
||||
- ASAN=ON
|
||||
|
||||
##########################################################################
|
||||
# Clang on OSX
|
||||
@ -65,17 +78,17 @@ matrix:
|
||||
# Latest XCode
|
||||
- os: osx
|
||||
env:
|
||||
- cc=clang
|
||||
- cxx=clang++
|
||||
- CXXFLAGS=""
|
||||
- cc=clang cxx=clang++
|
||||
- BUILD_TYPE=Debug
|
||||
- ASAN=ON
|
||||
|
||||
# XCode 8.3
|
||||
- os: osx
|
||||
osx_image: xcode8.3
|
||||
env:
|
||||
- cc=clang
|
||||
- cxx=clang++
|
||||
- CXXFLAGS=""
|
||||
- cc=clang cxx=clang++
|
||||
- BUILD_TYPE=Debug
|
||||
- ASAN=ON
|
||||
|
||||
before_install:
|
||||
# Set the compiler environment variables properly
|
||||
@ -83,6 +96,7 @@ before_install:
|
||||
- export CXX=${cxx}
|
||||
- ${CC} --version
|
||||
- ${CXX} --version
|
||||
- if [[ "$VALGRIND" == "true" ]]; then sudo apt-get install -qq valgrind ; fi
|
||||
|
||||
install:
|
||||
# coveralls test coverage:
|
||||
@ -92,13 +106,15 @@ install:
|
||||
before_script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_BUILD_TYPE=Debug -DSQLITECPP_USE_ASAN=ON -DSQLITECPP_USE_GCOV=ON -DSQLITECPP_BUILD_EXAMPLES=ON -DSQLITECPP_BUILD_TESTS=ON ..
|
||||
- cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DSQLITECPP_USE_ASAN=$ASAN -DSQLITECPP_USE_GCOV=$GCOV -DSQLITECPP_BUILD_EXAMPLES=ON -DSQLITECPP_BUILD_TESTS=ON ..
|
||||
|
||||
# build examples, and run tests (ie make & make test)
|
||||
script:
|
||||
- cmake --build .
|
||||
- export ASAN_OPTIONS=verbosity=1:debug=1
|
||||
- ctest --verbose --output-on-failure
|
||||
- if [[ "$VALGRIND" == "true" ]]; then valgrind --leak-check=full --error-exitcode=1 ./SQLiteCpp_example1 ; fi
|
||||
- if [[ "$VALGRIND" == "true" ]]; then valgrind --leak-check=full --error-exitcode=1 ./SQLiteCpp_tests ; fi
|
||||
|
||||
# generate and publish GCov coveralls results
|
||||
after_success:
|
||||
|
12
CHANGELOG.md
12
CHANGELOG.md
@ -2,12 +2,12 @@ Mar 30 2012
|
||||
- Start of a new thin C++ SQLite wrapper
|
||||
|
||||
Apr 2 2012
|
||||
- The wrapper is functionnal
|
||||
- The wrapper is functional
|
||||
- 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 Database::exec() method 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
|
||||
@ -75,7 +75,7 @@ Version 1.3.0 - November 1 2015
|
||||
- Added Backup class
|
||||
|
||||
Version 1.3.1 - February 10 2016
|
||||
- Swith Linux/Mac build to the provided SQLite3 C library
|
||||
- Switch 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)
|
||||
@ -157,9 +157,11 @@ Version 2.5.0 - December 31 2019
|
||||
- #251 Added example for getHeaderInfo()
|
||||
|
||||
Version 3.0.0 - January 1 2020
|
||||
- C++11 minimum
|
||||
- C++11 is now required
|
||||
- CMake 3.1 minimum
|
||||
- Visual Studio 2015 minimum
|
||||
- Googletest 1.10
|
||||
- Update Googletest to latest release 1.10
|
||||
- Add Github Actions continuous integration solution
|
||||
- Add Valgrind memcheck tool to Travis CI
|
||||
- Remove Statement::isOk() deprecated in 2.2.0 when renamed to Statement::hasRow()
|
||||
- Replace Database::backup() "C" implementation by calling the Backup class
|
||||
|
@ -43,14 +43,14 @@ else (MSVC)
|
||||
set(CPPLINT_ARG_OUTPUT "--output=eclipse")
|
||||
set(CPPCHECK_ARG_TEMPLATE "--template=gcc")
|
||||
# Useful compile flags and extra warnings
|
||||
add_compile_options(-fstack-protector -Wall -Wextra -Wpedantic -Wno-long-long -Wswitch-enum -Wshadow -Winline)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-c++0x-compat") # C++ only
|
||||
add_compile_options(-fstack-protector)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic -Wswitch-enum -Wshadow -Wno-long-long") # C++ only, don't bother with sqlite3
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
# GCC flags
|
||||
option(SQLITECPP_USE_GCOV "USE GCov instrumentation." OFF)
|
||||
if (SQLITECPP_USE_GCOV)
|
||||
message (STATUS "Using GCov instrumentation")
|
||||
add_compile_options (-coverage) # NOTE -fkeep-inline-functions would be usefull but not working with current google test and gcc 4.8
|
||||
add_compile_options (-coverage) # NOTE -fkeep-inline-functions would be useful but not working with current Google test and GCC 4.8
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -coverage")
|
||||
endif ()
|
||||
endif (CMAKE_COMPILER_IS_GNUCXX)
|
||||
@ -83,7 +83,7 @@ endif ()
|
||||
|
||||
## Build the C++ Wrapper ##
|
||||
|
||||
# adding a new file require explicittly modifing the CMakeLists.txt
|
||||
# adding a new file require explicitly modifying the CMakeLists.txt
|
||||
# so that CMake knows that it should rebuild the project (it is best practice)
|
||||
|
||||
# list of sources files of the library
|
||||
@ -307,7 +307,7 @@ if (SQLITECPP_BUILD_EXAMPLES)
|
||||
# add the basic example executable
|
||||
add_executable(SQLiteCpp_example1 ${SQLITECPP_EXAMPLES})
|
||||
target_link_libraries(SQLiteCpp_example1 SQLiteCpp sqlite3)
|
||||
# Link target with pthread and dl for linux
|
||||
# Link target with pthread and dl for Linux
|
||||
if (UNIX)
|
||||
target_link_libraries(SQLiteCpp_example1 pthread)
|
||||
if (NOT APPLE)
|
||||
@ -329,12 +329,12 @@ if (SQLITECPP_BUILD_TESTS)
|
||||
if (GTEST_FOUND)
|
||||
target_link_libraries(SQLiteCpp_tests GTest::GTest GTest::Main SQLiteCpp sqlite3)
|
||||
else (GTEST_FOUND)
|
||||
# deactivate some warnings for compiling the gtest library
|
||||
# deactivate some warnings for compiling the googletest library
|
||||
if (NOT MSVC)
|
||||
add_compile_options(-Wno-variadic-macros -Wno-long-long -Wno-switch-enum -Wno-float-equal -Wno-conversion-null -Wno-switch-default -Wno-pedantic)
|
||||
endif (NOT MSVC)
|
||||
|
||||
# add the subdirectory containing the CMakeLists.txt for the gtest library
|
||||
# add the subdirectory containing the CMakeLists.txt for the googletest library
|
||||
if (NOT EXISTS "${PROJECT_SOURCE_DIR}/googletest/CMakeLists.txt")
|
||||
message(FATAL_ERROR "Missing 'googletest' submodule! Either use 'git submodule init' and 'git submodule update' to get googletest according to the README, or deactivate unit tests with -DSQLITECPP_BUILD_TESTS=OFF")
|
||||
endif ()
|
||||
|
@ -72,6 +72,7 @@ Developments and tests are done under the following OSs:
|
||||
- Windows 10, and Windows Server 2012 R2 & Windows Server 2016 (AppVeyor)
|
||||
- OS X 10.11 (Travis CI)
|
||||
- Github Actions
|
||||
- Valgrind memcheck tool
|
||||
|
||||
And the following IDEs/Compilers
|
||||
- GCC 4.8.4, 5.3.0 and 7.1.1 (C++11, C++14, C++17)
|
||||
|
2
TODO.txt
2
TODO.txt
@ -1,5 +1,3 @@
|
||||
Switch to C++11 for v3.0.0
|
||||
|
||||
Add a Tutorial for SQLite newbies
|
||||
Add a real example in the form of a small interactive console application
|
||||
|
||||
|
2
build.sh
2
build.sh
@ -4,7 +4,7 @@
|
||||
# Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
# or copy at http://opensource.org/licenses/MIT)
|
||||
|
||||
# exit on firts error
|
||||
# exit on first error
|
||||
set -e
|
||||
|
||||
mkdir -p build
|
||||
|
@ -477,6 +477,12 @@ public:
|
||||
*/
|
||||
static Header getHeaderInfo(const std::string& aFilename);
|
||||
|
||||
// Parse SQLite header data from a database file.
|
||||
Header getHeaderInfo()
|
||||
{
|
||||
return getHeaderInfo(mFilename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief BackupType for the backup() method
|
||||
*/
|
||||
|
@ -287,28 +287,32 @@ Header Database::getHeaderInfo(const std::string& aFilename)
|
||||
|
||||
if (aFilename.empty())
|
||||
{
|
||||
throw SQLite::Exception("Could not open database, the aFilename parameter was empty.");
|
||||
throw SQLite::Exception("Filename parameter is empty");
|
||||
}
|
||||
|
||||
std::ifstream fileBuffer(aFilename.c_str(), std::ios::in | std::ios::binary);
|
||||
|
||||
if (fileBuffer.is_open())
|
||||
{
|
||||
fileBuffer.seekg(0, std::ios::beg);
|
||||
fileBuffer.read(pBuf, 100);
|
||||
fileBuffer.close();
|
||||
strncpy(pHeaderStr, pBuf, 16);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
throw SQLite::Exception("Error opening file: " + aFilename);
|
||||
std::ifstream fileBuffer(aFilename.c_str(), std::ios::in | std::ios::binary);
|
||||
if (fileBuffer.is_open())
|
||||
{
|
||||
fileBuffer.seekg(0, std::ios::beg);
|
||||
fileBuffer.read(pBuf, 100);
|
||||
fileBuffer.close();
|
||||
if (fileBuffer.gcount() < 100)
|
||||
{
|
||||
throw SQLite::Exception("File " + aFilename + " is too short");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw SQLite::Exception("Error opening file " + aFilename);
|
||||
}
|
||||
}
|
||||
|
||||
// If the "magic string" can't be found then header is invalid, corrupt or unreadable
|
||||
strncpy(pHeaderStr, pBuf, 16);
|
||||
if (!strncmp(pHeaderStr, "SQLite format 3", 15) == 0)
|
||||
{
|
||||
throw SQLite::Exception("Invalid or encrypted SQLite header");
|
||||
throw SQLite::Exception("Invalid or encrypted SQLite header in file " + aFilename);
|
||||
}
|
||||
|
||||
h.pageSizeBytes = (buf[16] << 8) | buf[17];
|
||||
|
@ -24,14 +24,16 @@
|
||||
TEST(Backup, initException)
|
||||
{
|
||||
remove("backup_test.db3");
|
||||
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
|
||||
EXPECT_THROW(SQLite::Backup backup(srcDB, srcDB), SQLite::Exception);
|
||||
EXPECT_THROW(SQLite::Backup backup(srcDB, "main", srcDB, "main"), SQLite::Exception);
|
||||
const std::string name("main");
|
||||
EXPECT_THROW(SQLite::Backup backup(srcDB, name, srcDB, name), SQLite::Exception);
|
||||
{
|
||||
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
|
||||
EXPECT_THROW(SQLite::Backup backup(srcDB, srcDB), SQLite::Exception);
|
||||
EXPECT_THROW(SQLite::Backup backup(srcDB, "main", srcDB, "main"), SQLite::Exception);
|
||||
const std::string name("main");
|
||||
EXPECT_THROW(SQLite::Backup backup(srcDB, name, srcDB, name), SQLite::Exception);
|
||||
}
|
||||
remove("backup_test.db3");
|
||||
}
|
||||
|
||||
@ -39,31 +41,33 @@ TEST(Backup, executeStepOne)
|
||||
{
|
||||
remove("backup_test.db3");
|
||||
remove("backup_test.db3.backup");
|
||||
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
|
||||
{
|
||||
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
|
||||
|
||||
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
SQLite::Backup backup(destDB, "main", srcDB, "main");
|
||||
int res = backup.executeStep(1); // backup only one page at a time
|
||||
ASSERT_EQ(SQLite::OK, res);
|
||||
const int total = backup.getTotalPageCount();
|
||||
ASSERT_EQ(2, total);
|
||||
int remaining = backup.getRemainingPageCount();
|
||||
ASSERT_EQ(1, remaining);
|
||||
res = backup.executeStep(1); // backup the second and last page
|
||||
ASSERT_EQ(SQLITE_DONE, res);
|
||||
remaining = backup.getRemainingPageCount();
|
||||
ASSERT_EQ(0, remaining);
|
||||
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
SQLite::Backup backup(destDB, "main", srcDB, "main");
|
||||
int res = backup.executeStep(1); // backup only one page at a time
|
||||
ASSERT_EQ(SQLite::OK, res);
|
||||
const int total = backup.getTotalPageCount();
|
||||
ASSERT_EQ(2, total);
|
||||
int remaining = backup.getRemainingPageCount();
|
||||
ASSERT_EQ(1, remaining);
|
||||
res = backup.executeStep(1); // backup the second and last page
|
||||
ASSERT_EQ(SQLITE_DONE, res);
|
||||
remaining = backup.getRemainingPageCount();
|
||||
ASSERT_EQ(0, remaining);
|
||||
|
||||
SQLite::Statement query(destDB, "SELECT * FROM backup_test ORDER BY id ASC");
|
||||
ASSERT_TRUE(query.executeStep());
|
||||
EXPECT_EQ(1, query.getColumn(0).getInt());
|
||||
EXPECT_STREQ("first", query.getColumn(1));
|
||||
ASSERT_TRUE(query.executeStep());
|
||||
EXPECT_EQ(2, query.getColumn(0).getInt());
|
||||
EXPECT_STREQ("second", query.getColumn(1));
|
||||
SQLite::Statement query(destDB, "SELECT * FROM backup_test ORDER BY id ASC");
|
||||
ASSERT_TRUE(query.executeStep());
|
||||
EXPECT_EQ(1, query.getColumn(0).getInt());
|
||||
EXPECT_STREQ("first", query.getColumn(1));
|
||||
ASSERT_TRUE(query.executeStep());
|
||||
EXPECT_EQ(2, query.getColumn(0).getInt());
|
||||
EXPECT_STREQ("second", query.getColumn(1));
|
||||
}
|
||||
remove("backup_test.db3");
|
||||
remove("backup_test.db3.backup");
|
||||
}
|
||||
@ -72,27 +76,29 @@ TEST(Backup, executeStepAll)
|
||||
{
|
||||
remove("backup_test.db3");
|
||||
remove("backup_test.db3.backup");
|
||||
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
|
||||
{
|
||||
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
|
||||
|
||||
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
SQLite::Backup backup(destDB, srcDB);
|
||||
const int res = backup.executeStep(); // uses default argument "-1" => execute all steps at once
|
||||
ASSERT_EQ(res, SQLITE_DONE);
|
||||
const int total = backup.getTotalPageCount();
|
||||
ASSERT_EQ(2, total);
|
||||
const int remaining = backup.getRemainingPageCount();
|
||||
ASSERT_EQ(0, remaining);
|
||||
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
SQLite::Backup backup(destDB, srcDB);
|
||||
const int res = backup.executeStep(); // uses default argument "-1" => execute all steps at once
|
||||
ASSERT_EQ(res, SQLITE_DONE);
|
||||
const int total = backup.getTotalPageCount();
|
||||
ASSERT_EQ(2, total);
|
||||
const int remaining = backup.getRemainingPageCount();
|
||||
ASSERT_EQ(0, remaining);
|
||||
|
||||
SQLite::Statement query(destDB, "SELECT * FROM backup_test ORDER BY id ASC");
|
||||
ASSERT_TRUE(query.executeStep());
|
||||
EXPECT_EQ(1, query.getColumn(0).getInt());
|
||||
EXPECT_STREQ("first", query.getColumn(1));
|
||||
ASSERT_TRUE(query.executeStep());
|
||||
EXPECT_EQ(2, query.getColumn(0).getInt());
|
||||
EXPECT_STREQ("second", query.getColumn(1));
|
||||
SQLite::Statement query(destDB, "SELECT * FROM backup_test ORDER BY id ASC");
|
||||
ASSERT_TRUE(query.executeStep());
|
||||
EXPECT_EQ(1, query.getColumn(0).getInt());
|
||||
EXPECT_STREQ("first", query.getColumn(1));
|
||||
ASSERT_TRUE(query.executeStep());
|
||||
EXPECT_EQ(2, query.getColumn(0).getInt());
|
||||
EXPECT_STREQ("second", query.getColumn(1));
|
||||
}
|
||||
remove("backup_test.db3");
|
||||
remove("backup_test.db3.backup");
|
||||
}
|
||||
@ -101,18 +107,20 @@ TEST(Backup, executeStepException)
|
||||
{
|
||||
remove("backup_test.db3");
|
||||
remove("backup_test.db3.backup");
|
||||
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
|
||||
{
|
||||
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
(void)destDB;
|
||||
}
|
||||
{
|
||||
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READONLY);
|
||||
SQLite::Backup backup(destDB, srcDB);
|
||||
EXPECT_THROW(backup.executeStep(), SQLite::Exception);
|
||||
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
|
||||
{
|
||||
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
(void)destDB;
|
||||
}
|
||||
{
|
||||
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READONLY);
|
||||
SQLite::Backup backup(destDB, srcDB);
|
||||
EXPECT_THROW(backup.executeStep(), SQLite::Exception);
|
||||
}
|
||||
}
|
||||
remove("backup_test.db3");
|
||||
remove("backup_test.db3.backup");
|
||||
|
@ -140,15 +140,16 @@ TEST(Database, backup)
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
|
||||
// Export the data into a file
|
||||
remove("backup");
|
||||
EXPECT_NO_THROW(db.backup("backup", SQLite::Database::Save));
|
||||
remove("backup.db3");
|
||||
EXPECT_NO_THROW(db.backup("backup.db3", SQLite::Database::Save));
|
||||
|
||||
// Trash the table
|
||||
db.exec("DROP TABLE test;");
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
|
||||
// Import the data back from the file
|
||||
EXPECT_NO_THROW(db.backup("backup", SQLite::Database::Load));
|
||||
EXPECT_NO_THROW(db.backup("backup.db3", SQLite::Database::Load));
|
||||
remove("backup.db3");
|
||||
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
}
|
||||
@ -359,23 +360,41 @@ TEST(Database, getHeaderInfo)
|
||||
{
|
||||
remove("test.db3");
|
||||
{
|
||||
//Call without passing a database file name
|
||||
// Call without passing a database file name
|
||||
EXPECT_THROW(SQLite::Database::getHeaderInfo(""),SQLite::Exception);
|
||||
|
||||
//Call with a non existant database
|
||||
// Call with a non-existent database
|
||||
EXPECT_THROW(SQLite::Database::getHeaderInfo("test.db3"), SQLite::Exception);
|
||||
|
||||
//Simulate a corrupt header by writing garbage to a file
|
||||
unsigned char badData[100];
|
||||
char* pBadData = reinterpret_cast<char*>(&badData[0]);
|
||||
// Simulate an incomplete header by writing garbage to a file
|
||||
{
|
||||
const unsigned char badData[] = "garbage...";
|
||||
const char* pBadData = reinterpret_cast<const char*>(&badData[0]);
|
||||
|
||||
std::ofstream corruptDb;
|
||||
corruptDb.open("corrupt.db3", std::ios::app | std::ios::binary);
|
||||
corruptDb.write(pBadData, 100);
|
||||
remove("short.db3");
|
||||
std::ofstream corruptDb;
|
||||
corruptDb.open("short.db3", std::ios::app | std::ios::binary);
|
||||
corruptDb.write(pBadData, sizeof(badData));
|
||||
corruptDb.close();
|
||||
|
||||
EXPECT_THROW(SQLite::Database::getHeaderInfo("corrupt.db3"), SQLite::Exception);
|
||||
EXPECT_THROW(SQLite::Database::getHeaderInfo("short.db3"), SQLite::Exception);
|
||||
remove("short.db3");
|
||||
}
|
||||
|
||||
remove("corrupt.db3");
|
||||
// Simulate a corrupt header by writing garbage to a file
|
||||
{
|
||||
const unsigned char badData[100] = "garbage...";
|
||||
const char* pBadData = reinterpret_cast<const char*>(&badData[0]);
|
||||
|
||||
remove("corrupt.db3");
|
||||
std::ofstream corruptDb;
|
||||
corruptDb.open("corrupt.db3", std::ios::app | std::ios::binary);
|
||||
corruptDb.write(pBadData, sizeof(badData));
|
||||
corruptDb.close();
|
||||
|
||||
EXPECT_THROW(SQLite::Database::getHeaderInfo("corrupt.db3"), SQLite::Exception);
|
||||
remove("corrupt.db3");
|
||||
}
|
||||
|
||||
// Create a new database
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
|
||||
@ -388,7 +407,7 @@ TEST(Database, getHeaderInfo)
|
||||
// Parse header fields from test database
|
||||
SQLite::Header h = SQLite::Database::getHeaderInfo("test.db3");
|
||||
|
||||
//Test header values expliticly set via PRAGMA statements
|
||||
//Test header values explicitly set via PRAGMA statements
|
||||
EXPECT_EQ(h.userVersion, 12345);
|
||||
EXPECT_EQ(h.applicationId, 2468);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user