sequel 4.5.0 → 4.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +14 -0
- data/README.rdoc +0 -1
- data/doc/mssql_stored_procedures.rdoc +43 -0
- data/doc/release_notes/3.18.0.txt +2 -3
- data/doc/release_notes/3.9.0.txt +1 -1
- data/doc/release_notes/4.6.0.txt +30 -0
- data/doc/security.rdoc +7 -0
- data/lib/sequel/adapters/jdbc/h2.rb +4 -4
- data/lib/sequel/adapters/jdbc/postgresql.rb +4 -0
- data/lib/sequel/adapters/oracle.rb +1 -0
- data/lib/sequel/adapters/shared/mssql.rb +94 -1
- data/lib/sequel/adapters/shared/mysql.rb +4 -4
- data/lib/sequel/adapters/shared/postgres.rb +4 -4
- data/lib/sequel/adapters/tinytds.rb +22 -4
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +8 -2
- data/lib/sequel/database/dataset_defaults.rb +1 -1
- data/lib/sequel/model/associations.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +35 -0
- data/spec/adapters/oracle_spec.rb +4 -4
- data/spec/adapters/postgres_spec.rb +93 -93
- data/spec/adapters/spec_helper.rb +3 -1
- data/spec/bin_spec.rb +2 -0
- data/spec/core/database_spec.rb +22 -22
- data/spec/core/dataset_spec.rb +8 -8
- data/spec/core/expression_filters_spec.rb +1 -1
- data/spec/core/mock_adapter_spec.rb +2 -2
- data/spec/core/schema_generator_spec.rb +3 -3
- data/spec/core/spec_helper.rb +3 -1
- data/spec/core_extensions_spec.rb +3 -1
- data/spec/extensions/auto_validations_spec.rb +17 -17
- data/spec/extensions/caching_spec.rb +4 -4
- data/spec/extensions/error_splitter_spec.rb +1 -1
- data/spec/extensions/hook_class_methods_spec.rb +6 -6
- data/spec/extensions/migration_spec.rb +53 -53
- data/spec/extensions/pagination_spec.rb +9 -9
- data/spec/extensions/pg_array_associations_spec.rb +2 -2
- data/spec/extensions/pg_array_spec.rb +2 -2
- data/spec/extensions/pg_hstore_spec.rb +15 -15
- data/spec/extensions/pg_interval_spec.rb +3 -3
- data/spec/extensions/pg_range_spec.rb +20 -20
- data/spec/extensions/pg_row_spec.rb +1 -1
- data/spec/extensions/schema_caching_spec.rb +3 -3
- data/spec/extensions/spec_helper.rb +3 -1
- data/spec/extensions/static_cache_spec.rb +16 -16
- data/spec/extensions/tree_spec.rb +8 -8
- data/spec/extensions/validation_class_methods_spec.rb +10 -10
- data/spec/integration/database_test.rb +3 -3
- data/spec/integration/dataset_test.rb +6 -0
- data/spec/integration/migrator_test.rb +67 -67
- data/spec/integration/model_test.rb +2 -2
- data/spec/integration/schema_test.rb +1 -1
- data/spec/integration/spec_helper.rb +3 -1
- data/spec/integration/transaction_test.rb +2 -2
- data/spec/model/association_reflection_spec.rb +4 -4
- data/spec/model/associations_spec.rb +1 -1
- data/spec/model/class_dataset_methods_spec.rb +1 -1
- data/spec/model/eager_loading_spec.rb +7 -0
- data/spec/model/model_spec.rb +4 -4
- data/spec/model/record_spec.rb +20 -20
- data/spec/model/spec_helper.rb +2 -1
- data/spec/model/validations_spec.rb +1 -1
- data/spec/rspec_helper.rb +18 -0
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4da9d52fb246c1f0e83b88184dd82d4bf7b609cd
|
4
|
+
data.tar.gz: 041e624b4f998ebc9835898be941fadc12fda8c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d965c77370235e2ceee16aca1e1193b01d2eb259b179307a51f8218778dda40c4fb35cea667568ce7cfa4d5f95297396a2876ae744d3638d359b81dfa63a019a
|
7
|
+
data.tar.gz: 052c8d3db3bd66279b50cf455e6928eb9e753e49f273399f85d5d0e2fe238ecc33c97a1a95d1b56f5bca9cb670c1fedb9eeb95fdb68232ac032647eb370b7992
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
=== 4.6.0 (2014-01-02)
|
2
|
+
|
3
|
+
* Add Database#call_mssql_sproc on MSSQL for calling stored procedures and handling output parameters (jrgns, jeremyevans) (#748)
|
4
|
+
|
5
|
+
* Handle RuntimeErrors raised by oci8 in the oracle adapter (jeremyevans)
|
6
|
+
|
7
|
+
* Support OFFSET/FETCH on Microsoft SQL Server 2012 (jeremyevans)
|
8
|
+
|
9
|
+
* Support :server option for Database#{commit,rollback}_prepared_transaction on PostgreSQL, MySQL, and H2 (jeremyevans) (#743)
|
10
|
+
|
11
|
+
* Do not attempt to eager load and raise an exception when doing Model.eager(...).naked.all (jeremyevans)
|
12
|
+
|
13
|
+
* Recognize a couple additional disconnect errors in the jdbc/postgresql adapter (jeremyevans) (#742)
|
14
|
+
|
1
15
|
=== 4.5.0 (2013-12-02)
|
2
16
|
|
3
17
|
* Support :on_commit=>(:drop|:delete_rows|:preserve_rows) options when creating temp tables on PostgreSQL (rosenfeld) (#737)
|
data/README.rdoc
CHANGED
@@ -19,7 +19,6 @@ toolkit for Ruby.
|
|
19
19
|
== Resources
|
20
20
|
|
21
21
|
* {Website}[http://sequel.jeremyevans.net]
|
22
|
-
* {Blog}[http://sequel.heroku.com]
|
23
22
|
* {Source code}[http://github.com/jeremyevans/sequel]
|
24
23
|
* {Bug tracking}[http://github.com/jeremyevans/sequel/issues]
|
25
24
|
* {Google group}[http://groups.google.com/group/sequel-talk]
|
@@ -0,0 +1,43 @@
|
|
1
|
+
= Stored Procedures in MSSQL
|
2
|
+
|
3
|
+
This guide documents the workaround implemented to allow executing stored procedures
|
4
|
+
in MSSQL, as well as getting the value of output variables.
|
5
|
+
|
6
|
+
== Simple Execution
|
7
|
+
|
8
|
+
The following stored procedure is used as an example:
|
9
|
+
|
10
|
+
CREATE PROCEDURE dbo.SequelTest(
|
11
|
+
@Input varchar(25),
|
12
|
+
@Output int OUTPUT
|
13
|
+
)
|
14
|
+
AS
|
15
|
+
SET @Output = LEN(@Input)
|
16
|
+
RETURN 0
|
17
|
+
|
18
|
+
Execute it as follows:
|
19
|
+
|
20
|
+
DB.call_mssql_sproc(:SequelTest, {:args => ['Input String', :output]})
|
21
|
+
|
22
|
+
Use the +:output+ symbol to denote an output variable. The result will contain a
|
23
|
+
hash of the output variables, as well as the result code and number of affected rows:
|
24
|
+
|
25
|
+
{:result => 0, :numrows => 1, :var1 => "1"}
|
26
|
+
|
27
|
+
Output variables will be strings by default. To specify their type, include the
|
28
|
+
SQL type:
|
29
|
+
|
30
|
+
DB.call_mssql_sproc(:SequelTest, {:args => ['Input String', [:output, 'int']]})
|
31
|
+
|
32
|
+
Result:
|
33
|
+
|
34
|
+
{:result => 0, :numrows => 1, :var1 => 1}
|
35
|
+
|
36
|
+
Output variables will be named +var#{n}+ where n is their zero indexed position
|
37
|
+
in the parameter list. To name the output variable, include their name:
|
38
|
+
|
39
|
+
DB.call_mssql_sproc(:SequelTest, {:args => ['Input String', [:output, nil, 'Output']]})
|
40
|
+
|
41
|
+
Result:
|
42
|
+
|
43
|
+
{:result => 0, :numrows => 1, :output => "1"}
|
@@ -52,9 +52,8 @@
|
|
52
52
|
the graphviz dot program in order to create visualizations
|
53
53
|
of the dataset's abstract syntax tree. Examples:
|
54
54
|
|
55
|
-
* http://sequel.
|
56
|
-
* http://sequel.
|
57
|
-
* http://imgpaste.com/i/lxngy.gif
|
55
|
+
* http://sequel.jeremyevans.net/images/to_dot_simple.gif
|
56
|
+
* http://sequel.jeremyevans.net/images/to_dot_complex.gif
|
58
57
|
|
59
58
|
Both the to_dot extension and reversible migrations support
|
60
59
|
were inspired by Aaron Patterson's recent work on ActiveRecord
|
data/doc/release_notes/3.9.0.txt
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* Database#call_mssql_sproc is now available for calling
|
4
|
+
stored procedures on Microsoft SQL Server, including the use
|
5
|
+
of output parameters.
|
6
|
+
|
7
|
+
* The Database#{commit,rollback}_prepared_transaction methods now
|
8
|
+
support a :server option for the server on which to operate.
|
9
|
+
|
10
|
+
= Other Improvements
|
11
|
+
|
12
|
+
* On Microsoft SQL Server 2012, the native OFFSET/FETCH support
|
13
|
+
is now used for offsets, instead of emulating support via the
|
14
|
+
ROW_NUMBER window function.
|
15
|
+
|
16
|
+
* Eager loading is now skipped when doing eager(...).naked.all on
|
17
|
+
a model dataset, instead of raising an error. This can fix issues
|
18
|
+
when the eager_each plugin is used.
|
19
|
+
|
20
|
+
* A couple additional disconnection errors are now detected in the
|
21
|
+
jdbc/postgresql adapter.
|
22
|
+
|
23
|
+
* The tinytds adapter now handles returning rows when the fields
|
24
|
+
are not immediately available.
|
25
|
+
|
26
|
+
* RuntimeErrors raised by oci8 are now handled correctly in the
|
27
|
+
oracle adapter.
|
28
|
+
|
29
|
+
* Sequel's specs now work with RSpec 3, while still running
|
30
|
+
correctly on RSpec 1.3 and 2.
|
data/doc/security.rdoc
CHANGED
@@ -168,6 +168,13 @@ Instead, you should do:
|
|
168
168
|
The Sequel::Dataset#lock_style method also treats an input string
|
169
169
|
as SQL code. This method should not be called with user input.
|
170
170
|
|
171
|
+
==== SQL Type Names
|
172
|
+
|
173
|
+
In general, most places where Sequel needs to use an SQL type that should
|
174
|
+
be specified by the user, it allows you to use a ruby string, and that
|
175
|
+
string is used verbatim as the SQL type. You should not use user input
|
176
|
+
for type strings.
|
177
|
+
|
171
178
|
=== SQL Identifier Injections
|
172
179
|
|
173
180
|
Usually, Sequel treats ruby symbols as SQL identifiers, and ruby
|
@@ -9,8 +9,8 @@ module Sequel
|
|
9
9
|
|
10
10
|
# Commit an existing prepared transaction with the given transaction
|
11
11
|
# identifier string.
|
12
|
-
def commit_prepared_transaction(transaction_id)
|
13
|
-
run("COMMIT TRANSACTION #{transaction_id}")
|
12
|
+
def commit_prepared_transaction(transaction_id, opts=OPTS)
|
13
|
+
run("COMMIT TRANSACTION #{transaction_id}", opts)
|
14
14
|
end
|
15
15
|
|
16
16
|
# H2 uses the :h2 database type.
|
@@ -20,8 +20,8 @@ module Sequel
|
|
20
20
|
|
21
21
|
# Rollback an existing prepared transaction with the given transaction
|
22
22
|
# identifier string.
|
23
|
-
def rollback_prepared_transaction(transaction_id)
|
24
|
-
run("ROLLBACK TRANSACTION #{transaction_id}")
|
23
|
+
def rollback_prepared_transaction(transaction_id, opts=OPTS)
|
24
|
+
run("ROLLBACK TRANSACTION #{transaction_id}", opts)
|
25
25
|
end
|
26
26
|
|
27
27
|
# H2 uses an IDENTITY type
|
@@ -83,6 +83,10 @@ module Sequel
|
|
83
83
|
|
84
84
|
private
|
85
85
|
|
86
|
+
def disconnect_error?(exception, opts)
|
87
|
+
super || exception.message =~ /\AThis connection has been closed\.\z|\AFATAL: terminating connection due to administrator command\z/
|
88
|
+
end
|
89
|
+
|
86
90
|
# Use setNull for nil arguments as the default behavior of setString
|
87
91
|
# with nil doesn't appear to work correctly on PostgreSQL.
|
88
92
|
def set_ps_arg_nil(cps, i)
|
@@ -34,6 +34,51 @@ module Sequel
|
|
34
34
|
# to :integer.
|
35
35
|
DECIMAL_TYPE_RE = /number|numeric|decimal/io
|
36
36
|
|
37
|
+
# Execute the given stored procedure with the given name.
|
38
|
+
#
|
39
|
+
# Options:
|
40
|
+
# :args :: Array of arguments to stored procedure. Output parameters to
|
41
|
+
# the function are specified using :output. You can also name
|
42
|
+
# output parameters and provide a type by using an array containing
|
43
|
+
# :output, the type name, and the parameter name.
|
44
|
+
# :server :: The server/shard on which to execute the procedure.
|
45
|
+
#
|
46
|
+
# Examples:
|
47
|
+
#
|
48
|
+
# DB.call_mssql_sproc(:SequelTest, {:args => ['input arg', :output]})
|
49
|
+
# DB.call_mssql_sproc(:SequelTest, {:args => ['input arg', [:output, 'int', 'varname']]})
|
50
|
+
def call_mssql_sproc(name, opts=OPTS)
|
51
|
+
args = opts[:args] || []
|
52
|
+
names = ['@RC AS RESULT', '@@ROWCOUNT AS NUMROWS']
|
53
|
+
declarations = ['@RC int']
|
54
|
+
values = []
|
55
|
+
|
56
|
+
args.each_with_index do |v, i|
|
57
|
+
if v.is_a?(Array)
|
58
|
+
v, type, select = v
|
59
|
+
else
|
60
|
+
type = select = nil
|
61
|
+
end
|
62
|
+
|
63
|
+
if v == :output
|
64
|
+
type = "nvarchar(max)" unless type
|
65
|
+
varname = "var#{i}" unless varname
|
66
|
+
select ||= varname
|
67
|
+
names << "@#{varname} AS #{quote_identifier(select)}"
|
68
|
+
declarations << "@#{varname} #{type}"
|
69
|
+
values << "@#{varname} OUTPUT"
|
70
|
+
else
|
71
|
+
values << literal(v)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
sql = "DECLARE #{declarations.join(', ')}; EXECUTE @RC = #{name} #{values.join(', ')}; SELECT #{names.join(', ')}"
|
76
|
+
|
77
|
+
ds = dataset.with_sql(sql)
|
78
|
+
ds = ds.server(opts[:server]) if opts[:server]
|
79
|
+
ds.first
|
80
|
+
end
|
81
|
+
|
37
82
|
# Microsoft SQL Server uses the :mssql type.
|
38
83
|
def database_type
|
39
84
|
:mssql
|
@@ -457,6 +502,10 @@ module Sequel
|
|
457
502
|
FORMAT_DATE = "'%Y%m%d'".freeze
|
458
503
|
CROSS_APPLY = 'CROSS APPLY'.freeze
|
459
504
|
OUTER_APPLY = 'OUTER APPLY'.freeze
|
505
|
+
OFFSET = " OFFSET ".freeze
|
506
|
+
ROWS = " ROWS".freeze
|
507
|
+
ROWS_ONLY = " ROWS ONLY".freeze
|
508
|
+
FETCH_NEXT = " FETCH NEXT ".freeze
|
460
509
|
|
461
510
|
Sequel::Dataset.def_mutation_method(:disable_insert_output, :output, :module=>self)
|
462
511
|
|
@@ -607,6 +656,18 @@ module Sequel
|
|
607
656
|
sql << BRACKET_OPEN << name.to_s.gsub(/\]/, DOUBLE_BRACKET_CLOSE) << BRACKET_CLOSE
|
608
657
|
end
|
609
658
|
|
659
|
+
# On MSSQL 2012+ add a default order to the current dataset if an offset is used.
|
660
|
+
# The default offset emulation using a subquery would be used in the unordered
|
661
|
+
# case by default, and that also adds a default order, so it's better to just
|
662
|
+
# avoid the subquery.
|
663
|
+
def select_sql
|
664
|
+
if @opts[:offset] && !@opts[:order] && is_2012_or_later?
|
665
|
+
order(1).select_sql
|
666
|
+
else
|
667
|
+
super
|
668
|
+
end
|
669
|
+
end
|
670
|
+
|
610
671
|
# The version of the database server.
|
611
672
|
def server_version
|
612
673
|
db.server_version(@opts[:server])
|
@@ -703,6 +764,11 @@ module Sequel
|
|
703
764
|
server_version >= 10000000
|
704
765
|
end
|
705
766
|
|
767
|
+
# Whether we are using SQL Server 2012 or later.
|
768
|
+
def is_2012_or_later?
|
769
|
+
server_version >= 11000000
|
770
|
+
end
|
771
|
+
|
706
772
|
# Use strict ISO-8601 format with T between date and time,
|
707
773
|
# since that is the format that is multilanguage and not
|
708
774
|
# DATEFORMAT dependent.
|
@@ -730,6 +796,11 @@ module Sequel
|
|
730
796
|
end
|
731
797
|
end
|
732
798
|
alias update_from_sql delete_from2_sql
|
799
|
+
|
800
|
+
# Microsoft SQL Server 2012 has native support for offsets, but only for ordered datasets.
|
801
|
+
def emulate_offset_with_row_number?
|
802
|
+
super && !(is_2012_or_later? && @opts[:order])
|
803
|
+
end
|
733
804
|
|
734
805
|
# Return the first primary key for the current table. If this table has
|
735
806
|
# multiple primary keys, this will only return one of them. Used by #_import.
|
@@ -800,7 +871,8 @@ module Sequel
|
|
800
871
|
BOOL_TRUE
|
801
872
|
end
|
802
873
|
|
803
|
-
# MSSQL adds the limit before the columns
|
874
|
+
# MSSQL adds the limit before the columns, except on 2012+ when using
|
875
|
+
# offsets on ordered queries.
|
804
876
|
def select_clause_methods
|
805
877
|
SELECT_CLAUSE_METHODS
|
806
878
|
end
|
@@ -816,6 +888,8 @@ module Sequel
|
|
816
888
|
# to allow the limit to be a bound variable.
|
817
889
|
def select_limit_sql(sql)
|
818
890
|
if l = @opts[:limit]
|
891
|
+
return if is_2012_or_later? && @opts[:order] && @opts[:offset]
|
892
|
+
|
819
893
|
if is_2005_or_later?
|
820
894
|
sql << TOP_PAREN
|
821
895
|
literal_append(sql, l)
|
@@ -840,6 +914,25 @@ module Sequel
|
|
840
914
|
end
|
841
915
|
end
|
842
916
|
|
917
|
+
# On 2012+ when there is an order with an offset, append the offset (and possible
|
918
|
+
# limit) at the end of the order clause.
|
919
|
+
def select_order_sql(sql)
|
920
|
+
super
|
921
|
+
if is_2012_or_later? && @opts[:order]
|
922
|
+
if o = @opts[:offset]
|
923
|
+
sql << OFFSET
|
924
|
+
literal_append(sql, o)
|
925
|
+
sql << ROWS
|
926
|
+
|
927
|
+
if l = @opts[:limit]
|
928
|
+
sql << FETCH_NEXT
|
929
|
+
literal_append(sql, l)
|
930
|
+
sql << ROWS_ONLY
|
931
|
+
end
|
932
|
+
end
|
933
|
+
end
|
934
|
+
end
|
935
|
+
|
843
936
|
# SQL fragment for MSSQL's OUTPUT clause.
|
844
937
|
def output_sql(sql)
|
845
938
|
return unless supports_output_clause?
|
@@ -50,8 +50,8 @@ module Sequel
|
|
50
50
|
|
51
51
|
# Commit an existing prepared transaction with the given transaction
|
52
52
|
# identifier string.
|
53
|
-
def commit_prepared_transaction(transaction_id)
|
54
|
-
run("XA COMMIT #{literal(transaction_id)}")
|
53
|
+
def commit_prepared_transaction(transaction_id, opts=OPTS)
|
54
|
+
run("XA COMMIT #{literal(transaction_id)}", opts)
|
55
55
|
end
|
56
56
|
|
57
57
|
# MySQL uses the :mysql database type
|
@@ -112,8 +112,8 @@ module Sequel
|
|
112
112
|
|
113
113
|
# Rollback an existing prepared transaction with the given transaction
|
114
114
|
# identifier string.
|
115
|
-
def rollback_prepared_transaction(transaction_id)
|
116
|
-
run("XA ROLLBACK #{literal(transaction_id)}")
|
115
|
+
def rollback_prepared_transaction(transaction_id, opts=OPTS)
|
116
|
+
run("XA ROLLBACK #{literal(transaction_id)}", opts)
|
117
117
|
end
|
118
118
|
|
119
119
|
# Get version of MySQL server, used for determined capabilities.
|
@@ -156,8 +156,8 @@ module Sequel
|
|
156
156
|
|
157
157
|
# Commit an existing prepared transaction with the given transaction
|
158
158
|
# identifier string.
|
159
|
-
def commit_prepared_transaction(transaction_id)
|
160
|
-
run("COMMIT PREPARED #{literal(transaction_id)}")
|
159
|
+
def commit_prepared_transaction(transaction_id, opts=OPTS)
|
160
|
+
run("COMMIT PREPARED #{literal(transaction_id)}", opts)
|
161
161
|
end
|
162
162
|
|
163
163
|
# Creates the function in the database. Arguments:
|
@@ -426,8 +426,8 @@ module Sequel
|
|
426
426
|
|
427
427
|
# Rollback an existing prepared transaction with the given transaction
|
428
428
|
# identifier string.
|
429
|
-
def rollback_prepared_transaction(transaction_id)
|
430
|
-
run("ROLLBACK PREPARED #{literal(transaction_id)}")
|
429
|
+
def rollback_prepared_transaction(transaction_id, opts=OPTS)
|
430
|
+
run("ROLLBACK PREPARED #{literal(transaction_id)}", opts)
|
431
431
|
end
|
432
432
|
|
433
433
|
# PostgreSQL uses SERIAL psuedo-type instead of AUTOINCREMENT for
|
@@ -230,11 +230,29 @@ module Sequel
|
|
230
230
|
# various cases.
|
231
231
|
def fetch_rows(sql)
|
232
232
|
execute(sql) do |result|
|
233
|
-
|
234
|
-
if
|
235
|
-
|
233
|
+
columns = result.fields.map!{|c| output_identifier(c)}
|
234
|
+
if columns.empty?
|
235
|
+
args = []
|
236
|
+
args << {:timezone=>:utc} if db.timezone == :utc
|
237
|
+
cols = nil
|
238
|
+
result.each(*args) do |r|
|
239
|
+
unless cols
|
240
|
+
cols = result.fields.map{|c| [c, output_identifier(c)]}
|
241
|
+
@columns = columns = cols.map{|c| c.last}
|
242
|
+
end
|
243
|
+
h = {}
|
244
|
+
cols.each do |s, sym|
|
245
|
+
h[sym] = r[s]
|
246
|
+
end
|
247
|
+
yield h
|
248
|
+
end
|
236
249
|
else
|
237
|
-
|
250
|
+
@columns = columns
|
251
|
+
if db.timezone == :utc
|
252
|
+
result.each(:timezone=>:utc){|r| yield r}
|
253
|
+
else
|
254
|
+
result.each{|r| yield r}
|
255
|
+
end
|
238
256
|
end
|
239
257
|
end
|
240
258
|
self
|
@@ -9,8 +9,9 @@ module Sequel
|
|
9
9
|
# If offset is used, an order must be provided, because the use of ROW_NUMBER
|
10
10
|
# requires an order.
|
11
11
|
def select_sql
|
12
|
-
return super unless
|
12
|
+
return super unless emulate_offset_with_row_number?
|
13
13
|
|
14
|
+
offset = @opts[:offset]
|
14
15
|
order = @opts[:order]
|
15
16
|
if require_offset_order?
|
16
17
|
order ||= default_offset_order
|
@@ -29,7 +30,7 @@ module Sequel
|
|
29
30
|
from_self(:alias=>dsa1).
|
30
31
|
select(*columns).
|
31
32
|
limit(@opts[:limit]).
|
32
|
-
where(SQL::Identifier.new(rn) >
|
33
|
+
where(SQL::Identifier.new(rn) > offset).
|
33
34
|
order(rn))
|
34
35
|
sql
|
35
36
|
end
|
@@ -46,5 +47,10 @@ module Sequel
|
|
46
47
|
def require_offset_order?
|
47
48
|
true
|
48
49
|
end
|
50
|
+
|
51
|
+
# Whether to use ROW_NUMBER to emulate offsets
|
52
|
+
def emulate_offset_with_row_number?
|
53
|
+
@opts[:offset]
|
54
|
+
end
|
49
55
|
end
|
50
56
|
end
|