sequel 5.85.0 → 5.86.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: ecb752c20a2b59df814e873f04ac143aadd875b503b2400cca8929d9eabff572
4
- data.tar.gz: d528c6d03626b725f27599c8cf624311517e4f4fe67c12139a2e815278fbb707
3
+ metadata.gz: 2945ab081dad1d3dc6d910e2902247b18750215023e0cfbb5b8f8159811b0d25
4
+ data.tar.gz: 6b2933b4ac2023a71526a76f40b949e873460e2a7f8aed1524bef47b71f91e79
5
5
  SHA512:
6
- metadata.gz: 4fcb91f8acb96a4a57152c9a0f41e78af1b42d6c393f8c90b2099e00d632676096c8ac27b0e31699fd31be0e22912b55e4372353fef93e967e548741dbc6406e
7
- data.tar.gz: e2545b4dcca9ca1a13f47cbfdf2f38802d2564f7f0766d526e5041b93a94142560517f5d3ef5c9a5d2692e67a482c8044b4812c064fd35c2edf0c19a3df6b25c
6
+ metadata.gz: 988bfe69b6b4953a7792431e3dd26bcb7ad13f01b8b1dc822fd9d79917608cc2f60bdb7e9a75cfa975bcd297ada83f00a2d80343424f9e4096c029437a9250ad
7
+ data.tar.gz: 51c2591400946af23395f0a3f49dfc87d4ce6f536e9cbc045ae7c86915007938c72b90f899dd347d749918218b86edc8dbaa63e8f9430d7075872a431d91b777
@@ -1,6 +1,6 @@
1
1
  # frozen-string-literal: true
2
2
 
3
- Sequel::JDBC.load_driver('com.ibm.db2.jcc.DB2Driver')
3
+ Sequel::JDBC.load_driver('Java::ComIbmDb2Jcc::DB2Driver')
4
4
  require_relative '../shared/db2'
5
5
  require_relative 'transactions'
6
6
 
@@ -25,7 +25,7 @@ module Sequel
25
25
  end
26
26
  end
27
27
  db.extend_datasets Sequel::DB2::DatasetMethods
28
- com.ibm.db2.jcc.DB2Driver
28
+ Java::ComIbmDb2Jcc::DB2Driver
29
29
  end
30
30
  end
31
31
 
@@ -1,6 +1,6 @@
1
1
  # frozen-string-literal: true
2
2
 
3
- Sequel::JDBC.load_driver('org.apache.derby.jdbc.EmbeddedDriver', :Derby)
3
+ Sequel::JDBC.load_driver('Java::OrgApacheDerbyJdbc::EmbeddedDriver', :Derby)
4
4
  require_relative 'transactions'
5
5
  require_relative '../utils/columns_limit_1'
6
6
 
@@ -10,7 +10,7 @@ module Sequel
10
10
  DATABASE_SETUP[:derby] = proc do |db|
11
11
  db.extend(Sequel::JDBC::Derby::DatabaseMethods)
12
12
  db.dataset_class = Sequel::JDBC::Derby::Dataset
13
- org.apache.derby.jdbc.EmbeddedDriver
13
+ Java::OrgApacheDerbyJdbc::EmbeddedDriver
14
14
  end
15
15
  end
16
16
 
@@ -1,6 +1,6 @@
1
1
  # frozen-string-literal: true
2
2
 
3
- Sequel::JDBC.load_driver('org.h2.Driver', :H2)
3
+ Sequel::JDBC.load_driver('Java::OrgH2::Driver', :H2)
4
4
  require_relative '../../extensions/auto_cast_date_and_time'
5
5
 
6
6
  module Sequel
@@ -9,7 +9,7 @@ module Sequel
9
9
  DATABASE_SETUP[:h2] = proc do |db|
10
10
  db.extend(Sequel::JDBC::H2::DatabaseMethods)
11
11
  db.dataset_class = Sequel::JDBC::H2::Dataset
12
- org.h2.Driver
12
+ Java::OrgH2::Driver
13
13
  end
14
14
  end
15
15
 
@@ -1,6 +1,6 @@
1
1
  # frozen-string-literal: true
2
2
 
3
- Sequel::JDBC.load_driver('org.hsqldb.jdbcDriver', :HSQLDB)
3
+ Sequel::JDBC.load_driver('Java::OrgHsqldb::jdbcDriver', :HSQLDB)
4
4
  require_relative 'transactions'
5
5
  require_relative '../../extensions/auto_cast_date_and_time'
6
6
 
@@ -10,7 +10,7 @@ module Sequel
10
10
  DATABASE_SETUP[:hsqldb] = proc do |db|
11
11
  db.extend(Sequel::JDBC::HSQLDB::DatabaseMethods)
12
12
  db.dataset_class = Sequel::JDBC::HSQLDB::Dataset
13
- org.hsqldb.jdbcDriver
13
+ Java::OrgHsqldb::jdbcDriver
14
14
  end
15
15
  end
16
16
 
@@ -1,6 +1,6 @@
1
1
  # frozen-string-literal: true
2
2
 
3
- Sequel::JDBC.load_driver('Java::net.sourceforge.jtds.jdbc.Driver', :JTDS)
3
+ Sequel::JDBC.load_driver('Java::NetSourceforgeJtdsJdbc::Driver', :JTDS)
4
4
  require_relative 'mssql'
5
5
 
6
6
  module Sequel
@@ -10,7 +10,7 @@ module Sequel
10
10
  db.extend(Sequel::JDBC::JTDS::DatabaseMethods)
11
11
  db.extend_datasets Sequel::MSSQL::DatasetMethods
12
12
  db.send(:set_mssql_unicode_strings)
13
- Java::net.sourceforge.jtds.jdbc.Driver
13
+ Java::NetSourceforgeJtdsJdbc::Driver
14
14
  end
15
15
  end
16
16
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Sequel
4
4
  module JDBC
5
- driver = Sequel::JDBC.load_driver(%w'com.mysql.cj.jdbc.Driver com.mysql.jdbc.Driver', :MySQL)
5
+ driver = Sequel::JDBC.load_driver(%w'Java::ComMysqlCjJdbc::Driver Java::ComMysqlJdbc::Driver', :MySQL)
6
6
  require_relative '../shared/mysql'
7
7
 
8
8
  Sequel.synchronize do
@@ -1,6 +1,6 @@
1
1
  # frozen-string-literal: true
2
2
 
3
- Sequel::JDBC.load_driver('Java::oracle.jdbc.driver.OracleDriver')
3
+ Sequel::JDBC.load_driver('Java::OracleJdbcDriver::OracleDriver')
4
4
  require_relative '../shared/oracle'
5
5
  require_relative 'transactions'
6
6
 
@@ -10,12 +10,12 @@ module Sequel
10
10
  DATABASE_SETUP[:oracle] = proc do |db|
11
11
  db.extend(Sequel::JDBC::Oracle::DatabaseMethods)
12
12
  db.dataset_class = Sequel::JDBC::Oracle::Dataset
13
- Java::oracle.jdbc.driver.OracleDriver
13
+ Java::OracleJdbcDriver::OracleDriver
14
14
  end
15
15
  end
16
16
 
17
17
  module Oracle
18
- JAVA_BIG_DECIMAL_CONSTRUCTOR = java.math.BigDecimal.java_class.constructor(Java::long).method(:new_instance)
18
+ JAVA_BIG_DECIMAL_CONSTRUCTOR = Java::JavaMath::BigDecimal.java_class.constructor(Java::long).method(:new_instance)
19
19
  ORACLE_DECIMAL = Object.new
20
20
  def ORACLE_DECIMAL.call(r, i)
21
21
  if v = r.getBigDecimal(i)
@@ -76,7 +76,7 @@ module Sequel
76
76
  rs = log_connection_yield(sql, conn){stmt.executeQuery(sql)}
77
77
  rs.next
78
78
  rs.getLong(1)
79
- rescue java.sql.SQLException
79
+ rescue Java::JavaSql::SQLException
80
80
  nil
81
81
  end
82
82
  end
@@ -122,7 +122,7 @@ module Sequel
122
122
  NUMERIC_TYPE = Java::JavaSQL::Types::NUMERIC
123
123
  TIMESTAMP_TYPE = Java::JavaSQL::Types::TIMESTAMP
124
124
  CLOB_TYPE = Java::JavaSQL::Types::CLOB
125
- TIMESTAMPTZ_TYPES = [Java::oracle.jdbc.OracleTypes::TIMESTAMPTZ, Java::oracle.jdbc.OracleTypes::TIMESTAMPLTZ].freeze
125
+ TIMESTAMPTZ_TYPES = [Java::OracleJdbc::OracleTypes::TIMESTAMPTZ, Java::OracleJdbc::OracleTypes::TIMESTAMPLTZ].freeze
126
126
 
127
127
  def type_convertor(map, meta, type, i)
128
128
  case type
@@ -1,6 +1,6 @@
1
1
  # frozen-string-literal: true
2
2
 
3
- Sequel::JDBC.load_driver('org.postgresql.Driver', :Postgres)
3
+ Sequel::JDBC.load_driver('Java::OrgPostgresql::Driver', :Postgres)
4
4
  require_relative '../shared/postgres'
5
5
 
6
6
  module Sequel
@@ -9,7 +9,7 @@ module Sequel
9
9
  DATABASE_SETUP[:postgresql] = proc do |db|
10
10
  db.dataset_class = Sequel::JDBC::Postgres::Dataset
11
11
  db.extend(Sequel::JDBC::Postgres::DatabaseMethods)
12
- org.postgresql.Driver
12
+ Java::OrgPostgresql::Driver
13
13
  end
14
14
  end
15
15
 
@@ -43,7 +43,7 @@ module Sequel
43
43
 
44
44
  synchronize(opts[:server]) do |conn|
45
45
  begin
46
- copy_manager = org.postgresql.copy.CopyManager.new(conn)
46
+ copy_manager = Java::OrgPostgresqlCopy::CopyManager.new(conn)
47
47
  copier = copy_manager.copy_in(copy_into_sql(table, opts))
48
48
  if defined?(yield)
49
49
  while buf = yield
@@ -74,7 +74,7 @@ module Sequel
74
74
  # See Sequel::Postgres::Adapter#copy_table
75
75
  def copy_table(table, opts=OPTS)
76
76
  synchronize(opts[:server]) do |conn|
77
- copy_manager = org.postgresql.copy.CopyManager.new(conn)
77
+ copy_manager = Java::OrgPostgresqlCopy::CopyManager.new(conn)
78
78
  copier = copy_manager.copy_out(copy_table_sql(table, opts))
79
79
  begin
80
80
  if defined?(yield)
@@ -148,7 +148,7 @@ module Sequel
148
148
  # and set that as the prepared statement argument.
149
149
  def set_ps_arg(cps, arg, i)
150
150
  if v = bound_variable_arg(arg, nil)
151
- obj = org.postgresql.util.PGobject.new
151
+ obj = Java::OrgPostgresqlUtil::PGobject.new
152
152
  obj.setType("unknown")
153
153
  obj.setValue(v)
154
154
  cps.setObject(i, obj)
@@ -6,12 +6,12 @@ require_relative 'transactions'
6
6
  module Sequel
7
7
  module JDBC
8
8
  drv = [
9
- lambda{Java::sybase.jdbc4.sqlanywhere.IDriver},
10
- lambda{Java::ianywhere.ml.jdbcodbc.jdbc4.IDriver},
11
- lambda{Java::sybase.jdbc.sqlanywhere.IDriver},
12
- lambda{Java::ianywhere.ml.jdbcodbc.jdbc.IDriver},
13
- lambda{Java::com.sybase.jdbc4.jdbc.Sybdriver},
14
- lambda{Java::com.sybase.jdbc3.jdbc.Sybdriver}
9
+ lambda{Java::SybaseJdbc4Sqlanywhere::IDriver},
10
+ lambda{Java::IanywhereMlJdbcodbcJdbc4::IDriver},
11
+ lambda{Java::SybaseJdbcSqlanywhere::IDriver},
12
+ lambda{Java::IanywhereMlJdbcodbcJdbc::IDriver},
13
+ lambda{Java::ComSybaseJdbc4Jdbc::Sybdriver},
14
+ lambda{Java::ComSybaseJdbc3Jdbc::Sybdriver}
15
15
  ].each do |class_proc|
16
16
  begin
17
17
  break class_proc.call
@@ -1,6 +1,6 @@
1
1
  # frozen-string-literal: true
2
2
 
3
- Sequel::JDBC.load_driver('org.sqlite.JDBC', :SQLite3)
3
+ Sequel::JDBC.load_driver('Java::OrgSqlite::JDBC', :SQLite3)
4
4
  require_relative '../shared/sqlite'
5
5
 
6
6
  module Sequel
@@ -10,7 +10,7 @@ module Sequel
10
10
  db.extend(Sequel::JDBC::SQLite::DatabaseMethods)
11
11
  db.extend_datasets Sequel::SQLite::DatasetMethods
12
12
  db.set_integer_booleans
13
- org.sqlite.JDBC
13
+ Java::OrgSqlite::JDBC
14
14
  end
15
15
  end
16
16
 
@@ -1,6 +1,6 @@
1
1
  # frozen-string-literal: true
2
2
 
3
- Sequel::JDBC.load_driver('com.microsoft.sqlserver.jdbc.SQLServerDriver')
3
+ Sequel::JDBC.load_driver('Java::ComMicrosoftSqlserverJdbc::SQLServerDriver')
4
4
  require_relative 'mssql'
5
5
 
6
6
  module Sequel
@@ -10,7 +10,7 @@ module Sequel
10
10
  db.extend(Sequel::JDBC::SQLServer::DatabaseMethods)
11
11
  db.extend_datasets Sequel::MSSQL::DatasetMethods
12
12
  db.send(:set_mssql_unicode_strings)
13
- com.microsoft.sqlserver.jdbc.SQLServerDriver
13
+ Java::ComMicrosoftSqlserverJdbc::SQLServerDriver
14
14
  end
15
15
  end
16
16
 
@@ -20,7 +20,7 @@ module Sequel
20
20
 
21
21
  # Create custom NativeException alias for nicer access, and also so that
22
22
  # JRuby 9.2+ so it doesn't use the deprecated ::NativeException
23
- NativeException = java.lang.Exception
23
+ NativeException = Java::JavaLang::Exception
24
24
 
25
25
  # Default database error classes
26
26
  DATABASE_ERROR_CLASSES = [NativeException]
@@ -227,7 +227,7 @@ module Sequel
227
227
  raise e unless driver
228
228
  # If the DriverManager can't get the connection - use the connect
229
229
  # method of the driver. (This happens under Tomcat for instance)
230
- props = java.util.Properties.new
230
+ props = Java::JavaUtil::Properties.new
231
231
  if opts && opts[:user] && opts[:password]
232
232
  props.setProperty("user", opts[:user])
233
233
  props.setProperty("password", opts[:password])
@@ -506,7 +506,7 @@ module Sequel
506
506
  # Gets the connection from JNDI.
507
507
  def get_connection_from_jndi
508
508
  jndi_name = JNDI_URI_REGEXP.match(uri)[1]
509
- javax.naming.InitialContext.new.lookup(jndi_name).connection
509
+ Java::JavaxNaming::InitialContext.new.lookup(jndi_name).connection
510
510
  end
511
511
 
512
512
  # Gets the JDBC connection uri from the JNDI resource.
@@ -530,19 +530,19 @@ module Sequel
530
530
 
531
531
  # Support Date objects used in bound variables
532
532
  def java_sql_date(date)
533
- java.sql.Date.new(Time.local(date.year, date.month, date.day).to_i * 1000)
533
+ Java::JavaSql::Date.new(Time.local(date.year, date.month, date.day).to_i * 1000)
534
534
  end
535
535
 
536
536
  # Support DateTime objects used in bound variables
537
537
  def java_sql_datetime(datetime)
538
- ts = java.sql.Timestamp.new(Time.local(datetime.year, datetime.month, datetime.day, datetime.hour, datetime.min, datetime.sec).to_i * 1000)
538
+ ts = Java::JavaSql::Timestamp.new(Time.local(datetime.year, datetime.month, datetime.day, datetime.hour, datetime.min, datetime.sec).to_i * 1000)
539
539
  ts.setNanos((datetime.sec_fraction * 1000000000).to_i)
540
540
  ts
541
541
  end
542
542
 
543
543
  # Support fractional seconds for Time objects used in bound variables
544
544
  def java_sql_timestamp(time)
545
- ts = java.sql.Timestamp.new(time.to_i * 1000)
545
+ ts = Java::JavaSql::Timestamp.new(time.to_i * 1000)
546
546
  ts.setNanos(time.nsec)
547
547
  ts
548
548
  end
@@ -2430,6 +2430,9 @@ module Sequel
2430
2430
  # Return the primary key to use for RETURNING in an INSERT statement
2431
2431
  def insert_pk
2432
2432
  (f = opts[:from]) && !f.empty? && (t = f.first)
2433
+
2434
+ t = t.call(self) if t.is_a? Sequel::SQL::DelayedEvaluation
2435
+
2433
2436
  case t
2434
2437
  when Symbol, String, SQL::Identifier, SQL::QualifiedIdentifier
2435
2438
  if pk = db.primary_key(t)
@@ -109,6 +109,8 @@ module Sequel
109
109
  # :database :: database name (filename or ':memory:' or file: URI)
110
110
  # :readonly :: open database in read-only mode; useful for reading
111
111
  # static data that you do not want to modify
112
+ # :disable_dqs :: disable double quoted strings in DDL and DML statements
113
+ # (requires SQLite 3.29.0+ and sqlite3 gem version 1.4.3+).
112
114
  # :timeout :: how long to wait for the database to be available if it
113
115
  # is locked, given in milliseconds (default is 5000)
114
116
  # :setup_regexp_function :: enable use of Regexp objects with SQL
@@ -128,6 +130,8 @@ module Sequel
128
130
  opts[:database] = ':memory:' if blank_object?(opts[:database])
129
131
  sqlite3_opts = {}
130
132
  sqlite3_opts[:readonly] = typecast_value_boolean(opts[:readonly]) if opts.has_key?(:readonly)
133
+ # SEQUEL6: Make strict: true the default behavior
134
+ sqlite3_opts[:strict] = typecast_value_boolean(opts[:disable_dqs]) if opts.has_key?(:disable_dqs)
131
135
  db = ::SQLite3::Database.new(opts[:database].to_s, sqlite3_opts)
132
136
  db.busy_timeout(typecast_value_integer(opts.fetch(:timeout, 5000)))
133
137
 
@@ -26,6 +26,11 @@ module Sequel
26
26
  :time=>Sequel::SQLTime, :boolean=>[TrueClass, FalseClass].freeze, :float=>Float, :decimal=>BigDecimal,
27
27
  :blob=>Sequel::SQL::Blob}.freeze
28
28
 
29
+ # :nocov:
30
+ URI_PARSER = defined?(::URI::RFC2396_PARSER) ? ::URI::RFC2396_PARSER : ::URI::DEFAULT_PARSER
31
+ # :nocov:
32
+ private_constant :URI_PARSER
33
+
29
34
  # Nested hook Proc; each new hook Proc just wraps the previous one.
30
35
  @initialize_hook = proc{|db| }
31
36
 
@@ -85,7 +90,7 @@ module Sequel
85
90
  def self.options_from_uri(uri)
86
91
  uri_options = uri_to_options(uri)
87
92
  uri.query.split('&').map{|s| s.split('=')}.each{|k,v| uri_options[k.to_sym] = v if k && !k.empty?} unless uri.query.to_s.strip.empty?
88
- uri_options.to_a.each{|k,v| uri_options[k] = URI::DEFAULT_PARSER.unescape(v) if v.is_a?(String)}
93
+ uri_options.to_a.each{|k,v| uri_options[k] = URI_PARSER.unescape(v) if v.is_a?(String)}
89
94
  uri_options
90
95
  end
91
96
  private_class_method :options_from_uri
@@ -27,6 +27,11 @@ Sequel.extension :eval_inspect
27
27
 
28
28
  module Sequel
29
29
  module SchemaDumper
30
+ # :nocov:
31
+ IGNORE_INDEX_ERRORS_KEY = RUBY_VERSION >= '3.4' ? 'ignore_index_errors: ' : ':ignore_index_errors=>'
32
+ # :nocov:
33
+ private_constant :IGNORE_INDEX_ERRORS_KEY
34
+
30
35
  # Convert the column schema information to a hash of column options, one of which must
31
36
  # be :type. The other options added should modify that type (e.g. :size). If a
32
37
  # database type is not recognized, return it as a String type.
@@ -161,7 +166,7 @@ END_MIG
161
166
  def dump_table_schema(table, options=OPTS)
162
167
  gen = dump_table_generator(table, options)
163
168
  commands = [gen.dump_columns, gen.dump_constraints, gen.dump_indexes].reject{|x| x == ''}.join("\n\n")
164
- "create_table(#{table.inspect}#{', :ignore_index_errors=>true' if !options[:same_db] && options[:indexes] != false && !gen.indexes.empty?}) do\n#{commands.gsub(/^/, ' ')}\nend"
169
+ "create_table(#{table.inspect}#{", #{IGNORE_INDEX_ERRORS_KEY}true" if !options[:same_db] && options[:indexes] != false && !gen.indexes.empty?}) do\n#{commands.gsub(/^/, ' ')}\nend"
165
170
  end
166
171
 
167
172
  private
@@ -425,6 +430,13 @@ END_MIG
425
430
 
426
431
  module Schema
427
432
  class CreateTableGenerator
433
+ # :nocov:
434
+ DEFAULT_KEY = RUBY_VERSION >= '3.4' ? 'default: ' : ':default=>'
435
+ IGNORE_ERRORS_KEY = RUBY_VERSION >= '3.4' ? 'ignore_errors: ' : ':ignore_errors=>'
436
+ # :nocov:
437
+ private_constant :DEFAULT_KEY
438
+ private_constant :IGNORE_ERRORS_KEY
439
+
428
440
  # Dump this generator's columns to a string that could be evaled inside
429
441
  # another instance to represent the same columns
430
442
  def dump_columns
@@ -508,7 +520,7 @@ END_MIG
508
520
  c = c.dup
509
521
  cols = c.delete(:columns)
510
522
  if table = options[:add_index] || options[:drop_index]
511
- "#{options[:drop_index] ? 'drop' : 'add'}_index #{table.inspect}, #{cols.inspect}#{', :ignore_errors=>true' if options[:ignore_errors]}#{opts_inspect(c)}"
523
+ "#{options[:drop_index] ? 'drop' : 'add'}_index #{table.inspect}, #{cols.inspect}#{", #{IGNORE_ERRORS_KEY}true" if options[:ignore_errors]}#{opts_inspect(c)}"
512
524
  else
513
525
  "index #{cols.inspect}#{opts_inspect(c)}"
514
526
  end
@@ -526,7 +538,7 @@ END_MIG
526
538
  if opts[:default]
527
539
  opts = opts.dup
528
540
  de = Sequel.eval_inspect(opts.delete(:default))
529
- ", :default=>#{de}#{", #{opts.inspect[1...-1]}" if opts.length > 0}"
541
+ ", #{DEFAULT_KEY}#{de}#{", #{opts.inspect[1...-1]}" if opts.length > 0}"
530
542
  else
531
543
  ", #{opts.inspect[1...-1]}" if opts.length > 0
532
544
  end
@@ -3,18 +3,31 @@
3
3
  module Sequel
4
4
  module Plugins
5
5
  # The subset_conditions plugin creates an additional *_conditions method
6
- # for every subset created, which returns the filter conditions the subset
7
- # uses. This can be useful if you want to use the conditions for a separate
8
- # filter or combine them with OR.
6
+ # for every `subset`, `where`, and `exclude` method call in a dataset_module
7
+ # block. This method returns the filter conditions, which can be useful if
8
+ # you want to use the conditions for a separate filter or combine them with OR.
9
+ # It also supports where_all and where_any dataset_module methods for
10
+ # combining multiple dataset method filters with AND or OR.
9
11
  #
10
12
  # Usage:
11
13
  #
12
14
  # # Add subset_conditions in the Album class
13
15
  # Album.plugin :subset_conditions
14
16
  #
15
- # # This will now create a published_conditions method
16
17
  # Album.dataset_module do
17
- # subset :published, published: true
18
+ # # This will now create a published_conditions method
19
+ # where :published, published: true
20
+ #
21
+ # # This will now create a not_bad_conditions method
22
+ # exclude :not_bad, :bad
23
+ #
24
+ # # This will create good_and_available and
25
+ # # good_and_available_conditions methods
26
+ # where_all :good_and_available, :published, :not_bad
27
+ #
28
+ # # This will create good_or_available and
29
+ # # good_or_available_conditions methods
30
+ # where_any :good_or_available, :published, :not_bad
18
31
  # end
19
32
  #
20
33
  # Album.where(Album.published_conditions).sql
@@ -25,6 +38,12 @@ module Sequel
25
38
  #
26
39
  # Album.where(Album.published_conditions | {ready: true}).sql
27
40
  # # SELECT * FROM albums WHERE ((published IS TRUE) OR (ready IS TRUE))
41
+ #
42
+ # Album.good_and_available.sql
43
+ # SELECT * FROM albums WHERE ((published IS TRUE) AND NOT bad)
44
+ #
45
+ # Album.good_or_available.sql
46
+ # SELECT * FROM albums WHERE ((published IS TRUE) OR NOT bad)
28
47
  module SubsetConditions
29
48
  def self.apply(model, &block)
30
49
  model.instance_exec do
@@ -42,6 +61,66 @@ module Sequel
42
61
  cond = cond.first if cond.size == 1
43
62
  define_method(:"#{name}_conditions"){filter_expr(cond, &block)}
44
63
  end
64
+
65
+ # Also create a method that returns the conditions the filter uses.
66
+ def exclude(name, *args, &block)
67
+ super
68
+ cond = args
69
+ cond = cond.first if cond.size == 1
70
+ define_method(:"#{name}_conditions"){Sequel.~(filter_expr(cond, &block))}
71
+ end
72
+
73
+ # Create a method that combines filters from already registered
74
+ # dataset methods, and filters for rows where all of the conditions
75
+ # are satisfied.
76
+ #
77
+ # Employee.dataset_module do
78
+ # where :active, active: true
79
+ # where :started, Sequel::CURRENT_DATE <= :start_date
80
+ # where_all(:active_and_started, :active, :started)
81
+ # end
82
+ #
83
+ # Employee.active_and_started.sql
84
+ # # SELECT * FROM employees WHERE ((active IS TRUE) AND (CURRENT_DATE <= start_date))
85
+ def where_all(name, *args)
86
+ _where_any_all(:&, name, args)
87
+ end
88
+
89
+ # Create a method that combines filters from already registered
90
+ # dataset methods, and filters for rows where any of the conditions
91
+ # are satisfied.
92
+ #
93
+ # Employee.dataset_module do
94
+ # where :active, active: true
95
+ # where :started, Sequel::CURRENT_DATE <= :start_date
96
+ # where_any(:active_or_started, :active, :started)
97
+ # end
98
+ #
99
+ # Employee.active_or_started.sql
100
+ # # SELECT * FROM employees WHERE ((active IS TRUE) OR (CURRENT_DATE <= start_date))
101
+ def where_any(name, *args)
102
+ _where_any_all(:|, name, args)
103
+ end
104
+
105
+ private
106
+
107
+ if RUBY_VERSION >= '2'
108
+ # Backbone of #where_any and #where_all
109
+ def _where_any_all(meth, name, args)
110
+ ds = model.dataset
111
+ # #bind used here because the dataset module may not yet be included in the model's dataset
112
+ where(name, Sequel.send(meth, *args.map{|a| self.instance_method(:"#{a}_conditions").bind(ds).call}))
113
+ end
114
+ else
115
+ # Cannot bind module method to arbitrary objects in Ruby 1.9.
116
+ # :nocov:
117
+ def _where_any_all(meth, name, args)
118
+ ds = model.dataset.clone
119
+ ds.extend(self)
120
+ where(name, Sequel.send(meth, *args.map{|a| ds.send(:"#{a}_conditions")}))
121
+ end
122
+ # :nocov:
123
+ end
45
124
  end
46
125
  end
47
126
  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 = 85
9
+ MINOR = 86
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.85.0
4
+ version: 5.86.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: 2024-10-01 00:00:00.000000000 Z
11
+ date: 2024-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bigdecimal