dbd/sqlite3/statement.c

1
#include "dbd_sqlite3.h"
2
 
3
extern int try_begin_transaction(connection_t *conn);
4
extern int try_end_transaction(connection_t *conn);
5
 
6
/*
7
 * Converts SQLite types to Lua types
8
 */
9
static lua_push_type_t sqlite_to_lua_push(unsigned int sqlite_type) {
10
    lua_push_type_t lua_type;
11
 
12
    switch(sqlite_type) {
13
    case SQLITE_NULL:
14
        lua_type = LUA_PUSH_NIL;
15
        break;
16
 
17
    case SQLITE_INTEGER:
18
        lua_type =  LUA_PUSH_INTEGER;
19
        break;
20
 
21
    case SQLITE_FLOAT:
22
        lua_type = LUA_PUSH_NUMBER;
23
        break;
24
 
25
    default:
26
        lua_type = LUA_PUSH_STRING;
27
    }
28
 
29
    return lua_type;
30
}
31
 
32
/*
33
 * runs sqlite3_step on a statement handle
34
 */
35
static int step(statement_t *statement) {
36
    int res = sqlite3_step(statement->stmt);
37
 
38
    if (res == SQLITE_DONE) {
39
	statement->more_data = 0;
40
	return 1;
41
    } else if (res == SQLITE_ROW) {
42
	statement->more_data = 1;
43
	return 1;
44
    }
45
 
46
    return 0;
47
}
48
 
49
/*
50
 * num_affected_rows = statement:affected()
51
 */
52
static int statement_affected(lua_State *L) {
53
    statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_SQLITE_STATEMENT);
54
 
55
    if (!statement->stmt) {
56
        luaL_error(L, DBI_ERR_INVALID_STATEMENT);
57
    }
58
 
59
    lua_pushinteger(L, statement->affected);
60
 
61
    return 1;   
62
}
63
 
64
/*
65
 * success = statement:close()
66
 */
67
static int statement_close(lua_State *L) {
68
    statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_SQLITE_STATEMENT);
69
    int ok = 0;
70
 
71
    if (statement->stmt) {
72
	if (sqlite3_finalize(statement->stmt) == SQLITE_OK) {
73
	    ok = 1;
74
	}
75
 
76
	statement->stmt = NULL;
77
    }
78
 
79
    lua_pushboolean(L, ok);
80
    return 1;
81
}
82
 
83
/*
84
 * column_names = statement:columns()
85
 */
86
static int statement_columns(lua_State *L) {
87
    statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_SQLITE_STATEMENT);
88
 
89
    int i;
90
    int num_columns;
91
    int d = 1;
92
 
93
    if (!statement->stmt) {
94
        luaL_error(L, DBI_ERR_INVALID_STATEMENT);
95
        return 0;
96
    }
97
 
98
    num_columns = sqlite3_column_count(statement->stmt);
99
    lua_newtable(L);
100
    for (i = 0; i < num_columns; i++) {
101
        const char *name = sqlite3_column_name(statement->stmt, i);
102
 
103
        LUA_PUSH_ARRAY_STRING(d, name);
104
    }
105
 
106
    return 1;
107
}
108
 
109
/*
110
 * success,err = statement:execute(...)
111
 */
112
static int statement_execute(lua_State *L) {
113
    int n = lua_gettop(L);
114
    statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_SQLITE_STATEMENT);
115
    int p;
116
    int errflag = 0;
117
    const char *errstr = NULL;
118
    int expected_params;
119
    int num_bind_params = n - 1;
120
 
121
    if (!statement->stmt) {
122
	lua_pushboolean(L, 0);
123
	lua_pushstring(L, DBI_ERR_EXECUTE_INVALID);
124
	return 2;
125
    }
126
 
127
    /*
128
     * reset the handle before binding params
129
     * this will be a NOP if the handle has not
130
     * been executed
131
     */
132
    if (sqlite3_reset(statement->stmt) != SQLITE_OK) {
133
	lua_pushboolean(L, 0);
134
	lua_pushfstring(L, DBI_ERR_EXECUTE_FAILED, sqlite3_errmsg(statement->conn->sqlite));
135
	return 2;
136
    }
137
 
138
    sqlite3_clear_bindings(statement->stmt);
139
 
140
    expected_params = sqlite3_bind_parameter_count(statement->stmt);
141
    if (expected_params != num_bind_params) {
142
	/*
143
         * sqlite3_reset does not handle this condition,
144
         * and the client library will fill unset params
145
         * with NULLs
146
         */ 
147
	lua_pushboolean(L, 0);
148
	lua_pushfstring(L, DBI_ERR_PARAM_MISCOUNT, expected_params, num_bind_params); 
149
	return 2;
150
    }
151
 
152
    for (p = 2; p <= n; p++) {
153
	int i = p - 1;
154
	int type = lua_type(L, p);
155
	char err[64];
156
 
157
	switch(type) {
158
	case LUA_TNIL:
159
	    errflag = sqlite3_bind_null(statement->stmt, i) != SQLITE_OK;
160
	    break;
161
	case LUA_TNUMBER:
162
	    errflag = sqlite3_bind_double(statement->stmt, i, lua_tonumber(L, p)) != SQLITE_OK;
163
	    break;
164
	case LUA_TSTRING:
165
	    errflag = sqlite3_bind_text(statement->stmt, i, lua_tostring(L, p), -1, SQLITE_STATIC) != SQLITE_OK;
166
	    break;
167
	case LUA_TBOOLEAN:
168
	    errflag = sqlite3_bind_int(statement->stmt, i, lua_toboolean(L, p)) != SQLITE_OK;
169
	    break;
170
	default:
171
	    /*
172
	     * Unknown/unsupported value type
173
	     */
174
	    errflag = 1;
175
            snprintf(err, sizeof(err)-1, DBI_ERR_BINDING_TYPE_ERR, lua_typename(L, type));
176
            errstr = err;
177
	}
178
 
179
	if (errflag)
180
	    break;
181
    }   
182
 
183
    if (errflag) {
184
	lua_pushboolean(L, 0);
185
	if (errstr)
186
	    lua_pushfstring(L, DBI_ERR_BINDING_PARAMS, errstr);
187
	else
188
	    lua_pushfstring(L, DBI_ERR_BINDING_PARAMS, sqlite3_errmsg(statement->conn->sqlite));
189
    
190
	return 2;
191
    }
192
    
193
    try_begin_transaction(statement->conn);
194
 
195
    if (!step(statement)) {
196
	lua_pushboolean(L, 0);
197
	lua_pushfstring(L, DBI_ERR_EXECUTE_FAILED, sqlite3_errmsg(statement->conn->sqlite));
198
	return 2;
199
    }
200
 
201
    statement->affected = sqlite3_changes(statement->conn->sqlite);
202
 
203
    lua_pushboolean(L, 1);
204
    return 1;
205
}
206
 
207
/*
208
 * must be called after an execute
209
 */
210
static int statement_fetch_impl(lua_State *L, statement_t *statement, int named_columns) {
211
    int num_columns;
212
 
213
    if (!statement->stmt) {
214
	luaL_error(L, DBI_ERR_FETCH_INVALID);
215
	return 0;
216
    }
217
 
218
    if (!statement->more_data) {
219
	/* 
220
         * Result set is empty, or not result set returned
221
         */
222
  
223
	lua_pushnil(L);
224
	return 1;
225
    }
226
 
227
    num_columns = sqlite3_column_count(statement->stmt);
228
 
229
    if (num_columns) {
230
	int i;
231
	int d = 1;
232
 
233
	lua_newtable(L);
234
 
235
	for (i = 0; i < num_columns; i++) {
236
	    lua_push_type_t lua_push = sqlite_to_lua_push(sqlite3_column_type(statement->stmt, i));
237
	    const char *name = sqlite3_column_name(statement->stmt, i);
238
 
239
	    if (lua_push == LUA_PUSH_NIL) {
240
                if (named_columns) {
241
                    LUA_PUSH_ATTRIB_NIL(name);
242
                } else {
243
                    LUA_PUSH_ARRAY_NIL(d);
244
                }
245
            } else if (lua_push == LUA_PUSH_INTEGER) {
246
		int val = sqlite3_column_int(statement->stmt, i);
247
 
248
                if (named_columns) {
249
                    LUA_PUSH_ATTRIB_INT(name, val);
250
                } else {
251
                    LUA_PUSH_ARRAY_INT(d, val);
252
                }
253
            } else if (lua_push == LUA_PUSH_NUMBER) {
254
		double val = sqlite3_column_double(statement->stmt, i);
255
 
256
                if (named_columns) {
257
                    LUA_PUSH_ATTRIB_FLOAT(name, val);
258
                } else {
259
                    LUA_PUSH_ARRAY_FLOAT(d, val);
260
                }
261
            } else if (lua_push == LUA_PUSH_STRING) {
262
		const char *val = (const char *)sqlite3_column_text(statement->stmt, i);
263
 
264
                if (named_columns) {
265
                    LUA_PUSH_ATTRIB_STRING(name, val);
266
                } else {
267
                    LUA_PUSH_ARRAY_STRING(d, val);
268
                }
269
            } else if (lua_push == LUA_PUSH_BOOLEAN) {
270
		int val = sqlite3_column_int(statement->stmt, i);
271
 
272
                if (named_columns) {
273
                    LUA_PUSH_ATTRIB_BOOL(name, val);
274
                } else {
275
                    LUA_PUSH_ARRAY_BOOL(d, val);
276
                }
277
            } else {
278
                luaL_error(L, DBI_ERR_UNKNOWN_PUSH);
279
            }
280
	}
281
    } else {
282
	/* 
283
         * no columns returned by statement?
284
         */ 
285
	lua_pushnil(L);
286
    }
287
 
288
    if (step(statement) == 0) {
289
	if (sqlite3_reset(statement->stmt) != SQLITE_OK) {
290
	    /* 
291
	     * reset needs to be called to retrieve the 'real' error message
292
	     */
293
	    luaL_error(L, DBI_ERR_FETCH_FAILED, sqlite3_errmsg(statement->conn->sqlite));
294
	}
295
    }
296
 
297
    return 1;    
298
}
299
 
300
static int next_iterator(lua_State *L) {
301
    statement_t *statement = (statement_t *)luaL_checkudata(L, lua_upvalueindex(1), DBD_SQLITE_STATEMENT);
302
    int named_columns = lua_toboolean(L, lua_upvalueindex(2));
303
 
304
    return statement_fetch_impl(L, statement, named_columns);
305
}
306
 
307
/*
308
 * table = statement:fetch(named_indexes)
309
 */
310
static int statement_fetch(lua_State *L) {
311
    statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_SQLITE_STATEMENT);
312
    int named_columns = lua_toboolean(L, 2);
313
 
314
    return statement_fetch_impl(L, statement, named_columns);
315
}
316
 
317
/*
318
 * iterfunc = statement:rows(named_indexes)
319
 */
320
static int statement_rows(lua_State *L) {
321
    if (lua_gettop(L) == 1) {
322
        lua_pushvalue(L, 1);
323
        lua_pushboolean(L, 0);
324
    } else {
325
        lua_pushvalue(L, 1);
326
        lua_pushboolean(L, lua_toboolean(L, 2));
327
    }
328
 
329
    lua_pushcclosure(L, next_iterator, 2);
330
    return 1;
331
}
332
 
333
/*
334
 * num_rows = statement:rowcount()
335
 */
336
static int statement_rowcount(lua_State *L) {
337
    luaL_error(L, DBI_ERR_NOT_IMPLEMENTED, DBD_SQLITE_STATEMENT, "rowcount");
338
 
339
    return 0;
340
}
341
 
342
/*
343
 * __gc
344
 */
345
static int statement_gc(lua_State *L) {
346
    /* always free the handle */
347
    statement_close(L);
348
 
349
    return 0;
350
}
351
 
352
/*
353
 * __tostring
354
 */
355
static int statement_tostring(lua_State *L) {
356
    statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_SQLITE_STATEMENT);
357
 
358
    lua_pushfstring(L, "%s: %p", DBD_SQLITE_STATEMENT, statement);
359
 
360
    return 1;
361
}
362
 
363
int dbd_sqlite3_statement_create(lua_State *L, connection_t *conn, const char *sql_query) { 
364
    statement_t *statement = NULL;
365
 
366
    statement = (statement_t *)lua_newuserdata(L, sizeof(statement_t));
367
    statement->conn = conn;
368
    statement->stmt = NULL;
369
    statement->more_data = 0;
370
    statement->affected = 0;
371
 
372
    if (sqlite3_prepare_v2(statement->conn->sqlite, sql_query, strlen(sql_query), &statement->stmt, NULL) != SQLITE_OK) {
373
	lua_pushnil(L);
374
	lua_pushfstring(L, DBI_ERR_PREP_STATEMENT, sqlite3_errmsg(statement->conn->sqlite));	
375
	return 2;
376
    } 
377
 
378
    luaL_getmetatable(L, DBD_SQLITE_STATEMENT);
379
    lua_setmetatable(L, -2);
380
    return 1;
381
} 
382
 
383
int dbd_sqlite3_statement(lua_State *L) {
384
    static const luaL_Reg statement_methods[] = {
385
	{"affected", statement_affected},
386
	{"close", statement_close},
387
	{"columns", statement_columns},
388
	{"execute", statement_execute},
389
	{"fetch", statement_fetch},
390
	{"rows", statement_rows},
391
	{"rowcount", statement_rowcount},
392
	{NULL, NULL}
393
    };
394
 
395
    static const luaL_Reg statement_class_methods[] = {
396
	{NULL, NULL}
397
    };
398
 
399
    luaL_newmetatable(L, DBD_SQLITE_STATEMENT);
400
    luaL_register(L, 0, statement_methods);
401
    lua_pushvalue(L,-1);
402
    lua_setfield(L, -2, "__index");
403
 
404
    lua_pushcfunction(L, statement_gc);
405
    lua_setfield(L, -2, "__gc");
406
 
407
    lua_pushcfunction(L, statement_tostring);
408
    lua_setfield(L, -2, "__tostring");
409
 
410
    luaL_register(L, DBD_SQLITE_STATEMENT, statement_class_methods);
411
 
412
    return 1;    
413
}