sqlite3 1.4.2 → 1.5.4

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,262 @@
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 "mini_portile2"
3
+ require "yaml"
23
4
 
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
5
+ module Sqlite3
6
+ module ExtConf
7
+ ENV_ALLOWLIST = ["CC", "CFLAGS", "LDFLAGS", "LIBS", "CPPFLAGS", "LT_SYS_LIBRARY_PATH", "CPP"]
31
8
 
32
- if with_config('sqlcipher')
33
- pkg_config("sqlcipher")
34
- else
35
- pkg_config("sqlite3")
36
- end
9
+ class << self
10
+ def configure
11
+ configure_cross_compiler
37
12
 
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
13
+ if system_libraries?
14
+ message "Building sqlite3-ruby using system #{libname}.\n"
15
+ configure_system_libraries
16
+ else
17
+ message "Building sqlite3-ruby using packaged sqlite3.\n"
18
+ configure_packaged_libraries
19
+ end
45
20
 
46
- if RbConfig::CONFIG["host_os"] =~ /mswin/
47
- $CFLAGS << ' -W3'
48
- end
21
+ configure_extension
49
22
 
50
- if RUBY_VERSION < '2.7'
51
- $CFLAGS << ' -DTAINTING_SUPPORT'
52
- end
23
+ create_makefile('sqlite3/sqlite3_native')
24
+ end
53
25
 
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
26
+ def configure_cross_compiler
27
+ RbConfig::CONFIG["CC"] = RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"] if ENV["CC"]
28
+ ENV["CC"] = RbConfig::CONFIG["CC"]
29
+ end
67
30
 
68
- asplode('sqlite3.h') unless find_header 'sqlite3.h'
69
- find_library 'pthread', 'pthread_create' # 1.8 support. *shrug*
31
+ def system_libraries?
32
+ sqlcipher? || enable_config("system-libraries")
33
+ end
70
34
 
71
- have_library 'dl' # for static builds
35
+ def libname
36
+ sqlcipher? ? "sqlcipher" : "sqlite3"
37
+ end
72
38
 
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
39
+ def sqlcipher?
40
+ with_config("sqlcipher") ||
41
+ with_config("sqlcipher-dir") ||
42
+ with_config("sqlcipher-include") ||
43
+ with_config("sqlcipher-lib")
44
+ end
45
+
46
+ def configure_system_libraries
47
+ pkg_config(libname)
48
+ append_cppflags("-DUSING_SQLCIPHER") if sqlcipher?
49
+ end
50
+
51
+ def configure_packaged_libraries
52
+ minimal_recipe.tap do |recipe|
53
+ recipe.configure_options += ["--enable-shared=no", "--enable-static=yes"]
54
+ ENV.to_h.tap do |env|
55
+ additional_cflags = [
56
+ "-fPIC", # needed for linking the static library into a shared library
57
+ "-O2", # see https://github.com/sparklemotion/sqlite3-ruby/issues/335 for some benchmarks
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
+ lib_path = File.join(recipe.path, "lib")
73
+ pcfile = File.join(lib_path, "pkgconfig", "sqlite3.pc")
74
+ abort_pkg_config("pkg_config") unless pkg_config(pcfile)
75
+
76
+ # see https://bugs.ruby-lang.org/issues/18490
77
+ flags = xpopen(["pkg-config", "--libs", "--static", pcfile], err: [:child, :out], &:read)
78
+ abort_pkg_config("xpopen") unless $?.success?
79
+ flags = flags.split
80
+
81
+ # see https://github.com/flavorjones/mini_portile/issues/118
82
+ "-L#{lib_path}".tap do |lib_path_flag|
83
+ flags.prepend(lib_path_flag) unless flags.include?(lib_path_flag)
84
+ end
85
+
86
+ flags.each { |flag| append_ldflags(flag) }
87
+ end
88
+ end
89
+
90
+ def configure_extension
91
+ if Gem::Requirement.new("< 2.7").satisfied_by?(Gem::Version.new(RUBY_VERSION))
92
+ append_cppflags("-DTAINTING_SUPPORT")
93
+ end
94
+
95
+ if find_header("sqlite3.h")
96
+ # noop
97
+ elsif sqlcipher? && find_header("sqlcipher/sqlite3.h")
98
+ append_cppflags("-DUSING_SQLCIPHER_INC_SUBDIR")
99
+ else
100
+ abort_could_not_find("sqlite3.h")
101
+ end
102
+
103
+ abort_could_not_find(libname) unless find_library(libname, "sqlite3_libversion_number", "sqlite3.h")
104
+
105
+ # Functions defined in 1.9 but not 1.8
106
+ have_func('rb_proc_arity')
107
+
108
+ # Functions defined in 2.1 but not 2.0
109
+ have_func('rb_integer_pack')
110
+
111
+ # These functions may not be defined
112
+ have_func('sqlite3_initialize')
113
+ have_func('sqlite3_backup_init')
114
+ have_func('sqlite3_column_database_name')
115
+ have_func('sqlite3_enable_load_extension')
116
+ have_func('sqlite3_load_extension')
117
+
118
+ unless have_func('sqlite3_open_v2') # https://www.sqlite.org/releaselog/3_5_0.html
119
+ abort("\nPlease use a version of SQLite3 >= 3.5.0\n\n")
120
+ end
121
+
122
+ have_func('sqlite3_prepare_v2')
123
+ have_type('sqlite3_int64', 'sqlite3.h')
124
+ have_type('sqlite3_uint64', 'sqlite3.h')
125
+ end
126
+
127
+ def minimal_recipe
128
+ MiniPortile.new(libname, sqlite3_config[:version]).tap do |recipe|
129
+ if sqlite_source_dir
130
+ recipe.source_directory = sqlite_source_dir
131
+ else
132
+ recipe.files = sqlite3_config[:files]
133
+ recipe.target = File.join(package_root_dir, "ports")
134
+ recipe.patch_files = Dir[File.join(package_root_dir, "patches", "*.patch")].sort
135
+ end
136
+ end
137
+ end
138
+
139
+ def package_root_dir
140
+ File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))
141
+ end
142
+
143
+ def sqlite3_config
144
+ mini_portile_config[:sqlite3]
145
+ end
146
+
147
+ def mini_portile_config
148
+ # TODO: once Ruby 2.7 is no longer supported, use symbolize_names: true
149
+ YAML.load_file(File.join(package_root_dir, "dependencies.yml"))
150
+ end
151
+
152
+ def abort_could_not_find(missing)
153
+ abort("\nCould not find #{missing}.\nPlease visit https://github.com/sparklemotion/sqlite3-ruby for installation instructions.\n\n")
154
+ end
155
+
156
+ def abort_pkg_config(id)
157
+ abort("\nCould not configure the build properly (#{id}). Please install either the `pkg-config` utility or the `pkg-config` rubygem.\n\n")
158
+ end
78
159
 
79
- # Functions defined in 1.9 but not 1.8
80
- have_func('rb_proc_arity')
160
+ def cross_build?
161
+ enable_config("cross-build")
162
+ end
81
163
 
82
- # Functions defined in 2.1 but not 2.0
83
- have_func('rb_integer_pack')
164
+ def sqlite_source_dir
165
+ arg_config("--with-sqlite-source-dir")
166
+ end
84
167
 
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')
168
+ def download
169
+ minimal_recipe.download
170
+ end
91
171
 
92
- unless have_func('sqlite3_open_v2')
93
- abort "Please use a newer version of SQLite3"
172
+ def print_help
173
+ print(<<~TEXT)
174
+ USAGE: ruby #{$PROGRAM_NAME} [options]
175
+
176
+ Flags that are always valid:
177
+
178
+ --disable-system-libraries
179
+ Use the packaged libraries, and ignore the system libraries.
180
+ (This is the default behavior.)
181
+
182
+ --enable-system-libraries
183
+ Use system libraries instead of building and using the packaged libraries.
184
+
185
+ --with-sqlcipher
186
+ Use libsqlcipher instead of libsqlite3.
187
+ (Implies `--enable-system-libraries`.)
188
+
189
+ --with-sqlite-source-dir=DIRECTORY
190
+ (dev only) Build sqlite from the source code in DIRECTORY
191
+
192
+ --help
193
+ Display this message.
194
+
195
+
196
+ Flags only used when using system libraries:
197
+
198
+ General (applying to all system libraries):
199
+
200
+ --with-opt-dir=DIRECTORY
201
+ Look for headers and libraries in DIRECTORY.
202
+
203
+ --with-opt-lib=DIRECTORY
204
+ Look for libraries in DIRECTORY.
205
+
206
+ --with-opt-include=DIRECTORY
207
+ Look for headers in DIRECTORY.
208
+
209
+ Related to sqlcipher:
210
+
211
+ --with-sqlcipher-dir=DIRECTORY
212
+ Look for sqlcipher headers and library in DIRECTORY.
213
+ (Implies `--with-sqlcipher` and `--enable-system-libraries`.)
214
+
215
+ --with-sqlcipher-lib=DIRECTORY
216
+ Look for sqlcipher library in DIRECTORY.
217
+ (Implies `--with-sqlcipher` and `--enable-system-libraries`.)
218
+
219
+ --with-sqlcipher-include=DIRECTORY
220
+ Look for sqlcipher headers in DIRECTORY.
221
+ (Implies `--with-sqlcipher` and `--enable-system-libraries`.)
222
+
223
+
224
+ Flags only used when building and using the packaged libraries:
225
+
226
+ --enable-cross-build
227
+ Enable cross-build mode. (You probably do not want to set this manually.)
228
+
229
+
230
+ Environment variables used for compiling the C extension:
231
+
232
+ CC
233
+ Use this path to invoke the compiler instead of `RbConfig::CONFIG['CC']`
234
+
235
+
236
+ Environment variables passed through to the compilation of packaged libraries:
237
+
238
+ CC
239
+ CPPFLAGS
240
+ CFLAGS
241
+ LDFLAGS
242
+ LIBS
243
+ LT_SYS_LIBRARY_PATH
244
+ CPP
245
+
246
+ TEXT
247
+ end
248
+ end
249
+ end
94
250
  end
95
251
 
96
- have_func('sqlite3_prepare_v2')
97
- have_type('sqlite3_int64', 'sqlite3.h')
98
- have_type('sqlite3_uint64', 'sqlite3.h')
252
+ if arg_config("--help")
253
+ Sqlite3::ExtConf.print_help
254
+ exit!(0)
255
+ end
256
+
257
+ if arg_config("--download-dependencies")
258
+ Sqlite3::ExtConf.download
259
+ exit!(0)
260
+ end
99
261
 
100
- create_makefile('sqlite3/sqlite3_native')
262
+ Sqlite3::ExtConf.configure
@@ -158,4 +158,6 @@ void Init_sqlite3_native()
158
158
  rb_define_singleton_method(mSqlite3, "threadsafe", threadsafe_p, 0);
159
159
  rb_define_const(mSqlite3, "SQLITE_VERSION", rb_str_new2(SQLITE_VERSION));
160
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
+
161
163
  }
@@ -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
  {