sqlite3 1.7.3-aarch64-linux → 2.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +394 -1
  3. data/CONTRIBUTING.md +37 -6
  4. data/FAQ.md +52 -84
  5. data/INSTALLATION.md +21 -13
  6. data/LICENSE +18 -22
  7. data/README.md +97 -9
  8. data/dependencies.yml +10 -11
  9. data/ext/sqlite3/aggregator.c +143 -146
  10. data/ext/sqlite3/aggregator.h +2 -4
  11. data/ext/sqlite3/backup.c +74 -65
  12. data/ext/sqlite3/backup.h +2 -2
  13. data/ext/sqlite3/database.c +619 -495
  14. data/ext/sqlite3/database.h +13 -4
  15. data/ext/sqlite3/exception.c +116 -92
  16. data/ext/sqlite3/exception.h +5 -1
  17. data/ext/sqlite3/extconf.rb +39 -27
  18. data/ext/sqlite3/sqlite3.c +176 -115
  19. data/ext/sqlite3/sqlite3_ruby.h +2 -2
  20. data/ext/sqlite3/statement.c +588 -300
  21. data/ext/sqlite3/statement.h +4 -3
  22. data/ext/sqlite3/timespec.h +20 -0
  23. data/lib/sqlite3/constants.rb +195 -47
  24. data/lib/sqlite3/database.rb +228 -187
  25. data/lib/sqlite3/errors.rb +54 -1
  26. data/lib/sqlite3/fork_safety.rb +66 -0
  27. data/lib/sqlite3/pragmas.rb +194 -141
  28. data/lib/sqlite3/resultset.rb +14 -97
  29. data/lib/sqlite3/statement.rb +58 -13
  30. data/lib/sqlite3/value.rb +17 -20
  31. data/lib/sqlite3/version.rb +2 -21
  32. data/lib/sqlite3/version_info.rb +17 -0
  33. data/lib/sqlite3.rb +8 -4
  34. data/ports/archives/sqlite-autoconf-3530200.tar.gz +0 -0
  35. metadata +28 -45
  36. data/API_CHANGES.md +0 -49
  37. data/ChangeLog.cvs +0 -88
  38. data/Gemfile +0 -10
  39. data/LICENSE-DEPENDENCIES +0 -20
  40. data/lib/sqlite3/3.0/sqlite3_native.so +0 -0
  41. data/lib/sqlite3/3.1/sqlite3_native.so +0 -0
  42. data/lib/sqlite3/3.2/sqlite3_native.so +0 -0
  43. data/lib/sqlite3/3.3/sqlite3_native.so +0 -0
  44. data/lib/sqlite3/translator.rb +0 -117
  45. data/test/helper.rb +0 -27
  46. data/test/test_backup.rb +0 -33
  47. data/test/test_collation.rb +0 -82
  48. data/test/test_database.rb +0 -668
  49. data/test/test_database_flags.rb +0 -95
  50. data/test/test_database_readonly.rb +0 -36
  51. data/test/test_database_readwrite.rb +0 -41
  52. data/test/test_deprecated.rb +0 -49
  53. data/test/test_encoding.rb +0 -165
  54. data/test/test_integration.rb +0 -507
  55. data/test/test_integration_aggregate.rb +0 -336
  56. data/test/test_integration_open_close.rb +0 -30
  57. data/test/test_integration_pending.rb +0 -115
  58. data/test/test_integration_resultset.rb +0 -142
  59. data/test/test_integration_statement.rb +0 -194
  60. data/test/test_pragmas.rb +0 -22
  61. data/test/test_result_set.rb +0 -47
  62. data/test/test_sqlite3.rb +0 -30
  63. data/test/test_statement.rb +0 -290
  64. data/test/test_statement_execute.rb +0 -39
@@ -12,133 +12,220 @@
12
12
 
13
13
  VALUE cSqlite3Database;
14
14
 
15
- static void deallocate(void * ctx)
15
+ /* See adr/2024-09-fork-safety.md */
16
+ static void
17
+ discard_db(sqlite3RubyPtr ctx)
18
+ {
19
+ sqlite3_file *sfile;
20
+ int status;
21
+
22
+ // release as much heap memory as possible by deallocating non-essential memory
23
+ // allocations held by the database library. Memory used to cache database pages to
24
+ // improve performance is an example of non-essential memory.
25
+ // on my development machine, this reduces the lost memory from 152k to 69k.
26
+ sqlite3_db_release_memory(ctx->db);
27
+
28
+ // release file descriptors
29
+ #ifdef HAVE_SQLITE3_DB_NAME
30
+ const char *db_name;
31
+ int j_db = 0;
32
+ while ((db_name = sqlite3_db_name(ctx->db, j_db)) != NULL) {
33
+ status = sqlite3_file_control(ctx->db, db_name, SQLITE_FCNTL_FILE_POINTER, &sfile);
34
+ if (status == 0 && sfile->pMethods != NULL) {
35
+ sfile->pMethods->xClose(sfile);
36
+ }
37
+ j_db++;
38
+ }
39
+ #else
40
+ status = sqlite3_file_control(ctx->db, NULL, SQLITE_FCNTL_FILE_POINTER, &sfile);
41
+ if (status == 0 && sfile->pMethods != NULL) {
42
+ sfile->pMethods->xClose(sfile);
43
+ }
44
+ #endif
45
+
46
+ status = sqlite3_file_control(ctx->db, NULL, SQLITE_FCNTL_JOURNAL_POINTER, &sfile);
47
+ if (status == 0 && sfile->pMethods != NULL) {
48
+ sfile->pMethods->xClose(sfile);
49
+ }
50
+
51
+ ctx->db = NULL;
52
+ ctx->flags |= SQLITE3_RB_DATABASE_DISCARDED;
53
+ }
54
+
55
+ static void
56
+ close_or_discard_db(sqlite3RubyPtr ctx)
16
57
  {
17
- sqlite3RubyPtr c = (sqlite3RubyPtr)ctx;
18
- sqlite3 * db = c->db;
58
+ if (ctx->db) {
59
+ int is_readonly = (ctx->flags & SQLITE3_RB_DATABASE_READONLY);
19
60
 
20
- if(db) sqlite3_close(db);
21
- xfree(c);
61
+ if (is_readonly || ctx->owner == getpid()) {
62
+ // Ordinary close.
63
+ sqlite3_close_v2(ctx->db);
64
+ ctx->db = NULL;
65
+ } else {
66
+ // This is an open connection carried across a fork(). "Discard" it.
67
+ discard_db(ctx);
68
+ }
69
+ }
22
70
  }
23
71
 
24
- static size_t database_memsize(const void *ctx)
72
+
73
+ static void
74
+ database_mark(void *ctx)
25
75
  {
26
- const sqlite3RubyPtr c = (const sqlite3RubyPtr)ctx;
27
- // NB: can't account for ctx->db because the type is incomplete.
28
- return sizeof(*c);
76
+ sqlite3RubyPtr c = (sqlite3RubyPtr)ctx;
77
+ rb_gc_mark(c->busy_handler);
78
+ }
79
+
80
+ static void
81
+ deallocate(void *ctx)
82
+ {
83
+ close_or_discard_db((sqlite3RubyPtr)ctx);
84
+ xfree(ctx);
85
+ }
86
+
87
+ static size_t
88
+ database_memsize(const void *ctx)
89
+ {
90
+ const sqlite3RubyPtr c = (const sqlite3RubyPtr)ctx;
91
+ // NB: can't account for ctx->db because the type is incomplete.
92
+ return sizeof(*c);
29
93
  }
30
94
 
31
95
  static const rb_data_type_t database_type = {
32
- "SQLite3::Backup",
33
- {
34
- NULL,
35
- deallocate,
36
- database_memsize,
37
- },
38
- 0,
39
- 0,
40
- RUBY_TYPED_WB_PROTECTED, // Not freed immediately because the dfree function do IOs.
96
+ .wrap_struct_name = "SQLite3::Backup",
97
+ .function = {
98
+ .dmark = database_mark,
99
+ .dfree = deallocate,
100
+ .dsize = database_memsize,
101
+ },
102
+ .flags = RUBY_TYPED_WB_PROTECTED, // Not freed immediately because the dfree function do IOs.
41
103
  };
42
104
 
43
- static VALUE allocate(VALUE klass)
105
+ static VALUE
106
+ allocate(VALUE klass)
44
107
  {
45
- sqlite3RubyPtr ctx;
46
- return TypedData_Make_Struct(klass, sqlite3Ruby, &database_type, ctx);
108
+ sqlite3RubyPtr ctx;
109
+ VALUE object = TypedData_Make_Struct(klass, sqlite3Ruby, &database_type, ctx);
110
+ ctx->owner = getpid();
111
+ return object;
47
112
  }
48
113
 
49
114
  static char *
50
115
  utf16_string_value_ptr(VALUE str)
51
116
  {
52
- StringValue(str);
53
- rb_str_buf_cat(str, "\x00\x00", 2L);
54
- return RSTRING_PTR(str);
117
+ StringValue(str);
118
+ rb_str_buf_cat(str, "\x00\x00", 2L);
119
+ return RSTRING_PTR(str);
55
120
  }
56
121
 
57
- static VALUE sqlite3_rb_close(VALUE self);
58
-
59
- sqlite3RubyPtr sqlite3_database_unwrap(VALUE database){
60
- sqlite3RubyPtr ctx;
61
- TypedData_Get_Struct(database, sqlite3Ruby, &database_type, ctx);
62
- return ctx;
122
+ sqlite3RubyPtr
123
+ sqlite3_database_unwrap(VALUE database)
124
+ {
125
+ sqlite3RubyPtr ctx;
126
+ TypedData_Get_Struct(database, sqlite3Ruby, &database_type, ctx);
127
+ return ctx;
63
128
  }
64
129
 
65
- static VALUE rb_sqlite3_open_v2(VALUE self, VALUE file, VALUE mode, VALUE zvfs)
130
+ static VALUE
131
+ rb_sqlite3_open_v2(VALUE self, VALUE file, VALUE mode, VALUE zvfs)
66
132
  {
67
- sqlite3RubyPtr ctx;
68
- int status;
133
+ sqlite3RubyPtr ctx;
134
+ int status;
135
+ int flags;
69
136
 
70
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
137
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
71
138
 
72
139
  #if defined TAINTING_SUPPORT
73
140
  # if defined StringValueCStr
74
- StringValuePtr(file);
75
- rb_check_safe_obj(file);
141
+ StringValuePtr(file);
142
+ rb_check_safe_obj(file);
76
143
  # else
77
- Check_SafeStr(file);
144
+ Check_SafeStr(file);
78
145
  # endif
79
146
  #endif
80
147
 
81
- status = sqlite3_open_v2(
82
- StringValuePtr(file),
83
- &ctx->db,
84
- NUM2INT(mode),
85
- NIL_P(zvfs) ? NULL : StringValuePtr(zvfs)
86
- );
87
-
88
- CHECK(ctx->db, status)
148
+ flags = NUM2INT(mode);
149
+ status = sqlite3_open_v2(
150
+ StringValuePtr(file),
151
+ &ctx->db,
152
+ flags,
153
+ NIL_P(zvfs) ? NULL : StringValuePtr(zvfs)
154
+ );
155
+
156
+ CHECK(ctx->db, status);
157
+ if (flags & SQLITE_OPEN_READONLY) {
158
+ ctx->flags |= SQLITE3_RB_DATABASE_READONLY;
159
+ }
89
160
 
90
- return self;
161
+ return self;
91
162
  }
92
163
 
93
- static VALUE rb_sqlite3_disable_quirk_mode(VALUE self)
164
+ static VALUE
165
+ rb_sqlite3_disable_quirk_mode(VALUE self)
94
166
  {
95
167
  #if defined SQLITE_DBCONFIG_DQS_DDL
96
- sqlite3RubyPtr ctx;
97
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
168
+ sqlite3RubyPtr ctx;
169
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
98
170
 
99
- if(!ctx->db) return Qfalse;
171
+ if (!ctx->db) { return Qfalse; }
100
172
 
101
- sqlite3_db_config(ctx->db, SQLITE_DBCONFIG_DQS_DDL, 0, (void*)0);
102
- sqlite3_db_config(ctx->db, SQLITE_DBCONFIG_DQS_DML, 0, (void*)0);
173
+ sqlite3_db_config(ctx->db, SQLITE_DBCONFIG_DQS_DDL, 0, (void *)0);
174
+ sqlite3_db_config(ctx->db, SQLITE_DBCONFIG_DQS_DML, 0, (void *)0);
103
175
 
104
- return Qtrue;
176
+ return Qtrue;
105
177
  #else
106
- return Qfalse;
178
+ return Qfalse;
107
179
  #endif
108
180
  }
109
181
 
110
- /* call-seq: db.close
182
+ /*
183
+ * Close the database and release all associated resources.
184
+ *
185
+ * ⚠ Writable connections that are carried across a <tt>fork()</tt> are not completely
186
+ * closed. {Sqlite does not support forking}[https://www.sqlite.org/howtocorrupt.html],
187
+ * and fully closing a writable connection that has been carried across a fork may corrupt the
188
+ * database. Since it is an incomplete close, not all memory resources are freed, but this is safer
189
+ * than risking data loss.
111
190
  *
112
- * Closes this database.
191
+ * See rdoc-ref:adr/2024-09-fork-safety.md for more information on fork safety.
113
192
  */
114
- static VALUE sqlite3_rb_close(VALUE self)
193
+ static VALUE
194
+ sqlite3_rb_close(VALUE self)
115
195
  {
116
- sqlite3RubyPtr ctx;
117
- sqlite3 * db;
118
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
196
+ sqlite3RubyPtr ctx;
197
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
119
198
 
120
- db = ctx->db;
121
- CHECK(db, sqlite3_close(ctx->db));
199
+ close_or_discard_db(ctx);
122
200
 
123
- ctx->db = NULL;
201
+ return self;
202
+ }
203
+
204
+ /* private method, primarily for testing */
205
+ static VALUE
206
+ sqlite3_rb_discard(VALUE self)
207
+ {
208
+ sqlite3RubyPtr ctx;
209
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
124
210
 
125
- rb_iv_set(self, "-aggregators", Qnil);
211
+ discard_db(ctx);
126
212
 
127
- return self;
213
+ return self;
128
214
  }
129
215
 
130
216
  /* call-seq: db.closed?
131
217
  *
132
218
  * Returns +true+ if this database instance has been closed (see #close).
133
219
  */
134
- static VALUE closed_p(VALUE self)
220
+ static VALUE
221
+ closed_p(VALUE self)
135
222
  {
136
- sqlite3RubyPtr ctx;
137
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
223
+ sqlite3RubyPtr ctx;
224
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
138
225
 
139
- if(!ctx->db) return Qtrue;
226
+ if (!ctx->db) { return Qtrue; }
140
227
 
141
- return Qfalse;
228
+ return Qfalse;
142
229
  }
143
230
 
144
231
  /* call-seq: total_changes
@@ -146,20 +233,22 @@ static VALUE closed_p(VALUE self)
146
233
  * Returns the total number of changes made to this database instance
147
234
  * since it was opened.
148
235
  */
149
- static VALUE total_changes(VALUE self)
236
+ static VALUE
237
+ total_changes(VALUE self)
150
238
  {
151
- sqlite3RubyPtr ctx;
152
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
153
- REQUIRE_OPEN_DB(ctx);
239
+ sqlite3RubyPtr ctx;
240
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
241
+ REQUIRE_OPEN_DB(ctx);
154
242
 
155
- return INT2NUM(sqlite3_total_changes(ctx->db));
243
+ return INT2NUM(sqlite3_total_changes(ctx->db));
156
244
  }
157
245
 
158
- static void tracefunc(void * data, const char *sql)
246
+ static void
247
+ tracefunc(void *data, const char *sql)
159
248
  {
160
- VALUE self = (VALUE)data;
161
- VALUE thing = rb_iv_get(self, "@tracefunc");
162
- rb_funcall(thing, rb_intern("call"), 1, rb_str_new2(sql));
249
+ VALUE self = (VALUE)data;
250
+ VALUE thing = rb_iv_get(self, "@tracefunc");
251
+ rb_funcall(thing, rb_intern("call"), 1, rb_str_new2(sql));
163
252
  }
164
253
 
165
254
  /* call-seq:
@@ -170,34 +259,37 @@ static void tracefunc(void * data, const char *sql)
170
259
  * statement executed. The block receives one parameter: the SQL statement
171
260
  * executed. If the block is +nil+, any existing tracer will be uninstalled.
172
261
  */
173
- static VALUE trace(int argc, VALUE *argv, VALUE self)
262
+ static VALUE
263
+ trace(int argc, VALUE *argv, VALUE self)
174
264
  {
175
- sqlite3RubyPtr ctx;
176
- VALUE block;
265
+ sqlite3RubyPtr ctx;
266
+ VALUE block;
177
267
 
178
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
179
- REQUIRE_OPEN_DB(ctx);
268
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
269
+ REQUIRE_OPEN_DB(ctx);
180
270
 
181
- rb_scan_args(argc, argv, "01", &block);
271
+ rb_scan_args(argc, argv, "01", &block);
182
272
 
183
- if(NIL_P(block) && rb_block_given_p()) block = rb_block_proc();
273
+ if (NIL_P(block) && rb_block_given_p()) { block = rb_block_proc(); }
184
274
 
185
- rb_iv_set(self, "@tracefunc", block);
275
+ rb_iv_set(self, "@tracefunc", block);
186
276
 
187
- sqlite3_trace(ctx->db, NIL_P(block) ? NULL : tracefunc, (void *)self);
277
+ sqlite3_trace(ctx->db, NIL_P(block) ? NULL : tracefunc, (void *)self);
188
278
 
189
- return self;
279
+ return self;
190
280
  }
191
281
 
192
- static int rb_sqlite3_busy_handler(void * ctx, int count)
282
+ static int
283
+ rb_sqlite3_busy_handler(void *context, int count)
193
284
  {
194
- VALUE self = (VALUE)(ctx);
195
- VALUE handle = rb_iv_get(self, "@busy_handler");
196
- VALUE result = rb_funcall(handle, rb_intern("call"), 1, INT2NUM(count));
285
+ sqlite3RubyPtr ctx = (sqlite3RubyPtr)context;
197
286
 
198
- if(Qfalse == result) return 0;
287
+ VALUE handle = ctx->busy_handler;
288
+ VALUE result = rb_funcall(handle, rb_intern("call"), 1, INT2NUM(count));
199
289
 
200
- return 1;
290
+ if (Qfalse == result) { return 0; }
291
+
292
+ return 1;
201
293
  }
202
294
 
203
295
  /* call-seq:
@@ -214,27 +306,68 @@ static int rb_sqlite3_busy_handler(void * ctx, int count)
214
306
  *
215
307
  * See also the mutually exclusive #busy_timeout.
216
308
  */
217
- static VALUE busy_handler(int argc, VALUE *argv, VALUE self)
309
+ static VALUE
310
+ busy_handler(int argc, VALUE *argv, VALUE self)
218
311
  {
219
- sqlite3RubyPtr ctx;
220
- VALUE block;
221
- int status;
312
+ sqlite3RubyPtr ctx;
313
+ VALUE block;
314
+ int status;
315
+
316
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
317
+ REQUIRE_OPEN_DB(ctx);
318
+
319
+ rb_scan_args(argc, argv, "01", &block);
320
+
321
+ if (NIL_P(block) && rb_block_given_p()) { block = rb_block_proc(); }
322
+ RB_OBJ_WRITE(self, &ctx->busy_handler, block);
323
+
324
+ status = sqlite3_busy_handler(
325
+ ctx->db,
326
+ NIL_P(block) ? NULL : rb_sqlite3_busy_handler,
327
+ (void *)ctx
328
+ );
222
329
 
223
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
224
- REQUIRE_OPEN_DB(ctx);
330
+ CHECK(ctx->db, status);
225
331
 
226
- rb_scan_args(argc, argv, "01", &block);
332
+ return self;
333
+ }
334
+
335
+ static int
336
+ rb_sqlite3_statement_timeout(void *context)
337
+ {
338
+ sqlite3RubyPtr ctx = (sqlite3RubyPtr)context;
339
+ struct timespec currentTime;
340
+ clock_gettime(CLOCK_MONOTONIC, &currentTime);
341
+
342
+ if (!timespecisset(&ctx->stmt_deadline)) {
343
+ // Set stmt_deadline if not already set
344
+ ctx->stmt_deadline = currentTime;
345
+ } else if (timespecafter(&currentTime, &ctx->stmt_deadline)) {
346
+ return 1;
347
+ }
227
348
 
228
- if(NIL_P(block) && rb_block_given_p()) block = rb_block_proc();
349
+ return 0;
350
+ }
229
351
 
230
- rb_iv_set(self, "@busy_handler", block);
352
+ /* call-seq: db.statement_timeout = ms
353
+ *
354
+ * Indicates that if a query lasts longer than the indicated number of
355
+ * milliseconds, SQLite should interrupt that query and return an error.
356
+ * By default, SQLite does not interrupt queries. To restore the default
357
+ * behavior, send 0 as the +ms+ parameter.
358
+ */
359
+ static VALUE
360
+ set_statement_timeout(VALUE self, VALUE milliseconds)
361
+ {
362
+ sqlite3RubyPtr ctx;
363
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
231
364
 
232
- status = sqlite3_busy_handler(
233
- ctx->db, NIL_P(block) ? NULL : rb_sqlite3_busy_handler, (void *)self);
365
+ ctx->stmt_timeout = NUM2INT(milliseconds);
366
+ int n = NUM2INT(milliseconds) == 0 ? -1 : 1000;
234
367
 
235
- CHECK(ctx->db, status);
368
+ sqlite3_progress_handler(ctx->db, n, rb_sqlite3_statement_timeout, (void *)ctx);
236
369
 
237
- return self;
370
+ return self;
238
371
  }
239
372
 
240
373
  /* call-seq: last_insert_row_id
@@ -242,115 +375,122 @@ static VALUE busy_handler(int argc, VALUE *argv, VALUE self)
242
375
  * Obtains the unique row ID of the last row to be inserted by this Database
243
376
  * instance.
244
377
  */
245
- static VALUE last_insert_row_id(VALUE self)
246
- {
247
- sqlite3RubyPtr ctx;
248
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
249
- REQUIRE_OPEN_DB(ctx);
250
-
251
- return LL2NUM(sqlite3_last_insert_rowid(ctx->db));
252
- }
253
-
254
- VALUE sqlite3val2rb(sqlite3_value * val)
255
- {
256
- switch(sqlite3_value_type(val)) {
257
- case SQLITE_INTEGER:
258
- return LL2NUM(sqlite3_value_int64(val));
259
- break;
260
- case SQLITE_FLOAT:
261
- return rb_float_new(sqlite3_value_double(val));
262
- break;
263
- case SQLITE_TEXT:
264
- return rb_str_new2((const char *)sqlite3_value_text(val));
265
- break;
266
- case SQLITE_BLOB: {
267
- /* Sqlite warns calling sqlite3_value_bytes may invalidate pointer from sqlite3_value_blob,
268
- so we explicitly get the length before getting blob pointer.
269
- Note that rb_str_new apparently create string with ASCII-8BIT (BINARY) encoding,
270
- which is what we want, as blobs are binary
271
- */
272
- int len = sqlite3_value_bytes(val);
273
- return rb_str_new((const char *)sqlite3_value_blob(val), len);
274
- break;
378
+ static VALUE
379
+ last_insert_row_id(VALUE self)
380
+ {
381
+ sqlite3RubyPtr ctx;
382
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
383
+ REQUIRE_OPEN_DB(ctx);
384
+
385
+ return LL2NUM(sqlite3_last_insert_rowid(ctx->db));
386
+ }
387
+
388
+ VALUE
389
+ sqlite3val2rb(sqlite3_value *val)
390
+ {
391
+ VALUE rb_val;
392
+
393
+ switch (sqlite3_value_type(val)) {
394
+ case SQLITE_INTEGER:
395
+ rb_val = LL2NUM(sqlite3_value_int64(val));
396
+ break;
397
+ case SQLITE_FLOAT:
398
+ rb_val = rb_float_new(sqlite3_value_double(val));
399
+ break;
400
+ case SQLITE_TEXT: {
401
+ rb_val = rb_utf8_str_new_cstr((const char *)sqlite3_value_text(val));
402
+ rb_obj_freeze(rb_val);
403
+ break;
404
+ }
405
+ case SQLITE_BLOB: {
406
+ int len = sqlite3_value_bytes(val);
407
+ rb_val = rb_str_new((const char *)sqlite3_value_blob(val), len);
408
+ rb_obj_freeze(rb_val);
409
+ break;
410
+ }
411
+ case SQLITE_NULL:
412
+ rb_val = Qnil;
413
+ break;
414
+ default:
415
+ rb_raise(rb_eRuntimeError, "bad type");
275
416
  }
276
- case SQLITE_NULL:
277
- return Qnil;
278
- break;
279
- default:
280
- rb_raise(rb_eRuntimeError, "bad type"); /* FIXME */
281
- }
282
- }
283
-
284
- void set_sqlite3_func_result(sqlite3_context * ctx, VALUE result)
285
- {
286
- switch(TYPE(result)) {
287
- case T_NIL:
288
- sqlite3_result_null(ctx);
289
- break;
290
- case T_FIXNUM:
291
- sqlite3_result_int64(ctx, (sqlite3_int64)FIX2LONG(result));
292
- break;
293
- case T_BIGNUM: {
417
+
418
+ return rb_val;
419
+ }
420
+
421
+ void
422
+ set_sqlite3_func_result(sqlite3_context *ctx, VALUE result)
423
+ {
424
+ switch (TYPE(result)) {
425
+ case T_NIL:
426
+ sqlite3_result_null(ctx);
427
+ break;
428
+ case T_FIXNUM:
429
+ sqlite3_result_int64(ctx, (sqlite3_int64)FIX2LONG(result));
430
+ break;
431
+ case T_BIGNUM: {
294
432
  #if SIZEOF_LONG < 8
295
- sqlite3_int64 num64;
433
+ sqlite3_int64 num64;
296
434
 
297
- if (bignum_to_int64(result, &num64)) {
298
- sqlite3_result_int64(ctx, num64);
299
- break;
300
- }
435
+ if (bignum_to_int64(result, &num64)) {
436
+ sqlite3_result_int64(ctx, num64);
437
+ break;
438
+ }
301
439
  #endif
440
+ }
441
+ case T_FLOAT:
442
+ sqlite3_result_double(ctx, NUM2DBL(result));
443
+ break;
444
+ case T_STRING:
445
+ if (CLASS_OF(result) == cSqlite3Blob
446
+ || rb_enc_get_index(result) == rb_ascii8bit_encindex()
447
+ ) {
448
+ sqlite3_result_blob(
449
+ ctx,
450
+ (const void *)StringValuePtr(result),
451
+ (int)RSTRING_LEN(result),
452
+ SQLITE_TRANSIENT
453
+ );
454
+ } else {
455
+ sqlite3_result_text(
456
+ ctx,
457
+ (const char *)StringValuePtr(result),
458
+ (int)RSTRING_LEN(result),
459
+ SQLITE_TRANSIENT
460
+ );
461
+ }
462
+ break;
463
+ default:
464
+ rb_raise(rb_eRuntimeError, "can't return %s",
465
+ rb_class2name(CLASS_OF(result)));
302
466
  }
303
- case T_FLOAT:
304
- sqlite3_result_double(ctx, NUM2DBL(result));
305
- break;
306
- case T_STRING:
307
- if(CLASS_OF(result) == cSqlite3Blob
308
- || rb_enc_get_index(result) == rb_ascii8bit_encindex()
309
- ) {
310
- sqlite3_result_blob(
311
- ctx,
312
- (const void *)StringValuePtr(result),
313
- (int)RSTRING_LEN(result),
314
- SQLITE_TRANSIENT
315
- );
316
- } else {
317
- sqlite3_result_text(
318
- ctx,
319
- (const char *)StringValuePtr(result),
320
- (int)RSTRING_LEN(result),
321
- SQLITE_TRANSIENT
322
- );
323
- }
324
- break;
325
- default:
326
- rb_raise(rb_eRuntimeError, "can't return %s",
327
- rb_class2name(CLASS_OF(result)));
328
- }
329
- }
330
-
331
- static void rb_sqlite3_func(sqlite3_context * ctx, int argc, sqlite3_value **argv)
332
- {
333
- VALUE callable = (VALUE)sqlite3_user_data(ctx);
334
- VALUE params = rb_ary_new2(argc);
335
- VALUE result;
336
- int i;
337
-
338
- if (argc > 0) {
339
- for(i = 0; i < argc; i++) {
340
- VALUE param = sqlite3val2rb(argv[i]);
341
- rb_ary_push(params, param);
467
+ }
468
+
469
+ static void
470
+ rb_sqlite3_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
471
+ {
472
+ VALUE callable = (VALUE)sqlite3_user_data(ctx);
473
+ VALUE params = rb_ary_new2(argc);
474
+ VALUE result;
475
+ int i;
476
+
477
+ if (argc > 0) {
478
+ for (i = 0; i < argc; i++) {
479
+ VALUE param = sqlite3val2rb(argv[i]);
480
+ rb_ary_push(params, param);
481
+ }
342
482
  }
343
- }
344
483
 
345
- result = rb_apply(callable, rb_intern("call"), params);
484
+ result = rb_apply(callable, rb_intern("call"), params);
346
485
 
347
- set_sqlite3_func_result(ctx, result);
486
+ set_sqlite3_func_result(ctx, result);
348
487
  }
349
488
 
350
489
  #ifndef HAVE_RB_PROC_ARITY
351
- int rb_proc_arity(VALUE self)
490
+ int
491
+ rb_proc_arity(VALUE self)
352
492
  {
353
- return (int)NUM2INT(rb_funcall(self, rb_intern("arity"), 0));
493
+ return (int)NUM2INT(rb_funcall(self, rb_intern("arity"), 0));
354
494
  }
355
495
  #endif
356
496
 
@@ -359,33 +499,34 @@ int rb_proc_arity(VALUE self)
359
499
  * Define a function named +name+ with +args+ using TextRep bitflags +flags+. The arity of the block
360
500
  * will be used as the arity for the function defined.
361
501
  */
362
- static VALUE define_function_with_flags(VALUE self, VALUE name, VALUE flags)
502
+ static VALUE
503
+ define_function_with_flags(VALUE self, VALUE name, VALUE flags)
363
504
  {
364
- sqlite3RubyPtr ctx;
365
- VALUE block;
366
- int status;
505
+ sqlite3RubyPtr ctx;
506
+ VALUE block;
507
+ int status;
367
508
 
368
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
369
- REQUIRE_OPEN_DB(ctx);
509
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
510
+ REQUIRE_OPEN_DB(ctx);
370
511
 
371
- block = rb_block_proc();
512
+ block = rb_block_proc();
372
513
 
373
- status = sqlite3_create_function(
374
- ctx->db,
375
- StringValuePtr(name),
376
- rb_proc_arity(block),
377
- NUM2INT(flags),
378
- (void *)block,
379
- rb_sqlite3_func,
380
- NULL,
381
- NULL
382
- );
514
+ status = sqlite3_create_function(
515
+ ctx->db,
516
+ StringValuePtr(name),
517
+ rb_proc_arity(block),
518
+ NUM2INT(flags),
519
+ (void *)block,
520
+ rb_sqlite3_func,
521
+ NULL,
522
+ NULL
523
+ );
383
524
 
384
- CHECK(ctx->db, status);
525
+ CHECK(ctx->db, status);
385
526
 
386
- rb_hash_aset(rb_iv_get(self, "@functions"), name, block);
527
+ rb_ary_push(rb_iv_get(self, "@functions"), block);
387
528
 
388
- return self;
529
+ return self;
389
530
  }
390
531
 
391
532
  /* call-seq: define_function(name) { |args,...| }
@@ -393,24 +534,26 @@ static VALUE define_function_with_flags(VALUE self, VALUE name, VALUE flags)
393
534
  * Define a function named +name+ with +args+. The arity of the block
394
535
  * will be used as the arity for the function defined.
395
536
  */
396
- static VALUE define_function(VALUE self, VALUE name)
537
+ static VALUE
538
+ define_function(VALUE self, VALUE name)
397
539
  {
398
- return define_function_with_flags(self, name, INT2FIX(SQLITE_UTF8));
540
+ return define_function_with_flags(self, name, INT2FIX(SQLITE_UTF8));
399
541
  }
400
542
 
401
543
  /* call-seq: interrupt
402
544
  *
403
545
  * Interrupts the currently executing operation, causing it to abort.
404
546
  */
405
- static VALUE interrupt(VALUE self)
547
+ static VALUE
548
+ interrupt(VALUE self)
406
549
  {
407
- sqlite3RubyPtr ctx;
408
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
409
- REQUIRE_OPEN_DB(ctx);
550
+ sqlite3RubyPtr ctx;
551
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
552
+ REQUIRE_OPEN_DB(ctx);
410
553
 
411
- sqlite3_interrupt(ctx->db);
554
+ sqlite3_interrupt(ctx->db);
412
555
 
413
- return self;
556
+ return self;
414
557
  }
415
558
 
416
559
  /* call-seq: errmsg
@@ -418,13 +561,14 @@ static VALUE interrupt(VALUE self)
418
561
  * Return a string describing the last error to have occurred with this
419
562
  * database.
420
563
  */
421
- static VALUE errmsg(VALUE self)
564
+ static VALUE
565
+ errmsg(VALUE self)
422
566
  {
423
- sqlite3RubyPtr ctx;
424
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
425
- REQUIRE_OPEN_DB(ctx);
567
+ sqlite3RubyPtr ctx;
568
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
569
+ REQUIRE_OPEN_DB(ctx);
426
570
 
427
- return rb_str_new2(sqlite3_errmsg(ctx->db));
571
+ return rb_str_new2(sqlite3_errmsg(ctx->db));
428
572
  }
429
573
 
430
574
  /* call-seq: errcode
@@ -432,13 +576,14 @@ static VALUE errmsg(VALUE self)
432
576
  * Return an integer representing the last error to have occurred with this
433
577
  * database.
434
578
  */
435
- static VALUE errcode_(VALUE self)
579
+ static VALUE
580
+ errcode_(VALUE self)
436
581
  {
437
- sqlite3RubyPtr ctx;
438
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
439
- REQUIRE_OPEN_DB(ctx);
582
+ sqlite3RubyPtr ctx;
583
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
584
+ REQUIRE_OPEN_DB(ctx);
440
585
 
441
- return INT2NUM(sqlite3_errcode(ctx->db));
586
+ return INT2NUM(sqlite3_errcode(ctx->db));
442
587
  }
443
588
 
444
589
  /* call-seq: complete?(sql)
@@ -446,12 +591,14 @@ static VALUE errcode_(VALUE self)
446
591
  * Return +true+ if the string is a valid (ie, parsable) SQL statement, and
447
592
  * +false+ otherwise.
448
593
  */
449
- static VALUE complete_p(VALUE UNUSED(self), VALUE sql)
594
+ static VALUE
595
+ complete_p(VALUE UNUSED(self), VALUE sql)
450
596
  {
451
- if(sqlite3_complete(StringValuePtr(sql)))
452
- return Qtrue;
597
+ if (sqlite3_complete(StringValuePtr(sql))) {
598
+ return Qtrue;
599
+ }
453
600
 
454
- return Qfalse;
601
+ return Qfalse;
455
602
  }
456
603
 
457
604
  /* call-seq: changes
@@ -460,37 +607,39 @@ static VALUE complete_p(VALUE UNUSED(self), VALUE sql)
460
607
  * operation performed. Note that a "delete from table" without a where
461
608
  * clause will not affect this value.
462
609
  */
463
- static VALUE changes(VALUE self)
610
+ static VALUE
611
+ changes(VALUE self)
464
612
  {
465
- sqlite3RubyPtr ctx;
466
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
467
- REQUIRE_OPEN_DB(ctx);
613
+ sqlite3RubyPtr ctx;
614
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
615
+ REQUIRE_OPEN_DB(ctx);
468
616
 
469
- return INT2NUM(sqlite3_changes(ctx->db));
617
+ return INT2NUM(sqlite3_changes(ctx->db));
470
618
  }
471
619
 
472
- static int rb_sqlite3_auth(
620
+ static int
621
+ rb_sqlite3_auth(
473
622
  void *ctx,
474
623
  int _action,
475
- const char * _a,
476
- const char * _b,
477
- const char * _c,
478
- const char * _d)
624
+ const char *_a,
625
+ const char *_b,
626
+ const char *_c,
627
+ const char *_d)
479
628
  {
480
- VALUE self = (VALUE)ctx;
481
- VALUE action = INT2NUM(_action);
482
- VALUE a = _a ? rb_str_new2(_a) : Qnil;
483
- VALUE b = _b ? rb_str_new2(_b) : Qnil;
484
- VALUE c = _c ? rb_str_new2(_c) : Qnil;
485
- VALUE d = _d ? rb_str_new2(_d) : Qnil;
486
- VALUE callback = rb_iv_get(self, "@authorizer");
487
- VALUE result = rb_funcall(callback, rb_intern("call"), 5, action, a, b, c, d);
629
+ VALUE self = (VALUE)ctx;
630
+ VALUE action = INT2NUM(_action);
631
+ VALUE a = _a ? rb_str_new2(_a) : Qnil;
632
+ VALUE b = _b ? rb_str_new2(_b) : Qnil;
633
+ VALUE c = _c ? rb_str_new2(_c) : Qnil;
634
+ VALUE d = _d ? rb_str_new2(_d) : Qnil;
635
+ VALUE callback = rb_iv_get(self, "@authorizer");
636
+ VALUE result = rb_funcall(callback, rb_intern("call"), 5, action, a, b, c, d);
488
637
 
489
- if(T_FIXNUM == TYPE(result)) return (int)NUM2INT(result);
490
- if(Qtrue == result) return SQLITE_OK;
491
- if(Qfalse == result) return SQLITE_DENY;
638
+ if (T_FIXNUM == TYPE(result)) { return (int)NUM2INT(result); }
639
+ if (Qtrue == result) { return SQLITE_OK; }
640
+ if (Qfalse == result) { return SQLITE_DENY; }
492
641
 
493
- return SQLITE_IGNORE;
642
+ return SQLITE_IGNORE;
494
643
  }
495
644
 
496
645
  /* call-seq: set_authorizer = auth
@@ -503,23 +652,24 @@ static int rb_sqlite3_auth(
503
652
  * is allowed to proceed. Returning 1 or false causes an authorization error to
504
653
  * occur, and returning 2 or nil causes the access to be silently denied.
505
654
  */
506
- static VALUE set_authorizer(VALUE self, VALUE authorizer)
655
+ static VALUE
656
+ set_authorizer(VALUE self, VALUE authorizer)
507
657
  {
508
- sqlite3RubyPtr ctx;
509
- int status;
658
+ sqlite3RubyPtr ctx;
659
+ int status;
510
660
 
511
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
512
- REQUIRE_OPEN_DB(ctx);
661
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
662
+ REQUIRE_OPEN_DB(ctx);
513
663
 
514
- status = sqlite3_set_authorizer(
515
- ctx->db, NIL_P(authorizer) ? NULL : rb_sqlite3_auth, (void *)self
516
- );
664
+ status = sqlite3_set_authorizer(
665
+ ctx->db, NIL_P(authorizer) ? NULL : rb_sqlite3_auth, (void *)self
666
+ );
517
667
 
518
- CHECK(ctx->db, status);
668
+ CHECK(ctx->db, status);
519
669
 
520
- rb_iv_set(self, "@authorizer", authorizer);
670
+ rb_iv_set(self, "@authorizer", authorizer);
521
671
 
522
- return self;
672
+ return self;
523
673
  }
524
674
 
525
675
  /* call-seq: db.busy_timeout = ms
@@ -532,15 +682,16 @@ static VALUE set_authorizer(VALUE self, VALUE authorizer)
532
682
  *
533
683
  * See also the mutually exclusive #busy_handler.
534
684
  */
535
- static VALUE set_busy_timeout(VALUE self, VALUE timeout)
685
+ static VALUE
686
+ set_busy_timeout(VALUE self, VALUE timeout)
536
687
  {
537
- sqlite3RubyPtr ctx;
538
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
539
- REQUIRE_OPEN_DB(ctx);
688
+ sqlite3RubyPtr ctx;
689
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
690
+ REQUIRE_OPEN_DB(ctx);
540
691
 
541
- CHECK(ctx->db, sqlite3_busy_timeout(ctx->db, (int)NUM2INT(timeout)));
692
+ CHECK(ctx->db, sqlite3_busy_timeout(ctx->db, (int)NUM2INT(timeout)));
542
693
 
543
- return self;
694
+ return self;
544
695
  }
545
696
 
546
697
  /* call-seq: db.extended_result_codes = true
@@ -548,42 +699,44 @@ static VALUE set_busy_timeout(VALUE self, VALUE timeout)
548
699
  * Enable extended result codes in SQLite. These result codes allow for more
549
700
  * detailed exception reporting, such a which type of constraint is violated.
550
701
  */
551
- static VALUE set_extended_result_codes(VALUE self, VALUE enable)
702
+ static VALUE
703
+ set_extended_result_codes(VALUE self, VALUE enable)
552
704
  {
553
- sqlite3RubyPtr ctx;
554
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
555
- REQUIRE_OPEN_DB(ctx);
705
+ sqlite3RubyPtr ctx;
706
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
707
+ REQUIRE_OPEN_DB(ctx);
556
708
 
557
- CHECK(ctx->db, sqlite3_extended_result_codes(ctx->db, RTEST(enable) ? 1 : 0));
709
+ CHECK(ctx->db, sqlite3_extended_result_codes(ctx->db, RTEST(enable) ? 1 : 0));
558
710
 
559
- return self;
711
+ return self;
560
712
  }
561
713
 
562
- int rb_comparator_func(void * ctx, int a_len, const void * a, int b_len, const void * b)
714
+ int
715
+ rb_comparator_func(void *ctx, int a_len, const void *a, int b_len, const void *b)
563
716
  {
564
- VALUE comparator;
565
- VALUE a_str;
566
- VALUE b_str;
567
- VALUE comparison;
568
- rb_encoding * internal_encoding;
717
+ VALUE comparator;
718
+ VALUE a_str;
719
+ VALUE b_str;
720
+ VALUE comparison;
721
+ rb_encoding *internal_encoding;
569
722
 
570
- internal_encoding = rb_default_internal_encoding();
723
+ internal_encoding = rb_default_internal_encoding();
571
724
 
572
- comparator = (VALUE)ctx;
573
- a_str = rb_str_new((const char *)a, a_len);
574
- b_str = rb_str_new((const char *)b, b_len);
725
+ comparator = (VALUE)ctx;
726
+ a_str = rb_str_new((const char *)a, a_len);
727
+ b_str = rb_str_new((const char *)b, b_len);
575
728
 
576
- rb_enc_associate_index(a_str, rb_utf8_encindex());
577
- rb_enc_associate_index(b_str, rb_utf8_encindex());
729
+ rb_enc_associate_index(a_str, rb_utf8_encindex());
730
+ rb_enc_associate_index(b_str, rb_utf8_encindex());
578
731
 
579
- if(internal_encoding) {
580
- a_str = rb_str_export_to_enc(a_str, internal_encoding);
581
- b_str = rb_str_export_to_enc(b_str, internal_encoding);
582
- }
732
+ if (internal_encoding) {
733
+ a_str = rb_str_export_to_enc(a_str, internal_encoding);
734
+ b_str = rb_str_export_to_enc(b_str, internal_encoding);
735
+ }
583
736
 
584
- comparison = rb_funcall(comparator, rb_intern("compare"), 2, a_str, b_str);
737
+ comparison = rb_funcall(comparator, rb_intern("compare"), 2, a_str, b_str);
585
738
 
586
- return NUM2INT(comparison);
739
+ return NUM2INT(comparison);
587
740
  }
588
741
 
589
742
  /* call-seq: db.collation(name, comparator)
@@ -593,159 +746,123 @@ int rb_comparator_func(void * ctx, int a_len, const void * a, int b_len, const v
593
746
  * two parameters and returns an integer less than, equal to, or greater than
594
747
  * 0.
595
748
  */
596
- static VALUE collation(VALUE self, VALUE name, VALUE comparator)
749
+ static VALUE
750
+ collation(VALUE self, VALUE name, VALUE comparator)
597
751
  {
598
- sqlite3RubyPtr ctx;
599
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
600
- REQUIRE_OPEN_DB(ctx);
752
+ sqlite3RubyPtr ctx;
753
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
754
+ REQUIRE_OPEN_DB(ctx);
601
755
 
602
- CHECK(ctx->db, sqlite3_create_collation(
603
- ctx->db,
604
- StringValuePtr(name),
605
- SQLITE_UTF8,
606
- (void *)comparator,
607
- NIL_P(comparator) ? NULL : rb_comparator_func));
756
+ CHECK(ctx->db, sqlite3_create_collation(
757
+ ctx->db,
758
+ StringValuePtr(name),
759
+ SQLITE_UTF8,
760
+ (void *)comparator,
761
+ NIL_P(comparator) ? NULL : rb_comparator_func));
608
762
 
609
- /* Make sure our comparator doesn't get garbage collected. */
610
- rb_hash_aset(rb_iv_get(self, "@collations"), name, comparator);
763
+ /* Make sure our comparator doesn't get garbage collected. */
764
+ rb_hash_aset(rb_iv_get(self, "@collations"), name, comparator);
611
765
 
612
- return self;
766
+ return self;
613
767
  }
614
768
 
615
769
  #ifdef HAVE_SQLITE3_LOAD_EXTENSION
616
- /* call-seq: db.load_extension(file)
617
- *
618
- * Loads an SQLite extension library from the named file. Extension
619
- * loading must be enabled using db.enable_load_extension(true) prior
620
- * to calling this API.
621
- */
622
- static VALUE load_extension(VALUE self, VALUE file)
770
+ static VALUE
771
+ load_extension_internal(VALUE self, VALUE file)
623
772
  {
624
- sqlite3RubyPtr ctx;
625
- int status;
626
- char *errMsg;
627
- VALUE errexp;
628
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
629
- REQUIRE_OPEN_DB(ctx);
773
+ sqlite3RubyPtr ctx;
774
+ int status;
775
+ char *errMsg;
776
+
777
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
778
+ REQUIRE_OPEN_DB(ctx);
779
+
780
+ status = sqlite3_load_extension(ctx->db, StringValuePtr(file), 0, &errMsg);
630
781
 
631
- status = sqlite3_load_extension(ctx->db, StringValuePtr(file), 0, &errMsg);
632
- if (status != SQLITE_OK)
633
- {
634
- errexp = rb_exc_new2(rb_eRuntimeError, errMsg);
635
- sqlite3_free(errMsg);
636
- rb_exc_raise(errexp);
637
- }
782
+ CHECK_MSG(ctx->db, status, errMsg);
638
783
 
639
- return self;
784
+ return self;
640
785
  }
641
786
  #endif
642
787
 
643
- #ifdef HAVE_SQLITE3_ENABLE_LOAD_EXTENSION
788
+ #if defined(HAVE_SQLITE3_ENABLE_LOAD_EXTENSION) && defined(HAVE_SQLITE3_LOAD_EXTENSION)
644
789
  /* call-seq: db.enable_load_extension(onoff)
645
790
  *
646
791
  * Enable or disable extension loading.
647
792
  */
648
- static VALUE enable_load_extension(VALUE self, VALUE onoff)
649
- {
650
- sqlite3RubyPtr ctx;
651
- int onoffparam;
652
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
653
- REQUIRE_OPEN_DB(ctx);
654
-
655
- if (Qtrue == onoff) {
656
- onoffparam = 1;
657
- } else if (Qfalse == onoff) {
658
- onoffparam = 0;
659
- } else {
660
- onoffparam = (int)NUM2INT(onoff);
661
- }
793
+ static VALUE
794
+ enable_load_extension(VALUE self, VALUE onoff)
795
+ {
796
+ sqlite3RubyPtr ctx;
797
+ int onoffparam;
798
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
799
+ REQUIRE_OPEN_DB(ctx);
800
+
801
+ if (Qtrue == onoff) {
802
+ onoffparam = 1;
803
+ } else if (Qfalse == onoff) {
804
+ onoffparam = 0;
805
+ } else {
806
+ onoffparam = (int)NUM2INT(onoff);
807
+ }
662
808
 
663
- CHECK(ctx->db, sqlite3_enable_load_extension(ctx->db, onoffparam));
809
+ CHECK(ctx->db, sqlite3_enable_load_extension(ctx->db, onoffparam));
664
810
 
665
- return self;
811
+ return self;
666
812
  }
667
813
  #endif
668
814
 
669
- static int enc_cb(void * _self, int UNUSED(columns), char **data, char **UNUSED(names))
670
- {
671
- VALUE self = (VALUE)_self;
672
-
673
- int index = rb_enc_find_index(data[0]);
674
- rb_encoding * e = rb_enc_from_index(index);
675
- rb_iv_set(self, "@encoding", rb_enc_from_encoding(e));
676
-
677
- return 0;
678
- }
679
-
680
- /* call-seq: db.encoding
681
- *
682
- * Fetch the encoding set on this database
683
- */
684
- static VALUE db_encoding(VALUE self)
685
- {
686
- sqlite3RubyPtr ctx;
687
- VALUE enc;
688
-
689
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
690
- REQUIRE_OPEN_DB(ctx);
691
-
692
- enc = rb_iv_get(self, "@encoding");
693
-
694
- if(NIL_P(enc)) {
695
- sqlite3_exec(ctx->db, "PRAGMA encoding", enc_cb, (void *)self, NULL);
696
- }
697
-
698
- return rb_iv_get(self, "@encoding");
699
- }
700
-
701
815
  /* call-seq: db.transaction_active?
702
816
  *
703
817
  * Returns +true+ if there is a transaction active, and +false+ otherwise.
704
818
  *
705
819
  */
706
- static VALUE transaction_active_p(VALUE self)
820
+ static VALUE
821
+ transaction_active_p(VALUE self)
707
822
  {
708
- sqlite3RubyPtr ctx;
709
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
710
- REQUIRE_OPEN_DB(ctx);
823
+ sqlite3RubyPtr ctx;
824
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
825
+ REQUIRE_OPEN_DB(ctx);
711
826
 
712
- return sqlite3_get_autocommit(ctx->db) ? Qfalse : Qtrue;
827
+ return sqlite3_get_autocommit(ctx->db) ? Qfalse : Qtrue;
713
828
  }
714
829
 
715
- static int hash_callback_function(VALUE callback_ary, int count, char **data, char **columns)
830
+ static int
831
+ hash_callback_function(VALUE callback_ary, int count, char **data, char **columns)
716
832
  {
717
- VALUE new_hash = rb_hash_new();
718
- int i;
833
+ VALUE new_hash = rb_hash_new();
834
+ int i;
719
835
 
720
- for (i = 0; i < count; i++) {
721
- if (data[i] == NULL) {
722
- rb_hash_aset(new_hash, rb_str_new_cstr(columns[i]), Qnil);
723
- } else {
724
- rb_hash_aset(new_hash, rb_str_new_cstr(columns[i]), rb_str_new_cstr(data[i]));
836
+ for (i = 0; i < count; i++) {
837
+ if (data[i] == NULL) {
838
+ rb_hash_aset(new_hash, rb_str_new_cstr(columns[i]), Qnil);
839
+ } else {
840
+ rb_hash_aset(new_hash, rb_str_new_cstr(columns[i]), rb_str_new_cstr(data[i]));
841
+ }
725
842
  }
726
- }
727
843
 
728
- rb_ary_push(callback_ary, new_hash);
844
+ rb_ary_push(callback_ary, new_hash);
729
845
 
730
- return 0;
846
+ return 0;
731
847
  }
732
848
 
733
- static int regular_callback_function(VALUE callback_ary, int count, char **data, char **columns)
849
+ static int
850
+ regular_callback_function(VALUE callback_ary, int count, char **data, char **columns)
734
851
  {
735
- VALUE new_ary = rb_ary_new();
736
- int i;
852
+ VALUE new_ary = rb_ary_new();
853
+ int i;
737
854
 
738
- for (i = 0; i < count; i++) {
739
- if (data[i] == NULL) {
740
- rb_ary_push(new_ary, Qnil);
741
- } else {
742
- rb_ary_push(new_ary, rb_str_new_cstr(data[i]));
855
+ for (i = 0; i < count; i++) {
856
+ if (data[i] == NULL) {
857
+ rb_ary_push(new_ary, Qnil);
858
+ } else {
859
+ rb_ary_push(new_ary, rb_str_new_cstr(data[i]));
860
+ }
743
861
  }
744
- }
745
862
 
746
- rb_ary_push(callback_ary, new_ary);
863
+ rb_ary_push(callback_ary, new_ary);
747
864
 
748
- return 0;
865
+ return 0;
749
866
  }
750
867
 
751
868
 
@@ -757,31 +874,30 @@ static int regular_callback_function(VALUE callback_ary, int count, char **data,
757
874
  * so the user may parse values with a block.
758
875
  * If no query is made, an empty array will be returned.
759
876
  */
760
- static VALUE exec_batch(VALUE self, VALUE sql, VALUE results_as_hash)
877
+ static VALUE
878
+ exec_batch(VALUE self, VALUE sql, VALUE results_as_hash)
761
879
  {
762
- sqlite3RubyPtr ctx;
763
- int status;
764
- VALUE callback_ary = rb_ary_new();
765
- char *errMsg;
766
- VALUE errexp;
880
+ sqlite3RubyPtr ctx;
881
+ int status;
882
+ VALUE callback_ary = rb_ary_new();
883
+ char *errMsg;
767
884
 
768
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
769
- REQUIRE_OPEN_DB(ctx);
885
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
886
+ REQUIRE_OPEN_DB(ctx);
770
887
 
771
- if(results_as_hash == Qtrue) {
772
- status = sqlite3_exec(ctx->db, StringValuePtr(sql), (sqlite3_callback)hash_callback_function, (void*)callback_ary, &errMsg);
773
- } else {
774
- status = sqlite3_exec(ctx->db, StringValuePtr(sql), (sqlite3_callback)regular_callback_function, (void*)callback_ary, &errMsg);
775
- }
888
+ if (results_as_hash == Qtrue) {
889
+ status = sqlite3_exec(ctx->db, StringValuePtr(sql), (sqlite3_callback)hash_callback_function,
890
+ (void *)callback_ary,
891
+ &errMsg);
892
+ } else {
893
+ status = sqlite3_exec(ctx->db, StringValuePtr(sql), (sqlite3_callback)regular_callback_function,
894
+ (void *)callback_ary,
895
+ &errMsg);
896
+ }
776
897
 
777
- if (status != SQLITE_OK)
778
- {
779
- errexp = rb_exc_new2(rb_eRuntimeError, errMsg);
780
- sqlite3_free(errMsg);
781
- rb_exc_raise(errexp);
782
- }
898
+ CHECK_MSG(ctx->db, status, errMsg);
783
899
 
784
- return callback_ary;
900
+ return callback_ary;
785
901
  }
786
902
 
787
903
  /* call-seq: db.db_filename(database_name)
@@ -789,88 +905,96 @@ static VALUE exec_batch(VALUE self, VALUE sql, VALUE results_as_hash)
789
905
  * Returns the file associated with +database_name+. Can return nil or an
790
906
  * empty string if the database is temporary, or in-memory.
791
907
  */
792
- static VALUE db_filename(VALUE self, VALUE db_name)
908
+ static VALUE
909
+ db_filename(VALUE self, VALUE db_name)
793
910
  {
794
- sqlite3RubyPtr ctx;
795
- const char * fname;
796
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
797
- REQUIRE_OPEN_DB(ctx);
911
+ sqlite3RubyPtr ctx;
912
+ const char *fname;
913
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
914
+ REQUIRE_OPEN_DB(ctx);
798
915
 
799
- fname = sqlite3_db_filename(ctx->db, StringValueCStr(db_name));
916
+ fname = sqlite3_db_filename(ctx->db, StringValueCStr(db_name));
800
917
 
801
- if(fname) return SQLITE3_UTF8_STR_NEW2(fname);
802
- return Qnil;
918
+ if (fname) { return SQLITE3_UTF8_STR_NEW2(fname); }
919
+ return Qnil;
803
920
  }
804
921
 
805
- static VALUE rb_sqlite3_open16(VALUE self, VALUE file)
922
+ static VALUE
923
+ rb_sqlite3_open16(VALUE self, VALUE file)
806
924
  {
807
- int status;
808
- sqlite3RubyPtr ctx;
925
+ int status;
926
+ sqlite3RubyPtr ctx;
809
927
 
810
- TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
928
+ TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx);
811
929
 
812
930
  #if defined TAINTING_SUPPORT
813
931
  #if defined StringValueCStr
814
- StringValuePtr(file);
815
- rb_check_safe_obj(file);
932
+ StringValuePtr(file);
933
+ rb_check_safe_obj(file);
816
934
  #else
817
- Check_SafeStr(file);
935
+ Check_SafeStr(file);
818
936
  #endif
819
937
  #endif
820
938
 
821
- status = sqlite3_open16(utf16_string_value_ptr(file), &ctx->db);
939
+ // sqlite3_open16 implicitly uses flags (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE)
940
+ // see https://www.sqlite.org/capi3ref.html#sqlite3_open
941
+ // so we do not ever set SQLITE3_RB_DATABASE_READONLY in ctx->flags
942
+ status = sqlite3_open16(utf16_string_value_ptr(file), &ctx->db);
822
943
 
823
- CHECK(ctx->db, status)
944
+ CHECK(ctx->db, status)
824
945
 
825
- return INT2NUM(status);
946
+ return INT2NUM(status);
826
947
  }
827
948
 
828
- void init_sqlite3_database(void)
949
+ void
950
+ init_sqlite3_database(void)
829
951
  {
830
952
  #if 0
831
- VALUE mSqlite3 = rb_define_module("SQLite3");
953
+ VALUE mSqlite3 = rb_define_module("SQLite3");
832
954
  #endif
833
- cSqlite3Database = rb_define_class_under(mSqlite3, "Database", rb_cObject);
834
-
835
- rb_define_alloc_func(cSqlite3Database, allocate);
836
- rb_define_private_method(cSqlite3Database, "open_v2", rb_sqlite3_open_v2, 3);
837
- rb_define_private_method(cSqlite3Database, "open16", rb_sqlite3_open16, 1);
838
- rb_define_method(cSqlite3Database, "collation", collation, 2);
839
- rb_define_method(cSqlite3Database, "close", sqlite3_rb_close, 0);
840
- rb_define_method(cSqlite3Database, "closed?", closed_p, 0);
841
- rb_define_method(cSqlite3Database, "total_changes", total_changes, 0);
842
- rb_define_method(cSqlite3Database, "trace", trace, -1);
843
- rb_define_method(cSqlite3Database, "last_insert_row_id", last_insert_row_id, 0);
844
- rb_define_method(cSqlite3Database, "define_function", define_function, 1);
845
- rb_define_method(cSqlite3Database, "define_function_with_flags", define_function_with_flags, 2);
846
- /* public "define_aggregator" is now a shim around define_aggregator2
847
- * implemented in Ruby */
848
- rb_define_private_method(cSqlite3Database, "define_aggregator2", rb_sqlite3_define_aggregator2, 2);
849
- rb_define_private_method(cSqlite3Database, "disable_quirk_mode", rb_sqlite3_disable_quirk_mode, 0);
850
- rb_define_method(cSqlite3Database, "interrupt", interrupt, 0);
851
- rb_define_method(cSqlite3Database, "errmsg", errmsg, 0);
852
- rb_define_method(cSqlite3Database, "errcode", errcode_, 0);
853
- rb_define_method(cSqlite3Database, "complete?", complete_p, 1);
854
- rb_define_method(cSqlite3Database, "changes", changes, 0);
855
- rb_define_method(cSqlite3Database, "authorizer=", set_authorizer, 1);
856
- rb_define_method(cSqlite3Database, "busy_handler", busy_handler, -1);
857
- rb_define_method(cSqlite3Database, "busy_timeout=", set_busy_timeout, 1);
858
- rb_define_method(cSqlite3Database, "extended_result_codes=", set_extended_result_codes, 1);
859
- rb_define_method(cSqlite3Database, "transaction_active?", transaction_active_p, 0);
860
- rb_define_private_method(cSqlite3Database, "exec_batch", exec_batch, 2);
861
- rb_define_private_method(cSqlite3Database, "db_filename", db_filename, 1);
862
-
863
- #ifdef HAVE_SQLITE3_LOAD_EXTENSION
864
- rb_define_method(cSqlite3Database, "load_extension", load_extension, 1);
955
+ cSqlite3Database = rb_define_class_under(mSqlite3, "Database", rb_cObject);
956
+
957
+ rb_define_alloc_func(cSqlite3Database, allocate);
958
+ rb_define_private_method(cSqlite3Database, "open_v2", rb_sqlite3_open_v2, 3);
959
+ rb_define_private_method(cSqlite3Database, "open16", rb_sqlite3_open16, 1);
960
+ rb_define_method(cSqlite3Database, "collation", collation, 2);
961
+ rb_define_method(cSqlite3Database, "close", sqlite3_rb_close, 0);
962
+ rb_define_private_method(cSqlite3Database, "discard", sqlite3_rb_discard, 0);
963
+ rb_define_method(cSqlite3Database, "closed?", closed_p, 0);
964
+ rb_define_method(cSqlite3Database, "total_changes", total_changes, 0);
965
+ rb_define_method(cSqlite3Database, "trace", trace, -1);
966
+ rb_define_method(cSqlite3Database, "last_insert_row_id", last_insert_row_id, 0);
967
+ rb_define_method(cSqlite3Database, "define_function", define_function, 1);
968
+ rb_define_method(cSqlite3Database, "define_function_with_flags", define_function_with_flags, 2);
969
+ /* public "define_aggregator" is now a shim around define_aggregator2
970
+ * implemented in Ruby */
971
+ rb_define_private_method(cSqlite3Database, "define_aggregator2", rb_sqlite3_define_aggregator2, 2);
972
+ rb_define_private_method(cSqlite3Database, "disable_quirk_mode", rb_sqlite3_disable_quirk_mode, 0);
973
+ rb_define_method(cSqlite3Database, "interrupt", interrupt, 0);
974
+ rb_define_method(cSqlite3Database, "errmsg", errmsg, 0);
975
+ rb_define_method(cSqlite3Database, "errcode", errcode_, 0);
976
+ rb_define_method(cSqlite3Database, "complete?", complete_p, 1);
977
+ rb_define_method(cSqlite3Database, "changes", changes, 0);
978
+ rb_define_method(cSqlite3Database, "authorizer=", set_authorizer, 1);
979
+ rb_define_method(cSqlite3Database, "busy_handler", busy_handler, -1);
980
+ rb_define_method(cSqlite3Database, "busy_timeout=", set_busy_timeout, 1);
981
+ #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
982
+ rb_define_method(cSqlite3Database, "statement_timeout=", set_statement_timeout, 1);
865
983
  #endif
984
+ rb_define_method(cSqlite3Database, "extended_result_codes=", set_extended_result_codes, 1);
985
+ rb_define_method(cSqlite3Database, "transaction_active?", transaction_active_p, 0);
986
+ rb_define_private_method(cSqlite3Database, "exec_batch", exec_batch, 2);
987
+ rb_define_private_method(cSqlite3Database, "db_filename", db_filename, 1);
866
988
 
989
+ #ifdef HAVE_SQLITE3_LOAD_EXTENSION
990
+ rb_define_private_method(cSqlite3Database, "load_extension_internal", load_extension_internal, 1);
867
991
  #ifdef HAVE_SQLITE3_ENABLE_LOAD_EXTENSION
868
- rb_define_method(cSqlite3Database, "enable_load_extension", enable_load_extension, 1);
992
+ rb_define_method(cSqlite3Database, "enable_load_extension", enable_load_extension, 1);
993
+ #endif
869
994
  #endif
870
995
 
871
- rb_define_method(cSqlite3Database, "encoding", db_encoding, 0);
872
996
 
873
- rb_sqlite3_aggregator_init();
997
+ rb_sqlite3_aggregator_init();
874
998
  }
875
999
 
876
1000
  #ifdef _MSC_VER