libdballe  9.14
sqlite.h
Go to the documentation of this file.
1 
4 #ifndef DBALLE_SQL_SQLITE_H
5 #define DBALLE_SQL_SQLITE_H
6 
7 #include <dballe/core/error.h>
8 #include <dballe/sql/sql.h>
9 #include <functional>
10 #include <sqlite3.h>
11 #include <vector>
12 
13 namespace dballe {
14 namespace sql {
15 struct SQLiteStatement;
16 
21 {
22  std::string msg;
23 
24  error_sqlite(sqlite3* db, const std::string& msg);
25  error_sqlite(const std::string& dbmsg, const std::string& msg);
26  ~error_sqlite() noexcept {}
27 
28  const char* what() const noexcept override { return msg.c_str(); }
29 
30  static void throwf(sqlite3* db, const char* fmt, ...)
32 };
33 
36 {
37 protected:
39  std::string pathname;
41  int flags = 0;
43  sqlite3* db = nullptr;
45  bool forked = false;
46 
47  void init_after_connect();
48  static void on_sqlite3_profile(void* arg, const char* query,
49  sqlite3_uint64 usecs);
50 
52 
53  void fork_prepare() override;
54  void fork_parent() override;
55  void fork_child() override;
56 
57  void check_connection();
58 
59  void reopen();
60 
61 public:
62  SQLiteConnection(const SQLiteConnection&) = delete;
63  SQLiteConnection(const SQLiteConnection&&) = delete;
65 
66  static std::shared_ptr<SQLiteConnection> create();
67 
68  SQLiteConnection& operator=(const SQLiteConnection&) = delete;
69 
70  operator sqlite3*() { return db; }
71 
72  void open_file(const std::string& pathname,
73  int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
74  void open_memory(int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
75  void open_private_file(int flags = SQLITE_OPEN_READWRITE |
76  SQLITE_OPEN_CREATE);
77 
78  std::unique_ptr<Transaction> transaction(bool readonly = false) override;
79  std::unique_ptr<SQLiteStatement> sqlitestatement(const std::string& query);
80 
81  bool has_table(const std::string& name) override;
82  std::string get_setting(const std::string& key) override;
83  void set_setting(const std::string& key, const std::string& value) override;
84  void drop_settings() override;
85  void execute(const std::string& query) override;
86  void explain(const std::string& query, FILE* out) override;
87 
91  void drop_table_if_exists(const char* name);
92 
99  int get_last_insert_id();
100 
102  int changes();
103 
105  void exec(const std::string& query);
106  void exec_nothrow(const std::string& query) noexcept;
107 
108 #if SQLITE_VERSION_NUMBER >= 3014000
109 
114  void trace(unsigned mask = SQLITE_TRACE_STMT);
115 #endif
116 };
117 
120 {
121  SQLiteConnection& conn;
122  std::string query;
123  sqlite3_stmt* stm = nullptr;
124 
125  SQLiteStatement(SQLiteConnection& conn, const std::string& query);
126  SQLiteStatement(const SQLiteStatement&) = delete;
127  SQLiteStatement(const SQLiteStatement&&) = delete;
128  ~SQLiteStatement();
129  SQLiteStatement& operator=(const SQLiteStatement&) = delete;
130 
138  template <typename... Args> void bind(const Args&... args)
139  {
140  bindn<sizeof...(args)>(args...);
141  }
142 
143  void bind_null_val(int idx);
144  void bind_val(int idx, int val);
145  void bind_val(int idx, unsigned val);
146  void bind_val(int idx, unsigned short val);
147  void bind_val(int idx, const Datetime& val);
148  void bind_val(int idx, const char* val); // Warning: SQLITE_STATIC is used
149  void bind_val(int idx,
150  const std::string& val); // Warning: SQLITE_STATIC is used
151  void
152  bind_val(int idx,
153  const std::vector<uint8_t>& val); // Warning: SQLITE_STATIC is used
154 
156  void execute();
157 
164  void execute(std::function<void()> on_row);
165 
170  void execute_one(std::function<void()> on_row);
171 
173  int column_int(int col) { return sqlite3_column_int(stm, col); }
174 
176  sqlite3_int64 column_int64(int col)
177  {
178  return sqlite3_column_int64(stm, col);
179  }
180 
182  double column_double(int col) { return sqlite3_column_double(stm, col); }
183 
185  const char* column_string(int col)
186  {
187  return (const char*)sqlite3_column_text(stm, col);
188  }
189 
191  std::vector<uint8_t> column_blob(int col)
192  {
193  int size = sqlite3_column_bytes(stm, col);
194  const uint8_t* val = (const uint8_t*)sqlite3_column_blob(stm, col);
195  return std::vector<uint8_t>(val, val + size);
196  }
197 
199  Datetime column_datetime(int col);
200 
202  bool column_isnull(int col)
203  {
204  return sqlite3_column_type(stm, col) == SQLITE_NULL;
205  }
206 
207  void wrap_sqlite3_reset();
208  void wrap_sqlite3_reset_nothrow() noexcept;
213  [[noreturn]] void reset_and_throw(const std::string& errmsg);
214 
215  operator sqlite3_stmt*() { return stm; }
216 #if 0
217  int execute();
220  int exec_direct(const char* query);
222  int exec_direct(const char* query, int qlen);
223 
225  int execute_and_close();
227  int exec_direct_and_close(const char* query);
229  int exec_direct_and_close(const char* query, int qlen);
230 
235  int columns_count();
236  bool fetch();
237  bool fetch_expecting_one();
238  void close_cursor();
239  void close_cursor_if_needed();
241  size_t select_rowcount();
243  size_t rowcount();
244 #endif
245 
246 private:
247  // Implementation of variadic bind: terminating condition
248  template <size_t total> void bindn() {}
249  // Implementation of variadic bind: recursive iteration over the parameter
250  // pack
251  template <size_t total, typename... Args, typename T>
252  void bindn(const T& first, const Args&... args)
253  {
254  bind_val(total - sizeof...(args), first);
255  bindn<total>(args...);
256  }
257 };
258 
259 } // namespace sql
260 } // namespace dballe
261 #endif
int changes()
Count the number of rows modified by the last query that was run.
const char * column_string(int col)
Read the string value of a column in the result set (0-based)
Definition: sqlite.h:185
void execute(const std::string &query) override
Execute a query without reading its results.
void drop_table_if_exists(const char *name)
Delete a table in the database if it exists, otherwise do nothing.
void reset_and_throw(const std::string &errmsg)
Get the current error message, reset the statement and throw error_sqlite.
sqlite3_int64 column_int64(int col)
Read the int value of a column in the result set (0-based)
Definition: sqlite.h:176
void exec(const std::string &query)
Wrap sqlite3_exec, without a callback.
int column_int(int col)
Read the int value of a column in the result set (0-based)
Definition: sqlite.h:173
bool column_isnull(int col)
Check if a column has a NULL value (0-based)
Definition: sqlite.h:202
Definition: utils.h:40
int get_last_insert_id()
Return LAST_INSERT_ID or LAST_INSER_ROWID or whatever is appropriate for the current database...
bool forked
Marker to catch attempts to reuse connections in forked processes.
Definition: sqlite.h:45
Definition: cmdline.h:18
double column_double(int col)
Read the double value of a column in the result set (0-based)
Definition: sqlite.h:182
void drop_settings() override
Drop the settings table.
void execute_one(std::function< void()> on_row)
Run the query, raising an error if there is more than one row in the result.
Definition: sql.h:53
std::unique_ptr< Transaction > transaction(bool readonly=false) override
Begin a transaction.
void explain(const std::string &query, FILE *out) override
Format and print the EXPLAIN output for the query to the given file.
sqlite3 * db
Database connection.
Definition: sqlite.h:43
Common infrastructure for talking with SQL databases.
Error in case of failed database operations.
Definition: error.h:21
std::string get_setting(const std::string &key) override
Get a value from the settings table.
Datetime column_datetime(int col)
Read the string value of a column and parse it as a Datetime.
Report an SQLite error.
Definition: sqlite.h:20
int flags
Connection flags.
Definition: sqlite.h:41
Date and time.
Definition: types.h:163
void execute()
Run the query, ignoring all results.
#define WREPORT_THROWF_ATTRS(a, b)
SQLite statement.
Definition: sqlite.h:119
std::string pathname
Connection pathname.
Definition: sqlite.h:39
void bind(const Args &... args)
Bind all the arguments in a single invocation.
Definition: sqlite.h:138
std::vector< uint8_t > column_blob(int col)
Read the string value of a column in the result set (0-based)
Definition: sqlite.h:191
bool has_table(const std::string &name) override
Check if the database contains a table.
Database connection.
Definition: sqlite.h:35
void set_setting(const std::string &key, const std::string &value) override
Set a value in the settings table.