7 #ifndef HAVE_BOOST_REGEX
10 #include <boost/regex.hpp>
13 using boost::regex_match;
18 static regex e_syntax(
"near \".*\": syntax error");
19 static regex e_user_abort(
"callback requested query abort");
26 extern "C" int my_sqlite3_busy_handler(
void *,
int)
28 throw std::runtime_error(
"sqlite3 timeout");
31 extern "C" int callback(
void *arg,
int argc,
char **argv,
char **azColName)
36 for(i=0; i<argc; i++){
37 printf(
"%s = %s\n", azColName[i], argv[i] ? argv[i] :
"NULL");
43 extern "C" int table_callback(
void *arg,
int argc,
char **argv,
char **azColName)
45 (void) argc; (void) azColName;
46 auto tables = (vector<table> *)arg;
47 bool view = (string(
"view") == argv[0]);
48 table tab(argv[2],
"main", !view, !view);
49 tables->push_back(tab);
53 extern "C" int column_callback(
void *arg,
int argc,
char **argv,
char **azColName)
55 (void) argc; (void) azColName;
57 column c(argv[1], sqltype::get(argv[2]));
58 tab->columns().push_back(c);
62 sqlite_connection::sqlite_connection(std::string &conninfo)
64 assert(sqlite3_libversion_number()==SQLITE_VERSION_NUMBER);
65 assert(strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0);
66 assert(strcmp(sqlite3_libversion(),SQLITE_VERSION)==0);
67 rc = sqlite3_open_v2(conninfo.c_str(), &db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_URI, 0);
69 throw std::runtime_error(sqlite3_errmsg(db));
73 void sqlite_connection::q(
const char *query)
75 rc = sqlite3_exec(db, query, callback, 0, &zErrMsg);
77 auto e = std::runtime_error(zErrMsg);
78 sqlite3_free(zErrMsg);
83 sqlite_connection::~sqlite_connection()
89 schema_sqlite::schema_sqlite(std::string &conninfo,
bool no_catalog)
92 std::string query =
"SELECT * FROM main.sqlite_master where type in ('table', 'view')";
95 query+=
" AND name NOT like 'sqlite_%%'";
97 version =
"SQLite " SQLITE_VERSION
" " SQLITE_SOURCE_ID;
100 cerr <<
"Loading tables...";
102 rc = sqlite3_exec(db, query.c_str(), table_callback, (
void *)&tables, &zErrMsg);
104 auto e = std::runtime_error(zErrMsg);
105 sqlite3_free(zErrMsg);
112 table tab(
"sqlite_master",
"main",
false,
false);
113 tables.push_back(tab);
116 cerr <<
"done." << endl;
118 cerr <<
"Loading columns and constraints...";
120 for (
auto t = tables.begin(); t != tables.end(); ++t) {
121 string q(
"pragma table_info(");
125 rc = sqlite3_exec(db, q.c_str(), column_callback, (
void *)&*t, &zErrMsg);
127 auto e = std::runtime_error(zErrMsg);
128 sqlite3_free(zErrMsg);
133 cerr <<
"done." << endl;
135 #define BINOP(n,t) do {op o(#n,sqltype::get(#t),sqltype::get(#t),sqltype::get(#t)); register_operator(o); } while(0)
158 BINOP(IS NOT, INTEGER);
163 #define FUNC(n,r) do { \
164 routine proc("", "", sqltype::get(#r), #n); \
165 register_routine(proc); \
168 #define FUNC1(n,r,a) do { \
169 routine proc("", "", sqltype::get(#r), #n); \
170 proc.argtypes.push_back(sqltype::get(#a)); \
171 register_routine(proc); \
174 #define FUNC2(n,r,a,b) do { \
175 routine proc("", "", sqltype::get(#r), #n); \
176 proc.argtypes.push_back(sqltype::get(#a)); \
177 proc.argtypes.push_back(sqltype::get(#b)); \
178 register_routine(proc); \
181 #define FUNC3(n,r,a,b,c) do { \
182 routine proc("", "", sqltype::get(#r), #n); \
183 proc.argtypes.push_back(sqltype::get(#a)); \
184 proc.argtypes.push_back(sqltype::get(#b)); \
185 proc.argtypes.push_back(sqltype::get(#c)); \
186 register_routine(proc); \
189 FUNC(last_insert_rowid, INTEGER);
190 FUNC(random, INTEGER);
191 FUNC(sqlite_source_id, TEXT);
192 FUNC(sqlite_version, TEXT);
193 FUNC(total_changes, INTEGER);
195 FUNC1(abs, INTEGER, REAL);
196 FUNC1(hex, TEXT, TEXT);
197 FUNC1(length, INTEGER, TEXT);
198 FUNC1(lower, TEXT, TEXT);
199 FUNC1(ltrim, TEXT, TEXT);
200 FUNC1(quote, TEXT, TEXT);
201 FUNC1(randomblob, TEXT, INTEGER);
202 FUNC1(round, INTEGER, REAL);
203 FUNC1(rtrim, TEXT, TEXT);
204 FUNC1(soundex, TEXT, TEXT);
205 FUNC1(sqlite_compileoption_get, TEXT, INTEGER);
206 FUNC1(sqlite_compileoption_used, INTEGER, TEXT);
207 FUNC1(trim, TEXT, TEXT);
208 FUNC1(typeof, TEXT, INTEGER);
209 FUNC1(typeof, TEXT, NUMERIC);
210 FUNC1(typeof, TEXT, REAL);
211 FUNC1(typeof, TEXT, TEXT);
212 FUNC1(unicode, INTEGER, TEXT);
213 FUNC1(upper, TEXT, TEXT);
214 FUNC1(zeroblob, TEXT, INTEGER);
216 FUNC2(glob, INTEGER, TEXT, TEXT);
217 FUNC2(instr, INTEGER, TEXT, TEXT);
218 FUNC2(like, INTEGER, TEXT, TEXT);
219 FUNC2(ltrim, TEXT, TEXT, TEXT);
220 FUNC2(rtrim, TEXT, TEXT, TEXT);
221 FUNC2(trim, TEXT, TEXT, TEXT);
222 FUNC2(round, INTEGER, REAL, INTEGER);
223 FUNC2(substr, TEXT, TEXT, INTEGER);
225 FUNC3(substr, TEXT, TEXT, INTEGER, INTEGER);
226 FUNC3(replace, TEXT, TEXT, TEXT, TEXT);
229 #define AGG(n,r, a) do { \
230 routine proc("", "", sqltype::get(#r), #n); \
231 proc.argtypes.push_back(sqltype::get(#a)); \
232 register_aggregate(proc); \
235 AGG(avg, INTEGER, INTEGER);
236 AGG(avg, REAL, REAL);
237 AGG(count, INTEGER, REAL);
238 AGG(count, INTEGER, TEXT);
239 AGG(count, INTEGER, INTEGER);
240 AGG(group_concat, TEXT, TEXT);
241 AGG(max, REAL, REAL);
242 AGG(max, INTEGER, INTEGER);
243 AGG(sum, REAL, REAL);
244 AGG(sum, INTEGER, INTEGER);
245 AGG(total, REAL, INTEGER);
246 AGG(total, REAL, REAL);
248 booltype = sqltype::get(
"INTEGER");
249 inttype = sqltype::get(
"INTEGER");
251 internaltype = sqltype::get(
"internal");
252 arraytype = sqltype::get(
"ARRAY");
262 dut_sqlite::dut_sqlite(std::string &conninfo)
265 q(
"PRAGMA main.auto_vacuum = 2");
268 extern "C" int dut_callback(
void *arg,
int argc,
char **argv,
char **azColName)
270 (void) arg; (void) argc; (void) argv; (void) azColName;
274 void dut_sqlite::test(
const std::string &stmt)
277 rc = sqlite3_exec(db, stmt.c_str(), dut_callback, 0, &zErrMsg);
280 if (regex_match(zErrMsg, e_syntax))
282 else if (regex_match(zErrMsg, e_user_abort)) {
283 sqlite3_free(zErrMsg);
288 sqlite3_free(zErrMsg);
schema and dut classes for SQLite 3