sqlite3 1.5.0-arm64-darwin
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sqlite3 might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/.gemtest +0 -0
- data/API_CHANGES.md +49 -0
- data/CHANGELOG.md +425 -0
- data/CONTRIBUTING.md +24 -0
- data/ChangeLog.cvs +88 -0
- data/Gemfile +3 -0
- data/LICENSE +27 -0
- data/LICENSE-DEPENDENCIES +20 -0
- data/README.md +233 -0
- data/ext/sqlite3/aggregator.c +274 -0
- data/ext/sqlite3/aggregator.h +12 -0
- data/ext/sqlite3/backup.c +168 -0
- data/ext/sqlite3/backup.h +15 -0
- data/ext/sqlite3/database.c +853 -0
- data/ext/sqlite3/database.h +17 -0
- data/ext/sqlite3/exception.c +98 -0
- data/ext/sqlite3/exception.h +8 -0
- data/ext/sqlite3/extconf.rb +252 -0
- data/ext/sqlite3/sqlite3.c +163 -0
- data/ext/sqlite3/sqlite3_ruby.h +48 -0
- data/ext/sqlite3/statement.c +442 -0
- data/ext/sqlite3/statement.h +16 -0
- data/faq/faq.md +431 -0
- data/faq/faq.rb +145 -0
- data/faq/faq.yml +426 -0
- data/lib/sqlite3/2.6/sqlite3_native.bundle +0 -0
- data/lib/sqlite3/2.7/sqlite3_native.bundle +0 -0
- data/lib/sqlite3/3.0/sqlite3_native.bundle +0 -0
- data/lib/sqlite3/3.1/sqlite3_native.bundle +0 -0
- data/lib/sqlite3/constants.rb +50 -0
- data/lib/sqlite3/database.rb +741 -0
- data/lib/sqlite3/errors.rb +35 -0
- data/lib/sqlite3/pragmas.rb +595 -0
- data/lib/sqlite3/resultset.rb +187 -0
- data/lib/sqlite3/statement.rb +145 -0
- data/lib/sqlite3/translator.rb +118 -0
- data/lib/sqlite3/value.rb +57 -0
- data/lib/sqlite3/version.rb +23 -0
- data/lib/sqlite3.rb +15 -0
- data/test/helper.rb +27 -0
- data/test/test_backup.rb +33 -0
- data/test/test_collation.rb +82 -0
- data/test/test_database.rb +545 -0
- data/test/test_database_flags.rb +95 -0
- data/test/test_database_readonly.rb +36 -0
- data/test/test_database_readwrite.rb +41 -0
- data/test/test_deprecated.rb +44 -0
- data/test/test_encoding.rb +155 -0
- data/test/test_integration.rb +507 -0
- data/test/test_integration_aggregate.rb +336 -0
- data/test/test_integration_open_close.rb +30 -0
- data/test/test_integration_pending.rb +115 -0
- data/test/test_integration_resultset.rb +142 -0
- data/test/test_integration_statement.rb +194 -0
- data/test/test_result_set.rb +37 -0
- data/test/test_sqlite3.rb +30 -0
- data/test/test_statement.rb +263 -0
- data/test/test_statement_execute.rb +35 -0
- metadata +190 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
#ifndef SQLITE3_DATABASE_RUBY
|
2
|
+
#define SQLITE3_DATABASE_RUBY
|
3
|
+
|
4
|
+
#include <sqlite3_ruby.h>
|
5
|
+
|
6
|
+
struct _sqlite3Ruby {
|
7
|
+
sqlite3 *db;
|
8
|
+
};
|
9
|
+
|
10
|
+
typedef struct _sqlite3Ruby sqlite3Ruby;
|
11
|
+
typedef sqlite3Ruby * sqlite3RubyPtr;
|
12
|
+
|
13
|
+
void init_sqlite3_database();
|
14
|
+
void set_sqlite3_func_result(sqlite3_context * ctx, VALUE result);
|
15
|
+
VALUE sqlite3val2rb(sqlite3_value * val);
|
16
|
+
|
17
|
+
#endif
|
@@ -0,0 +1,98 @@
|
|
1
|
+
#include <sqlite3_ruby.h>
|
2
|
+
|
3
|
+
void rb_sqlite3_raise(sqlite3 * db, int status)
|
4
|
+
{
|
5
|
+
VALUE klass = Qnil;
|
6
|
+
|
7
|
+
/* Consider only lower 8 bits, to work correctly when
|
8
|
+
extended result codes are enabled. */
|
9
|
+
switch(status & 0xff) {
|
10
|
+
case SQLITE_OK:
|
11
|
+
return;
|
12
|
+
break;
|
13
|
+
case SQLITE_ERROR:
|
14
|
+
klass = rb_path2class("SQLite3::SQLException");
|
15
|
+
break;
|
16
|
+
case SQLITE_INTERNAL:
|
17
|
+
klass = rb_path2class("SQLite3::InternalException");
|
18
|
+
break;
|
19
|
+
case SQLITE_PERM:
|
20
|
+
klass = rb_path2class("SQLite3::PermissionException");
|
21
|
+
break;
|
22
|
+
case SQLITE_ABORT:
|
23
|
+
klass = rb_path2class("SQLite3::AbortException");
|
24
|
+
break;
|
25
|
+
case SQLITE_BUSY:
|
26
|
+
klass = rb_path2class("SQLite3::BusyException");
|
27
|
+
break;
|
28
|
+
case SQLITE_LOCKED:
|
29
|
+
klass = rb_path2class("SQLite3::LockedException");
|
30
|
+
break;
|
31
|
+
case SQLITE_NOMEM:
|
32
|
+
klass = rb_path2class("SQLite3::MemoryException");
|
33
|
+
break;
|
34
|
+
case SQLITE_READONLY:
|
35
|
+
klass = rb_path2class("SQLite3::ReadOnlyException");
|
36
|
+
break;
|
37
|
+
case SQLITE_INTERRUPT:
|
38
|
+
klass = rb_path2class("SQLite3::InterruptException");
|
39
|
+
break;
|
40
|
+
case SQLITE_IOERR:
|
41
|
+
klass = rb_path2class("SQLite3::IOException");
|
42
|
+
break;
|
43
|
+
case SQLITE_CORRUPT:
|
44
|
+
klass = rb_path2class("SQLite3::CorruptException");
|
45
|
+
break;
|
46
|
+
case SQLITE_NOTFOUND:
|
47
|
+
klass = rb_path2class("SQLite3::NotFoundException");
|
48
|
+
break;
|
49
|
+
case SQLITE_FULL:
|
50
|
+
klass = rb_path2class("SQLite3::FullException");
|
51
|
+
break;
|
52
|
+
case SQLITE_CANTOPEN:
|
53
|
+
klass = rb_path2class("SQLite3::CantOpenException");
|
54
|
+
break;
|
55
|
+
case SQLITE_PROTOCOL:
|
56
|
+
klass = rb_path2class("SQLite3::ProtocolException");
|
57
|
+
break;
|
58
|
+
case SQLITE_EMPTY:
|
59
|
+
klass = rb_path2class("SQLite3::EmptyException");
|
60
|
+
break;
|
61
|
+
case SQLITE_SCHEMA:
|
62
|
+
klass = rb_path2class("SQLite3::SchemaChangedException");
|
63
|
+
break;
|
64
|
+
case SQLITE_TOOBIG:
|
65
|
+
klass = rb_path2class("SQLite3::TooBigException");
|
66
|
+
break;
|
67
|
+
case SQLITE_CONSTRAINT:
|
68
|
+
klass = rb_path2class("SQLite3::ConstraintException");
|
69
|
+
break;
|
70
|
+
case SQLITE_MISMATCH:
|
71
|
+
klass = rb_path2class("SQLite3::MismatchException");
|
72
|
+
break;
|
73
|
+
case SQLITE_MISUSE:
|
74
|
+
klass = rb_path2class("SQLite3::MisuseException");
|
75
|
+
break;
|
76
|
+
case SQLITE_NOLFS:
|
77
|
+
klass = rb_path2class("SQLite3::UnsupportedException");
|
78
|
+
break;
|
79
|
+
case SQLITE_AUTH:
|
80
|
+
klass = rb_path2class("SQLite3::AuthorizationException");
|
81
|
+
break;
|
82
|
+
case SQLITE_FORMAT:
|
83
|
+
klass = rb_path2class("SQLite3::FormatException");
|
84
|
+
break;
|
85
|
+
case SQLITE_RANGE:
|
86
|
+
klass = rb_path2class("SQLite3::RangeException");
|
87
|
+
break;
|
88
|
+
case SQLITE_NOTADB:
|
89
|
+
klass = rb_path2class("SQLite3::NotADatabaseException");
|
90
|
+
break;
|
91
|
+
default:
|
92
|
+
klass = rb_eRuntimeError;
|
93
|
+
}
|
94
|
+
|
95
|
+
klass = rb_exc_new2(klass, sqlite3_errmsg(db));
|
96
|
+
rb_iv_set(klass, "@code", INT2FIX(status));
|
97
|
+
rb_exc_raise(klass);
|
98
|
+
}
|
@@ -0,0 +1,252 @@
|
|
1
|
+
require "mkmf"
|
2
|
+
require "mini_portile2"
|
3
|
+
|
4
|
+
module Sqlite3
|
5
|
+
module ExtConf
|
6
|
+
ENV_ALLOWLIST = ["CC", "CFLAGS", "LDFLAGS", "LIBS", "CPPFLAGS", "LT_SYS_LIBRARY_PATH", "CPP"]
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def configure
|
10
|
+
configure_cross_compiler
|
11
|
+
|
12
|
+
if system_libraries?
|
13
|
+
message "Building sqlite3-ruby using system #{libname}.\n"
|
14
|
+
configure_system_libraries
|
15
|
+
else
|
16
|
+
message "Building sqlite3-ruby using packaged sqlite3.\n"
|
17
|
+
configure_packaged_libraries
|
18
|
+
end
|
19
|
+
|
20
|
+
configure_extension
|
21
|
+
|
22
|
+
create_makefile('sqlite3/sqlite3_native')
|
23
|
+
end
|
24
|
+
|
25
|
+
def configure_cross_compiler
|
26
|
+
RbConfig::CONFIG["CC"] = RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"] if ENV["CC"]
|
27
|
+
ENV["CC"] = RbConfig::CONFIG["CC"]
|
28
|
+
end
|
29
|
+
|
30
|
+
def system_libraries?
|
31
|
+
sqlcipher? || enable_config("system-libraries")
|
32
|
+
end
|
33
|
+
|
34
|
+
def libname
|
35
|
+
sqlcipher? ? "sqlcipher" : "sqlite3"
|
36
|
+
end
|
37
|
+
|
38
|
+
def sqlcipher?
|
39
|
+
with_config("sqlcipher") ||
|
40
|
+
with_config("sqlcipher-dir") ||
|
41
|
+
with_config("sqlcipher-include") ||
|
42
|
+
with_config("sqlcipher-lib")
|
43
|
+
end
|
44
|
+
|
45
|
+
def configure_system_libraries
|
46
|
+
pkg_config(libname)
|
47
|
+
append_cppflags("-DUSING_SQLCIPHER") if sqlcipher?
|
48
|
+
end
|
49
|
+
|
50
|
+
def configure_packaged_libraries
|
51
|
+
minimal_recipe.tap do |recipe|
|
52
|
+
recipe.configure_options += ["--enable-shared=no", "--enable-static=yes"]
|
53
|
+
ENV.to_h.tap do |env|
|
54
|
+
additional_cflags = [
|
55
|
+
"-fPIC", # needed for linking the static library into a shared library
|
56
|
+
"-O2", # see https://github.com/sparklemotion/sqlite3-ruby/issues/335 for some benchmarks
|
57
|
+
]
|
58
|
+
env["CFLAGS"] = [env["CFLAGS"], additional_cflags].flatten.join(" ")
|
59
|
+
recipe.configure_options += env.select { |k,v| ENV_ALLOWLIST.include?(k) }
|
60
|
+
.map { |key, value| "#{key}=#{value.strip}" }
|
61
|
+
end
|
62
|
+
|
63
|
+
unless File.exist?(File.join(recipe.target, recipe.host, recipe.name, recipe.version))
|
64
|
+
recipe.cook
|
65
|
+
end
|
66
|
+
recipe.activate
|
67
|
+
|
68
|
+
ENV["PKG_CONFIG_ALLOW_SYSTEM_CFLAGS"] = "t" # on macos, pkg-config will not return --cflags without this
|
69
|
+
pcfile = File.join(recipe.path, "lib", "pkgconfig", "sqlite3.pc")
|
70
|
+
if pkg_config(pcfile)
|
71
|
+
# see https://bugs.ruby-lang.org/issues/18490
|
72
|
+
libs = xpopen(["pkg-config", "--libs", "--static", pcfile], err: [:child, :out], &:read)
|
73
|
+
libs.split.each { |lib| append_ldflags(lib) } if $?.success?
|
74
|
+
else
|
75
|
+
abort("\nCould not configure the build properly. Please install either the `pkg-config` utility or the `pkg-config` rubygem.\n\n")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def configure_extension
|
81
|
+
if Gem::Requirement.new("< 2.7").satisfied_by?(Gem::Version.new(RUBY_VERSION))
|
82
|
+
append_cppflags("-DTAINTING_SUPPORT")
|
83
|
+
end
|
84
|
+
|
85
|
+
if find_header("sqlite3.h")
|
86
|
+
# noop
|
87
|
+
elsif sqlcipher? && find_header("sqlcipher/sqlite3.h")
|
88
|
+
append_cppflags("-DUSING_SQLCIPHER_INC_SUBDIR")
|
89
|
+
else
|
90
|
+
abort_could_not_find("sqlite3.h")
|
91
|
+
end
|
92
|
+
|
93
|
+
abort_could_not_find(libname) unless find_library(libname, "sqlite3_libversion_number", "sqlite3.h")
|
94
|
+
|
95
|
+
# Functions defined in 1.9 but not 1.8
|
96
|
+
have_func('rb_proc_arity')
|
97
|
+
|
98
|
+
# Functions defined in 2.1 but not 2.0
|
99
|
+
have_func('rb_integer_pack')
|
100
|
+
|
101
|
+
# These functions may not be defined
|
102
|
+
have_func('sqlite3_initialize')
|
103
|
+
have_func('sqlite3_backup_init')
|
104
|
+
have_func('sqlite3_column_database_name')
|
105
|
+
have_func('sqlite3_enable_load_extension')
|
106
|
+
have_func('sqlite3_load_extension')
|
107
|
+
|
108
|
+
unless have_func('sqlite3_open_v2') # https://www.sqlite.org/releaselog/3_5_0.html
|
109
|
+
abort("\nPlease use a version of SQLite3 >= 3.5.0\n\n")
|
110
|
+
end
|
111
|
+
|
112
|
+
have_func('sqlite3_prepare_v2')
|
113
|
+
have_type('sqlite3_int64', 'sqlite3.h')
|
114
|
+
have_type('sqlite3_uint64', 'sqlite3.h')
|
115
|
+
end
|
116
|
+
|
117
|
+
def minimal_recipe
|
118
|
+
MiniPortile.new(libname, sqlite3_config[:version]).tap do |recipe|
|
119
|
+
recipe.files = sqlite3_config[:files]
|
120
|
+
recipe.target = File.join(package_root_dir, "ports")
|
121
|
+
recipe.patch_files = Dir[File.join(package_root_dir, "patches", "*.patch")].sort
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def package_root_dir
|
126
|
+
File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))
|
127
|
+
end
|
128
|
+
|
129
|
+
def sqlite3_config
|
130
|
+
mini_portile_config[:sqlite3]
|
131
|
+
end
|
132
|
+
|
133
|
+
def mini_portile_config
|
134
|
+
{
|
135
|
+
sqlite3: {
|
136
|
+
# checksum verified by first checking the published sha3(256) checksum against https://sqlite.org/download.html:
|
137
|
+
#
|
138
|
+
# $ sha3sum -a 256 ports/archives/sqlite-autoconf-3390300.tar.gz
|
139
|
+
# dfa055c70724cd63f0b7da6e9f53530d8da51fe021e3f864d58c7c847d590e1d ports/archives/sqlite-autoconf-3390300.tar.gz
|
140
|
+
#
|
141
|
+
# $ sha256sum ports/archives/sqlite-autoconf-3390300.tar.gz
|
142
|
+
# 7868fb3082be3f2cf4491c6fba6de2bddcbc293a35fefb0624ee3c13f01422b9 ports/archives/sqlite-autoconf-3390300.tar.gz
|
143
|
+
#
|
144
|
+
version: "3.39.3",
|
145
|
+
files: [{
|
146
|
+
url: "https://www.sqlite.org/2022/sqlite-autoconf-3390300.tar.gz",
|
147
|
+
sha256: "7868fb3082be3f2cf4491c6fba6de2bddcbc293a35fefb0624ee3c13f01422b9",
|
148
|
+
}],
|
149
|
+
}
|
150
|
+
}
|
151
|
+
end
|
152
|
+
|
153
|
+
def abort_could_not_find(missing)
|
154
|
+
abort("\nCould not find #{missing}.\nPlease visit https://github.com/sparklemotion/sqlite3-ruby for installation instructions.\n\n")
|
155
|
+
end
|
156
|
+
|
157
|
+
def cross_build?
|
158
|
+
enable_config("cross-build")
|
159
|
+
end
|
160
|
+
|
161
|
+
def download
|
162
|
+
minimal_recipe.download
|
163
|
+
end
|
164
|
+
|
165
|
+
def print_help
|
166
|
+
print(<<~TEXT)
|
167
|
+
USAGE: ruby #{$PROGRAM_NAME} [options]
|
168
|
+
|
169
|
+
Flags that are always valid:
|
170
|
+
|
171
|
+
--disable-system-libraries
|
172
|
+
Use the packaged libraries, and ignore the system libraries.
|
173
|
+
(This is the default behavior.)
|
174
|
+
|
175
|
+
--enable-system-libraries
|
176
|
+
Use system libraries instead of building and using the packaged libraries.
|
177
|
+
|
178
|
+
--with-sqlcipher
|
179
|
+
Use libsqlcipher instead of libsqlite3.
|
180
|
+
(Implies `--enable-system-libraries`.)
|
181
|
+
|
182
|
+
--help
|
183
|
+
Display this message.
|
184
|
+
|
185
|
+
|
186
|
+
Flags only used when using system libraries:
|
187
|
+
|
188
|
+
General (applying to all system libraries):
|
189
|
+
|
190
|
+
--with-opt-dir=DIRECTORY
|
191
|
+
Look for headers and libraries in DIRECTORY.
|
192
|
+
|
193
|
+
--with-opt-lib=DIRECTORY
|
194
|
+
Look for libraries in DIRECTORY.
|
195
|
+
|
196
|
+
--with-opt-include=DIRECTORY
|
197
|
+
Look for headers in DIRECTORY.
|
198
|
+
|
199
|
+
Related to sqlcipher:
|
200
|
+
|
201
|
+
--with-sqlcipher-dir=DIRECTORY
|
202
|
+
Look for sqlcipher headers and library in DIRECTORY.
|
203
|
+
(Implies `--with-sqlcipher` and `--enable-system-libraries`.)
|
204
|
+
|
205
|
+
--with-sqlcipher-lib=DIRECTORY
|
206
|
+
Look for sqlcipher library in DIRECTORY.
|
207
|
+
(Implies `--with-sqlcipher` and `--enable-system-libraries`.)
|
208
|
+
|
209
|
+
--with-sqlcipher-include=DIRECTORY
|
210
|
+
Look for sqlcipher headers in DIRECTORY.
|
211
|
+
(Implies `--with-sqlcipher` and `--enable-system-libraries`.)
|
212
|
+
|
213
|
+
|
214
|
+
Flags only used when building and using the packaged libraries:
|
215
|
+
|
216
|
+
--enable-cross-build
|
217
|
+
Enable cross-build mode. (You probably do not want to set this manually.)
|
218
|
+
|
219
|
+
|
220
|
+
Environment variables used for compiling the C extension:
|
221
|
+
|
222
|
+
CC
|
223
|
+
Use this path to invoke the compiler instead of `RbConfig::CONFIG['CC']`
|
224
|
+
|
225
|
+
|
226
|
+
Environment variables passed through to the compilation of packaged libraries:
|
227
|
+
|
228
|
+
CC
|
229
|
+
CPPFLAGS
|
230
|
+
CFLAGS
|
231
|
+
LDFLAGS
|
232
|
+
LIBS
|
233
|
+
LT_SYS_LIBRARY_PATH
|
234
|
+
CPP
|
235
|
+
|
236
|
+
TEXT
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
if arg_config("--help")
|
243
|
+
Sqlite3::ExtConf.print_help
|
244
|
+
exit!(0)
|
245
|
+
end
|
246
|
+
|
247
|
+
if arg_config("--download-dependencies")
|
248
|
+
Sqlite3::ExtConf.download
|
249
|
+
exit!(0)
|
250
|
+
end
|
251
|
+
|
252
|
+
Sqlite3::ExtConf.configure
|
@@ -0,0 +1,163 @@
|
|
1
|
+
#include <sqlite3_ruby.h>
|
2
|
+
|
3
|
+
VALUE mSqlite3;
|
4
|
+
VALUE cSqlite3Blob;
|
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
|
+
|
63
|
+
static VALUE libversion(VALUE UNUSED(klass))
|
64
|
+
{
|
65
|
+
return INT2NUM(sqlite3_libversion_number());
|
66
|
+
}
|
67
|
+
|
68
|
+
static VALUE using_sqlcipher(VALUE UNUSED(klass))
|
69
|
+
{
|
70
|
+
#ifdef USING_SQLCIPHER
|
71
|
+
return Qtrue;
|
72
|
+
#else
|
73
|
+
return Qfalse;
|
74
|
+
#endif
|
75
|
+
}
|
76
|
+
|
77
|
+
/* Returns the compile time setting of the SQLITE_THREADSAFE flag.
|
78
|
+
* See: https://www.sqlite.org/c3ref/threadsafe.html
|
79
|
+
*/
|
80
|
+
static VALUE threadsafe_p(VALUE UNUSED(klass))
|
81
|
+
{
|
82
|
+
return INT2NUM(sqlite3_threadsafe());
|
83
|
+
}
|
84
|
+
|
85
|
+
void init_sqlite3_constants()
|
86
|
+
{
|
87
|
+
VALUE mSqlite3Constants;
|
88
|
+
VALUE mSqlite3Open;
|
89
|
+
|
90
|
+
mSqlite3Constants = rb_define_module_under(mSqlite3, "Constants");
|
91
|
+
|
92
|
+
/* sqlite3_open_v2 flags for Database::new */
|
93
|
+
mSqlite3Open = rb_define_module_under(mSqlite3Constants, "Open");
|
94
|
+
|
95
|
+
/* symbols = IO.readlines('sqlite3.h').map { |n| /\A#define\s+(SQLITE_OPEN_\w+)\s/ =~ n && $1 }.compact
|
96
|
+
* pad = symbols.map(&:length).max - 9
|
97
|
+
* symbols.each { |s| printf %Q{ rb_define_const(mSqlite3Open, %-#{pad}s INT2FIX(#{s}));\n}, '"' + s[12..-1] + '",' }
|
98
|
+
*/
|
99
|
+
rb_define_const(mSqlite3Open, "READONLY", INT2FIX(SQLITE_OPEN_READONLY));
|
100
|
+
rb_define_const(mSqlite3Open, "READWRITE", INT2FIX(SQLITE_OPEN_READWRITE));
|
101
|
+
rb_define_const(mSqlite3Open, "CREATE", INT2FIX(SQLITE_OPEN_CREATE));
|
102
|
+
rb_define_const(mSqlite3Open, "DELETEONCLOSE", INT2FIX(SQLITE_OPEN_DELETEONCLOSE));
|
103
|
+
rb_define_const(mSqlite3Open, "EXCLUSIVE", INT2FIX(SQLITE_OPEN_EXCLUSIVE));
|
104
|
+
rb_define_const(mSqlite3Open, "MAIN_DB", INT2FIX(SQLITE_OPEN_MAIN_DB));
|
105
|
+
rb_define_const(mSqlite3Open, "TEMP_DB", INT2FIX(SQLITE_OPEN_TEMP_DB));
|
106
|
+
rb_define_const(mSqlite3Open, "TRANSIENT_DB", INT2FIX(SQLITE_OPEN_TRANSIENT_DB));
|
107
|
+
rb_define_const(mSqlite3Open, "MAIN_JOURNAL", INT2FIX(SQLITE_OPEN_MAIN_JOURNAL));
|
108
|
+
rb_define_const(mSqlite3Open, "TEMP_JOURNAL", INT2FIX(SQLITE_OPEN_TEMP_JOURNAL));
|
109
|
+
rb_define_const(mSqlite3Open, "SUBJOURNAL", INT2FIX(SQLITE_OPEN_SUBJOURNAL));
|
110
|
+
rb_define_const(mSqlite3Open, "MASTER_JOURNAL", INT2FIX(SQLITE_OPEN_MASTER_JOURNAL));
|
111
|
+
rb_define_const(mSqlite3Open, "NOMUTEX", INT2FIX(SQLITE_OPEN_NOMUTEX));
|
112
|
+
rb_define_const(mSqlite3Open, "FULLMUTEX", INT2FIX(SQLITE_OPEN_FULLMUTEX));
|
113
|
+
#ifdef SQLITE_OPEN_AUTOPROXY
|
114
|
+
/* SQLITE_VERSION_NUMBER>=3007002 */
|
115
|
+
rb_define_const(mSqlite3Open, "AUTOPROXY", INT2FIX(SQLITE_OPEN_AUTOPROXY));
|
116
|
+
rb_define_const(mSqlite3Open, "SHAREDCACHE", INT2FIX(SQLITE_OPEN_SHAREDCACHE));
|
117
|
+
rb_define_const(mSqlite3Open, "PRIVATECACHE", INT2FIX(SQLITE_OPEN_PRIVATECACHE));
|
118
|
+
rb_define_const(mSqlite3Open, "WAL", INT2FIX(SQLITE_OPEN_WAL));
|
119
|
+
#endif
|
120
|
+
#ifdef SQLITE_OPEN_URI
|
121
|
+
/* SQLITE_VERSION_NUMBER>=3007007 */
|
122
|
+
rb_define_const(mSqlite3Open, "URI", INT2FIX(SQLITE_OPEN_URI));
|
123
|
+
#endif
|
124
|
+
#ifdef SQLITE_OPEN_MEMORY
|
125
|
+
/* SQLITE_VERSION_NUMBER>=3007013 */
|
126
|
+
rb_define_const(mSqlite3Open, "MEMORY", INT2FIX(SQLITE_OPEN_MEMORY));
|
127
|
+
#endif
|
128
|
+
}
|
129
|
+
|
130
|
+
void Init_sqlite3_native()
|
131
|
+
{
|
132
|
+
/*
|
133
|
+
* SQLite3 is a wrapper around the popular database
|
134
|
+
* sqlite[http://sqlite.org].
|
135
|
+
*
|
136
|
+
* For an example of usage, see SQLite3::Database.
|
137
|
+
*/
|
138
|
+
mSqlite3 = rb_define_module("SQLite3");
|
139
|
+
|
140
|
+
/* A class for differentiating between strings and blobs, when binding them
|
141
|
+
* into statements.
|
142
|
+
*/
|
143
|
+
cSqlite3Blob = rb_define_class_under(mSqlite3, "Blob", rb_cString);
|
144
|
+
|
145
|
+
/* Initialize the sqlite3 library */
|
146
|
+
#ifdef HAVE_SQLITE3_INITIALIZE
|
147
|
+
sqlite3_initialize();
|
148
|
+
#endif
|
149
|
+
|
150
|
+
init_sqlite3_constants();
|
151
|
+
init_sqlite3_database();
|
152
|
+
init_sqlite3_statement();
|
153
|
+
#ifdef HAVE_SQLITE3_BACKUP_INIT
|
154
|
+
init_sqlite3_backup();
|
155
|
+
#endif
|
156
|
+
rb_define_singleton_method(mSqlite3, "sqlcipher?", using_sqlcipher, 0);
|
157
|
+
rb_define_singleton_method(mSqlite3, "libversion", libversion, 0);
|
158
|
+
rb_define_singleton_method(mSqlite3, "threadsafe", threadsafe_p, 0);
|
159
|
+
rb_define_const(mSqlite3, "SQLITE_VERSION", rb_str_new2(SQLITE_VERSION));
|
160
|
+
rb_define_const(mSqlite3, "SQLITE_VERSION_NUMBER", INT2FIX(SQLITE_VERSION_NUMBER));
|
161
|
+
rb_define_const(mSqlite3, "SQLITE_LOADED_VERSION", rb_str_new2(sqlite3_libversion()));
|
162
|
+
|
163
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#ifndef SQLITE3_RUBY
|
2
|
+
#define SQLITE3_RUBY
|
3
|
+
|
4
|
+
#include <ruby.h>
|
5
|
+
|
6
|
+
#ifdef UNUSED
|
7
|
+
#elif defined(__GNUC__)
|
8
|
+
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
|
9
|
+
#elif defined(__LCLINT__)
|
10
|
+
# define UNUSED(x) /*@unused@*/ x
|
11
|
+
#else
|
12
|
+
# define UNUSED(x) x
|
13
|
+
#endif
|
14
|
+
|
15
|
+
#include <ruby/encoding.h>
|
16
|
+
|
17
|
+
#define USASCII_P(_obj) (rb_enc_get_index(_obj) == rb_usascii_encindex())
|
18
|
+
#define UTF8_P(_obj) (rb_enc_get_index(_obj) == rb_utf8_encindex())
|
19
|
+
#define UTF16_LE_P(_obj) (rb_enc_get_index(_obj) == rb_enc_find_index("UTF-16LE"))
|
20
|
+
#define UTF16_BE_P(_obj) (rb_enc_get_index(_obj) == rb_enc_find_index("UTF-16BE"))
|
21
|
+
#define SQLITE3_UTF8_STR_NEW2(_obj) \
|
22
|
+
(rb_enc_associate_index(rb_str_new2(_obj), rb_utf8_encindex()))
|
23
|
+
|
24
|
+
#ifdef USING_SQLCIPHER_INC_SUBDIR
|
25
|
+
# include <sqlcipher/sqlite3.h>
|
26
|
+
#else
|
27
|
+
# include <sqlite3.h>
|
28
|
+
#endif
|
29
|
+
|
30
|
+
#ifndef HAVE_TYPE_SQLITE3_INT64
|
31
|
+
typedef sqlite_int64 sqlite3_int64;
|
32
|
+
#endif
|
33
|
+
|
34
|
+
#ifndef HAVE_TYPE_SQLITE3_UINT64
|
35
|
+
typedef sqlite_uint64 sqlite3_uint64;
|
36
|
+
#endif
|
37
|
+
|
38
|
+
extern VALUE mSqlite3;
|
39
|
+
extern VALUE cSqlite3Blob;
|
40
|
+
|
41
|
+
#include <database.h>
|
42
|
+
#include <statement.h>
|
43
|
+
#include <exception.h>
|
44
|
+
#include <backup.h>
|
45
|
+
|
46
|
+
int bignum_to_int64(VALUE big, sqlite3_int64 *result);
|
47
|
+
|
48
|
+
#endif
|