amalgalite 0.4.2-x86-mswin32-60

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 (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
+