sqlite3 2.0.0-x86_64-linux-gnu

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,22 @@
1
+ #ifndef SQLITE3_DATABASE_RUBY
2
+ #define SQLITE3_DATABASE_RUBY
3
+
4
+ #include <sqlite3_ruby.h>
5
+
6
+ struct _sqlite3Ruby {
7
+ sqlite3 *db;
8
+ VALUE busy_handler;
9
+ int stmt_timeout;
10
+ struct timespec stmt_deadline;
11
+ };
12
+
13
+ typedef struct _sqlite3Ruby sqlite3Ruby;
14
+ typedef sqlite3Ruby *sqlite3RubyPtr;
15
+
16
+ void init_sqlite3_database();
17
+ void set_sqlite3_func_result(sqlite3_context *ctx, VALUE result);
18
+
19
+ sqlite3RubyPtr sqlite3_database_unwrap(VALUE database);
20
+ VALUE sqlite3val2rb(sqlite3_value *val);
21
+
22
+ #endif
@@ -0,0 +1,117 @@
1
+ #include <sqlite3_ruby.h>
2
+
3
+ void
4
+ rb_sqlite3_raise(sqlite3 *db, int status)
5
+ {
6
+ VALUE klass = Qnil;
7
+
8
+ /* Consider only lower 8 bits, to work correctly when
9
+ extended result codes are enabled. */
10
+ switch (status & 0xff) {
11
+ case SQLITE_OK:
12
+ return;
13
+ break;
14
+ case SQLITE_ERROR:
15
+ klass = rb_path2class("SQLite3::SQLException");
16
+ break;
17
+ case SQLITE_INTERNAL:
18
+ klass = rb_path2class("SQLite3::InternalException");
19
+ break;
20
+ case SQLITE_PERM:
21
+ klass = rb_path2class("SQLite3::PermissionException");
22
+ break;
23
+ case SQLITE_ABORT:
24
+ klass = rb_path2class("SQLite3::AbortException");
25
+ break;
26
+ case SQLITE_BUSY:
27
+ klass = rb_path2class("SQLite3::BusyException");
28
+ break;
29
+ case SQLITE_LOCKED:
30
+ klass = rb_path2class("SQLite3::LockedException");
31
+ break;
32
+ case SQLITE_NOMEM:
33
+ klass = rb_path2class("SQLite3::MemoryException");
34
+ break;
35
+ case SQLITE_READONLY:
36
+ klass = rb_path2class("SQLite3::ReadOnlyException");
37
+ break;
38
+ case SQLITE_INTERRUPT:
39
+ klass = rb_path2class("SQLite3::InterruptException");
40
+ break;
41
+ case SQLITE_IOERR:
42
+ klass = rb_path2class("SQLite3::IOException");
43
+ break;
44
+ case SQLITE_CORRUPT:
45
+ klass = rb_path2class("SQLite3::CorruptException");
46
+ break;
47
+ case SQLITE_NOTFOUND:
48
+ klass = rb_path2class("SQLite3::NotFoundException");
49
+ break;
50
+ case SQLITE_FULL:
51
+ klass = rb_path2class("SQLite3::FullException");
52
+ break;
53
+ case SQLITE_CANTOPEN:
54
+ klass = rb_path2class("SQLite3::CantOpenException");
55
+ break;
56
+ case SQLITE_PROTOCOL:
57
+ klass = rb_path2class("SQLite3::ProtocolException");
58
+ break;
59
+ case SQLITE_EMPTY:
60
+ klass = rb_path2class("SQLite3::EmptyException");
61
+ break;
62
+ case SQLITE_SCHEMA:
63
+ klass = rb_path2class("SQLite3::SchemaChangedException");
64
+ break;
65
+ case SQLITE_TOOBIG:
66
+ klass = rb_path2class("SQLite3::TooBigException");
67
+ break;
68
+ case SQLITE_CONSTRAINT:
69
+ klass = rb_path2class("SQLite3::ConstraintException");
70
+ break;
71
+ case SQLITE_MISMATCH:
72
+ klass = rb_path2class("SQLite3::MismatchException");
73
+ break;
74
+ case SQLITE_MISUSE:
75
+ klass = rb_path2class("SQLite3::MisuseException");
76
+ break;
77
+ case SQLITE_NOLFS:
78
+ klass = rb_path2class("SQLite3::UnsupportedException");
79
+ break;
80
+ case SQLITE_AUTH:
81
+ klass = rb_path2class("SQLite3::AuthorizationException");
82
+ break;
83
+ case SQLITE_FORMAT:
84
+ klass = rb_path2class("SQLite3::FormatException");
85
+ break;
86
+ case SQLITE_RANGE:
87
+ klass = rb_path2class("SQLite3::RangeException");
88
+ break;
89
+ case SQLITE_NOTADB:
90
+ klass = rb_path2class("SQLite3::NotADatabaseException");
91
+ break;
92
+ default:
93
+ klass = rb_path2class("SQLite3::Exception");
94
+ }
95
+
96
+ klass = rb_exc_new2(klass, sqlite3_errmsg(db));
97
+ rb_iv_set(klass, "@code", INT2FIX(status));
98
+ rb_exc_raise(klass);
99
+ }
100
+
101
+ /*
102
+ * accepts a sqlite3 error message as the final argument, which will be `sqlite3_free`d
103
+ */
104
+ void
105
+ rb_sqlite3_raise_msg(sqlite3 *db, int status, const char *msg)
106
+ {
107
+ VALUE exception;
108
+
109
+ if (status == SQLITE_OK) {
110
+ return;
111
+ }
112
+
113
+ exception = rb_exc_new2(rb_path2class("SQLite3::Exception"), msg);
114
+ sqlite3_free((void *)msg);
115
+ rb_iv_set(exception, "@code", INT2FIX(status));
116
+ rb_exc_raise(exception);
117
+ }
@@ -0,0 +1,10 @@
1
+ #ifndef SQLITE3_EXCEPTION_RUBY
2
+ #define SQLITE3_EXCEPTION_RUBY
3
+
4
+ #define CHECK(_db, _status) rb_sqlite3_raise(_db, _status);
5
+ #define CHECK_MSG(_db, _status, _msg) rb_sqlite3_raise_msg(_db, _status, _msg);
6
+
7
+ void rb_sqlite3_raise(sqlite3 *db, int status);
8
+ void rb_sqlite3_raise_msg(sqlite3 *db, int status, const char *msg);
9
+
10
+ #endif
@@ -0,0 +1,284 @@
1
+ require "mkmf"
2
+ require "yaml"
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 += [
53
+ "--enable-shared=no",
54
+ "--enable-static=yes",
55
+ "--enable-fts5"
56
+ ]
57
+ ENV.to_h.tap do |env|
58
+ user_cflags = with_config("sqlite-cflags")
59
+ more_cflags = [
60
+ "-fPIC", # needed for linking the static library into a shared library
61
+ "-O2", # see https://github.com/sparklemotion/sqlite3-ruby/issues/335 for some benchmarks
62
+ "-fvisibility=hidden", # see https://github.com/rake-compiler/rake-compiler-dock/issues/87
63
+ "-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1"
64
+ ]
65
+ env["CFLAGS"] = [user_cflags, env["CFLAGS"], more_cflags].flatten.join(" ")
66
+ recipe.configure_options += env.select { |k, v| ENV_ALLOWLIST.include?(k) }
67
+ .map { |key, value| "#{key}=#{value.strip}" }
68
+ end
69
+
70
+ unless File.exist?(File.join(recipe.target, recipe.host, recipe.name, recipe.version))
71
+ recipe.cook
72
+ end
73
+ recipe.activate
74
+
75
+ # on macos, pkg-config will not return --cflags without this
76
+ ENV["PKG_CONFIG_ALLOW_SYSTEM_CFLAGS"] = "t"
77
+
78
+ # only needed for Ruby 3.1.3, see https://bugs.ruby-lang.org/issues/19233
79
+ RbConfig::CONFIG["PKG_CONFIG"] = config_string("PKG_CONFIG") || "pkg-config"
80
+
81
+ lib_path = File.join(recipe.path, "lib")
82
+ pcfile = File.join(lib_path, "pkgconfig", "sqlite3.pc")
83
+ abort_pkg_config("pkg_config") unless pkg_config(pcfile)
84
+
85
+ # see https://bugs.ruby-lang.org/issues/18490
86
+ ldflags = xpopen(["pkg-config", "--libs", "--static", pcfile], err: [:child, :out], &:read)
87
+ abort_pkg_config("xpopen") unless $?.success?
88
+ ldflags = ldflags.split
89
+
90
+ # see https://github.com/flavorjones/mini_portile/issues/118
91
+ "-L#{lib_path}".tap do |lib_path_flag|
92
+ ldflags.prepend(lib_path_flag) unless ldflags.include?(lib_path_flag)
93
+ end
94
+
95
+ ldflags.each { |ldflag| append_ldflags(ldflag) }
96
+ end
97
+ end
98
+
99
+ def configure_extension
100
+ append_cflags("-fvisibility=hidden") # see https://github.com/rake-compiler/rake-compiler-dock/issues/87
101
+
102
+ if find_header("sqlite3.h")
103
+ # noop
104
+ elsif sqlcipher? && find_header("sqlcipher/sqlite3.h")
105
+ append_cppflags("-DUSING_SQLCIPHER_INC_SUBDIR")
106
+ else
107
+ abort_could_not_find("sqlite3.h")
108
+ end
109
+
110
+ abort_could_not_find(libname) unless find_library(libname, "sqlite3_libversion_number", "sqlite3.h")
111
+
112
+ # Truffle Ruby doesn't support this yet:
113
+ # https://github.com/oracle/truffleruby/issues/3408
114
+ have_func("rb_enc_interned_str_cstr")
115
+
116
+ # Functions defined in 1.9 but not 1.8
117
+ have_func("rb_proc_arity")
118
+
119
+ # Functions defined in 2.1 but not 2.0
120
+ have_func("rb_integer_pack")
121
+
122
+ # These functions may not be defined
123
+ have_func("sqlite3_initialize")
124
+ have_func("sqlite3_backup_init")
125
+ have_func("sqlite3_column_database_name")
126
+ have_func("sqlite3_enable_load_extension")
127
+ have_func("sqlite3_load_extension")
128
+
129
+ unless have_func("sqlite3_open_v2") # https://www.sqlite.org/releaselog/3_5_0.html
130
+ abort("\nPlease use a version of SQLite3 >= 3.5.0\n\n")
131
+ end
132
+
133
+ have_func("sqlite3_prepare_v2")
134
+ have_type("sqlite3_int64", "sqlite3.h")
135
+ have_type("sqlite3_uint64", "sqlite3.h")
136
+ end
137
+
138
+ def minimal_recipe
139
+ require "mini_portile2"
140
+
141
+ MiniPortile.new(libname, sqlite3_config[:version]).tap do |recipe|
142
+ if sqlite_source_dir
143
+ recipe.source_directory = sqlite_source_dir
144
+ else
145
+ recipe.files = sqlite3_config[:files]
146
+ recipe.target = File.join(package_root_dir, "ports")
147
+ recipe.patch_files = Dir[File.join(package_root_dir, "patches", "*.patch")].sort
148
+ end
149
+ end
150
+ end
151
+
152
+ def package_root_dir
153
+ File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))
154
+ end
155
+
156
+ def sqlite3_config
157
+ mini_portile_config[:sqlite3]
158
+ end
159
+
160
+ def mini_portile_config
161
+ YAML.load_file(File.join(package_root_dir, "dependencies.yml"), symbolize_names: true)
162
+ end
163
+
164
+ def abort_could_not_find(missing)
165
+ abort("\nCould not find #{missing}.\nPlease visit https://github.com/sparklemotion/sqlite3-ruby for installation instructions.\n\n")
166
+ end
167
+
168
+ def abort_pkg_config(id)
169
+ abort("\nCould not configure the build properly (#{id}). Please install either the `pkg-config` utility or the `pkg-config` rubygem.\n\n")
170
+ end
171
+
172
+ def cross_build?
173
+ enable_config("cross-build")
174
+ end
175
+
176
+ def sqlite_source_dir
177
+ arg_config("--with-sqlite-source-dir")
178
+ end
179
+
180
+ def download
181
+ minimal_recipe.download
182
+ end
183
+
184
+ def darwin?
185
+ RbConfig::CONFIG["target_os"].include?("darwin")
186
+ end
187
+
188
+ def print_help
189
+ print(<<~TEXT)
190
+ USAGE: ruby #{$PROGRAM_NAME} [options]
191
+
192
+ Flags that are always valid:
193
+
194
+ --disable-system-libraries
195
+ Use the packaged libraries, and ignore the system libraries.
196
+ (This is the default behavior.)
197
+
198
+ --enable-system-libraries
199
+ Use system libraries instead of building and using the packaged libraries.
200
+
201
+ --with-sqlcipher
202
+ Use libsqlcipher instead of libsqlite3.
203
+ (Implies `--enable-system-libraries`.)
204
+
205
+ --with-sqlite-source-dir=DIRECTORY
206
+ (dev only) Build sqlite from the source code in DIRECTORY
207
+
208
+ --help
209
+ Display this message.
210
+
211
+
212
+ Flags only used when using system libraries:
213
+
214
+ General (applying to all system libraries):
215
+
216
+ --with-opt-dir=DIRECTORY
217
+ Look for headers and libraries in DIRECTORY.
218
+
219
+ --with-opt-lib=DIRECTORY
220
+ Look for libraries in DIRECTORY.
221
+
222
+ --with-opt-include=DIRECTORY
223
+ Look for headers in DIRECTORY.
224
+
225
+ Related to sqlcipher:
226
+
227
+ --with-sqlcipher-dir=DIRECTORY
228
+ Look for sqlcipher headers and library in DIRECTORY.
229
+ (Implies `--with-sqlcipher` and `--enable-system-libraries`.)
230
+
231
+ --with-sqlcipher-lib=DIRECTORY
232
+ Look for sqlcipher library in DIRECTORY.
233
+ (Implies `--with-sqlcipher` and `--enable-system-libraries`.)
234
+
235
+ --with-sqlcipher-include=DIRECTORY
236
+ Look for sqlcipher headers in DIRECTORY.
237
+ (Implies `--with-sqlcipher` and `--enable-system-libraries`.)
238
+
239
+
240
+ Flags only used when building and using the packaged libraries:
241
+
242
+ --with-sqlite-cflags=CFLAGS
243
+ Explicitly pass compiler flags to the sqlite library build. These flags will
244
+ appear on the commandline before any flags set in the CFLAGS environment
245
+ variable. This is useful for setting compilation options in your project's
246
+ bundler config. See INSTALLATION.md for more information.
247
+
248
+ --enable-cross-build
249
+ Enable cross-build mode. (You probably do not want to set this manually.)
250
+
251
+
252
+ Environment variables used for compiling the gem's C extension:
253
+
254
+ CC
255
+ Use this path to invoke the compiler instead of `RbConfig::CONFIG['CC']`
256
+
257
+
258
+ Environment variables passed through to the compilation of sqlite:
259
+
260
+ CC
261
+ CPPFLAGS
262
+ CFLAGS
263
+ LDFLAGS
264
+ LIBS
265
+ LT_SYS_LIBRARY_PATH
266
+ CPP
267
+
268
+ TEXT
269
+ end
270
+ end
271
+ end
272
+ end
273
+
274
+ if arg_config("--help")
275
+ Sqlite3::ExtConf.print_help
276
+ exit!(0)
277
+ end
278
+
279
+ if arg_config("--download-dependencies")
280
+ Sqlite3::ExtConf.download
281
+ exit!(0)
282
+ end
283
+
284
+ Sqlite3::ExtConf.configure
@@ -0,0 +1,208 @@
1
+ #include <sqlite3_ruby.h>
2
+
3
+ VALUE mSqlite3;
4
+ VALUE cSqlite3Blob;
5
+
6
+ int
7
+ bignum_to_int64(VALUE value, sqlite3_int64 *result)
8
+ {
9
+ #ifdef HAVE_RB_INTEGER_PACK
10
+ const int nails = 0;
11
+ int t = rb_integer_pack(value, result, 1, sizeof(*result), nails,
12
+ INTEGER_PACK_NATIVE_BYTE_ORDER |
13
+ INTEGER_PACK_2COMP);
14
+ switch (t) {
15
+ case -2:
16
+ case +2:
17
+ return 0;
18
+ case +1:
19
+ if (!nails) {
20
+ if (*result < 0) { return 0; }
21
+ }
22
+ break;
23
+ case -1:
24
+ if (!nails) {
25
+ if (*result >= 0) { return 0; }
26
+ } else {
27
+ *result += INT64_MIN;
28
+ }
29
+ break;
30
+ }
31
+ return 1;
32
+ #else
33
+ # ifndef RBIGNUM_LEN
34
+ # define RBIGNUM_LEN(x) RBIGNUM(x)->len
35
+ # endif
36
+ const long len = RBIGNUM_LEN(value);
37
+ if (len == 0) {
38
+ *result = 0;
39
+ return 1;
40
+ }
41
+ if (len > 63 / (SIZEOF_BDIGITS * CHAR_BIT) + 1) { return 0; }
42
+ if (len == 63 / (SIZEOF_BDIGITS * CHAR_BIT) + 1) {
43
+ const BDIGIT *digits = RBIGNUM_DIGITS(value);
44
+ BDIGIT blast = digits[len - 1];
45
+ BDIGIT bmax = (BDIGIT)1UL << (63 % (CHAR_BIT * SIZEOF_BDIGITS));
46
+ if (blast > bmax) { return 0; }
47
+ if (blast == bmax) {
48
+ if (RBIGNUM_POSITIVE_P(value)) {
49
+ return 0;
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
64
+ libversion(VALUE UNUSED(klass))
65
+ {
66
+ return INT2NUM(sqlite3_libversion_number());
67
+ }
68
+
69
+ static VALUE
70
+ using_sqlcipher(VALUE UNUSED(klass))
71
+ {
72
+ #ifdef USING_SQLCIPHER
73
+ return Qtrue;
74
+ #else
75
+ return Qfalse;
76
+ #endif
77
+ }
78
+
79
+ /* Returns the compile time setting of the SQLITE_THREADSAFE flag.
80
+ * See: https://www.sqlite.org/c3ref/threadsafe.html
81
+ */
82
+ static VALUE
83
+ threadsafe_p(VALUE UNUSED(klass))
84
+ {
85
+ return INT2NUM(sqlite3_threadsafe());
86
+ }
87
+
88
+ /*
89
+ * call-seq:
90
+ * status(parameter) → Hash
91
+ * status(parameter, reset_flag = false) → Hash
92
+ *
93
+ * Queries the SQLite3 library for run-time status information. Passing a truthy +reset_flag+ will
94
+ * reset the highwater mark to the current value.
95
+ *
96
+ * [Parameters]
97
+ * - +parameter+ (Integer, SQLite3::Constants::Status): The status parameter to query.
98
+ * - +reset_flag+ (Boolean): Whether to reset the highwater mark. (default is +false+)
99
+ *
100
+ * [Returns]
101
+ * A Hash containing +:current+ and +:highwater+ keys for integer values.
102
+ */
103
+ static VALUE
104
+ rb_sqlite3_status(int argc, VALUE *argv, VALUE klass)
105
+ {
106
+ VALUE opArg, resetFlagArg;
107
+
108
+ rb_scan_args(argc, argv, "11", &opArg, &resetFlagArg);
109
+
110
+ int op = NUM2INT(opArg);
111
+ bool resetFlag = RTEST(resetFlagArg);
112
+
113
+ int pCurrent = 0;
114
+ int pHighwater = 0;
115
+ sqlite3_status(op, &pCurrent, &pHighwater, resetFlag);
116
+
117
+ VALUE hash = rb_hash_new();
118
+ rb_hash_aset(hash, ID2SYM(rb_intern("current")), INT2FIX(pCurrent));
119
+ rb_hash_aset(hash, ID2SYM(rb_intern("highwater")), INT2FIX(pHighwater));
120
+
121
+ return hash;
122
+ }
123
+
124
+ void
125
+ init_sqlite3_constants(void)
126
+ {
127
+ VALUE mSqlite3Constants;
128
+ VALUE mSqlite3Open;
129
+
130
+ mSqlite3Constants = rb_define_module_under(mSqlite3, "Constants");
131
+
132
+ /* sqlite3_open_v2 flags for Database::new */
133
+ mSqlite3Open = rb_define_module_under(mSqlite3Constants, "Open");
134
+
135
+ /* symbols = IO.readlines('sqlite3.h').map { |n| /\A#define\s+(SQLITE_OPEN_\w+)\s/ =~ n && $1 }.compact
136
+ * pad = symbols.map(&:length).max - 9
137
+ * symbols.each { |s| printf %Q{ rb_define_const(mSqlite3Open, %-#{pad}s INT2FIX(#{s}));\n}, '"' + s[12..-1] + '",' }
138
+ */
139
+ rb_define_const(mSqlite3Open, "READONLY", INT2FIX(SQLITE_OPEN_READONLY));
140
+ rb_define_const(mSqlite3Open, "READWRITE", INT2FIX(SQLITE_OPEN_READWRITE));
141
+ rb_define_const(mSqlite3Open, "CREATE", INT2FIX(SQLITE_OPEN_CREATE));
142
+ rb_define_const(mSqlite3Open, "DELETEONCLOSE", INT2FIX(SQLITE_OPEN_DELETEONCLOSE));
143
+ rb_define_const(mSqlite3Open, "EXCLUSIVE", INT2FIX(SQLITE_OPEN_EXCLUSIVE));
144
+ rb_define_const(mSqlite3Open, "MAIN_DB", INT2FIX(SQLITE_OPEN_MAIN_DB));
145
+ rb_define_const(mSqlite3Open, "TEMP_DB", INT2FIX(SQLITE_OPEN_TEMP_DB));
146
+ rb_define_const(mSqlite3Open, "TRANSIENT_DB", INT2FIX(SQLITE_OPEN_TRANSIENT_DB));
147
+ rb_define_const(mSqlite3Open, "MAIN_JOURNAL", INT2FIX(SQLITE_OPEN_MAIN_JOURNAL));
148
+ rb_define_const(mSqlite3Open, "TEMP_JOURNAL", INT2FIX(SQLITE_OPEN_TEMP_JOURNAL));
149
+ rb_define_const(mSqlite3Open, "SUBJOURNAL", INT2FIX(SQLITE_OPEN_SUBJOURNAL));
150
+ rb_define_const(mSqlite3Open, "MASTER_JOURNAL",
151
+ INT2FIX(SQLITE_OPEN_MASTER_JOURNAL)); /* pre-3.33.0 */
152
+ rb_define_const(mSqlite3Open, "SUPER_JOURNAL", INT2FIX(SQLITE_OPEN_MASTER_JOURNAL));
153
+ rb_define_const(mSqlite3Open, "NOMUTEX", INT2FIX(SQLITE_OPEN_NOMUTEX));
154
+ rb_define_const(mSqlite3Open, "FULLMUTEX", INT2FIX(SQLITE_OPEN_FULLMUTEX));
155
+ #ifdef SQLITE_OPEN_AUTOPROXY
156
+ /* SQLITE_VERSION_NUMBER>=3007002 */
157
+ rb_define_const(mSqlite3Open, "AUTOPROXY", INT2FIX(SQLITE_OPEN_AUTOPROXY));
158
+ rb_define_const(mSqlite3Open, "SHAREDCACHE", INT2FIX(SQLITE_OPEN_SHAREDCACHE));
159
+ rb_define_const(mSqlite3Open, "PRIVATECACHE", INT2FIX(SQLITE_OPEN_PRIVATECACHE));
160
+ rb_define_const(mSqlite3Open, "WAL", INT2FIX(SQLITE_OPEN_WAL));
161
+ #endif
162
+ #ifdef SQLITE_OPEN_URI
163
+ /* SQLITE_VERSION_NUMBER>=3007007 */
164
+ rb_define_const(mSqlite3Open, "URI", INT2FIX(SQLITE_OPEN_URI));
165
+ #endif
166
+ #ifdef SQLITE_OPEN_MEMORY
167
+ /* SQLITE_VERSION_NUMBER>=3007013 */
168
+ rb_define_const(mSqlite3Open, "MEMORY", INT2FIX(SQLITE_OPEN_MEMORY));
169
+ #endif
170
+ }
171
+
172
+ RUBY_FUNC_EXPORTED
173
+ void
174
+ Init_sqlite3_native(void)
175
+ {
176
+ /*
177
+ * SQLite3 is a wrapper around the popular database
178
+ * sqlite[http://sqlite.org].
179
+ *
180
+ * For an example of usage, see SQLite3::Database.
181
+ */
182
+ mSqlite3 = rb_define_module("SQLite3");
183
+
184
+ /* A class for differentiating between strings and blobs, when binding them
185
+ * into statements.
186
+ */
187
+ cSqlite3Blob = rb_define_class_under(mSqlite3, "Blob", rb_cString);
188
+
189
+ /* Initialize the sqlite3 library */
190
+ #ifdef HAVE_SQLITE3_INITIALIZE
191
+ sqlite3_initialize();
192
+ #endif
193
+
194
+ init_sqlite3_constants();
195
+ init_sqlite3_database();
196
+ init_sqlite3_statement();
197
+ #ifdef HAVE_SQLITE3_BACKUP_INIT
198
+ init_sqlite3_backup();
199
+ #endif
200
+ rb_define_singleton_method(mSqlite3, "sqlcipher?", using_sqlcipher, 0);
201
+ rb_define_singleton_method(mSqlite3, "libversion", libversion, 0);
202
+ rb_define_singleton_method(mSqlite3, "threadsafe", threadsafe_p, 0);
203
+ rb_define_singleton_method(mSqlite3, "status", rb_sqlite3_status, -1);
204
+ rb_define_const(mSqlite3, "SQLITE_VERSION", rb_str_new2(SQLITE_VERSION));
205
+ rb_define_const(mSqlite3, "SQLITE_VERSION_NUMBER", INT2FIX(SQLITE_VERSION_NUMBER));
206
+ rb_define_const(mSqlite3, "SQLITE_LOADED_VERSION", rb_str_new2(sqlite3_libversion()));
207
+
208
+ }
@@ -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) (rb_utf8_str_new_cstr(_obj))
22
+
23
+ #ifdef USING_SQLCIPHER_INC_SUBDIR
24
+ # include <sqlcipher/sqlite3.h>
25
+ #else
26
+ # include <sqlite3.h>
27
+ #endif
28
+
29
+ #ifndef HAVE_TYPE_SQLITE3_INT64
30
+ typedef sqlite_int64 sqlite3_int64;
31
+ #endif
32
+
33
+ #ifndef HAVE_TYPE_SQLITE3_UINT64
34
+ typedef sqlite_uint64 sqlite3_uint64;
35
+ #endif
36
+
37
+ extern VALUE mSqlite3;
38
+ extern VALUE cSqlite3Blob;
39
+
40
+ #include <database.h>
41
+ #include <statement.h>
42
+ #include <exception.h>
43
+ #include <backup.h>
44
+ #include <timespec.h>
45
+
46
+ int bignum_to_int64(VALUE big, sqlite3_int64 *result);
47
+
48
+ #endif