sqlite-ruby 2.1.0-mswin32

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.
@@ -0,0 +1,8 @@
1
+ require 'mkmf'
2
+
3
+ dir_config( "sqlite" )
4
+ have_library( "sqlite" )
5
+
6
+ if have_header( "sqlite.h" ) and have_library( "sqlite", "sqlite_open" )
7
+ create_makefile( "sqlite_api" )
8
+ end
@@ -0,0 +1,1414 @@
1
+ /*-------------------------------------------------------------------------- *
2
+ * Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions are met:
7
+ *
8
+ * * Redistributions of source code must retain the above copyright notice,
9
+ * this list of conditions and the following disclaimer.
10
+ *
11
+ * * Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ *
15
+ * * The names of its contributors may not be used to endorse or promote
16
+ * products derived from this software without specific prior written
17
+ * permission.
18
+ *
19
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ * POSSIBILITY OF SUCH DAMAGE.
30
+ *-------------------------------------------------------------------------- */
31
+
32
+ #include <stdarg.h> /* for variable-arity methods */
33
+ #include <stdlib.h> /* malloc() */
34
+ #include <sqlite.h> /* for the SQLite API */
35
+ #include "ruby.h" /* for the Ruby API */
36
+
37
+ /* TODO: methods not yet implemented:
38
+ * sqlite_set_authorizer
39
+ * sqlite_trace
40
+ * sqlite_encode_binary
41
+ * sqlite_decode_binary
42
+ *
43
+ * sqlite_open_encrypted
44
+ * sqlite_rekey */
45
+
46
+ /*>=-----------------------------------------------------------------------=<*
47
+ * MACROS
48
+ * ------------------------------------------------------------------------
49
+ * These are for performing frequently requested tasks.
50
+ *>=-----------------------------------------------------------------------=<*/
51
+
52
+ #define GetDB(var,val) \
53
+ Data_Get_Struct( val, sqlite, var ); \
54
+ if( var == NULL ) { \
55
+ static_raise_db_error( -1, "attempt to access a closed database" ); \
56
+ }
57
+
58
+ #define GetVM(var,val) \
59
+ Data_Get_Struct( val, sqlite_vm, var ); \
60
+ if( var == NULL ) { \
61
+ return Qnil; \
62
+ }
63
+
64
+ #define GetFunc(var,val) \
65
+ Data_Get_Struct( val, sqlite_func, var )
66
+
67
+ /* special macro for helping RDoc to ignore "section"-level comments. */
68
+ #define NO_RDOC
69
+
70
+ /*>=-----------------------------------------------------------------------=<*
71
+ * CONSTANTS
72
+ * ------------------------------------------------------------------------
73
+ * These are constants used internally by the extension library.
74
+ *>=-----------------------------------------------------------------------=<*/
75
+ NO_RDOC
76
+
77
+ static VALUE mSQLite;
78
+ static VALUE mAPI;
79
+ static VALUE mExceptions;
80
+
81
+ static VALUE DatabaseException;
82
+
83
+ static ID idRow;
84
+ static ID idColumns;
85
+ static ID idTypes;
86
+ static ID idCall;
87
+
88
+ static struct {
89
+ char *name;
90
+ VALUE object;
91
+ } g_sqlite_exceptions[] = {
92
+ { "OK", 0 },
93
+ { "SQL", 0 },
94
+ { "Internal", 0 },
95
+ { "Permissions", 0 },
96
+ { "Abort", 0 },
97
+ { "Busy", 0 },
98
+ { "Locked", 0 },
99
+ { "OutOfMemory", 0 },
100
+ { "ReadOnly", 0 },
101
+ { "Interrupt", 0 },
102
+ { "IOError", 0 },
103
+ { "Corrupt", 0 },
104
+ { "NotFound", 0 },
105
+ { "Full", 0 },
106
+ { "CantOpen", 0 },
107
+ { "Protocol", 0 },
108
+ { "Empty", 0 },
109
+ { "SchemaChanged", 0 },
110
+ { "TooBig", 0 },
111
+ { "Constraint", 0 },
112
+ { "Mismatch", 0 },
113
+ { "Misuse", 0 },
114
+ { "UnsupportedOSFeature", 0 },
115
+ { "Authorization", 0 },
116
+ { "Format", 0 },
117
+ { "Range", 0 },
118
+ { "NotADatabase", 0 },
119
+ { NULL, 0 }
120
+ };
121
+
122
+ #ifdef DONT_DEFINE___RDOC_PURPOSES_ONLY
123
+ x = rb_define_class_under( mExceptions, "SQLException", DatabaseException )
124
+ x = rb_define_class_under( mExceptions, "InternalException", DatabaseException )
125
+ x = rb_define_class_under( mExceptions, "PermissionsException", DatabaseException )
126
+ x = rb_define_class_under( mExceptions, "AbortException", DatabaseException )
127
+ x = rb_define_class_under( mExceptions, "BusyException", DatabaseException )
128
+ x = rb_define_class_under( mExceptions, "LockedException", DatabaseException )
129
+ x = rb_define_class_under( mExceptions, "OutOfMemoryException", DatabaseException )
130
+ x = rb_define_class_under( mExceptions, "ReadOnlyException", DatabaseException )
131
+ x = rb_define_class_under( mExceptions, "InterruptException", DatabaseException )
132
+ x = rb_define_class_under( mExceptions, "IOErrorException", DatabaseException )
133
+ x = rb_define_class_under( mExceptions, "CorruptException", DatabaseException )
134
+ x = rb_define_class_under( mExceptions, "NotFoundException", DatabaseException )
135
+ x = rb_define_class_under( mExceptions, "FullException", DatabaseException )
136
+ x = rb_define_class_under( mExceptions, "CantOpenException", DatabaseException )
137
+ x = rb_define_class_under( mExceptions, "ProtocolException", DatabaseException )
138
+ x = rb_define_class_under( mExceptions, "EmptyException", DatabaseException )
139
+ x = rb_define_class_under( mExceptions, "SchemaChangedException", DatabaseException )
140
+ x = rb_define_class_under( mExceptions, "TooBigException", DatabaseException )
141
+ x = rb_define_class_under( mExceptions, "ConstraintException", DatabaseException )
142
+ x = rb_define_class_under( mExceptions, "MismatchException", DatabaseException )
143
+ x = rb_define_class_under( mExceptions, "MisuseException", DatabaseException )
144
+ x = rb_define_class_under( mExceptions, "UnsupportedOSFeatureException", DatabaseException )
145
+ x = rb_define_class_under( mExceptions, "AuthorizationException", DatabaseException )
146
+ x = rb_define_class_under( mExceptions, "FormatException", DatabaseException )
147
+ x = rb_define_class_under( mExceptions, "RangeException", DatabaseException )
148
+ x = rb_define_class_under( mExceptions, "NotADatabaseException", DatabaseException )
149
+ #endif
150
+
151
+ /*>=-----------------------------------------------------------------------=<*
152
+ * PUBLIC FUNCTION DECLARATIONS
153
+ * ------------------------------------------------------------------------
154
+ * These functions are exported, for Ruby to access directly.
155
+ *>=-----------------------------------------------------------------------=<*/
156
+ NO_RDOC
157
+
158
+ void Init_sqlite_api();
159
+
160
+ /*>=-----------------------------------------------------------------------=<*
161
+ * PRIVATE METHOD DECLARATIONS
162
+ * ------------------------------------------------------------------------
163
+ * These are the method hooks that will be used in this extension library.
164
+ *>=-----------------------------------------------------------------------=<*/
165
+ NO_RDOC
166
+
167
+ static VALUE
168
+ static_api_open( VALUE module, VALUE file_name, VALUE mode );
169
+
170
+ static VALUE
171
+ static_api_close( VALUE module, VALUE db );
172
+
173
+ static VALUE
174
+ static_api_compile( VALUE module, VALUE db, VALUE sql );
175
+
176
+ static VALUE
177
+ static_api_bind( VALUE module, VALUE vm, VALUE idx, VALUE value );
178
+
179
+ static VALUE
180
+ static_api_finalize( VALUE module, VALUE vm );
181
+
182
+ static VALUE
183
+ static_api_reset( VALUE module, VALUE vm );
184
+
185
+ static VALUE
186
+ static_api_last_insert_row_id( VALUE module, VALUE db );
187
+
188
+ static VALUE
189
+ static_api_changes( VALUE module, VALUE db );
190
+
191
+ static VALUE
192
+ static_api_interrupt( VALUE module, VALUE db );
193
+
194
+ static VALUE
195
+ static_api_complete( VALUE module, VALUE sql );
196
+
197
+ static VALUE
198
+ static_api_busy_handler( VALUE module, VALUE db, VALUE handler );
199
+
200
+ static VALUE
201
+ static_api_busy_timeout( VALUE module, VALUE db, VALUE ms );
202
+
203
+ static VALUE
204
+ static_api_progress_handler( VALUE module, VALUE db, VALUE n, VALUE handler );
205
+
206
+ static VALUE
207
+ static_api_commit_hook( VALUE module, VALUE db, VALUE handler );
208
+
209
+ static VALUE
210
+ static_api_create_function( VALUE module, VALUE db, VALUE name, VALUE n,
211
+ VALUE proc );
212
+
213
+ static VALUE
214
+ static_api_create_aggregate( VALUE module, VALUE db, VALUE name, VALUE n,
215
+ VALUE step, VALUE finalize );
216
+
217
+ static VALUE
218
+ static_api_function_type( VALUE module, VALUE db, VALUE name, VALUE type );
219
+
220
+ static VALUE
221
+ static_api_set_result( VALUE module, VALUE func, VALUE result );
222
+
223
+ static VALUE
224
+ static_api_set_result_error( VALUE module, VALUE func, VALUE string );
225
+
226
+ static VALUE
227
+ static_api_aggregate_context( VALUE module, VALUE func );
228
+
229
+ static VALUE
230
+ static_api_aggregate_count( VALUE module, VALUE func );
231
+
232
+ /*>=-----------------------------------------------------------------------=<*
233
+ * PRIVATE FUNCTION DECLARATIONS
234
+ * ------------------------------------------------------------------------
235
+ * These are the functions that will be used in this extension library.
236
+ *>=-----------------------------------------------------------------------=<*/
237
+ NO_RDOC
238
+
239
+ static void
240
+ static_configure_exception_classes();
241
+
242
+ static void
243
+ static_raise_db_error( int code, char *msg, ... );
244
+
245
+ static void
246
+ static_raise_db_error2( int code, char **msg );
247
+
248
+ static void
249
+ static_free_vm( sqlite_vm *vm );
250
+
251
+ static int
252
+ static_busy_handler( void* cookie, const char *entity, int times );
253
+
254
+ static int
255
+ static_progress_handler( void* cookie );
256
+
257
+ static int
258
+ static_commit_hook( void* cookie );
259
+
260
+ static void
261
+ static_function_callback( sqlite_func *func, int argc, const char **argv );
262
+
263
+ static void
264
+ static_aggregate_finalize_callback( sqlite_func *func );
265
+
266
+ /*>=-----------------------------------------------------------------------=<*
267
+ * PRIVATE METHOD IMPLEMENTATIONS
268
+ * ------------------------------------------------------------------------
269
+ * Here are the implementations of the methods declared in the previous
270
+ * section.
271
+ *>=-----------------------------------------------------------------------=<*/
272
+ NO_RDOC
273
+
274
+ /**
275
+ * call-seq:
276
+ * open( file_name, mode ) -> db
277
+ *
278
+ * Open the named database file. Returns the opaque handle.
279
+ */
280
+ static VALUE
281
+ static_api_open( VALUE module, VALUE file_name, VALUE mode )
282
+ {
283
+ char *s_file_name;
284
+ char *errmsg;
285
+ int i_mode;
286
+ sqlite *db;
287
+
288
+ Check_Type( file_name, T_STRING );
289
+ Check_Type( mode, T_FIXNUM );
290
+
291
+ s_file_name = STR2CSTR( file_name );
292
+ i_mode = FIX2INT( mode );
293
+
294
+ db = sqlite_open( s_file_name, i_mode, &errmsg );
295
+ if( db == NULL )
296
+ {
297
+ static_raise_db_error2( -1, &errmsg );
298
+ /* "raise" does not return */
299
+ }
300
+
301
+ return Data_Wrap_Struct( rb_cData, NULL, sqlite_close, db );
302
+ }
303
+
304
+ /**
305
+ * call-seq:
306
+ * close( db )
307
+ *
308
+ * Closes the given opaque database handle. The handle _must_ be one that was
309
+ * returned by a call to #open.
310
+ */
311
+ static VALUE
312
+ static_api_close( VALUE module, VALUE db )
313
+ {
314
+ sqlite *handle;
315
+
316
+ /* FIXME: should this be executed atomically? */
317
+ GetDB( handle, db );
318
+ sqlite_close( handle );
319
+
320
+ /* don't need to free the handle anymore */
321
+ RDATA(db)->dfree = NULL;
322
+ RDATA(db)->data = NULL;
323
+
324
+ return Qnil;
325
+ }
326
+
327
+ /**
328
+ * call-seq:
329
+ * compile( db, sql ) -> [ vm, remainder ]
330
+ *
331
+ * Compiles the given SQL statement and returns a new virtual machine handle
332
+ * for executing it. Returns a tuple: [ vm, remainder ], where +remainder+ is
333
+ * any text that follows the first complete SQL statement in the +sql+
334
+ * parameter.
335
+ */
336
+ static VALUE
337
+ static_api_compile( VALUE module, VALUE db, VALUE sql )
338
+ {
339
+ sqlite *handle;
340
+ sqlite_vm *vm;
341
+ char *errmsg;
342
+ const char *sql_tail;
343
+ int result;
344
+ VALUE tuple;
345
+
346
+ GetDB( handle, db );
347
+ Check_Type( sql, T_STRING );
348
+
349
+ result = sqlite_compile( handle,
350
+ STR2CSTR( sql ),
351
+ &sql_tail,
352
+ &vm,
353
+ &errmsg );
354
+
355
+ if( result != SQLITE_OK )
356
+ {
357
+ static_raise_db_error2( result, &errmsg );
358
+ /* "raise" does not return */
359
+ }
360
+
361
+ tuple = rb_ary_new();
362
+ rb_ary_push( tuple, Data_Wrap_Struct( rb_cData, NULL, static_free_vm, vm ) );
363
+ rb_ary_push( tuple, rb_str_new2( sql_tail ) );
364
+
365
+ return tuple;
366
+ }
367
+
368
+ /**
369
+ * call-seq:
370
+ * step( vm ) -> hash | nil
371
+ *
372
+ * Steps through a single result for the given virtual machine. Returns a
373
+ * Hash object. If there was a valid row returned, the hash will contain
374
+ * a <tt>:row</tt> key, which maps to an array of values for that row.
375
+ * In addition, the hash will (nearly) always contain a <tt>:columns</tt>
376
+ * key (naming the columns in the result) and a <tt>:types</tt> key
377
+ * (giving the data types for each column).
378
+ *
379
+ * This will return +nil+ if there was an error previously.
380
+ */
381
+ static VALUE
382
+ static_api_step( VALUE module, VALUE vm )
383
+ {
384
+ sqlite_vm *vm_ptr;
385
+ const char **values;
386
+ const char **metadata;
387
+ int columns;
388
+ int result;
389
+ int index;
390
+ VALUE hash;
391
+ VALUE value;
392
+
393
+ GetVM( vm_ptr, vm );
394
+ hash = rb_hash_new();
395
+
396
+ result = sqlite_step( vm_ptr,
397
+ &columns,
398
+ &values,
399
+ &metadata );
400
+
401
+ switch( result )
402
+ {
403
+ case SQLITE_BUSY:
404
+ static_raise_db_error( result, "busy in step" );
405
+
406
+ case SQLITE_ROW:
407
+ value = rb_ary_new2( columns );
408
+ for( index = 0; index < columns; index++ )
409
+ {
410
+ VALUE entry = Qnil;
411
+
412
+ if( values[index] != NULL )
413
+ entry = rb_str_new2( values[index] );
414
+
415
+ rb_ary_store( value, index, entry );
416
+ }
417
+ rb_hash_aset( hash, ID2SYM(idRow), value );
418
+
419
+ case SQLITE_DONE:
420
+ value = rb_ivar_get( vm, idColumns );
421
+
422
+ if( value == Qnil )
423
+ {
424
+ value = rb_ary_new2( columns );
425
+ for( index = 0; index < columns; index++ )
426
+ {
427
+ rb_ary_store( value, index, rb_str_new2( metadata[ index ] ) );
428
+ }
429
+ rb_ivar_set( vm, idColumns, value );
430
+ }
431
+
432
+ rb_hash_aset( hash, ID2SYM(idColumns), value );
433
+
434
+ value = rb_ivar_get( vm, idTypes );
435
+
436
+ if( value == Qnil )
437
+ {
438
+ value = rb_ary_new2( columns );
439
+ for( index = 0; index < columns; index++ )
440
+ {
441
+ VALUE item = Qnil;
442
+ if( metadata[ index+columns ] )
443
+ item = rb_str_new2( metadata[ index+columns ] );
444
+ rb_ary_store( value, index, item );
445
+ }
446
+ rb_ivar_set( vm, idTypes, value );
447
+ }
448
+
449
+ rb_hash_aset( hash, ID2SYM(idTypes), value );
450
+ break;
451
+
452
+ case SQLITE_ERROR:
453
+ case SQLITE_MISUSE:
454
+ {
455
+ char *msg = NULL;
456
+ sqlite_finalize( vm_ptr, &msg );
457
+ RDATA(vm)->dfree = NULL;
458
+ RDATA(vm)->data = NULL;
459
+ static_raise_db_error2( result, &msg );
460
+ }
461
+ /* "raise" doesn't return */
462
+
463
+ default:
464
+ static_raise_db_error( -1, "[BUG] unknown result %d from sqlite_step",
465
+ result );
466
+ /* "raise" doesn't return */
467
+ }
468
+
469
+ return hash;
470
+ }
471
+
472
+ /**
473
+ * call-seq:
474
+ * finalize( vm ) -> nil
475
+ *
476
+ * Destroys the given virtual machine and releases any associated memory. Once
477
+ * finalized, the VM should not be used.
478
+ */
479
+ static VALUE
480
+ static_api_finalize( VALUE module, VALUE vm )
481
+ {
482
+ sqlite_vm *vm_ptr;
483
+ int result;
484
+ char *errmsg;
485
+
486
+ /* FIXME: should this be executed atomically? */
487
+ GetVM( vm_ptr, vm );
488
+
489
+ result = sqlite_finalize( vm_ptr, &errmsg );
490
+ if( result != SQLITE_OK )
491
+ {
492
+ static_raise_db_error2( result, &errmsg );
493
+ /* "raise" does not return */
494
+ }
495
+
496
+ /* don't need to free the handle anymore */
497
+ RDATA(vm)->dfree = NULL;
498
+ RDATA(vm)->data = NULL;
499
+
500
+ return Qnil;
501
+ }
502
+
503
+ /**
504
+ * call-seq:
505
+ * last_insert_row_id( db ) -> fixnum
506
+ *
507
+ * Returns the unique row ID of the last insert operation.
508
+ */
509
+ static VALUE
510
+ static_api_last_insert_row_id( VALUE module, VALUE db )
511
+ {
512
+ sqlite *handle;
513
+
514
+ GetDB( handle, db );
515
+
516
+ return INT2FIX( sqlite_last_insert_rowid( handle ) );
517
+ }
518
+
519
+ /**
520
+ * call-seq:
521
+ * changes( db ) -> fixnum
522
+ *
523
+ * Returns the number of changed rows affected by the last operation.
524
+ * (Note: doing a "delete from table" without a where clause does not affect
525
+ * the result of this method--see the documentation for SQLite itself for
526
+ * the reason behind this.)
527
+ */
528
+ static VALUE
529
+ static_api_changes( VALUE module, VALUE db )
530
+ {
531
+ sqlite *handle;
532
+
533
+ GetDB( handle, db );
534
+
535
+ return INT2FIX( sqlite_changes( handle ) );
536
+ }
537
+
538
+ /**
539
+ * call-seq:
540
+ * interrupt( db ) -> nil
541
+ *
542
+ * Interrupts the currently executing operation.
543
+ */
544
+ static VALUE
545
+ static_api_interrupt( VALUE module, VALUE db )
546
+ {
547
+ sqlite *handle;
548
+
549
+ GetDB( handle, db );
550
+ sqlite_interrupt( handle );
551
+
552
+ return Qnil;
553
+ }
554
+
555
+ /**
556
+ * call-seq:
557
+ * complete( sql ) -> true | false
558
+ *
559
+ * Returns +true+ if the given SQL text is complete (parsable), and
560
+ * +false+ otherwise.
561
+ */
562
+ static VALUE
563
+ static_api_complete( VALUE module, VALUE sql )
564
+ {
565
+ Check_Type( sql, T_STRING );
566
+ return ( sqlite_complete( STR2CSTR( sql ) ) ? Qtrue : Qfalse );
567
+ }
568
+
569
+ /**
570
+ * call-seq:
571
+ * busy_handler( db, handler ) -> nil
572
+ *
573
+ * Installs a callback to be invoked whenever a request cannot be honored
574
+ * because a database is busy. The handler should take two parameters: a
575
+ * string naming the resource that was being accessed, and an integer indicating
576
+ * how many times the current request has failed due to the resource being busy.
577
+ *
578
+ * If the handler returns +false+, the operation will be aborted, with a
579
+ * SQLite::BusyException being raised. Otherwise, SQLite will attempt to
580
+ * access the resource again.
581
+ *
582
+ * See #busy_timeout for an easier way to manage the common case.
583
+ */
584
+ static VALUE
585
+ static_api_busy_handler( VALUE module, VALUE db, VALUE handler )
586
+ {
587
+ sqlite *handle;
588
+
589
+ GetDB( handle, db );
590
+ if( handler == Qnil )
591
+ {
592
+ sqlite_busy_handler( handle, NULL, NULL );
593
+ }
594
+ else
595
+ {
596
+ if( !rb_obj_is_kind_of( handler, rb_cProc ) )
597
+ {
598
+ rb_raise( rb_eArgError, "handler must be a proc" );
599
+ }
600
+
601
+ sqlite_busy_handler( handle, static_busy_handler, (void*)handler );
602
+ }
603
+
604
+ return Qnil;
605
+ }
606
+
607
+ /**
608
+ * call-seq:
609
+ * busy_timeout( db, ms ) -> nil
610
+ *
611
+ * Specifies the number of milliseconds that SQLite should wait before retrying
612
+ * to access a busy resource. Specifying zero milliseconds restores the default
613
+ * behavior.
614
+ */
615
+ static VALUE
616
+ static_api_busy_timeout( VALUE module, VALUE db, VALUE ms )
617
+ {
618
+ sqlite *handle;
619
+
620
+ GetDB( handle, db );
621
+ Check_Type( ms, T_FIXNUM );
622
+
623
+ sqlite_busy_timeout( handle, FIX2INT( ms ) );
624
+
625
+ return Qnil;
626
+ }
627
+
628
+ /**
629
+ * call-seq:
630
+ * create_function( db, name, args, proc ) -> nil
631
+ *
632
+ * Defines a new function that may be invoked from within an SQL
633
+ * statement. The +args+ parameter specifies how many arguments the function
634
+ * expects--use -1 to specify variable arity. The +proc+ parameter must be
635
+ * a proc that expects +args+ + 1 parameters, with the first parameter
636
+ * being an opaque handle to the function object itself:
637
+ *
638
+ * proc do |func, *args|
639
+ * ...
640
+ * end
641
+ *
642
+ * The function object is used when calling the #set_result and
643
+ * #set_result_error methods.
644
+ */
645
+ static VALUE
646
+ static_api_create_function( VALUE module, VALUE db, VALUE name, VALUE n,
647
+ VALUE proc )
648
+ {
649
+ sqlite *handle;
650
+ int result;
651
+
652
+ GetDB( handle, db );
653
+ Check_Type( name, T_STRING );
654
+ Check_Type( n, T_FIXNUM );
655
+ if( !rb_obj_is_kind_of( proc, rb_cProc ) )
656
+ {
657
+ rb_raise( rb_eArgError, "handler must be a proc" );
658
+ }
659
+
660
+ result = sqlite_create_function( handle,
661
+ StringValueCStr(name),
662
+ FIX2INT(n),
663
+ static_function_callback,
664
+ (void*)proc );
665
+
666
+ if( result != SQLITE_OK )
667
+ {
668
+ static_raise_db_error( result, "create function %s(%d)",
669
+ StringValueCStr(name), FIX2INT(n) );
670
+ /* "raise" does not return */
671
+ }
672
+
673
+ return Qnil;
674
+ }
675
+
676
+ /**
677
+ * call-seq:
678
+ * create_aggregate( db, name, args, step, finalize ) -> nil
679
+ *
680
+ * Defines a new aggregate function that may be invoked from within an SQL
681
+ * statement. The +args+ parameter specifies how many arguments the function
682
+ * expects--use -1 to specify variable arity.
683
+ *
684
+ * The +step+ parameter specifies a proc object that will be invoked for each
685
+ * row that the function processes. It should accept an opaque handle to the
686
+ * function object, followed by its expected arguments:
687
+ *
688
+ * step = proc do |func, *args|
689
+ * ...
690
+ * end
691
+ *
692
+ * The +finalize+ parameter specifies a proc object that will be invoked after
693
+ * all rows have been processed. This gives the function an opportunity to
694
+ * aggregate and finalize the results. It should accept a single parameter:
695
+ * the opaque function handle:
696
+ *
697
+ * finalize = proc do |func|
698
+ * ...
699
+ * end
700
+ *
701
+ * The function object is used when calling the #set_result,
702
+ * #set_result_error, #aggregate_context, and #aggregate_count methods.
703
+ */
704
+ static VALUE
705
+ static_api_create_aggregate( VALUE module, VALUE db, VALUE name, VALUE n,
706
+ VALUE step, VALUE finalize )
707
+ {
708
+ sqlite *handle;
709
+ int result;
710
+ VALUE data;
711
+
712
+ GetDB( handle, db );
713
+ Check_Type( name, T_STRING );
714
+ Check_Type( n, T_FIXNUM );
715
+ if( !rb_obj_is_kind_of( step, rb_cProc ) )
716
+ {
717
+ rb_raise( rb_eArgError, "step must be a proc" );
718
+ }
719
+ if( !rb_obj_is_kind_of( finalize, rb_cProc ) )
720
+ {
721
+ rb_raise( rb_eArgError, "finalize must be a proc" );
722
+ }
723
+
724
+ /* FIXME: will the GC kill this before it is used? */
725
+ data = rb_ary_new3( 2, step, finalize );
726
+
727
+ result = sqlite_create_aggregate( handle,
728
+ StringValueCStr(name),
729
+ FIX2INT(n),
730
+ static_function_callback,
731
+ static_aggregate_finalize_callback,
732
+ (void*)data );
733
+
734
+ if( result != SQLITE_OK )
735
+ {
736
+ static_raise_db_error( result, "create aggregate %s(%d)",
737
+ StringValueCStr(name), FIX2INT(n) );
738
+ /* "raise" does not return */
739
+ }
740
+
741
+ return Qnil;
742
+ }
743
+
744
+ /**
745
+ * call-seq:
746
+ * function_type( db, name, type ) -> nil
747
+ *
748
+ * Allows you to specify the type of the data that the named function returns. If
749
+ * type is SQLite::API::NUMERIC, then the function is expected to return a numeric
750
+ * value. If it is SQLite::API::TEXT, then the function is expected to return a
751
+ * textual value. If it is SQLite::API::ARGS, then the function returns whatever its
752
+ * arguments are. And if it is a positive (or zero) integer, then the function
753
+ * returns whatever type the argument at that position is.
754
+ */
755
+ static VALUE
756
+ static_api_function_type( VALUE module, VALUE db, VALUE name, VALUE type )
757
+ {
758
+ sqlite *handle;
759
+ int result;
760
+
761
+ GetDB( handle, db );
762
+ Check_Type( name, T_STRING );
763
+ Check_Type( type, T_FIXNUM );
764
+
765
+ result = sqlite_function_type( handle,
766
+ StringValuePtr( name ),
767
+ FIX2INT( type ) );
768
+
769
+ if( result != SQLITE_OK )
770
+ {
771
+ static_raise_db_error( result, "function type %s(%d)",
772
+ StringValuePtr(name), FIX2INT(type) );
773
+ /* "raise" does not return */
774
+ }
775
+
776
+ return Qnil;
777
+ }
778
+
779
+ /**
780
+ * call-seq:
781
+ * set_result( func, result ) -> result
782
+ *
783
+ * Sets the result of the given function to the given value. This is typically
784
+ * called in the callback function for #create_function or the finalize
785
+ * callback in #create_aggregate. The result must be either a string, an integer,
786
+ * or a double.
787
+ *
788
+ * The +func+ parameter must be the opaque function handle as given to the
789
+ * callback functions mentioned above.
790
+ */
791
+ static VALUE
792
+ static_api_set_result( VALUE module, VALUE func, VALUE result )
793
+ {
794
+ sqlite_func *func_ptr;
795
+
796
+ GetFunc( func_ptr, func );
797
+ switch( TYPE(result) )
798
+ {
799
+ case T_STRING:
800
+ sqlite_set_result_string( func_ptr,
801
+ RSTRING(result)->ptr,
802
+ RSTRING(result)->len );
803
+ break;
804
+
805
+ case T_FIXNUM:
806
+ sqlite_set_result_int( func_ptr, FIX2INT(result) );
807
+ break;
808
+
809
+ case T_FLOAT:
810
+ sqlite_set_result_double( func_ptr, NUM2DBL(result) );
811
+ break;
812
+
813
+ default:
814
+ static_raise_db_error( -1, "bad type in set result (%d)",
815
+ TYPE(result) );
816
+ }
817
+
818
+ return result;
819
+ }
820
+
821
+ /**
822
+ * call-seq:
823
+ * set_result_error( func, string ) -> string
824
+ *
825
+ * Sets the result of the given function to be the error message given in the
826
+ * +string+ parameter. The +func+ parameter must be an opaque function handle
827
+ * as given to the callback function for #create_function or
828
+ * #create_aggregate.
829
+ */
830
+ static VALUE
831
+ static_api_set_result_error( VALUE module, VALUE func, VALUE string )
832
+ {
833
+ sqlite_func *func_ptr;
834
+
835
+ GetFunc( func_ptr, func );
836
+ Check_Type( string, T_STRING );
837
+
838
+ sqlite_set_result_error( func_ptr, RSTRING(string)->ptr,
839
+ RSTRING(string)->len );
840
+
841
+ return string;
842
+ }
843
+
844
+ /**
845
+ * call-seq:
846
+ * aggregate_context( func ) -> hash
847
+ *
848
+ * Returns the aggregate context for the given function. This context is a
849
+ * Hash object that is allocated on demand and is available only to the
850
+ * current invocation of the function. It may be used by aggregate functions
851
+ * to accumulate data over multiple rows, prior to being finalized.
852
+ *
853
+ * The +func+ parameter must be an opaque function handle as given to the
854
+ * callbacks for #create_aggregate.
855
+ *
856
+ * See #create_aggregate and #aggregate_count.
857
+ */
858
+ static VALUE
859
+ static_api_aggregate_context( VALUE module, VALUE func )
860
+ {
861
+ sqlite_func *func_ptr;
862
+ VALUE *ptr;
863
+
864
+ GetFunc( func_ptr, func );
865
+
866
+ /* FIXME: pointers to VALUEs...how nice is the GC about this kind of
867
+ * thing? Especially when someone else frees the memory? */
868
+
869
+ ptr = (VALUE*)sqlite_aggregate_context( func_ptr, sizeof(VALUE) );
870
+
871
+ if( *ptr == 0 )
872
+ *ptr = rb_hash_new();
873
+
874
+ return *ptr;
875
+ }
876
+
877
+ /**
878
+ * call-seq:
879
+ * aggregate_count( func ) -> fixnum
880
+ *
881
+ * Returns the number of rows that have been processed so far by the current
882
+ * aggregate function. This always includes the current row, so that number
883
+ * that is returned will always be at least 1.
884
+ *
885
+ * The +func+ parameter must be an opaque function handle as given to the
886
+ * callbacks for #create_aggregate.
887
+ */
888
+ static VALUE
889
+ static_api_aggregate_count( VALUE module, VALUE func )
890
+ {
891
+ sqlite_func *func_ptr;
892
+
893
+ GetFunc( func_ptr, func );
894
+ return INT2FIX( sqlite_aggregate_count( func_ptr ) );
895
+ }
896
+
897
+ /*>=-----------------------------------------------------------------------=<*
898
+ * PRIVATE FUNCTION IMPLEMENTATIONS
899
+ * ------------------------------------------------------------------------
900
+ * Here are the implementations of the functions declared previously.
901
+ *>=-----------------------------------------------------------------------=<*/
902
+ NO_RDOC
903
+
904
+ /*
905
+ * Document-class: SQLite::Exceptions
906
+ *
907
+ * This module contains all exceptions thrown by SQLite routines.
908
+ */
909
+
910
+ /*
911
+ * Document-class: SQLite::Exceptions::DatabaseException
912
+ *
913
+ * This is the root of the SQLite exception hierarchy. This exception will
914
+ * be thrown for any general errors, or for exceptions for which SQLite itself
915
+ * did not declare a specific error code.
916
+ */
917
+
918
+ /*
919
+ * Document-class: SQLite::Exceptions::SQLException
920
+ *
921
+ * From the SQLite documentation:
922
+ *
923
+ * "This return value indicates that there was an error in the SQL that was
924
+ * passed into the sqlite_exec."
925
+ */
926
+
927
+ /*
928
+ * Document-class: SQLite::Exceptions::InternalException
929
+ *
930
+ * From the SQLite documentation:
931
+ *
932
+ * "This value indicates that an internal consistency check within the SQLite
933
+ * library failed. This can only happen if there is a bug in the SQLite library.
934
+ * If you ever get an SQLITE_INTERNAL reply from an sqlite_exec call, please
935
+ * report the problem on the SQLite mailing list."
936
+ */
937
+
938
+ /*
939
+ * Document-class: SQLite::Exceptions::PermissionsException
940
+ *
941
+ * From the SQLite documentation:
942
+ *
943
+ * "This return value says that the access permissions on the database file are
944
+ * such that the file cannot be opened."
945
+ */
946
+
947
+ /*
948
+ * Document-class: SQLite::Exceptions::AbortException
949
+ *
950
+ * From the SQLite documentation:
951
+ *
952
+ * "This value is returned if the callback function returns non-zero."
953
+ */
954
+
955
+ /*
956
+ * Document-class: SQLite::Exceptions::BusyException
957
+ *
958
+ * From the SQLite documentation:
959
+ *
960
+ * "This return code indicates that another program or thread has the database
961
+ * locked. SQLite allows two or more threads to read the database at the same
962
+ * time, but only one thread can have the database open for writing at the same
963
+ * time. Locking in SQLite is on the entire database."
964
+ */
965
+
966
+ /*
967
+ * Document-class: SQLite::Exceptions::LockedException
968
+ *
969
+ * From the SQLite documentation:
970
+ *
971
+ * "This return code is similar to SQLITE_BUSY in that it indicates that the
972
+ * database is locked. But the source of the lock is a recursive call to
973
+ * sqlite_exec. This return can only occur if you attempt to invoke sqlite_exec
974
+ * from within a callback routine of a query from a prior invocation of
975
+ * sqlite_exec. Recursive calls to sqlite_exec are allowed as long as they do
976
+ * not attempt to write the same table."
977
+ */
978
+
979
+ /*
980
+ * Document-class: SQLite::Exceptions::OutOfMemoryException
981
+ *
982
+ * From the SQLite documentation:
983
+ *
984
+ * "This value is returned if a call to malloc fails."
985
+ */
986
+
987
+ /*
988
+ * Document-class: SQLite::Exceptions::ReadOnlyException
989
+ *
990
+ * From the SQLite documentation:
991
+ *
992
+ * "This return code indicates that an attempt was made to write to a database
993
+ * file that is opened for reading only."
994
+ */
995
+
996
+ /*
997
+ * Document-class: SQLite::Exceptions::InterruptException
998
+ *
999
+ * From the SQLite documentation:
1000
+ *
1001
+ * "This value is returned if a call to sqlite_interrupt interrupts a database
1002
+ * operation in progress."
1003
+ */
1004
+
1005
+ /*
1006
+ * Document-class: SQLite::Exceptions::IOErrorException
1007
+ *
1008
+ * From the SQLite documentation:
1009
+ *
1010
+ * "This value is returned if the operating system informs SQLite that it is
1011
+ * unable to perform some disk I/O operation. This could mean that there is no
1012
+ * more space left on the disk."
1013
+ */
1014
+
1015
+ /*
1016
+ * Document-class: SQLite::Exceptions::CorruptException
1017
+ *
1018
+ * From the SQLite documentation:
1019
+ *
1020
+ * "This value is returned if SQLite detects that the database it is working on
1021
+ * has become corrupted. Corruption might occur due to a rogue process writing
1022
+ * to the database file or it might happen due to an perviously (sic) undetected
1023
+ * logic error in of SQLite. This value is also returned if a disk I/O error
1024
+ * occurs in such a way that SQLite is forced to leave the database file in a
1025
+ * corrupted state. The latter should only happen due to a hardware or operating
1026
+ * system malfunction."
1027
+ */
1028
+
1029
+ /*
1030
+ * Document-class: SQLite::Exceptions::NotFoundException
1031
+ *
1032
+ * From the SQLite documentation:
1033
+ *
1034
+ * "(Internal Only) Table or record not found."
1035
+ */
1036
+
1037
+ /*
1038
+ * Document-class: SQLite::Exceptions::FullException
1039
+ *
1040
+ * From the SQLite documentation:
1041
+ *
1042
+ * "This value is returned if an insertion failed because there is no space
1043
+ * left on the disk, or the database is too big to hold any more information.
1044
+ * The latter case should only occur for databases that are larger than 2GB in
1045
+ * size."
1046
+ */
1047
+
1048
+ /*
1049
+ * Document-class: SQLite::Exceptions::CantOpenException
1050
+ *
1051
+ * From the SQLite documentation:
1052
+ *
1053
+ * "This value is returned if the database file could not be opened for some
1054
+ * reason."
1055
+ */
1056
+
1057
+ /*
1058
+ * Document-class: SQLite::Exceptions::ProtocolException
1059
+ *
1060
+ * From the SQLite documentation:
1061
+ *
1062
+ * "This value is returned if some other process is messing with file locks and
1063
+ * has violated the file locking protocol that SQLite uses on its rollback
1064
+ * journal files."
1065
+ */
1066
+
1067
+ /*
1068
+ * Document-class: SQLite::Exceptions::EmptyException
1069
+ *
1070
+ * From the SQLite documentation:
1071
+ *
1072
+ * "(Internal Only) Database table is empty"
1073
+ */
1074
+
1075
+ /*
1076
+ * Document-class: SQLite::Exceptions::SchemaChangedException
1077
+ *
1078
+ * From the SQLite documentation:
1079
+ *
1080
+ * "When the database first opened, SQLite reads the database schema into
1081
+ * memory and uses that schema to parse new SQL statements. If another process
1082
+ * changes the schema, the command currently being processed will abort because
1083
+ * the virtual machine code generated assumed the old schema. This is the
1084
+ * return code for such cases. Retrying the command usually will clear the
1085
+ * problem."
1086
+ */
1087
+
1088
+ /*
1089
+ * Document-class: SQLite::Exceptions::TooBigException
1090
+ *
1091
+ * From the SQLite documentation:
1092
+ *
1093
+ * "SQLite will not store more than about 1 megabyte of data in a single row of
1094
+ * a single table. If you attempt to store more than 1 megabyte in a single
1095
+ * row, this is the return code you get."
1096
+ */
1097
+
1098
+ /*
1099
+ * Document-class: SQLite::Exceptions::ConstraintException
1100
+ *
1101
+ * From the SQLite documentation:
1102
+ *
1103
+ * "This constant is returned if the SQL statement would have violated a
1104
+ * database constraint."
1105
+ */
1106
+
1107
+ /*
1108
+ * Document-class: SQLite::Exceptions::MismatchException
1109
+ *
1110
+ * From the SQLite documentation:
1111
+ *
1112
+ * "This error occurs when there is an attempt to insert non-integer data into
1113
+ * a column labeled INTEGER PRIMARY KEY. For most columns, SQLite ignores the
1114
+ * data type and allows any kind of data to be stored. But an INTEGER PRIMARY
1115
+ * KEY column is only allowed to store integer data."
1116
+ */
1117
+
1118
+ /*
1119
+ * Document-class: SQLite::Exceptions::MisuseException
1120
+ *
1121
+ * From the SQLite documentation:
1122
+ *
1123
+ * "This error might occur if one or more of the SQLite API routines is used
1124
+ * incorrectly. Examples of incorrect usage include calling sqlite_exec after
1125
+ * the database has been closed using sqlite_close or calling sqlite_exec with
1126
+ * the same database pointer simultaneously from two separate threads."
1127
+ */
1128
+
1129
+ /*
1130
+ * Document-class: SQLite::Exceptions::UnsupportedOSFeatureException
1131
+ *
1132
+ * From the SQLite documentation:
1133
+ *
1134
+ * "This error means that you have attempts to create or access a file
1135
+ * database file that is larger that 2GB on a legacy Unix machine that
1136
+ * lacks large file support."
1137
+ */
1138
+
1139
+ /*
1140
+ * Document-class: SQLite::Exceptions::AuthorizationException
1141
+ *
1142
+ * From the SQLite documentation:
1143
+ *
1144
+ * "This error indicates that the authorizer callback has disallowed the SQL
1145
+ * you are attempting to execute."
1146
+ */
1147
+
1148
+ /*
1149
+ * Document-class: SQLite::Exceptions::FormatException
1150
+ *
1151
+ * From the SQLite documentation:
1152
+ *
1153
+ * "Auxiliary database format error"
1154
+ */
1155
+
1156
+ /*
1157
+ * Document-class: SQLite::Exceptions::RangeException
1158
+ *
1159
+ * From the SQLite documentation:
1160
+ *
1161
+ * "2nd parameter to sqlite_bind out of range"
1162
+ */
1163
+
1164
+ /*
1165
+ * Document-class: SQLite::Exceptions::NotADatabaseException
1166
+ *
1167
+ * From the SQLite documentation:
1168
+ *
1169
+ * "File opened that is not a database file"
1170
+ */
1171
+
1172
+ static void
1173
+ static_configure_exception_classes()
1174
+ {
1175
+ int i;
1176
+
1177
+ for( i = 1; g_sqlite_exceptions[ i ].name != NULL; i++ )
1178
+ {
1179
+ char name[ 128 ];
1180
+
1181
+ sprintf( name, "%sException", g_sqlite_exceptions[ i ].name );
1182
+ g_sqlite_exceptions[ i ].object = rb_define_class_under( mExceptions, name, DatabaseException );
1183
+ }
1184
+ }
1185
+
1186
+ static void
1187
+ static_raise_db_error( int code, char *msg, ... )
1188
+ {
1189
+ va_list args;
1190
+ char message[ 2048 ];
1191
+ VALUE exc;
1192
+
1193
+ va_start( args, msg );
1194
+ vsnprintf( message, sizeof( message ), msg, args );
1195
+ va_end( args );
1196
+
1197
+ exc = ( code <= 0 ? DatabaseException : g_sqlite_exceptions[ code ].object );
1198
+
1199
+ rb_raise( exc, message );
1200
+ }
1201
+
1202
+ static void
1203
+ static_raise_db_error2( int code, char **msg )
1204
+ {
1205
+ VALUE err = rb_str_new2( *msg ? *msg : "(no message)" );
1206
+ if( *msg ) free( *msg );
1207
+ *msg = NULL;
1208
+
1209
+ static_raise_db_error( code, "%s", STR2CSTR( err ) );
1210
+ }
1211
+
1212
+ static void
1213
+ static_free_vm( sqlite_vm *vm )
1214
+ {
1215
+ /* FIXME: can sqlite_finalize be called with a second parameter of NULL? */
1216
+ sqlite_finalize( vm, NULL );
1217
+ }
1218
+
1219
+ static int
1220
+ static_busy_handler( void* cookie, const char *entity, int times )
1221
+ {
1222
+ VALUE handler = (VALUE)cookie;
1223
+ VALUE result;
1224
+
1225
+ result = rb_funcall( handler, idCall, 2, rb_str_new2( entity ),
1226
+ INT2FIX( times ) );
1227
+
1228
+ if( result == Qnil || result == Qfalse )
1229
+ return 0;
1230
+
1231
+ return 1;
1232
+ }
1233
+
1234
+ static int
1235
+ static_progress_handler( void* cookie )
1236
+ {
1237
+ VALUE handler = (VALUE)cookie;
1238
+ VALUE result;
1239
+
1240
+ result = rb_funcall( handler, idCall, 0 );
1241
+
1242
+ if( result == Qnil || result == Qfalse )
1243
+ return 0;
1244
+
1245
+ return 1;
1246
+ }
1247
+
1248
+ static int
1249
+ static_commit_hook( void* cookie )
1250
+ {
1251
+ VALUE handler = (VALUE)cookie;
1252
+ VALUE result;
1253
+
1254
+ result = rb_funcall( handler, idCall, 0 );
1255
+
1256
+ if( result == Qnil || result == Qfalse )
1257
+ return 0;
1258
+
1259
+ return 1;
1260
+ }
1261
+
1262
+ static VALUE
1263
+ static_protected_function_callback( VALUE args )
1264
+ {
1265
+ VALUE proc;
1266
+ VALUE proc_args;
1267
+
1268
+ proc = rb_ary_entry( args, 0 );
1269
+ proc_args = rb_ary_entry( args, 1 );
1270
+
1271
+ rb_apply( proc, idCall, proc_args );
1272
+
1273
+ return Qnil;
1274
+ }
1275
+
1276
+ static void
1277
+ static_function_callback( sqlite_func *func, int argc, const char **argv )
1278
+ {
1279
+ VALUE proc;
1280
+ VALUE args;
1281
+ VALUE protect_args;
1282
+ int index;
1283
+ int exception = 0;
1284
+
1285
+ proc = (VALUE)sqlite_user_data( func );
1286
+ if( TYPE(proc) == T_ARRAY )
1287
+ proc = rb_ary_entry( proc, 0 );
1288
+
1289
+ args = rb_ary_new2( argc + 1 );
1290
+ rb_ary_push( args, Data_Wrap_Struct( rb_cData, NULL, NULL, func ) );
1291
+
1292
+ for( index = 0; index < argc; index++ )
1293
+ {
1294
+ VALUE entry = Qnil;
1295
+
1296
+ if( argv[index] )
1297
+ entry = rb_str_new2( argv[index] );
1298
+
1299
+ rb_ary_push( args, entry );
1300
+ }
1301
+
1302
+ protect_args = rb_ary_new3( 2, proc, args );
1303
+ rb_protect( static_protected_function_callback,
1304
+ protect_args,
1305
+ &exception );
1306
+
1307
+ if( exception )
1308
+ {
1309
+ sqlite_set_result_error( func, "error occurred while processing function", -1 );
1310
+ }
1311
+ }
1312
+
1313
+ static void
1314
+ static_aggregate_finalize_callback( sqlite_func *func )
1315
+ {
1316
+ VALUE proc;
1317
+ VALUE args;
1318
+ VALUE protect_args;
1319
+ int exception = 0;
1320
+
1321
+ proc = rb_ary_entry( (VALUE)sqlite_user_data( func ), 1 );
1322
+ args = rb_ary_new3( 1, Data_Wrap_Struct( rb_cData, NULL, NULL, func ) );
1323
+
1324
+ protect_args = rb_ary_new3( 2, proc, args );
1325
+
1326
+ rb_protect( static_protected_function_callback,
1327
+ protect_args,
1328
+ &exception );
1329
+
1330
+ if( exception )
1331
+ {
1332
+ sqlite_set_result_error( func, "error occurred while processing aggregate finalize", -1 );
1333
+ }
1334
+ }
1335
+
1336
+ /*>=-----------------------------------------------------------------------=<*
1337
+ * MODULE INITIALIZATION
1338
+ * ------------------------------------------------------------------------
1339
+ * This is the "main" function for a Ruby extension. When Ruby loads the
1340
+ * extension, it will invoke this method to set things up. For this
1341
+ * extension, it defines the SQLite and SQLite::API modules, and then
1342
+ * declares the API method hooks.
1343
+ *>=-----------------------------------------------------------------------=<*/
1344
+ NO_RDOC
1345
+
1346
+ /**
1347
+ * Document-class: SQLite::API
1348
+ *
1349
+ * This is a one-to-one bridge between Ruby code and the C interface for SQLite.
1350
+ * It defines (more-or-less) one method per function (with #set_result being
1351
+ * one exception). It is generally not advisable to use these methods directly;
1352
+ * instead, you should use the SQLite::Database class and related interfaces,
1353
+ * which provide a more object-oriented view of this interface.
1354
+ */
1355
+ void Init_sqlite_api()
1356
+ {
1357
+ VALUE version;
1358
+
1359
+ idRow = rb_intern( "row" );
1360
+ idColumns = rb_intern( "columns" );
1361
+ idTypes = rb_intern( "types" );
1362
+ idCall = rb_intern( "call" );
1363
+
1364
+ mSQLite = rb_define_module( "SQLite" );
1365
+ mExceptions = rb_define_module_under( mSQLite, "Exceptions" );
1366
+
1367
+ DatabaseException = rb_define_class_under( mExceptions, "DatabaseException",
1368
+ rb_eStandardError );
1369
+
1370
+ static_configure_exception_classes();
1371
+
1372
+ mAPI = rb_define_module_under( mSQLite, "API" );
1373
+
1374
+ rb_define_const( mAPI, "VERSION", rb_str_new2( sqlite_libversion() ) );
1375
+ rb_define_const( mAPI, "ENCODING", rb_str_new2( sqlite_libencoding() ) );
1376
+ rb_define_const( mAPI, "NUMERIC", INT2FIX( SQLITE_NUMERIC ) );
1377
+ rb_define_const( mAPI, "TEXT", INT2FIX( SQLITE_TEXT ) );
1378
+ rb_define_const( mAPI, "ARGS", INT2FIX( SQLITE_ARGS ) );
1379
+
1380
+ rb_define_module_function( mAPI, "open", static_api_open, 2 );
1381
+ rb_define_module_function( mAPI, "close", static_api_close, 1 );
1382
+
1383
+ rb_define_module_function( mAPI, "compile", static_api_compile, 2 );
1384
+ rb_define_module_function( mAPI, "step", static_api_step, 1 );
1385
+ rb_define_module_function( mAPI, "finalize", static_api_finalize, 1 );
1386
+
1387
+ rb_define_module_function( mAPI, "last_insert_row_id",
1388
+ static_api_last_insert_row_id, 1 );
1389
+ rb_define_module_function( mAPI, "changes", static_api_changes, 1 );
1390
+
1391
+ rb_define_module_function( mAPI, "interrupt", static_api_interrupt, 1 );
1392
+
1393
+ rb_define_module_function( mAPI, "complete", static_api_complete, 1 );
1394
+
1395
+ rb_define_module_function( mAPI, "busy_handler", static_api_busy_handler, 2 );
1396
+ rb_define_module_function( mAPI, "busy_timeout", static_api_busy_timeout, 2 );
1397
+
1398
+ rb_define_module_function( mAPI, "create_function",
1399
+ static_api_create_function, 4 );
1400
+ rb_define_module_function( mAPI, "create_aggregate",
1401
+ static_api_create_aggregate, 5 );
1402
+ rb_define_module_function( mAPI, "function_type",
1403
+ static_api_function_type, 3 );
1404
+
1405
+ rb_define_module_function( mAPI, "set_result",
1406
+ static_api_set_result, 2 );
1407
+ rb_define_module_function( mAPI, "set_result_error",
1408
+ static_api_set_result_error, 2 );
1409
+
1410
+ rb_define_module_function( mAPI, "aggregate_context",
1411
+ static_api_aggregate_context, 1 );
1412
+ rb_define_module_function( mAPI, "aggregate_count",
1413
+ static_api_aggregate_count, 1 );
1414
+ }