sqlite3 1.5.0-arm64-darwin

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.

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 +425 -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 +274 -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 +252 -0
  20. data/ext/sqlite3/sqlite3.c +163 -0
  21. data/ext/sqlite3/sqlite3_ruby.h +48 -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.bundle +0 -0
  28. data/lib/sqlite3/2.7/sqlite3_native.bundle +0 -0
  29. data/lib/sqlite3/3.0/sqlite3_native.bundle +0 -0
  30. data/lib/sqlite3/3.1/sqlite3_native.bundle +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 +23 -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 +545 -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 +30 -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