19 #ifndef SQLITE_DRIVER_HPP 20 #define SQLITE_DRIVER_HPP 29 namespace vgi {
namespace dbconn {
namespace dbd {
namespace sqlite {
31 enum class open_flag : int
33 READONLY = SQLITE_OPEN_READONLY,
34 READWRITE = SQLITE_OPEN_READWRITE,
35 CREATE = SQLITE_OPEN_CREATE,
36 DELETEONCLOSE = SQLITE_OPEN_DELETEONCLOSE,
37 EXCLUSIVE = SQLITE_OPEN_EXCLUSIVE,
38 #ifdef SQLITE_OPEN_AUTOPROXY 39 AUTOPROXY = SQLITE_OPEN_AUTOPROXY,
41 #ifdef SQLITE_OPEN_URI 42 URI = SQLITE_OPEN_URI,
44 #ifdef SQLITE_OPEN_MEMORY 45 MEMORY = SQLITE_OPEN_MEMORY,
47 MAIN_DB = SQLITE_OPEN_MAIN_DB,
48 TEMP_DB = SQLITE_OPEN_TEMP_DB,
49 TRANSIENT_DB = SQLITE_OPEN_TRANSIENT_DB,
50 MAIN_JOURNAL = SQLITE_OPEN_MAIN_JOURNAL,
51 TEMP_JOURNAL = SQLITE_OPEN_TEMP_JOURNAL,
52 SUBJOURNAL = SQLITE_OPEN_SUBJOURNAL,
53 MASTER_JOURNAL = SQLITE_OPEN_MASTER_JOURNAL,
54 NOMUTEX = SQLITE_OPEN_NOMUTEX,
55 FULLMUTEX = SQLITE_OPEN_FULLMUTEX,
56 SHAREDCACHE = SQLITE_OPEN_SHAREDCACHE,
57 PRIVATECACHE = SQLITE_OPEN_PRIVATECACHE,
58 #ifdef SQLITE_OPEN_WAL 63 constexpr open_flag operator|(open_flag l, open_flag r) {
return open_flag(utils::base_type(l) | utils::base_type(r)); }
66 enum class config_flag : int
68 #ifdef SQLITE_CONFIG_LOG 69 LOG = SQLITE_CONFIG_LOG,
71 #ifdef SQLITE_CONFIG_URI 72 URI = SQLITE_CONFIG_URI,
74 #ifdef SQLITE_CONFIG_PCACHE2 75 PCACHE2 = SQLITE_CONFIG_PCACHE2,
77 #ifdef SQLITE_CONFIG_GETPCACHE2 78 GETPCACHE2 = SQLITE_CONFIG_GETPCACHE2,
80 #ifdef SQLITE_CONFIG_COVERING_INDEX_SCAN 81 COVERING_INDEX = SQLITE_CONFIG_COVERING_INDEX_SCAN,
83 #ifdef SQLITE_CONFIG_SQLLOG 84 SQLLOG = SQLITE_CONFIG_SQLLOG,
86 #ifdef SQLITE_CONFIG_MMAP_SIZE 87 MMAP_SIZE = SQLITE_CONFIG_MMAP_SIZE,
89 #ifdef SQLITE_CONFIG_WIN32_HEAPSIZE 90 WIN32_HEAPSIZE = SQLITE_CONFIG_WIN32_HEAPSIZE,
92 #ifdef SQLITE_CONFIG_PCACHE_HDRSZ 93 PCACHE_HDRSZ = SQLITE_CONFIG_PCACHE_HDRSZ,
95 #ifdef SQLITE_CONFIG_PMASZ 96 PMASZ = SQLITE_CONFIG_PMASZ,
98 #ifdef SQLITE_CONFIG_STMTJRNL_SPILL 99 STMTJRNL_SPILL = SQLITE_CONFIG_STMTJRNL_SPILL,
101 SINGLETHREAD = SQLITE_CONFIG_SINGLETHREAD,
102 MULTITHREAD = SQLITE_CONFIG_MULTITHREAD,
103 SERIALIZED = SQLITE_CONFIG_SERIALIZED,
104 MALLOC = SQLITE_CONFIG_MALLOC,
105 GETMALLOC = SQLITE_CONFIG_GETMALLOC,
106 SCRATCH = SQLITE_CONFIG_SCRATCH,
107 PAGECACHE = SQLITE_CONFIG_PAGECACHE,
108 HEAP = SQLITE_CONFIG_HEAP,
109 MEMSTATUS = SQLITE_CONFIG_MEMSTATUS,
110 MUTEX = SQLITE_CONFIG_MUTEX,
111 GETMUTEX = SQLITE_CONFIG_GETMUTEX,
112 LOOKASIDE = SQLITE_CONFIG_LOOKASIDE,
113 PCACHE = SQLITE_CONFIG_PCACHE,
114 GETPCACHE = SQLITE_CONFIG_GETPCACHE,
119 enum class db_config_flag : int
121 #ifdef SQLITE_DBCONFIG_MAINDBNAME 122 MAINDBNAME = SQLITE_DBCONFIG_MAINDBNAME,
124 #ifdef SQLITE_DBCONFIG_ENABLE_FKEY 125 ENABLE_FKEY = SQLITE_DBCONFIG_ENABLE_FKEY,
127 #ifdef SQLITE_DBCONFIG_ENABLE_TRIGGER 128 ENABLE_TRIGGER = SQLITE_DBCONFIG_ENABLE_TRIGGER,
130 #ifdef SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 131 ENABLE_FTS3_TOKENIZER = SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER,
133 #ifdef SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 134 ENABLE_LOAD_EXTENSION = SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION,
136 #ifdef SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 137 NO_CKPT_ON_CLOSE = SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE,
139 LOOKASIDE = SQLITE_DBCONFIG_LOOKASIDE
142 static const char* decode_errcode(
int c)
146 case SQLITE_OK :
return "Successful result";
147 case SQLITE_ERROR :
return "SQL error or missing database";
148 case SQLITE_INTERNAL :
return "Internal logic error in SQLite";
149 case SQLITE_PERM :
return "Access permission denied";
150 case SQLITE_ABORT :
return "Callback routine requested an abort";
151 case SQLITE_BUSY :
return "The database file is locked";
152 case SQLITE_LOCKED :
return "A table in the database is locked";
153 case SQLITE_NOMEM :
return "A malloc() failed";
154 case SQLITE_READONLY :
return "Attempt to write a readonly database";
155 case SQLITE_INTERRUPT :
return "Operation terminated by sqlite3_interrupt()";
156 case SQLITE_IOERR :
return "Some kind of disk I/O error occurred";
157 case SQLITE_CORRUPT :
return "The database disk image is malformed";
158 case SQLITE_NOTFOUND :
return "Unknown opcode in sqlite3_file_control()";
159 case SQLITE_FULL :
return "Insertion failed because database is full";
160 case SQLITE_CANTOPEN :
return "Unable to open the database file";
161 case SQLITE_PROTOCOL :
return "Database lock protocol error";
162 case SQLITE_EMPTY :
return "Database is empty";
163 case SQLITE_SCHEMA :
return "The database schema changed";
164 case SQLITE_TOOBIG :
return "String or BLOB exceeds size limit";
165 case SQLITE_CONSTRAINT:
return "Abort due to constraint violation";
166 case SQLITE_MISMATCH :
return "Data type mismatch";
167 case SQLITE_MISUSE :
return "Library used incorrectly";
168 case SQLITE_NOLFS :
return "Uses OS features not supported on host";
169 case SQLITE_AUTH :
return "Authorization denied";
170 case SQLITE_FORMAT :
return "Auxiliary database format error";
171 case SQLITE_RANGE :
return "2nd parameter to sqlite3_bind out of range";
172 case SQLITE_NOTADB :
return "File opened that is not a database file";
174 case SQLITE_NOTICE :
return "Notifications from sqlite3_log()";
176 #ifdef SQLITE_WARNING 177 case SQLITE_WARNING :
return "Warnings from sqlite3_log()";
179 case SQLITE_ROW :
return "sqlite3_step() has another row ready";
180 case SQLITE_DONE :
return "sqlite3_step() has finished executing";
215 virtual bool has_data()
217 return column_count();
220 virtual bool more_results()
222 return (stmts_index > 0 && (stmts_index < sqlite_stmts.size() || (stmts_index == sqlite_stmts.size() && stepped)));
225 virtual size_t row_count()
const 227 return std::abs(row_cnt);
230 virtual size_t rows_affected()
const 232 return affected_rows;
235 virtual size_t column_count()
const 240 virtual std::string column_name(
size_t col_idx)
243 return sqlite3_column_name(sqlite_stmt, col_idx);
246 virtual int column_index(
const std::string& col_name)
248 auto it = name2index.find(col_name);
249 if (it != name2index.end())
256 throw std::runtime_error(std::string(__FUNCTION__).append(
": Cursors are not supported by database"));
261 throw std::runtime_error(std::string(__FUNCTION__).append(
": Cursors are not supported by database"));
266 throw std::runtime_error(std::string(__FUNCTION__).append(
": Cursors are not supported by database"));
272 if (stepped && column_cnt > 0)
277 auto res = sqlite3_step(sqlite_stmt);
281 affected_rows = (row_cnt > 0 ? row_cnt : sqlite3_changes(sqlite_conn));
282 sqlite3_reset(sqlite_stmt);
283 if (stmts_index > 0 && stmts_index < sqlite_stmts.size())
286 row_cnt = column_cnt = 0;
287 sqlite_stmt = sqlite_stmts[stmts_index++];
288 int tmp = affected_rows;
299 column_cnt = sqlite3_column_count(sqlite_stmt);
300 for (
auto i = 0; i < column_cnt; ++i)
301 name2index[sqlite3_column_name(sqlite_stmt, i)] = i;
310 throw std::runtime_error(std::string(__FUNCTION__).append(
": ").append(decode_errcode(res)));
315 virtual bool is_null(
size_t col_idx)
318 return (SQLITE_NULL == sqlite3_column_type(sqlite_stmt, col_idx));
321 virtual int16_t get_short(
size_t col_idx)
323 return get_slint<int16_t>(col_idx);
326 virtual uint16_t get_ushort(
size_t col_idx)
328 return get_slint<uint16_t>(col_idx);
331 virtual int32_t get_int(
size_t col_idx)
333 return get_slint<int32_t>(col_idx);
336 virtual uint32_t get_uint(
size_t col_idx)
338 return get_slint<uint32_t>(col_idx);
341 virtual int64_t get_long(
size_t col_idx)
343 return get_slint64<int64_t>(col_idx);
346 virtual uint64_t get_ulong(
size_t col_idx)
348 return get_slint64<uint64_t>(col_idx);
351 virtual float get_float(
size_t col_idx)
353 return static_cast<float>(get_double(col_idx));
356 virtual double get_double(
size_t col_idx)
359 return sqlite3_column_double(sqlite_stmt, col_idx);
362 virtual bool get_bool(
size_t col_idx)
364 return get_slint<bool>(col_idx);
367 virtual char get_char(
size_t col_idx)
370 return *sqlite3_column_text(sqlite_stmt, col_idx);
373 virtual std::string get_string(
size_t col_idx)
376 auto start =
reinterpret_cast<const char*
>(sqlite3_column_text(sqlite_stmt, col_idx));
377 return std::move(std::string(start, sqlite3_column_bytes(sqlite_stmt, col_idx)));
380 virtual int get_date(
size_t col_idx)
382 auto s = get_string(col_idx);
383 s.erase(std::remove(s.begin(), s.end(),
'-'), s.end());
387 virtual double get_time(
size_t col_idx)
389 auto s = get_string(col_idx);
390 s.erase(std::remove(s.begin(), s.end(),
':'), s.end());
394 virtual time_t get_datetime(
size_t col_idx)
396 std::string s = get_string(col_idx);
397 std::memset(&stm, 0,
sizeof(stm));
398 std::sscanf(s.c_str(),
"%04d-%02d-%02d %02d:%02d:%02d", &stm.tm_year, &stm.tm_mon, &stm.tm_mday, &stm.tm_hour, &stm.tm_min, &stm.tm_sec);
405 virtual char16_t get_u16char(
size_t col_idx)
408 return *(
reinterpret_cast<const char16_t*
>(sqlite3_column_text16(sqlite_stmt, col_idx)));
411 virtual std::u16string get_u16string(
size_t col_idx)
414 auto start =
reinterpret_cast<const char16_t*
>(sqlite3_column_text16(sqlite_stmt, col_idx));
415 sqlite3_column_bytes16(sqlite_stmt, col_idx);
416 return std::u16string(start);
419 virtual std::vector<uint8_t> get_binary(
size_t col_idx)
422 auto data = sqlite3_column_blob(sqlite_stmt, col_idx);
423 std::vector<uint8_t> t(sqlite3_column_bytes(sqlite_stmt, col_idx));
424 std::memcpy(reinterpret_cast<void*>(t.data()), data, t.size());
431 if (
nullptr != sqlite_conn)
432 sqlite3_interrupt(sqlite_conn);
433 if (
nullptr != sqlite_stmt)
434 return (SQLITE_OK == sqlite3_reset(sqlite_stmt));
441 result_set(std::vector<sqlite3_stmt*>& stmts) : sqlite_stmts(stmts) {}
446 T get_slint(
size_t col_idx)
449 return static_cast<T
>(sqlite3_column_int(sqlite_stmt, col_idx));
453 T get_slint64(
size_t col_idx)
456 return static_cast<T
>(sqlite3_column_int64(sqlite_stmt, col_idx));
461 if (sqlite_stmt ==
nullptr)
462 throw std::runtime_error(std::string(__FUNCTION__).append(
": Invalid result state object state"));
466 bool stepped =
false;
469 size_t stmts_index = 0;
470 size_t affected_rows = 0;
471 sqlite3* sqlite_conn =
nullptr;
472 sqlite3_stmt* sqlite_stmt =
nullptr;
474 std::vector<sqlite3_stmt*>& sqlite_stmts;
475 std::map<std::string, int> name2index;
491 driver& version(
long& ver)
493 std::lock_guard<utils::spin_lock> lg(lock);
494 ver = sqlite3_libversion_number();
498 driver& version_string(std::string& ver)
500 std::lock_guard<utils::spin_lock> lg(lock);
501 ver = sqlite3_libversion();
505 driver& max_connections(
unsigned int conn_num)
507 std::lock_guard<utils::spin_lock> lg(lock);
512 template <
typename... T>
513 driver& config(config_flag flag, T... t)
516 std::lock_guard<utils::spin_lock> lg(lock);
517 if (flag == config_flag::SOFT_HEAP_LIMIT)
519 if (
sizeof...(t) != 1)
524 sqlite3_soft_heap_limit(p);
530 throw std::runtime_error(std::string(__FUNCTION__).append(
": This function must be used before any connections are opened"));
532 ret = sqlite3_config(utils::base_type(flag), t...);
533 sqlite3_initialize();
535 if (SQLITE_OK != ret)
536 throw std::runtime_error(std::string(__FUNCTION__).append(
": Failed to set config parameter: ").append(std::to_string(utils::base_type(flag))).append(
": ").append(decode_errcode(ret)));
551 void upd_conn_count(
int change)
553 std::lock_guard<utils::spin_lock> lg(lock);
559 std::lock_guard<utils::spin_lock> lg(lock);
560 return conn_cnt == max_conn;
564 unsigned int max_conn = UINT_MAX;
565 unsigned int conn_cnt = 0;
566 utils::spin_lock lock;
589 : sqlite_conn(conn.sqlite_conn), is_utf16(conn.is_utf16),
590 is_autocommit(conn.is_autocommit), oflag(conn.oflag),
591 vfsname(std::move(conn.vfsname)), server(std::move(conn.server))
593 conn.sqlite_conn =
nullptr;
601 sqlite_conn = conn.sqlite_conn;
602 conn.sqlite_conn =
nullptr;
603 is_utf16 = conn.is_utf16;
604 is_autocommit = conn.is_autocommit;
606 vfsname = std::move(conn.vfsname);
607 server = std::move(conn.server);
612 template <
typename... T>
613 connection& config(db_config_flag flag, T... t)
615 if (sqlite_conn ==
nullptr)
616 throw std::runtime_error(std::string(__FUNCTION__).append(
": This function must be used after connection is opened"));
617 int ret = sqlite3_db_config(sqlite_conn, utils::base_type(flag), t...);
618 if (SQLITE_OK != ret)
619 throw std::runtime_error(std::string(__FUNCTION__).append(
": Failed to set config parameter: ").append(std::to_string(utils::base_type(flag))).append(
": ").append(decode_errcode(ret)));
623 virtual bool connect()
625 if (drv->is_max_conn())
626 throw std::runtime_error(std::string(__FUNCTION__).append(
": Can't open new connections, please revise max connections"));
628 if (
true == connected())
632 if (SQLITE_OK != (is_utf16 ? sqlite3_open16(server.c_str(), &sqlite_conn) : sqlite3_open(server.c_str(), &sqlite_conn)))
633 throw std::runtime_error(std::string(__FUNCTION__).append(
": Failed to connect: ").append(server));
637 if (SQLITE_OK != sqlite3_open_v2(server.c_str(), &sqlite_conn, oflag, (vfsname.empty() ?
nullptr : vfsname.c_str())))
638 throw std::runtime_error(std::string(__FUNCTION__).append(
": Failed to connect: ").append(server));
640 drv->upd_conn_count(1);
644 virtual void disconnect()
646 if (
nullptr != sqlite_conn)
648 sqlite3_close(sqlite_conn);
649 sqlite_conn =
nullptr;
650 drv->upd_conn_count(-1);
654 virtual bool connected()
const 656 return (
nullptr != sqlite_conn);
659 virtual bool alive()
const 661 return (
nullptr != sqlite_conn);
664 virtual void autocommit(
bool ac)
666 if (
nullptr != sqlite_conn)
668 if (ac != is_autocommit)
672 sqlite_exec(
"rollback transaction;");
674 sqlite_exec(
"begin transaction;");
679 virtual void commit()
681 if (
false == is_autocommit)
683 sqlite_exec(
"commit transaction;");
684 sqlite_exec(
"begin transaction;");
688 virtual void rollback()
690 if (
false == is_autocommit)
692 sqlite_exec(
"rollback transaction;");
693 sqlite_exec(
"begin transaction;");
701 oflag = utils::base_type(flag);
717 sqlite3* native_connection()
const 723 void sqlite_exec(
const std::string& sql)
726 if (SQLITE_OK != sqlite3_exec(sqlite_conn, sql.c_str(),
nullptr,
nullptr, &err))
728 std::string s = (err ? err :
"unknown error");
730 throw std::runtime_error(std::string(__FUNCTION__).append(
": Failed to execute: ").append(sql).append(
": ").append(s));
743 : drv(drv), server(server)
749 sqlite3* sqlite_conn =
nullptr;
750 bool is_utf16 =
false;
751 bool is_autocommit =
true;
760 return create_connection(
new connection(
this, server));
785 virtual bool cancel()
787 bool res = rs.cancel();
788 for (
auto stmt : sqlite_stmts)
790 if (SQLITE_OK != sqlite3_finalize(stmt))
793 sqlite_stmts.clear();
794 rs.sqlite_stmt =
nullptr;
805 virtual dbi::iresult_set* execute(
const std::string& cmd,
bool usecursor =
false,
bool scrollable =
false)
809 command.erase(std::find_if(command.rbegin(), command.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), command.end());
811 while (command.length() > 0 && plen != command.length())
813 command.erase(command.begin(), std::find_if(command.begin(), command.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
814 sqlite_stmts.push_back(
nullptr);
815 prepare(command, &sqlite_stmts[sqlite_stmts.size() - 1]);
816 plen = command.length();
822 virtual void prepare(
const std::string& cmd)
825 throw std::runtime_error(std::string(__FUNCTION__).append(
": SQL command is not set"));
826 if (
false == conn.alive())
827 throw std::runtime_error(std::string(__FUNCTION__).append(
": Database connection is dead"));
829 sqlite_stmts.resize(1);
830 prepare(cmd, &sqlite_stmts[0]);
833 virtual void call(
const std::string& cmd)
835 throw std::runtime_error(std::string(__FUNCTION__).append(
": Stored procedures are not supported by database"));
838 virtual int proc_retval()
840 throw std::runtime_error(std::string(__FUNCTION__).append(
": Stored procedures are not supported by database"));
843 virtual void set_null(
size_t param_idx)
846 if (SQLITE_OK != sqlite3_bind_null(sqlite_stmts.front(), param_idx + 1))
847 throw std::runtime_error(std::string(__FUNCTION__).append(
": Failed to set null at index ").append(std::to_string(param_idx)));
850 virtual void set_short(
size_t param_idx, int16_t val)
852 set_slint(param_idx, val);
855 virtual void set_ushort(
size_t param_idx, uint16_t val)
857 set_slint(param_idx, val);
860 virtual void set_int(
size_t param_idx, int32_t val)
862 set_slint(param_idx, val);
865 virtual void set_uint(
size_t param_idx, uint32_t val)
867 set_int(param_idx, val);
870 virtual void set_long(
size_t param_idx, int64_t val)
872 set_slint64(param_idx, val);
875 virtual void set_ulong(
size_t param_idx, uint64_t val)
877 set_slint64(param_idx, val);
880 virtual void set_float(
size_t param_idx,
float val)
882 set_double(param_idx, val);
885 virtual void set_double(
size_t param_idx,
double val)
888 if (SQLITE_OK != sqlite3_bind_double(sqlite_stmts.front(), param_idx + 1, val))
889 throw std::runtime_error(std::string(__FUNCTION__).append(
": Failed to set double at index ").append(std::to_string(param_idx)));
892 virtual void set_bool(
size_t param_idx,
bool val)
894 set_slint(param_idx, val);
897 virtual void set_char(
size_t param_idx,
char val)
899 set_string(param_idx, std::string(1, val));
902 virtual void set_string(
size_t param_idx,
const std::string& val)
905 if (SQLITE_OK != sqlite3_bind_text(sqlite_stmts.front(), param_idx + 1, val.c_str(), val.size(), SQLITE_TRANSIENT))
906 throw std::runtime_error(std::string(__FUNCTION__).append(
": Failed to set string at index ").append(std::to_string(param_idx)));
909 virtual void set_date(
size_t param_idx,
int val)
911 auto yr = val / 10000;
912 auto mon = (val % 10000) / 100;
913 auto day = val % 100;
914 std::vector<char> dt(11);
915 std::sprintf(dt.data(),
"%4d-%02d-%02d", yr, mon, day);
916 set_string(param_idx, dt.data());
919 virtual void set_time(
size_t param_idx,
double val)
921 auto t =
static_cast<int>(val);
923 auto min = (t % 10000) / 100;
925 auto ms =
static_cast<int>(floor((val - t) * 1000 + 0.5));
926 std::vector<char> dt(13);
927 std::sprintf(dt.data(),
"%02d:%02d:%02d.%03d", hr, min, sec, ms);
928 set_string(param_idx, dt.data());
931 virtual void set_datetime(
size_t param_idx, time_t val)
933 #if defined(_WIN32) || defined(_WIN64) 934 ::localtime_s(&stm, &val);
936 ::localtime_r(&val, &stm);
939 std::vector<char> dt(20);
940 std::sprintf(dt.data(),
"%04d-%02d-%02d %02d:%02d:%02d", stm.tm_year, stm.tm_mon + 1, stm.tm_mday, stm.tm_hour, stm.tm_min, stm.tm_sec);
941 set_string(param_idx, dt.data());
944 virtual void set_u16char(
size_t param_idx, char16_t val)
946 set_u16string(param_idx, std::u16string(1, val));
949 virtual void set_u16string(
size_t param_idx,
const std::u16string& val)
952 if (SQLITE_OK != sqlite3_bind_text16(sqlite_stmts.front(), param_idx + 1, val.data(), val.size() *
sizeof(char16_t), SQLITE_TRANSIENT))
953 throw std::runtime_error(std::string(__FUNCTION__).append(
": Failed to set text16 at index ").append(std::to_string(param_idx)));
956 virtual void set_binary(
size_t param_idx,
const std::vector<uint8_t>& val)
959 if (SQLITE_OK != sqlite3_bind_blob(sqlite_stmts.front(), param_idx + 1, val.data(), val.size(), SQLITE_TRANSIENT))
960 throw std::runtime_error(std::string(__FUNCTION__).append(
": Failed to set blob at index ").append(std::to_string(param_idx)));
970 rs.sqlite_conn = conn.sqlite_conn;
974 void set_slint(
size_t param_idx, T val)
977 int ret = sqlite3_bind_int(sqlite_stmts.front(), param_idx + 1, val);
978 if (SQLITE_OK != ret)
979 throw std::runtime_error(std::string(__FUNCTION__).append(
": Failed to set int at index ").append(std::to_string(param_idx)).append(
": ").append(decode_errcode(ret)));
983 void set_slint64(
size_t param_idx, T val)
986 int ret = sqlite3_bind_int64(sqlite_stmts.front(), param_idx + 1, val);
987 if (SQLITE_OK != ret)
988 throw std::runtime_error(std::string(__FUNCTION__).append(
": Failed to set int64 at index ").append(std::to_string(param_idx)).append(
": ").append(decode_errcode(ret)));
991 void prepare(
const std::string& cmd, sqlite3_stmt** stmtptr)
993 auto ret = sqlite3_prepare_v2(conn.sqlite_conn, cmd.c_str(), cmd.length(), stmtptr, &tail);
994 if (SQLITE_OK != ret)
995 throw std::runtime_error(std::string(__FUNCTION__).append(
": Failed to prepare command, error code: ").append(decode_errcode(ret)));
999 size_t rows_affected = 0;
1001 std::string err =
"";
1002 for (
size_t i = 0; i < sqlite_stmts.size(); ++i)
1005 rs.sqlite_stmt = sqlite_stmts[i];
1010 catch (
const std::exception& e)
1013 err.append(e.what()).append(
"; ");
1016 rows_affected += rs.rows_affected();
1019 rs.stmts_index = i + 1;
1023 rs.affected_rows = rows_affected;
1025 throw std::runtime_error(std::string(__FUNCTION__).append(
": Failed to execute ").append(std::to_string(failed_cnt)).append(
" command(s): ").append(err));
1031 if (sqlite_stmts.size() == 0)
1032 throw std::runtime_error(std::string(__FUNCTION__).append(
": Invalid statement object state"));
1036 const char* tail =
nullptr;
1037 std::vector<sqlite3_stmt*> sqlite_stmts;
1039 bool cursor =
false;
1040 std::string command;
1048 return new statement(dynamic_cast<connection&>(iconn));
1058 #endif // SQLITE_DRIVER_HPP iresult_set - is an interface that describes common functionality for all concrete native implementat...
sqlite driver class based on sqlite3 C++ library.
istatement - is an interface that describes common functionality for all concrete native implementati...
iconnection - is an interface that describes common functionality for all concrete native implementat...
result_set - is a class that implements dbi::iresult_set interface and represents results of SQL quer...
statement - is a class that implements dbi::istatement interface and represents native database state...
idriver - is an interface for driver classes which declares function for creating a connection object...
connection - is a class that implements dbi::iconnection interface and represents native database con...
connection - is a class that manages native driver connection handle.