sqlite3 1.5.0.rc1-x86-linux

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/API_CHANGES.md +49 -0
  4. data/CHANGELOG.md +419 -0
  5. data/CONTRIBUTING.md +24 -0
  6. data/ChangeLog.cvs +88 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE +27 -0
  9. data/LICENSE-DEPENDENCIES +20 -0
  10. data/README.md +233 -0
  11. data/ext/sqlite3/aggregator.c +273 -0
  12. data/ext/sqlite3/aggregator.h +12 -0
  13. data/ext/sqlite3/backup.c +168 -0
  14. data/ext/sqlite3/backup.h +15 -0
  15. data/ext/sqlite3/database.c +853 -0
  16. data/ext/sqlite3/database.h +17 -0
  17. data/ext/sqlite3/exception.c +98 -0
  18. data/ext/sqlite3/exception.h +8 -0
  19. data/ext/sqlite3/extconf.rb +159 -0
  20. data/ext/sqlite3/sqlite3.c +163 -0
  21. data/ext/sqlite3/sqlite3_ruby.h +45 -0
  22. data/ext/sqlite3/statement.c +442 -0
  23. data/ext/sqlite3/statement.h +16 -0
  24. data/faq/faq.md +431 -0
  25. data/faq/faq.rb +145 -0
  26. data/faq/faq.yml +426 -0
  27. data/lib/sqlite3/2.6/sqlite3_native.so +0 -0
  28. data/lib/sqlite3/2.7/sqlite3_native.so +0 -0
  29. data/lib/sqlite3/3.0/sqlite3_native.so +0 -0
  30. data/lib/sqlite3/3.1/sqlite3_native.so +0 -0
  31. data/lib/sqlite3/constants.rb +50 -0
  32. data/lib/sqlite3/database.rb +741 -0
  33. data/lib/sqlite3/errors.rb +35 -0
  34. data/lib/sqlite3/pragmas.rb +595 -0
  35. data/lib/sqlite3/resultset.rb +187 -0
  36. data/lib/sqlite3/statement.rb +145 -0
  37. data/lib/sqlite3/translator.rb +118 -0
  38. data/lib/sqlite3/value.rb +57 -0
  39. data/lib/sqlite3/version.rb +25 -0
  40. data/lib/sqlite3.rb +15 -0
  41. data/test/helper.rb +27 -0
  42. data/test/test_backup.rb +33 -0
  43. data/test/test_collation.rb +82 -0
  44. data/test/test_database.rb +538 -0
  45. data/test/test_database_flags.rb +95 -0
  46. data/test/test_database_readonly.rb +36 -0
  47. data/test/test_database_readwrite.rb +41 -0
  48. data/test/test_deprecated.rb +44 -0
  49. data/test/test_encoding.rb +155 -0
  50. data/test/test_integration.rb +507 -0
  51. data/test/test_integration_aggregate.rb +336 -0
  52. data/test/test_integration_open_close.rb +30 -0
  53. data/test/test_integration_pending.rb +115 -0
  54. data/test/test_integration_resultset.rb +142 -0
  55. data/test/test_integration_statement.rb +194 -0
  56. data/test/test_result_set.rb +37 -0
  57. data/test/test_sqlite3.rb +25 -0
  58. data/test/test_statement.rb +263 -0
  59. data/test/test_statement_execute.rb +35 -0
  60. 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