sqlite3 1.3.7 → 1.3.13
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.
- checksums.yaml +7 -0
- data/CHANGELOG.rdoc +45 -1
- data/Gemfile +15 -0
- data/Manifest.txt +2 -0
- data/README.rdoc +29 -6
- data/ext/sqlite3/database.c +95 -22
- data/ext/sqlite3/extconf.rb +27 -7
- data/ext/sqlite3/sqlite3.c +112 -0
- data/ext/sqlite3/sqlite3_ruby.h +3 -4
- data/ext/sqlite3/statement.c +27 -18
- data/faq/faq.yml +1 -1
- data/lib/sqlite3/database.rb +34 -22
- data/lib/sqlite3/pragmas.rb +357 -49
- data/lib/sqlite3/resultset.rb +1 -1
- data/lib/sqlite3/version.rb +2 -2
- data/lib/sqlite3.rb +5 -0
- data/setup.rb +2 -2
- data/tasks/gem.rake +12 -6
- data/tasks/native.rake +22 -7
- data/tasks/vendor_sqlite3.rake +66 -20
- data/test/helper.rb +8 -4
- data/test/test_database.rb +95 -4
- data/test/test_database_readonly.rb +9 -2
- data/test/test_encoding.rb +34 -0
- data/test/test_integration.rb +35 -14
- data/test/test_integration_pending.rb +1 -1
- data/test/test_sqlite3.rb +12 -0
- data/test/test_statement.rb +14 -3
- metadata +120 -118
- data/.gemtest +0 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: b430789a68a6d6079e0395db6fc53421e4b317ab
|
|
4
|
+
data.tar.gz: db014f4a1f4e980913a3dcb48d9aab14a5a9eca1
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 7e2764239b107677240476bb608bcb46cc0966c06d06e90881113b91dbdb8342c6c7558760cf0645a56449ac8e267f13a0e25dbef0d3e820a38f5857a96c4e05
|
|
7
|
+
data.tar.gz: 1e08a478ed043d22bbe95df2151bf009a7f03a1457c37df4199c8601fa1ccb9de27986e64341c4fb9a009e5ab4023638704078222f88441b55ac1ee2773838d8
|
data/CHANGELOG.rdoc
CHANGED
|
@@ -1,7 +1,51 @@
|
|
|
1
|
-
=== 1.3.
|
|
1
|
+
=== 1.3.12
|
|
2
|
+
|
|
3
|
+
* Bugfixes:
|
|
4
|
+
* OS X install will default to homebrew if available. Fixes #195
|
|
5
|
+
|
|
6
|
+
=== 1.3.11 / 2015-10-10
|
|
7
|
+
|
|
8
|
+
* Enhancements:
|
|
9
|
+
* Windows: build against SQLite 3.8.11.1
|
|
10
|
+
|
|
11
|
+
* Internal:
|
|
12
|
+
* Use rake-compiler-dock to build Windows binaries. Pull #159 [larskanis]
|
|
13
|
+
* Expand Ruby versions being tested for Travis and AppVeyor
|
|
14
|
+
|
|
15
|
+
=== 1.3.10 / 2014-10-30
|
|
16
|
+
|
|
17
|
+
* Enhancements:
|
|
18
|
+
* Windows: build against SQLite 3.8.7.1. Closes #134, #135 [Hubro]
|
|
19
|
+
|
|
20
|
+
=== 1.3.9 / 2014-02-25
|
|
21
|
+
|
|
22
|
+
* Bugfixes:
|
|
23
|
+
* Reset exception message. Closes #80
|
|
24
|
+
* Reduce warnings due unused pointers. Closes #89
|
|
25
|
+
* Add BSD-3 license reference to gemspec. Refs #99 and #106
|
|
26
|
+
|
|
27
|
+
=== 1.3.8 / 2013-08-17
|
|
28
|
+
|
|
29
|
+
* Enhancements:
|
|
30
|
+
* Windows: build against SQLite 3.7.17
|
|
31
|
+
|
|
32
|
+
* Bugfixes:
|
|
33
|
+
* Reset exception message. Closes #80
|
|
34
|
+
* Correctly convert BLOB values to Ruby. Closes #65
|
|
35
|
+
* Add MIT license reference to gemspec. Closes #99
|
|
36
|
+
* Remove unused pointer. Closes #89
|
|
37
|
+
|
|
38
|
+
* Internal:
|
|
39
|
+
* Backport improvements in cross compilation for Windows
|
|
40
|
+
* Use of Minitest for internal tests
|
|
41
|
+
* Use Gemfile (generated by Hoe) to deal with dependencies
|
|
42
|
+
* Cleanup Travis CI
|
|
43
|
+
|
|
44
|
+
=== 1.3.7 / 2013-01-11
|
|
2
45
|
|
|
3
46
|
* Bugfixes
|
|
4
47
|
* Closing a bad statement twice will not segv.
|
|
48
|
+
* Aggregate handlers are initialized on each query. Closes #44
|
|
5
49
|
|
|
6
50
|
* Internal
|
|
7
51
|
* Unset environment variables that could affect cross compilation.
|
data/Gemfile
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# -*- ruby -*-
|
|
2
|
+
|
|
3
|
+
# DO NOT EDIT THIS FILE. Instead, edit Rakefile, and run `rake bundler:gemfile`.
|
|
4
|
+
|
|
5
|
+
source "https://rubygems.org/"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
gem "minitest", "~>5.9", :group => [:development, :test]
|
|
9
|
+
gem "rake-compiler", "~>0.9.3", :group => [:development, :test]
|
|
10
|
+
gem "rake-compiler-dock", "~>0.5.2", :group => [:development, :test]
|
|
11
|
+
gem "mini_portile", "~>0.6.2", :group => [:development, :test]
|
|
12
|
+
gem "hoe-bundler", "~>1.0", :group => [:development, :test]
|
|
13
|
+
gem "hoe", "~>3.15", :group => [:development, :test]
|
|
14
|
+
|
|
15
|
+
# vim: syntax=ruby
|
data/Manifest.txt
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
API_CHANGES.rdoc
|
|
2
2
|
CHANGELOG.rdoc
|
|
3
3
|
ChangeLog.cvs
|
|
4
|
+
Gemfile
|
|
4
5
|
LICENSE
|
|
5
6
|
Manifest.txt
|
|
6
7
|
README.rdoc
|
|
@@ -45,6 +46,7 @@ test/test_integration_open_close.rb
|
|
|
45
46
|
test/test_integration_pending.rb
|
|
46
47
|
test/test_integration_resultset.rb
|
|
47
48
|
test/test_integration_statement.rb
|
|
49
|
+
test/test_result_set.rb
|
|
48
50
|
test/test_sqlite3.rb
|
|
49
51
|
test/test_statement.rb
|
|
50
52
|
test/test_statement_execute.rb
|
data/README.rdoc
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
= SQLite3/Ruby Interface
|
|
2
2
|
|
|
3
|
-
*
|
|
3
|
+
* https://github.com/sparklemotion/sqlite3-ruby
|
|
4
4
|
* http://groups.google.com/group/sqlite3-ruby
|
|
5
|
+
* http://rubygems.org/gems/sqlite3
|
|
6
|
+
* http://www.rubydoc.info/gems/sqlite3/frames
|
|
7
|
+
|
|
8
|
+
{<img src="https://travis-ci.org/sparklemotion/sqlite3-ruby.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/sparklemotion/sqlite3-ruby]
|
|
5
9
|
|
|
6
10
|
== DESCRIPTION
|
|
7
11
|
|
|
@@ -18,7 +22,7 @@ Note that this module is only compatible with SQLite 3.6.16 or newer.
|
|
|
18
22
|
# Open a database
|
|
19
23
|
db = SQLite3::Database.new "test.db"
|
|
20
24
|
|
|
21
|
-
# Create a
|
|
25
|
+
# Create a table
|
|
22
26
|
rows = db.execute <<-SQL
|
|
23
27
|
create table numbers (
|
|
24
28
|
name varchar(30),
|
|
@@ -33,12 +37,31 @@ Note that this module is only compatible with SQLite 3.6.16 or newer.
|
|
|
33
37
|
}.each do |pair|
|
|
34
38
|
db.execute "insert into numbers values ( ?, ? )", pair
|
|
35
39
|
end
|
|
36
|
-
|
|
40
|
+
|
|
37
41
|
# Find a few rows
|
|
38
42
|
db.execute( "select * from numbers" ) do |row|
|
|
39
43
|
p row
|
|
40
44
|
end
|
|
41
45
|
|
|
46
|
+
# Create another table with multiple columns
|
|
47
|
+
|
|
48
|
+
db.execute <<-SQL
|
|
49
|
+
create table students (
|
|
50
|
+
name varchar(50),
|
|
51
|
+
email varchar(50),
|
|
52
|
+
grade varchar(5),
|
|
53
|
+
blog varchar(50)
|
|
54
|
+
);
|
|
55
|
+
SQL
|
|
56
|
+
|
|
57
|
+
# Execute inserts with parameter markers
|
|
58
|
+
db.execute("INSERT INTO students (name, email, grade, blog)
|
|
59
|
+
VALUES (?, ?, ?, ?)", ["Jane", "me@janedoe.com", "A", "http://blog.janedoe.com"])
|
|
60
|
+
|
|
61
|
+
db.execute( "select * from students" ) do |row|
|
|
62
|
+
p row
|
|
63
|
+
end
|
|
64
|
+
|
|
42
65
|
|
|
43
66
|
== Compilation and Installation
|
|
44
67
|
|
|
@@ -75,10 +98,10 @@ can be found here:
|
|
|
75
98
|
|
|
76
99
|
Uh oh. After contacting the mailing list, you've found that you've actually
|
|
77
100
|
discovered a bug. You can file the bug at the
|
|
78
|
-
{github issues page}[
|
|
101
|
+
{github issues page}[https://github.com/sparklemotion/sqlite3-ruby/issues]
|
|
79
102
|
which can be found here:
|
|
80
103
|
|
|
81
|
-
*
|
|
104
|
+
* https://github.com/sparklemotion/sqlite3-ruby/issues
|
|
82
105
|
|
|
83
106
|
== Usage
|
|
84
107
|
|
|
@@ -91,5 +114,5 @@ FAQ, please send them to {the mailing list}[http://groups.google.com/group/sqlit
|
|
|
91
114
|
|
|
92
115
|
The source repository is accessible via git:
|
|
93
116
|
|
|
94
|
-
git clone git://github.com/
|
|
117
|
+
git clone git://github.com/sparklemotion/sqlite3-ruby.git
|
|
95
118
|
|
data/ext/sqlite3/database.c
CHANGED
|
@@ -30,6 +30,8 @@ utf16_string_value_ptr(VALUE str)
|
|
|
30
30
|
return RSTRING_PTR(str);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
static VALUE sqlite3_rb_close(VALUE self);
|
|
34
|
+
|
|
33
35
|
/* call-seq: SQLite3::Database.new(file, options = {})
|
|
34
36
|
*
|
|
35
37
|
* Create a new Database object that opens the given file. If utf16
|
|
@@ -44,6 +46,7 @@ static VALUE initialize(int argc, VALUE *argv, VALUE self)
|
|
|
44
46
|
VALUE file;
|
|
45
47
|
VALUE opts;
|
|
46
48
|
VALUE zvfs;
|
|
49
|
+
VALUE flags;
|
|
47
50
|
#ifdef HAVE_SQLITE3_OPEN_V2
|
|
48
51
|
int mode = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
|
|
49
52
|
#endif
|
|
@@ -77,11 +80,37 @@ static VALUE initialize(int argc, VALUE *argv, VALUE self)
|
|
|
77
80
|
}
|
|
78
81
|
#endif
|
|
79
82
|
|
|
83
|
+
/* The three primary flag values for sqlite3_open_v2 are:
|
|
84
|
+
* SQLITE_OPEN_READONLY
|
|
85
|
+
* SQLITE_OPEN_READWRITE
|
|
86
|
+
* SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE -- always used for sqlite3_open and sqlite3_open16
|
|
87
|
+
*/
|
|
80
88
|
if (Qtrue == rb_hash_aref(opts, ID2SYM(rb_intern("readonly")))) {
|
|
81
89
|
#ifdef HAVE_SQLITE3_OPEN_V2
|
|
82
90
|
mode = SQLITE_OPEN_READONLY;
|
|
83
91
|
#else
|
|
84
92
|
rb_raise(rb_eNotImpError, "sqlite3-ruby was compiled against a version of sqlite that does not support readonly databases");
|
|
93
|
+
#endif
|
|
94
|
+
}
|
|
95
|
+
if (Qtrue == rb_hash_aref(opts, ID2SYM(rb_intern("readwrite")))) {
|
|
96
|
+
#ifdef HAVE_SQLITE3_OPEN_V2
|
|
97
|
+
if (mode == SQLITE_OPEN_READONLY) {
|
|
98
|
+
rb_raise(rb_eRuntimeError, "conflicting options: readonly and readwrite");
|
|
99
|
+
}
|
|
100
|
+
mode = SQLITE_OPEN_READWRITE;
|
|
101
|
+
#else
|
|
102
|
+
rb_raise(rb_eNotImpError, "sqlite3-ruby was compiled against a version of sqlite that does not support readwrite without create");
|
|
103
|
+
#endif
|
|
104
|
+
}
|
|
105
|
+
flags = rb_hash_aref(opts, ID2SYM(rb_intern("flags")));
|
|
106
|
+
if (flags != Qnil) {
|
|
107
|
+
#ifdef HAVE_SQLITE3_OPEN_V2
|
|
108
|
+
if ((mode & SQLITE_OPEN_CREATE) == 0) {
|
|
109
|
+
rb_raise(rb_eRuntimeError, "conflicting options: flags with readonly and/or readwrite");
|
|
110
|
+
}
|
|
111
|
+
mode = (int)NUM2INT(flags);
|
|
112
|
+
#else
|
|
113
|
+
rb_raise(rb_eNotImpError, "sqlite3-ruby was compiled against a version of sqlite that does not support flags on open");
|
|
85
114
|
#endif
|
|
86
115
|
}
|
|
87
116
|
#ifdef HAVE_SQLITE3_OPEN_V2
|
|
@@ -114,14 +143,13 @@ static VALUE initialize(int argc, VALUE *argv, VALUE self)
|
|
|
114
143
|
rb_iv_set(self, "@results_as_hash", rb_hash_aref(opts, sym_results_as_hash));
|
|
115
144
|
rb_iv_set(self, "@type_translation", rb_hash_aref(opts, sym_type_translation));
|
|
116
145
|
#ifdef HAVE_SQLITE3_OPEN_V2
|
|
117
|
-
rb_iv_set(self, "@readonly", mode
|
|
146
|
+
rb_iv_set(self, "@readonly", (mode & SQLITE_OPEN_READONLY) ? Qtrue : Qfalse);
|
|
118
147
|
#else
|
|
119
148
|
rb_iv_set(self, "@readonly", Qfalse);
|
|
120
149
|
#endif
|
|
121
150
|
|
|
122
151
|
if(rb_block_given_p()) {
|
|
123
|
-
rb_yield
|
|
124
|
-
rb_funcall(self, rb_intern("close"), 0);
|
|
152
|
+
rb_ensure(rb_yield, self, sqlite3_rb_close, self);
|
|
125
153
|
}
|
|
126
154
|
|
|
127
155
|
return self;
|
|
@@ -281,9 +309,23 @@ static VALUE sqlite3val2rb(sqlite3_value * val)
|
|
|
281
309
|
case SQLITE_TEXT:
|
|
282
310
|
return rb_tainted_str_new2((const char *)sqlite3_value_text(val));
|
|
283
311
|
break;
|
|
284
|
-
case SQLITE_BLOB:
|
|
285
|
-
|
|
312
|
+
case SQLITE_BLOB: {
|
|
313
|
+
/* Sqlite warns calling sqlite3_value_bytes may invalidate pointer from sqlite3_value_blob,
|
|
314
|
+
so we explicitly get the length before getting blob pointer.
|
|
315
|
+
Note that rb_str_new and rb_tainted_str_new apparently create string with ASCII-8BIT (BINARY) encoding,
|
|
316
|
+
which is what we want, as blobs are binary
|
|
317
|
+
*/
|
|
318
|
+
int len = sqlite3_value_bytes(val);
|
|
319
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
|
320
|
+
return rb_tainted_str_new((const char *)sqlite3_value_blob(val), len);
|
|
321
|
+
#else
|
|
322
|
+
/* When encoding is not available, make it class SQLite3::Blob. */
|
|
323
|
+
VALUE strargv[1];
|
|
324
|
+
strargv[0] = rb_tainted_str_new((const char *)sqlite3_value_blob(val), len);
|
|
325
|
+
return rb_class_new_instance(1, strargv, cSqlite3Blob);
|
|
326
|
+
#endif
|
|
286
327
|
break;
|
|
328
|
+
}
|
|
287
329
|
case SQLITE_NULL:
|
|
288
330
|
return Qnil;
|
|
289
331
|
break;
|
|
@@ -301,23 +343,39 @@ static void set_sqlite3_func_result(sqlite3_context * ctx, VALUE result)
|
|
|
301
343
|
case T_FIXNUM:
|
|
302
344
|
sqlite3_result_int64(ctx, (sqlite3_int64)FIX2LONG(result));
|
|
303
345
|
break;
|
|
304
|
-
case T_BIGNUM:
|
|
346
|
+
case T_BIGNUM: {
|
|
305
347
|
#if SIZEOF_LONG < 8
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
348
|
+
sqlite3_int64 num64;
|
|
349
|
+
|
|
350
|
+
if (bignum_to_int64(result, &num64)) {
|
|
351
|
+
sqlite3_result_int64(ctx, num64);
|
|
352
|
+
break;
|
|
309
353
|
}
|
|
310
354
|
#endif
|
|
355
|
+
}
|
|
311
356
|
case T_FLOAT:
|
|
312
357
|
sqlite3_result_double(ctx, NUM2DBL(result));
|
|
313
358
|
break;
|
|
314
359
|
case T_STRING:
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
360
|
+
if(CLASS_OF(result) == cSqlite3Blob
|
|
361
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
|
362
|
+
|| rb_enc_get_index(result) == rb_ascii8bit_encindex()
|
|
363
|
+
#endif
|
|
364
|
+
) {
|
|
365
|
+
sqlite3_result_blob(
|
|
366
|
+
ctx,
|
|
367
|
+
(const void *)StringValuePtr(result),
|
|
368
|
+
(int)RSTRING_LEN(result),
|
|
369
|
+
SQLITE_TRANSIENT
|
|
370
|
+
);
|
|
371
|
+
} else {
|
|
372
|
+
sqlite3_result_text(
|
|
373
|
+
ctx,
|
|
374
|
+
(const char *)StringValuePtr(result),
|
|
375
|
+
(int)RSTRING_LEN(result),
|
|
376
|
+
SQLITE_TRANSIENT
|
|
377
|
+
);
|
|
378
|
+
}
|
|
321
379
|
break;
|
|
322
380
|
default:
|
|
323
381
|
rb_raise(rb_eRuntimeError, "can't return %s",
|
|
@@ -328,22 +386,18 @@ static void set_sqlite3_func_result(sqlite3_context * ctx, VALUE result)
|
|
|
328
386
|
static void rb_sqlite3_func(sqlite3_context * ctx, int argc, sqlite3_value **argv)
|
|
329
387
|
{
|
|
330
388
|
VALUE callable = (VALUE)sqlite3_user_data(ctx);
|
|
331
|
-
VALUE
|
|
389
|
+
VALUE params = rb_ary_new2(argc);
|
|
332
390
|
VALUE result;
|
|
333
391
|
int i;
|
|
334
392
|
|
|
335
393
|
if (argc > 0) {
|
|
336
|
-
params = xcalloc((size_t)argc, sizeof(VALUE *));
|
|
337
|
-
|
|
338
394
|
for(i = 0; i < argc; i++) {
|
|
339
395
|
VALUE param = sqlite3val2rb(argv[i]);
|
|
340
|
-
|
|
341
|
-
params[i] = param;
|
|
396
|
+
rb_ary_push(params, param);
|
|
342
397
|
}
|
|
343
398
|
}
|
|
344
399
|
|
|
345
|
-
result =
|
|
346
|
-
xfree(params);
|
|
400
|
+
result = rb_apply(callable, rb_intern("call"), params);
|
|
347
401
|
|
|
348
402
|
set_sqlite3_func_result(ctx, result);
|
|
349
403
|
}
|
|
@@ -768,6 +822,24 @@ static VALUE transaction_active_p(VALUE self)
|
|
|
768
822
|
return sqlite3_get_autocommit(ctx->db) ? Qfalse : Qtrue;
|
|
769
823
|
}
|
|
770
824
|
|
|
825
|
+
/* call-seq: db.db_filename(database_name)
|
|
826
|
+
*
|
|
827
|
+
* Returns the file associated with +database_name+. Can return nil or an
|
|
828
|
+
* empty string if the database is temporary, or in-memory.
|
|
829
|
+
*/
|
|
830
|
+
static VALUE db_filename(VALUE self, VALUE db_name)
|
|
831
|
+
{
|
|
832
|
+
sqlite3RubyPtr ctx;
|
|
833
|
+
const char * fname;
|
|
834
|
+
Data_Get_Struct(self, sqlite3Ruby, ctx);
|
|
835
|
+
REQUIRE_OPEN_DB(ctx);
|
|
836
|
+
|
|
837
|
+
fname = sqlite3_db_filename(ctx->db, StringValueCStr(db_name));
|
|
838
|
+
|
|
839
|
+
if(fname) return SQLITE3_UTF8_STR_NEW2(fname);
|
|
840
|
+
return Qnil;
|
|
841
|
+
}
|
|
842
|
+
|
|
771
843
|
void init_sqlite3_database()
|
|
772
844
|
{
|
|
773
845
|
ID id_utf16, id_results_as_hash, id_type_translation;
|
|
@@ -795,6 +867,7 @@ void init_sqlite3_database()
|
|
|
795
867
|
rb_define_method(cSqlite3Database, "busy_handler", busy_handler, -1);
|
|
796
868
|
rb_define_method(cSqlite3Database, "busy_timeout=", set_busy_timeout, 1);
|
|
797
869
|
rb_define_method(cSqlite3Database, "transaction_active?", transaction_active_p, 0);
|
|
870
|
+
rb_define_private_method(cSqlite3Database, "db_filename", db_filename, 1);
|
|
798
871
|
|
|
799
872
|
#ifdef HAVE_SQLITE3_LOAD_EXTENSION
|
|
800
873
|
rb_define_method(cSqlite3Database, "load_extension", load_extension, 1);
|
data/ext/sqlite3/extconf.rb
CHANGED
|
@@ -6,14 +6,29 @@ require 'mkmf'
|
|
|
6
6
|
|
|
7
7
|
RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
|
|
8
8
|
|
|
9
|
-
# --with-sqlite3-{dir,include,lib}
|
|
10
|
-
dir_config("sqlite3")
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
|
|
11
|
+
ldflags = cppflags = nil
|
|
12
|
+
if RbConfig::CONFIG["host_os"] =~ /darwin/
|
|
13
|
+
begin
|
|
14
|
+
brew_prefix = `brew --prefix sqlite3`.chomp
|
|
15
|
+
ldflags = "#{brew_prefix}/lib"
|
|
16
|
+
cppflags = "#{brew_prefix}/include"
|
|
17
|
+
pkg_conf = "#{brew_prefix}/lib/pkgconfig"
|
|
18
|
+
|
|
19
|
+
# pkg_config should be less error prone than parsing compiler
|
|
20
|
+
# commandline options, but we need to set default ldflags and cpp flags
|
|
21
|
+
# in case the user doesn't have pkg-config installed
|
|
22
|
+
ENV['PKG_CONFIG_PATH'] ||= pkg_conf
|
|
23
|
+
rescue
|
|
24
|
+
end
|
|
15
25
|
end
|
|
16
26
|
|
|
27
|
+
pkg_config("sqlite3")
|
|
28
|
+
|
|
29
|
+
# --with-sqlite3-{dir,include,lib}
|
|
30
|
+
dir_config("sqlite3", cppflags, ldflags)
|
|
31
|
+
|
|
17
32
|
if RbConfig::CONFIG["host_os"] =~ /mswin/
|
|
18
33
|
$CFLAGS << ' -W3'
|
|
19
34
|
end
|
|
@@ -24,19 +39,24 @@ def asplode missing
|
|
|
24
39
|
"http://www.sqlite.org/ first."
|
|
25
40
|
else
|
|
26
41
|
abort <<-error
|
|
27
|
-
#{missing} is missing. Try '
|
|
28
|
-
|
|
42
|
+
#{missing} is missing. Try 'brew install sqlite3',
|
|
43
|
+
'yum install sqlite-devel' or 'apt-get install libsqlite3-dev'
|
|
44
|
+
and check your shared library search path (the
|
|
29
45
|
location where your sqlite3 shared library is located).
|
|
30
46
|
error
|
|
31
47
|
end
|
|
32
48
|
end
|
|
33
49
|
|
|
34
50
|
asplode('sqlite3.h') unless find_header 'sqlite3.h'
|
|
51
|
+
find_library 'pthread', 'pthread_create' # 1.8 support. *shrug*
|
|
35
52
|
asplode('sqlite3') unless find_library 'sqlite3', 'sqlite3_libversion_number'
|
|
36
53
|
|
|
37
54
|
# Functions defined in 1.9 but not 1.8
|
|
38
55
|
have_func('rb_proc_arity')
|
|
39
56
|
|
|
57
|
+
# Functions defined in 2.1 but not 2.0
|
|
58
|
+
have_func('rb_integer_pack')
|
|
59
|
+
|
|
40
60
|
# These functions may not be defined
|
|
41
61
|
have_func('sqlite3_initialize')
|
|
42
62
|
have_func('sqlite3_backup_init')
|
data/ext/sqlite3/sqlite3.c
CHANGED
|
@@ -3,11 +3,121 @@
|
|
|
3
3
|
VALUE mSqlite3;
|
|
4
4
|
VALUE cSqlite3Blob;
|
|
5
5
|
|
|
6
|
+
int bignum_to_int64(VALUE value, sqlite3_int64 *result)
|
|
7
|
+
{
|
|
8
|
+
#ifdef HAVE_RB_INTEGER_PACK
|
|
9
|
+
const int nails = 0;
|
|
10
|
+
int t = rb_integer_pack(value, result, 1, sizeof(*result), nails,
|
|
11
|
+
INTEGER_PACK_NATIVE_BYTE_ORDER|
|
|
12
|
+
INTEGER_PACK_2COMP);
|
|
13
|
+
switch (t) {
|
|
14
|
+
case -2: case +2:
|
|
15
|
+
return 0;
|
|
16
|
+
case +1:
|
|
17
|
+
if (!nails) {
|
|
18
|
+
if (*result < 0) return 0;
|
|
19
|
+
}
|
|
20
|
+
break;
|
|
21
|
+
case -1:
|
|
22
|
+
if (!nails) {
|
|
23
|
+
if (*result >= 0) return 0;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
*result += INT64_MIN;
|
|
27
|
+
}
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
return 1;
|
|
31
|
+
#else
|
|
32
|
+
# ifndef RBIGNUM_LEN
|
|
33
|
+
# define RBIGNUM_LEN(x) RBIGNUM(x)->len
|
|
34
|
+
# endif
|
|
35
|
+
const long len = RBIGNUM_LEN(value);
|
|
36
|
+
if (len == 0) {
|
|
37
|
+
*result = 0;
|
|
38
|
+
return 1;
|
|
39
|
+
}
|
|
40
|
+
if (len > 63 / (SIZEOF_BDIGITS * CHAR_BIT) + 1) return 0;
|
|
41
|
+
if (len == 63 / (SIZEOF_BDIGITS * CHAR_BIT) + 1) {
|
|
42
|
+
const BDIGIT *digits = RBIGNUM_DIGITS(value);
|
|
43
|
+
BDIGIT blast = digits[len-1];
|
|
44
|
+
BDIGIT bmax = (BDIGIT)1UL << (63 % (CHAR_BIT * SIZEOF_BDIGITS));
|
|
45
|
+
if (blast > bmax) return 0;
|
|
46
|
+
if (blast == bmax) {
|
|
47
|
+
if (RBIGNUM_POSITIVE_P(value)) {
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
long i = len-1;
|
|
52
|
+
while (i) {
|
|
53
|
+
if (digits[--i]) return 0;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
*result = (sqlite3_int64)NUM2LL(value);
|
|
59
|
+
return 1;
|
|
60
|
+
#endif
|
|
61
|
+
}
|
|
62
|
+
|
|
6
63
|
static VALUE libversion(VALUE UNUSED(klass))
|
|
7
64
|
{
|
|
8
65
|
return INT2NUM(sqlite3_libversion_number());
|
|
9
66
|
}
|
|
10
67
|
|
|
68
|
+
/* Returns the compile time setting of the SQLITE_THREADSAFE flag.
|
|
69
|
+
* See: https://www.sqlite.org/c3ref/threadsafe.html
|
|
70
|
+
*/
|
|
71
|
+
static VALUE threadsafe_p(VALUE UNUSED(klass))
|
|
72
|
+
{
|
|
73
|
+
return INT2NUM(sqlite3_threadsafe());
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
void init_sqlite3_constants()
|
|
77
|
+
{
|
|
78
|
+
VALUE mSqlite3Constants;
|
|
79
|
+
VALUE mSqlite3Open;
|
|
80
|
+
|
|
81
|
+
mSqlite3Constants = rb_define_module_under(mSqlite3, "Constants");
|
|
82
|
+
|
|
83
|
+
/* sqlite3_open_v2 flags for Database::new */
|
|
84
|
+
mSqlite3Open = rb_define_module_under(mSqlite3Constants, "Open");
|
|
85
|
+
|
|
86
|
+
/* symbols = IO.readlines('sqlite3.h').map { |n| /\A#define\s+(SQLITE_OPEN_\w+)\s/ =~ n && $1 }.compact
|
|
87
|
+
* pad = symbols.map(&:length).max - 9
|
|
88
|
+
* symbols.each { |s| printf %Q{ rb_define_const(mSqlite3Open, %-#{pad}s INT2FIX(#{s}));\n}, '"' + s[12..-1] + '",' }
|
|
89
|
+
*/
|
|
90
|
+
rb_define_const(mSqlite3Open, "READONLY", INT2FIX(SQLITE_OPEN_READONLY));
|
|
91
|
+
rb_define_const(mSqlite3Open, "READWRITE", INT2FIX(SQLITE_OPEN_READWRITE));
|
|
92
|
+
rb_define_const(mSqlite3Open, "CREATE", INT2FIX(SQLITE_OPEN_CREATE));
|
|
93
|
+
rb_define_const(mSqlite3Open, "DELETEONCLOSE", INT2FIX(SQLITE_OPEN_DELETEONCLOSE));
|
|
94
|
+
rb_define_const(mSqlite3Open, "EXCLUSIVE", INT2FIX(SQLITE_OPEN_EXCLUSIVE));
|
|
95
|
+
rb_define_const(mSqlite3Open, "MAIN_DB", INT2FIX(SQLITE_OPEN_MAIN_DB));
|
|
96
|
+
rb_define_const(mSqlite3Open, "TEMP_DB", INT2FIX(SQLITE_OPEN_TEMP_DB));
|
|
97
|
+
rb_define_const(mSqlite3Open, "TRANSIENT_DB", INT2FIX(SQLITE_OPEN_TRANSIENT_DB));
|
|
98
|
+
rb_define_const(mSqlite3Open, "MAIN_JOURNAL", INT2FIX(SQLITE_OPEN_MAIN_JOURNAL));
|
|
99
|
+
rb_define_const(mSqlite3Open, "TEMP_JOURNAL", INT2FIX(SQLITE_OPEN_TEMP_JOURNAL));
|
|
100
|
+
rb_define_const(mSqlite3Open, "SUBJOURNAL", INT2FIX(SQLITE_OPEN_SUBJOURNAL));
|
|
101
|
+
rb_define_const(mSqlite3Open, "MASTER_JOURNAL", INT2FIX(SQLITE_OPEN_MASTER_JOURNAL));
|
|
102
|
+
rb_define_const(mSqlite3Open, "NOMUTEX", INT2FIX(SQLITE_OPEN_NOMUTEX));
|
|
103
|
+
rb_define_const(mSqlite3Open, "FULLMUTEX", INT2FIX(SQLITE_OPEN_FULLMUTEX));
|
|
104
|
+
#ifdef SQLITE_OPEN_AUTOPROXY
|
|
105
|
+
/* SQLITE_VERSION_NUMBER>=3007002 */
|
|
106
|
+
rb_define_const(mSqlite3Open, "AUTOPROXY", INT2FIX(SQLITE_OPEN_AUTOPROXY));
|
|
107
|
+
rb_define_const(mSqlite3Open, "SHAREDCACHE", INT2FIX(SQLITE_OPEN_SHAREDCACHE));
|
|
108
|
+
rb_define_const(mSqlite3Open, "PRIVATECACHE", INT2FIX(SQLITE_OPEN_PRIVATECACHE));
|
|
109
|
+
rb_define_const(mSqlite3Open, "WAL", INT2FIX(SQLITE_OPEN_WAL));
|
|
110
|
+
#endif
|
|
111
|
+
#ifdef SQLITE_OPEN_URI
|
|
112
|
+
/* SQLITE_VERSION_NUMBER>=3007007 */
|
|
113
|
+
rb_define_const(mSqlite3Open, "URI", INT2FIX(SQLITE_OPEN_URI));
|
|
114
|
+
#endif
|
|
115
|
+
#ifdef SQLITE_OPEN_MEMORY
|
|
116
|
+
/* SQLITE_VERSION_NUMBER>=3007013 */
|
|
117
|
+
rb_define_const(mSqlite3Open, "MEMORY", INT2FIX(SQLITE_OPEN_MEMORY));
|
|
118
|
+
#endif
|
|
119
|
+
}
|
|
120
|
+
|
|
11
121
|
void Init_sqlite3_native()
|
|
12
122
|
{
|
|
13
123
|
/*
|
|
@@ -28,6 +138,7 @@ void Init_sqlite3_native()
|
|
|
28
138
|
sqlite3_initialize();
|
|
29
139
|
#endif
|
|
30
140
|
|
|
141
|
+
init_sqlite3_constants();
|
|
31
142
|
init_sqlite3_database();
|
|
32
143
|
init_sqlite3_statement();
|
|
33
144
|
#ifdef HAVE_SQLITE3_BACKUP_INIT
|
|
@@ -35,6 +146,7 @@ void Init_sqlite3_native()
|
|
|
35
146
|
#endif
|
|
36
147
|
|
|
37
148
|
rb_define_singleton_method(mSqlite3, "libversion", libversion, 0);
|
|
149
|
+
rb_define_singleton_method(mSqlite3, "threadsafe", threadsafe_p, 0);
|
|
38
150
|
rb_define_const(mSqlite3, "SQLITE_VERSION", rb_str_new2(SQLITE_VERSION));
|
|
39
151
|
rb_define_const(mSqlite3, "SQLITE_VERSION_NUMBER", INT2FIX(SQLITE_VERSION_NUMBER));
|
|
40
152
|
}
|
data/ext/sqlite3/sqlite3_ruby.h
CHANGED
|
@@ -12,13 +12,10 @@
|
|
|
12
12
|
# define UNUSED(x) x
|
|
13
13
|
#endif
|
|
14
14
|
|
|
15
|
-
#ifndef RBIGNUM_LEN
|
|
16
|
-
#define RBIGNUM_LEN(x) RBIGNUM(x)->len
|
|
17
|
-
#endif
|
|
18
|
-
|
|
19
15
|
#ifdef HAVE_RUBY_ENCODING_H
|
|
20
16
|
#include <ruby/encoding.h>
|
|
21
17
|
|
|
18
|
+
#define USASCII_P(_obj) (rb_enc_get_index(_obj) == rb_usascii_encindex())
|
|
22
19
|
#define UTF8_P(_obj) (rb_enc_get_index(_obj) == rb_utf8_encindex())
|
|
23
20
|
#define UTF16_LE_P(_obj) (rb_enc_get_index(_obj) == rb_enc_find_index("UTF-16LE"))
|
|
24
21
|
#define UTF16_BE_P(_obj) (rb_enc_get_index(_obj) == rb_enc_find_index("UTF-16BE"))
|
|
@@ -50,4 +47,6 @@ extern VALUE cSqlite3Blob;
|
|
|
50
47
|
#include <exception.h>
|
|
51
48
|
#include <backup.h>
|
|
52
49
|
|
|
50
|
+
int bignum_to_int64(VALUE big, sqlite3_int64 *result);
|
|
51
|
+
|
|
53
52
|
#endif
|