sequel 4.6.0 → 4.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +32 -0
- data/doc/association_basics.rdoc +18 -0
- data/doc/migration.rdoc +30 -0
- data/doc/release_notes/4.7.0.txt +103 -0
- data/doc/security.rdoc +5 -0
- data/doc/sql.rdoc +21 -12
- data/doc/validations.rdoc +10 -2
- data/doc/virtual_rows.rdoc +22 -29
- data/lib/sequel/adapters/jdbc.rb +4 -1
- data/lib/sequel/adapters/jdbc/h2.rb +5 -0
- data/lib/sequel/adapters/odbc.rb +0 -1
- data/lib/sequel/adapters/postgres.rb +8 -1
- data/lib/sequel/adapters/shared/db2.rb +5 -0
- data/lib/sequel/adapters/shared/mssql.rb +1 -1
- data/lib/sequel/adapters/shared/oracle.rb +5 -0
- data/lib/sequel/adapters/shared/postgres.rb +5 -0
- data/lib/sequel/adapters/shared/sqlanywhere.rb +1 -1
- data/lib/sequel/adapters/shared/sqlite.rb +6 -1
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +1 -1
- data/lib/sequel/database/schema_methods.rb +1 -0
- data/lib/sequel/database/transactions.rb +11 -26
- data/lib/sequel/dataset/actions.rb +3 -3
- data/lib/sequel/dataset/features.rb +5 -0
- data/lib/sequel/dataset/sql.rb +16 -1
- data/lib/sequel/model/associations.rb +22 -7
- data/lib/sequel/model/base.rb +2 -2
- data/lib/sequel/plugins/auto_validations.rb +5 -1
- data/lib/sequel/plugins/instance_hooks.rb +21 -3
- data/lib/sequel/plugins/pg_array_associations.rb +21 -5
- data/lib/sequel/plugins/update_or_create.rb +60 -0
- data/lib/sequel/plugins/validation_helpers.rb +5 -2
- data/lib/sequel/sql.rb +55 -9
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/postgres_spec.rb +25 -4
- data/spec/core/database_spec.rb +1 -1
- data/spec/core/dataset_spec.rb +1 -1
- data/spec/core/expression_filters_spec.rb +53 -1
- data/spec/extensions/auto_validations_spec.rb +18 -0
- data/spec/extensions/instance_hooks_spec.rb +14 -0
- data/spec/extensions/pg_array_associations_spec.rb +40 -0
- data/spec/extensions/to_dot_spec.rb +1 -1
- data/spec/extensions/update_or_create_spec.rb +81 -0
- data/spec/extensions/validation_helpers_spec.rb +15 -11
- data/spec/integration/associations_test.rb +1 -1
- data/spec/integration/database_test.rb +8 -0
- data/spec/integration/dataset_test.rb +15 -10
- data/spec/integration/type_test.rb +4 -0
- data/spec/model/associations_spec.rb +20 -0
- data/spec/spec_config.rb +1 -1
- metadata +364 -360
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c36878b92e104f343cc1e7c92ff6e94026040c1
|
4
|
+
data.tar.gz: ee7e4399243acbbfa11e6f427fedb49684b2426f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: faea6910ec5976db18b931961ed086cd295560a7ea54227b9af0811ecb98e75d61ba34899bf0d762c67182dea1be980daf339cce65aad1e9fe06eb7365c43f84
|
7
|
+
data.tar.gz: d3f3b358199a9f624387f2218074b2d01e39e9a295504dc988dbb8e792155af32e26ac17ca5bbfd95fc3c2d5b7fc084edeab90fa0123b0c673952ec048d0d574
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,35 @@
|
|
1
|
+
=== 4.7.0 (2014-02-01)
|
2
|
+
|
3
|
+
* Don't swallow underlying exception if there is an exception closing the cursor on PostgreSQL (jeremyevans) (#761)
|
4
|
+
|
5
|
+
* Recognize primary key unique constraint violations on MSSQL and SQLAnywhere (jeremyevans)
|
6
|
+
|
7
|
+
* Recognize composite unique constraint violations on SQLite (timcraft) (#758)
|
8
|
+
|
9
|
+
* Make #* method without arguments on SQL::Function return a Function with * prepended to the arguments (jeremyevans)
|
10
|
+
|
11
|
+
* Add #function to SQL::Identifier and SQL::QualifiedIdentifier, allowing for easy use of schema qualified functions or functions names that need quoting (jeremyevans)
|
12
|
+
|
13
|
+
* Add SQL::Function#distinct for easier creation of aggregate functions using DISTINCT (jeremyevans)
|
14
|
+
|
15
|
+
* Add SQL::Function#over for easier creation of window functions (jeremyevans)
|
16
|
+
|
17
|
+
* Don't clear validation instance_hooks until after a successful save (jeremyevans)
|
18
|
+
|
19
|
+
* Support :raise_on_save_failure option for one_to_many, pg_array_to_many, and many_to_pg_array associations (jeremyevans)
|
20
|
+
|
21
|
+
* Make SQLTime#to_s return a string in HH:MM:SS format, since it shouldn't include date information (jeremyevans)
|
22
|
+
|
23
|
+
* Support the Database#tables :schema option in the jdbc adapter (robbiegill, jeremyevans) (#755)
|
24
|
+
|
25
|
+
* Automatically rollback transactions in killed threads in ruby 2.0+ (chanks) (#752)
|
26
|
+
|
27
|
+
* Add update_or_create plugin, for updating an object if it exists, or creating such an object if it does not (jeremyevans)
|
28
|
+
|
29
|
+
* Make auto_validations uniqueness validations work correctly for STI subclasses (jeremyevans)
|
30
|
+
|
31
|
+
* Support :dataset option to validates_unique vaildation (jeremyevans)
|
32
|
+
|
1
33
|
=== 4.6.0 (2014-01-02)
|
2
34
|
|
3
35
|
* Add Database#call_mssql_sproc on MSSQL for calling stored procedures and handling output parameters (jrgns, jeremyevans) (#748)
|
data/doc/association_basics.rdoc
CHANGED
@@ -689,6 +689,14 @@ The add_<i>association</i> method returns the now associated object:
|
|
689
689
|
|
690
690
|
@album = @artist.add_album(:name=>'RF')
|
691
691
|
|
692
|
+
Note that the add_* methods for +one_to_many+ persist the changes by
|
693
|
+
saving the passed in (or newly created) object. However, to avoid
|
694
|
+
silent failures of these methods, they explicitly raise exceptions
|
695
|
+
even when raise_on_save_failure is false for the associated model.
|
696
|
+
You can disable this behavior (i.e. return nil instead of raising
|
697
|
+
exceptions on a save failure) by setting the <tt>:raise_on_save_failure=>false</tt>
|
698
|
+
option for the association.
|
699
|
+
|
692
700
|
=== remove_<i>association</i>(object_to_disassociate) (e.g. remove_album) [+one_to_many+ and +many_to_many+]
|
693
701
|
|
694
702
|
The remove_<i>association</i> method disassociates the passed object from
|
@@ -1645,6 +1653,16 @@ add_<i>association</i> method, Sequel will automatically save the object.
|
|
1645
1653
|
If you don't want to validate objects when these implicit saves are done,
|
1646
1654
|
the validate option should be set to false.
|
1647
1655
|
|
1656
|
+
==== :raise_on_save_failure [+one_to_many+ associations]
|
1657
|
+
|
1658
|
+
Set to false to not raise an exception when validation or a before hook
|
1659
|
+
fails when implicitly saving an associated object in the add_* or remove_*
|
1660
|
+
methods. This mirrors the raise_on_save_failure model setting, which these
|
1661
|
+
methods do not respect (by design, since the setting is dangerous).
|
1662
|
+
|
1663
|
+
If you use this option, you must explicitly check all add_* and remove_* return
|
1664
|
+
values to see if they were successful.
|
1665
|
+
|
1648
1666
|
==== :allow_eager
|
1649
1667
|
|
1650
1668
|
If set to false, you cannot load the association eagerly via eager or
|
data/doc/migration.rdoc
CHANGED
@@ -482,6 +482,36 @@ depend on which migrations that have been applied. Applied migrations greater
|
|
482
482
|
than that version will be migrated down, while unapplied migrations less than
|
483
483
|
or equal to that version will be migrated up.
|
484
484
|
|
485
|
+
== Running migrations from a Rake task
|
486
|
+
|
487
|
+
You can also incorporate migrations into a Rakefile. Here's an example
|
488
|
+
using integer migration versions.
|
489
|
+
|
490
|
+
namespace :db do
|
491
|
+
desc "Run migrations"
|
492
|
+
task :migrate, [:version] do |t, args|
|
493
|
+
require "sequel"
|
494
|
+
Sequel.extension :migration
|
495
|
+
db = Sequel.connect(ENV.fetch("DATABASE_URL"))
|
496
|
+
if args[:version]
|
497
|
+
puts "Migrating to version #{args[:version]}"
|
498
|
+
Sequel::Migrator.run(db, "db/migrations", target: args[:version].to_i)
|
499
|
+
else
|
500
|
+
puts "Migrating to latest"
|
501
|
+
Sequel::Migrator.run(db, "db/migrations")
|
502
|
+
end
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
To migrate to the latest version, run:
|
507
|
+
|
508
|
+
rake db:migrate
|
509
|
+
|
510
|
+
This Rake task takes an optional argument specifying the target
|
511
|
+
version. To migrate to version 42, run:
|
512
|
+
|
513
|
+
rake db:migrate[42]
|
514
|
+
|
485
515
|
== Verbose migrations
|
486
516
|
|
487
517
|
By default, <tt>sequel -m</tt> operates as a well behaved command line utility
|
@@ -0,0 +1,103 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* Alternatives for the more complex virtual row method calls have
|
4
|
+
been added:
|
5
|
+
|
6
|
+
# Window Functions using SQL::Function#over
|
7
|
+
# before: select{sum(:over, :args=>:col1, :partition=>:col2){}}
|
8
|
+
select{sum(:col1).over(:partition=>:col2)}
|
9
|
+
|
10
|
+
# count(*) using SQL::Function#*
|
11
|
+
# before: select{count(:*){}}
|
12
|
+
select{count{}.*}
|
13
|
+
|
14
|
+
# count(distinct col) using SQL::Function#distinct
|
15
|
+
# before: select{count(:distinct, :col){}}
|
16
|
+
select{count(:col).distinct}
|
17
|
+
|
18
|
+
Additionally, schema qualified functions are now supported via
|
19
|
+
SQL::QualifiedIdentifier#function, and quoted functions are now
|
20
|
+
supported via SQL::Identifier#function on some databases:
|
21
|
+
|
22
|
+
# "func"("col")
|
23
|
+
select{func.function(:col)}
|
24
|
+
|
25
|
+
# "schema"."func"("col1")
|
26
|
+
select{schema__func.function(:col1)}
|
27
|
+
|
28
|
+
If the database does not support quoting function names, then
|
29
|
+
Sequel will not quote them.
|
30
|
+
|
31
|
+
* An update_or_create plugin has been added, for updating a matching
|
32
|
+
object if one exists, or creating an object if it does not. For
|
33
|
+
example, the following code will update the number of copies sold
|
34
|
+
for album with the name 'Hello', or it will create an album with
|
35
|
+
the name 'Hello' and 1000 number of copies sold:
|
36
|
+
|
37
|
+
Album.plugin :update_or_create
|
38
|
+
Album.update_or_create(:name=>'Hello') do |album|
|
39
|
+
album.num_copies_sold = 1000
|
40
|
+
end
|
41
|
+
|
42
|
+
You can also use a shorter form of this, with two hashes:
|
43
|
+
|
44
|
+
Album.update_or_create({:name=>'Hello'}, {:num_copies_sold=>1000})
|
45
|
+
|
46
|
+
This plugin also adds a method named find_or_new, which does the
|
47
|
+
same thing as update_or_create, except it doesn't persist any
|
48
|
+
changes.
|
49
|
+
|
50
|
+
* A :raise_on_save_failure option has been added for one_to_many,
|
51
|
+
pg_array_to_many, and many_to_pg_array associations. This mirrors
|
52
|
+
the Model.raise_on_save_failure setting, and if set to false, it
|
53
|
+
will make the add/remove methods return nil instead of raising
|
54
|
+
an error if there is a validation/hook error when saving the
|
55
|
+
associated record.
|
56
|
+
|
57
|
+
* The validates_unique validation in validation_helpers now supports a
|
58
|
+
:dataset option to provide the base dataset to use to check
|
59
|
+
uniqueness. This is useful when the model itself uses a filtered
|
60
|
+
dataset, but the unique index in the database is on an unfiltered
|
61
|
+
dataset.
|
62
|
+
|
63
|
+
The auto_validations plugin uses this option to ensure that unique
|
64
|
+
validations are setup correctly in subclasses using single table
|
65
|
+
inheritance.
|
66
|
+
|
67
|
+
= Other Improvements
|
68
|
+
|
69
|
+
* Sequel now automatically rolls back transactions in killed threads
|
70
|
+
on ruby 2.0+. It is still impossible to do so on ruby 1.9.
|
71
|
+
|
72
|
+
* In the instance_hooks plugin, validation instance hooks are now
|
73
|
+
not cleared until after a successful save.
|
74
|
+
|
75
|
+
* Composite unique key constraint violations are now recognized
|
76
|
+
and raised as Sequel::UniqueConstraintViolation on SQLite.
|
77
|
+
|
78
|
+
* Primary key unique constraint violations are now recognized and
|
79
|
+
and raised as Sequel::UniqueConstraintViolation on Microsoft
|
80
|
+
SQL Server and SQLAnywhere.
|
81
|
+
|
82
|
+
* If an exception occurs when using a cursor in the postgres adapter,
|
83
|
+
and an exception also occurs when closing the cursor when cleaning
|
84
|
+
up, the initial exception is now raised.
|
85
|
+
|
86
|
+
* You can now get tables in a specific schema in the jdbc adapter
|
87
|
+
using the :schema option to Database#tables. This was already
|
88
|
+
supported in most jdbc subadapters because they implement #tables
|
89
|
+
using database specific code instead of looking at the JDBC
|
90
|
+
metadata, but it should now work for all jdbc subadapters.
|
91
|
+
|
92
|
+
* Sequel::SQLTime#to_s is now defined and returns a string in
|
93
|
+
HH:MM:SS format (leaving off the date).
|
94
|
+
|
95
|
+
= Backwards Compatibility
|
96
|
+
|
97
|
+
* The odbc adapter's :driver option is no longer deprecated, as reports
|
98
|
+
were received that it still works.
|
99
|
+
|
100
|
+
* If you were re-adding instance validation hooks using instance_hooks
|
101
|
+
after a save failure, and then retrying the save, you may now end up
|
102
|
+
with duplicate validations. You no longer need to re-add validation
|
103
|
+
hooks unless the object was saved successfully.
|
data/doc/security.rdoc
CHANGED
@@ -175,6 +175,11 @@ be specified by the user, it allows you to use a ruby string, and that
|
|
175
175
|
string is used verbatim as the SQL type. You should not use user input
|
176
176
|
for type strings.
|
177
177
|
|
178
|
+
==== SQL Function Names
|
179
|
+
|
180
|
+
In most cases, Sequel does not quote SQL function names. You should not use
|
181
|
+
user input for function names.
|
182
|
+
|
178
183
|
=== SQL Identifier Injections
|
179
184
|
|
180
185
|
Usually, Sequel treats ruby symbols as SQL identifiers, and ruby
|
data/doc/sql.rdoc
CHANGED
@@ -182,7 +182,7 @@ You can also use the <tt>Sequel.as</tt> method to create an alias, and the +as+
|
|
182
182
|
|
183
183
|
The easiest way to use SQL functions is via a virtual row:
|
184
184
|
|
185
|
-
DB[:albums].select{func
|
185
|
+
DB[:albums].select{func.function} # SELECT func() FROM "albums"
|
186
186
|
DB[:albums].select{func(col1, col2)} # SELECT func("col1", "col2") FROM "albums"
|
187
187
|
|
188
188
|
You can also use the <tt>Sequel.function</tt> method on the symbol that contains the function name:
|
@@ -196,34 +196,43 @@ Aggregate functions work the same way as normal functions, since they share the
|
|
196
196
|
|
197
197
|
Sequel.function(:sum, :column) # sum(column)
|
198
198
|
|
199
|
-
|
199
|
+
To use the DISTINCT modifier to an aggregate function, call the distinct method on the function:
|
200
200
|
|
201
|
-
|
202
|
-
DB[:albums].select{sum(:distinct, :column){}} # SELECT sum(DISTINCT column) FROM albums
|
201
|
+
DB[:albums].select{sum(:column).distinct} # SELECT sum(DISTINCT column) FROM albums
|
203
202
|
|
204
|
-
If you want to use the wildcard as the sole argument of the aggregate function,
|
203
|
+
If you want to use the wildcard as the sole argument of the aggregate function, use the * method on the Function:
|
205
204
|
|
206
|
-
Sequel.function(:count
|
207
|
-
DB[:albums].select{count
|
205
|
+
Sequel.function(:count).* # count(*)
|
206
|
+
DB[:albums].select{count.function.*} # SELECT count(*) FROM albums
|
208
207
|
|
209
208
|
Note that Sequel provides helper methods for aggregate functions such as +count+, +sum+, +min+, +max+, +avg+, and +group_and_count+, which handle common uses of aggregate functions.
|
210
209
|
|
211
210
|
=== Window Functions
|
212
211
|
|
213
|
-
If the database supports window functions, Sequel can handle them
|
212
|
+
If the database supports window functions, Sequel can handle them by calling the over method on a Function:
|
214
213
|
|
215
|
-
DB[:albums].select{function
|
214
|
+
DB[:albums].select{function.function.over}
|
216
215
|
# SELECT function() OVER () FROM albums
|
217
216
|
|
218
|
-
DB[:albums].select{count
|
217
|
+
DB[:albums].select{count.function.*.over}
|
219
218
|
# SELECT count(*) OVER () FROM albums
|
220
219
|
|
221
|
-
DB[:albums].select{function(:over
|
220
|
+
DB[:albums].select{function(:col1).over(:partition=>col2, :order=>col3)}
|
222
221
|
# SELECT function(col1) OVER (PARTITION BY col2 ORDER BY col3) FROM albums
|
223
222
|
|
224
|
-
DB[:albums].select{function(
|
223
|
+
DB[:albums].select{function(c1, c2).over(:partition=>[c3, c4], :order=>[c5, c6])}
|
225
224
|
# SELECT function(c1, c2) OVER (PARTITION BY c3, c4 ORDER BY c5, c6) FROM albums
|
226
225
|
|
226
|
+
=== Schema Qualified Functions
|
227
|
+
|
228
|
+
If the database supports schema qualified functions, Sequel can handle them by calling the function method on a QuailfiedIdentifier:
|
229
|
+
|
230
|
+
DB[:albums].select{schema__function.function}
|
231
|
+
# SELECT schema.function() FROM albums
|
232
|
+
|
233
|
+
DB[:albums].select{schema__function.function(col, 2, "a")}
|
234
|
+
# SELECT schema.function(col, 2, 'a') FROM albums
|
235
|
+
|
227
236
|
=== Equality Operator (=)
|
228
237
|
|
229
238
|
Sequel uses hashes to specify equality:
|
data/doc/validations.rdoc
CHANGED
@@ -245,7 +245,7 @@ These methods check that the specified attributes can be valid integers or valid
|
|
245
245
|
|
246
246
|
=== +validates_schema_types+
|
247
247
|
|
248
|
-
+validates_schema_types+ uses the database metadata for the model's table to determine which ruby type(s) should be used for the given database type, and calls +validates_type+ with that ruby type. It's designed to be used with the <tt>raise_on_typecast_failure = false</tt> setting (the default starting in Sequel 4). <tt>raise_on_typecast_failure = false</tt
|
248
|
+
+validates_schema_types+ uses the database metadata for the model's table to determine which ruby type(s) should be used for the given database type, and calls +validates_type+ with that ruby type. It's designed to be used with the <tt>raise_on_typecast_failure = false</tt> setting (the default starting in Sequel 4). <tt>raise_on_typecast_failure = false</tt>, Sequel attempts to typecast values, but silently ignores any errors raised:
|
249
249
|
|
250
250
|
Album.raise_on_typecast_failure = false
|
251
251
|
album = Album.new
|
@@ -294,10 +294,18 @@ You can mix and match the two approaches. For example, if all albums should hav
|
|
294
294
|
|
295
295
|
If you provide a block, it is called with the dataset to use for the uniqueness check, which you can then filter to scope the uniqueness validation to a subset of the model's dataset.
|
296
296
|
|
297
|
-
|
297
|
+
You can also include an options hash as the last argument. Unlike the other validations, the options hash for +validates_unique+ only recognizes for these options:
|
298
298
|
|
299
|
+
:dataset :: The base dataset to use for the unique query, defaults to the model's dataset
|
299
300
|
:message :: The message to use
|
300
301
|
:only_if_modified :: Only check the uniqueness if the object is new or one of the columns has been modified.
|
302
|
+
:where :: A callable object where call takes three arguments, a dataset,
|
303
|
+
the current object, and an array of columns, and should return
|
304
|
+
a modified dataset that is filtered to include only rows with
|
305
|
+
the same values as the current object for each column in the array.
|
306
|
+
This is useful any time the unique constraints are derived from
|
307
|
+
the columns and not the columns themselves (such as unique constraints
|
308
|
+
on lower(column)).
|
301
309
|
|
302
310
|
+validates_unique+ is the only method in +validation_helpers+ that checks with the database. Attempting to validate uniqueness outside of the database suffers from a race condition, so any time you want to add a uniqueness validation, you should make sure to add a uniqueness constraint or unique index on the underlying database table. See the {"Migrations and Schema Modification" guide}[rdoc-ref:doc/migration.rdoc] for details on how to do that.
|
303
311
|
|
data/doc/virtual_rows.rdoc
CHANGED
@@ -140,55 +140,48 @@ your function call:
|
|
140
140
|
ds.where{function(1, a) > 1}
|
141
141
|
# WHERE function(1, a) > 1
|
142
142
|
|
143
|
-
If the SQL function does not accept any arguments,
|
144
|
-
|
145
|
-
SQL::Identifier:
|
143
|
+
If the SQL function does not accept any arguments, create an identifier, then
|
144
|
+
call the function method on it to produce a function:
|
146
145
|
|
147
|
-
ds.select{|o| o.version
|
148
|
-
ds.select{version
|
146
|
+
ds.select{|o| o.version.function}
|
147
|
+
ds.select{version.function}
|
149
148
|
# SELECT version()
|
150
149
|
|
151
|
-
To use the SQL wildcard (*) as the sole argument in a function call
|
152
|
-
|
153
|
-
the method, and provide an empty block to the method:
|
150
|
+
To use the SQL wildcard (*) as the sole argument in a function call, create a
|
151
|
+
function without arguments, then call the * method on the function:
|
154
152
|
|
155
|
-
ds.select{|o| o.count
|
156
|
-
ds.select{count
|
153
|
+
ds.select{|o| o.count.function.*}
|
154
|
+
ds.select{count.function.*}
|
157
155
|
# SELECT count(*)
|
158
156
|
|
159
|
-
To append the DISTINCT keyword before the method arguments,
|
160
|
-
|
161
|
-
the method:
|
157
|
+
To append the DISTINCT keyword before the method arguments, just call the
|
158
|
+
distinct method on the returned Function:
|
162
159
|
|
163
|
-
ds.select{|o| o.count(
|
164
|
-
ds.select{count(
|
160
|
+
ds.select{|o| o.count(o.col1).distinct)}
|
161
|
+
ds.select{count(col1).distinct}
|
165
162
|
# SELECT count(DISTINCT col1)
|
166
163
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
ds.select{|o| o.count(:distinct, o.col1, o.col2){}}
|
171
|
-
ds.select{count(:distinct, col1, col2){}}
|
164
|
+
ds.select{|o| o.count(o.col1, o.col2).distinct}
|
165
|
+
ds.select{count(col1, col2).distinct}
|
172
166
|
# SELECT count(DISTINCT col1, col2)
|
173
167
|
|
174
168
|
== SQL::WindowFunctions - SQL window function calls
|
175
169
|
|
176
170
|
SQL::WindowFunctions can be thought of as calls to SQL window functions. Not
|
177
171
|
all databases support them, but they are very helpful for certain types of
|
178
|
-
queries. To use them, you
|
179
|
-
|
180
|
-
to the method. Here are some examples of use:
|
172
|
+
queries. To use them, you should just call the over method on the Function
|
173
|
+
object returned, with the options for the window:
|
181
174
|
|
182
|
-
ds.select{|o| o.rank
|
183
|
-
ds.select{rank
|
175
|
+
ds.select{|o| o.rank.function.over}
|
176
|
+
ds.select{rank.function.over}
|
184
177
|
# SELECT rank() OVER ()
|
185
178
|
|
186
|
-
ds.select{|o| o.count
|
187
|
-
ds.select{count
|
179
|
+
ds.select{|o| o.count.function.*.over}
|
180
|
+
ds.select{count.function.*.over}
|
188
181
|
# SELECT count(*) OVER ()
|
189
182
|
|
190
|
-
ds.select{|o| o.sum(
|
191
|
-
ds.select{sum(
|
183
|
+
ds.select{|o| o.sum(o.col1).over(:partition=>o.col2, :order=>o.col3)}
|
184
|
+
ds.select{sum(col1).over(:partition=>col2, :order=>col3)}
|
192
185
|
# SELECT sum(col1) OVER (PARTITION BY col2 ORDER BY col3)
|
193
186
|
|
194
187
|
== Operators
|
data/lib/sequel/adapters/jdbc.rb
CHANGED
@@ -497,7 +497,10 @@ module Sequel
|
|
497
497
|
def get_tables(type, opts)
|
498
498
|
ts = []
|
499
499
|
m = output_identifier_meth
|
500
|
-
|
500
|
+
if schema = opts[:schema]
|
501
|
+
schema = schema.to_s
|
502
|
+
end
|
503
|
+
metadata(:getTables, nil, schema, nil, [type].to_java(:string)){|h| ts << m.call(h[:table_name])}
|
501
504
|
ts
|
502
505
|
end
|
503
506
|
|
data/lib/sequel/adapters/odbc.rb
CHANGED
@@ -14,7 +14,6 @@ module Sequel
|
|
14
14
|
conn = if opts.include?(:drvconnect)
|
15
15
|
::ODBC::Database.new.drvconnect(opts[:drvconnect])
|
16
16
|
elsif opts.include?(:driver)
|
17
|
-
Deprecation.deprecate("The odbc driver's handling of the :driver option is thought to be broken and will probably be removed in the future. If you are successfully using it, please contact the developers.")
|
18
17
|
drv = ::ODBC::Driver.new
|
19
18
|
drv.name = 'Sequel ODBC Driver130'
|
20
19
|
opts.each do |param, value|
|
@@ -780,8 +780,15 @@ module Sequel
|
|
780
780
|
return if res.ntuples < rows_per_fetch
|
781
781
|
end
|
782
782
|
end
|
783
|
+
rescue Exception => e
|
784
|
+
raise
|
783
785
|
ensure
|
784
|
-
|
786
|
+
begin
|
787
|
+
execute_ddl("CLOSE #{cursor_name}", server_opts)
|
788
|
+
rescue
|
789
|
+
raise e if e
|
790
|
+
raise
|
791
|
+
end
|
785
792
|
end
|
786
793
|
end
|
787
794
|
end
|