SQLiteXX  0.1.0
 All Classes Namespaces Files Functions Enumerations Enumerator
Statement.cpp
1 
2 #include "Statement.h"
3 
4 namespace sqlite
5 {
7  {
8  return row_iterator(statement);
9  }
10 
12  {
13  // statement argument is unused because the end is a nullptr.
14  // This will stop warnings
15  (void)statement;
16 
17  return row_iterator();
18  }
19 
20  statement::statement() noexcept :
21  m_handle(nullptr, sqlite3_finalize),
22  m_done(false)
23  {}
24 
25  statement::operator bool() const noexcept
26  {
27  return static_cast<bool>(m_handle);
28  }
29 
32  sqlite3_stmt* statement::handle() const noexcept
33  {
34  return m_handle.get();
35  }
36 
37  bool statement::step() const
38  {
39  // This is to signal when the user has reached the end but
40  // calls step again. The official SQLite3 API specifies that "sqlite3_step"
41  // should not be called again after done before a reset. We just want it to
42  // return false signaling done and be a NOP.
43  if (m_done) return false;
44 
45  const int result = sqlite3_step(handle());
46 
47  if (result == SQLITE_ROW) return true;
48  if (result == SQLITE_DONE) {
49  m_done = true;
50  return false;
51  }
52 
53  throw_last_error();
54  return false;
55  }
56 
57  int statement::execute() const
58  {
59  bool done = !step();
60  // This variable is only used for the assert.
61  // Doing this so there is no warnings on release builds.
62  ((void)done);
63  assert(done);
64 
65  return sqlite3_changes(sqlite3_db_handle(handle()));
66  }
67 
68  void statement::bind(const int index, const int value) const
69  {
70  if (SQLITE_OK != sqlite3_bind_int(handle(), index, value))
71  {
72  throw_last_error();
73  }
74  }
75 
76  void statement::bind(const int index, const double value) const
77  {
78  if (SQLITE_OK != sqlite3_bind_double(handle(), index, value))
79  {
80  throw_last_error();
81  }
82  }
83 
84  void statement::bind(const int index, const void * const value, const int size, bindtype type) const
85  {
86  if (SQLITE_OK != sqlite3_bind_blob(handle(), index, value, size, type == bindtype::transiently ? SQLITE_TRANSIENT : SQLITE_STATIC))
87  {
88  throw_last_error();
89  }
90  }
91 
92  void statement::bind(const int index, const blob &value) const
93  {
94  if (SQLITE_OK != sqlite3_bind_blob(handle(), index, value.data(), value.size(), SQLITE_TRANSIENT))
95  {
96  throw_last_error();
97  }
98  }
99 
100  void statement::bind(const int index, const char * const value, const int size, bindtype type) const
101  {
102  if (SQLITE_OK != sqlite3_bind_text(handle(), index, value, size, type == bindtype::transiently ? SQLITE_TRANSIENT : SQLITE_STATIC))
103  {
104  throw_last_error();
105  }
106  }
107 
108  void statement::bind(const int index, const char16_t * const value, const int size, bindtype type) const
109  {
110  if (SQLITE_OK != sqlite3_bind_text16(handle(), index, value, size, type == bindtype::transiently ? SQLITE_TRANSIENT : SQLITE_STATIC))
111  {
112  throw_last_error();
113  }
114  }
115 
116  void statement::bind(const int index, const std::string &value) const
117  {
118  bind(index, value.c_str(), value.size());
119  }
120 
121  void statement::bind(const int index, const std::u16string &value) const
122  {
123  bind(index, value.c_str(), value.size() * sizeof(char16_t));
124  }
125 
126  void statement::throw_last_error() const
127  {
128  throw_error_code(sqlite3_db_handle(handle()));
129  }
130 
132  {
133  if (statement.step())
134  {
135  m_statement = &statement;
136  }
137  }
138 
140  {
141  if (!m_statement->step())
142  {
143  m_statement = nullptr;
144  }
145 
146  return *this;
147  }
148 
149  bool row_iterator::operator!=(const row_iterator &other) const noexcept
150  {
151  return m_statement != other.m_statement;
152  }
153 
154  row row_iterator::operator*() const noexcept
155  {
156  return row(m_statement->handle());
157  }
158 }
row operator*() const noexcept
Dereference operation.
Definition: Statement.cpp:154
A SQLite dynamically typed value object, aka "sqlite3_value".
Definition: Value.h:27
size_t size() const
Used to get the size of the contained 'blob'.
Definition: Blob.cpp:48
const void * data() const
The raw data of the blob's contents.
Definition: Blob.cpp:44
bool operator!=(const row_iterator &other) const noexcept
Comparison operation.
Definition: Statement.cpp:149
means that the content will likely change in the near future and that SQLite should make its own priv...
bool step() const
Evaluates a prepared statement.
Definition: Statement.cpp:37
void bind(const int index, const int value) const
Binds an integer value to a parameter in an SQL prepared statement.
Definition: Statement.cpp:68
sqlite3_stmt * handle() const noexcept
Returns pointer to the underlying "sqlite3_stmt" object.
Definition: Statement.cpp:32
Helps when iterating over rows in a "SELECT" statement.
Definition: Statement.h:592
int execute() const
Executes a prepared statement and will return the number of changes to the database.
Definition: Statement.cpp:57
bindtype
Used to specify the way to bind a value to a statement.
Definition: SQLiteEnums.h:23
Represents a single SQL statement that has been compiled into binary form and is ready to be evaluate...
Definition: Statement.h:350
Represents a returned row when stepping through a "SELECT" statement.
Definition: Statement.h:307
row_iterator() noexcept=default
Default constructor.
row_iterator end(const statement &statement) noexcept
Returns an iterator to the end.
Definition: Statement.cpp:11
row_iterator begin(const statement &statement) noexcept
Returns an iterator to the first row of a statement.
Definition: Statement.cpp:6
statement() noexcept
Default constructor.
Definition: Statement.cpp:20
row_iterator & operator++() noexcept
Increment iterator to the next row object of the statement.
Definition: Statement.cpp:139
A "Binary Large OBject".
Definition: Blob.h:20