sequel 4.37.0 → 4.38.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +12 -0
- data/doc/core_extensions.rdoc +16 -0
- data/doc/dataset_filtering.rdoc +3 -0
- data/doc/opening_databases.rdoc +1 -0
- data/doc/release_notes/4.38.0.txt +67 -0
- data/doc/sql.rdoc +5 -7
- data/lib/sequel/adapters/jdbc/derby.rb +6 -0
- data/lib/sequel/adapters/postgres.rb +3 -2
- data/lib/sequel/adapters/shared/access.rb +6 -0
- data/lib/sequel/adapters/shared/sqlite.rb +25 -0
- data/lib/sequel/dataset/sql.rb +2 -0
- data/lib/sequel/extensions/connection_expiration.rb +5 -0
- data/lib/sequel/model.rb +1 -1
- data/lib/sequel/model/base.rb +6 -4
- data/lib/sequel/sql.rb +41 -10
- data/lib/sequel/version.rb +1 -1
- data/spec/core/expression_filters_spec.rb +38 -0
- data/spec/core_extensions_spec.rb +6 -1
- data/spec/extensions/core_refinements_spec.rb +2 -1
- data/spec/integration/dataset_test.rb +8 -0
- data/spec/model/hooks_spec.rb +40 -0
- data/spec/model/record_spec.rb +3 -2
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fbbe9aec719ae1c6ace4c686bf0e02f352b1283a
|
4
|
+
data.tar.gz: 347e71c258109c785c11b55e354fd4f616060cdc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e8ef32de9f9efb9ae6b03598ca6a2809409b51a60fe2759fcd2c1556d8376c08fe31366db86f7016ea25745b16f6323428838f6ebd72c96ef4a7036514cf8ce
|
7
|
+
data.tar.gz: 986105b21db0f6ffa3455e4cb8972a0b4af165026455d888bdec4054d3b31c71b8118e036c8f201934e99070ce11b3b88b32908a4d405225a11d97383fa0fd3b
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
=== 4.38.0 (2016-09-01)
|
2
|
+
|
3
|
+
* Support :driver_options option when using the postgres adapter with pg driver (jeremyevans)
|
4
|
+
|
5
|
+
* Don't use after commit/rollback database hooks if the model instance methods are not overridden (jeremyevans)
|
6
|
+
|
7
|
+
* Add SQL::NumericMethods#coerce, allowing code such as Sequel.expr{1 - x} (jeremyevans)
|
8
|
+
|
9
|
+
* Support ** operator for exponentiation on expressions, similar to +, -, *, and / (jeremyevans)
|
10
|
+
|
11
|
+
* Add Sequel::SQLTime.date= to set the date used for SQLTime instances (jeremyevans)
|
12
|
+
|
1
13
|
=== 4.37.0 (2016-08-01)
|
2
14
|
|
3
15
|
* Add support for regular expression matching on Oracle 10g+ using REGEXP_LIKE (johndcaldwell) (#1221)
|
data/doc/core_extensions.rdoc
CHANGED
@@ -40,6 +40,16 @@ All of Sequel's extensions to the core classes are stored in Sequel's core_exten
|
|
40
40
|
|
41
41
|
Sequel has no internal dependency on the core extensions. This includes Sequel's core, Sequel::Model, and all plugins and extensions that ship with Sequel. However, it is possible that external plugins and extensions will depend on the core extensions. Such plugins and extensions should be updated so that they no longer depend on the core extensions.
|
42
42
|
|
43
|
+
== Refinements
|
44
|
+
|
45
|
+
Most of the these extensions can be added on a per-file basis using refinements (if you are using Ruby 2.0+). To use refinements, first load them:
|
46
|
+
|
47
|
+
Sequel.extension :core_refinements
|
48
|
+
|
49
|
+
Then for each file where you want to use the refinements:
|
50
|
+
|
51
|
+
using Sequel::CoreRefinements
|
52
|
+
|
43
53
|
== Core Extension Methods
|
44
54
|
|
45
55
|
This section will briefly describe all of the methods added to the core classes, and what the alternative method is that doesn't require the core extensions.
|
@@ -130,6 +140,11 @@ The standard mathematical operators are defined on Symbol, and return a Sequel n
|
|
130
140
|
:a - :b # SQL: a - b
|
131
141
|
:a * :b # SQL: a * b
|
132
142
|
:a / :b # SQL: a / b
|
143
|
+
:a ** :b # SQL: power(a, b)
|
144
|
+
|
145
|
+
Sequel also supports ruby's coercion protocols on symbols (note that this does not work when using refinements):
|
146
|
+
|
147
|
+
1 + :b # SQL: 1 + b
|
133
148
|
|
134
149
|
Alternatives:
|
135
150
|
|
@@ -137,6 +152,7 @@ Alternatives:
|
|
137
152
|
Sequel.-(:a, :b)
|
138
153
|
Sequel.*(:a, :b)
|
139
154
|
Sequel./(:a, :b)
|
155
|
+
Sequel.**(:a, :b)
|
140
156
|
|
141
157
|
==== *
|
142
158
|
|
data/doc/dataset_filtering.rdoc
CHANGED
@@ -92,6 +92,9 @@ This works for the standard inequality and arithmetic operators:
|
|
92
92
|
items.where{price / 100 >= 200}.sql
|
93
93
|
#=> "SELECT * FROM items WHERE ((price / 100) >= 200)
|
94
94
|
|
95
|
+
items.where{price ** 2 >= 200}.sql
|
96
|
+
#=> "SELECT * FROM items WHERE (power(price, 2) >= 200)
|
97
|
+
|
95
98
|
You use the overloaded bitwise and (&) and or (|) operators to combine expressions:
|
96
99
|
|
97
100
|
items.where{(price + 100 < 200) & (price * 100 <= 200)}.sql
|
data/doc/opening_databases.rdoc
CHANGED
@@ -331,6 +331,7 @@ The following additional options are supported:
|
|
331
331
|
as a string, or :float to convert to an infinite float.
|
332
332
|
:connect_timeout :: Set the number of seconds to wait for a connection (default 20, only respected
|
333
333
|
if using the pg library).
|
334
|
+
:driver_options :: A hash of options to pass to the underlying driver (only respected if using the pg library)
|
334
335
|
:encoding :: Set the client_encoding to the given string
|
335
336
|
:notice_receiver :: A proc that be called with the PGresult objects that have notice or warning messages.
|
336
337
|
The default notice receiver just prints the messages to stderr, but this can be used
|
@@ -0,0 +1,67 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* Sequel::SQL::NumericMethods#coerce has been added, which adds
|
4
|
+
support for ruby's coercion protocol when performing numeric
|
5
|
+
operations. Previously, Sequel supported code like:
|
6
|
+
|
7
|
+
Sequel.expr{a - 1}
|
8
|
+
|
9
|
+
This is because a in this case returns a Sequel::SQL::Indentifier,
|
10
|
+
which defines #- to return a Sequel::SQL::NumericExpression. By
|
11
|
+
supporting #coerce, the following code now also works:
|
12
|
+
|
13
|
+
Sequel.expr{1 - a}
|
14
|
+
|
15
|
+
This is because Integer#- calls #coerce on the argument if it is
|
16
|
+
defined (ruby's coercion protocol). Previously, you had to handle
|
17
|
+
this differently, using something like:
|
18
|
+
|
19
|
+
Sequel.expr(1) - a
|
20
|
+
# or
|
21
|
+
Sequel.-(1, a)
|
22
|
+
|
23
|
+
* Sequel now supports the ** operator for exponentiation on
|
24
|
+
expressions, similar to the +, -, *, and / operators. Sequel uses
|
25
|
+
the database power function to implement this by default on the
|
26
|
+
databases that support it (most of them). On Access, it uses the ^
|
27
|
+
operator, on Derby it is emulated using a combination of exp/ln
|
28
|
+
(with some loss of precision). SQLite doesn't support a power
|
29
|
+
function at all, but Sequel emulates it using multiplication for
|
30
|
+
known integer exponents.
|
31
|
+
|
32
|
+
* Sequel::SQLTime.date= has been added, which allows you to set the
|
33
|
+
date used for Sequel::SQLTime instances. Sequel::SQLTime is a
|
34
|
+
subclass of Time that is literalized using only the time components,
|
35
|
+
and is the ruby class used to store values of database time columns
|
36
|
+
on most adapters. Sequel::SQLTime defaults to using the current
|
37
|
+
date, but you can now set a specific date, for more consistency with
|
38
|
+
some drivers (Mysql2 uses 2000-01-01, tiny_tds uses 1900-01-01).
|
39
|
+
|
40
|
+
* The postgres adapter now supports a :driver_options option when
|
41
|
+
using the pg driver, which is passed directly to pg. This can be
|
42
|
+
used to specify a client SSL certificate or to specify the
|
43
|
+
certificate authority root certificate when using
|
44
|
+
:sslmode=>'verify-full'.
|
45
|
+
|
46
|
+
= Other Improvements
|
47
|
+
|
48
|
+
* Sequel no longer uses after_commit/rollback database hooks by
|
49
|
+
default if the after_commit/after_rollback model methods are not
|
50
|
+
overridden. This provides a performance speedup, but the main
|
51
|
+
benefit is that it no longer causes memory issues when saving a
|
52
|
+
large number of model instances in a single transaction, and it
|
53
|
+
also works with prepared transactions/2 phase commit. You can
|
54
|
+
still set use_after_commit_rollback= manually to force the
|
55
|
+
after_commit/rollback setting.
|
56
|
+
|
57
|
+
Note that Sequel 5 will move after_commit/rollback model hooks to
|
58
|
+
a plugin, and the default and recommended approach will be to use
|
59
|
+
the database after_commit/rollback hooks in the after_save or
|
60
|
+
similar model hooks.
|
61
|
+
|
62
|
+
= Backwards Compatibility
|
63
|
+
|
64
|
+
* The Sequel::Model use_after_commit_rollback class and instance
|
65
|
+
methods now return nil by default instead of true. nil now
|
66
|
+
indicates the default behavior of checking whether the appropriate
|
67
|
+
model hook has been defined, and only adding a database hook if so.
|
data/doc/sql.rdoc
CHANGED
@@ -368,6 +368,7 @@ The standard mathematical operates are defined on most Sequel-specific expressio
|
|
368
368
|
Sequel.expr(:table__column) - 1 # "table"."column" - 1
|
369
369
|
Sequel.qualify(:table, :column) * 1 # "table"."column" * 1
|
370
370
|
Sequel.expr(:column) / 1 # "column" / 1
|
371
|
+
Sequel.expr(:column) ** 1 # power("column", 1)
|
371
372
|
|
372
373
|
You can also call the operator methods directly on the Sequel module:
|
373
374
|
|
@@ -375,15 +376,12 @@ You can also call the operator methods directly on the Sequel module:
|
|
375
376
|
Sequel.-(:table__column, 1) # "table"."column" - 1
|
376
377
|
Sequel.*(Sequel.qualify(:table, :column), 1) # "table"."column" * 1
|
377
378
|
Sequel./(:column, 1) # "column" / 1
|
379
|
+
Sequel.**(:column, 1) # power("column", 1)
|
378
380
|
|
379
|
-
Note that the following
|
381
|
+
Note that since Sequel implements support for ruby's coercion protocol, the following also works:
|
380
382
|
|
381
|
-
1 + Sequel.expr(:column)
|
382
|
-
|
383
|
-
For commutative operates such as + and *, this isn't a problem as you can just reorder, but non-commutative operators such as - and / cannot be expressed directly. The solution is to use one of the methods on the Sequel module:
|
384
|
-
|
385
|
-
Sequel.expr(1) / :column # (1 / "column")
|
386
|
-
Sequel./(1, :column) # (1 / "column")
|
383
|
+
1 + Sequel.expr(:column)
|
384
|
+
1 - Sequel.qualify(:table__column)
|
387
385
|
|
388
386
|
=== Boolean Operators (AND OR)
|
389
387
|
|
@@ -224,6 +224,12 @@ module Sequel
|
|
224
224
|
complex_expression_emulate_append(sql, op, args)
|
225
225
|
when :&, :|, :^, :<<, :>>
|
226
226
|
raise Error, "Derby doesn't support the #{op} operator"
|
227
|
+
when :**
|
228
|
+
sql << 'exp('
|
229
|
+
literal_append(sql, args[1])
|
230
|
+
sql << ' * ln('
|
231
|
+
literal_append(sql, args[0])
|
232
|
+
sql << "))"
|
227
233
|
when :extract
|
228
234
|
sql << args.at(0).to_s << PAREN_OPEN
|
229
235
|
literal_append(sql, args.at(1))
|
@@ -227,8 +227,8 @@ module Sequel
|
|
227
227
|
# client encoding for the connection, :connect_timeout is a
|
228
228
|
# connection timeout in seconds, :sslmode sets whether postgres's
|
229
229
|
# sslmode, and :notice_receiver handles server notices in a proc.
|
230
|
-
# :connect_timeout, :
|
231
|
-
# if the pg driver is used.
|
230
|
+
# :connect_timeout, :driver_options, :sslmode, and :notice_receiver
|
231
|
+
# are only supported if the pg driver is used.
|
232
232
|
def connect(server)
|
233
233
|
opts = server_opts(server)
|
234
234
|
if SEQUEL_POSTGRES_USES_PG
|
@@ -241,6 +241,7 @@ module Sequel
|
|
241
241
|
:connect_timeout => opts[:connect_timeout] || 20,
|
242
242
|
:sslmode => opts[:sslmode]
|
243
243
|
}.delete_if { |key, value| blank_object?(value) }
|
244
|
+
connection_params.merge!(opts[:driver_options]) if opts[:driver_options]
|
244
245
|
conn = Adapter.connect(connection_params)
|
245
246
|
|
246
247
|
conn.instance_variable_set(:@prepared_statements, {})
|
@@ -157,6 +157,12 @@ module Sequel
|
|
157
157
|
c ||= true
|
158
158
|
end
|
159
159
|
sql << PAREN_CLOSE
|
160
|
+
when :**
|
161
|
+
sql << PAREN_OPEN
|
162
|
+
literal_append(sql, args[0])
|
163
|
+
sql << ' ^ '
|
164
|
+
literal_append(sql, args[1])
|
165
|
+
sql << PAREN_CLOSE
|
160
166
|
when :extract
|
161
167
|
part = args.at(0)
|
162
168
|
raise(Sequel::Error, "unsupported extract argument: #{part.inspect}") unless format = EXTRACT_MAP[part]
|
@@ -555,6 +555,31 @@ module Sequel
|
|
555
555
|
complex_expression_sql_append(sql, (op == :"NOT ILIKE" ? :ILIKE : :LIKE), args)
|
556
556
|
when :^
|
557
557
|
complex_expression_arg_pairs_append(sql, args){|a, b| Sequel.lit(["((~(", " & ", ")) & (", " | ", "))"], a, b, a, b)}
|
558
|
+
when :**
|
559
|
+
unless (exp = args[1]).is_a?(Integer)
|
560
|
+
raise(Sequel::Error, "can only emulate exponentiation on SQLite if exponent is an integer, given #{exp.inspect}")
|
561
|
+
end
|
562
|
+
case exp
|
563
|
+
when 0
|
564
|
+
sql << '1'
|
565
|
+
else
|
566
|
+
sql << '('
|
567
|
+
arg = args.at(0)
|
568
|
+
if exp < 0
|
569
|
+
invert = true
|
570
|
+
exp = exp.abs
|
571
|
+
sql << '(1.0 / ('
|
572
|
+
end
|
573
|
+
(exp - 1).times do
|
574
|
+
literal_append(sql, arg)
|
575
|
+
sql << " * "
|
576
|
+
end
|
577
|
+
literal_append(sql, arg)
|
578
|
+
sql << PAREN_CLOSE
|
579
|
+
if invert
|
580
|
+
sql << "))"
|
581
|
+
end
|
582
|
+
end
|
558
583
|
when :extract
|
559
584
|
part = args.at(0)
|
560
585
|
raise(Sequel::Error, "unsupported extract argument: #{part.inspect}") unless format = EXTRACT_MAP[part]
|
data/lib/sequel/dataset/sql.rb
CHANGED
@@ -476,6 +476,8 @@ module Sequel
|
|
476
476
|
sql << PAREN_CLOSE
|
477
477
|
when :ILIKE, :'NOT ILIKE'
|
478
478
|
complex_expression_sql_append(sql, (op == :ILIKE ? :LIKE : :"NOT LIKE"), args.map{|v| Sequel.function(:UPPER, v)})
|
479
|
+
when :**
|
480
|
+
function_sql_append(sql, Sequel.function(:power, *args))
|
479
481
|
when *TWO_ARITY_OPERATORS
|
480
482
|
if REGEXP_OPERATORS.include?(op) && !supports_regexp?
|
481
483
|
raise InvalidOperation, "Pattern matching via regular expressions is not supported on #{db.database_type}"
|
@@ -10,6 +10,11 @@
|
|
10
10
|
#
|
11
11
|
# DB.extension(:connection_expiration)
|
12
12
|
#
|
13
|
+
# The default connection timeout is 14400 seconds (4 hours).
|
14
|
+
# To override it:
|
15
|
+
#
|
16
|
+
# DB.pool.connection_expiration_timeout = 3600 # 1 hour
|
17
|
+
#
|
13
18
|
# Note that this extension only affects the default threaded
|
14
19
|
# and the sharded threaded connection pool. The single
|
15
20
|
# threaded and sharded single threaded connection pools are
|
data/lib/sequel/model.rb
CHANGED
@@ -117,7 +117,7 @@ module Sequel
|
|
117
117
|
@strict_param_setting = true
|
118
118
|
@typecast_empty_string_to_nil = true
|
119
119
|
@typecast_on_assignment = true
|
120
|
-
@use_after_commit_rollback =
|
120
|
+
@use_after_commit_rollback = nil
|
121
121
|
@use_transactions = true
|
122
122
|
|
123
123
|
Sequel.require %w"default_inflections inflections plugins dataset_module base exceptions errors", "model"
|
data/lib/sequel/model/base.rb
CHANGED
@@ -1946,7 +1946,8 @@ module Sequel
|
|
1946
1946
|
# allow running inside a transaction
|
1947
1947
|
def _destroy(opts)
|
1948
1948
|
sh = {:server=>this_server}
|
1949
|
-
|
1949
|
+
uacr = use_after_commit_rollback
|
1950
|
+
db.after_rollback(sh){after_destroy_rollback} if uacr.nil? ? (method(:after_destroy_rollback).owner != InstanceMethods) : uacr
|
1950
1951
|
called = false
|
1951
1952
|
around_destroy do
|
1952
1953
|
called = true
|
@@ -1956,7 +1957,7 @@ module Sequel
|
|
1956
1957
|
true
|
1957
1958
|
end
|
1958
1959
|
raise_hook_failure(:around_destroy) unless called
|
1959
|
-
db.after_commit(sh){after_destroy_commit} if uacr
|
1960
|
+
db.after_commit(sh){after_destroy_commit} if uacr.nil? ? (method(:after_destroy_commit).owner != InstanceMethods) : uacr
|
1960
1961
|
self
|
1961
1962
|
end
|
1962
1963
|
|
@@ -2025,7 +2026,8 @@ module Sequel
|
|
2025
2026
|
# it's own transaction.
|
2026
2027
|
def _save(opts)
|
2027
2028
|
sh = {:server=>this_server}
|
2028
|
-
|
2029
|
+
uacr = use_after_commit_rollback
|
2030
|
+
db.after_rollback(sh){after_rollback} if uacr.nil? ? (method(:after_rollback).owner != InstanceMethods) : uacr
|
2029
2031
|
pk = nil
|
2030
2032
|
called_save = false
|
2031
2033
|
called_cu = false
|
@@ -2071,7 +2073,7 @@ module Sequel
|
|
2071
2073
|
end
|
2072
2074
|
raise_hook_failure(:around_save) unless called_save
|
2073
2075
|
_after_save(pk)
|
2074
|
-
db.after_commit(sh){after_commit} if uacr
|
2076
|
+
db.after_commit(sh){after_commit} if uacr.nil? ? (method(:after_commit).owner != InstanceMethods) : uacr
|
2075
2077
|
self
|
2076
2078
|
end
|
2077
2079
|
|
data/lib/sequel/sql.rb
CHANGED
@@ -45,10 +45,21 @@ module Sequel
|
|
45
45
|
# Time subclass that gets literalized with only the time value, so it operates
|
46
46
|
# like a standard SQL time type.
|
47
47
|
class SQLTime < ::Time
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
48
|
+
@date = nil
|
49
|
+
|
50
|
+
class << self
|
51
|
+
# Set the date used for SQLTime instances.
|
52
|
+
attr_writer :date
|
53
|
+
|
54
|
+
def date
|
55
|
+
@date || now
|
56
|
+
end
|
57
|
+
|
58
|
+
# Create a new SQLTime instance given an hour, minute, and second.
|
59
|
+
def create(hour, minute, second, usec = 0)
|
60
|
+
t = date
|
61
|
+
local(t.year, t.month, t.day, hour, minute, second, usec)
|
62
|
+
end
|
52
63
|
end
|
53
64
|
|
54
65
|
# Return a string in HH:MM:SS format representing the time.
|
@@ -163,9 +174,9 @@ module Sequel
|
|
163
174
|
:'NOT ILIKE'=>:ILIKE}
|
164
175
|
|
165
176
|
# Standard mathematical operators used in +NumericMethods+
|
166
|
-
MATHEMATICAL_OPERATORS = [:+, :-, :/,
|
177
|
+
MATHEMATICAL_OPERATORS = [:+, :-, :/, :*, :**]
|
167
178
|
|
168
|
-
# Bitwise mathematical operators used in +
|
179
|
+
# Bitwise mathematical operators used in +BitwiseMethods+
|
169
180
|
BITWISE_OPERATORS = [:&, :|, :^, :<<, :>>, :%]
|
170
181
|
|
171
182
|
# Operators that check for equality
|
@@ -190,10 +201,10 @@ module Sequel
|
|
190
201
|
LIKE_OPERATORS = [:LIKE, :'NOT LIKE', :ILIKE, :'NOT ILIKE']
|
191
202
|
|
192
203
|
# Operator symbols that take exactly two arguments
|
193
|
-
TWO_ARITY_OPERATORS = EQUALITY_OPERATORS + INEQUALITY_OPERATORS + IS_OPERATORS + IN_OPERATORS + REGEXP_OPERATORS + LIKE_OPERATORS
|
204
|
+
TWO_ARITY_OPERATORS = EQUALITY_OPERATORS + INEQUALITY_OPERATORS + IS_OPERATORS + IN_OPERATORS + REGEXP_OPERATORS + LIKE_OPERATORS + [:**]
|
194
205
|
|
195
206
|
# Operator symbols that take one or more arguments
|
196
|
-
N_ARITY_OPERATORS = [:AND, :OR, :'||'] + MATHEMATICAL_OPERATORS + BITWISE_OPERATORS
|
207
|
+
N_ARITY_OPERATORS = [:AND, :OR, :'||'] + MATHEMATICAL_OPERATORS + BITWISE_OPERATORS - [:**]
|
197
208
|
|
198
209
|
# Operator symbols that take only a single argument
|
199
210
|
ONE_ARITY_OPERATORS = [:NOT, :NOOP, :'B~']
|
@@ -775,8 +786,21 @@ module Sequel
|
|
775
786
|
#
|
776
787
|
# :a + 'b' # "a" || 'b'
|
777
788
|
module NumericMethods
|
778
|
-
ComplexExpression::MATHEMATICAL_OPERATORS.each do |o|
|
779
|
-
module_eval("def #{o}(o) NumericExpression.new(#{o.inspect}, self, o) end", __FILE__, __LINE__)
|
789
|
+
(ComplexExpression::MATHEMATICAL_OPERATORS - [:+]).each do |o|
|
790
|
+
module_eval("def #{o}(o) NumericExpression.new(#{o.inspect}, self, o) end", __FILE__, __LINE__)
|
791
|
+
end
|
792
|
+
|
793
|
+
# If the argument given is Numeric, treat it as a NumericExpression,
|
794
|
+
# allowing code such as:
|
795
|
+
#
|
796
|
+
# 1 + Sequel.expr(:x) # SQL: (1 + x)
|
797
|
+
# Sequel.expr{1 - x(y)} # SQL: (1 - x(y))
|
798
|
+
def coerce(other)
|
799
|
+
if other.is_a?(Numeric)
|
800
|
+
[SQL::NumericExpression.new(:NOOP, other), self]
|
801
|
+
else
|
802
|
+
super
|
803
|
+
end
|
780
804
|
end
|
781
805
|
|
782
806
|
# Use || as the operator when called with StringExpression and String instances,
|
@@ -852,6 +876,13 @@ module Sequel
|
|
852
876
|
END
|
853
877
|
end
|
854
878
|
end
|
879
|
+
|
880
|
+
# Return NumericExpression for the exponentiation:
|
881
|
+
#
|
882
|
+
# Sequel.**(2, 3) # SQL: power(2, 3)
|
883
|
+
def **(a, b)
|
884
|
+
SQL::NumericExpression.new(:**, a, b)
|
885
|
+
end
|
855
886
|
|
856
887
|
# Invert the given expression. Returns a <tt>Sequel::SQL::BooleanExpression</tt>
|
857
888
|
# created from this argument, not matching all of the conditions.
|
data/lib/sequel/version.rb
CHANGED
@@ -5,7 +5,7 @@ module Sequel
|
|
5
5
|
MAJOR = 4
|
6
6
|
# The minor version of Sequel. Bumped for every non-patch level
|
7
7
|
# release, generally around once a month.
|
8
|
-
MINOR =
|
8
|
+
MINOR = 38
|
9
9
|
# The tiny version of Sequel. Usually 0, only bumped for bugfix
|
10
10
|
# releases that fix regressions from previous versions.
|
11
11
|
TINY = 0
|
@@ -134,6 +134,7 @@ describe "Blockless Ruby Filters" do
|
|
134
134
|
@d.lit(Sequel.expr(:x) - true).must_equal "(x - 't')"
|
135
135
|
@d.lit(Sequel.expr(:x) / false).must_equal "(x / 'f')"
|
136
136
|
@d.lit(Sequel.expr(:x) * nil).must_equal '(x * NULL)'
|
137
|
+
@d.lit(Sequel.expr(:x) ** 1).must_equal 'power(x, 1)'
|
137
138
|
@d.lit(Sequel.join([:x, nil])).must_equal '(x || NULL)'
|
138
139
|
end
|
139
140
|
|
@@ -145,6 +146,17 @@ describe "Blockless Ruby Filters" do
|
|
145
146
|
@d.lit(Sequel.expr(:x) + Sequel.expr(:y).like('a')).must_equal "(x + (y LIKE 'a' ESCAPE '\\'))"
|
146
147
|
@d.lit(Sequel.expr(:x) - ~Sequel.expr(:y).like('a')).must_equal "(x - (y NOT LIKE 'a' ESCAPE '\\'))"
|
147
148
|
@d.lit(Sequel.join([:x, ~Sequel.expr(:y).like('a')])).must_equal "(x || (y NOT LIKE 'a' ESCAPE '\\'))"
|
149
|
+
@d.lit(Sequel.expr(:x) ** (Sequel.expr(:y) + 1)).must_equal 'power(x, (y + 1))'
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should allow mathematical or string operations on numerics when argument is a generic or numeric expressions" do
|
153
|
+
@d.lit(1 + Sequel.expr(:x)).must_equal '(1 + x)'
|
154
|
+
@d.lit(2**65 - Sequel.+(:x, 1)).must_equal "(#{2**65} - (x + 1))"
|
155
|
+
@d.lit(1.0 / Sequel.function(:x)).must_equal '(1.0 / x())'
|
156
|
+
@d.lit(BigDecimal.new('1.0') * Sequel.expr(:a__y)).must_equal '(1.0 * a.y)'
|
157
|
+
@d.lit(2 ** Sequel.cast(:x, Integer)).must_equal 'power(2, CAST(x AS integer))'
|
158
|
+
@d.lit(1 + Sequel.lit('x')).must_equal '(1 + x)'
|
159
|
+
@d.lit(1 + Sequel.lit('?', :x)).must_equal '(1 + x)'
|
148
160
|
end
|
149
161
|
|
150
162
|
it "should support AND conditions via &" do
|
@@ -192,6 +204,7 @@ describe "Blockless Ruby Filters" do
|
|
192
204
|
@d.l(Sequel.lit('x').like('a')).must_equal '(x LIKE \'a\' ESCAPE \'\\\')'
|
193
205
|
@d.l(Sequel.lit('x') + 1 > 100).must_equal '((x + 1) > 100)'
|
194
206
|
@d.l((Sequel.lit('x') * :y) < 100.01).must_equal '((x * y) < 100.01)'
|
207
|
+
@d.l((Sequel.lit('x') ** :y) < 100.01).must_equal '(power(x, y) < 100.01)'
|
195
208
|
@d.l((Sequel.lit('x') - Sequel.expr(:y)/2) >= 100000000000000000000000000000000000).must_equal '((x - (y / 2)) >= 100000000000000000000000000000000000)'
|
196
209
|
@d.l((Sequel.lit('z') * ((Sequel.lit('x') / :y)/(Sequel.expr(:x) + :y))) <= 100).must_equal '((z * (x / y / (x + y))) <= 100)'
|
197
210
|
@d.l(~((((Sequel.lit('x') - :y)/(Sequel.expr(:x) + :y))*:z) <= 100)).must_equal '((((x - y) / (x + y)) * z) > 100)'
|
@@ -397,6 +410,7 @@ describe "Blockless Ruby Filters" do
|
|
397
410
|
@d.lit(d - 1).must_equal '((SELECT a FROM items) - 1)'
|
398
411
|
@d.lit(d * 1).must_equal '((SELECT a FROM items) * 1)'
|
399
412
|
@d.lit(d / 1).must_equal '((SELECT a FROM items) / 1)'
|
413
|
+
@d.lit(d ** 1).must_equal 'power((SELECT a FROM items), 1)'
|
400
414
|
|
401
415
|
@d.lit(d => 1).must_equal '((SELECT a FROM items) = 1)'
|
402
416
|
@d.lit(Sequel.~(d => 1)).must_equal '((SELECT a FROM items) != 1)'
|
@@ -665,6 +679,7 @@ describe Sequel::SQL::VirtualRow do
|
|
665
679
|
@d.l{|o| o.+(1, :b) > 2}.must_equal '((1 + "b") > 2)'
|
666
680
|
@d.l{|o| o.-(1, :b) < 2}.must_equal '((1 - "b") < 2)'
|
667
681
|
@d.l{|o| o.*(1, :b) >= 2}.must_equal '((1 * "b") >= 2)'
|
682
|
+
@d.l{|o| o.**(1, :b) >= 2}.must_equal '(power(1, "b") >= 2)'
|
668
683
|
@d.l{|o| o./(1, :b) <= 2}.must_equal '((1 / "b") <= 2)'
|
669
684
|
@d.l{|o| o.~(:a=>1)}.must_equal '("a" != 1)'
|
670
685
|
@d.l{|o| o.~([[:a, 1], [:b, 2]])}.must_equal '(("a" != 1) OR ("b" != 2))'
|
@@ -934,6 +949,16 @@ describe "Sequel core extension replacements" do
|
|
934
949
|
end
|
935
950
|
end
|
936
951
|
|
952
|
+
it "Sequel.** should use power function if given 2 arguments" do
|
953
|
+
l(Sequel.**(1, 2), 'power(1, 2)')
|
954
|
+
end
|
955
|
+
|
956
|
+
it "Sequel.** should raise if not given 2 arguments" do
|
957
|
+
proc{Sequel.**}.must_raise(ArgumentError)
|
958
|
+
proc{Sequel.**(1)}.must_raise(ArgumentError)
|
959
|
+
proc{Sequel.**(1, 2, 3)}.must_raise(ArgumentError)
|
960
|
+
end
|
961
|
+
|
937
962
|
it "Sequel.like should use a LIKE expression" do
|
938
963
|
l(Sequel.like('a', 'b'), "('a' LIKE 'b' ESCAPE '\\')")
|
939
964
|
l(Sequel.like(:a, :b), "(a LIKE b ESCAPE '\\')")
|
@@ -1048,12 +1073,24 @@ describe "Sequel::SQLTime" do
|
|
1048
1073
|
before do
|
1049
1074
|
@db = Sequel.mock
|
1050
1075
|
end
|
1076
|
+
after do
|
1077
|
+
Sequel::SQLTime.date = nil
|
1078
|
+
end
|
1051
1079
|
|
1052
1080
|
it ".create should create from hour, minutes, seconds and optional microseconds" do
|
1053
1081
|
@db.literal(Sequel::SQLTime.create(1, 2, 3)).must_equal "'01:02:03.000000'"
|
1054
1082
|
@db.literal(Sequel::SQLTime.create(1, 2, 3, 500000)).must_equal "'01:02:03.500000'"
|
1055
1083
|
end
|
1056
1084
|
|
1085
|
+
it ".create should use today's date by default" do
|
1086
|
+
Sequel::SQLTime.create(1, 2, 3).strftime('%Y-%m-%d').must_equal Date.today.strftime('%Y-%m-%d')
|
1087
|
+
end
|
1088
|
+
|
1089
|
+
it ".create should use specific date if set" do
|
1090
|
+
Sequel::SQLTime.date = Date.new(2000)
|
1091
|
+
Sequel::SQLTime.create(1, 2, 3).strftime('%Y-%m-%d').must_equal Date.new(2000).strftime('%Y-%m-%d')
|
1092
|
+
end
|
1093
|
+
|
1057
1094
|
it "#to_s should include hour, minute, and second by default" do
|
1058
1095
|
Sequel::SQLTime.create(1, 2, 3).to_s.must_equal "01:02:03"
|
1059
1096
|
Sequel::SQLTime.create(1, 2, 3, 500000).to_s.must_equal "01:02:03"
|
@@ -1082,6 +1119,7 @@ describe "Sequel::SQL::Wrapper" do
|
|
1082
1119
|
s = Sequel::SQL::Wrapper.new(o)
|
1083
1120
|
@ds.literal(s).must_equal "foo"
|
1084
1121
|
@ds.literal(s+1).must_equal "(foo + 1)"
|
1122
|
+
@ds.literal(s**1).must_equal "power(foo, 1)"
|
1085
1123
|
@ds.literal(s & true).must_equal "(foo AND 't')"
|
1086
1124
|
@ds.literal(s < 1).must_equal "(foo < 1)"
|
1087
1125
|
@ds.literal(s.sql_subscript(1)).must_equal "foo[1]"
|
@@ -87,12 +87,17 @@ describe "Core extensions" do
|
|
87
87
|
@d.l(~:x__y).must_equal 'NOT x.y'
|
88
88
|
end
|
89
89
|
|
90
|
-
it "should support + - * / via Symbol
|
90
|
+
it "should support + - * / power via Symbol#+,-,*,/,**" do
|
91
91
|
@d.l(:x + 1 > 100).must_equal '((x + 1) > 100)'
|
92
92
|
@d.l((:x * :y) < 100.01).must_equal '((x * y) < 100.01)'
|
93
93
|
@d.l((:x - :y/2) >= 100000000000000000000000000000000000).must_equal '((x - (y / 2)) >= 100000000000000000000000000000000000)'
|
94
94
|
@d.l((((:x - :y)/(:x + :y))*:z) <= 100).must_equal '((((x - y) / (x + y)) * z) <= 100)'
|
95
95
|
@d.l(~((((:x - :y)/(:x + :y))*:z) <= 100)).must_equal '((((x - y) / (x + y)) * z) > 100)'
|
96
|
+
@d.l(~((((:x ** :y)/(:x + :y))*:z) <= 100)).must_equal '(((power(x, y) / (x + y)) * z) > 100)'
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should support coercion for symbols" do
|
100
|
+
@d.l(1 + :x > 2).must_equal '((1 + x) > 2)'
|
96
101
|
end
|
97
102
|
|
98
103
|
it "should support LIKE via Symbol#like" do
|
@@ -22,12 +22,13 @@ describe "Core refinements" do
|
|
22
22
|
@d.l(~:x__y).must_equal 'NOT x.y'
|
23
23
|
end
|
24
24
|
|
25
|
-
it "should support + - * / via Symbol
|
25
|
+
it "should support + - * / power via Symbol#+,-,*,/,**" do
|
26
26
|
@d.l(:x + 1 > 100).must_equal '((x + 1) > 100)'
|
27
27
|
@d.l((:x * :y) < 100.01).must_equal '((x * y) < 100.01)'
|
28
28
|
@d.l((:x - :y/2) >= 100000000000000000000000000000000000).must_equal '((x - (y / 2)) >= 100000000000000000000000000000000000)'
|
29
29
|
@d.l((((:x - :y)/(:x + :y))*:z) <= 100).must_equal '((((x - y) / (x + y)) * z) <= 100)'
|
30
30
|
@d.l(~((((:x - :y)/(:x + :y))*:z) <= 100)).must_equal '((((x - y) / (x + y)) * z) > 100)'
|
31
|
+
@d.l(~((((:x ** :y)/(:x + :y))*:z) <= 100)).must_equal '(((power(x, y) / (x + y)) * z) > 100)'
|
31
32
|
end
|
32
33
|
|
33
34
|
it "should support LIKE via Symbol#like" do
|
@@ -1297,6 +1297,14 @@ describe "Sequel::Dataset DSL support" do
|
|
1297
1297
|
@ds.get{a * b}.to_i.must_equal 200
|
1298
1298
|
@ds.get{a / b}.to_i.must_equal 2
|
1299
1299
|
end
|
1300
|
+
|
1301
|
+
it "should work with exponentiation operator" do
|
1302
|
+
@ds.insert(:a=>2)
|
1303
|
+
(-4..4).each do |i|
|
1304
|
+
# Allow minor differences due to emulation issues on some adapters
|
1305
|
+
@ds.get{(a / 1.0) ** i}.to_f.must_be_close_to((2**i).to_f)
|
1306
|
+
end
|
1307
|
+
end
|
1300
1308
|
|
1301
1309
|
cspecify "should work with bitwise shift operators", :derby do
|
1302
1310
|
@ds.insert(3, 2)
|
data/spec/model/hooks_spec.rb
CHANGED
@@ -601,4 +601,44 @@ describe "Model#after_commit and #after_rollback" do
|
|
601
601
|
o.save
|
602
602
|
@db.sqls.must_equal ['BEGIN', 'as', 'COMMIT']
|
603
603
|
end
|
604
|
+
|
605
|
+
it "should handle use_after_commit_rollback when subclassing after loading" do
|
606
|
+
@m = Class.new(Sequel::Model(@db[:items]))
|
607
|
+
@m.use_transactions = true
|
608
|
+
o = @m.load({})
|
609
|
+
@db.sqls
|
610
|
+
o.save
|
611
|
+
@db.sqls.must_equal ['BEGIN', 'COMMIT']
|
612
|
+
|
613
|
+
c = Class.new(@m)
|
614
|
+
o = c.load({})
|
615
|
+
def o.after_commit; db.execute 'ac' end
|
616
|
+
@db.sqls
|
617
|
+
o.save
|
618
|
+
@db.sqls.must_equal ['BEGIN', 'COMMIT', 'ac']
|
619
|
+
|
620
|
+
o = c.load({})
|
621
|
+
@db.sqls
|
622
|
+
o.save
|
623
|
+
@db.sqls.must_equal ['BEGIN', 'COMMIT']
|
624
|
+
|
625
|
+
c.send(:define_method, :after_commit){db.execute 'ac'}
|
626
|
+
o = c.load({})
|
627
|
+
@db.sqls
|
628
|
+
o.save
|
629
|
+
@db.sqls.must_equal ['BEGIN', 'COMMIT', 'ac']
|
630
|
+
|
631
|
+
c = Class.new(@m)
|
632
|
+
c.send(:include, Module.new{def after_commit; db.execute 'ac'; end})
|
633
|
+
o = c.load({})
|
634
|
+
@db.sqls
|
635
|
+
o.save
|
636
|
+
@db.sqls.must_equal ['BEGIN', 'COMMIT', 'ac']
|
637
|
+
|
638
|
+
c.use_after_commit_rollback = false
|
639
|
+
o = c.load({})
|
640
|
+
@db.sqls
|
641
|
+
o.save
|
642
|
+
@db.sqls.must_equal ['BEGIN', 'COMMIT']
|
643
|
+
end
|
604
644
|
end
|
data/spec/model/record_spec.rb
CHANGED
@@ -1304,8 +1304,9 @@ describe Sequel::Model, "#(set|update)_(all|only)" do
|
|
1304
1304
|
end
|
1305
1305
|
|
1306
1306
|
it "#set_all should set not set restricted fields" do
|
1307
|
-
@o1.
|
1308
|
-
@o1.use_after_commit_rollback
|
1307
|
+
@o1.use_after_commit_rollback.must_equal nil
|
1308
|
+
@o1.set_all(:x => 1, :use_after_commit_rollback => true)
|
1309
|
+
@o1.use_after_commit_rollback.must_equal nil
|
1309
1310
|
@o1.values.must_equal(:x => 1)
|
1310
1311
|
end
|
1311
1312
|
|
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: 4.
|
4
|
+
version: 4.38.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: 2016-
|
11
|
+
date: 2016-09-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -238,6 +238,7 @@ extra_rdoc_files:
|
|
238
238
|
- doc/release_notes/4.35.0.txt
|
239
239
|
- doc/release_notes/4.36.0.txt
|
240
240
|
- doc/release_notes/4.37.0.txt
|
241
|
+
- doc/release_notes/4.38.0.txt
|
241
242
|
files:
|
242
243
|
- CHANGELOG
|
243
244
|
- MIT-LICENSE
|
@@ -364,6 +365,7 @@ files:
|
|
364
365
|
- doc/release_notes/4.35.0.txt
|
365
366
|
- doc/release_notes/4.36.0.txt
|
366
367
|
- doc/release_notes/4.37.0.txt
|
368
|
+
- doc/release_notes/4.38.0.txt
|
367
369
|
- doc/release_notes/4.4.0.txt
|
368
370
|
- doc/release_notes/4.5.0.txt
|
369
371
|
- doc/release_notes/4.6.0.txt
|