sqlite3 1.5.0-arm-linux
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sqlite3 might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/.gemtest +0 -0
- data/API_CHANGES.md +49 -0
- data/CHANGELOG.md +425 -0
- data/CONTRIBUTING.md +24 -0
- data/ChangeLog.cvs +88 -0
- data/Gemfile +3 -0
- data/LICENSE +27 -0
- data/LICENSE-DEPENDENCIES +20 -0
- data/README.md +233 -0
- data/ext/sqlite3/aggregator.c +274 -0
- data/ext/sqlite3/aggregator.h +12 -0
- data/ext/sqlite3/backup.c +168 -0
- data/ext/sqlite3/backup.h +15 -0
- data/ext/sqlite3/database.c +853 -0
- data/ext/sqlite3/database.h +17 -0
- data/ext/sqlite3/exception.c +98 -0
- data/ext/sqlite3/exception.h +8 -0
- data/ext/sqlite3/extconf.rb +252 -0
- data/ext/sqlite3/sqlite3.c +163 -0
- data/ext/sqlite3/sqlite3_ruby.h +48 -0
- data/ext/sqlite3/statement.c +442 -0
- data/ext/sqlite3/statement.h +16 -0
- data/faq/faq.md +431 -0
- data/faq/faq.rb +145 -0
- data/faq/faq.yml +426 -0
- data/lib/sqlite3/2.6/sqlite3_native.so +0 -0
- data/lib/sqlite3/2.7/sqlite3_native.so +0 -0
- data/lib/sqlite3/3.0/sqlite3_native.so +0 -0
- data/lib/sqlite3/3.1/sqlite3_native.so +0 -0
- data/lib/sqlite3/constants.rb +50 -0
- data/lib/sqlite3/database.rb +741 -0
- data/lib/sqlite3/errors.rb +35 -0
- data/lib/sqlite3/pragmas.rb +595 -0
- data/lib/sqlite3/resultset.rb +187 -0
- data/lib/sqlite3/statement.rb +145 -0
- data/lib/sqlite3/translator.rb +118 -0
- data/lib/sqlite3/value.rb +57 -0
- data/lib/sqlite3/version.rb +23 -0
- data/lib/sqlite3.rb +15 -0
- data/test/helper.rb +27 -0
- data/test/test_backup.rb +33 -0
- data/test/test_collation.rb +82 -0
- data/test/test_database.rb +545 -0
- data/test/test_database_flags.rb +95 -0
- data/test/test_database_readonly.rb +36 -0
- data/test/test_database_readwrite.rb +41 -0
- data/test/test_deprecated.rb +44 -0
- data/test/test_encoding.rb +155 -0
- data/test/test_integration.rb +507 -0
- data/test/test_integration_aggregate.rb +336 -0
- data/test/test_integration_open_close.rb +30 -0
- data/test/test_integration_pending.rb +115 -0
- data/test/test_integration_resultset.rb +142 -0
- data/test/test_integration_statement.rb +194 -0
- data/test/test_result_set.rb +37 -0
- data/test/test_sqlite3.rb +30 -0
- data/test/test_statement.rb +263 -0
- data/test/test_statement_execute.rb +35 -0
- metadata +190 -0
@@ -0,0 +1,442 @@
|
|
1
|
+
#include <sqlite3_ruby.h>
|
2
|
+
|
3
|
+
#define REQUIRE_OPEN_STMT(_ctxt) \
|
4
|
+
if(!_ctxt->st) \
|
5
|
+
rb_raise(rb_path2class("SQLite3::Exception"), "cannot use a closed statement");
|
6
|
+
|
7
|
+
VALUE cSqlite3Statement;
|
8
|
+
|
9
|
+
static void deallocate(void * ctx)
|
10
|
+
{
|
11
|
+
sqlite3StmtRubyPtr c = (sqlite3StmtRubyPtr)ctx;
|
12
|
+
xfree(c);
|
13
|
+
}
|
14
|
+
|
15
|
+
static VALUE allocate(VALUE klass)
|
16
|
+
{
|
17
|
+
sqlite3StmtRubyPtr ctx = xcalloc((size_t)1, sizeof(sqlite3StmtRuby));
|
18
|
+
ctx->st = NULL;
|
19
|
+
ctx->done_p = 0;
|
20
|
+
|
21
|
+
return Data_Wrap_Struct(klass, NULL, deallocate, ctx);
|
22
|
+
}
|
23
|
+
|
24
|
+
/* call-seq: SQLite3::Statement.new(db, sql)
|
25
|
+
*
|
26
|
+
* Create a new statement attached to the given Database instance, and which
|
27
|
+
* encapsulates the given SQL text. If the text contains more than one
|
28
|
+
* statement (i.e., separated by semicolons), then the #remainder property
|
29
|
+
* will be set to the trailing text.
|
30
|
+
*/
|
31
|
+
static VALUE initialize(VALUE self, VALUE db, VALUE sql)
|
32
|
+
{
|
33
|
+
sqlite3RubyPtr db_ctx;
|
34
|
+
sqlite3StmtRubyPtr ctx;
|
35
|
+
const char *tail = NULL;
|
36
|
+
int status;
|
37
|
+
|
38
|
+
StringValue(sql);
|
39
|
+
|
40
|
+
Data_Get_Struct(db, sqlite3Ruby, db_ctx);
|
41
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
42
|
+
|
43
|
+
if(!db_ctx->db)
|
44
|
+
rb_raise(rb_eArgError, "prepare called on a closed database");
|
45
|
+
|
46
|
+
if(!UTF8_P(sql)) {
|
47
|
+
sql = rb_str_export_to_enc(sql, rb_utf8_encoding());
|
48
|
+
}
|
49
|
+
|
50
|
+
#ifdef HAVE_SQLITE3_PREPARE_V2
|
51
|
+
status = sqlite3_prepare_v2(
|
52
|
+
#else
|
53
|
+
status = sqlite3_prepare(
|
54
|
+
#endif
|
55
|
+
db_ctx->db,
|
56
|
+
(const char *)StringValuePtr(sql),
|
57
|
+
(int)RSTRING_LEN(sql),
|
58
|
+
&ctx->st,
|
59
|
+
&tail
|
60
|
+
);
|
61
|
+
|
62
|
+
CHECK(db_ctx->db, status);
|
63
|
+
|
64
|
+
rb_iv_set(self, "@connection", db);
|
65
|
+
rb_iv_set(self, "@remainder", rb_str_new2(tail));
|
66
|
+
rb_iv_set(self, "@columns", Qnil);
|
67
|
+
rb_iv_set(self, "@types", Qnil);
|
68
|
+
|
69
|
+
return self;
|
70
|
+
}
|
71
|
+
|
72
|
+
/* call-seq: stmt.close
|
73
|
+
*
|
74
|
+
* Closes the statement by finalizing the underlying statement
|
75
|
+
* handle. The statement must not be used after being closed.
|
76
|
+
*/
|
77
|
+
static VALUE sqlite3_rb_close(VALUE self)
|
78
|
+
{
|
79
|
+
sqlite3StmtRubyPtr ctx;
|
80
|
+
|
81
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
82
|
+
|
83
|
+
REQUIRE_OPEN_STMT(ctx);
|
84
|
+
|
85
|
+
sqlite3_finalize(ctx->st);
|
86
|
+
ctx->st = NULL;
|
87
|
+
|
88
|
+
return self;
|
89
|
+
}
|
90
|
+
|
91
|
+
/* call-seq: stmt.closed?
|
92
|
+
*
|
93
|
+
* Returns true if the statement has been closed.
|
94
|
+
*/
|
95
|
+
static VALUE closed_p(VALUE self)
|
96
|
+
{
|
97
|
+
sqlite3StmtRubyPtr ctx;
|
98
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
99
|
+
|
100
|
+
if(!ctx->st) return Qtrue;
|
101
|
+
|
102
|
+
return Qfalse;
|
103
|
+
}
|
104
|
+
|
105
|
+
static VALUE step(VALUE self)
|
106
|
+
{
|
107
|
+
sqlite3StmtRubyPtr ctx;
|
108
|
+
sqlite3_stmt *stmt;
|
109
|
+
int value, length;
|
110
|
+
VALUE list;
|
111
|
+
rb_encoding * internal_encoding;
|
112
|
+
|
113
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
114
|
+
|
115
|
+
REQUIRE_OPEN_STMT(ctx);
|
116
|
+
|
117
|
+
if(ctx->done_p) return Qnil;
|
118
|
+
|
119
|
+
{
|
120
|
+
VALUE db = rb_iv_get(self, "@connection");
|
121
|
+
rb_funcall(db, rb_intern("encoding"), 0);
|
122
|
+
internal_encoding = rb_default_internal_encoding();
|
123
|
+
}
|
124
|
+
|
125
|
+
stmt = ctx->st;
|
126
|
+
|
127
|
+
value = sqlite3_step(stmt);
|
128
|
+
if (rb_errinfo() != Qnil) {
|
129
|
+
/* some user defined function was invoked as a callback during step and
|
130
|
+
* it raised an exception that has been suppressed until step returns.
|
131
|
+
* Now re-raise it. */
|
132
|
+
VALUE exception = rb_errinfo();
|
133
|
+
rb_set_errinfo(Qnil);
|
134
|
+
rb_exc_raise(exception);
|
135
|
+
}
|
136
|
+
|
137
|
+
length = sqlite3_column_count(stmt);
|
138
|
+
list = rb_ary_new2((long)length);
|
139
|
+
|
140
|
+
switch(value) {
|
141
|
+
case SQLITE_ROW:
|
142
|
+
{
|
143
|
+
int i;
|
144
|
+
for(i = 0; i < length; i++) {
|
145
|
+
switch(sqlite3_column_type(stmt, i)) {
|
146
|
+
case SQLITE_INTEGER:
|
147
|
+
rb_ary_push(list, LL2NUM(sqlite3_column_int64(stmt, i)));
|
148
|
+
break;
|
149
|
+
case SQLITE_FLOAT:
|
150
|
+
rb_ary_push(list, rb_float_new(sqlite3_column_double(stmt, i)));
|
151
|
+
break;
|
152
|
+
case SQLITE_TEXT:
|
153
|
+
{
|
154
|
+
VALUE str = rb_str_new(
|
155
|
+
(const char *)sqlite3_column_text(stmt, i),
|
156
|
+
(long)sqlite3_column_bytes(stmt, i)
|
157
|
+
);
|
158
|
+
rb_enc_associate_index(str, rb_utf8_encindex());
|
159
|
+
if(internal_encoding)
|
160
|
+
str = rb_str_export_to_enc(str, internal_encoding);
|
161
|
+
rb_ary_push(list, str);
|
162
|
+
}
|
163
|
+
break;
|
164
|
+
case SQLITE_BLOB:
|
165
|
+
{
|
166
|
+
VALUE str = rb_str_new(
|
167
|
+
(const char *)sqlite3_column_blob(stmt, i),
|
168
|
+
(long)sqlite3_column_bytes(stmt, i)
|
169
|
+
);
|
170
|
+
rb_ary_push(list, str);
|
171
|
+
}
|
172
|
+
break;
|
173
|
+
case SQLITE_NULL:
|
174
|
+
rb_ary_push(list, Qnil);
|
175
|
+
break;
|
176
|
+
default:
|
177
|
+
rb_raise(rb_eRuntimeError, "bad type");
|
178
|
+
}
|
179
|
+
}
|
180
|
+
}
|
181
|
+
break;
|
182
|
+
case SQLITE_DONE:
|
183
|
+
ctx->done_p = 1;
|
184
|
+
return Qnil;
|
185
|
+
break;
|
186
|
+
default:
|
187
|
+
sqlite3_reset(stmt);
|
188
|
+
ctx->done_p = 0;
|
189
|
+
CHECK(sqlite3_db_handle(ctx->st), value);
|
190
|
+
}
|
191
|
+
|
192
|
+
return list;
|
193
|
+
}
|
194
|
+
|
195
|
+
/* call-seq: stmt.bind_param(key, value)
|
196
|
+
*
|
197
|
+
* Binds value to the named (or positional) placeholder. If +param+ is a
|
198
|
+
* Fixnum, it is treated as an index for a positional placeholder.
|
199
|
+
* Otherwise it is used as the name of the placeholder to bind to.
|
200
|
+
*
|
201
|
+
* See also #bind_params.
|
202
|
+
*/
|
203
|
+
static VALUE bind_param(VALUE self, VALUE key, VALUE value)
|
204
|
+
{
|
205
|
+
sqlite3StmtRubyPtr ctx;
|
206
|
+
int status;
|
207
|
+
int index;
|
208
|
+
|
209
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
210
|
+
REQUIRE_OPEN_STMT(ctx);
|
211
|
+
|
212
|
+
switch(TYPE(key)) {
|
213
|
+
case T_SYMBOL:
|
214
|
+
key = rb_funcall(key, rb_intern("to_s"), 0);
|
215
|
+
case T_STRING:
|
216
|
+
if(RSTRING_PTR(key)[0] != ':') key = rb_str_plus(rb_str_new2(":"), key);
|
217
|
+
index = sqlite3_bind_parameter_index(ctx->st, StringValuePtr(key));
|
218
|
+
break;
|
219
|
+
default:
|
220
|
+
index = (int)NUM2INT(key);
|
221
|
+
}
|
222
|
+
|
223
|
+
if(index == 0)
|
224
|
+
rb_raise(rb_path2class("SQLite3::Exception"), "no such bind parameter");
|
225
|
+
|
226
|
+
switch(TYPE(value)) {
|
227
|
+
case T_STRING:
|
228
|
+
if(CLASS_OF(value) == cSqlite3Blob
|
229
|
+
|| rb_enc_get_index(value) == rb_ascii8bit_encindex()
|
230
|
+
) {
|
231
|
+
status = sqlite3_bind_blob(
|
232
|
+
ctx->st,
|
233
|
+
index,
|
234
|
+
(const char *)StringValuePtr(value),
|
235
|
+
(int)RSTRING_LEN(value),
|
236
|
+
SQLITE_TRANSIENT
|
237
|
+
);
|
238
|
+
} else {
|
239
|
+
|
240
|
+
|
241
|
+
if (UTF16_LE_P(value) || UTF16_BE_P(value)) {
|
242
|
+
status = sqlite3_bind_text16(
|
243
|
+
ctx->st,
|
244
|
+
index,
|
245
|
+
(const char *)StringValuePtr(value),
|
246
|
+
(int)RSTRING_LEN(value),
|
247
|
+
SQLITE_TRANSIENT
|
248
|
+
);
|
249
|
+
} else {
|
250
|
+
if (!UTF8_P(value) || !USASCII_P(value)) {
|
251
|
+
value = rb_str_encode(value, rb_enc_from_encoding(rb_utf8_encoding()), 0, Qnil);
|
252
|
+
}
|
253
|
+
status = sqlite3_bind_text(
|
254
|
+
ctx->st,
|
255
|
+
index,
|
256
|
+
(const char *)StringValuePtr(value),
|
257
|
+
(int)RSTRING_LEN(value),
|
258
|
+
SQLITE_TRANSIENT
|
259
|
+
);
|
260
|
+
}
|
261
|
+
}
|
262
|
+
break;
|
263
|
+
case T_BIGNUM: {
|
264
|
+
sqlite3_int64 num64;
|
265
|
+
if (bignum_to_int64(value, &num64)) {
|
266
|
+
status = sqlite3_bind_int64(ctx->st, index, num64);
|
267
|
+
break;
|
268
|
+
}
|
269
|
+
}
|
270
|
+
case T_FLOAT:
|
271
|
+
status = sqlite3_bind_double(ctx->st, index, NUM2DBL(value));
|
272
|
+
break;
|
273
|
+
case T_FIXNUM:
|
274
|
+
status = sqlite3_bind_int64(ctx->st, index, (sqlite3_int64)FIX2LONG(value));
|
275
|
+
break;
|
276
|
+
case T_NIL:
|
277
|
+
status = sqlite3_bind_null(ctx->st, index);
|
278
|
+
break;
|
279
|
+
default:
|
280
|
+
rb_raise(rb_eRuntimeError, "can't prepare %s",
|
281
|
+
rb_class2name(CLASS_OF(value)));
|
282
|
+
break;
|
283
|
+
}
|
284
|
+
|
285
|
+
CHECK(sqlite3_db_handle(ctx->st), status);
|
286
|
+
|
287
|
+
return self;
|
288
|
+
}
|
289
|
+
|
290
|
+
/* call-seq: stmt.reset!
|
291
|
+
*
|
292
|
+
* Resets the statement. This is typically done internally, though it might
|
293
|
+
* occasionally be necessary to manually reset the statement.
|
294
|
+
*/
|
295
|
+
static VALUE reset_bang(VALUE self)
|
296
|
+
{
|
297
|
+
sqlite3StmtRubyPtr ctx;
|
298
|
+
|
299
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
300
|
+
REQUIRE_OPEN_STMT(ctx);
|
301
|
+
|
302
|
+
sqlite3_reset(ctx->st);
|
303
|
+
|
304
|
+
ctx->done_p = 0;
|
305
|
+
|
306
|
+
return self;
|
307
|
+
}
|
308
|
+
|
309
|
+
/* call-seq: stmt.clear_bindings!
|
310
|
+
*
|
311
|
+
* Resets the statement. This is typically done internally, though it might
|
312
|
+
* occasionally be necessary to manually reset the statement.
|
313
|
+
*/
|
314
|
+
static VALUE clear_bindings_bang(VALUE self)
|
315
|
+
{
|
316
|
+
sqlite3StmtRubyPtr ctx;
|
317
|
+
|
318
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
319
|
+
REQUIRE_OPEN_STMT(ctx);
|
320
|
+
|
321
|
+
sqlite3_clear_bindings(ctx->st);
|
322
|
+
|
323
|
+
ctx->done_p = 0;
|
324
|
+
|
325
|
+
return self;
|
326
|
+
}
|
327
|
+
|
328
|
+
/* call-seq: stmt.done?
|
329
|
+
*
|
330
|
+
* returns true if all rows have been returned.
|
331
|
+
*/
|
332
|
+
static VALUE done_p(VALUE self)
|
333
|
+
{
|
334
|
+
sqlite3StmtRubyPtr ctx;
|
335
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
336
|
+
|
337
|
+
if(ctx->done_p) return Qtrue;
|
338
|
+
return Qfalse;
|
339
|
+
}
|
340
|
+
|
341
|
+
/* call-seq: stmt.column_count
|
342
|
+
*
|
343
|
+
* Returns the number of columns to be returned for this statement
|
344
|
+
*/
|
345
|
+
static VALUE column_count(VALUE self)
|
346
|
+
{
|
347
|
+
sqlite3StmtRubyPtr ctx;
|
348
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
349
|
+
REQUIRE_OPEN_STMT(ctx);
|
350
|
+
|
351
|
+
return INT2NUM((long)sqlite3_column_count(ctx->st));
|
352
|
+
}
|
353
|
+
|
354
|
+
/* call-seq: stmt.column_name(index)
|
355
|
+
*
|
356
|
+
* Get the column name at +index+. 0 based.
|
357
|
+
*/
|
358
|
+
static VALUE column_name(VALUE self, VALUE index)
|
359
|
+
{
|
360
|
+
sqlite3StmtRubyPtr ctx;
|
361
|
+
const char * name;
|
362
|
+
|
363
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
364
|
+
REQUIRE_OPEN_STMT(ctx);
|
365
|
+
|
366
|
+
name = sqlite3_column_name(ctx->st, (int)NUM2INT(index));
|
367
|
+
|
368
|
+
if(name) return SQLITE3_UTF8_STR_NEW2(name);
|
369
|
+
return Qnil;
|
370
|
+
}
|
371
|
+
|
372
|
+
/* call-seq: stmt.column_decltype(index)
|
373
|
+
*
|
374
|
+
* Get the column type at +index+. 0 based.
|
375
|
+
*/
|
376
|
+
static VALUE column_decltype(VALUE self, VALUE index)
|
377
|
+
{
|
378
|
+
sqlite3StmtRubyPtr ctx;
|
379
|
+
const char * name;
|
380
|
+
|
381
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
382
|
+
REQUIRE_OPEN_STMT(ctx);
|
383
|
+
|
384
|
+
name = sqlite3_column_decltype(ctx->st, (int)NUM2INT(index));
|
385
|
+
|
386
|
+
if(name) return rb_str_new2(name);
|
387
|
+
return Qnil;
|
388
|
+
}
|
389
|
+
|
390
|
+
/* call-seq: stmt.bind_parameter_count
|
391
|
+
*
|
392
|
+
* Return the number of bind parameters
|
393
|
+
*/
|
394
|
+
static VALUE bind_parameter_count(VALUE self)
|
395
|
+
{
|
396
|
+
sqlite3StmtRubyPtr ctx;
|
397
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
398
|
+
REQUIRE_OPEN_STMT(ctx);
|
399
|
+
|
400
|
+
return INT2NUM((long)sqlite3_bind_parameter_count(ctx->st));
|
401
|
+
}
|
402
|
+
|
403
|
+
#ifdef HAVE_SQLITE3_COLUMN_DATABASE_NAME
|
404
|
+
|
405
|
+
/* call-seq: stmt.database_name(column_index)
|
406
|
+
*
|
407
|
+
* Return the database name for the column at +column_index+
|
408
|
+
*/
|
409
|
+
static VALUE database_name(VALUE self, VALUE index)
|
410
|
+
{
|
411
|
+
sqlite3StmtRubyPtr ctx;
|
412
|
+
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
|
413
|
+
REQUIRE_OPEN_STMT(ctx);
|
414
|
+
|
415
|
+
return SQLITE3_UTF8_STR_NEW2(
|
416
|
+
sqlite3_column_database_name(ctx->st, NUM2INT(index)));
|
417
|
+
}
|
418
|
+
|
419
|
+
#endif
|
420
|
+
|
421
|
+
void init_sqlite3_statement()
|
422
|
+
{
|
423
|
+
cSqlite3Statement = rb_define_class_under(mSqlite3, "Statement", rb_cObject);
|
424
|
+
|
425
|
+
rb_define_alloc_func(cSqlite3Statement, allocate);
|
426
|
+
rb_define_method(cSqlite3Statement, "initialize", initialize, 2);
|
427
|
+
rb_define_method(cSqlite3Statement, "close", sqlite3_rb_close, 0);
|
428
|
+
rb_define_method(cSqlite3Statement, "closed?", closed_p, 0);
|
429
|
+
rb_define_method(cSqlite3Statement, "bind_param", bind_param, 2);
|
430
|
+
rb_define_method(cSqlite3Statement, "reset!", reset_bang, 0);
|
431
|
+
rb_define_method(cSqlite3Statement, "clear_bindings!", clear_bindings_bang, 0);
|
432
|
+
rb_define_method(cSqlite3Statement, "step", step, 0);
|
433
|
+
rb_define_method(cSqlite3Statement, "done?", done_p, 0);
|
434
|
+
rb_define_method(cSqlite3Statement, "column_count", column_count, 0);
|
435
|
+
rb_define_method(cSqlite3Statement, "column_name", column_name, 1);
|
436
|
+
rb_define_method(cSqlite3Statement, "column_decltype", column_decltype, 1);
|
437
|
+
rb_define_method(cSqlite3Statement, "bind_parameter_count", bind_parameter_count, 0);
|
438
|
+
|
439
|
+
#ifdef HAVE_SQLITE3_COLUMN_DATABASE_NAME
|
440
|
+
rb_define_method(cSqlite3Statement, "database_name", database_name, 1);
|
441
|
+
#endif
|
442
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#ifndef SQLITE3_STATEMENT_RUBY
|
2
|
+
#define SQLITE3_STATEMENT_RUBY
|
3
|
+
|
4
|
+
#include <sqlite3_ruby.h>
|
5
|
+
|
6
|
+
struct _sqlite3StmtRuby {
|
7
|
+
sqlite3_stmt *st;
|
8
|
+
int done_p;
|
9
|
+
};
|
10
|
+
|
11
|
+
typedef struct _sqlite3StmtRuby sqlite3StmtRuby;
|
12
|
+
typedef sqlite3StmtRuby * sqlite3StmtRubyPtr;
|
13
|
+
|
14
|
+
void init_sqlite3_statement();
|
15
|
+
|
16
|
+
#endif
|