This repository has been archived by the owner on Sep 13, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
sqlite_helper.h
136 lines (115 loc) · 3.58 KB
/
sqlite_helper.h
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#ifndef QGSVIRTUALLAYER_SQLITE_UTILS_H
#define QGSVIRTUALLAYER_SQLITE_UTILS_H
extern "C" {
#include <sqlite3.h>
}
#include <memory>
// custom deleter for QgsSqliteHandle
struct SqliteHandleDeleter
{
void operator()(sqlite3* handle) {
sqlite3_close(handle);
}
};
typedef std::unique_ptr<sqlite3, SqliteHandleDeleter> QgsScopedSqlite;
namespace Sqlite
{
static QgsScopedSqlite open( const QString& path )
{
QgsScopedSqlite sqlite;
int r;
sqlite3* db;
r = sqlite3_open( path.toLocal8Bit().constData(), &db );
if (r) {
throw std::runtime_error( sqlite3_errmsg(db) );
}
sqlite.reset(db);
return sqlite;
};
struct Query
{
Query( sqlite3* db, const QString& q ) : db_(db), nBind_(1)
{
QByteArray ba( q.toLocal8Bit() );
int r = sqlite3_prepare_v2( db, ba.constData(), ba.size(), &stmt_, NULL );
if (r) {
QString err = QString( "Query preparation error on %1" ).arg(q);
throw std::runtime_error( err.toLocal8Bit().constData() );
}
}
~Query()
{
sqlite3_finalize( stmt_ );
}
int step() { return sqlite3_step(stmt_); }
Query& bind( const QString& str, int idx )
{
QByteArray ba( str.toLocal8Bit() );
int r = sqlite3_bind_text( stmt_, idx, ba.constData(), ba.size(), SQLITE_TRANSIENT );
if (r) {
throw std::runtime_error( sqlite3_errmsg(db_) );
}
return *this;
}
Query& bind( const QString& str )
{
return bind( str, nBind_++ );
}
static void exec( sqlite3* db, const QString& sql )
{
char *errMsg = 0;
int r = sqlite3_exec( db, sql.toLocal8Bit().constData(), NULL, NULL, &errMsg );
if (r) {
QString err = QString( "Query execution error on %1: %2 - %3" ).arg(sql).arg(r).arg(errMsg);
throw std::runtime_error( err.toLocal8Bit().constData() );
}
}
void reset()
{
int r = sqlite3_reset( stmt_ );
if (r) {
throw std::runtime_error( sqlite3_errmsg(db_) );
}
nBind_ = 1;
}
int column_count() const
{
return sqlite3_column_count(stmt_);
}
QString column_name(int i) const
{
return QString( sqlite3_column_name(stmt_, i) );
}
int column_int( int i ) const
{
return sqlite3_column_int( stmt_, i );
}
qint64 column_int64( int i ) const
{
return sqlite3_column_int64( stmt_, i );
}
double column_double( int i ) const
{
return sqlite3_column_double( stmt_, i );
}
QString column_text( int i ) const
{
int size = sqlite3_column_bytes( stmt_, i );
const char* str = (const char*)sqlite3_column_text( stmt_, i );
return QString::fromUtf8( str, size );
}
QByteArray column_blob( int i ) const
{
int size = sqlite3_column_bytes( stmt_, i );
const char* data = (const char*)sqlite3_column_blob( stmt_, i );
// data is not copied. QByteArray is just here a augmented pointer
return QByteArray::fromRawData( data, size );
}
sqlite3_stmt* stmt() { return stmt_; }
private:
sqlite3* db_;
sqlite3_stmt* stmt_;
int nBind_;
};
}
#endif