Skip to content

Commit 81d0fe5

Browse files
committed
Add RowIterator and Row class fundation
1 parent 3fdd78e commit 81d0fe5

File tree

9 files changed

+239
-24
lines changed

9 files changed

+239
-24
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ set(SQLITECPP_SRC
105105
${PROJECT_SOURCE_DIR}/src/Column.cpp
106106
${PROJECT_SOURCE_DIR}/src/Database.cpp
107107
${PROJECT_SOURCE_DIR}/src/Exception.cpp
108+
${PROJECT_SOURCE_DIR}/src/Row.cpp
108109
${PROJECT_SOURCE_DIR}/src/RowExecutor.cpp
109110
${PROJECT_SOURCE_DIR}/src/Savepoint.cpp
110111
${PROJECT_SOURCE_DIR}/src/Statement.cpp
@@ -120,6 +121,7 @@ set(SQLITECPP_INC
120121
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Column.h
121122
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Database.h
122123
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Exception.h
124+
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Row.h
123125
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/RowExecutor.h
124126
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Savepoint.h
125127
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Statement.h

include/SQLiteCpp/Column.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class Column
5454
* @param[in] aStmtPtr Shared pointer to the prepared SQLite Statement Object.
5555
* @param[in] aIndex Index of the column in the row of result, starting at 0
5656
*/
57-
explicit Column(const Statement::TStatementPtr& aStmtPtr, int aIndex);
57+
explicit Column(const RowExecutor::TStatementPtr& aStmtPtr, int aIndex);
5858

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

254254
private:
255-
Statement::TStatementPtr mStmtPtr; ///< Shared Pointer to the prepared SQLite Statement Object
255+
RowExecutor::TStatementPtr mStmtPtr; ///< Shared Pointer to the prepared SQLite Statement Object
256256
int mIndex; ///< Index of the column in the row of result, starting at 0
257257
};
258258

@@ -283,9 +283,10 @@ T Statement::getColumns()
283283
template<typename T, const int... Is>
284284
T Statement::getColumns(const std::integer_sequence<int, Is...>)
285285
{
286-
return T{Column(getStatement(), Is)...};
286+
return T{ Column(getStatement(), Is)... };
287287
}
288288

289289
#endif
290290

291+
291292
} // namespace SQLite

include/SQLiteCpp/Row.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* @file Row.h
3+
* @ingroup SQLiteCpp
4+
* @brief TODO:
5+
*
6+
* Copyright (c) 2015 Shibao HONG (shibaohong@outlook.com)
7+
* Copyright (c) 2015-2021 Sebastien Rombauts (sebastien.rombauts@gmail.com)
8+
*
9+
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
10+
* or copy at http://opensource.org/licenses/MIT)
11+
*/
12+
#pragma once
13+
14+
#include <SQLiteCpp/RowExecutor.h>
15+
16+
#include <string>
17+
18+
namespace SQLite
19+
{
20+
21+
22+
class Row
23+
{
24+
public:
25+
Row(RowExecutor::TStatementWeakPtr apRow, std::size_t aID);
26+
27+
std::size_t getRowNumber() const
28+
{
29+
return ID;
30+
}
31+
32+
/**
33+
* @brief Test if the column value is NULL
34+
*
35+
* @param[in] aIndex Index of the column, starting at 0
36+
*
37+
* @return true if the column value is NULL
38+
*
39+
* Throw an exception if the specified index is out of the [0, getColumnCount()) range.
40+
*/
41+
bool isColumnNull(const int aIndex) const;
42+
43+
/**
44+
* @brief Return a pointer to the text value (NULL terminated string) of the column.
45+
*
46+
* @warning The value pointed at is only valid while the statement is valid (ie. not finalized),
47+
* thus you must copy it before using it beyond its scope (to a std::string for instance).
48+
*/
49+
const char* getText(uint32_t aColumnID) const noexcept;
50+
51+
private:
52+
RowExecutor::TStatementWeakPtr mpRow;
53+
std::size_t ID;
54+
};
55+
56+
} // namespace SQLite

include/SQLiteCpp/RowExecutor.h

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* @file RowExecutor.h
33
* @ingroup SQLiteCpp
4-
* @brief TODO:
4+
* @brief Step executor for SQLite prepared Statement Object
55
*
66
* Copyright (c) 2015 Shibao HONG (shibaohong@outlook.com)
77
* Copyright (c) 2015-2021 Sebastien Rombauts (sebastien.rombauts@gmail.com)
@@ -130,17 +130,17 @@ class RowExecutor
130130
int getChanges() const noexcept;
131131

132132
/// Return the number of columns in the result set returned by the prepared statement
133-
int getColumnCount() const
133+
int getColumnCount() const noexcept
134134
{
135135
return mColumnCount;
136136
}
137137
/// true when a row has been fetched with executeStep()
138-
bool hasRow() const
138+
bool hasRow() const noexcept
139139
{
140140
return mbHasRow;
141141
}
142142
/// true when the last executeStep() had no more row to fetch
143-
bool isDone() const
143+
bool isDone() const noexcept
144144
{
145145
return mbDone;
146146
}
@@ -167,7 +167,10 @@ class RowExecutor
167167
*
168168
* @return raw pointer to Statement Object
169169
*/
170-
TStatementPtr getStatement() const noexcept;
170+
TStatementPtr getStatement() const noexcept
171+
{
172+
return mpStatement;
173+
}
171174

172175
/**
173176
* @brief Return a prepared SQLite Statement Object.
@@ -176,6 +179,19 @@ class RowExecutor
176179
* @return raw pointer to Prepared Statement Object
177180
*/
178181
sqlite3_stmt* getPreparedStatement() const;
182+
183+
/**
184+
* @brief Return a prepared SQLite Statement Object.
185+
*
186+
* Throw an exception if the statement object was not prepared.
187+
* @return raw pointer to Prepared Statement Object
188+
*/
189+
TRowWeakPtr getExecutorWeakPtr() const
190+
{
191+
return mpRowExecutor;
192+
}
193+
194+
////////////////////////////////////////////////////////////////////////////
179195

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

225-
int mColumnCount{ 0 }; //!< Number of columns in the result of the prepared statement
226-
bool mbHasRow{ false }; //!< true when a row has been fetched with executeStep()
227-
bool mbDone{ false }; //!< true when the last executeStep() had no more row to fetch
241+
/// Shared Pointer to this object.
242+
/// Allows RowIterator to execute next step
243+
TRowPtr mpRowExecutor{};
244+
245+
int mColumnCount = 0; //!< Number of columns in the result of the prepared statement
246+
bool mbHasRow = false; //!< true when a row has been fetched with executeStep()
247+
bool mbDone = false; //!< true when the last executeStep() had no more row to fetch
228248

229249
/// Map of columns index by name (mutable so getColumnIndex can be const)
230250
mutable TColumnsMap mColumnNames{};

include/SQLiteCpp/Statement.h

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* @file Statement.h
33
* @ingroup SQLiteCpp
4-
* @brief A prepared SQLite Statement is a compiled SQL query ready to be executed, pointing to a row of result.
4+
* @brief A prepared SQLite Statement Object binder and Column getter.
55
*
66
* Copyright (c) 2012-2021 Sebastien Rombauts (sebastien.rombauts@gmail.com)
77
*
@@ -541,8 +541,64 @@ class Statement : public RowExecutor
541541
/// Return the number of bind parameters in the statement
542542
int getBindParameterCount() const noexcept;
543543

544+
////////////////////////////////////////////////////////////////////////////
545+
546+
class RowIterator
547+
{
548+
public:
549+
using iterator_category = std::input_iterator_tag;
550+
using value_type = Row;
551+
using reference = const Row&;
552+
using pointer = const Row*;
553+
using difference_type = std::ptrdiff_t;
554+
555+
RowIterator() = default;
556+
RowIterator(TStatementWeakPtr apStatement, TRowWeakPtr apRow, uint16_t aID) :
557+
mpStatement(apStatement), mpRow(apRow), mID(aID), mRow(apStatement, aID) {}
558+
559+
reference operator*() const
560+
{
561+
return mRow;
562+
}
563+
pointer operator->() const noexcept
564+
{
565+
return &mRow;
566+
}
567+
568+
reference operator++() noexcept
569+
{
570+
mRow = Row(mpStatement, ++mID);
571+
advance();
572+
return mRow;
573+
}
574+
value_type operator++(int)
575+
{
576+
Row copy{ mRow };
577+
mRow = Row(mpStatement, ++mID);
578+
advance();
579+
return copy;
580+
}
581+
582+
bool operator==(const RowIterator& aIt) const;
583+
bool operator!=(const RowIterator& aIt) const
584+
{
585+
return !(*this == aIt);
586+
}
587+
588+
private:
589+
void advance() noexcept;
590+
591+
TStatementWeakPtr mpStatement{};
592+
TRowWeakPtr mpRow{};
593+
uint16_t mID{};
594+
Row mRow{ mpStatement, mID };
595+
};
596+
597+
RowIterator begin();
598+
RowIterator end();
599+
544600
private:
545-
std::string mQuery; //!< UTF-8 SQL Query
601+
std::string mQuery; //!< UTF-8 SQL Query,
546602
};
547603

548604

src/Column.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const int Null = SQLITE_NULL;
2626

2727

2828
// Encapsulation of a Column in a row of the result pointed by the prepared Statement.
29-
Column::Column(const Statement::TStatementPtr& aStmtPtr, int aIndex) :
29+
Column::Column(const RowExecutor::TStatementPtr& aStmtPtr, int aIndex) :
3030
mStmtPtr(aStmtPtr),
3131
mIndex(aIndex)
3232
{

src/Row.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* @file Row.cpp
3+
* @ingroup SQLiteCpp
4+
* @brief TODO:
5+
*
6+
* Copyright (c) 2015 Shibao HONG (shibaohong@outlook.com)
7+
* Copyright (c) 2015-2021 Sebastien Rombauts (sebastien.rombauts@gmail.com)
8+
*
9+
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
10+
* or copy at http://opensource.org/licenses/MIT)
11+
*/
12+
#include <SQLiteCpp/Row.h>
13+
14+
#include <SQLiteCpp/Exception.h>
15+
16+
#include <sqlite3.h>
17+
18+
namespace SQLite
19+
{
20+
21+
22+
Row::Row(RowExecutor::TStatementWeakPtr apRow, std::size_t aID) :
23+
mpRow(apRow), ID(aID)
24+
{
25+
}
26+
27+
bool Row::isColumnNull(const int aIndex) const
28+
{
29+
return false;
30+
}
31+
32+
const char* Row::getText(uint32_t aColumnID) const noexcept
33+
{
34+
auto statement = mpRow.lock();
35+
36+
37+
auto pText = reinterpret_cast<const char*>(sqlite3_column_text(statement.get(), aColumnID));
38+
return (pText ? pText : "");
39+
}
40+
41+
} // namespace SQLite

src/RowExecutor.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* @file RowExecutor.cpp
33
* @ingroup SQLiteCpp
4-
* @brief TODO:
4+
* @brief Step executor for SQLite prepared Statement Object
55
*
66
* Copyright (c) 2015 Shibao HONG (shibaohong@outlook.com)
77
* Copyright (c) 2015-2021 Sebastien Rombauts (sebastien.rombauts@gmail.com)
@@ -24,6 +24,10 @@ namespace SQLite
2424
{
2525
prepareStatement(aQuery);
2626
createColumnInfo();
27+
28+
mpRowExecutor.swap(TRowPtr(this, [](const RowExecutor* const) {
29+
//empty destructor to make shared_ptr without ownership
30+
}));
2731
}
2832

2933
void SQLite::RowExecutor::prepareStatement(const std::string& aQuery)
@@ -165,12 +169,6 @@ namespace SQLite
165169
return sqlite3_errmsg(mpSQLite);
166170
}
167171

168-
// Return std::shared_ptr with SQLite statement object
169-
RowExecutor::TStatementPtr RowExecutor::getStatement() const noexcept
170-
{
171-
return mpStatement;
172-
}
173-
174172
// Return prepered SQLite statement object or throw
175173
sqlite3_stmt* RowExecutor::getPreparedStatement() const
176174
{

0 commit comments

Comments
 (0)