sequel 4.6.0 → 4.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +32 -0
  3. data/doc/association_basics.rdoc +18 -0
  4. data/doc/migration.rdoc +30 -0
  5. data/doc/release_notes/4.7.0.txt +103 -0
  6. data/doc/security.rdoc +5 -0
  7. data/doc/sql.rdoc +21 -12
  8. data/doc/validations.rdoc +10 -2
  9. data/doc/virtual_rows.rdoc +22 -29
  10. data/lib/sequel/adapters/jdbc.rb +4 -1
  11. data/lib/sequel/adapters/jdbc/h2.rb +5 -0
  12. data/lib/sequel/adapters/odbc.rb +0 -1
  13. data/lib/sequel/adapters/postgres.rb +8 -1
  14. data/lib/sequel/adapters/shared/db2.rb +5 -0
  15. data/lib/sequel/adapters/shared/mssql.rb +1 -1
  16. data/lib/sequel/adapters/shared/oracle.rb +5 -0
  17. data/lib/sequel/adapters/shared/postgres.rb +5 -0
  18. data/lib/sequel/adapters/shared/sqlanywhere.rb +1 -1
  19. data/lib/sequel/adapters/shared/sqlite.rb +6 -1
  20. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +1 -1
  21. data/lib/sequel/database/schema_methods.rb +1 -0
  22. data/lib/sequel/database/transactions.rb +11 -26
  23. data/lib/sequel/dataset/actions.rb +3 -3
  24. data/lib/sequel/dataset/features.rb +5 -0
  25. data/lib/sequel/dataset/sql.rb +16 -1
  26. data/lib/sequel/model/associations.rb +22 -7
  27. data/lib/sequel/model/base.rb +2 -2
  28. data/lib/sequel/plugins/auto_validations.rb +5 -1
  29. data/lib/sequel/plugins/instance_hooks.rb +21 -3
  30. data/lib/sequel/plugins/pg_array_associations.rb +21 -5
  31. data/lib/sequel/plugins/update_or_create.rb +60 -0
  32. data/lib/sequel/plugins/validation_helpers.rb +5 -2
  33. data/lib/sequel/sql.rb +55 -9
  34. data/lib/sequel/version.rb +1 -1
  35. data/spec/adapters/postgres_spec.rb +25 -4
  36. data/spec/core/database_spec.rb +1 -1
  37. data/spec/core/dataset_spec.rb +1 -1
  38. data/spec/core/expression_filters_spec.rb +53 -1
  39. data/spec/extensions/auto_validations_spec.rb +18 -0
  40. data/spec/extensions/instance_hooks_spec.rb +14 -0
  41. data/spec/extensions/pg_array_associations_spec.rb +40 -0
  42. data/spec/extensions/to_dot_spec.rb +1 -1
  43. data/spec/extensions/update_or_create_spec.rb +81 -0
  44. data/spec/extensions/validation_helpers_spec.rb +15 -11
  45. data/spec/integration/associations_test.rb +1 -1
  46. data/spec/integration/database_test.rb +8 -0
  47. data/spec/integration/dataset_test.rb +15 -10
  48. data/spec/integration/type_test.rb +4 -0
  49. data/spec/model/associations_spec.rb +20 -0
  50. data/spec/spec_config.rb +1 -1
  51. metadata +364 -360
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4da9d52fb246c1f0e83b88184dd82d4bf7b609cd
4
- data.tar.gz: 041e624b4f998ebc9835898be941fadc12fda8c4
3
+ metadata.gz: 4c36878b92e104f343cc1e7c92ff6e94026040c1
4
+ data.tar.gz: ee7e4399243acbbfa11e6f427fedb49684b2426f
5
5
  SHA512:
6
- metadata.gz: d965c77370235e2ceee16aca1e1193b01d2eb259b179307a51f8218778dda40c4fb35cea667568ce7cfa4d5f95297396a2876ae744d3638d359b81dfa63a019a
7
- data.tar.gz: 052c8d3db3bd66279b50cf455e6928eb9e753e49f273399f85d5d0e2fe238ecc33c97a1a95d1b56f5bca9cb670c1fedb9eeb95fdb68232ac032647eb370b7992
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)
@@ -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
@@ -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.
@@ -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
@@ -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{}} # SELECT func() FROM "albums"
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
- However, if you want to use the DISTINCT modifier to an aggregate function, you either have to use literal SQL or a virtual row block:
199
+ To use the DISTINCT modifier to an aggregate function, call the distinct method on the function:
200
200
 
201
- Sequel.function(:sum, Sequel.lit('DISTINCT column')) # sum(DISTINCT column)
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, you again have to use literal SQL or a virtual row block:
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, Sequel.lit('*')) # count(*)
207
- DB[:albums].select{count(:*){}} # SELECT count(*) FROM albums
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 using a virtual row block:
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(:over){}}
214
+ DB[:albums].select{function.function.over}
216
215
  # SELECT function() OVER () FROM albums
217
216
 
218
- DB[:albums].select{count(:over, :*=>true){}}
217
+ DB[:albums].select{count.function.*.over}
219
218
  # SELECT count(*) OVER () FROM albums
220
219
 
221
- DB[:albums].select{function(:over, :args=>col1, :partition=>col2, :order=>col3){}}
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(:over, :args=>[c1, c2], :partition=>[c3, c4], :order=>[c5, c6]){}}
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:
@@ -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, Sequel attempts to typecast values, but silently ignores any errors raised:
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
- Additionally, you can also include an optional options hash as the last argument. Unlike the other validations, the options hash for +validates_unique+ only checks for two options:
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
 
@@ -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, you need to provide an empty
144
- block to the method to distinguish it from a call that will produce an
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 (most often
152
- used with the count function), you should provide :* as the sole argument to
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, you need to make
160
- :distinct the first argument of the method call, and provide an empty block to
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(:distinct, o.col1){}}
164
- ds.select{count(:distinct, col1){}}
160
+ ds.select{|o| o.count(o.col1).distinct)}
161
+ ds.select{count(col1).distinct}
165
162
  # SELECT count(DISTINCT col1)
166
163
 
167
- To use multiple columns with the DISTINCT keyword, use multiple arguments in
168
- the method call:
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 need to make :over the first argument of the method
179
- call, with an optional hash as the second argument, and provide an empty block
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(:over){}}
183
- ds.select{rank(:over){}}
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(:over, :*=>true){}}
187
- ds.select{count(:over, :*=>true){}}
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(:over, :args=>o.col1, :partition=>o.col2, :order=>o.col3){}}
191
- ds.select{sum(:over, :args=>col1, :partition=>col2, :order=>col3){}}
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
@@ -497,7 +497,10 @@ module Sequel
497
497
  def get_tables(type, opts)
498
498
  ts = []
499
499
  m = output_identifier_meth
500
- metadata(:getTables, nil, nil, nil, [type].to_java(:string)){|h| ts << m.call(h[:table_name])}
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
 
@@ -223,6 +223,11 @@ module Sequel
223
223
  def select_clause_methods
224
224
  SELECT_CLAUSE_METHODS
225
225
  end
226
+
227
+ # H2 supports quoted function names.
228
+ def supports_quoted_function_names?
229
+ true
230
+ end
226
231
  end
227
232
  end
228
233
  end
@@ -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
- execute_ddl("CLOSE #{cursor_name}", server_opts)
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