sqlite3 2.1.1-x64-mingw-ucrt → 2.2.0-x64-mingw-ucrt

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a8969e0c070915409b5c6b92980ac9c919a183705648ac49911e15651cc43585
4
- data.tar.gz: 54a9f65d914d9c9f138f06671cf3a4f98d8b82a8edc9da0fa52e981790bd37cd
3
+ metadata.gz: '096eb78a16f8bb2d4c0cface81a0e72d997437ac3307dff664d0b7561d9d6be7'
4
+ data.tar.gz: a2a595e70285134280eeb6dc349ee3e26e82d10cb34ffdf731d894387bdab314
5
5
  SHA512:
6
- metadata.gz: 357749864d3152c5497e47bc8f8a603c083fb2570cd8238abc3998d02ebaefe00a52232c61d9ef58f96c84d71e0ee6485a0cb73700cc93b395cccdaf650f4d42
7
- data.tar.gz: a6cc1d7204fbbcddb78ac336fb6ccbbe5dbac54290e2233aaecbd0a803b11d17071246fee769e0b6d617cbbbbcea7f53b99f824a54f4fe74110717a20ba67c04
6
+ metadata.gz: a830939fc2b9823a229f077cf8230c18f58be186af86e64899faa324634496f6330dc22318d32bb22cbbcc4b0574df1d090104bc272dba20f020eff79be270c9
7
+ data.tar.gz: f07573f2f5128c1a14c2ab175efdbfdde54cc15bee678ed48768db5ac1b332d28a9549f76d9ee68a4c68eeb5e552c5744857d9955bf9b5ce2554c62f8f0871c8
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # sqlite3-ruby Changelog
2
2
 
3
+ ## 2.2.0 / 2024-10-30
4
+
5
+ ### Added
6
+
7
+ - URI filenames are now allowed. This allows the injection of some behavior via recognized query parameters. See https://www.sqlite.org/uri.html for more information. [#571] @flavorjones
8
+
9
+
10
+ ### Improved
11
+
12
+ - SQL Syntax errors during `Database#prepare` will raise a verbose exception with a multiline message indicating with a "^" exactly where in the statement the error occurred. [#554] @fractaledmind @flavorjones
13
+
14
+
3
15
  ## 2.1.1 / 2024-10-22
4
16
 
5
17
  ### Dependencies
@@ -1,101 +1,82 @@
1
1
  #include <sqlite3_ruby.h>
2
2
 
3
- void
4
- rb_sqlite3_raise(sqlite3 *db, int status)
3
+ static VALUE
4
+ status2klass(int status)
5
5
  {
6
- VALUE klass = Qnil;
7
-
8
6
  /* Consider only lower 8 bits, to work correctly when
9
7
  extended result codes are enabled. */
10
8
  switch (status & 0xff) {
11
9
  case SQLITE_OK:
12
- return;
13
- break;
10
+ return Qnil;
14
11
  case SQLITE_ERROR:
15
- klass = rb_path2class("SQLite3::SQLException");
16
- break;
12
+ return rb_path2class("SQLite3::SQLException");
17
13
  case SQLITE_INTERNAL:
18
- klass = rb_path2class("SQLite3::InternalException");
19
- break;
14
+ return rb_path2class("SQLite3::InternalException");
20
15
  case SQLITE_PERM:
21
- klass = rb_path2class("SQLite3::PermissionException");
22
- break;
16
+ return rb_path2class("SQLite3::PermissionException");
23
17
  case SQLITE_ABORT:
24
- klass = rb_path2class("SQLite3::AbortException");
25
- break;
18
+ return rb_path2class("SQLite3::AbortException");
26
19
  case SQLITE_BUSY:
27
- klass = rb_path2class("SQLite3::BusyException");
28
- break;
20
+ return rb_path2class("SQLite3::BusyException");
29
21
  case SQLITE_LOCKED:
30
- klass = rb_path2class("SQLite3::LockedException");
31
- break;
22
+ return rb_path2class("SQLite3::LockedException");
32
23
  case SQLITE_NOMEM:
33
- klass = rb_path2class("SQLite3::MemoryException");
34
- break;
24
+ return rb_path2class("SQLite3::MemoryException");
35
25
  case SQLITE_READONLY:
36
- klass = rb_path2class("SQLite3::ReadOnlyException");
37
- break;
26
+ return rb_path2class("SQLite3::ReadOnlyException");
38
27
  case SQLITE_INTERRUPT:
39
- klass = rb_path2class("SQLite3::InterruptException");
40
- break;
28
+ return rb_path2class("SQLite3::InterruptException");
41
29
  case SQLITE_IOERR:
42
- klass = rb_path2class("SQLite3::IOException");
43
- break;
30
+ return rb_path2class("SQLite3::IOException");
44
31
  case SQLITE_CORRUPT:
45
- klass = rb_path2class("SQLite3::CorruptException");
46
- break;
32
+ return rb_path2class("SQLite3::CorruptException");
47
33
  case SQLITE_NOTFOUND:
48
- klass = rb_path2class("SQLite3::NotFoundException");
49
- break;
34
+ return rb_path2class("SQLite3::NotFoundException");
50
35
  case SQLITE_FULL:
51
- klass = rb_path2class("SQLite3::FullException");
52
- break;
36
+ return rb_path2class("SQLite3::FullException");
53
37
  case SQLITE_CANTOPEN:
54
- klass = rb_path2class("SQLite3::CantOpenException");
55
- break;
38
+ return rb_path2class("SQLite3::CantOpenException");
56
39
  case SQLITE_PROTOCOL:
57
- klass = rb_path2class("SQLite3::ProtocolException");
58
- break;
40
+ return rb_path2class("SQLite3::ProtocolException");
59
41
  case SQLITE_EMPTY:
60
- klass = rb_path2class("SQLite3::EmptyException");
61
- break;
42
+ return rb_path2class("SQLite3::EmptyException");
62
43
  case SQLITE_SCHEMA:
63
- klass = rb_path2class("SQLite3::SchemaChangedException");
64
- break;
44
+ return rb_path2class("SQLite3::SchemaChangedException");
65
45
  case SQLITE_TOOBIG:
66
- klass = rb_path2class("SQLite3::TooBigException");
67
- break;
46
+ return rb_path2class("SQLite3::TooBigException");
68
47
  case SQLITE_CONSTRAINT:
69
- klass = rb_path2class("SQLite3::ConstraintException");
70
- break;
48
+ return rb_path2class("SQLite3::ConstraintException");
71
49
  case SQLITE_MISMATCH:
72
- klass = rb_path2class("SQLite3::MismatchException");
73
- break;
50
+ return rb_path2class("SQLite3::MismatchException");
74
51
  case SQLITE_MISUSE:
75
- klass = rb_path2class("SQLite3::MisuseException");
76
- break;
52
+ return rb_path2class("SQLite3::MisuseException");
77
53
  case SQLITE_NOLFS:
78
- klass = rb_path2class("SQLite3::UnsupportedException");
79
- break;
54
+ return rb_path2class("SQLite3::UnsupportedException");
80
55
  case SQLITE_AUTH:
81
- klass = rb_path2class("SQLite3::AuthorizationException");
82
- break;
56
+ return rb_path2class("SQLite3::AuthorizationException");
83
57
  case SQLITE_FORMAT:
84
- klass = rb_path2class("SQLite3::FormatException");
85
- break;
58
+ return rb_path2class("SQLite3::FormatException");
86
59
  case SQLITE_RANGE:
87
- klass = rb_path2class("SQLite3::RangeException");
88
- break;
60
+ return rb_path2class("SQLite3::RangeException");
89
61
  case SQLITE_NOTADB:
90
- klass = rb_path2class("SQLite3::NotADatabaseException");
91
- break;
62
+ return rb_path2class("SQLite3::NotADatabaseException");
92
63
  default:
93
- klass = rb_path2class("SQLite3::Exception");
64
+ return rb_path2class("SQLite3::Exception");
65
+ }
66
+ }
67
+
68
+ void
69
+ rb_sqlite3_raise(sqlite3 *db, int status)
70
+ {
71
+ VALUE klass = status2klass(status);
72
+ if (NIL_P(klass)) {
73
+ return;
94
74
  }
95
75
 
96
- klass = rb_exc_new2(klass, sqlite3_errmsg(db));
97
- rb_iv_set(klass, "@code", INT2FIX(status));
98
- rb_exc_raise(klass);
76
+ VALUE exception = rb_exc_new2(klass, sqlite3_errmsg(db));
77
+ rb_iv_set(exception, "@code", INT2FIX(status));
78
+
79
+ rb_exc_raise(exception);
99
80
  }
100
81
 
101
82
  /*
@@ -104,14 +85,38 @@ rb_sqlite3_raise(sqlite3 *db, int status)
104
85
  void
105
86
  rb_sqlite3_raise_msg(sqlite3 *db, int status, const char *msg)
106
87
  {
107
- VALUE exception;
108
-
109
- if (status == SQLITE_OK) {
88
+ VALUE klass = status2klass(status);
89
+ if (NIL_P(klass)) {
110
90
  return;
111
91
  }
112
92
 
113
- exception = rb_exc_new2(rb_path2class("SQLite3::Exception"), msg);
93
+ VALUE exception = rb_exc_new2(klass, msg);
94
+ rb_iv_set(exception, "@code", INT2FIX(status));
114
95
  sqlite3_free((void *)msg);
96
+
97
+ rb_exc_raise(exception);
98
+ }
99
+
100
+ void
101
+ rb_sqlite3_raise_with_sql(sqlite3 *db, int status, const char *sql)
102
+ {
103
+ VALUE klass = status2klass(status);
104
+ if (NIL_P(klass)) {
105
+ return;
106
+ }
107
+
108
+ const char *error_msg = sqlite3_errmsg(db);
109
+ int error_offset = -1;
110
+ #ifdef HAVE_SQLITE3_ERROR_OFFSET
111
+ error_offset = sqlite3_error_offset(db);
112
+ #endif
113
+
114
+ VALUE exception = rb_exc_new2(klass, error_msg);
115
115
  rb_iv_set(exception, "@code", INT2FIX(status));
116
+ if (sql) {
117
+ rb_iv_set(exception, "@sql", rb_str_new2(sql));
118
+ rb_iv_set(exception, "@sql_offset", INT2FIX(error_offset));
119
+ }
120
+
116
121
  rb_exc_raise(exception);
117
122
  }
@@ -3,8 +3,10 @@
3
3
 
4
4
  #define CHECK(_db, _status) rb_sqlite3_raise(_db, _status);
5
5
  #define CHECK_MSG(_db, _status, _msg) rb_sqlite3_raise_msg(_db, _status, _msg);
6
+ #define CHECK_PREPARE(_db, _status, _sql) rb_sqlite3_raise_with_sql(_db, _status, _sql)
6
7
 
7
8
  void rb_sqlite3_raise(sqlite3 *db, int status);
8
9
  void rb_sqlite3_raise_msg(sqlite3 *db, int status, const char *msg);
10
+ void rb_sqlite3_raise_with_sql(sqlite3 *db, int status, const char *sql);
9
11
 
10
12
  #endif
@@ -50,8 +50,9 @@ module Sqlite3
50
50
  def configure_packaged_libraries
51
51
  minimal_recipe.tap do |recipe|
52
52
  recipe.configure_options += [
53
- "--enable-shared=no",
54
- "--enable-static=yes",
53
+ "--disable-shared",
54
+ "--enable-static",
55
+ "--disable-tcl",
55
56
  "--enable-fts5"
56
57
  ]
57
58
  ENV.to_h.tap do |env|
@@ -60,7 +61,8 @@ module Sqlite3
60
61
  "-fPIC", # needed for linking the static library into a shared library
61
62
  "-O2", # see https://github.com/sparklemotion/sqlite3-ruby/issues/335 for some benchmarks
62
63
  "-fvisibility=hidden", # see https://github.com/rake-compiler/rake-compiler-dock/issues/87
63
- "-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1"
64
+ "-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1",
65
+ "-DSQLITE_USE_URI=1"
64
66
  ]
65
67
  env["CFLAGS"] = [user_cflags, env["CFLAGS"], more_cflags].flatten.join(" ")
66
68
  recipe.configure_options += env.select { |k, v| ENV_ALLOWLIST.include?(k) }
@@ -132,6 +134,7 @@ module Sqlite3
132
134
 
133
135
  have_func("sqlite3_prepare_v2")
134
136
  have_func("sqlite3_db_name", "sqlite3.h") # v3.39.0
137
+ have_func("sqlite3_error_offset", "sqlite3.h") # v3.38.0
135
138
 
136
139
  have_type("sqlite3_int64", "sqlite3.h")
137
140
  have_type("sqlite3_uint64", "sqlite3.h")
@@ -78,7 +78,7 @@ prepare(VALUE self, VALUE db, VALUE sql)
78
78
  &tail
79
79
  );
80
80
 
81
- CHECK(db_ctx->db, status);
81
+ CHECK_PREPARE(db_ctx->db, status, StringValuePtr(sql));
82
82
  timespecclear(&db_ctx->stmt_deadline);
83
83
 
84
84
  return rb_utf8_str_new_cstr(tail);
Binary file
Binary file
Binary file
@@ -4,6 +4,34 @@ module SQLite3
4
4
  class Exception < ::StandardError
5
5
  # A convenience for accessing the error code for this exception.
6
6
  attr_reader :code
7
+
8
+ # If the error is associated with a SQL query, this is the query
9
+ attr_reader :sql
10
+
11
+ # If the error is associated with a particular offset in a SQL query, this is the non-negative
12
+ # offset. If the offset is not available, this will be -1.
13
+ attr_reader :sql_offset
14
+
15
+ def message
16
+ [super, sql_error].compact.join(":\n")
17
+ end
18
+
19
+ private def sql_error
20
+ return nil unless @sql
21
+ return @sql.chomp unless @sql_offset >= 0
22
+
23
+ offset = @sql_offset
24
+ sql.lines.flat_map do |line|
25
+ if offset >= 0 && line.length > offset
26
+ blanks = " " * offset
27
+ offset = -1
28
+ [line.chomp, blanks + "^"]
29
+ else
30
+ offset -= line.length if offset
31
+ line.chomp
32
+ end
33
+ end.join("\n")
34
+ end
7
35
  end
8
36
 
9
37
  class SQLException < Exception; end
@@ -1,3 +1,3 @@
1
1
  module SQLite3
2
- VERSION = "2.1.1"
2
+ VERSION = "2.2.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sqlite3
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
4
+ version: 2.2.0
5
5
  platform: x64-mingw-ucrt
6
6
  authors:
7
7
  - Jamis Buck
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2024-10-22 00:00:00.000000000 Z
14
+ date: 2024-10-30 00:00:00.000000000 Z
15
15
  dependencies: []
16
16
  description: |
17
17
  Ruby library to interface with the SQLite3 database engine (http://www.sqlite.org). Precompiled