sqlite3 1.5.0 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +390 -0
  3. data/CONTRIBUTING.md +34 -2
  4. data/{faq/faq.md → FAQ.md} +0 -43
  5. data/INSTALLATION.md +269 -0
  6. data/LICENSE +18 -22
  7. data/README.md +76 -128
  8. data/dependencies.yml +13 -0
  9. data/ext/sqlite3/aggregator.c +142 -146
  10. data/ext/sqlite3/aggregator.h +2 -4
  11. data/ext/sqlite3/backup.c +86 -64
  12. data/ext/sqlite3/backup.h +2 -2
  13. data/ext/sqlite3/database.c +543 -465
  14. data/ext/sqlite3/database.h +9 -4
  15. data/ext/sqlite3/exception.c +111 -92
  16. data/ext/sqlite3/exception.h +3 -1
  17. data/ext/sqlite3/extconf.rb +83 -51
  18. data/ext/sqlite3/sqlite3.c +160 -115
  19. data/ext/sqlite3/sqlite3_ruby.h +2 -2
  20. data/ext/sqlite3/statement.c +518 -293
  21. data/ext/sqlite3/statement.h +3 -3
  22. data/ext/sqlite3/timespec.h +20 -0
  23. data/lib/sqlite3/constants.rb +171 -47
  24. data/lib/sqlite3/database.rb +141 -181
  25. data/lib/sqlite3/errors.rb +26 -1
  26. data/lib/sqlite3/pragmas.rb +128 -138
  27. data/lib/sqlite3/resultset.rb +14 -105
  28. data/lib/sqlite3/statement.rb +58 -13
  29. data/lib/sqlite3/value.rb +17 -20
  30. data/lib/sqlite3/version.rb +1 -21
  31. data/lib/sqlite3.rb +6 -4
  32. data/ports/archives/sqlite-autoconf-3460000.tar.gz +0 -0
  33. metadata +19 -107
  34. data/API_CHANGES.md +0 -49
  35. data/ChangeLog.cvs +0 -88
  36. data/Gemfile +0 -3
  37. data/LICENSE-DEPENDENCIES +0 -20
  38. data/faq/faq.rb +0 -145
  39. data/faq/faq.yml +0 -426
  40. data/lib/sqlite3/translator.rb +0 -118
  41. data/ports/archives/sqlite-autoconf-3380500.tar.gz +0 -0
  42. data/test/helper.rb +0 -27
  43. data/test/test_backup.rb +0 -33
  44. data/test/test_collation.rb +0 -82
  45. data/test/test_database.rb +0 -545
  46. data/test/test_database_flags.rb +0 -95
  47. data/test/test_database_readonly.rb +0 -36
  48. data/test/test_database_readwrite.rb +0 -41
  49. data/test/test_deprecated.rb +0 -44
  50. data/test/test_encoding.rb +0 -155
  51. data/test/test_integration.rb +0 -507
  52. data/test/test_integration_aggregate.rb +0 -336
  53. data/test/test_integration_open_close.rb +0 -30
  54. data/test/test_integration_pending.rb +0 -115
  55. data/test/test_integration_resultset.rb +0 -142
  56. data/test/test_integration_statement.rb +0 -194
  57. data/test/test_result_set.rb +0 -37
  58. data/test/test_sqlite3.rb +0 -30
  59. data/test/test_statement.rb +0 -263
  60. data/test/test_statement_execute.rb +0 -35
@@ -4,14 +4,19 @@
4
4
  #include <sqlite3_ruby.h>
5
5
 
6
6
  struct _sqlite3Ruby {
7
- sqlite3 *db;
7
+ sqlite3 *db;
8
+ VALUE busy_handler;
9
+ int stmt_timeout;
10
+ struct timespec stmt_deadline;
8
11
  };
9
12
 
10
13
  typedef struct _sqlite3Ruby sqlite3Ruby;
11
- typedef sqlite3Ruby * sqlite3RubyPtr;
14
+ typedef sqlite3Ruby *sqlite3RubyPtr;
12
15
 
13
16
  void init_sqlite3_database();
14
- void set_sqlite3_func_result(sqlite3_context * ctx, VALUE result);
15
- VALUE sqlite3val2rb(sqlite3_value * val);
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);
16
21
 
17
22
  #endif
@@ -1,98 +1,117 @@
1
1
  #include <sqlite3_ruby.h>
2
2
 
3
- void rb_sqlite3_raise(sqlite3 * db, int status)
3
+ void
4
+ rb_sqlite3_raise(sqlite3 *db, int status)
4
5
  {
5
- VALUE klass = Qnil;
6
+ VALUE klass = Qnil;
6
7
 
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
- }
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
+ }
94
95
 
95
- klass = rb_exc_new2(klass, sqlite3_errmsg(db));
96
- rb_iv_set(klass, "@code", INT2FIX(status));
97
- rb_exc_raise(klass);
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);
98
117
  }
@@ -2,7 +2,9 @@
2
2
  #define SQLITE3_EXCEPTION_RUBY
3
3
 
4
4
  #define CHECK(_db, _status) rb_sqlite3_raise(_db, _status);
5
+ #define CHECK_MSG(_db, _status, _msg) rb_sqlite3_raise_msg(_db, _status, _msg);
5
6
 
6
- void rb_sqlite3_raise(sqlite3 * db, int status);
7
+ void rb_sqlite3_raise(sqlite3 *db, int status);
8
+ void rb_sqlite3_raise_msg(sqlite3 *db, int status, const char *msg);
7
9
 
8
10
  #endif
@@ -1,5 +1,5 @@
1
1
  require "mkmf"
2
- require "mini_portile2"
2
+ require "yaml"
3
3
 
4
4
  module Sqlite3
5
5
  module ExtConf
@@ -19,7 +19,7 @@ module Sqlite3
19
19
 
20
20
  configure_extension
21
21
 
22
- create_makefile('sqlite3/sqlite3_native')
22
+ create_makefile("sqlite3/sqlite3_native")
23
23
  end
24
24
 
25
25
  def configure_cross_compiler
@@ -49,15 +49,22 @@ module Sqlite3
49
49
 
50
50
  def configure_packaged_libraries
51
51
  minimal_recipe.tap do |recipe|
52
- recipe.configure_options += ["--enable-shared=no", "--enable-static=yes"]
52
+ recipe.configure_options += [
53
+ "--enable-shared=no",
54
+ "--enable-static=yes",
55
+ "--enable-fts5"
56
+ ]
53
57
  ENV.to_h.tap do |env|
54
- additional_cflags = [
58
+ user_cflags = with_config("sqlite-cflags")
59
+ more_cflags = [
55
60
  "-fPIC", # needed for linking the static library into a shared library
56
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"
57
64
  ]
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}" }
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}" }
61
68
  end
62
69
 
63
70
  unless File.exist?(File.join(recipe.target, recipe.host, recipe.name, recipe.version))
@@ -65,22 +72,32 @@ module Sqlite3
65
72
  end
66
73
  recipe.activate
67
74
 
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")
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)
76
93
  end
94
+
95
+ ldflags.each { |ldflag| append_ldflags(ldflag) }
77
96
  end
78
97
  end
79
98
 
80
99
  def configure_extension
81
- if Gem::Requirement.new("< 2.7").satisfied_by?(Gem::Version.new(RUBY_VERSION))
82
- append_cppflags("-DTAINTING_SUPPORT")
83
- end
100
+ append_cflags("-fvisibility=hidden") # see https://github.com/rake-compiler/rake-compiler-dock/issues/87
84
101
 
85
102
  if find_header("sqlite3.h")
86
103
  # noop
@@ -92,33 +109,43 @@ module Sqlite3
92
109
 
93
110
  abort_could_not_find(libname) unless find_library(libname, "sqlite3_libversion_number", "sqlite3.h")
94
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
+
95
116
  # Functions defined in 1.9 but not 1.8
96
- have_func('rb_proc_arity')
117
+ have_func("rb_proc_arity")
97
118
 
98
119
  # Functions defined in 2.1 but not 2.0
99
- have_func('rb_integer_pack')
120
+ have_func("rb_integer_pack")
100
121
 
101
122
  # 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')
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")
107
128
 
108
- unless have_func('sqlite3_open_v2') # https://www.sqlite.org/releaselog/3_5_0.html
129
+ unless have_func("sqlite3_open_v2") # https://www.sqlite.org/releaselog/3_5_0.html
109
130
  abort("\nPlease use a version of SQLite3 >= 3.5.0\n\n")
110
131
  end
111
132
 
112
- have_func('sqlite3_prepare_v2')
113
- have_type('sqlite3_int64', 'sqlite3.h')
114
- have_type('sqlite3_uint64', 'sqlite3.h')
133
+ have_func("sqlite3_prepare_v2")
134
+ have_type("sqlite3_int64", "sqlite3.h")
135
+ have_type("sqlite3_uint64", "sqlite3.h")
115
136
  end
116
137
 
117
138
  def minimal_recipe
139
+ require "mini_portile2"
140
+
118
141
  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
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
122
149
  end
123
150
  end
124
151
 
@@ -131,37 +158,33 @@ module Sqlite3
131
158
  end
132
159
 
133
160
  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
- }
161
+ YAML.load_file(File.join(package_root_dir, "dependencies.yml"), symbolize_names: true)
151
162
  end
152
163
 
153
164
  def abort_could_not_find(missing)
154
165
  abort("\nCould not find #{missing}.\nPlease visit https://github.com/sparklemotion/sqlite3-ruby for installation instructions.\n\n")
155
166
  end
156
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
+
157
172
  def cross_build?
158
173
  enable_config("cross-build")
159
174
  end
160
175
 
176
+ def sqlite_source_dir
177
+ arg_config("--with-sqlite-source-dir")
178
+ end
179
+
161
180
  def download
162
181
  minimal_recipe.download
163
182
  end
164
183
 
184
+ def darwin?
185
+ RbConfig::CONFIG["target_os"].include?("darwin")
186
+ end
187
+
165
188
  def print_help
166
189
  print(<<~TEXT)
167
190
  USAGE: ruby #{$PROGRAM_NAME} [options]
@@ -179,6 +202,9 @@ module Sqlite3
179
202
  Use libsqlcipher instead of libsqlite3.
180
203
  (Implies `--enable-system-libraries`.)
181
204
 
205
+ --with-sqlite-source-dir=DIRECTORY
206
+ (dev only) Build sqlite from the source code in DIRECTORY
207
+
182
208
  --help
183
209
  Display this message.
184
210
 
@@ -213,17 +239,23 @@ module Sqlite3
213
239
 
214
240
  Flags only used when building and using the packaged libraries:
215
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
+
216
248
  --enable-cross-build
217
249
  Enable cross-build mode. (You probably do not want to set this manually.)
218
250
 
219
251
 
220
- Environment variables used for compiling the C extension:
252
+ Environment variables used for compiling the gem's C extension:
221
253
 
222
254
  CC
223
255
  Use this path to invoke the compiler instead of `RbConfig::CONFIG['CC']`
224
256
 
225
257
 
226
- Environment variables passed through to the compilation of packaged libraries:
258
+ Environment variables passed through to the compilation of sqlite:
227
259
 
228
260
  CC
229
261
  CPPFLAGS