Skip to content

Commit 95158f3

Browse files
committed
Implement working Row class.
Move more statement info to StatementPtr. Replace int&uint16_t with int_fast16_t.
1 parent 5dcde6d commit 95158f3

File tree

10 files changed

+210
-104
lines changed

10 files changed

+210
-104
lines changed

include/SQLiteCpp/Column.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class Column
5151
* @param[in] aStmtPtr Shared pointer to the prepared SQLite Statement Object.
5252
* @param[in] aIndex Index of the column in the row of result, starting at 0
5353
*/
54-
explicit Column(const TStatementPtr& aStatementPtr, uint16_t aIndex) noexcept :
54+
explicit Column(const TStatementPtr& aStatementPtr, int_fast16_t aIndex) noexcept :
5555
mStatementPtr(aStatementPtr),
5656
mIndex(aIndex), mRowIndex(mStatementPtr->mCurrentStep) {}
5757

@@ -61,6 +61,14 @@ class Column
6161
Column(Column&& aColumn) noexcept = default;
6262
Column& operator=(Column&& aColumn) noexcept = default;
6363

64+
/**
65+
* @return Column index in statement return table.
66+
*/
67+
int_fast16_t getIndex() const noexcept
68+
{
69+
return mIndex;
70+
}
71+
6472
/**
6573
* @brief Return a pointer to the named assigned to this result column (potentially aliased)
6674
*
@@ -241,7 +249,7 @@ class Column
241249
sqlite3_stmt* getStatement() const;
242250

243251
TStatementPtr mStatementPtr; ///< Shared Pointer to the prepared SQLite Statement Object
244-
uint16_t mIndex; ///< Index of the column in the row of result, starting at 0
252+
int_fast16_t mIndex; ///< Index of the column in the row of result, starting at 0
245253
std::size_t mRowIndex; ///< Index of the statement row, starting at 0
246254
};
247255

include/SQLiteCpp/Row.h

Lines changed: 70 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
*/
1212
#pragma once
1313

14+
#include <SQLiteCpp/Exception.h>
1415
#include <SQLiteCpp/StatementPtr.h>
1516
#include <SQLiteCpp/Column.h>
1617

18+
#include <iterator>
1719
#include <memory>
1820
#include <string>
1921

@@ -22,35 +24,67 @@ namespace SQLite
2224
{
2325

2426
/**
25-
* @brief CLASS IS WIP!
27+
* @brief Small class returned by StatementExecutor::RowIterator.
28+
*
29+
* Use with for-range to iterate on statement columns.
2630
*/
2731
class Row
2832
{
2933
public:
30-
Row(TStatementWeakPtr apStatement, std::size_t aID) :
31-
mpStatement(apStatement), mID(aID) {}
34+
Row(TStatementWeakPtr apStatement, std::size_t aID);
3235

33-
std::size_t getRowNumber() const
36+
/**
37+
* @return Row ID/steps executed since statement start (starting at 0).
38+
*/
39+
std::size_t getRowNumber() const noexcept
3440
{
3541
return mID;
3642
}
3743

44+
/**
45+
* @return Column with given index
46+
*
47+
* @throws SQLite::Exception when index is out of bounds
48+
*/
49+
Column operator[](int_fast16_t aIndex) const;
50+
/**
51+
* @return Column with given name
52+
*
53+
* @throws SQLite::Exception when there is no column with given name
54+
*/
55+
Column operator[](const char* aName) const;
56+
57+
////////////////////////////////////////////////////////////////////////////
58+
59+
/**
60+
* @brief Return the index of the specified (potentially aliased) column name
61+
*
62+
* @param[in] apName Aliased name of the column, that is, the named specified in the query (not the original name)
63+
*
64+
* @throws SQLite::Exception if the specified name is not known.
65+
*/
66+
int_fast16_t getColumnIndex(const char* apName) const;
67+
68+
////////////////////////////////////////////////////////////////////////////
69+
3870
/**
3971
* @brief RandomAccessIterator for row columns.
72+
*
73+
* Use by using for-range on Row or by calling Row::begin().
4074
*/
4175
class ColumnIterator
4276
{
4377
public:
44-
//TODO: using iterator_category = std::random_access_iterator_tag;
78+
// TODO: using iterator_category = std::random_access_iterator_tag;
4579
using iterator_category = std::bidirectional_iterator_tag;
4680
using value_type = Column;
4781
using reference = const Column&;
4882
using pointer = const Column*;
4983
using difference_type = std::ptrdiff_t;
5084

5185
ColumnIterator() = default;
52-
ColumnIterator(TStatementPtr apStatement, uint16_t aID) :
53-
mpStatement(apStatement), mID(aID), mColumn(apStatement, aID) {}
86+
ColumnIterator(TStatementPtr apStatement, int_fast16_t aID) :
87+
mpStatement(apStatement), mRowID(apStatement->mCurrentStep), mID(aID), mColumn(apStatement, aID) {}
5488

5589
reference operator*() const noexcept
5690
{
@@ -91,17 +125,41 @@ class Row
91125
}
92126

93127
private:
94-
TStatementPtr mpStatement{}; //!< Shared pointer to prepared Statement Object
95-
std::size_t mRowID{}; //!< Current row number
96-
uint16_t mID{}; //!< Current column number
128+
TStatementPtr mpStatement; //!< Shared pointer to prepared Statement Object
129+
std::size_t mRowID; //!< Current row number
130+
int_fast16_t mID; //!< Current column number
97131

98132
/// Internal column object storage
99133
Column mColumn{ mpStatement, mID };
100134
};
101135

136+
/**
137+
* @return RowIterator to first column of this prepared statement.
138+
*/
139+
ColumnIterator begin() const;
140+
141+
/**
142+
* @return RowIterator to after the last column of this prepared statement.
143+
*/
144+
ColumnIterator end() const;
145+
102146
private:
103-
TStatementWeakPtr mpStatement;
104-
std::size_t mID;
147+
/**
148+
* @brief Checks if weak_ptr contains existing SQLite Statement Object.
149+
*
150+
* @throws SQLite::Exception when weak_ptr is expired.
151+
*/
152+
void checkStatement() const
153+
{
154+
if (mpStatement.expired())
155+
{
156+
throw SQLite::Exception("Row is used after destruction of SQLite Statement Object");
157+
}
158+
}
159+
160+
TStatementWeakPtr mpStatement; //!< Weak Pointer to the prepared SQLite Statement Object
161+
std::size_t mID; //!< Index of the statement row, starting at 0
162+
int_fast16_t mColumnCount{}; //!< Number of columns in row
105163
};
106164

107165
} // namespace SQLite

include/SQLiteCpp/Statement.h

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -93,70 +93,70 @@ class Statement : public StatementExecutor
9393
// => if you know what you are doing, use bindNoCopy() instead of bind()
9494

9595
SQLITECPP_PURE_FUNC
96-
int getIndex(const char * const apName) const;
96+
int getIndex(const char* const apName) const;
9797

9898
/**
9999
* @brief Bind an int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
100100
*/
101-
void bind(const int aIndex, const int32_t aValue);
101+
void bind(const int_fast16_t aIndex, const int32_t aValue);
102102
/**
103103
* @brief Bind a 32bits unsigned int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
104104
*/
105-
void bind(const int aIndex, const uint32_t aValue);
105+
void bind(const int_fast16_t aIndex, const uint32_t aValue);
106106
/**
107107
* @brief Bind a 64bits int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
108108
*/
109-
void bind(const int aIndex, const int64_t aValue);
109+
void bind(const int_fast16_t aIndex, const int64_t aValue);
110110
/**
111111
* @brief Bind a double (64bits float) value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
112112
*/
113-
void bind(const int aIndex, const double aValue);
113+
void bind(const int_fast16_t aIndex, const double aValue);
114114
/**
115115
* @brief Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
116116
*
117117
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
118118
*/
119-
void bind(const int aIndex, const std::string& aValue);
119+
void bind(const int_fast16_t aIndex, const std::string& aValue);
120120
/**
121121
* @brief Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
122122
*
123123
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
124124
*/
125-
void bind(const int aIndex, const char* apValue);
125+
void bind(const int_fast16_t aIndex, const char* apValue);
126126
/**
127127
* @brief Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
128128
*
129129
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
130130
*/
131-
void bind(const int aIndex, const void* apValue, const int aSize);
131+
void bind(const int_fast16_t aIndex, const void* apValue, const int aSize);
132132
/**
133133
* @brief Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1).
134134
*
135135
* The string can contain null characters as it is binded using its size.
136136
*
137137
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
138138
*/
139-
void bindNoCopy(const int aIndex, const std::string& aValue);
139+
void bindNoCopy(const int_fast16_t aIndex, const std::string& aValue);
140140
/**
141141
* @brief Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
142142
*
143143
* Main usage is with null-terminated literal text (aka in code static strings)
144144
*
145145
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
146146
*/
147-
void bindNoCopy(const int aIndex, const char* apValue);
147+
void bindNoCopy(const int_fast16_t aIndex, const char* apValue);
148148
/**
149149
* @brief Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
150150
*
151151
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
152152
*/
153-
void bindNoCopy(const int aIndex, const void* apValue, const int aSize);
153+
void bindNoCopy(const int_fast16_t aIndex, const void* apValue, const int aSize);
154154
/**
155155
* @brief Bind a NULL value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
156156
*
157157
* @see clearBindings() to set all bound parameters to NULL.
158158
*/
159-
void bind(const int aIndex);
159+
void bind(const int_fast16_t aIndex);
160160

161161
/**
162162
* @brief Bind an int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
@@ -258,28 +258,28 @@ class Statement : public StatementExecutor
258258
/**
259259
* @brief Bind an int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
260260
*/
261-
void bind(const std::string& aName, const int32_t aValue)
261+
void bind(const std::string& aName, const int32_t aValue)
262262
{
263263
bind(aName.c_str(), aValue);
264264
}
265265
/**
266266
* @brief Bind a 32bits unsigned int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
267267
*/
268-
void bind(const std::string& aName, const uint32_t aValue)
268+
void bind(const std::string& aName, const uint32_t aValue)
269269
{
270270
bind(aName.c_str(), aValue);
271271
}
272272
/**
273273
* @brief Bind a 64bits int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
274274
*/
275-
void bind(const std::string& aName, const int64_t aValue)
275+
void bind(const std::string& aName, const int64_t aValue)
276276
{
277277
bind(aName.c_str(), aValue);
278278
}
279279
/**
280280
* @brief Bind a double (64bits float) value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
281281
*/
282-
void bind(const std::string& aName, const double aValue)
282+
void bind(const std::string& aName, const double aValue)
283283
{
284284
bind(aName.c_str(), aValue);
285285
}
@@ -288,7 +288,7 @@ class Statement : public StatementExecutor
288288
*
289289
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
290290
*/
291-
void bind(const std::string& aName, const std::string& aValue)
291+
void bind(const std::string& aName, const std::string& aValue)
292292
{
293293
bind(aName.c_str(), aValue);
294294
}
@@ -297,7 +297,7 @@ class Statement : public StatementExecutor
297297
*
298298
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
299299
*/
300-
void bind(const std::string& aName, const char* apValue)
300+
void bind(const std::string& aName, const char* apValue)
301301
{
302302
bind(aName.c_str(), apValue);
303303
}
@@ -306,7 +306,7 @@ class Statement : public StatementExecutor
306306
*
307307
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
308308
*/
309-
void bind(const std::string& aName, const void* apValue, const int aSize)
309+
void bind(const std::string& aName, const void* apValue, const int aSize)
310310
{
311311
bind(aName.c_str(), apValue, aSize);
312312
}
@@ -378,7 +378,7 @@ class Statement : public StatementExecutor
378378
* Thus, you should instead extract immediately its data (getInt(), getText()...)
379379
* and use or copy this data for any later usage.
380380
*/
381-
Column getColumn(const int aIndex);
381+
Column getColumn(const int_fast16_t aIndex);
382382

383383
/**
384384
* @brief Return a copy of the column data specified by its column name (less efficient than using an index)
@@ -431,12 +431,12 @@ class Statement : public StatementExecutor
431431
*
432432
* @note Requires std=C++14
433433
*/
434-
template<typename T, int N>
434+
template<typename T, int_fast16_t N>
435435
T getColumns()
436436
{
437437
checkRow();
438438
checkIndex(N - 1);
439-
return getColumns<T>(std::make_integer_sequence<int, N>{});
439+
return getColumns<T>(std::make_integer_sequence<int_fast16_t, N>{});
440440
}
441441

442442
private:
@@ -449,7 +449,7 @@ class Statement : public StatementExecutor
449449
* @return Column object for each column in statement
450450
*/
451451
template<typename T, const int... Is>
452-
T getColumns(const std::integer_sequence<int, Is...>)
452+
T getColumns(const std::integer_sequence<int_fast16_t, Is...>)
453453
{
454454
return T{ Column(getStatementPtr(), Is)... };
455455
}
@@ -466,7 +466,7 @@ class Statement : public StatementExecutor
466466
*
467467
* Throw an exception if the specified index is out of the [0, getColumnCount()) range.
468468
*/
469-
bool isColumnNull(const int aIndex) const;
469+
bool isColumnNull(const int_fast16_t aIndex) const;
470470

471471
/**
472472
* @brief Test if the column value is NULL
@@ -488,7 +488,7 @@ class Statement : public StatementExecutor
488488
*
489489
* Throw an exception if the specified index is out of the [0, getColumnCount()) range.
490490
*/
491-
const char* getColumnName(const int aIndex) const;
491+
const char* getColumnName(const int_fast16_t aIndex) const;
492492

493493
#ifdef SQLITE_ENABLE_COLUMN_METADATA
494494
/**
@@ -500,7 +500,7 @@ class Statement : public StatementExecutor
500500
*
501501
* Throw an exception if the specified index is out of the [0, getColumnCount()) range.
502502
*/
503-
const char* getColumnOriginName(const int aIndex) const;
503+
const char* getColumnOriginName(const int_fast16_t aIndex) const;
504504
#endif
505505

506506
/**
@@ -528,7 +528,7 @@ class Statement : public StatementExecutor
528528
* - the statement is not a SELECT query
529529
* - the column at aIndex is not a table column but an expression or subquery
530530
*/
531-
const char* getColumnDeclaredType(const int aIndex) const;
531+
const char* getColumnDeclaredType(const int_fast16_t aIndex) const;
532532

533533
////////////////////////////////////////////////////////////////////////////
534534

0 commit comments

Comments
 (0)