sequel 5.54.0 → 5.55.0

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: 3baaadc192f621e371699d654e998661db242d11385b328e5298ebfa7ce97d53
4
- data.tar.gz: b6595670122d1ec5bbaccabef8d3af58a08f4d6edb6ffa782e34a1152d971143
3
+ metadata.gz: dfed01eed8d575d13963be4568c8935f82c47a59b2be32d382439d50153f032d
4
+ data.tar.gz: 9ac182c00cdc1f54c26626005f990c5e0a05eebaae3b3c5b88bac0fcd770cd8e
5
5
  SHA512:
6
- metadata.gz: ebf7ff5a43c42d769a1f35e7c90f32c24e7776cde36c17c1800a4603b8173066bb90864b0644dfb6402221e1ed37ea36a9b026e6ab07e3086ed208eb6fb58d67
7
- data.tar.gz: 82b525b77248038a08e2b247ae8de8028a1d4f67f332b267bd81f9d4087ebd900fcb58b1a7b9b82b20e3b93a00dd3a665d03dbe583ba94866c43663993c7436b
6
+ metadata.gz: c9aceee8528a749c541f74eeb07610b520e4342ac8d11abda3222fd0d760e2ff2a16e1b08b7931f5d24cb0ae9fced020ef695798ffac6c4b4af15508e8927468
7
+ data.tar.gz: 19e40f6386373bdbba07b5a65faf5ffc99a5693e81b0eaeaf1abffc9b07cc29c2688ea658629f633eb36a3427f74857cab28216d18cfb208cca97a75ea10788e
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
1
+ === 5.55.0 (2022-04-01)
2
+
3
+ * Support :setup_regexp_function Database option in the sqlite adapter to allow the use of regexps when querying (jeremyevans)
4
+
5
+ * Add auto_restrict_eager_graph plugin for automatically disallow eager_graph with associations needing but lacking graph options (jeremyevans)
6
+
7
+ * Fix placeholder literalizer optimization for dataset aggregate methods on a model dataset (belousovAV) (#1847, #1848)
8
+
1
9
  === 5.54.0 (2022-03-01)
2
10
 
3
11
  * Add enum plugin for treating columns as enums in a model (jeremyevans) (#1839)
@@ -383,6 +383,9 @@ The following additional options are supported:
383
383
 
384
384
  :readonly :: open database in read-only mode
385
385
  :timeout :: the busy timeout to use in milliseconds (default: 5000).
386
+ :setup_regexp_function :: Whether to setup a REGEXP function in the underlying SQLite3::Database object. Doing so
387
+ allows you to use regexp support in dataset expressions. Note that this creates a new
388
+ Regexp object per call to the function, so it is not an efficient implementation.
386
389
 
387
390
  Note that SQLite memory databases are restricted to a single connection by
388
391
  default. This is because SQLite does not allow multiple connections to
data/doc/querying.rdoc CHANGED
@@ -357,7 +357,9 @@ For ranges, Sequel uses a pair of inequality statements:
357
357
  # SELECT * FROM artists WHERE ((id >= 1) AND (id < 5))
358
358
 
359
359
  Finally, for regexps, Sequel uses an SQL regular expression. Note that this
360
- is probably only supported on PostgreSQL and MySQL.
360
+ is only supported by default on PostgreSQL and MySQL. It can also be supported
361
+ on SQLite when using the sqlite adapter with the :setup_regexp_function
362
+ Database option.
361
363
 
362
364
  Artist.where(name: /JM$/)
363
365
  # SELECT * FROM artists WHERE (name ~ 'JM$')
@@ -0,0 +1,21 @@
1
+ = New Features
2
+
3
+ * An auto_restrict_eager_graph plugin has been added for automatically
4
+ disallowing the use of eager_graph with associations using blocks but
5
+ lacking graph_* options. This can prevent potentionally invalid usage,
6
+ as the restrictions added by the block are not used by eager_graph.
7
+
8
+ * The sqlite adapter now supports the :setup_regexp_function
9
+ Database option. This option will define a REGEXP function in the
10
+ database that will allow regexp support in queries, such as:
11
+
12
+ DB[:table].where(column: /(some|pattern)/)
13
+
14
+ Note that this creates a Ruby Regexp object per column value tested,
15
+ so it isn't the most optimal approach.
16
+
17
+ = Other Improvements
18
+
19
+ * Calling dataset aggregate methods such as #max on a model dataset now
20
+ works correctly. Previously, it could fail if called enough times to
21
+ optimize using a placeholder literalizer.
data/doc/sql.rdoc CHANGED
@@ -528,7 +528,7 @@ Inverting the LIKE operator works like other inversions:
528
528
 
529
529
  ~Sequel.like(:name, 'A%') # ("name" NOT LIKE 'A%' ESCAPE '\')
530
530
 
531
- Sequel also supports SQL regular expressions on MySQL and PostgreSQL. You can use these by passing a Ruby regular expression to +like+ or +ilike+, or by making the regular expression a hash value:
531
+ Sequel also supports SQL regular expressions on MySQL and PostgreSQL (and SQLite when using the sqlite adapter with the :setup_regexp_function Database option). You can use these by passing a Ruby regular expression to +like+ or +ilike+, or by making the regular expression a hash value:
532
532
 
533
533
  Sequel.like(:name, /^A/) # ("name" ~ '^A')
534
534
  ~Sequel.ilike(:name, /^A/) # ("name" !~* '^A')
@@ -98,6 +98,11 @@ module Sequel
98
98
  # The conversion procs to use for this database
99
99
  attr_reader :conversion_procs
100
100
 
101
+ def initialize(opts = OPTS)
102
+ super
103
+ @allow_regexp = typecast_value_boolean(opts[:setup_regexp_function])
104
+ end
105
+
101
106
  # Connect to the database. Since SQLite is a file based database,
102
107
  # available options are limited:
103
108
  #
@@ -119,6 +124,12 @@ module Sequel
119
124
  end
120
125
 
121
126
  connection_pragmas.each{|s| log_connection_yield(s, db){db.execute_batch(s)}}
127
+
128
+ if typecast_value_boolean(opts[:setup_regexp_function])
129
+ db.create_function("regexp", 2) do |func, regexp_str, string|
130
+ func.result = Regexp.new(regexp_str).match(string) ? 1 : 0
131
+ end
132
+ end
122
133
 
123
134
  class << db
124
135
  attr_reader :prepared_statements
@@ -128,6 +139,12 @@ module Sequel
128
139
  db
129
140
  end
130
141
 
142
+ # Whether this Database instance is setup to allow regexp matching.
143
+ # True if the :setup_regexp_function option was passed when creating the Database.
144
+ def allow_regexp?
145
+ @allow_regexp
146
+ end
147
+
131
148
  # Disconnect given connections from the database.
132
149
  def disconnect_connection(c)
133
150
  c.prepared_statements.each_value{|v| v.first.close}
@@ -321,6 +338,28 @@ module Sequel
321
338
  BindArgumentMethods = prepared_statements_module(:bind, ArgumentMapper)
322
339
  PreparedStatementMethods = prepared_statements_module(:prepare, BindArgumentMethods)
323
340
 
341
+ # Support regexp functions if using :setup_regexp_function Database option.
342
+ def complex_expression_sql_append(sql, op, args)
343
+ case op
344
+ when :~, :'!~', :'~*', :'!~*'
345
+ return super unless supports_regexp?
346
+
347
+ case_insensitive = [:'~*', :'!~*'].include?(op)
348
+ sql << 'NOT ' if [:'!~', :'!~*'].include?(op)
349
+ sql << '('
350
+ sql << 'LOWER(' if case_insensitive
351
+ literal_append(sql, args[0])
352
+ sql << ')' if case_insensitive
353
+ sql << ' REGEXP '
354
+ sql << 'LOWER(' if case_insensitive
355
+ literal_append(sql, args[1])
356
+ sql << ')' if case_insensitive
357
+ sql << ')'
358
+ else
359
+ super
360
+ end
361
+ end
362
+
324
363
  def fetch_rows(sql)
325
364
  execute(sql) do |result|
326
365
  cps = db.conversion_procs
@@ -344,6 +383,11 @@ module Sequel
344
383
  end
345
384
  end
346
385
  end
386
+
387
+ # Support regexp if using :setup_regexp_function Database option.
388
+ def supports_regexp?
389
+ db.allow_regexp?
390
+ end
347
391
 
348
392
  private
349
393
 
@@ -894,9 +894,10 @@ module Sequel
894
894
  # Clone of this dataset usable in aggregate operations. Does
895
895
  # a from_self if dataset contains any parameters that would
896
896
  # affect normal aggregation, or just removes an existing
897
- # order if not.
897
+ # order if not. Also removes the row_proc, which isn't needed
898
+ # for aggregate calculations.
898
899
  def aggregate_dataset
899
- options_overlap(COUNT_FROM_SELF_OPTS) ? from_self : unordered
900
+ (options_overlap(COUNT_FROM_SELF_OPTS) ? from_self : unordered).naked
900
901
  end
901
902
 
902
903
  # Append aliasing expression to SQL string.
@@ -0,0 +1,62 @@
1
+ # frozen-string-literal: true
2
+
3
+ module Sequel
4
+ module Plugins
5
+ # The auto_restrict_eager_graph plugin will automatically disallow the use
6
+ # of eager_graph for associations that have associated blocks but no :graph_*
7
+ # association options. The reason for this is the block will have an effect
8
+ # during regular and eager loading, but not loading via eager_graph, and it
9
+ # is likely that whatever the block is doing should have an equivalent done
10
+ # when eager_graphing. Most likely, not including a :graph_* option was either
11
+ # an oversight (and one should be added), or use with eager_graph was never
12
+ # intended (and usage should be forbidden). Disallowing eager_graph in this
13
+ # case prevents likely unexpected behavior during eager_graph.
14
+ #
15
+ # As an example of this, consider the following code:
16
+ #
17
+ # Album.one_to_many :popular_tracks, class: :Track do |ds|
18
+ # ds = ds.where(popular: true)
19
+ # end
20
+ #
21
+ # Album.eager(:popular_tracks).all
22
+ # # SELECT * FROM albums
23
+ # # SELECT * FROM tracks WHERE ((popular IS TRUE) AND (album_id IN (...)))
24
+ #
25
+ # # Notice that no condition for tracks.popular is added.
26
+ # Album.eager_graph(:popular_tracks).all
27
+ # # SELECT ... FROM albums LEFT JOIN tracks ON (tracks.album_id = albums.id)
28
+ #
29
+ # With the auto_restrict_eager_graph plugin, the eager_graph call above will
30
+ # raise an error, alerting you to the fact that you either should not be
31
+ # using eager_graph with the association, or that you should be adding an
32
+ # appropriate :graph_* option, such as:
33
+ #
34
+ # Album.one_to_many :popular_tracks, class: :Track, graph_conditions: {popular: true} do |ds|
35
+ # ds = ds.where(popular: true)
36
+ # end
37
+ #
38
+ # Usage:
39
+ #
40
+ # # Automatically restrict eager_graph for associations if appropriate for all
41
+ # # model subclasses (called before loading subclasses)
42
+ # Sequel::Model.plugin :auto_restrict_eager_graph
43
+ #
44
+ # # Automatically restrict eager_graph for associations in Album class
45
+ # Album.plugin :auto_restrict_eager_graph
46
+ module AutoRestrictEagerGraph
47
+ module ClassMethods
48
+ # When defining an association, if a block is given for the association, but
49
+ # a :graph_* option is not used, disallow the use of eager_graph.
50
+ def associate(type, name, opts = OPTS, &block)
51
+ opts = super
52
+
53
+ if opts[:block] && !opts.has_key?(:allow_eager_graph) && !opts[:orig_opts].any?{|k,| /\Agraph_/ =~ k}
54
+ opts[:allow_eager_graph] = false
55
+ end
56
+
57
+ opts
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -6,7 +6,7 @@ module Sequel
6
6
 
7
7
  # The minor version of Sequel. Bumped for every non-patch level
8
8
  # release, generally around once a month.
9
- MINOR = 54
9
+ MINOR = 55
10
10
 
11
11
  # The tiny version of Sequel. Usually 0, only bumped for bugfix
12
12
  # releases that fix regressions from previous versions.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.54.0
4
+ version: 5.55.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-01 00:00:00.000000000 Z
11
+ date: 2022-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -199,6 +199,7 @@ extra_rdoc_files:
199
199
  - doc/release_notes/5.52.0.txt
200
200
  - doc/release_notes/5.53.0.txt
201
201
  - doc/release_notes/5.54.0.txt
202
+ - doc/release_notes/5.55.0.txt
202
203
  - doc/release_notes/5.6.0.txt
203
204
  - doc/release_notes/5.7.0.txt
204
205
  - doc/release_notes/5.8.0.txt
@@ -281,6 +282,7 @@ files:
281
282
  - doc/release_notes/5.52.0.txt
282
283
  - doc/release_notes/5.53.0.txt
283
284
  - doc/release_notes/5.54.0.txt
285
+ - doc/release_notes/5.55.0.txt
284
286
  - doc/release_notes/5.6.0.txt
285
287
  - doc/release_notes/5.7.0.txt
286
288
  - doc/release_notes/5.8.0.txt
@@ -479,6 +481,7 @@ files:
479
481
  - lib/sequel/plugins/association_pks.rb
480
482
  - lib/sequel/plugins/association_proxies.rb
481
483
  - lib/sequel/plugins/async_thread_pool.rb
484
+ - lib/sequel/plugins/auto_restrict_eager_graph.rb
482
485
  - lib/sequel/plugins/auto_validations.rb
483
486
  - lib/sequel/plugins/auto_validations_constraint_validations_presence_message.rb
484
487
  - lib/sequel/plugins/before_after_save.rb