Skip to content

Commit

Permalink
Database() constructor to wrap an existing sqlite3*, leaving it open …
Browse files Browse the repository at this point in the history
…on destruct
  • Loading branch information
mlin committed Jan 23, 2021
1 parent c0818e4 commit 4590c8e
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 6 deletions.
30 changes: 24 additions & 6 deletions include/SQLiteCpp/Database.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,21 @@ class Database

#endif // c++17

/**
* @brief Wrap an existing sqlite3* connection opened by other means.
*
* When the Database object is constructed as a wrapper, its destruction does NOT automatically
* sqlite3_close() the connection. In this case (only), Statement objects may outlive the Database object with
* which they were constructed, so long as the underlying connection remains open.
*
* @param[in] apSQLite Existing sqlite3* connection to be wrapped
* @param[in] aBusyTimeoutMs Amount of milliseconds to wait before returning SQLITE_BUSY (see setBusyTimeout())
*
* @throw SQLite::Exception in case of error
*/
Database(sqlite3* apSQLite,
const int aBusyTimeoutMs = 0);

// Database is non-copyable
Database(const Database&) = delete;
Database& operator=(const Database&) = delete;
Expand All @@ -217,7 +232,12 @@ class Database
*
* @warning assert in case of error
*/
~Database() = default;
~Database()
{
if (!mCloseOnDestruct) {
mSQLitePtr.release(); // prevent Deleter
}
}

// Deleter functor to use with smart pointers to close the SQLite database connection in an RAII fashion.
struct Deleter
Expand Down Expand Up @@ -414,7 +434,7 @@ class Database
/// Return UTF-8 encoded English language explanation of the most recent failed API call (if any).
const char* getErrorMsg() const noexcept;

/// Return the filename used to open the database.
/// Return the filename used to open the database; empty if the Database wrapped existing sqlite3*
const std::string& getFilename() const noexcept
{
return mFilename;
Expand Down Expand Up @@ -536,10 +556,7 @@ class Database
static Header getHeaderInfo(const std::string& aFilename);

// Parse SQLite header data from a database file.
Header getHeaderInfo()
{
return getHeaderInfo(mFilename);
}
Header getHeaderInfo();

/**
* @brief BackupType for the backup() method
Expand Down Expand Up @@ -571,6 +588,7 @@ class Database
private:
// TODO: perhaps switch to having Statement sharing a pointer to the Connexion
std::unique_ptr<sqlite3, Deleter> mSQLitePtr; ///< Pointer to SQLite Database Connection Handle
bool mCloseOnDestruct; ///< true iff ~Database() is to use sqlite3_close() on mSQLitePtr
std::string mFilename; ///< UTF-8 filename used to open the database
};

Expand Down
26 changes: 26 additions & 0 deletions src/Database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Database::Database(const char* apFilename,
const int aFlags /* = SQLite::OPEN_READONLY*/,
const int aBusyTimeoutMs /* = 0 */,
const char* apVfs /* = nullptr*/) :
mCloseOnDestruct(true),
mFilename(apFilename)
{
sqlite3* handle;
Expand All @@ -86,6 +87,19 @@ Database::Database(const char* apFilename,
}
}

// Wrap an existing sqlite3* connection opened by other means.
Database::Database(sqlite3* apSQLite,
const int aBusyTimeoutMs /* = 0 */) :
mCloseOnDestruct(false)
{
SQLITECPP_ASSERT(apSQLite != nullptr, "Database(nullptr)");
mSQLitePtr.reset(apSQLite);
if (aBusyTimeoutMs > 0)
{
setBusyTimeout(aBusyTimeoutMs);
}
}

// Deleter functor to use with smart pointers to close the SQLite database connection in an RAII fashion.
void Database::Deleter::operator()(sqlite3* apSQLite)
{
Expand Down Expand Up @@ -432,6 +446,18 @@ Header Database::getHeaderInfo(const std::string& aFilename)
return h;
}

Header Database::getHeaderInfo()
{
if (!mFilename.empty())
{
return getHeaderInfo(mFilename);
}
const char *zFilename = sqlite3_db_filename(mSQLitePtr.get(), nullptr);
return getHeaderInfo(std::string(zFilename ? zFilename : ""));
}



void Database::backup(const char* apFilename, BackupType aType)
{
// Open the database file identified by apFilename
Expand Down

0 comments on commit 4590c8e

Please sign in to comment.