sqlite3 1.4.2 → 1.6.3

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.
@@ -1,100 +1,273 @@
1
- ENV['RC_ARCHS'] = '' if RUBY_PLATFORM =~ /darwin/
2
-
3
- require 'mkmf'
4
-
5
- # :stopdoc:
6
-
7
- RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
8
-
9
- ldflags = cppflags = nil
10
- if RbConfig::CONFIG["host_os"] =~ /darwin/
11
- begin
12
- if with_config('sqlcipher')
13
- brew_prefix = `brew --prefix sqlcipher`.chomp
14
- ldflags = "#{brew_prefix}/lib"
15
- cppflags = "#{brew_prefix}/include/sqlcipher"
16
- pkg_conf = "#{brew_prefix}/lib/pkgconfig"
17
- else
18
- brew_prefix = `brew --prefix sqlite3`.chomp
19
- ldflags = "#{brew_prefix}/lib"
20
- cppflags = "#{brew_prefix}/include"
21
- pkg_conf = "#{brew_prefix}/lib/pkgconfig"
22
- end
1
+ require "mkmf"
2
+ require "yaml"
23
3
 
24
- # pkg_config should be less error prone than parsing compiler
25
- # commandline options, but we need to set default ldflags and cpp flags
26
- # in case the user doesn't have pkg-config installed
27
- ENV['PKG_CONFIG_PATH'] ||= pkg_conf
28
- rescue
29
- end
30
- end
4
+ module Sqlite3
5
+ module ExtConf
6
+ ENV_ALLOWLIST = ["CC", "CFLAGS", "LDFLAGS", "LIBS", "CPPFLAGS", "LT_SYS_LIBRARY_PATH", "CPP"]
31
7
 
32
- if with_config('sqlcipher')
33
- pkg_config("sqlcipher")
34
- else
35
- pkg_config("sqlite3")
36
- end
8
+ class << self
9
+ def configure
10
+ configure_cross_compiler
37
11
 
38
- # --with-sqlite3-{dir,include,lib}
39
- if with_config('sqlcipher')
40
- $CFLAGS << ' -DUSING_SQLCIPHER'
41
- dir_config("sqlcipher", cppflags, ldflags)
42
- else
43
- dir_config("sqlite3", cppflags, ldflags)
44
- end
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
45
19
 
46
- if RbConfig::CONFIG["host_os"] =~ /mswin/
47
- $CFLAGS << ' -W3'
48
- end
20
+ configure_extension
49
21
 
50
- if RUBY_VERSION < '2.7'
51
- $CFLAGS << ' -DTAINTING_SUPPORT'
52
- end
22
+ create_makefile('sqlite3/sqlite3_native')
23
+ end
53
24
 
54
- def asplode missing
55
- if RUBY_PLATFORM =~ /mingw|mswin/
56
- abort "#{missing} is missing. Install SQLite3 from " +
57
- "http://www.sqlite.org/ first."
58
- else
59
- abort <<-error
60
- #{missing} is missing. Try 'brew install sqlite3',
61
- 'yum install sqlite-devel' or 'apt-get install libsqlite3-dev'
62
- and check your shared library search path (the
63
- location where your sqlite3 shared library is located).
64
- error
65
- end
66
- end
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
67
29
 
68
- asplode('sqlite3.h') unless find_header 'sqlite3.h'
69
- find_library 'pthread', 'pthread_create' # 1.8 support. *shrug*
30
+ def system_libraries?
31
+ sqlcipher? || enable_config("system-libraries")
32
+ end
70
33
 
71
- have_library 'dl' # for static builds
34
+ def libname
35
+ sqlcipher? ? "sqlcipher" : "sqlite3"
36
+ end
72
37
 
73
- if with_config('sqlcipher')
74
- asplode('sqlcipher') unless find_library 'sqlcipher', 'sqlite3_libversion_number'
75
- else
76
- asplode('sqlite3') unless find_library 'sqlite3', 'sqlite3_libversion_number'
77
- end
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
+ "-fvisibility=hidden", # see https://github.com/rake-compiler/rake-compiler-dock/issues/87
58
+ ]
59
+ env["CFLAGS"] = [env["CFLAGS"], additional_cflags].flatten.join(" ")
60
+ recipe.configure_options += env.select { |k,v| ENV_ALLOWLIST.include?(k) }
61
+ .map { |key, value| "#{key}=#{value.strip}" }
62
+ end
63
+
64
+ unless File.exist?(File.join(recipe.target, recipe.host, recipe.name, recipe.version))
65
+ recipe.cook
66
+ end
67
+ recipe.activate
68
+
69
+ # on macos, pkg-config will not return --cflags without this
70
+ ENV["PKG_CONFIG_ALLOW_SYSTEM_CFLAGS"] = "t"
71
+
72
+ # only needed for Ruby 3.1.3, see https://bugs.ruby-lang.org/issues/19233
73
+ RbConfig::CONFIG["PKG_CONFIG"] = config_string("PKG_CONFIG") || "pkg-config"
74
+
75
+ lib_path = File.join(recipe.path, "lib")
76
+ pcfile = File.join(lib_path, "pkgconfig", "sqlite3.pc")
77
+ abort_pkg_config("pkg_config") unless pkg_config(pcfile)
78
+
79
+ # see https://bugs.ruby-lang.org/issues/18490
80
+ ldflags = xpopen(["pkg-config", "--libs", "--static", pcfile], err: [:child, :out], &:read)
81
+ abort_pkg_config("xpopen") unless $?.success?
82
+ ldflags = ldflags.split
83
+
84
+ # see https://github.com/flavorjones/mini_portile/issues/118
85
+ "-L#{lib_path}".tap do |lib_path_flag|
86
+ ldflags.prepend(lib_path_flag) unless ldflags.include?(lib_path_flag)
87
+ end
88
+
89
+ ldflags.each { |ldflag| append_ldflags(ldflag) }
90
+ end
91
+ end
92
+
93
+ def configure_extension
94
+ if Gem::Requirement.new("< 2.7").satisfied_by?(Gem::Version.new(RUBY_VERSION))
95
+ append_cppflags("-DTAINTING_SUPPORT")
96
+ end
97
+
98
+ append_cflags("-fvisibility=hidden") # see https://github.com/rake-compiler/rake-compiler-dock/issues/87
99
+
100
+ if find_header("sqlite3.h")
101
+ # noop
102
+ elsif sqlcipher? && find_header("sqlcipher/sqlite3.h")
103
+ append_cppflags("-DUSING_SQLCIPHER_INC_SUBDIR")
104
+ else
105
+ abort_could_not_find("sqlite3.h")
106
+ end
107
+
108
+ abort_could_not_find(libname) unless find_library(libname, "sqlite3_libversion_number", "sqlite3.h")
109
+
110
+ # Functions defined in 1.9 but not 1.8
111
+ have_func('rb_proc_arity')
112
+
113
+ # Functions defined in 2.1 but not 2.0
114
+ have_func('rb_integer_pack')
115
+
116
+ # These functions may not be defined
117
+ have_func('sqlite3_initialize')
118
+ have_func('sqlite3_backup_init')
119
+ have_func('sqlite3_column_database_name')
120
+ have_func('sqlite3_enable_load_extension')
121
+ have_func('sqlite3_load_extension')
122
+
123
+ unless have_func('sqlite3_open_v2') # https://www.sqlite.org/releaselog/3_5_0.html
124
+ abort("\nPlease use a version of SQLite3 >= 3.5.0\n\n")
125
+ end
126
+
127
+ have_func('sqlite3_prepare_v2')
128
+ have_type('sqlite3_int64', 'sqlite3.h')
129
+ have_type('sqlite3_uint64', 'sqlite3.h')
130
+ end
131
+
132
+ def minimal_recipe
133
+ require "mini_portile2"
134
+
135
+ MiniPortile.new(libname, sqlite3_config[:version]).tap do |recipe|
136
+ if sqlite_source_dir
137
+ recipe.source_directory = sqlite_source_dir
138
+ else
139
+ recipe.files = sqlite3_config[:files]
140
+ recipe.target = File.join(package_root_dir, "ports")
141
+ recipe.patch_files = Dir[File.join(package_root_dir, "patches", "*.patch")].sort
142
+ end
143
+ end
144
+ end
145
+
146
+ def package_root_dir
147
+ File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))
148
+ end
149
+
150
+ def sqlite3_config
151
+ mini_portile_config[:sqlite3]
152
+ end
153
+
154
+ def mini_portile_config
155
+ # TODO: once Ruby 2.7 is no longer supported, use symbolize_names: true
156
+ YAML.load_file(File.join(package_root_dir, "dependencies.yml"))
157
+ end
158
+
159
+ def abort_could_not_find(missing)
160
+ abort("\nCould not find #{missing}.\nPlease visit https://github.com/sparklemotion/sqlite3-ruby for installation instructions.\n\n")
161
+ end
78
162
 
79
- # Functions defined in 1.9 but not 1.8
80
- have_func('rb_proc_arity')
163
+ def abort_pkg_config(id)
164
+ abort("\nCould not configure the build properly (#{id}). Please install either the `pkg-config` utility or the `pkg-config` rubygem.\n\n")
165
+ end
81
166
 
82
- # Functions defined in 2.1 but not 2.0
83
- have_func('rb_integer_pack')
167
+ def cross_build?
168
+ enable_config("cross-build")
169
+ end
84
170
 
85
- # These functions may not be defined
86
- have_func('sqlite3_initialize')
87
- have_func('sqlite3_backup_init')
88
- have_func('sqlite3_column_database_name')
89
- have_func('sqlite3_enable_load_extension')
90
- have_func('sqlite3_load_extension')
171
+ def sqlite_source_dir
172
+ arg_config("--with-sqlite-source-dir")
173
+ end
91
174
 
92
- unless have_func('sqlite3_open_v2')
93
- abort "Please use a newer version of SQLite3"
175
+ def download
176
+ minimal_recipe.download
177
+ end
178
+
179
+ def darwin?
180
+ RbConfig::CONFIG["target_os"].include?("darwin")
181
+ end
182
+
183
+ def print_help
184
+ print(<<~TEXT)
185
+ USAGE: ruby #{$PROGRAM_NAME} [options]
186
+
187
+ Flags that are always valid:
188
+
189
+ --disable-system-libraries
190
+ Use the packaged libraries, and ignore the system libraries.
191
+ (This is the default behavior.)
192
+
193
+ --enable-system-libraries
194
+ Use system libraries instead of building and using the packaged libraries.
195
+
196
+ --with-sqlcipher
197
+ Use libsqlcipher instead of libsqlite3.
198
+ (Implies `--enable-system-libraries`.)
199
+
200
+ --with-sqlite-source-dir=DIRECTORY
201
+ (dev only) Build sqlite from the source code in DIRECTORY
202
+
203
+ --help
204
+ Display this message.
205
+
206
+
207
+ Flags only used when using system libraries:
208
+
209
+ General (applying to all system libraries):
210
+
211
+ --with-opt-dir=DIRECTORY
212
+ Look for headers and libraries in DIRECTORY.
213
+
214
+ --with-opt-lib=DIRECTORY
215
+ Look for libraries in DIRECTORY.
216
+
217
+ --with-opt-include=DIRECTORY
218
+ Look for headers in DIRECTORY.
219
+
220
+ Related to sqlcipher:
221
+
222
+ --with-sqlcipher-dir=DIRECTORY
223
+ Look for sqlcipher headers and library in DIRECTORY.
224
+ (Implies `--with-sqlcipher` and `--enable-system-libraries`.)
225
+
226
+ --with-sqlcipher-lib=DIRECTORY
227
+ Look for sqlcipher library in DIRECTORY.
228
+ (Implies `--with-sqlcipher` and `--enable-system-libraries`.)
229
+
230
+ --with-sqlcipher-include=DIRECTORY
231
+ Look for sqlcipher headers in DIRECTORY.
232
+ (Implies `--with-sqlcipher` and `--enable-system-libraries`.)
233
+
234
+
235
+ Flags only used when building and using the packaged libraries:
236
+
237
+ --enable-cross-build
238
+ Enable cross-build mode. (You probably do not want to set this manually.)
239
+
240
+
241
+ Environment variables used for compiling the C extension:
242
+
243
+ CC
244
+ Use this path to invoke the compiler instead of `RbConfig::CONFIG['CC']`
245
+
246
+
247
+ Environment variables passed through to the compilation of packaged libraries:
248
+
249
+ CC
250
+ CPPFLAGS
251
+ CFLAGS
252
+ LDFLAGS
253
+ LIBS
254
+ LT_SYS_LIBRARY_PATH
255
+ CPP
256
+
257
+ TEXT
258
+ end
259
+ end
260
+ end
261
+ end
262
+
263
+ if arg_config("--help")
264
+ Sqlite3::ExtConf.print_help
265
+ exit!(0)
94
266
  end
95
267
 
96
- have_func('sqlite3_prepare_v2')
97
- have_type('sqlite3_int64', 'sqlite3.h')
98
- have_type('sqlite3_uint64', 'sqlite3.h')
268
+ if arg_config("--download-dependencies")
269
+ Sqlite3::ExtConf.download
270
+ exit!(0)
271
+ end
99
272
 
100
- create_makefile('sqlite3/sqlite3_native')
273
+ Sqlite3::ExtConf.configure
@@ -82,7 +82,7 @@ static VALUE threadsafe_p(VALUE UNUSED(klass))
82
82
  return INT2NUM(sqlite3_threadsafe());
83
83
  }
84
84
 
85
- void init_sqlite3_constants()
85
+ void init_sqlite3_constants(void)
86
86
  {
87
87
  VALUE mSqlite3Constants;
88
88
  VALUE mSqlite3Open;
@@ -127,7 +127,8 @@ void init_sqlite3_constants()
127
127
  #endif
128
128
  }
129
129
 
130
- void Init_sqlite3_native()
130
+ RUBY_FUNC_EXPORTED
131
+ void Init_sqlite3_native(void)
131
132
  {
132
133
  /*
133
134
  * SQLite3 is a wrapper around the popular database
@@ -158,4 +159,6 @@ void Init_sqlite3_native()
158
159
  rb_define_singleton_method(mSqlite3, "threadsafe", threadsafe_p, 0);
159
160
  rb_define_const(mSqlite3, "SQLITE_VERSION", rb_str_new2(SQLITE_VERSION));
160
161
  rb_define_const(mSqlite3, "SQLITE_VERSION_NUMBER", INT2FIX(SQLITE_VERSION_NUMBER));
162
+ rb_define_const(mSqlite3, "SQLITE_LOADED_VERSION", rb_str_new2(sqlite3_libversion()));
163
+
161
164
  }
@@ -21,8 +21,11 @@
21
21
  #define SQLITE3_UTF8_STR_NEW2(_obj) \
22
22
  (rb_enc_associate_index(rb_str_new2(_obj), rb_utf8_encindex()))
23
23
 
24
-
25
- #include <sqlite3.h>
24
+ #ifdef USING_SQLCIPHER_INC_SUBDIR
25
+ # include <sqlcipher/sqlite3.h>
26
+ #else
27
+ # include <sqlite3.h>
28
+ #endif
26
29
 
27
30
  #ifndef HAVE_TYPE_SQLITE3_INT64
28
31
  typedef sqlite_int64 sqlite3_int64;
@@ -290,7 +290,7 @@ static VALUE bind_param(VALUE self, VALUE key, VALUE value)
290
290
  /* call-seq: stmt.reset!
291
291
  *
292
292
  * Resets the statement. This is typically done internally, though it might
293
- * occassionally be necessary to manually reset the statement.
293
+ * occasionally be necessary to manually reset the statement.
294
294
  */
295
295
  static VALUE reset_bang(VALUE self)
296
296
  {
@@ -309,7 +309,7 @@ static VALUE reset_bang(VALUE self)
309
309
  /* call-seq: stmt.clear_bindings!
310
310
  *
311
311
  * Resets the statement. This is typically done internally, though it might
312
- * occassionally be necessary to manually reset the statement.
312
+ * occasionally be necessary to manually reset the statement.
313
313
  */
314
314
  static VALUE clear_bindings_bang(VALUE self)
315
315
  {
@@ -418,7 +418,7 @@ static VALUE database_name(VALUE self, VALUE index)
418
418
 
419
419
  #endif
420
420
 
421
- void init_sqlite3_statement()
421
+ void init_sqlite3_statement(void)
422
422
  {
423
423
  cSqlite3Statement = rb_define_class_under(mSqlite3, "Statement", rb_cObject);
424
424