1
1
#include <sqlite3_ruby.h>
2
2
3
3
#define REQUIRE_OPEN_STMT (_ctxt ) \
4
- if(!_ctxt->st) \
4
+ if (!_ctxt->st) \
5
5
rb_raise(rb_path2class("SQLite3::Exception"), "cannot use a closed statement");
6
6
7
- static void
8
- require_open_db (VALUE stmt_rb )
9
- {
10
- VALUE closed_p = rb_funcall (
11
- rb_iv_get (stmt_rb , "@connection" ),
12
- rb_intern ("closed?" ), 0 );
13
-
14
- if (RTEST (closed_p )) {
15
- rb_raise (rb_path2class ("SQLite3::Exception" ),
16
- "cannot use a statement associated with a closed database" );
17
- }
18
- }
19
-
7
+ #define REQUIRE_LIVE_DB (_ctxt ) \
8
+ if (_ctxt->db->flags & SQLITE_DATABASE_DISCARDED) \
9
+ rb_raise(rb_path2class("SQLite3::Exception"), "cannot use a statement associated with a discarded database");
20
10
21
11
VALUE cSqlite3Statement ;
22
12
@@ -71,6 +61,11 @@ prepare(VALUE self, VALUE db, VALUE sql)
71
61
72
62
TypedData_Get_Struct (self , sqlite3StmtRuby , & statement_type , ctx );
73
63
64
+ /* Dereferencing a pointer to the database struct will be faster than accessing it through the
65
+ * instance variable @connection. The struct pointer is guaranteed to be live because instance
66
+ * variable will keep it from being GCed. */
67
+ ctx -> db = db_ctx ;
68
+
74
69
#ifdef HAVE_SQLITE3_PREPARE_V2
75
70
status = sqlite3_prepare_v2 (
76
71
#else
@@ -135,7 +130,7 @@ step(VALUE self)
135
130
136
131
TypedData_Get_Struct (self , sqlite3StmtRuby , & statement_type , ctx );
137
132
138
- require_open_db ( self );
133
+ REQUIRE_LIVE_DB ( ctx );
139
134
REQUIRE_OPEN_STMT (ctx );
140
135
141
136
if (ctx -> done_p ) { return Qnil ; }
@@ -232,7 +227,7 @@ bind_param(VALUE self, VALUE key, VALUE value)
232
227
233
228
TypedData_Get_Struct (self , sqlite3StmtRuby , & statement_type , ctx );
234
229
235
- require_open_db ( self );
230
+ REQUIRE_LIVE_DB ( ctx );
236
231
REQUIRE_OPEN_STMT (ctx );
237
232
238
233
switch (TYPE (key )) {
@@ -326,7 +321,7 @@ reset_bang(VALUE self)
326
321
327
322
TypedData_Get_Struct (self , sqlite3StmtRuby , & statement_type , ctx );
328
323
329
- require_open_db ( self );
324
+ REQUIRE_LIVE_DB ( ctx );
330
325
REQUIRE_OPEN_STMT (ctx );
331
326
332
327
sqlite3_reset (ctx -> st );
@@ -348,7 +343,7 @@ clear_bindings_bang(VALUE self)
348
343
349
344
TypedData_Get_Struct (self , sqlite3StmtRuby , & statement_type , ctx );
350
345
351
- require_open_db ( self );
346
+ REQUIRE_LIVE_DB ( ctx );
352
347
REQUIRE_OPEN_STMT (ctx );
353
348
354
349
sqlite3_clear_bindings (ctx -> st );
@@ -382,7 +377,7 @@ column_count(VALUE self)
382
377
sqlite3StmtRubyPtr ctx ;
383
378
TypedData_Get_Struct (self , sqlite3StmtRuby , & statement_type , ctx );
384
379
385
- require_open_db ( self );
380
+ REQUIRE_LIVE_DB ( ctx );
386
381
REQUIRE_OPEN_STMT (ctx );
387
382
388
383
return INT2NUM (sqlite3_column_count (ctx -> st ));
@@ -415,7 +410,7 @@ column_name(VALUE self, VALUE index)
415
410
416
411
TypedData_Get_Struct (self , sqlite3StmtRuby , & statement_type , ctx );
417
412
418
- require_open_db ( self );
413
+ REQUIRE_LIVE_DB ( ctx );
419
414
REQUIRE_OPEN_STMT (ctx );
420
415
421
416
name = sqlite3_column_name (ctx -> st , (int )NUM2INT (index ));
@@ -440,7 +435,7 @@ column_decltype(VALUE self, VALUE index)
440
435
441
436
TypedData_Get_Struct (self , sqlite3StmtRuby , & statement_type , ctx );
442
437
443
- require_open_db ( self );
438
+ REQUIRE_LIVE_DB ( ctx );
444
439
REQUIRE_OPEN_STMT (ctx );
445
440
446
441
name = sqlite3_column_decltype (ctx -> st , (int )NUM2INT (index ));
@@ -459,7 +454,7 @@ bind_parameter_count(VALUE self)
459
454
sqlite3StmtRubyPtr ctx ;
460
455
TypedData_Get_Struct (self , sqlite3StmtRuby , & statement_type , ctx );
461
456
462
- require_open_db ( self );
457
+ REQUIRE_LIVE_DB ( ctx );
463
458
REQUIRE_OPEN_STMT (ctx );
464
459
465
460
return INT2NUM (sqlite3_bind_parameter_count (ctx -> st ));
@@ -568,7 +563,7 @@ stats_as_hash(VALUE self)
568
563
sqlite3StmtRubyPtr ctx ;
569
564
TypedData_Get_Struct (self , sqlite3StmtRuby , & statement_type , ctx );
570
565
571
- require_open_db ( self );
566
+ REQUIRE_LIVE_DB ( ctx );
572
567
REQUIRE_OPEN_STMT (ctx );
573
568
574
569
VALUE arg = rb_hash_new ();
@@ -587,7 +582,7 @@ stat_for(VALUE self, VALUE key)
587
582
sqlite3StmtRubyPtr ctx ;
588
583
TypedData_Get_Struct (self , sqlite3StmtRuby , & statement_type , ctx );
589
584
590
- require_open_db ( self );
585
+ REQUIRE_LIVE_DB ( ctx );
591
586
REQUIRE_OPEN_STMT (ctx );
592
587
593
588
if (SYMBOL_P (key )) {
@@ -609,7 +604,7 @@ memused(VALUE self)
609
604
sqlite3StmtRubyPtr ctx ;
610
605
TypedData_Get_Struct (self , sqlite3StmtRuby , & statement_type , ctx );
611
606
612
- require_open_db ( self );
607
+ REQUIRE_LIVE_DB ( ctx );
613
608
REQUIRE_OPEN_STMT (ctx );
614
609
615
610
return INT2NUM (sqlite3_stmt_status (ctx -> st , SQLITE_STMTSTATUS_MEMUSED , 0 ));
@@ -628,7 +623,7 @@ database_name(VALUE self, VALUE index)
628
623
sqlite3StmtRubyPtr ctx ;
629
624
TypedData_Get_Struct (self , sqlite3StmtRuby , & statement_type , ctx );
630
625
631
- require_open_db ( self );
626
+ REQUIRE_LIVE_DB ( ctx );
632
627
REQUIRE_OPEN_STMT (ctx );
633
628
634
629
return SQLITE3_UTF8_STR_NEW2 (
@@ -647,7 +642,7 @@ get_sql(VALUE self)
647
642
sqlite3StmtRubyPtr ctx ;
648
643
TypedData_Get_Struct (self , sqlite3StmtRuby , & statement_type , ctx );
649
644
650
- require_open_db ( self );
645
+ REQUIRE_LIVE_DB ( ctx );
651
646
REQUIRE_OPEN_STMT (ctx );
652
647
653
648
return rb_obj_freeze (SQLITE3_UTF8_STR_NEW2 (sqlite3_sql (ctx -> st )));
@@ -667,7 +662,7 @@ get_expanded_sql(VALUE self)
667
662
668
663
TypedData_Get_Struct (self , sqlite3StmtRuby , & statement_type , ctx );
669
664
670
- require_open_db ( self );
665
+ REQUIRE_LIVE_DB ( ctx );
671
666
REQUIRE_OPEN_STMT (ctx );
672
667
673
668
expanded_sql = sqlite3_expanded_sql (ctx -> st );
0 commit comments