amalgalite 0.4.2-x86-mswin32-60

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/HISTORY +81 -0
  2. data/LICENSE +29 -0
  3. data/README +40 -0
  4. data/bin/amalgalite-pack-into-db +155 -0
  5. data/examples/a.rb +9 -0
  6. data/examples/blob.rb +105 -0
  7. data/examples/bootstrap.rb +36 -0
  8. data/examples/gem-db.rb +94 -0
  9. data/examples/requires.rb +54 -0
  10. data/examples/schema-info.rb +34 -0
  11. data/ext/amalgalite3.c +201 -0
  12. data/ext/amalgalite3.h +121 -0
  13. data/ext/amalgalite3_blob.c +241 -0
  14. data/ext/amalgalite3_constants.c +221 -0
  15. data/ext/amalgalite3_database.c +550 -0
  16. data/ext/amalgalite3_requires_bootstrap.c +210 -0
  17. data/ext/amalgalite3_statement.c +628 -0
  18. data/ext/extconf.rb +19 -0
  19. data/ext/gen_constants.rb +130 -0
  20. data/ext/rbconfig-mingw.rb +178 -0
  21. data/ext/sqlite3.c +97092 -0
  22. data/ext/sqlite3.h +6364 -0
  23. data/ext/sqlite3_options.h +4 -0
  24. data/ext/sqlite3ext.h +372 -0
  25. data/gemspec.rb +55 -0
  26. data/lib/amalgalite.rb +33 -0
  27. data/lib/amalgalite/blob.rb +186 -0
  28. data/lib/amalgalite/boolean.rb +42 -0
  29. data/lib/amalgalite/column.rb +86 -0
  30. data/lib/amalgalite/core_ext/kernel/require.rb +14 -0
  31. data/lib/amalgalite/database.rb +514 -0
  32. data/lib/amalgalite/index.rb +43 -0
  33. data/lib/amalgalite/paths.rb +70 -0
  34. data/lib/amalgalite/profile_tap.rb +130 -0
  35. data/lib/amalgalite/requires.rb +112 -0
  36. data/lib/amalgalite/schema.rb +115 -0
  37. data/lib/amalgalite/sqlite3.rb +6 -0
  38. data/lib/amalgalite/sqlite3/constants.rb +82 -0
  39. data/lib/amalgalite/sqlite3/database/status.rb +69 -0
  40. data/lib/amalgalite/sqlite3/status.rb +61 -0
  41. data/lib/amalgalite/sqlite3/version.rb +38 -0
  42. data/lib/amalgalite/statement.rb +394 -0
  43. data/lib/amalgalite/table.rb +36 -0
  44. data/lib/amalgalite/taps.rb +2 -0
  45. data/lib/amalgalite/taps/console.rb +27 -0
  46. data/lib/amalgalite/taps/io.rb +71 -0
  47. data/lib/amalgalite/trace_tap.rb +35 -0
  48. data/lib/amalgalite/type_map.rb +63 -0
  49. data/lib/amalgalite/type_maps/default_map.rb +167 -0
  50. data/lib/amalgalite/type_maps/storage_map.rb +41 -0
  51. data/lib/amalgalite/type_maps/text_map.rb +23 -0
  52. data/lib/amalgalite/version.rb +37 -0
  53. data/lib/amalgalite/view.rb +26 -0
  54. data/lib/amalgalite3.so +0 -0
  55. data/spec/amalgalite_spec.rb +4 -0
  56. data/spec/blob_spec.rb +81 -0
  57. data/spec/boolean_spec.rb +23 -0
  58. data/spec/database_spec.rb +238 -0
  59. data/spec/default_map_spec.rb +87 -0
  60. data/spec/integeration_spec.rb +111 -0
  61. data/spec/paths_spec.rb +28 -0
  62. data/spec/schema_spec.rb +60 -0
  63. data/spec/spec_helper.rb +25 -0
  64. data/spec/sqlite3/constants_spec.rb +65 -0
  65. data/spec/sqlite3/database_status_spec.rb +36 -0
  66. data/spec/sqlite3/status_spec.rb +18 -0
  67. data/spec/sqlite3/version_spec.rb +14 -0
  68. data/spec/sqlite3_spec.rb +23 -0
  69. data/spec/statement_spec.rb +134 -0
  70. data/spec/storage_map_spec.rb +41 -0
  71. data/spec/tap_spec.rb +59 -0
  72. data/spec/text_map_spec.rb +23 -0
  73. data/spec/type_map_spec.rb +17 -0
  74. data/spec/version_spec.rb +9 -0
  75. data/tasks/announce.rake +39 -0
  76. data/tasks/config.rb +110 -0
  77. data/tasks/distribution.rake +53 -0
  78. data/tasks/documentation.rake +33 -0
  79. data/tasks/extension.rake +100 -0
  80. data/tasks/rspec.rake +32 -0
  81. data/tasks/rubyforge.rake +59 -0
  82. data/tasks/utils.rb +80 -0
  83. metadata +192 -0
@@ -0,0 +1,550 @@
1
+ #include "amalgalite3.h"
2
+ /**
3
+ * Copyright (c) 2008 Jeremy Hinegardner
4
+ * All rights reserved. See LICENSE and/or COPYING for details.
5
+ *
6
+ * vim: shiftwidth=4
7
+ */
8
+
9
+ VALUE cAS_Database; /* class Amalgliate::SQLite3::Database */
10
+ VALUE cAS_Database_Stat; /* class Amalgliate::SQLite3::Database::Stat */
11
+
12
+ /**
13
+ * Document-method: open
14
+ *
15
+ * call-seq:
16
+ * Amalagliate::SQLite3::Database.open( filename, flags = READWRITE | CREATE ) -> Database
17
+ *
18
+ * Create a new SQLite3 database with a UTF-8 encoding.
19
+ *
20
+ */
21
+ VALUE am_sqlite3_database_open(int argc, VALUE *argv, VALUE class)
22
+ {
23
+ VALUE self = am_sqlite3_database_alloc(class);
24
+ VALUE rFlags;
25
+ VALUE rFilename;
26
+ int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
27
+ char* filename;
28
+ int rc;
29
+ am_sqlite3* am_db;
30
+
31
+
32
+ /* at least a filename argument is required */
33
+ rb_scan_args( argc, argv, "11", &rFilename, &rFlags );
34
+
35
+ /* convert flags to the sqlite version */
36
+ flags = ( Qnil == rFlags ) ? flags : FIX2INT(rFlags);
37
+ filename = StringValuePtr(rFilename);
38
+
39
+ /* extract the sqlite3 wrapper struct */
40
+ Data_Get_Struct(self, am_sqlite3, am_db);
41
+
42
+ /* open the sqlite3 database */
43
+ rc = sqlite3_open_v2( filename, &(am_db->db), flags, 0);
44
+ if ( SQLITE_OK != rc ) {
45
+ rb_raise(eAS_Error, "Failure to open database %s : [SQLITE_ERROR %d] : %s\n",
46
+ filename, rc, sqlite3_errmsg(am_db->db));
47
+ }
48
+
49
+ /* by default turn on the extended result codes */
50
+ rc = sqlite3_extended_result_codes( am_db->db, 1);
51
+ if ( SQLITE_OK != rc ) {
52
+ rb_raise(eAS_Error, "Failure to set extended result codes %s : [SQLITE_ERROR %d] : %s\n",
53
+ filename, rc, sqlite3_errmsg(am_db->db));
54
+ }
55
+
56
+ return self;
57
+ }
58
+
59
+ /**
60
+ * call-seq:
61
+ * Amalgalite::SQLite3::Database.open16( filename ) -> SQLite3::Database
62
+ *
63
+ * Create a new SQLite3 database with a UTF-16 encoding
64
+ *
65
+ */
66
+ VALUE am_sqlite3_database_open16(VALUE class, VALUE rFilename)
67
+ {
68
+ VALUE self = am_sqlite3_database_alloc(class);
69
+ char* filename = StringValuePtr(rFilename);
70
+ am_sqlite3* am_db;
71
+ int rc;
72
+
73
+ Data_Get_Struct(self, am_sqlite3, am_db);
74
+ rc = sqlite3_open16( filename, &(am_db->db) );
75
+ if ( SQLITE_OK != rc ) {
76
+ rb_raise(eAS_Error, "Failure to open UTF-16 database %s : [SQLITE_ERROR %d] : %s\n",
77
+ filename, rc, sqlite3_errmsg( am_db->db ));
78
+ }
79
+
80
+ /* by default turn on the extended result codes */
81
+ rc = sqlite3_extended_result_codes( am_db->db, 1);
82
+ if ( SQLITE_OK != rc ) {
83
+ rb_raise(eAS_Error, "Failure to set extended result codes on UTF-16 database %s : [SQLITE_ERROR %d] : %s\n",
84
+ filename, rc, sqlite3_errmsg16(am_db->db));
85
+ }
86
+
87
+ return self;
88
+ }
89
+
90
+ /**
91
+ * call-seq:
92
+ * database.close
93
+ *
94
+ * Close the database
95
+ */
96
+ VALUE am_sqlite3_database_close(VALUE self)
97
+ {
98
+ am_sqlite3 *am_db;
99
+ int rc = 0;
100
+
101
+ Data_Get_Struct(self, am_sqlite3, am_db);
102
+ rc = sqlite3_close( am_db->db );
103
+ if ( SQLITE_OK != rc ) {
104
+ rb_raise(eAS_Error, "Failure to close database : [SQLITE_ERROR %d] : %s\n",
105
+ rc, sqlite3_errmsg( am_db->db ));
106
+ }
107
+
108
+ return self;
109
+
110
+ }
111
+
112
+ /**
113
+ * call-seq:
114
+ * database.last_insert_rowid -> Integer
115
+ *
116
+ * Return the rowid of the last row inserted into the database from this
117
+ * database connection.
118
+ */
119
+ VALUE am_sqlite3_database_last_insert_rowid(VALUE self)
120
+ {
121
+ am_sqlite3 *am_db;
122
+ sqlite3_int64 last_id;
123
+
124
+ Data_Get_Struct(self, am_sqlite3, am_db);
125
+ last_id = sqlite3_last_insert_rowid( am_db->db );
126
+
127
+ return SQLINT64_2NUM( last_id );
128
+ }
129
+
130
+ /**
131
+ * call-seq:
132
+ * database.autocommit? -> true or false
133
+ *
134
+ * return true if the database is in autocommit mode, otherwise return false
135
+ *
136
+ */
137
+ VALUE am_sqlite3_database_is_autocommit(VALUE self)
138
+ {
139
+ am_sqlite3 *am_db;
140
+ int rc;
141
+
142
+ Data_Get_Struct(self, am_sqlite3, am_db);
143
+ rc = sqlite3_get_autocommit( am_db->db );
144
+
145
+ return ( 0 == rc ) ? Qfalse : Qtrue ;
146
+ }
147
+
148
+ /**
149
+ * call-seq:
150
+ * database.row_changes -> Integer
151
+ *
152
+ * return the number of rows changed with the most recent INSERT, UPDATE or
153
+ * DELETE statement.
154
+ *
155
+ */
156
+ VALUE am_sqlite3_database_row_changes(VALUE self)
157
+ {
158
+ am_sqlite3 *am_db;
159
+ int rc;
160
+
161
+ Data_Get_Struct(self, am_sqlite3, am_db);
162
+ rc = sqlite3_changes( am_db->db );
163
+
164
+ return INT2FIX(rc);
165
+ }
166
+
167
+ /**
168
+ * call-seq:
169
+ * database.last_error_code -> Integer
170
+ *
171
+ * return the last error code that happened in the database
172
+ *
173
+ */
174
+ VALUE am_sqlite3_database_last_error_code(VALUE self)
175
+ {
176
+ am_sqlite3 *am_db;
177
+ int code;
178
+
179
+ Data_Get_Struct(self, am_sqlite3, am_db);
180
+ code = sqlite3_errcode( am_db->db );
181
+
182
+ return INT2FIX( code );
183
+ }
184
+
185
+ /**
186
+ * call-seq:
187
+ * database.last_error_message -> String
188
+ *
189
+ * return the last error message that happened in the database
190
+ *
191
+ */
192
+ VALUE am_sqlite3_database_last_error_message(VALUE self)
193
+ {
194
+ am_sqlite3 *am_db;
195
+ const char *message;
196
+
197
+ Data_Get_Struct(self, am_sqlite3, am_db);
198
+ message = sqlite3_errmsg( am_db->db );
199
+
200
+ return rb_str_new2( message );
201
+ }
202
+
203
+ /**
204
+ * call-seq:
205
+ * database.total_changes -> Integer
206
+ *
207
+ * return the number of rows changed by INSERT, UPDATE or DELETE statements
208
+ * in the database connection since the connection was opened.
209
+ *
210
+ */
211
+ VALUE am_sqlite3_database_total_changes(VALUE self)
212
+ {
213
+ am_sqlite3 *am_db;
214
+ int rc;
215
+
216
+ Data_Get_Struct(self, am_sqlite3, am_db);
217
+ rc = sqlite3_total_changes( am_db->db );
218
+
219
+ return INT2FIX(rc);
220
+ }
221
+
222
+ /*
223
+ * call-seq:
224
+ * stat.update!( reset = false ) -> nil
225
+ *
226
+ * Populates the _@current_ and _@higwater_ instance variables of the given
227
+ * Database Stat object with the values from the sqlite3_db_status call.
228
+ * If reset it true then the highwater mark for the stat is reset
229
+ *
230
+ */
231
+ VALUE am_sqlite3_database_stat_update_bang( int argc, VALUE *argv, VALUE self )
232
+ {
233
+ int current = -1;
234
+ int highwater = -1;
235
+ int reset_flag = 0;
236
+ int status_op = FIX2INT( rb_iv_get( self, "@code" ) );
237
+ int rc;
238
+
239
+ am_sqlite3 *am_db;
240
+
241
+ VALUE reset = Qfalse;
242
+ VALUE db = rb_iv_get( self, "@api_db" );
243
+
244
+ Data_Get_Struct(db, am_sqlite3, am_db);
245
+
246
+ if ( argc > 0 ) {
247
+ reset = argv[0];
248
+ reset_flag = ( Qtrue == reset ) ? 1 : 0 ;
249
+ }
250
+
251
+ rc = sqlite3_db_status( am_db->db, status_op, &current, &highwater, reset_flag );
252
+
253
+ if ( SQLITE_OK != rc ) {
254
+ VALUE n = rb_iv_get( self, "@name");
255
+ char* name = StringValuePtr( n );
256
+ rb_raise(eAS_Error, "Failure to retrieve database status for %s : [SQLITE_ERROR %d] \n", name, rc);
257
+ }
258
+
259
+ rb_iv_set( self, "@current", INT2NUM( current ) );
260
+ rb_iv_set( self, "@highwater", INT2NUM( highwater) );
261
+
262
+ return Qnil;
263
+ }
264
+
265
+
266
+
267
+ /**
268
+ * call-seq:
269
+ * database.prepare( sql ) -> SQLite3::Statement
270
+ *
271
+ * Create a new SQLite3 statement.
272
+ */
273
+ VALUE am_sqlite3_database_prepare(VALUE self, VALUE rSQL)
274
+ {
275
+ VALUE sql = StringValue( rSQL );
276
+ VALUE stmt = am_sqlite3_statement_alloc(cAS_Statement);
277
+ am_sqlite3 *am_db;
278
+ am_sqlite3_stmt *am_stmt;
279
+ const char *tail;
280
+ int rc;
281
+
282
+ Data_Get_Struct(self, am_sqlite3, am_db);
283
+
284
+ Data_Get_Struct(stmt, am_sqlite3_stmt, am_stmt);
285
+ rc = sqlite3_prepare_v2( am_db->db, RSTRING(sql)->ptr, RSTRING(sql)->len,
286
+ &(am_stmt->stmt), &tail);
287
+ if ( SQLITE_OK != rc) {
288
+ rb_raise(eAS_Error, "Failure to prepare statement %s : [SQLITE_ERROR %d] : %s\n",
289
+ RSTRING(sql)->ptr, rc, sqlite3_errmsg(am_db->db));
290
+ am_sqlite3_statement_free( am_stmt );
291
+ }
292
+
293
+ if ( tail != NULL ) {
294
+ am_stmt->remaining_sql = rb_str_new2( tail );
295
+ rb_gc_register_address( &(am_stmt->remaining_sql) );
296
+ } else {
297
+ am_stmt->remaining_sql = Qnil;
298
+ }
299
+
300
+ return stmt;
301
+ }
302
+
303
+ /**
304
+ * This function is registered with a sqlite3 database using the sqlite3_trace
305
+ * function. During the registration process a handle on a VALUE is also
306
+ * registered.
307
+ *
308
+ * When this function is called, it calls the 'trace' method on the tap object,
309
+ * which is the VALUE that was registered during the sqlite3_trace call.
310
+ *
311
+ * This function corresponds to the SQLite xTrace function specification.
312
+ *
313
+ */
314
+ void amalgalite_xTrace(void* tap, const char* msg)
315
+ {
316
+ VALUE trace_obj = (VALUE) tap;
317
+
318
+ rb_funcall( trace_obj, rb_intern("trace"), 1, rb_str_new2( msg ) );
319
+ return;
320
+ }
321
+
322
+
323
+ /**
324
+ * call-seq:
325
+ * database.register_trace_tap( tap_obj )
326
+ *
327
+ * This registers an object to be called with every trace event in SQLite.
328
+ *
329
+ * This is an experimental api and is subject to change, or removal.
330
+ *
331
+ */
332
+ VALUE am_sqlite3_database_register_trace_tap(VALUE self, VALUE tap)
333
+ {
334
+ am_sqlite3 *am_db;
335
+ int rc;
336
+
337
+ Data_Get_Struct(self, am_sqlite3, am_db);
338
+
339
+ /* Qnil, unregister the item and tell the garbage collector we are done with
340
+ * it.
341
+ */
342
+ if ( Qnil == tap ) {
343
+
344
+ sqlite3_trace( am_db->db, NULL, NULL );
345
+ rb_gc_unregister_address( &(am_db->trace_obj) );
346
+ am_db->trace_obj = Qnil;
347
+
348
+ /* register the item and store the reference to the object in the am_db
349
+ * structure. We also have to tell the Ruby garbage collector that we
350
+ * point to the Ruby object from C.
351
+ */
352
+ } else {
353
+
354
+ am_db->trace_obj = tap;
355
+ rb_gc_register_address( &(am_db->trace_obj) );
356
+ sqlite3_trace( am_db->db, amalgalite_xTrace, (void *)am_db->trace_obj );
357
+ }
358
+
359
+ return Qnil;
360
+ }
361
+
362
+ /**
363
+ * the amagliate trace function to be registered with register_trace_tap
364
+ * When it is called, it calls the 'trace' method on the tap object.
365
+ *
366
+ * This function conforms to the sqlite3 xProfile function specification.
367
+ */
368
+ void amalgalite_xProfile(void* tap, const char* msg, sqlite3_uint64 time)
369
+ {
370
+ VALUE trace_obj = (VALUE) tap;
371
+
372
+ rb_funcall( trace_obj, rb_intern("profile"),
373
+ 2, rb_str_new2( msg ), SQLUINT64_2NUM(time) );
374
+
375
+ return;
376
+ }
377
+
378
+ /**
379
+ * call-seq:
380
+ * database.register_profile_tap( tap_obj )
381
+ *
382
+ * This registers an object to be called with every profile event in SQLite.
383
+ *
384
+ * This is an experimental api and is subject to change or removal.
385
+ *
386
+ */
387
+ VALUE am_sqlite3_database_register_profile_tap(VALUE self, VALUE tap)
388
+ {
389
+ am_sqlite3 *am_db;
390
+ int rc;
391
+
392
+ Data_Get_Struct(self, am_sqlite3, am_db);
393
+
394
+ /* Qnil, unregister the item and tell the garbage collector we are done with
395
+ * it.
396
+ */
397
+
398
+ if ( tap == Qnil ) {
399
+ sqlite3_profile( am_db->db, NULL, NULL );
400
+ rb_gc_unregister_address( &(am_db->profile_obj) );
401
+ am_db->profile_obj = Qnil;
402
+
403
+ /* register the item and store the reference to the object in the am_db
404
+ * structure. We also have to tell the Ruby garbage collector that we
405
+ * point to the Ruby object from C.
406
+ */
407
+ } else {
408
+ am_db->profile_obj = tap;
409
+ rb_gc_register_address( &(am_db->profile_obj) );
410
+ sqlite3_profile( am_db->db, amalgalite_xProfile, (void *)am_db->profile_obj );
411
+ }
412
+ return Qnil;
413
+ }
414
+
415
+ /**
416
+ * call-seq:
417
+ * datatabase.table_column_metadata( db_name, table_name, column_name) -> Hash
418
+ *
419
+ * Returns a hash containing the meta information about the column. The
420
+ * available keys are:
421
+ *
422
+ * declared_data_type:: the declared data type of the column
423
+ * collation_sequence_name:: the name of the collation sequence for the column
424
+ * not_null_constraint:: True if the column has a NOT NULL constraint
425
+ * primary_key:: True if the column is part of a primary key
426
+ * auto_increment:: True if the column is AUTO INCREMENT
427
+ *
428
+ */
429
+ VALUE am_sqlite3_database_table_column_metadata(VALUE self, VALUE db_name, VALUE tbl_name, VALUE col_name)
430
+ {
431
+ am_sqlite3 *am_db;
432
+ int rc;
433
+
434
+ /* input */
435
+ const char *zDbName = StringValuePtr( db_name );
436
+ const char *zTableName = StringValuePtr( tbl_name );
437
+ const char *zColumnName = StringValuePtr( col_name );
438
+
439
+ /* output */
440
+ const char *pzDataType = NULL;
441
+ const char *pzCollSeq = NULL;
442
+ int pNotNull, pPrimaryKey, pAutoinc;
443
+ VALUE rHash = rb_hash_new();
444
+ VALUE rStr = Qnil;
445
+
446
+ Data_Get_Struct(self, am_sqlite3, am_db);
447
+
448
+ rc = sqlite3_table_column_metadata( am_db->db,
449
+ zDbName, zTableName, zColumnName,
450
+ &pzDataType, &pzCollSeq,
451
+ &pNotNull, &pPrimaryKey, &pAutoinc);
452
+ if ( SQLITE_OK != rc ) {
453
+ rb_raise(eAS_Error, "Failure retrieveing column meta data for table '%s' column '%s' : [SQLITE_ERROR %d] : %s\n",
454
+ zTableName, zColumnName, rc, sqlite3_errmsg( am_db-> db ));
455
+
456
+ }
457
+
458
+ rStr = ( NULL == pzDataType) ? Qnil : rb_str_new2( pzDataType );
459
+ rb_hash_aset( rHash, rb_str_new2("declared_data_type"), rStr );
460
+
461
+ rStr = ( NULL == pzCollSeq) ? Qnil : rb_str_new2( pzCollSeq );
462
+ rb_hash_aset( rHash, rb_str_new2("collation_sequence_name"), rStr );
463
+
464
+ rb_hash_aset( rHash, rb_str_new2("not_null_constraint"), ( pNotNull ? Qtrue : Qfalse ));
465
+ rb_hash_aset( rHash, rb_str_new2("primary_key"), ( pPrimaryKey ? Qtrue : Qfalse ));
466
+ rb_hash_aset( rHash, rb_str_new2("auto_increment"), ( pAutoinc ? Qtrue : Qfalse ));
467
+
468
+ return rHash;
469
+ }
470
+
471
+ /***********************************************************************
472
+ * Ruby life cycle methods
473
+ ***********************************************************************/
474
+
475
+
476
+ /*
477
+ * garbage collector free method for the am_data structure. Make sure to un
478
+ * registere the trace and profile objects if they are not Qnil
479
+ */
480
+ void am_sqlite3_database_free(am_sqlite3* am_db)
481
+ {
482
+ if ( Qnil != am_db->trace_obj ) {
483
+ rb_gc_unregister_address( &(am_db->trace_obj) );
484
+ am_db->trace_obj = Qnil;
485
+ }
486
+
487
+ if ( Qnil != am_db->profile_obj) {
488
+ rb_gc_unregister_address( &(am_db->profile_obj) );
489
+ am_db->profile_obj = Qnil;
490
+ }
491
+
492
+ free(am_db);
493
+ return;
494
+ }
495
+
496
+ /*
497
+ * allocate the am_data structure
498
+ */
499
+ VALUE am_sqlite3_database_alloc(VALUE klass)
500
+ {
501
+ am_sqlite3* am_db = ALLOC(am_sqlite3);
502
+ VALUE obj ;
503
+
504
+ am_db->trace_obj = Qnil;
505
+ am_db->profile_obj = Qnil;
506
+
507
+ obj = Data_Wrap_Struct(klass, NULL, am_sqlite3_database_free, am_db);
508
+ return obj;
509
+ }
510
+
511
+ /**
512
+ * Document-class: Amalgalite::SQLite3::Database
513
+ *
514
+ * The ruby extension wrapper around the core sqlite3 database object.
515
+ *
516
+ */
517
+ void Init_amalgalite3_database( )
518
+ {
519
+
520
+ VALUE ma = rb_define_module("Amalgalite");
521
+ VALUE mas = rb_define_module_under(ma, "SQLite3");
522
+
523
+ /*
524
+ * Encapsulate an SQLite3 database
525
+ */
526
+ cAS_Database = rb_define_class_under( mas, "Database", rb_cObject);
527
+
528
+ rb_define_alloc_func(cAS_Database, am_sqlite3_database_alloc);
529
+ rb_define_singleton_method(cAS_Database, "open", am_sqlite3_database_open, -1);
530
+ rb_define_singleton_method(cAS_Database, "open16", am_sqlite3_database_open16, 1);
531
+ rb_define_method(cAS_Database, "prepare", am_sqlite3_database_prepare, 1);
532
+ rb_define_method(cAS_Database, "close", am_sqlite3_database_close, 0); /* in amalgalite3_database.c */
533
+ rb_define_method(cAS_Database, "last_insert_rowid", am_sqlite3_database_last_insert_rowid, 0); /* in amalgalite3_database.c */
534
+ rb_define_method(cAS_Database, "autocommit?", am_sqlite3_database_is_autocommit, 0); /* in amalgalite3_database.c */
535
+ rb_define_method(cAS_Database, "register_trace_tap", am_sqlite3_database_register_trace_tap, 1); /* in amalgalite3_database.c */
536
+ rb_define_method(cAS_Database, "register_profile_tap", am_sqlite3_database_register_profile_tap, 1); /* in amalgalite3_database.c */
537
+ rb_define_method(cAS_Database, "table_column_metadata", am_sqlite3_database_table_column_metadata, 3); /* in amalgalite3_database.c */
538
+ rb_define_method(cAS_Database, "row_changes", am_sqlite3_database_row_changes, 0); /* in amalgalite3_database.c */
539
+ rb_define_method(cAS_Database, "total_changes", am_sqlite3_database_total_changes, 0); /* in amalgalite3_database.c */
540
+ rb_define_method(cAS_Database, "last_error_code", am_sqlite3_database_last_error_code, 0); /* in amalgalite3_database.c */
541
+ rb_define_method(cAS_Database, "last_error_message", am_sqlite3_database_last_error_message, 0); /* in amalgalite3_database.c */
542
+
543
+ /*
544
+ * Ecapuslate a SQLite3 Database stat
545
+ */
546
+ cAS_Database_Stat = rb_define_class_under( cAS_Database, "Stat", rb_cObject );
547
+ rb_define_method(cAS_Database_Stat, "update!", am_sqlite3_database_stat_update_bang, -1); /* in amalgalite3_database.c */
548
+
549
+ }
550
+