Skip to content

Commit

Permalink
Add StatementPtr - better structure for Statement shared_ptr
Browse files Browse the repository at this point in the history
  • Loading branch information
Kacperos155 committed Jul 25, 2022
1 parent 4117377 commit 48741e7
Show file tree
Hide file tree
Showing 12 changed files with 234 additions and 148 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ set(SQLITECPP_SRC
${PROJECT_SOURCE_DIR}/src/Savepoint.cpp
${PROJECT_SOURCE_DIR}/src/Statement.cpp
${PROJECT_SOURCE_DIR}/src/StatementExecutor.cpp
${PROJECT_SOURCE_DIR}/src/StatementPtr.cpp
${PROJECT_SOURCE_DIR}/src/Transaction.cpp
)
source_group(src FILES ${SQLITECPP_SRC})
Expand All @@ -125,6 +126,7 @@ set(SQLITECPP_INC
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Savepoint.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Statement.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/StatementExecutor.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/StatementPtr.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Transaction.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/VariadicBind.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/ExecuteMany.h
Expand Down
30 changes: 4 additions & 26 deletions include/SQLiteCpp/Column.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@
*/
#pragma once

#include <SQLiteCpp/Statement.h>
#include <SQLiteCpp/Exception.h>
#include <SQLiteCpp/StatementPtr.h>

#include <ostream>
#include <string>
#include <memory>

// Forward declarations to avoid inclusion of <sqlite3.h> in a header
struct sqlite3_stmt;

namespace SQLite
{
Expand Down Expand Up @@ -55,7 +53,7 @@ class Column
*
* @throws Exception is thrown in case of error, then the Column object is NOT constructed.
*/
explicit Column(const StatementExecutor::TStatementPtr& aStmtPtr, int aIndex);
explicit Column(const StatementPtr::TStatementPtr& aStmtPtr, int aIndex);

/**
* @brief Return a pointer to the named assigned to this result column (potentially aliased)
Expand Down Expand Up @@ -226,7 +224,7 @@ class Column
}

private:
StatementExecutor::TStatementPtr mStmtPtr; ///< Shared Pointer to the prepared SQLite Statement Object
StatementPtr::TStatementPtr mStmtPtr; ///< Shared Pointer to the prepared SQLite Statement Object
int mIndex; ///< Index of the column in the row of result, starting at 0
};

Expand All @@ -242,25 +240,5 @@ class Column
*/
std::ostream& operator<<(std::ostream& aStream, const Column& aColumn);

#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>
T Statement::getColumns()
{
checkRow();
checkIndex(N - 1);
return getColumns<T>(std::make_integer_sequence<int, N>{});
}

// Helper function called by getColums<typename T, int N>
template<typename T, const int... Is>
T Statement::getColumns(const std::integer_sequence<int, Is...>)
{
return T{ Column(getStatement(), Is)... };
}

#endif


} // namespace SQLite
1 change: 1 addition & 0 deletions include/SQLiteCpp/Database.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*/
#pragma once

#include <SQLiteCpp/Exception.h>
#include <SQLiteCpp/Column.h>

// c++17: MinGW GCC version > 8
Expand Down
11 changes: 3 additions & 8 deletions include/SQLiteCpp/Row.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,11 @@
*/
#pragma once

//#include <SQLiteCpp/RowExecutor.h>
#include <SQLiteCpp/StatementPtr.h>

#include <memory>
#include <string>

// Forward declaration to avoid inclusion of <sqlite3.h> in a header
struct sqlite3_stmt;

namespace SQLite
{
Expand All @@ -27,11 +25,8 @@ namespace SQLite
*/
class Row
{
/// Weak pointer to SQLite Prepared Statement Object
using TStatementWeakPtr = std::weak_ptr<sqlite3_stmt>;

public:
Row(TStatementWeakPtr apRow, std::size_t aID);
Row(TRowWeakPtr apStatement, std::size_t aID);

std::size_t getRowNumber() const
{
Expand All @@ -58,7 +53,7 @@ class Row
const char* getText(uint32_t aColumnID) const noexcept;

private:
TStatementWeakPtr mpRow;
TRowWeakPtr mpStatement;
std::size_t ID;
};

Expand Down
27 changes: 17 additions & 10 deletions include/SQLiteCpp/Statement.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,13 @@ class Statement : public StatementExecutor
*/
Statement(const Database& aDatabase, const std::string& aQuery);

/**
* @brief Move an SQLite statement.
*
* @param[in] aStatement Statement to move
*/
Statement(Statement&& aStatement) noexcept = default;
Statement& operator=(Statement&& aStatement) noexcept = default;

// Statement is non-copyable
Statement(const Statement&) = delete;
Statement& operator=(const Statement&) = delete;

Statement(Statement&& aStatement) = default;
Statement& operator=(Statement&& aStatement) = default;

/// Finalize and unregister the SQL query from the SQLite Database Connection.
/// The finalization will be done by the destructor of the last shared pointer
~Statement() = default;
Expand Down Expand Up @@ -440,15 +435,27 @@ class Statement : public StatementExecutor
* @note Requires std=C++14
*/
template<typename T, int N>
T getColumns();
T getColumns()
{
checkRow();
checkIndex(N - 1);
return getColumns<T>(std::make_integer_sequence<int, N>{});
}

private:
/**
* @brief Helper function used by getColumns<typename T, int N> to expand an integer_sequence used to generate
* the required Column objects
*
* @note Requires std=C++14
*
* @return Column object for each column in statement
*/
template<typename T, const int... Is>
T getColumns(const std::integer_sequence<int, Is...>);
T getColumns(const std::integer_sequence<int, Is...>)
{
return T{ Column(getStatement(), Is)... };
}

public:
#endif
Expand Down
47 changes: 16 additions & 31 deletions include/SQLiteCpp/StatementExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,21 @@
* @ingroup SQLiteCpp
* @brief Step executor for SQLite prepared Statement Object
*
* Copyright (c) 2015 Shibao HONG ([email protected])
* Copyright (c) 2015-2021 Sebastien Rombauts ([email protected])
* Copyright (c) 2012-2021 Sebastien Rombauts ([email protected])
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#pragma once

#include <SQLiteCpp/StatementPtr.h>
#include <SQLiteCpp/Row.h>
#include <SQLiteCpp/Exception.h>

#include <memory>
#include <string>
#include <map>

// Forward declaration to avoid inclusion of <sqlite3.h> in a header
struct sqlite3_stmt;

namespace SQLite
{
Expand All @@ -44,24 +42,13 @@ extern const int OK; ///< SQLITE_OK
class StatementExecutor
{
public:
/// Shared pointer to SQLite Prepared Statement Object
using TStatementPtr = std::shared_ptr<sqlite3_stmt>;

/// Weak pointer to SQLite Prepared Statement Object
using TStatementWeakPtr = std::weak_ptr<sqlite3_stmt>;

/// Shared pointer to SQLite StatementExecutor
using TRowPtr = std::shared_ptr<StatementExecutor>;

/// Weak pointer to SQLite StatementExecutor
using TRowWeakPtr = std::weak_ptr<StatementExecutor>;

/// Type to store columns names and indexes
using TColumnsMap = std::map<std::string, int, std::less<>>;

StatementExecutor(const StatementExecutor&) = delete;
StatementExecutor(StatementExecutor&&) = default;
StatementExecutor& operator=(const StatementExecutor&) = delete;

StatementExecutor(StatementExecutor&&) = default;
StatementExecutor& operator=(StatementExecutor&&) = default;

/// Reset the statement to make it ready for a new execution. Throws an exception on error.
Expand Down Expand Up @@ -180,8 +167,8 @@ class StatementExecutor
using difference_type = std::ptrdiff_t;

RowIterator() = default;
RowIterator(TStatementWeakPtr apStatement, TRowWeakPtr apRow, uint16_t aID) :
mpStatement(apStatement), mpRow(apRow), mID(aID), mRow(apStatement, aID) {}
RowIterator(TRowWeakPtr apStatement, uint16_t aID) :
mpStatement(apStatement), mID(aID), mRow(apStatement, aID) {}

reference operator*() const
{
Expand Down Expand Up @@ -216,8 +203,7 @@ class StatementExecutor
/// Executing next statement step
void advance() noexcept;

TStatementWeakPtr mpStatement{}; //!< Weak pointer to SQLite Statement Object
TRowWeakPtr mpRow{}; //!< Weak pointer to StatementExecutor Object
TRowWeakPtr mpStatement{}; //!< Weak pointer to prepared Statement Object
uint16_t mID{}; //!< Current row number

/// Internal row object storage
Expand Down Expand Up @@ -256,9 +242,9 @@ class StatementExecutor
*
* @return raw pointer to Statement Object
*/
TStatementPtr getStatement() const noexcept
StatementPtr::TStatementPtr getStatement() const noexcept
{
return mpStatement;
return mpStatement->mpStatement;
}

/**
Expand All @@ -277,7 +263,7 @@ class StatementExecutor
*/
TRowWeakPtr getExecutorWeakPtr() const
{
return mpRowExecutor;
return mpStatement;
}

////////////////////////////////////////////////////////////////////////////
Expand All @@ -291,7 +277,7 @@ class StatementExecutor
{
if (SQLite::OK != aRet)
{
throw SQLite::Exception(mpSQLite, aRet);
throw SQLite::Exception(mpStatement->mpConnection, aRet);
}
}

Expand All @@ -318,18 +304,17 @@ class StatementExecutor
}

private:
/// Create prepared SQLite Statement Object
void prepareStatement(const std::string& aQuery);

/// Get column number and create map with columns names
void createColumnInfo();

sqlite3* mpSQLite{}; //!< Pointer to SQLite Database Connection Handle
TStatementPtr mpStatement{}; //!< Shared Pointer to the prepared SQLite Statement Object
// xD
bool checkReturnCode(int aReturnCode) const;
// xD
bool checkReturnCode(int aReturnCode, int aErrorCode) const;

/// Shared Pointer to this object.
/// Allows RowIterator to execute next step
TRowPtr mpRowExecutor{};
TRowPtr mpStatement{};

int mColumnCount = 0; //!< Number of columns in the result of the prepared statement
bool mbHasRow = false; //!< true when a row has been fetched with executeStep()
Expand Down
75 changes: 75 additions & 0 deletions include/SQLiteCpp/StatementPtr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/**
* @file StatementPtr.h
* @ingroup SQLiteCpp
* @brief Pointer for prepared SQLite Statement Object
*
* Copyright (c) 2022 Sebastien Rombauts ([email protected])
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#pragma once

#include <memory>
#include <string>

// Forward declaration to avoid inclusion of <sqlite3.h> in a header
struct sqlite3;
struct sqlite3_stmt;

namespace SQLite
{


/**
* @brief Container for SQLite Statement pointer.
*
* You should never create this object unless you are expanding SQLiteCPP API.
*/
struct StatementPtr
{
/**
* @brief Don't create this object unless you are expanding SQLiteCPP API.
*
* @param[in] apSQLite the SQLite Database Connection
* @param[in] aQuery an UTF-8 encoded query string
*
* @throws Exception is thrown in case of error, then the StatementPtr object is NOT constructed.
*/
StatementPtr(sqlite3* apSQLite, const std::string& aQuery);

/// Shared pointer to SQLite prepared Statement Object
using TStatementPtr = std::shared_ptr<sqlite3_stmt>;

sqlite3* const mpConnection; //!< Pointer to SQLite Database Connection Handle
TStatementPtr const mpStatement; //!< Shared Pointer to the prepared SQLite Statement Object
std::size_t mCurrentStep = 0; //!< Current step of prepared Statement Object

/// Resets SQLite Statement Object
int reset() noexcept;

/// Execute next step of SQLite Statement Object
int step() noexcept;

/**
* @brief Returns pointer to prepared SQLite Statement Object.
* Use this ONLY on sqlite3 function!
*
* @return Pointer to SQLite Statement Object
*/
sqlite3_stmt* getPreparedStatement() const;

private:
/// Create prepared SQLite Statement Object
TStatementPtr prepareStatement(sqlite3* apConnection, const std::string& aQuery) const;
};


/// Shared pointer to SQLite StatementPtr
using TRowPtr = std::shared_ptr<StatementPtr>;

/// Weak pointer to SQLite StatementPtr
using TRowWeakPtr = std::weak_ptr<StatementPtr>;


} // namespace SQLite
Loading

0 comments on commit 48741e7

Please sign in to comment.