Skip to content

Commit

Permalink
Add RowIterator and Row class fundation
Browse files Browse the repository at this point in the history
  • Loading branch information
Kacperos155 committed Jul 24, 2022
1 parent 3fdd78e commit 81d0fe5
Show file tree
Hide file tree
Showing 9 changed files with 239 additions and 24 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ set(SQLITECPP_SRC
${PROJECT_SOURCE_DIR}/src/Column.cpp
${PROJECT_SOURCE_DIR}/src/Database.cpp
${PROJECT_SOURCE_DIR}/src/Exception.cpp
${PROJECT_SOURCE_DIR}/src/Row.cpp
${PROJECT_SOURCE_DIR}/src/RowExecutor.cpp
${PROJECT_SOURCE_DIR}/src/Savepoint.cpp
${PROJECT_SOURCE_DIR}/src/Statement.cpp
Expand All @@ -120,6 +121,7 @@ set(SQLITECPP_INC
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Column.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Database.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Exception.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Row.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/RowExecutor.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Savepoint.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Statement.h
Expand Down
7 changes: 4 additions & 3 deletions include/SQLiteCpp/Column.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class Column
* @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
*/
explicit Column(const Statement::TStatementPtr& aStmtPtr, int aIndex);
explicit Column(const RowExecutor::TStatementPtr& aStmtPtr, int aIndex);

// default destructor: the finalization will be done by the destructor of the last shared pointer
// default copy constructor and assignment operator are perfectly suited :
Expand Down Expand Up @@ -252,7 +252,7 @@ class Column
}

private:
Statement::TStatementPtr mStmtPtr; ///< Shared Pointer to the prepared SQLite Statement Object
RowExecutor::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 Down Expand Up @@ -283,9 +283,10 @@ T Statement::getColumns()
template<typename T, const int... Is>
T Statement::getColumns(const std::integer_sequence<int, Is...>)
{
return T{Column(getStatement(), Is)...};
return T{ Column(getStatement(), Is)... };
}

#endif


} // namespace SQLite
56 changes: 56 additions & 0 deletions include/SQLiteCpp/Row.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* @file Row.h
* @ingroup SQLiteCpp
* @brief TODO:
*
* Copyright (c) 2015 Shibao HONG ([email protected])
* Copyright (c) 2015-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/RowExecutor.h>

#include <string>

namespace SQLite
{


class Row
{
public:
Row(RowExecutor::TStatementWeakPtr apRow, std::size_t aID);

std::size_t getRowNumber() const
{
return ID;
}

/**
* @brief Test if the column value is NULL
*
* @param[in] aIndex Index of the column, starting at 0
*
* @return true if the column value is NULL
*
* Throw an exception if the specified index is out of the [0, getColumnCount()) range.
*/
bool isColumnNull(const int aIndex) const;

/**
* @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(uint32_t aColumnID) const noexcept;

private:
RowExecutor::TStatementWeakPtr mpRow;
std::size_t ID;
};

} // namespace SQLite
36 changes: 28 additions & 8 deletions include/SQLiteCpp/RowExecutor.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @file RowExecutor.h
* @ingroup SQLiteCpp
* @brief TODO:
* @brief Step executor for SQLite prepared Statement Object
*
* Copyright (c) 2015 Shibao HONG ([email protected])
* Copyright (c) 2015-2021 Sebastien Rombauts ([email protected])
Expand Down Expand Up @@ -130,17 +130,17 @@ class RowExecutor
int getChanges() const noexcept;

/// Return the number of columns in the result set returned by the prepared statement
int getColumnCount() const
int getColumnCount() const noexcept
{
return mColumnCount;
}
/// true when a row has been fetched with executeStep()
bool hasRow() const
bool hasRow() const noexcept
{
return mbHasRow;
}
/// true when the last executeStep() had no more row to fetch
bool isDone() const
bool isDone() const noexcept
{
return mbDone;
}
Expand All @@ -167,7 +167,10 @@ class RowExecutor
*
* @return raw pointer to Statement Object
*/
TStatementPtr getStatement() const noexcept;
TStatementPtr getStatement() const noexcept
{
return mpStatement;
}

/**
* @brief Return a prepared SQLite Statement Object.
Expand All @@ -176,6 +179,19 @@ class RowExecutor
* @return raw pointer to Prepared Statement Object
*/
sqlite3_stmt* getPreparedStatement() const;

/**
* @brief Return a prepared SQLite Statement Object.
*
* Throw an exception if the statement object was not prepared.
* @return raw pointer to Prepared Statement Object
*/
TRowWeakPtr getExecutorWeakPtr() const
{
return mpRowExecutor;
}

////////////////////////////////////////////////////////////////////////////

/**
* @brief Check if a return code equals SQLITE_OK, else throw a SQLite::Exception with the SQLite error message
Expand Down Expand Up @@ -222,9 +238,13 @@ class RowExecutor
sqlite3* mpSQLite{}; //!< Pointer to SQLite Database Connection Handle
TStatementPtr mpStatement{}; //!< Shared Pointer to the prepared SQLite Statement Object

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()
bool mbDone{ false }; //!< true when the last executeStep() had no more row to fetch
/// Shared Pointer to this object.
/// Allows RowIterator to execute next step
TRowPtr mpRowExecutor{};

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()
bool mbDone = false; //!< true when the last executeStep() had no more row to fetch

/// Map of columns index by name (mutable so getColumnIndex can be const)
mutable TColumnsMap mColumnNames{};
Expand Down
60 changes: 58 additions & 2 deletions include/SQLiteCpp/Statement.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @file Statement.h
* @ingroup SQLiteCpp
* @brief A prepared SQLite Statement is a compiled SQL query ready to be executed, pointing to a row of result.
* @brief A prepared SQLite Statement Object binder and Column getter.
*
* Copyright (c) 2012-2021 Sebastien Rombauts ([email protected])
*
Expand Down Expand Up @@ -541,8 +541,64 @@ class Statement : public RowExecutor
/// Return the number of bind parameters in the statement
int getBindParameterCount() const noexcept;

////////////////////////////////////////////////////////////////////////////

class RowIterator
{
public:
using iterator_category = std::input_iterator_tag;
using value_type = Row;
using reference = const Row&;
using pointer = const Row*;
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) {}

reference operator*() const
{
return mRow;
}
pointer operator->() const noexcept
{
return &mRow;
}

reference operator++() noexcept
{
mRow = Row(mpStatement, ++mID);
advance();
return mRow;
}
value_type operator++(int)
{
Row copy{ mRow };
mRow = Row(mpStatement, ++mID);
advance();
return copy;
}

bool operator==(const RowIterator& aIt) const;
bool operator!=(const RowIterator& aIt) const
{
return !(*this == aIt);
}

private:
void advance() noexcept;

TStatementWeakPtr mpStatement{};
TRowWeakPtr mpRow{};
uint16_t mID{};
Row mRow{ mpStatement, mID };
};

RowIterator begin();
RowIterator end();

private:
std::string mQuery; //!< UTF-8 SQL Query
std::string mQuery; //!< UTF-8 SQL Query,
};


Expand Down
2 changes: 1 addition & 1 deletion src/Column.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const int Null = SQLITE_NULL;


// Encapsulation of a Column in a row of the result pointed by the prepared Statement.
Column::Column(const Statement::TStatementPtr& aStmtPtr, int aIndex) :
Column::Column(const RowExecutor::TStatementPtr& aStmtPtr, int aIndex) :
mStmtPtr(aStmtPtr),
mIndex(aIndex)
{
Expand Down
41 changes: 41 additions & 0 deletions src/Row.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* @file Row.cpp
* @ingroup SQLiteCpp
* @brief TODO:
*
* Copyright (c) 2015 Shibao HONG ([email protected])
* Copyright (c) 2015-2021 Sebastien Rombauts ([email protected])
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#include <SQLiteCpp/Row.h>

#include <SQLiteCpp/Exception.h>

#include <sqlite3.h>

namespace SQLite
{


Row::Row(RowExecutor::TStatementWeakPtr apRow, std::size_t aID) :
mpRow(apRow), ID(aID)
{
}

bool Row::isColumnNull(const int aIndex) const
{
return false;
}

const char* Row::getText(uint32_t aColumnID) const noexcept
{
auto statement = mpRow.lock();


auto pText = reinterpret_cast<const char*>(sqlite3_column_text(statement.get(), aColumnID));
return (pText ? pText : "");
}

} // namespace SQLite
12 changes: 5 additions & 7 deletions src/RowExecutor.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @file RowExecutor.cpp
* @ingroup SQLiteCpp
* @brief TODO:
* @brief Step executor for SQLite prepared Statement Object
*
* Copyright (c) 2015 Shibao HONG ([email protected])
* Copyright (c) 2015-2021 Sebastien Rombauts ([email protected])
Expand All @@ -24,6 +24,10 @@ namespace SQLite
{
prepareStatement(aQuery);
createColumnInfo();

mpRowExecutor.swap(TRowPtr(this, [](const RowExecutor* const) {
//empty destructor to make shared_ptr without ownership
}));
}

void SQLite::RowExecutor::prepareStatement(const std::string& aQuery)
Expand Down Expand Up @@ -165,12 +169,6 @@ namespace SQLite
return sqlite3_errmsg(mpSQLite);
}

// Return std::shared_ptr with SQLite statement object
RowExecutor::TStatementPtr RowExecutor::getStatement() const noexcept
{
return mpStatement;
}

// Return prepered SQLite statement object or throw
sqlite3_stmt* RowExecutor::getPreparedStatement() const
{
Expand Down
Loading

0 comments on commit 81d0fe5

Please sign in to comment.