sqlite3 2.0.0-x86-linux-gnu

Sign up to get free protection for your applications and to get access to all the features.
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,56 @@
1
+ # Contributing to sqlite3-ruby
2
+
3
+ **This document is a work-in-progress.**
4
+
5
+ This doc is a short introduction on how to modify and maintain the sqlite3-ruby gem.
6
+
7
+
8
+ ## Architecture notes
9
+
10
+ ### Garbage collection
11
+
12
+ All statements keep pointers back to their respective database connections.
13
+ The `@connection` instance variable on the `Statement` handle keeps the database
14
+ connection alive. Memory allocated for a statement handler will be freed in
15
+ two cases:
16
+
17
+ 1. `#close` is called on the statement
18
+ 2. The `SQLite3::Database` object gets garbage collected
19
+
20
+ We can't free the memory for the statement in the garbage collection function
21
+ for the statement handler. The reason is because there exists a race
22
+ condition. We cannot guarantee the order in which objects will be garbage
23
+ collected. So, it is possible that a connection and a statement are up for
24
+ garbage collection. If the database connection were to be free'd before the
25
+ statement, then boom. Instead we'll be conservative and free unclosed
26
+ statements when the connection is terminated.
27
+
28
+
29
+
30
+ ## Building gems
31
+
32
+ As a prerequisite please make sure you have `docker` correctly installed, so that you're able to cross-compile the native gems.
33
+
34
+ Run `bin/build-gems` which will package gems for all supported platforms, and run some basic sanity tests on those packages using `bin/test-gem-set` and `bin/test-gem-file-contents`.
35
+
36
+
37
+ ## Updating the version of libsqlite3
38
+
39
+ Update `/dependencies.yml` to reflect:
40
+
41
+ - the version of libsqlite3
42
+ - the URL from which to download
43
+ - the checksum of the file, which will need to be verified manually (see comments in that file)
44
+
45
+
46
+ ## Making a release
47
+
48
+ A quick checklist:
49
+
50
+ - [ ] make sure CI is green!
51
+ - [ ] update `CHANGELOG.md` and `lib/sqlite3/version.rb`
52
+ - [ ] run `bin/build-gems` and make sure it completes and all the tests pass
53
+ - [ ] create a git tag using a format that matches the pattern `v\d+\.\d+\.\d+`, e.g. `v1.3.13`
54
+ - [ ] `git push && git push --tags`
55
+ - [ ] `for g in gems/*.gem ; do gem push $g ; done`
56
+ - [ ] create a release at https://github.com/sparklemotion/sqlite3-ruby/releases and include sha2 checksums
data/FAQ.md ADDED
@@ -0,0 +1,388 @@
1
+
2
+ ## How do I do a database query?
3
+ ### I just want an array of the rows...
4
+
5
+ Use the `Database#execute` method. If you don't give it a block, it will
6
+ return an array of all the rows:
7
+
8
+ ```ruby
9
+ require 'sqlite3'
10
+
11
+ db = SQLite3::Database.new( "test.db" )
12
+ rows = db.execute( "select * from test" )
13
+ ```
14
+
15
+ ### I'd like to use a block to iterate through the rows...
16
+
17
+ Use the `Database#execute` method. If you give it a block, each row of the
18
+ result will be yielded to the block:
19
+
20
+
21
+ ```ruby
22
+ require 'sqlite3'
23
+
24
+ db = SQLite3::Database.new( "test.db" )
25
+ db.execute( "select * from test" ) do |row|
26
+ ...
27
+ end
28
+ ```
29
+
30
+ ### I need to get the column names as well as the rows...
31
+
32
+ Use the `Database#execute2` method. This works just like `Database#execute`;
33
+ if you don't give it a block, it returns an array of rows; otherwise, it
34
+ will yield each row to the block. _However_, the first row returned is
35
+ always an array of the column names from the query:
36
+
37
+
38
+ ```ruby
39
+ require 'sqlite3'
40
+
41
+ db = SQLite3::Database.new( "test.db" )
42
+ columns, *rows = db.execute2( "select * from test" )
43
+
44
+ # or use a block:
45
+
46
+ columns = nil
47
+ db.execute2( "select * from test" ) do |row|
48
+ if columns.nil?
49
+ columns = row
50
+ else
51
+ # process row
52
+ end
53
+ end
54
+ ```
55
+
56
+ ### I just want the first row of the result set...
57
+
58
+ Easy. Just call `Database#get_first_row`:
59
+
60
+
61
+ ```ruby
62
+ row = db.get_first_row( "select * from table" )
63
+ ```
64
+
65
+
66
+ This also supports bind variables, just like `Database#execute`
67
+ and friends.
68
+
69
+ ### I just want the first value of the first row of the result set...
70
+
71
+ Also easy. Just call `Database#get_first_value`:
72
+
73
+
74
+ ```ruby
75
+ count = db.get_first_value( "select count(*) from table" )
76
+ ```
77
+
78
+
79
+ This also supports bind variables, just like `Database#execute`
80
+ and friends.
81
+
82
+ ## How do I prepare a statement for repeated execution?
83
+
84
+ If the same statement is going to be executed repeatedly, you can speed
85
+ things up a bit by _preparing_ the statement. You do this via the
86
+ `Database#prepare` method. It returns a `Statement` object, and you can
87
+ then invoke `#execute` on that to get the `ResultSet`:
88
+
89
+
90
+ ```ruby
91
+ stmt = db.prepare( "select * from person" )
92
+
93
+ 1000.times do
94
+ stmt.execute do |result|
95
+ ...
96
+ end
97
+ end
98
+
99
+ stmt.close
100
+
101
+ # or, use a block
102
+
103
+ db.prepare( "select * from person" ) do |stmt|
104
+ 1000.times do
105
+ stmt.execute do |result|
106
+ ...
107
+ end
108
+ end
109
+ end
110
+ ```
111
+
112
+
113
+ This is made more useful by the ability to bind variables to placeholders
114
+ via the `Statement#bind_param` and `Statement#bind_params` methods. (See the
115
+ next FAQ for details.)
116
+
117
+ ## How do I use placeholders in an SQL statement?
118
+
119
+ Placeholders in an SQL statement take any of the following formats:
120
+
121
+
122
+ * `?`
123
+ * `?_nnn_`
124
+ * `:_word_`
125
+
126
+
127
+ Where _n_ is an integer, and _word_ is an alpha-numeric identifier (or
128
+ number). When the placeholder is associated with a number, that number
129
+ identifies the index of the bind variable to replace it with. When it
130
+ is an identifier, it identifies the name of the corresponding bind
131
+ variable. (In the instance of the first format--a single question
132
+ mark--the placeholder is assigned a number one greater than the last
133
+ index used, or 1 if it is the first.)
134
+
135
+
136
+ For example, here is a query using these placeholder formats:
137
+
138
+
139
+ ```sql
140
+ select *
141
+ from table
142
+ where ( c = ?2 or c = ? )
143
+ and d = :name
144
+ and e = :1
145
+ ```
146
+
147
+
148
+ This defines 5 different placeholders: 1, 2, 3, and "name".
149
+
150
+
151
+ You replace these placeholders by _binding_ them to values. This can be
152
+ accomplished in a variety of ways.
153
+
154
+
155
+ The `Database#execute`, and `Database#execute2` methods all accept additional
156
+ arguments following the SQL statement. These arguments are assumed to be
157
+ bind parameters, and they are bound (positionally) to their corresponding
158
+ placeholders:
159
+
160
+
161
+ ```ruby
162
+ db.execute( "select * from table where a = ? and b = ?",
163
+ "hello",
164
+ "world" )
165
+ ```
166
+
167
+
168
+ The above would replace the first question mark with 'hello' and the
169
+ second with 'world'. If the placeholders have an explicit index given, they
170
+ will be replaced with the bind parameter at that index (1-based).
171
+
172
+
173
+ If a Hash is given as a bind parameter, then its key/value pairs are bound
174
+ to the placeholders. This is how you bind by name:
175
+
176
+
177
+ ```ruby
178
+ db.execute( "select * from table where a = :name and b = :value",
179
+ "name" => "bob",
180
+ "value" => "priceless" )
181
+ ```
182
+
183
+
184
+ You can also bind explicitly using the `Statement` object itself. Just pass
185
+ additional parameters to the `Statement#execute` statement:
186
+
187
+
188
+ ```ruby
189
+ db.prepare( "select * from table where a = :name and b = ?" ) do |stmt|
190
+ stmt.execute "value", "name" => "bob"
191
+ end
192
+ ```
193
+
194
+
195
+ Or do a `Database#prepare` to get the `Statement`, and then use either
196
+ `Statement#bind_param` or `Statement#bind_params`:
197
+
198
+
199
+ ```ruby
200
+ stmt = db.prepare( "select * from table where a = :name and b = ?" )
201
+
202
+ stmt.bind_param( "name", "bob" )
203
+ stmt.bind_param( 1, "value" )
204
+
205
+ # or
206
+
207
+ stmt.bind_params( "value", "name" => "bob" )
208
+ ```
209
+
210
+ ## How do I discover metadata about a query?
211
+
212
+ If you ever want to know the names or types of the columns in a result
213
+ set, you can do it in several ways.
214
+
215
+
216
+ The first way is to ask the row object itself. Each row will have a
217
+ property "fields" that returns an array of the column names. The row
218
+ will also have a property "types" that returns an array of the column
219
+ types:
220
+
221
+
222
+ ```ruby
223
+ rows = db.execute( "select * from table" )
224
+ p rows[0].fields
225
+ p rows[0].types
226
+ ```
227
+
228
+
229
+ Obviously, this approach requires you to execute a statement that actually
230
+ returns data. If you don't know if the statement will return any rows, but
231
+ you still need the metadata, you can use `Database#query` and ask the
232
+ `ResultSet` object itself:
233
+
234
+
235
+ ```ruby
236
+ db.query( "select * from table" ) do |result|
237
+ p result.columns
238
+ p result.types
239
+ ...
240
+ end
241
+ ```
242
+
243
+
244
+ Lastly, you can use `Database#prepare` and ask the `Statement` object what
245
+ the metadata are:
246
+
247
+
248
+ ```ruby
249
+ stmt = db.prepare( "select * from table" )
250
+ p stmt.columns
251
+ p stmt.types
252
+ ```
253
+
254
+ ## I'd like the rows to be indexible by column name.
255
+
256
+ By default, each row from a query is returned as an `Array` of values. This
257
+ means that you can only obtain values by their index. Sometimes, however,
258
+ you would like to obtain values by their column name.
259
+
260
+
261
+ The first way to do this is to set the Database property `results_as_hash`
262
+ to true. If you do this, then all rows will be returned as Hash objects,
263
+ with the column names as the keys. (In this case, the `fields` property
264
+ is unavailable on the row, although the "types" property remains.)
265
+
266
+
267
+ ```ruby
268
+ db.results_as_hash = true
269
+ db.execute( "select * from table" ) do |row|
270
+ p row['column1']
271
+ p row['column2']
272
+ end
273
+ ```
274
+
275
+
276
+ The other way is to use Ara Howard's
277
+ [`ArrayFields`](http://rubyforge.org/projects/arrayfields)
278
+ module. Just `require "arrayfields"`, and all of your rows will be indexable
279
+ by column name, even though they are still arrays!
280
+
281
+
282
+ ```ruby
283
+ require 'arrayfields'
284
+
285
+ ...
286
+ db.execute( "select * from table" ) do |row|
287
+ p row[0] == row['column1']
288
+ p row[1] == row['column2']
289
+ end
290
+ ```
291
+
292
+ ## How do I insert binary data into the database?
293
+
294
+ Use blobs. Blobs are new features of SQLite3. You have to use bind
295
+ variables to make it work:
296
+
297
+
298
+ ```ruby
299
+ db.execute( "insert into foo ( ?, ? )",
300
+ SQLite3::Blob.new( "\0\1\2\3\4\5" ),
301
+ SQLite3::Blob.new( "a\0b\0c\0d ) )
302
+ ```
303
+
304
+
305
+ The blob values must be indicated explicitly by binding each parameter to
306
+ a value of type `SQLite3::Blob`.
307
+
308
+ ## How do I do a DDL (insert, update, delete) statement?
309
+
310
+ You can actually do inserts, updates, and deletes in exactly the same way
311
+ as selects, but in general the `Database#execute` method will be most
312
+ convenient:
313
+
314
+
315
+ ```ruby
316
+ db.execute( "insert into table values ( ?, ? )", *bind_vars )
317
+ ```
318
+
319
+ ## How do I execute multiple statements in a single string?
320
+
321
+ The standard query methods (`Database#execute`, `Database#execute2`,
322
+ `Database#query`, and `Statement#execute`) will only execute the first
323
+ statement in the string that is given to them. Thus, if you have a
324
+ string with multiple SQL statements, each separated by a string,
325
+ you can't use those methods to execute them all at once.
326
+
327
+
328
+ Instead, use `Database#execute_batch`:
329
+
330
+
331
+ ```ruby
332
+ sql = <<SQL
333
+ create table the_table (
334
+ a varchar2(30),
335
+ b varchar2(30)
336
+ );
337
+
338
+ insert into the_table values ( 'one', 'two' );
339
+ insert into the_table values ( 'three', 'four' );
340
+ insert into the_table values ( 'five', 'six' );
341
+ SQL
342
+
343
+ db.execute_batch( sql )
344
+ ```
345
+
346
+
347
+ Unlike the other query methods, `Database#execute_batch` accepts no
348
+ block. It will also only ever return `nil`. Thus, it is really only
349
+ suitable for batch processing of DDL statements.
350
+
351
+ ## How do I begin/end a transaction
352
+
353
+ Use `Database#transaction` to start a transaction. If you give it a block,
354
+ the block will be automatically committed at the end of the block,
355
+ unless an exception was raised, in which case the transaction will be
356
+ rolled back. (Never explicitly call `Database#commit` or `Database#rollback`
357
+ inside of a transaction block--you'll get errors when the block
358
+ terminates!)
359
+
360
+
361
+ ```ruby
362
+ database.transaction do |db|
363
+ db.execute( "insert into table values ( 'a', 'b', 'c' )" )
364
+ ...
365
+ end
366
+ ```
367
+
368
+
369
+ Alternatively, if you don't give a block to `Database#transaction`, the
370
+ transaction remains open until you explicitly call `Database#commit` or
371
+ `Database#rollback`.
372
+
373
+
374
+ ```ruby
375
+ db.transaction
376
+ db.execute( "insert into table values ( 'a', 'b', 'c' )" )
377
+ db.commit
378
+ ```
379
+
380
+
381
+ Note that SQLite does not allow nested transactions, so you'll get errors
382
+ if you try to open a new transaction while one is already active. Use
383
+ `Database#transaction_active?` to determine whether a transaction is
384
+ active or not.
385
+
386
+ ## How do I discover metadata about a table/index?
387
+
388
+ ## How do I do tweak database settings?
data/INSTALLATION.md ADDED
@@ -0,0 +1,267 @@
1
+
2
+ # Installation and Using SQLite3 extensions
3
+
4
+ This document will help you install the `sqlite3` ruby gem. It also contains instructions on loading database extensions and building against drop-in replacements for sqlite3.
5
+
6
+ ## Installation
7
+
8
+ ### Native Gems (recommended)
9
+
10
+ In v2.0.0 and later, native (precompiled) gems are available for recent Ruby versions on these platforms:
11
+
12
+ - `aarch64-linux-gnu` (requires: glibc >= 2.29)
13
+ - `aarch64-linux-musl`
14
+ - `arm-linux-gnu` (requires: glibc >= 2.29)
15
+ - `arm-linux-musl`
16
+ - `arm64-darwin`
17
+ - `x64-mingw32` / `x64-mingw-ucrt`
18
+ - `x86-linux-gnu` (requires: glibc >= 2.17)
19
+ - `x86-linux-musl`
20
+ - `x86_64-darwin`
21
+ - `x86_64-linux-gnu` (requires: glibc >= 2.17)
22
+ - `x86_64-linux-musl`
23
+
24
+ ⚠ Ruby 3.0 linux users must use Rubygems >= 3.3.22 in order to use these gems.
25
+
26
+ ⚠ Musl linux users should update to Bundler >= 2.5.6 to avoid https://github.com/rubygems/rubygems/issues/7432
27
+
28
+ If you are using one of these Ruby versions on one of these platforms, the native gem is the recommended way to install sqlite3-ruby.
29
+
30
+ For example, on a linux system running Ruby 3.1:
31
+
32
+ ``` text
33
+ $ ruby -v
34
+ ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
35
+
36
+ $ time gem install sqlite3
37
+ Fetching sqlite3-1.5.0-x86_64-linux.gem
38
+ Successfully installed sqlite3-1.5.0-x86_64-linux
39
+ 1 gem installed
40
+
41
+ real 0m4.274s
42
+ user 0m0.734s
43
+ sys 0m0.165s
44
+ ```
45
+
46
+ #### Avoiding the precompiled native gem
47
+
48
+ The maintainers strongly urge you to use a native gem if at all possible. It will be a better experience for you and allow us to focus our efforts on improving functionality rather than diagnosing installation issues.
49
+
50
+ If you're on a platform that supports a native gem but you want to avoid using it in your project, do one of the following:
51
+
52
+ - If you're not using Bundler, then run `gem install sqlite3 --platform=ruby`
53
+ - If you are using Bundler
54
+ - version 2.3.18 or later, you can specify [`gem "sqlite3", force_ruby_platform: true`](https://bundler.io/v2.3/man/gemfile.5.html#FORCE_RUBY_PLATFORM)
55
+ - version 2.1 or later, then you'll need to run `bundle config set force_ruby_platform true`
56
+ - version 2.0 or earlier, then you'll need to run `bundle config force_ruby_platform true`
57
+
58
+
59
+ ### Compiling the source gem
60
+
61
+ If you are on a platform or version of Ruby that is not covered by the Native Gems, then the vanilla "ruby platform" (non-native) gem will be installed by the `gem install` or `bundle` commands.
62
+
63
+
64
+ #### Packaged libsqlite3
65
+
66
+ By default, as of v1.5.0 of this library, the latest available version of libsqlite3 is packaged with the gem and will be compiled and used automatically. This takes a bit longer than the native gem, but will provide a modern, well-supported version of libsqlite3.
67
+
68
+ For example, on a linux system running Ruby 2.5:
69
+
70
+ ``` text
71
+ $ ruby -v
72
+ ruby 2.5.9p229 (2021-04-05 revision 67939) [x86_64-linux]
73
+
74
+ $ time gem install sqlite3
75
+ Building native extensions. This could take a while...
76
+ Successfully installed sqlite3-1.5.0
77
+ 1 gem installed
78
+
79
+ real 0m20.620s
80
+ user 0m23.361s
81
+ sys 0m5.839s
82
+ ```
83
+
84
+ ##### Controlling compilation flags for sqlite
85
+
86
+ Upstream sqlite allows for the setting of some parameters at compile time. If you're an expert and would like to set these, you may do so at gem install time in two different ways ...
87
+
88
+ **If you're installing the gem using `gem install`** then you can pass in these compile-time flags like this:
89
+
90
+ ``` sh
91
+ gem install sqlite3 --platform=ruby -- \
92
+ --with-sqlite-cflags="-DSQLITE_DEFAULT_CACHE_SIZE=9999 -DSQLITE_DEFAULT_PAGE_SIZE=4444"
93
+ ```
94
+
95
+ or the equivalent:
96
+
97
+ ``` sh
98
+ CFLAGS="-DSQLITE_DEFAULT_CACHE_SIZE=9999 -DSQLITE_DEFAULT_PAGE_SIZE=4444" \
99
+ gem install sqlite3 --platform=ruby
100
+ ```
101
+
102
+ **If you're installing the gem using `bundler`** then you should first pin the gem to the "ruby" platform gem, so that you are compiling from source:
103
+
104
+ ``` ruby
105
+ # Gemfile
106
+ gem "sqlite3", force_ruby_platform: true # requires bundler >= 2.3.18
107
+ ```
108
+
109
+ and then set up a bundler config parameter for `build.sqlite3`:
110
+
111
+ ``` sh
112
+ bundle config set build.sqlite3 \
113
+ "--with-sqlite-cflags='-DSQLITE_DEFAULT_CACHE_SIZE=9999 -DSQLITE_DEFAULT_PAGE_SIZE=4444'"
114
+ ```
115
+
116
+ NOTE the use of single quotes within the double-quoted string to ensure the space between compiler flags is interpreted correctly. The contents of your `.bundle/config` file should look like:
117
+
118
+ ``` yaml
119
+ ---
120
+ BUNDLE_BUILD__SQLITE3: "--with-sqlite-cflags='-DSQLITE_DEFAULT_CACHE_SIZE=9999 -DSQLITE_DEFAULT_PAGE_SIZE=4444'"
121
+ ```
122
+
123
+
124
+ #### System libsqlite3
125
+
126
+ If you would prefer to build the sqlite3-ruby gem against your system libsqlite3, which requires that you install libsqlite3 and its development files yourself, you may do so by using the `--enable-system-libraries` flag at gem install time.
127
+
128
+ PLEASE NOTE:
129
+
130
+ - you must avoid installing a precompiled native gem (see [previous section](#avoiding-the-precompiled-native-gem))
131
+ - only versions of libsqlite3 `>= 3.5.0` are supported,
132
+ - and some library features may depend on how your libsqlite3 was compiled.
133
+
134
+ For example, on a linux system running Ruby 2.5:
135
+
136
+ ``` text
137
+ $ time gem install sqlite3 -- --enable-system-libraries
138
+ Building native extensions with: '--enable-system-libraries'
139
+ This could take a while...
140
+ Successfully installed sqlite3-1.5.0
141
+ 1 gem installed
142
+
143
+ real 0m4.234s
144
+ user 0m3.809s
145
+ sys 0m0.912s
146
+ ```
147
+
148
+ If you're using bundler, you can opt into system libraries like this:
149
+
150
+ ``` sh
151
+ bundle config build.sqlite3 --enable-system-libraries
152
+ ```
153
+
154
+ If you have sqlite3 installed in a non-standard location, you may need to specify the location of the include and lib files by using `--with-sqlite-include` and `--with-sqlite-lib` options (or a `--with-sqlite-dir` option, see [MakeMakefile#dir_config](https://ruby-doc.org/stdlib-3.1.1/libdoc/mkmf/rdoc/MakeMakefile.html#method-i-dir_config)). If you have pkg-config installed and configured properly, this may not be necessary.
155
+
156
+ ``` sh
157
+ gem install sqlite3 -- \
158
+ --enable-system-libraries \
159
+ --with-sqlite3-include=/opt/local/include \
160
+ --with-sqlite3-lib=/opt/local/lib
161
+ ```
162
+
163
+
164
+ #### System libsqlcipher
165
+
166
+ If you'd like to link against a system-installed libsqlcipher, you may do so by using the `--with-sqlcipher` flag:
167
+
168
+ ``` text
169
+ $ time gem install sqlite3 -- --with-sqlcipher
170
+ Building native extensions with: '--with-sqlcipher'
171
+ This could take a while...
172
+ Successfully installed sqlite3-1.5.0
173
+ 1 gem installed
174
+
175
+ real 0m4.772s
176
+ user 0m3.906s
177
+ sys 0m0.896s
178
+ ```
179
+
180
+ If you have sqlcipher installed in a non-standard location, you may need to specify the location of the include and lib files by using `--with-sqlite-include` and `--with-sqlite-lib` options (or a `--with-sqlite-dir` option, see [MakeMakefile#dir_config](https://ruby-doc.org/stdlib-3.1.1/libdoc/mkmf/rdoc/MakeMakefile.html#method-i-dir_config)). If you have pkg-config installed and configured properly, this may not be necessary.
181
+
182
+
183
+ ## Using SQLite3 extensions
184
+
185
+ ### How do I load a sqlite extension?
186
+
187
+ Some add-ons are available to sqlite as "extensions". The instructions that upstream sqlite provides at https://www.sqlite.org/loadext.html are the canonical source of advice, but here's a brief example showing how you can do this with the `sqlite3` ruby gem.
188
+
189
+ In this example, I'll be loading the ["spellfix" extension](https://www.sqlite.org/spellfix1.html):
190
+
191
+ ``` text
192
+ # download spellfix.c from somewherehttp://www.sqlite.org/src/finfo?name=ext/misc/spellfix.c
193
+ $ wget https://raw.githubusercontent.com/sqlite/sqlite/master/ext/misc/spellfix.c
194
+ spellfix.c 100%[=================================================>] 100.89K --.-KB/s in 0.09s
195
+
196
+ # follow instructions at https://www.sqlite.org/loadext.html
197
+ # (you will need sqlite3 development packages for this)
198
+ $ gcc -g -fPIC -shared spellfix.c -o spellfix.o
199
+
200
+ $ ls -lt
201
+ total 192
202
+ -rwxrwxr-x 1 flavorjones flavorjones 87984 2023-05-24 10:44 spellfix.o
203
+ -rw-rw-r-- 1 flavorjones flavorjones 103310 2023-05-24 10:43 spellfix.c
204
+ ```
205
+
206
+ Then, in your application, use that `spellfix.o` file like this:
207
+
208
+ ``` ruby
209
+ require "sqlite3"
210
+
211
+ db = SQLite3::Database.new(':memory:')
212
+ db.enable_load_extension(true)
213
+ db.load_extension("/path/to/sqlite/spellfix.o")
214
+ db.execute("CREATE VIRTUAL TABLE demo USING spellfix1;")
215
+ ```
216
+
217
+ ### How do I use my own sqlite3 shared library?
218
+
219
+ Some folks have strong opinions about what features they want compiled into sqlite3; or may be using a package like SQLite Encryption Extension ("SEE"). This section will explain how to get your Ruby application to load that specific shared library.
220
+
221
+ If you've installed your alternative as an autotools-style installation, the directory structure will look like this:
222
+
223
+ ```
224
+ /opt/sqlite3
225
+ ├── bin
226
+ │   └── sqlite3
227
+ ├── include
228
+ │   ├── sqlite3.h
229
+ │   └── sqlite3ext.h
230
+ ├── lib
231
+ │   ├── libsqlite3.a
232
+ │   ├── libsqlite3.la
233
+ │   ├── libsqlite3.so -> libsqlite3.so.0.8.6
234
+ │   ├── libsqlite3.so.0 -> libsqlite3.so.0.8.6
235
+ │   ├── libsqlite3.so.0.8.6
236
+ │   └── pkgconfig
237
+ │   └── sqlite3.pc
238
+ └── share
239
+ └── man
240
+ └── man1
241
+ └── sqlite3.1
242
+ ```
243
+
244
+ You can build this gem against that library like this:
245
+
246
+ ```
247
+ gem install sqlite3 --platform=ruby -- \
248
+ --enable-system-libraries \
249
+ --with-opt-dir=/opt/sqlite
250
+ ```
251
+
252
+ Explanation:
253
+
254
+ - use `--platform=ruby` to avoid the precompiled native gems (see the README)
255
+ - the `--` separates arguments passed to "gem install" from arguments passed to the C extension builder
256
+ - use `--enable-system-libraries` to avoid the vendored sqlite3 source
257
+ - use `--with-opt-dir=/path/to/installation` to point the build process at the desired header files and shared object files
258
+
259
+ Alternatively, if you've simply downloaded an "amalgamation" and so your compiled library and header files are in arbitrary locations, try this more detailed command:
260
+
261
+ ```
262
+ gem install sqlite3 --platform=ruby -- \
263
+ --enable-system-libraries \
264
+ --with-opt-include=/path/to/include \
265
+ --with-opt-lib=/path/to/lib
266
+ ```
267
+