amalgalite 1.8.0-x64-mingw-ucrt

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +60 -0
  3. data/HISTORY.md +386 -0
  4. data/LICENSE +31 -0
  5. data/Manifest.txt +105 -0
  6. data/README.md +62 -0
  7. data/Rakefile +27 -0
  8. data/TODO.md +57 -0
  9. data/bin/amalgalite-pack +147 -0
  10. data/examples/a.rb +9 -0
  11. data/examples/blob.rb +88 -0
  12. data/examples/bootstrap.rb +36 -0
  13. data/examples/define_aggregate.rb +75 -0
  14. data/examples/define_function.rb +104 -0
  15. data/examples/fts5.rb +152 -0
  16. data/examples/gem-db.rb +94 -0
  17. data/examples/require_me.rb +11 -0
  18. data/examples/requires.rb +42 -0
  19. data/examples/schema-info.rb +34 -0
  20. data/ext/amalgalite/c/amalgalite.c +355 -0
  21. data/ext/amalgalite/c/amalgalite.h +151 -0
  22. data/ext/amalgalite/c/amalgalite_blob.c +240 -0
  23. data/ext/amalgalite/c/amalgalite_constants.c +1432 -0
  24. data/ext/amalgalite/c/amalgalite_database.c +1188 -0
  25. data/ext/amalgalite/c/amalgalite_requires_bootstrap.c +282 -0
  26. data/ext/amalgalite/c/amalgalite_statement.c +649 -0
  27. data/ext/amalgalite/c/extconf.rb +71 -0
  28. data/ext/amalgalite/c/gen_constants.rb +353 -0
  29. data/ext/amalgalite/c/notes.txt +134 -0
  30. data/ext/amalgalite/c/sqlite3.c +243616 -0
  31. data/ext/amalgalite/c/sqlite3.h +12894 -0
  32. data/ext/amalgalite/c/sqlite3_options.h +4 -0
  33. data/ext/amalgalite/c/sqlite3ext.h +705 -0
  34. data/lib/amalgalite/3.1/amalgalite.so +0 -0
  35. data/lib/amalgalite/aggregate.rb +73 -0
  36. data/lib/amalgalite/blob.rb +186 -0
  37. data/lib/amalgalite/boolean.rb +42 -0
  38. data/lib/amalgalite/busy_timeout.rb +47 -0
  39. data/lib/amalgalite/column.rb +99 -0
  40. data/lib/amalgalite/core_ext/kernel/require.rb +21 -0
  41. data/lib/amalgalite/csv_table_importer.rb +75 -0
  42. data/lib/amalgalite/database.rb +933 -0
  43. data/lib/amalgalite/function.rb +61 -0
  44. data/lib/amalgalite/index.rb +43 -0
  45. data/lib/amalgalite/memory_database.rb +15 -0
  46. data/lib/amalgalite/packer.rb +231 -0
  47. data/lib/amalgalite/paths.rb +80 -0
  48. data/lib/amalgalite/profile_tap.rb +131 -0
  49. data/lib/amalgalite/progress_handler.rb +21 -0
  50. data/lib/amalgalite/requires.rb +151 -0
  51. data/lib/amalgalite/schema.rb +225 -0
  52. data/lib/amalgalite/sqlite3/constants.rb +95 -0
  53. data/lib/amalgalite/sqlite3/database/function.rb +48 -0
  54. data/lib/amalgalite/sqlite3/database/status.rb +68 -0
  55. data/lib/amalgalite/sqlite3/status.rb +60 -0
  56. data/lib/amalgalite/sqlite3/version.rb +55 -0
  57. data/lib/amalgalite/sqlite3.rb +6 -0
  58. data/lib/amalgalite/statement.rb +421 -0
  59. data/lib/amalgalite/table.rb +91 -0
  60. data/lib/amalgalite/taps/console.rb +27 -0
  61. data/lib/amalgalite/taps/io.rb +74 -0
  62. data/lib/amalgalite/taps.rb +2 -0
  63. data/lib/amalgalite/trace_tap.rb +35 -0
  64. data/lib/amalgalite/type_map.rb +63 -0
  65. data/lib/amalgalite/type_maps/default_map.rb +166 -0
  66. data/lib/amalgalite/type_maps/storage_map.rb +38 -0
  67. data/lib/amalgalite/type_maps/text_map.rb +21 -0
  68. data/lib/amalgalite/version.rb +8 -0
  69. data/lib/amalgalite/view.rb +26 -0
  70. data/lib/amalgalite.rb +51 -0
  71. data/spec/aggregate_spec.rb +158 -0
  72. data/spec/amalgalite_spec.rb +4 -0
  73. data/spec/blob_spec.rb +78 -0
  74. data/spec/boolean_spec.rb +24 -0
  75. data/spec/busy_handler.rb +157 -0
  76. data/spec/data/iso-3166-country.txt +242 -0
  77. data/spec/data/iso-3166-schema.sql +22 -0
  78. data/spec/data/iso-3166-subcountry.txt +3995 -0
  79. data/spec/data/make-iso-db.sh +12 -0
  80. data/spec/database_spec.rb +505 -0
  81. data/spec/default_map_spec.rb +92 -0
  82. data/spec/function_spec.rb +78 -0
  83. data/spec/integeration_spec.rb +97 -0
  84. data/spec/iso_3166_database.rb +58 -0
  85. data/spec/json_spec.rb +24 -0
  86. data/spec/packer_spec.rb +60 -0
  87. data/spec/paths_spec.rb +28 -0
  88. data/spec/progress_handler_spec.rb +91 -0
  89. data/spec/requires_spec.rb +54 -0
  90. data/spec/rtree_spec.rb +66 -0
  91. data/spec/schema_spec.rb +131 -0
  92. data/spec/spec_helper.rb +48 -0
  93. data/spec/sqlite3/constants_spec.rb +108 -0
  94. data/spec/sqlite3/database_status_spec.rb +36 -0
  95. data/spec/sqlite3/status_spec.rb +22 -0
  96. data/spec/sqlite3/version_spec.rb +28 -0
  97. data/spec/sqlite3_spec.rb +53 -0
  98. data/spec/statement_spec.rb +168 -0
  99. data/spec/storage_map_spec.rb +38 -0
  100. data/spec/tap_spec.rb +57 -0
  101. data/spec/text_map_spec.rb +20 -0
  102. data/spec/type_map_spec.rb +14 -0
  103. data/spec/version_spec.rb +8 -0
  104. data/tasks/custom.rake +101 -0
  105. data/tasks/default.rake +244 -0
  106. data/tasks/extension.rake +28 -0
  107. data/tasks/this.rb +208 -0
  108. metadata +325 -0
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #
4
+ # Basic amalgalite example creating a table, inserting rows and doing various
5
+ # selects and prepared statements
6
+ #
7
+ require 'rubygems'
8
+ require 'amalgalite'
9
+
10
+ #
11
+ # Create a database, this will create the DB if it doesn't exist
12
+ #
13
+ puts "Opening database (version #{Amalgalite::Version})"
14
+ db = Amalgalite::Database.new("gems.db")
15
+
16
+ #
17
+ # Setup taps into profile and trace information of sqlite, the profile tap will
18
+ # goto the profile_tap.log file and the trace information will go to the
19
+ # trace_tap.log file
20
+ #
21
+ puts "Establishing taps"
22
+ db.trace_tap = Amalgalite::Taps::IO.new( trace_tap_file = File.open("trace_tap.log", "w+") )
23
+ db.profile_tap = Amalgalite::Taps::IO.new( profile_tap_file = File.open("profile_tap.log", "w+") )
24
+
25
+ #
26
+ # Create the schema unless it already exists in the table. The meta information
27
+ # about the database schema is available as the result of the db.schema method
28
+ #
29
+ schema = db.schema
30
+ unless schema.tables['gems']
31
+ puts "Create schema"
32
+ db.execute <<-SQL
33
+ CREATE TABLE gems (
34
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
35
+ name VARCHAR(128),
36
+ version VARCHAR(32),
37
+ author VARCHAR(128)
38
+ );
39
+ SQL
40
+ db.reload_schema!
41
+ end
42
+
43
+ #
44
+ # Get some data from the system to insert into the database. Since everyone
45
+ # probably has gems installed, that's a ready known piece of information. We'll
46
+ # just pull in the latest version of each installed gem and dump some meta
47
+ # information into a db for testing.
48
+ #
49
+ latest_specs = Gem.source_index.latest_specs
50
+
51
+ puts "Inserting #{latest_specs.size} rows of gem information..."
52
+ before = Time.now
53
+
54
+ # Inserting bulk rows as a transaction is good practice with SQLite, it is
55
+ # MUCH faster.
56
+ db.transaction do |db_in_transaction|
57
+ db_in_transaction.prepare("INSERT INTO gems(name, version, author) VALUES( :name, :version, :author );") do |stmt|
58
+ latest_specs.each do |spec|
59
+ insert_data = {}
60
+ insert_data[':name'] = spec.name.to_s
61
+ insert_data[':version'] = spec.version.to_s
62
+ insert_data[':author'] = spec.authors.join(' ')
63
+ #puts "Inserting #{insert_data.inspect}"
64
+ stmt.execute( insert_data )
65
+ end
66
+ end
67
+ end
68
+ puts "Took #{Time.now - before} seconds"
69
+ puts "Done Inserting"
70
+
71
+ authors_by_number = db.execute("SELECT author, count( name ) as num_gems FROM gems GROUP BY author ORDER BY num_gems DESC")
72
+ favorite_author = authors_by_number.first
73
+ puts "Your favorite gem author is <#{favorite_author['author']}>, with #{favorite_author['num_gems']} gems installed."
74
+
75
+ #
76
+ # Now we'll look at the profile sampler and see what information it traced about
77
+ # our behavoir.
78
+ #
79
+ db.profile_tap.samplers.each do |stat_name, stat_values|
80
+ puts "-" * 20
81
+ puts stat_values.to_s
82
+ end
83
+
84
+ #
85
+ # Clear out the taps (not really necessary, just cleaning up)
86
+ #
87
+ db.trace_tap = profile_tap = nil
88
+
89
+ #
90
+ # close things down
91
+ #
92
+ db.close
93
+ trace_tap_file.close
94
+ profile_tap_file.close
@@ -0,0 +1,11 @@
1
+ CONSTANT = "bad"
2
+ class RequireMe
3
+ def initialize( msg )
4
+ @msg = msg
5
+ puts "RequireMe initialized"
6
+ end
7
+
8
+ def foo
9
+ puts @msg
10
+ end
11
+ end
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #
4
+ # An Amalgalite example showing how to 'require' data in an amalgalite database
5
+ #
6
+ # We'll make a database with one table, that we store file contents in.
7
+ #
8
+
9
+ $: << "../lib"
10
+ $: << "../ext"
11
+ require 'rubygems'
12
+ require 'amalgalite'
13
+
14
+ style = ARGV.shift || "normal"
15
+
16
+ #
17
+ # create the database
18
+ #
19
+ dbfile = Amalgalite::Requires::Bootstrap::DEFAULT_DB
20
+ File.unlink( dbfile ) if File.exist?( dbfile )
21
+ require 'amalgalite/packer'
22
+ options = { :verbose => true }
23
+ if style == "compressed" then
24
+ options[:compressed] = true
25
+ end
26
+ p = Amalgalite::Packer.new( options )
27
+ p.pack( [ "require_me.rb" ] )
28
+
29
+ require 'amalgalite/requires'
30
+ begin
31
+ Amalgalite::Requires.new( :dbfile_name => p.dbfile )
32
+ FileUtils.mv 'require_me.rb', 'rm.rb', :verbose => true
33
+ require 'require_me'
34
+ e = RequireMe.new( "#{style} require style works!" )
35
+ e.foo
36
+ require 'require_me'
37
+ puts
38
+
39
+ ensure
40
+ FileUtils.mv 'rm.rb', 'require_me.rb', :verbose => true
41
+ File.unlink( dbfile ) if File.exist?( dbfile )
42
+ end
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'amalgalite'
5
+
6
+ db_name = ARGV.shift
7
+ unless db_name
8
+ puts "Usage: #{File.basename($0)} dbname"
9
+ exit 1
10
+ end
11
+ db = Amalgalite::Database.new( db_name )
12
+ col_info = %w[ default_value declared_data_type collation_sequence_name not_null_constraint primary_key auto_increment ]
13
+ max_width = col_info.collect { |c| c.length }.sort.last
14
+
15
+ db.schema.tables.keys.sort.each do |table_name|
16
+ puts "Table: #{table_name}"
17
+ puts "=" * 42
18
+ db.schema.tables[table_name].columns.each_pair do |col_name, col|
19
+ puts " Column : #{col.name}"
20
+ col_info.each do |ci|
21
+ puts " |#{ci.rjust( max_width, "." )} : #{col.send( ci )}"
22
+ end
23
+ puts
24
+ end
25
+
26
+ db.schema.tables[table_name].indexes.each_pair do |idx_name, index|
27
+ puts " Index : #{index.name}"
28
+ puts " |#{"sequence_number".rjust( max_width, "." )} : #{index.sequence_number}"
29
+ puts " |#{"is unique?".rjust( max_width, ".")} : #{index.unique?}"
30
+ puts " |#{"columns".rjust( max_width, ".")} : #{index.columns.collect { |c| c.name }.join(',') }"
31
+ puts
32
+ end
33
+ end
34
+
@@ -0,0 +1,355 @@
1
+ /**
2
+ * Copyright (c) 2008 Jeremy Hinegardner
3
+ * All rights reserved. See LICENSE and/or COPYING for details.
4
+ *
5
+ * vim: shiftwidth=4
6
+ :*/
7
+
8
+ #include "amalgalite.h"
9
+
10
+ /* Module and Classes */
11
+ VALUE mA; /* module Amalgalite */
12
+ VALUE mAS; /* module Amalgalite::SQLite3 */
13
+ VALUE mASV; /* module Amalgalite::SQLite3::Version */
14
+ VALUE eAS_Error; /* class Amalgalite::SQLite3::Error */
15
+ VALUE cAS_Stat; /* class Amalgalite::SQLite3::Stat */
16
+
17
+ /*----------------------------------------------------------------------
18
+ * module methods for Amalgalite::SQLite3
19
+ *---------------------------------------------------------------------*/
20
+
21
+ /*
22
+ * call-seq:
23
+ * Amalgalite::SQLite3.threadsafe? -> true or false
24
+ *
25
+ * Has the SQLite3 extension been compiled "threadsafe". If threadsafe? is
26
+ * true then the internal SQLite mutexes are enabled and SQLite is threadsafe.
27
+ * That is threadsafe within the context of 'C' threads.
28
+ *
29
+ */
30
+ VALUE am_sqlite3_threadsafe(VALUE self)
31
+ {
32
+ if (sqlite3_threadsafe()) {
33
+ return Qtrue;
34
+ } else {
35
+ return Qfalse;
36
+ }
37
+ }
38
+
39
+ /*
40
+ * call-seq:
41
+ * Amalgalite::SQLite.temp_directory -> String or nil
42
+ *
43
+ * Return the directory name that all that all the temporary files created by
44
+ * SQLite creates will be placed. If _nil_ is returned, then SQLite will search
45
+ * for an appropriate directory.
46
+ */
47
+ VALUE am_sqlite3_get_temp_directory( VALUE self )
48
+ {
49
+ if (NULL == sqlite3_temp_directory) {
50
+ return Qnil;
51
+ } else {
52
+ return rb_str_new2( sqlite3_temp_directory );
53
+ }
54
+ }
55
+
56
+ /*
57
+ * call-seq:
58
+ * Amalgalite::SQLite.temp_directory = "/tmp/location"
59
+ *
60
+ * Set the temporary directory used by sqlite to store temporary directories.
61
+ * It is not safe to set this value after a Database has been opened.
62
+ *
63
+ */
64
+ VALUE am_sqlite3_set_temp_directory( VALUE self, VALUE new_dir )
65
+ {
66
+ char *p = NULL ;
67
+
68
+ if ( NULL != sqlite3_temp_directory ) {
69
+ free( sqlite3_temp_directory );
70
+ }
71
+
72
+ if ( Qnil != new_dir ) {
73
+ VALUE str = StringValue( new_dir );
74
+
75
+ p = calloc( RSTRING_LEN(str) + 1, sizeof(char) );
76
+ strncpy( p, RSTRING_PTR(str), RSTRING_LEN(str) );
77
+ }
78
+
79
+ sqlite3_temp_directory = p;
80
+
81
+ return Qnil;
82
+ }
83
+
84
+ VALUE amalgalite_format_string( const char* pattern, VALUE string )
85
+ {
86
+ VALUE to_s= rb_funcall( string, rb_intern("to_s"), 0 );
87
+ VALUE str = StringValue( to_s );
88
+ char *p = sqlite3_mprintf(pattern, RSTRING_PTR(str));
89
+ VALUE rv = Qnil;
90
+ if ( NULL != p ) {
91
+ rv = rb_str_new2( p );
92
+ sqlite3_free( p );
93
+ } else {
94
+ rb_raise( rb_eNoMemError, "Unable to quote string" );
95
+ }
96
+
97
+ return rv;
98
+ }
99
+ /*
100
+ * call-seq:
101
+ * Amalgalite::SQLite.escape( string ) => escaped_string
102
+ *
103
+ * Takes the input string and escapes each ' (single quote) character by
104
+ * doubling it.
105
+ */
106
+ VALUE am_sqlite3_escape( VALUE self, VALUE string )
107
+ {
108
+ return ( Qnil == string ) ? Qnil : amalgalite_format_string( "%q", string );
109
+ }
110
+
111
+ /*
112
+ * call-seq:
113
+ * Amalgalite::SQLite.quote( string ) => quoted-escaped string
114
+ *
115
+ * Takes the input string and surrounds it with single quotes, it also escapes
116
+ * each embedded single quote with double quotes.
117
+ */
118
+ VALUE am_sqlite3_quote( VALUE self, VALUE string )
119
+ {
120
+ return ( Qnil == string ) ? Qnil : amalgalite_format_string( "%Q", string );
121
+ }
122
+
123
+ /*
124
+ * call-seq:
125
+ * Amalgalite::SQLite3.complete?( ... , opts = { :utf16 => false }) -> True, False
126
+ *
127
+ * Is the text passed in as a parameter a complete SQL statement? Or is
128
+ * additional input required before sending the SQL to the extension. If the
129
+ * extra 'opts' parameter is used, you can send in a UTF-16 encoded string as
130
+ * the SQL.
131
+ *
132
+ * A complete statement must end with a semicolon.
133
+ *
134
+ */
135
+ VALUE am_sqlite3_complete(VALUE self, VALUE args)
136
+ {
137
+ VALUE sql = rb_ary_shift( args );
138
+ VALUE opts = rb_ary_shift( args );
139
+ VALUE utf16 = Qnil;
140
+ int result = 0;
141
+
142
+ if ( ( Qnil != opts ) && ( T_HASH == TYPE(opts) ) ){
143
+ utf16 = rb_hash_aref( opts, rb_intern("utf16") );
144
+ }
145
+
146
+ if ( (Qfalse == utf16) || (Qnil == utf16) ) {
147
+ result = sqlite3_complete( StringValuePtr( sql ) );
148
+ } else {
149
+ result = sqlite3_complete16( (void*) StringValuePtr( sql ) );
150
+ }
151
+
152
+ return ( result > 0 ) ? Qtrue : Qfalse;
153
+ }
154
+
155
+ /*
156
+ * call-seq:
157
+ * Amalgalite::SQLite3::Stat.update!( reset = false ) -> nil
158
+ *
159
+ * Populates the _@current_ and _@higwater_ instance variables of self
160
+ * object with the values from the sqlite3_status call. If reset it true then
161
+ * the highwater mark for the stat is reset
162
+ *
163
+ */
164
+ VALUE am_sqlite3_stat_update_bang( int argc, VALUE *argv, VALUE self )
165
+ {
166
+ int status_op = -1;
167
+ int current = -1;
168
+ int highwater = -1;
169
+ VALUE reset = Qfalse;
170
+ int reset_flag = 0;
171
+ int rc;
172
+
173
+ status_op = FIX2INT( rb_iv_get( self, "@code" ) );
174
+ if ( argc > 0 ) {
175
+ reset = argv[0];
176
+ reset_flag = ( Qtrue == reset ) ? 1 : 0 ;
177
+ }
178
+
179
+ rc = sqlite3_status( status_op, &current, &highwater, reset_flag );
180
+
181
+ if ( SQLITE_OK != rc ) {
182
+ VALUE n = rb_iv_get( self, "@name" ) ;
183
+ char* name = StringValuePtr( n );
184
+ rb_raise(eAS_Error, "Failure to retrieve status for %s : [SQLITE_ERROR %d] \n", name, rc);
185
+ }
186
+
187
+ rb_iv_set( self, "@current", INT2NUM( current ) );
188
+ rb_iv_set( self, "@highwater", INT2NUM( highwater) );
189
+
190
+ return Qnil;
191
+ }
192
+
193
+ /*
194
+ * call-seq:
195
+ * Amalgalite::SQLite3.randomness( N ) -> String of length N
196
+ *
197
+ * Generate N bytes of random data.
198
+ *
199
+ */
200
+ VALUE am_sqlite3_randomness(VALUE self, VALUE num_bytes)
201
+ {
202
+ int n = NUM2INT(num_bytes);
203
+ char *buf = ALLOCA_N(char, n);
204
+
205
+ sqlite3_randomness( n, buf );
206
+ return rb_str_new( buf, n );
207
+ }
208
+
209
+ /*----------------------------------------------------------------------
210
+ * module methods for Amalgalite::SQLite3::Version
211
+ *---------------------------------------------------------------------*/
212
+
213
+ /*
214
+ * call-seq:
215
+ * Amalgalite::SQLite3::Version.to_s -> String
216
+ *
217
+ * Return the SQLite C library version number as a string
218
+ *
219
+ */
220
+ VALUE am_sqlite3_runtime_version(VALUE self)
221
+ {
222
+ return rb_str_new2(sqlite3_libversion());
223
+ }
224
+
225
+ /*
226
+ * call-seq:
227
+ * Amalgalite::SQLite3.Version.to_i -> Fixnum
228
+ *
229
+ * Return the SQLite C library version number as an integer
230
+ *
231
+ */
232
+ VALUE am_sqlite3_runtime_version_number(VALUE self)
233
+ {
234
+ return INT2FIX(sqlite3_libversion_number());
235
+ }
236
+
237
+ /*
238
+ * call-seq:
239
+ * Amalgalite::SQLite3::Version.runtime_source_id -> String
240
+ *
241
+ * Return the SQLite C library source id as a string
242
+ *
243
+ */
244
+ VALUE am_sqlite3_runtime_source_id(VALUE self)
245
+ {
246
+ return rb_str_new2(sqlite3_sourceid());
247
+ }
248
+
249
+ /*
250
+ * call-seq:
251
+ * Amalgalite::SQLite::Version.compiled_version -> String
252
+ *
253
+ * Return the compiletime version number as a string.
254
+ *
255
+ */
256
+ VALUE am_sqlite3_compiled_version(VALUE self)
257
+ {
258
+ return rb_str_new2( SQLITE_VERSION );
259
+ }
260
+
261
+ /*
262
+ * call-seql:
263
+ * Amalgalite::SQLite::Version.compiled_version_number -> Fixnum
264
+ *
265
+ * Return the compiletime library version from the
266
+ * embedded version of sqlite3.
267
+ *
268
+ */
269
+ VALUE am_sqlite3_compiled_version_number( VALUE self )
270
+ {
271
+ return INT2FIX( SQLITE_VERSION_NUMBER );
272
+ }
273
+
274
+ /*
275
+ * call-seq:
276
+ * Amalgalite::SQLite3::Version.compiled_source_id -> String
277
+ *
278
+ * Return the compiled SQLite C library source id as a string
279
+ *
280
+ */
281
+ VALUE am_sqlite3_compiled_source_id(VALUE self)
282
+ {
283
+ return rb_str_new2( SQLITE_SOURCE_ID );
284
+ }
285
+
286
+ /**
287
+ * Document-class: Amalgalite::SQLite3
288
+ *
289
+ * The SQLite ruby extension inside Amalgalite.
290
+ *
291
+ */
292
+
293
+ void Init_amalgalite()
294
+ {
295
+ int rc = 0;
296
+
297
+ /*
298
+ * top level module encapsulating the entire Amalgalite library
299
+ */
300
+ mA = rb_define_module("Amalgalite");
301
+
302
+ mAS = rb_define_module_under(mA, "SQLite3");
303
+ rb_define_module_function(mAS, "threadsafe?", am_sqlite3_threadsafe, 0);
304
+ rb_define_module_function(mAS, "complete?", am_sqlite3_complete, -2);
305
+ rb_define_module_function(mAS, "randomness", am_sqlite3_randomness,1);
306
+ rb_define_module_function(mAS, "temp_directory", am_sqlite3_get_temp_directory, 0);
307
+ rb_define_module_function(mAS, "temp_directory=", am_sqlite3_set_temp_directory, 1);
308
+
309
+ rb_define_module_function(mAS, "escape", am_sqlite3_escape, 1);
310
+ rb_define_module_function(mAS, "quote", am_sqlite3_quote, 1);
311
+
312
+ /*
313
+ * class encapsulating a single Stat
314
+ */
315
+ cAS_Stat = rb_define_class_under(mAS, "Stat", rb_cObject);
316
+ rb_define_method(cAS_Stat, "update!", am_sqlite3_stat_update_bang, -1);
317
+
318
+ /*
319
+ * Base class of all SQLite3 errors
320
+ */
321
+ eAS_Error = rb_define_class_under(mAS, "Error", rb_eStandardError); /* in amalgalite.c */
322
+
323
+ /**
324
+ * Encapsulation of the SQLite C library version
325
+ */
326
+ mASV = rb_define_module_under(mAS, "Version");
327
+ rb_define_module_function(mASV, "to_s", am_sqlite3_runtime_version, 0); /* in amalgalite.c */
328
+ rb_define_module_function(mASV, "runtime_version", am_sqlite3_runtime_version, 0); /* in amalgalite.c */
329
+ rb_define_module_function(mASV, "to_i", am_sqlite3_runtime_version_number, 0); /* in amalgalite.c */
330
+ rb_define_module_function(mASV, "runtime_version_number", am_sqlite3_runtime_version_number, 0); /* in amalgalite.c */
331
+ rb_define_module_function(mASV, "compiled_version", am_sqlite3_compiled_version, 0 ); /* in amalgalite.c */
332
+ rb_define_module_function(mASV, "compiled_version_number", am_sqlite3_compiled_version_number, 0 ); /* in amalgalite.c */
333
+ rb_define_module_function(mASV, "runtime_source_id", am_sqlite3_runtime_source_id, 0); /* in amalgalite.c */
334
+ rb_define_module_function(mASV, "compiled_source_id", am_sqlite3_compiled_source_id, 0); /* in amalgalite.c */
335
+
336
+ /*
337
+ * Initialize the rest of the module
338
+ */
339
+ Init_amalgalite_constants( );
340
+ Init_amalgalite_database( );
341
+ Init_amalgalite_statement( );
342
+ Init_amalgalite_blob( );
343
+ Init_amalgalite_requires_bootstrap( );
344
+
345
+ /*
346
+ * initialize sqlite itself
347
+ */
348
+ rc = sqlite3_initialize();
349
+ if ( SQLITE_OK != rc ) {
350
+ rb_raise(eAS_Error, "Failure to initialize the sqlite3 library : [SQLITE_ERROR %d]\n", rc);
351
+ }
352
+
353
+ }
354
+
355
+
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Copyright (c) 2008 Jeremy Hinegardner
3
+ * All rights reserved. See LICENSE and/or COPYING for details.
4
+ *
5
+ * vim: shiftwidth=4
6
+ */
7
+
8
+ #ifndef __AMALGALITE_H__
9
+ #define __AMALGALITE_H__
10
+
11
+ #include "ruby.h"
12
+ #include "sqlite3.h"
13
+ #include <string.h>
14
+
15
+ /* wrapper struct around the sqlite3 opaque pointer */
16
+ typedef struct am_sqlite3 {
17
+ sqlite3 *db;
18
+ VALUE trace_obj;
19
+ VALUE profile_obj;
20
+ VALUE busy_handler_obj;
21
+ VALUE progress_handler_obj;
22
+ } am_sqlite3;
23
+
24
+ /* wrapper struct around the sqlite3_statement opaque pointer */
25
+ typedef struct am_sqlite3_stmt {
26
+ sqlite3_stmt *stmt;
27
+ VALUE remaining_sql;
28
+ } am_sqlite3_stmt;
29
+
30
+ /* wrapper struct around the sqlite3_blob opaque ponter */
31
+ typedef struct am_sqlite3_blob {
32
+ sqlite3_blob *blob;
33
+ sqlite3 *db;
34
+ int length;
35
+ int current_offset;
36
+ } am_sqlite3_blob;
37
+
38
+ /* wrapper struct around the information needed to call rb_apply
39
+ * used to encapsulate data into a call for amalgalite_wrap_apply
40
+ */
41
+ typedef struct am_protected {
42
+ VALUE instance;
43
+ ID method;
44
+ int argc;
45
+ VALUE *argv;
46
+ } am_protected_t;
47
+
48
+ /** module and classes **/
49
+ extern VALUE mA; /* module Amalgalite */
50
+ extern VALUE mAS; /* module Amalgalite::SQLite3 */
51
+ extern VALUE mASV; /* module Amalgalite::SQLite3::Version */
52
+ extern VALUE eAS_Error; /* class Amalgalite::SQLite3::Error */
53
+ extern VALUE cAR; /* class Amalgalite::Requries */
54
+ extern VALUE cARB; /* class Amalgalite::Requries::Bootstrap */
55
+
56
+ /*----------------------------------------------------------------------
57
+ * Prototype for Amalgalite::SQLite3::Database
58
+ *---------------------------------------------------------------------*/
59
+ extern VALUE cAS_Database; /* class Amalgalite::SQLite3::Database */
60
+
61
+ extern void am_define_constants_under(VALUE);
62
+ extern VALUE am_sqlite3_database_alloc(VALUE klass);
63
+ extern void am_sqlite3_database_free(am_sqlite3*);
64
+ extern VALUE am_sqlite3_database_open(int argc, VALUE* argv, VALUE self);
65
+ extern VALUE am_sqlite3_database_close(VALUE self);
66
+ extern VALUE am_sqlite3_database_open16(VALUE self, VALUE rFilename);
67
+ extern VALUE am_sqlite3_database_last_insert_rowid(VALUE self);
68
+ extern VALUE am_sqlite3_database_is_autocommit(VALUE self);
69
+ extern VALUE am_sqlite3_database_row_changes(VALUE self);
70
+ extern VALUE am_sqlite3_database_total_changes(VALUE self);
71
+ extern VALUE am_sqlite3_database_table_column_metadata(VALUE self, VALUE db_name, VALUE tbl_name, VALUE col_name);
72
+
73
+ extern VALUE am_sqlite3_database_prepare(VALUE self, VALUE rSQL);
74
+ extern VALUE am_sqlite3_database_register_trace_tap(VALUE self, VALUE tap);
75
+ extern VALUE am_sqlite3_database_register_profile_tap(VALUE self, VALUE tap);
76
+ extern VALUE am_sqlite3_database_busy_handler(VALUE self, VALUE handler);
77
+
78
+ /*----------------------------------------------------------------------
79
+ * Prototype for Amalgalite::SQLite3::Statement
80
+ *---------------------------------------------------------------------*/
81
+ extern VALUE cAS_Statement; /* class Amalgalite::SQLite3::Statement */
82
+
83
+ extern VALUE am_sqlite3_statement_alloc(VALUE klass);
84
+ extern void am_sqlite3_statement_free(am_sqlite3_stmt* );
85
+ extern VALUE am_sqlite3_statement_sql(VALUE self);
86
+ extern VALUE am_sqlite3_statement_close(VALUE self);
87
+ extern VALUE am_sqlite3_statement_step(VALUE self);
88
+ extern VALUE am_sqlite3_statement_column_count(VALUE self);
89
+ extern VALUE am_sqlite3_statement_column_name(VALUE self, VALUE index);
90
+ extern VALUE am_sqlite3_statement_column_decltype(VALUE self, VALUE index);
91
+ extern VALUE am_sqlite3_statement_column_type(VALUE self, VALUE index);
92
+ extern VALUE am_sqlite3_statement_column_blob(VALUE self, VALUE index);
93
+ extern VALUE am_sqlite3_statement_column_text(VALUE self, VALUE index);
94
+ extern VALUE am_sqlite3_statement_column_int(VALUE self, VALUE index);
95
+ extern VALUE am_sqlite3_statement_column_int64(VALUE self, VALUE index);
96
+ extern VALUE am_sqlite3_statement_column_double(VALUE self, VALUE index);
97
+
98
+ extern VALUE am_sqlite3_statement_column_database_name(VALUE self, VALUE position);
99
+ extern VALUE am_sqlite3_statement_column_table_name(VALUE self, VALUE position);
100
+ extern VALUE am_sqlite3_statement_column_origin_name(VALUE self, VALUE position);
101
+
102
+ extern VALUE am_sqlite3_statement_reset(VALUE self);
103
+ extern VALUE am_sqlite3_statement_clear_bindings(VALUE self);
104
+ extern VALUE am_sqlite3_statement_bind_parameter_count(VALUE self);
105
+ extern VALUE am_sqlite3_statement_bind_parameter_index(VALUE self, VALUE parameter_name);
106
+ extern VALUE am_sqlite3_statement_remaining_sql(VALUE self);
107
+ extern VALUE am_sqlite3_statement_bind_text(VALUE self, VALUE position, VALUE value);
108
+ extern VALUE am_sqlite3_statement_bind_blob(VALUE self, VALUE position, VALUE value);
109
+ extern VALUE am_sqlite3_statement_bind_zeroblob(VALUE self, VALUE position, VALUE value);
110
+ extern VALUE am_sqlite3_statement_bind_int(VALUE self, VALUE position, VALUE value);
111
+ extern VALUE am_sqlite3_statement_bind_int64(VALUE self, VALUE position, VALUE value);
112
+ extern VALUE am_sqlite3_statement_bind_double(VALUE self, VALUE position, VALUE value);
113
+ extern VALUE am_sqlite3_statement_bind_null(VALUE self, VALUE position);
114
+
115
+ /*----------------------------------------------------------------------
116
+ * Prototype for Amalgalite::SQLite3::Blob
117
+ *---------------------------------------------------------------------*/
118
+ extern VALUE cAS_Blob; /* class Amalgalite::SQLite3::Blob */
119
+
120
+ extern VALUE am_sqlite3_blob_alloc(VALUE klass);
121
+ extern VALUE am_sqlite3_blob_initialize( VALUE self, VALUE db, VALUE db_name, VALUE table_name, VALUE column_name, VALUE rowid, VALUE flag) ;
122
+ extern void am_sqlite3_blob_free(am_sqlite3_blob* );
123
+ extern VALUE am_sqlite3_blob_read(VALUE self, VALUE length);
124
+ extern VALUE am_sqlite3_blob_write(VALUE self, VALUE buffer);
125
+ extern VALUE am_sqlite3_blob_close(VALUE self);
126
+ extern VALUE am_sqlite3_blob_length(VALUE self);
127
+
128
+ /*----------------------------------------------------------------------
129
+ * more initialization methods
130
+ *----------------------------------------------------------------------*/
131
+ extern void Init_amalgalite_constants( );
132
+ extern void Init_amalgalite_database( );
133
+ extern void Init_amalgalite_statement( );
134
+ extern void Init_amalgalite_blob( );
135
+ extern void Init_amalgalite_requires_bootstrap( );
136
+
137
+
138
+ /***********************************************************************
139
+ * Type conversion macros between sqlite data types and ruby types
140
+ **********************************************************************/
141
+
142
+ #define SQLINT64_2NUM(x) ( LL2NUM( x ) )
143
+ #define SQLUINT64_2NUM(x) ( ULL2NUM( x ) )
144
+ #define NUM2SQLINT64( obj ) ( NUM2LL( obj ) )
145
+ #define NUM2SQLUINT64( obj ) ( NUM2ULL( obj ) )
146
+
147
+ /***********************************************************************
148
+ * return the last exception in ruby's error message
149
+ */
150
+ #define ERROR_INFO_MESSAGE() ( rb_obj_as_string( rb_gv_get("$!") ) )
151
+ #endif