blob: 7c514f01a6d1e93102cf26f1f00f0f9e86e65cfc (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
// Copyright (c) 2022 Klemens D. Morgenstern
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_SQLITE_RESULTSET_HPP
#define BOOST_SQLITE_RESULTSET_HPP
#include <memory>
#include <boost/sqlite/row.hpp>
#include <boost/describe/members.hpp>
#include <boost/system/result.hpp>
BOOST_SQLITE_BEGIN_NAMESPACE
struct connection ;
/**
@brief Representation of a result from a database.
@ingroup reference
If is a forward-range with output iterators.
@par Example
@code{.cpp}
extern sqlite::connection conn;
sqlite::resultset rs = conn.query("select * from users;");
do
{
handle_row(r.current());
}
while (rs.read_next()) // read it line by line
@endcode
*/
struct resultset
{
/// Returns the current row.
row current() const &
{
row r;
r.stm_ = impl_.get();
return r;
}
/// Checks if the last row has been reached.
bool done() const {return done_;}
///@{
/// Read the next row. Returns false if there's nothing more to read.
BOOST_SQLITE_DECL bool read_next(system::error_code & ec, error_info & ei);
BOOST_SQLITE_DECL bool read_next();
///@}
///
std::size_t column_count() const
{
return sqlite3_column_count(impl_.get());
}
/// Returns the name of the column idx.
cstring_ref column_name(std::size_t idx) const
{
return sqlite3_column_name(impl_.get(), static_cast<int>(idx));
}
/// Returns the name of the source table for column idx.
cstring_ref table_name(std::size_t idx) const
{
return sqlite3_column_table_name(impl_.get(), static_cast<int>(idx));
}
/// Returns the origin name of the column for column idx.
cstring_ref column_origin_name(std::size_t idx) const
{
return sqlite3_column_origin_name(impl_.get(), static_cast<int>(idx));
}
/// The input iterator can be used to read every row in a for-loop
struct iterator
{
using value_type = value;
using difference_type = int;
using reference = value&;
using iterator_category = std::forward_iterator_tag;
iterator() {}
explicit iterator(sqlite3_stmt * stmt, bool sentinel) : sentinel_(sentinel )
{
row_.stm_ = stmt;
}
bool operator!=(iterator rhs) const
{
return sentinel_ != rhs.sentinel_;
}
row &operator*() { return row_; }
row *operator->() { return &row_; }
BOOST_SQLITE_DECL
iterator operator++();
iterator operator++(int)
{
auto l = *this;
++(*this);
return l;
}
private:
row row_;
bool sentinel_ = true;
};
/// Return an input iterator to the currently unread row
iterator begin() { return iterator(impl_.get(), done_);}
/// Sentinel iterator.
iterator end() { return iterator(impl_.get(), true); }
private:
friend struct connection;
friend struct statement;
struct deleter_
{
constexpr deleter_() noexcept {}
bool delete_ = true;
void operator()(sqlite3_stmt * sm)
{
if (sqlite3_data_count(sm) > 0)
while ( sqlite3_step(sm) == SQLITE_ROW);
if (delete_)
sqlite3_finalize(sm);
else
{
sqlite3_clear_bindings(sm);
sqlite3_reset(sm);
}
}
};
std::unique_ptr<sqlite3_stmt, deleter_> impl_;
bool done_ = false;
};
BOOST_SQLITE_END_NAMESPACE
#endif //BOOST_SQLITE_RESULTSET_HPP
|