extralite 1.25 → 1.27

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a6e8245385b707be08a300ff6bb089291cfa27500fd99f35698f3dc566147e0
4
- data.tar.gz: 1bc49ffc376a8e8f17da33cda6afdd59299e9d6dac381ef2ff9c7ea8d3a92418
3
+ metadata.gz: a027328ec4af0d01bc81706f4f8e1ea08770a1341d8a36953882244b2d20ed88
4
+ data.tar.gz: 916fabb4a5328e93bcdcb8121b54aa3e958b87915e9b1c9027cccb44941837b9
5
5
  SHA512:
6
- metadata.gz: 1e119afa5f07f499935cd83692cb86c22c548ed7f4e35b46735860349186e66c5b1cd1ca2b32cbc8aa41c1e9106c942d38958b145480b397d838a5d75d32985f
7
- data.tar.gz: 28f0b76e7ed23e51b9f99f7a8756534163330f909668d7f2d1fa34bd1517ee37ccfdcffe18028fa51cbf427353f313256832daead4ed09a00742a4bd24236744
6
+ metadata.gz: fc4cd60e38d6e229d5d28ab6e28db3a16f7ddf1ffde53e3f5a97cacebe607158604421016bab34fa5bf96659ab4d0074fffb0f51712e4429d5529f59bbcdec0d
7
+ data.tar.gz: db9905c1c839a4135fe4c1156b3991f8cad5ac438b5c70091be34e8afee7563371e19afe45cd835cec2f83dd26fc92e5855bf7c53c6ee473728b80caabb3e5e1
data/.github/FUNDING.yml CHANGED
@@ -1 +1 @@
1
- github: ciconia
1
+ github: noteflakes
data/.yardopts ADDED
@@ -0,0 +1,8 @@
1
+ -o ./_yardoc
2
+ -m markdown -M redcarpet
3
+ --verbose
4
+ --protected
5
+ --no-private
6
+ --exclude sqlite3_constants.rb
7
+ ./lib
8
+ ./ext/extralite
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ # 1.27 2023-06-12
2
+
3
+ - Fix execution of prepared statements in Sequel adapter (#23 @gschlager)
4
+ - Update bundled sqlite code to version 3.42.0 (#22 @gschlager)
5
+
6
+ # 1.26 2023-05-17
7
+
8
+ - Improve documentation
9
+
1
10
  # 1.25 2023-03-10
2
11
 
3
12
  - Remove bundled sqlite3 source files from extralite.gemspec
data/Gemfile.lock CHANGED
@@ -1,13 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- extralite (1.25)
4
+ extralite (1.27)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
9
  docile (1.4.0)
10
- json (2.6.1)
10
+ json (2.6.3)
11
11
  minitest (5.15.0)
12
12
  rake (13.0.6)
13
13
  rake-compiler (1.1.6)
data/README.md CHANGED
@@ -14,7 +14,7 @@ with an SQLite3 database, as well as prepared statements.
14
14
  Extralite comes in two flavors: the `extralite` gem which uses the
15
15
  system-installed sqlite3 library, and the `extralite-bundle` gem which bundles
16
16
  the latest version of SQLite
17
- ([3.40.1](https://sqlite.org/releaselog/3_40_1.html)), offering access to the
17
+ ([3.42.0](https://sqlite.org/releaselog/3_42_0.html)), offering access to the
18
18
  latest features and enhancements.
19
19
 
20
20
  ## Features
@@ -56,6 +56,7 @@ else
56
56
  $CFLAGS << ' -DTAINTING_SUPPORT'
57
57
  end
58
58
 
59
+ # @!visibility private
59
60
  def asplode missing
60
61
  if RUBY_PLATFORM =~ /mingw|mswin/
61
62
  abort "#{missing} is missing. Install SQLite3 from " +
@@ -1,6 +1,12 @@
1
1
  #include <stdio.h>
2
2
  #include "extralite.h"
3
3
 
4
+ /*
5
+ * Document-class: Extralite::PreparedStatement
6
+ *
7
+ * This class represents a prepared statement.
8
+ */
9
+
4
10
  VALUE cPreparedStatement;
5
11
 
6
12
  static size_t PreparedStatement_size(const void *ptr) {
@@ -1,5 +1,4 @@
1
1
  module Extralite
2
-
3
2
  SQLITE_STATUS_MEMORY_USED = 0
4
3
  SQLITE_STATUS_PAGECACHE_USED = 1
5
4
  SQLITE_STATUS_PAGECACHE_OVERFLOW = 2
@@ -1,3 +1,4 @@
1
1
  module Extralite
2
- VERSION = '1.25'
2
+ # Extralite version
3
+ VERSION = '1.27'
3
4
  end
data/lib/extralite.rb CHANGED
@@ -29,6 +29,7 @@ module Extralite
29
29
  class Database
30
30
  alias_method :execute, :query
31
31
 
32
+ # @!visibility private
32
33
  TABLES_SQL = <<~SQL
33
34
  SELECT name FROM sqlite_master
34
35
  WHERE type ='table'
@@ -7,22 +7,28 @@
7
7
  require 'extralite'
8
8
  require 'sequel/adapters/shared/sqlite'
9
9
 
10
+ # @!visibility private
10
11
  module Sequel
12
+ # Extralite Sequel adapter
11
13
  module Extralite
14
+ # @!visibility private
12
15
  FALSE_VALUES = (%w'0 false f no n'.each(&:freeze) + [0]).freeze
13
16
 
14
17
  blob = Object.new
18
+ # @!visibility private
15
19
  def blob.call(s)
16
20
  Sequel::SQL::Blob.new(s.to_s)
17
21
  end
18
22
 
19
23
  boolean = Object.new
24
+ # @!visibility private
20
25
  def boolean.call(s)
21
26
  s = s.downcase if s.is_a?(String)
22
27
  !FALSE_VALUES.include?(s)
23
28
  end
24
29
 
25
30
  date = Object.new
31
+ # @!visibility private
26
32
  def date.call(s)
27
33
  case s
28
34
  when String
@@ -37,22 +43,26 @@ module Sequel
37
43
  end
38
44
 
39
45
  integer = Object.new
46
+ # @!visibility private
40
47
  def integer.call(s)
41
48
  s.to_i
42
49
  end
43
50
 
44
51
  float = Object.new
52
+ # @!visibility private
45
53
  def float.call(s)
46
54
  s.to_f
47
55
  end
48
56
 
49
57
  numeric = Object.new
58
+ # @!visibility private
50
59
  def numeric.call(s)
51
60
  s = s.to_s unless s.is_a?(String)
52
61
  BigDecimal(s) rescue s
53
62
  end
54
63
 
55
64
  time = Object.new
65
+ # @!visibility private
56
66
  def time.call(s)
57
67
  case s
58
68
  when String
@@ -82,19 +92,21 @@ module Sequel
82
92
  end
83
93
  SQLITE_TYPES.freeze
84
94
 
95
+ # @!visibility private
85
96
  USE_EXTENDED_RESULT_CODES = false
86
-
97
+
98
+ # Database adapter for Sequel
87
99
  class Database < Sequel::Database
88
100
  include ::Sequel::SQLite::DatabaseMethods
89
-
101
+
90
102
  set_adapter_scheme :extralite
91
-
103
+
92
104
  # Mimic the file:// uri, by having 2 preceding slashes specify a relative
93
105
  # path, and 3 preceding slashes specify an absolute path.
94
106
  def self.uri_to_options(uri) # :nodoc:
95
107
  { :database => (uri.host.nil? && uri.path == '/') ? nil : "#{uri.host}#{uri.path}" }
96
108
  end
97
-
109
+
98
110
  private_class_method :uri_to_options
99
111
 
100
112
  # The conversion procs to use for this database
@@ -119,14 +131,14 @@ module Sequel
119
131
  # if USE_EXTENDED_RESULT_CODES
120
132
  # db.extended_result_codes = true
121
133
  # end
122
-
134
+
123
135
  connection_pragmas.each{|s| log_connection_yield(s, db){db.query(s)}}
124
-
136
+
125
137
  class << db
126
138
  attr_reader :prepared_statements
127
139
  end
128
140
  db.instance_variable_set(:@prepared_statements, {})
129
-
141
+
130
142
  db
131
143
  end
132
144
 
@@ -135,7 +147,7 @@ module Sequel
135
147
  c.prepared_statements.each_value{|v| v.first.close }
136
148
  c.close
137
149
  end
138
-
150
+
139
151
  # Run the given SQL with the given arguments and yield each row.
140
152
  def execute(sql, opts=OPTS, &block)
141
153
  _execute(:select, sql, opts, &block)
@@ -145,7 +157,7 @@ module Sequel
145
157
  def execute_dui(sql, opts=OPTS)
146
158
  _execute(:update, sql, opts)
147
159
  end
148
-
160
+
149
161
  # Drop any prepared statements on the connection when executing DDL. This is because
150
162
  # prepared statements lock the table in such a way that you can't drop or alter the
151
163
  # table while a prepared statement that references it still exists.
@@ -156,11 +168,13 @@ module Sequel
156
168
  super
157
169
  end
158
170
  end
159
-
171
+
172
+ # @!visibility private
160
173
  def execute_insert(sql, opts=OPTS)
161
174
  _execute(:insert, sql, opts)
162
175
  end
163
-
176
+
177
+ # @!visibility private
164
178
  def freeze
165
179
  @conversion_procs.freeze
166
180
  super
@@ -181,13 +195,13 @@ module Sequel
181
195
  end
182
196
 
183
197
  private
184
-
198
+
185
199
  def adapter_initialize
186
200
  @conversion_procs = SQLITE_TYPES.dup
187
201
  @conversion_procs['datetime'] = @conversion_procs['timestamp'] = method(:to_application_timestamp)
188
202
  set_integer_booleans
189
203
  end
190
-
204
+
191
205
  # Yield an available connection. Rescue any Extralite::Error and turn
192
206
  # them into DatabaseErrors.
193
207
  def _execute(type, sql, opts, &block)
@@ -212,7 +226,7 @@ module Sequel
212
226
  raise_error(e)
213
227
  end
214
228
  end
215
-
229
+
216
230
  # The SQLite adapter does not need the pool to convert exceptions.
217
231
  # Also, force the max connections to 1 if a memory database is being
218
232
  # used, as otherwise each connection gets a separate database.
@@ -223,7 +237,7 @@ module Sequel
223
237
  o[:max_connections] = 1 if @opts[:database] == ':memory:' || blank_object?(@opts[:database])
224
238
  o
225
239
  end
226
-
240
+
227
241
  def prepared_statement_argument(arg)
228
242
  case arg
229
243
  when Date, DateTime, Time
@@ -267,9 +281,9 @@ module Sequel
267
281
  log_sql << ")"
268
282
  end
269
283
  if block
270
- log_connection_yield(log_sql, conn, args){cps.execute(ps_args, &block)}
284
+ log_connection_yield(log_sql, conn, args){cps.query(ps_args, &block)}
271
285
  else
272
- log_connection_yield(log_sql, conn, args){cps.execute!(ps_args){|r|}}
286
+ log_connection_yield(log_sql, conn, args){cps.query(ps_args){|r|}}
273
287
  case type
274
288
  when :insert
275
289
  conn.last_insert_rowid
@@ -278,7 +292,7 @@ module Sequel
278
292
  end
279
293
  end
280
294
  end
281
-
295
+
282
296
  # # SQLite3 raises ArgumentError in addition to SQLite3::Exception in
283
297
  # # some cases, such as operations on a closed database.
284
298
  def database_error_classes
@@ -297,15 +311,17 @@ module Sequel
297
311
  end
298
312
  end
299
313
  end
300
-
314
+
315
+ # Dataset adapter for Sequel
301
316
  class Dataset < Sequel::Dataset
302
317
  include ::Sequel::SQLite::DatasetMethods
303
318
 
319
+ # @!visibility private
304
320
  module ArgumentMapper
305
321
  include Sequel::Dataset::ArgumentMapper
306
-
322
+
307
323
  protected
308
-
324
+
309
325
  # Return a hash with the same values as the given hash,
310
326
  # but with the keys converted to strings.
311
327
  def map_to_prepared_args(hash)
@@ -313,19 +329,22 @@ module Sequel
313
329
  hash.each{|k,v| args[k.to_s.gsub('.', '__')] = v}
314
330
  args
315
331
  end
316
-
332
+
317
333
  private
318
-
334
+
319
335
  # SQLite uses a : before the name of the argument for named
320
336
  # arguments.
321
337
  def prepared_arg(k)
322
338
  LiteralString.new("#{prepared_arg_placeholder}#{k.to_s.gsub('.', '__')}")
323
339
  end
324
340
  end
325
-
341
+
342
+ # @!visibility private
326
343
  BindArgumentMethods = prepared_statements_module(:bind, ArgumentMapper)
344
+ # @!visibility private
327
345
  PreparedStatementMethods = prepared_statements_module(:prepare, BindArgumentMethods)
328
346
 
347
+ # @!visibility private
329
348
  def fetch_rows(sql, &block)
330
349
  execute(sql, &block)
331
350
  # execute(sql) do |result|
@@ -350,9 +369,9 @@ module Sequel
350
369
  # end
351
370
  # end
352
371
  end
353
-
372
+
354
373
  private
355
-
374
+
356
375
  # The base type name for a given type, without any parenthetical part.
357
376
  def base_type_name(t)
358
377
  (t =~ /^(.*?)\(/ ? $1 : t).downcase if t
data/test/test_sequel.rb CHANGED
@@ -4,21 +4,43 @@ require_relative 'helper'
4
4
  require 'sequel'
5
5
 
6
6
  class SequelExtraliteTest < MiniTest::Test
7
- def test_sequel
8
- db = Sequel.connect('extralite::memory:')
9
- db.create_table :items do
7
+ def setup
8
+ @db = Sequel.connect('extralite::memory:')
9
+ @db.create_table :items do
10
10
  primary_key :id
11
11
  String :name, unique: true, null: false
12
12
  Float :price, null: false
13
13
  end
14
14
 
15
- items = db[:items]
16
-
15
+ items = @db[:items]
17
16
  items.insert(name: 'abc', price: 123)
18
17
  items.insert(name: 'def', price: 456)
19
18
  items.insert(name: 'ghi', price: 789)
19
+ end
20
+
21
+ def teardown
22
+ @db.disconnect
23
+ end
24
+
25
+ def test_sequel
26
+ items = @db[:items]
20
27
 
21
28
  assert_equal 3, items.count
22
29
  assert_equal (123+456+789) / 3, items.avg(:price)
23
30
  end
31
+
32
+ def test_prepared_statement
33
+ items = @db[:items]
34
+ prepared_query = items.where(name: :$name).prepare(:select, :select_by_name)
35
+ prepared_insert = items.prepare(:insert, :insert_with_name_and_price, name: :$name, price: :$price)
36
+
37
+ assert_equal prepared_query.call(name: 'def'), [{ id: 2, name: 'def', price: 456 }]
38
+ assert_equal @db.call(:select_by_name, name: 'def'), [{ id: 2, name: 'def', price: 456 }]
39
+
40
+ id = prepared_insert.call(name: 'jkl', price: 444)
41
+ assert_equal items[id: id], { id: id, name: 'jkl', price: 444 }
42
+
43
+ id = @db.call(:insert_with_name_and_price, name: 'mno', price: 555)
44
+ assert_equal items[id: id], { id: id, name: 'mno', price: 555 }
45
+ end
24
46
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: extralite
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.25'
4
+ version: '1.27'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-10 00:00:00.000000000 Z
11
+ date: 2023-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -91,6 +91,7 @@ files:
91
91
  - ".github/FUNDING.yml"
92
92
  - ".github/workflows/test.yml"
93
93
  - ".gitignore"
94
+ - ".yardopts"
94
95
  - CHANGELOG.md
95
96
  - Gemfile
96
97
  - Gemfile.lock