Skip to content

Commit 2da22a7

Browse files
committed
Add RowIterator and Row class fundation
1 parent 3fdd78e commit 2da22a7

File tree

9 files changed

+244
-28
lines changed

9 files changed

+244
-28
lines changed

CMakeLists.txt

+2
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

+4-7
Original file line numberDiff line numberDiff line change
@@ -54,11 +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);
58-
59-
// default destructor: the finalization will be done by the destructor of the last shared pointer
60-
// default copy constructor and assignment operator are perfectly suited :
61-
// they copy the Statement::Ptr which in turn increments the reference counter.
57+
explicit Column(const RowExecutor::TStatementPtr& aStmtPtr, int aIndex);
6258

6359
/**
6460
* @brief Return a pointer to the named assigned to this result column (potentially aliased)
@@ -252,7 +248,7 @@ class Column
252248
}
253249

254250
private:
255-
Statement::TStatementPtr mStmtPtr; ///< Shared Pointer to the prepared SQLite Statement Object
251+
RowExecutor::TStatementPtr mStmtPtr; ///< Shared Pointer to the prepared SQLite Statement Object
256252
int mIndex; ///< Index of the column in the row of result, starting at 0
257253
};
258254

@@ -283,9 +279,10 @@ T Statement::getColumns()
283279
template<typename T, const int... Is>
284280
T Statement::getColumns(const std::integer_sequence<int, Is...>)
285281
{
286-
return T{Column(getStatement(), Is)...};
282+
return T{ Column(getStatement(), Is)... };
287283
}
288284

289285
#endif
290286

287+
291288
} // namespace SQLite

include/SQLiteCpp/Row.h

+56
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 ([email protected])
7+
* Copyright (c) 2015-2021 Sebastien Rombauts ([email protected])
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

+33-8
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 ([email protected])
77
* Copyright (c) 2015-2021 Sebastien Rombauts ([email protected])
@@ -45,6 +45,11 @@ class RowExecutor
4545
/// Type to store columns names and indexes
4646
using TColumnsMap = std::map<std::string, int, std::less<>>;
4747

48+
RowExecutor(const RowExecutor&) = delete;
49+
RowExecutor(RowExecutor&&) = default;
50+
RowExecutor& operator=(const RowExecutor&) = delete;
51+
RowExecutor& operator=(RowExecutor&&) = default;
52+
4853
/// Reset the statement to make it ready for a new execution. Throws an exception on error.
4954
void reset();
5055

@@ -130,17 +135,17 @@ class RowExecutor
130135
int getChanges() const noexcept;
131136

132137
/// Return the number of columns in the result set returned by the prepared statement
133-
int getColumnCount() const
138+
int getColumnCount() const noexcept
134139
{
135140
return mColumnCount;
136141
}
137142
/// true when a row has been fetched with executeStep()
138-
bool hasRow() const
143+
bool hasRow() const noexcept
139144
{
140145
return mbHasRow;
141146
}
142147
/// true when the last executeStep() had no more row to fetch
143-
bool isDone() const
148+
bool isDone() const noexcept
144149
{
145150
return mbDone;
146151
}
@@ -167,7 +172,10 @@ class RowExecutor
167172
*
168173
* @return raw pointer to Statement Object
169174
*/
170-
TStatementPtr getStatement() const noexcept;
175+
TStatementPtr getStatement() const noexcept
176+
{
177+
return mpStatement;
178+
}
171179

172180
/**
173181
* @brief Return a prepared SQLite Statement Object.
@@ -176,6 +184,19 @@ class RowExecutor
176184
* @return raw pointer to Prepared Statement Object
177185
*/
178186
sqlite3_stmt* getPreparedStatement() const;
187+
188+
/**
189+
* @brief Return a prepared SQLite Statement Object.
190+
*
191+
* Throw an exception if the statement object was not prepared.
192+
* @return raw pointer to Prepared Statement Object
193+
*/
194+
TRowWeakPtr getExecutorWeakPtr() const
195+
{
196+
return mpRowExecutor;
197+
}
198+
199+
////////////////////////////////////////////////////////////////////////////
179200

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

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
246+
/// Shared Pointer to this object.
247+
/// Allows RowIterator to execute next step
248+
TRowPtr mpRowExecutor{};
249+
250+
int mColumnCount = 0; //!< Number of columns in the result of the prepared statement
251+
bool mbHasRow = false; //!< true when a row has been fetched with executeStep()
252+
bool mbDone = false; //!< true when the last executeStep() had no more row to fetch
228253

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

include/SQLiteCpp/Statement.h

+58-2
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 ([email protected])
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

+1-1
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

+41
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 ([email protected])
7+
* Copyright (c) 2015-2021 Sebastien Rombauts ([email protected])
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

+5-7
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 ([email protected])
77
* Copyright (c) 2015-2021 Sebastien Rombauts ([email protected])
@@ -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)