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
|
#include <cassert>
#include <iostream>
#include <memory>
#include <sstream>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <notmuch.h>
#include <sqlite3.h>
#include "sqlstmt.h"
using namespace std;
static void
dbthrow (sqlite3 *db, const char *query)
{
const char *dbpath = sqlite3_db_filename (db, "main");
if (!dbpath)
dbpath = "sqlite3 database";
ostringstream errbuf;
if (query)
errbuf << dbpath << ":\n Query: " << query
<< "\n Error: " << sqlite3_errmsg (db);
else
errbuf << dbpath << ": " << sqlite3_errmsg (db);
throw sqlerr_t (errbuf.str ());
}
sqlstmt_t &
sqlstmt_t::set_status (int status)
{
status_ = status;
if (status != SQLITE_OK && status != SQLITE_ROW && status != SQLITE_DONE)
dbthrow (sqlite3_db_handle (stmt_), nullptr);
return *this;
}
void
sqlstmt_t::fail ()
{
assert (status_ != SQLITE_OK);
if (status_ == SQLITE_DONE)
throw sqldone_t(string ("No rows left in query: ") + sqlite3_sql (stmt_));
else
throw sqlerr_t(string ("sqlstmt_t::operator[]: used after error\n"
" Query: ") + sqlite3_sql (stmt_)
+ "\n Error: " + sqlite3_errstr(status_));
}
sqlstmt_t::sqlstmt_t (sqlite3 *db, const char *fmt, ...)
{
va_list ap;
va_start (ap, fmt);
char *query = sqlite3_vmprintf(fmt, ap);
va_end (ap);
if (!query)
throw sqlerr_t ("sqlite3_vmprintf: out of memory");
unique_ptr<char, decltype(&sqlite3_free)> _c (query, sqlite3_free);
const char *tail;
if (sqlite3_prepare_v2(db, query, -1, &stmt_, &tail))
dbthrow (db, query);
if (tail && *tail)
throw sqlerr_t (string("illegal compound query\n Query: ") + query);
}
sqlstmt_t::sqlstmt_t(const sqlstmt_t &l)
{
int err = sqlite3_prepare_v2(sqlite3_db_handle(l.stmt_),
sqlite3_sql(l.stmt_), -1, &stmt_, nullptr);
if (err)
throw sqlerr_t (string("could not copy query\n Query: ")
+ sqlite3_sql(l.stmt_) + "\n Error: "
+ sqlite3_errstr(err) + "\n");
}
void
sqlexec (sqlite3 *db, const char *fmt, ...)
{
char *query;
va_list ap;
va_start (ap, fmt);
query = sqlite3_vmprintf (fmt, ap);
unique_ptr<char, decltype(&sqlite3_free)> _c (query, sqlite3_free);
va_end (ap);
if (!query)
throw sqlerr_t ("sqlite3_vmprintf: out of memory in sqlexec");
int err = sqlite3_exec (db, query, NULL, NULL, NULL);
if (err != SQLITE_OK && err != SQLITE_DONE && err != SQLITE_ROW)
dbthrow (db, query);
}
|