MLIB
Loading...
Searching...
No Matches
sqlitepp.h
Go to the documentation of this file.
1/*
2 Copyright (c) Mircea Neacsu (2014-2025) Licensed under MIT License.
3 This file is part of MLIB project. See LICENSE file for full license terms.
4*/
5
7
8#pragma once
9
10#if __has_include("defs.h")
11#include "defs.h"
12#endif
13
14#include <string>
15#include <map>
16#include <memory>
17#include <cassert>
18#include <cstring>
19#include <filesystem>
20
21#include "safe_winsock.h"
22#include <sqlite3/sqlite3.h>
23#include "errorcode.h"
24
25#ifndef _WIN32
26//#include <strings.h>
27#endif
28
29#if (defined(_MSVC_LANG) && _MSVC_LANG < 202002L) \
30 || (!defined(_MSVC_LANG) && (__cplusplus < 202002L))
31#error "sqlitepp requires c++20"
32#endif
33
34#pragma comment(lib, "sqlite3.lib")
35
36namespace mlib {
37
38class Database;
39
41class Query
42{
43public:
45 Query ();
46
48 Query (Database& db, const std::string& sql = std::string ());
49
51 Query (const Query& other);
52
54 Query (Query&& other);
55
57 Query& operator= (Query&& rhs);
58
60 Query& operator= (const Query& rhs);
61
62 ~Query ();
63
65 operator sqlite3_stmt* ();
66
68 Query& operator= (const std::string& str);
69
71 Query& sql (const std::string& str);
72
74 std::string sql () const;
75
77 operator std::string () const;
78
80 erc step ();
81
82 Query& bind (int par, const std::string& val);
83 Query& bind (const std::string& parname, const std::string& val);
84 Query& bind (int par, int val);
85 Query& bind (const std::string& parname, int val);
86 Query& bind (int par, double val);
87 Query& bind (const std::string& parname, double val);
88 Query& bind (int par, sqlite3_int64 val);
89 Query& bind (const std::string& parname, sqlite3_int64 val);
90 Query& bind (int par, void* val, int len);
91 Query& bind (const std::string& parname, void* val, int len);
92#ifdef _WIN32
93 Query& bind (int par, const SYSTEMTIME& st);
94 Query& bind (const std::string& parname, const SYSTEMTIME& st);
95#endif
96
98
99 int column_int (int nc) const;
100 int column_int (const std::string& colname) const;
101
102 std::string column_str (int nc) const;
103 std::string column_str (const std::string& colname) const;
104
105 const char* column_text (int nc) const;
106 const char* column_text (const std::string& colname) const;
107
108 double column_double (int nc) const;
109 double column_double (const std::string& colname) const;
110
111 sqlite3_int64 column_int64 (int nc) const;
112 sqlite3_int64 column_int64 (const std::string& name) const;
113
114 const void* column_blob (int nc) const;
115 const void* column_blob (const std::string& name) const;
116
117#ifdef _WIN32
118 SYSTEMTIME column_time (int nc) const;
119 SYSTEMTIME column_time (const std::string& name) const;
120#endif
121
122 int column_type (int nc) const;
123 int column_type (const std::string& colname) const;
124
125 int column_size (int nc) const;
126 int column_size (const std::string& colname) const;
127
128#ifndef SQLITE_OMIT_DECLTYPE
129 std::string decl_type (int nc) const;
130 std::string decl_type (const std::string& colname) const;
131#endif
132
133#ifdef SQLITE_ENABLE_COLUMN_METADATA
134 std::string table_name (int nc) const;
135 std::string table_name (const std::string& colname) const;
136
137 std::string database_name (int nc) const;
138 std::string database_name (const std::string& colname) const;
139#endif
140
141 std::string column_name (int nc) const;
142
144 int columns ();
145
147 erc reset ();
148
150 void clear ();
151
152private:
153 friend class Database;
154
155 void map_columns () const;
156 int find_col (const std::string& colname) const;
157 erc check_errors (int rc);
158
159 sqlite3_stmt* stmt;
160 std::shared_ptr<sqlite3> dbase;
161
164 struct iless
165 {
166 bool operator() (const std::string& left, const std::string& right) const;
167 };
168
169 std::map<std::string, int, Query::iless> mutable index;
170 bool mutable col_mapped;
171};
172
175{
176public:
178 enum class openflags
179 {
180 readonly = SQLITE_OPEN_READONLY,
181 readwrite = SQLITE_OPEN_READWRITE,
182 create = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
183 uri = SQLITE_OPEN_URI,
184 nomutex = SQLITE_OPEN_NOMUTEX,
185 fullmutex = SQLITE_OPEN_FULLMUTEX,
186 sharedcache = SQLITE_OPEN_SHAREDCACHE,
187 privatecache = SQLITE_OPEN_PRIVATECACHE,
188 memory = SQLITE_OPEN_MEMORY | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
189 nofollow = SQLITE_OPEN_NOFOLLOW,
190 ext_result = SQLITE_OPEN_EXRESCODE
191 };
192
194 Database ();
195
197 Database (const std::filesystem::path& name, openflags flags = openflags::create);
198
200 Database& copy (Database& src);
201
203 bool connected ()
204 {
205 return (bool)db;
206 };
207
209 bool is_readonly ();
210
212 operator sqlite3* ()
213 {
214 return handle ();
215 }
216
218 sqlite3* handle () const
219 {
220 return db ? db.get () : nullptr;
221 }
222
224 sqlite3_int64 last_rowid ();
225
227 sqlite3_int64 changes ();
228
230 sqlite3_int64 total_changes ();
231
233 erc open (const std::filesystem::path& name, openflags flags = openflags::create);
234
236 erc close ();
237
239 erc exec (const std::string& sql);
240
242 checked<Query> make_query (const std::string& sql);
243
245 checked<Query> make_query_multiple (std::string& sql);
246
248 std::filesystem::path path (const std::string& schema = "main") const;
249
251 std::string schema (int n) const;
252
254 int extended_error ();
255
257 erc flush ();
258
260 inline static void Errors (mlib::errfac& fac)
261 {
262 sqlite_errors = &fac;
263 }
264
266 inline static const errfac& Errors ()
267 {
268 return *sqlite_errors;
269 }
270
271private:
272 std::shared_ptr<sqlite3> db;
273 friend class Query;
274
275 static errfac* sqlite_errors;
276};
277
278
279/*==================== INLINE FUNCTIONS ===========================*/
280inline sqlite3_int64 Database::last_rowid ()
281{
282 assert (db);
283 return sqlite3_last_insert_rowid (db.get ());
284}
285
286inline sqlite3_int64 Database::changes ()
287{
288 assert (db);
289 return sqlite3_changes64 (db.get ());
290}
291
292inline sqlite3_int64 mlib::Database::total_changes ()
293{
294 assert (db);
295 return sqlite3_total_changes64 (db.get ());
296}
297
299 : stmt (0)
300 , col_mapped (false)
301{}
302
303inline Query::operator sqlite3_stmt* ()
304{
305 return stmt;
306}
307
308inline int Query::columns ()
309{
310 return sqlite3_column_count (stmt);
311}
312
318inline Query& Query::operator= (const std::string& str)
319{
320 return sql (str);
321}
322
323inline bool Query::iless::operator() (const std::string& left, const std::string& right) const
324{
325#ifdef _WIN32
326 return _strcmpi (left.c_str (), right.c_str ()) < 0;
327#else
328 return strcasecmp (left.c_str (), right.c_str ()) < 0;
329#endif
330}
331
335inline Query::operator std::string () const
336{
337 return sql ();
338}
339
342{
343 return static_cast<Database::openflags> (static_cast<int> (f1) | static_cast<int> (f2));
344}
345
346}; // namespace mlib
Wrapper for database connection handle.
Definition sqlitepp.h:175
static void Errors(mlib::errfac &fac)
Set error facility for all SQLITEPP errors.
Definition sqlitepp.h:260
erc close()
Close database connection.
Definition sqlitepp.cpp:177
Database()
Default constructor.
Definition sqlitepp.cpp:54
int extended_error()
Return extended result code.
Definition sqlitepp.cpp:237
Database & copy(Database &src)
Copy database content.
Definition sqlitepp.cpp:80
erc exec(const std::string &sql)
Execute multiple SQL sentences.
Definition sqlitepp.cpp:184
openflags
Flags for database opening mode.
Definition sqlitepp.h:179
@ sharedcache
database connection is eligible to use shared cache mode
Definition sqlitepp.h:186
@ nofollow
filename cannot be a symbolic link
Definition sqlitepp.h:189
@ privatecache
database connection does not participate in shared cache mode
Definition sqlitepp.h:187
@ readwrite
Read/write access on existing database.
Definition sqlitepp.h:181
@ readonly
Read-only access.
Definition sqlitepp.h:180
@ ext_result
enables extended result codes
Definition sqlitepp.h:190
@ create
Read/write/create access.
Definition sqlitepp.h:182
@ uri
filename is interpreted as a URI
Definition sqlitepp.h:183
@ fullmutex
database connection opens in the serialized mode
Definition sqlitepp.h:185
@ nomutex
database connection opens in multi-threaded mode
Definition sqlitepp.h:184
@ memory
database opened in memory
Definition sqlitepp.h:188
checked< Query > make_query(const std::string &sql)
Return a Query object containing a prepared statement with the given SQL text.
Definition sqlitepp.cpp:202
checked< Query > make_query_multiple(std::string &sql)
Return a Query object containing the first prepared statement of the given SQL text.
Definition sqlitepp.cpp:220
sqlite3_int64 changes()
Return number of records changed by last query.
Definition sqlitepp.h:286
bool connected()
Check if database is opened or not.
Definition sqlitepp.h:203
sqlite3_int64 last_rowid()
Return rowid of last successful insert.
Definition sqlitepp.h:280
std::filesystem::path path(const std::string &schema="main") const
Return file path of a database connection.
Definition sqlitepp.cpp:120
sqlite3_int64 total_changes()
Return total number of changes since database was opened.
Definition sqlitepp.h:292
sqlite3 * handle() const
Return handle of database connection.
Definition sqlitepp.h:218
erc open(const std::filesystem::path &name, openflags flags=openflags::create)
Open database connection.
Definition sqlitepp.cpp:162
bool is_readonly()
Return true if database connection is read-only.
Definition sqlitepp.cpp:148
static const errfac & Errors()
Return error facility used by SQLITEPP.
Definition sqlitepp.h:266
std::string schema(int n) const
Return schema name for a database connection.
Definition sqlitepp.cpp:136
erc flush()
Flush.
Definition sqlitepp.cpp:243
Wrapper for SQL prepared sentences.
Definition sqlitepp.h:42
int column_int(int nc) const
Return column value converted to an integer.
Definition sqlitepp.cpp:826
std::string decl_type(int nc) const
Definition sqlitepp.cpp:637
int column_type(int nc) const
Return data type for a column specified by name or number.
Definition sqlitepp.cpp:594
Query & clear_bindings()
Reset all parameters to NULL values.
Definition sqlitepp.cpp:577
sqlite3_int64 column_int64(int nc) const
Return column value converted to a 64-bit integer.
Definition sqlitepp.cpp:905
std::string column_str(int nc) const
Return column value as an UTF-8 encoded string.
Definition sqlitepp.cpp:842
void clear()
Finalizes the statement and removes the database connection.
Definition sqlitepp.cpp:423
const char * column_text(int nc) const
Return a pointer to a NULL-terminated text with the column content.
Definition sqlitepp.cpp:863
Query()
Default constructor.
Definition sqlitepp.h:298
erc reset()
Reset statement to initial state.
Definition sqlitepp.cpp:413
int columns()
Return number of columns in the result set.
Definition sqlitepp.h:308
std::string column_name(int nc) const
Return column name.
Definition sqlitepp.cpp:789
Query & operator=(Query &&rhs)
Move assignment operator.
Definition sqlitepp.cpp:322
int column_size(int nc) const
Return number of bytes in a column that contains a BLOB or a string.
Definition sqlitepp.cpp:610
const void * column_blob(int nc) const
Return a pointer to a BLOB with the column content.
Definition sqlitepp.cpp:921
Query & sql(const std::string &str)
Assign SQL text to a query.
Definition sqlitepp.cpp:367
std::string table_name(int nc) const
Return originating table name.
Definition sqlitepp.cpp:685
double column_double(int nc) const
Return floating point value of the column.
Definition sqlitepp.cpp:884
erc step()
Evaluate the statement.
Definition sqlitepp.cpp:401
std::string sql() const
Retrieve SQL text.
Definition sqlitepp.cpp:387
std::string database_name(int nc) const
Return originating schema name.
Definition sqlitepp.cpp:741
Query & bind(int par, const std::string &val)
Bind a parameter specified by number to a character string.
Definition sqlitepp.cpp:453
Provides a mechanism similar to expected for creating objects associated with error codes.
Definition errorcode.h:203
objects returned as a function result or thrown directly.
Definition errorcode.h:73
An error facility routes a group of errors handled in a similar manner.
Definition errorcode.h:141
Definition of mlib::erc and mlib::errfac classes.
sock::mflags operator|(sock::mflags f1, sock::mflags f2)
Bitwise OR operator for send message flags.
Definition sock.h:691