sequel 3.25.0 → 3.26.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/CHANGELOG +28 -0
  2. data/README.rdoc +3 -3
  3. data/Rakefile +17 -11
  4. data/doc/release_notes/3.26.0.txt +88 -0
  5. data/lib/sequel/adapters/ado.rb +10 -0
  6. data/lib/sequel/adapters/do.rb +12 -0
  7. data/lib/sequel/adapters/jdbc.rb +6 -6
  8. data/lib/sequel/adapters/mysql.rb +8 -2
  9. data/lib/sequel/adapters/mysql2.rb +5 -1
  10. data/lib/sequel/adapters/odbc.rb +10 -2
  11. data/lib/sequel/adapters/oracle.rb +5 -1
  12. data/lib/sequel/adapters/postgres.rb +10 -4
  13. data/lib/sequel/adapters/shared/access.rb +11 -0
  14. data/lib/sequel/adapters/shared/oracle.rb +0 -4
  15. data/lib/sequel/adapters/shared/postgres.rb +0 -12
  16. data/lib/sequel/adapters/tinytds.rb +9 -0
  17. data/lib/sequel/connection_pool.rb +1 -1
  18. data/lib/sequel/connection_pool/threaded.rb +3 -2
  19. data/lib/sequel/core.rb +1 -1
  20. data/lib/sequel/database/connecting.rb +3 -3
  21. data/lib/sequel/database/dataset.rb +1 -1
  22. data/lib/sequel/database/dataset_defaults.rb +1 -1
  23. data/lib/sequel/database/logging.rb +1 -1
  24. data/lib/sequel/database/misc.rb +23 -6
  25. data/lib/sequel/database/query.rb +16 -15
  26. data/lib/sequel/database/schema_methods.rb +21 -16
  27. data/lib/sequel/dataset/actions.rb +19 -16
  28. data/lib/sequel/dataset/features.rb +8 -2
  29. data/lib/sequel/dataset/graph.rb +1 -1
  30. data/lib/sequel/dataset/misc.rb +29 -9
  31. data/lib/sequel/dataset/mutation.rb +3 -3
  32. data/lib/sequel/dataset/prepared_statements.rb +11 -11
  33. data/lib/sequel/dataset/query.rb +28 -7
  34. data/lib/sequel/dataset/sql.rb +2 -2
  35. data/lib/sequel/extensions/migration.rb +1 -0
  36. data/lib/sequel/model.rb +5 -4
  37. data/lib/sequel/model/associations.rb +487 -328
  38. data/lib/sequel/model/base.rb +43 -26
  39. data/lib/sequel/model/exceptions.rb +2 -0
  40. data/lib/sequel/plugins/identity_map.rb +111 -4
  41. data/lib/sequel/plugins/sharding.rb +12 -20
  42. data/lib/sequel/plugins/xml_serializer.rb +2 -2
  43. data/lib/sequel/version.rb +1 -1
  44. data/spec/adapters/postgres_spec.rb +0 -6
  45. data/spec/core/connection_pool_spec.rb +6 -0
  46. data/spec/core/database_spec.rb +12 -0
  47. data/spec/core/schema_spec.rb +9 -2
  48. data/spec/extensions/identity_map_spec.rb +162 -0
  49. data/spec/extensions/many_through_many_spec.rb +3 -19
  50. data/spec/extensions/xml_serializer_spec.rb +4 -4
  51. data/spec/model/eager_loading_spec.rb +7 -21
  52. data/spec/model/record_spec.rb +23 -0
  53. metadata +36 -34
@@ -43,6 +43,17 @@ module Sequel
43
43
 
44
44
  private
45
45
 
46
+ # Access uses # to quote dates
47
+ def literal_date(d)
48
+ d.strftime('#%Y-%m-%d#')
49
+ end
50
+
51
+ # Access uses # to quote datetimes
52
+ def literal_datetime(t)
53
+ t.strftime('#%Y-%m-%d %H:%M:%S#')
54
+ end
55
+ alias literal_time literal_datetime
56
+
46
57
  # Access uses TOP for limits
47
58
  def select_limit_sql(sql)
48
59
  sql << " TOP #{@opts[:limit]}" if @opts[:limit]
@@ -26,10 +26,6 @@ module Sequel
26
26
  ds.map{|r| ds.send(:output_identifier, r[:tname])}
27
27
  end
28
28
 
29
- def table_exists?(name)
30
- from(:tab).filter(:tname =>dataset.send(:input_identifier, name), :tabtype => 'TABLE').count > 0
31
- end
32
-
33
29
  def views(opts={})
34
30
  ds = from(:tab).server(opts[:server]).select(:tname).filter(:tabtype => 'VIEW')
35
31
  ds.map{|r| ds.send(:output_identifier, r[:tname])}
@@ -368,18 +368,6 @@ module Sequel
368
368
  true
369
369
  end
370
370
 
371
- # Whether the given table exists in the database
372
- #
373
- # Options:
374
- # * :schema - The schema to search (default_schema by default)
375
- # * :server - The server to use
376
- def table_exists?(table, opts={})
377
- im = input_identifier_meth
378
- schema, table = schema_and_table(table)
379
- opts[:schema] ||= schema
380
- tables(opts){|ds| !ds.first(:relname=>im.call(table)).nil?}
381
- end
382
-
383
371
  # Array of symbols specifying table names in the current database.
384
372
  # The dataset used is yielded to the block if one is provided,
385
373
  # otherwise, an array of symbols of table names is returned.
@@ -74,10 +74,19 @@ module Sequel
74
74
  super
75
75
  end
76
76
 
77
+ # tiny_tds uses TinyTds::Error as the base error class.
78
+ def database_error_classes
79
+ [TinyTds::Error]
80
+ end
81
+
77
82
  # Close the TinyTds::Client object.
78
83
  def disconnect_connection(c)
79
84
  c.close
80
85
  end
86
+
87
+ def disconnect_error?(e, opts)
88
+ super || (opts[:conn] && !opts[:conn].active?)
89
+ end
81
90
  end
82
91
 
83
92
  class Dataset < Sequel::Dataset
@@ -53,7 +53,7 @@ class Sequel::ConnectionPool
53
53
 
54
54
  # Return a connection pool class based on the given options.
55
55
  def connection_pool_class(opts)
56
- opts[:pool_class] || CONNECTION_POOL_MAP[[!!opts[:single_threaded], !!opts[:servers]]]
56
+ CONNECTION_POOL_MAP[opts[:pool_class]] || opts[:pool_class] || CONNECTION_POOL_MAP[[!!opts[:single_threaded], !!opts[:servers]]]
57
57
  end
58
58
  end
59
59
  extend ClassMethods
@@ -83,9 +83,10 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
83
83
  end
84
84
  yield conn
85
85
  rescue Sequel::DatabaseDisconnectError
86
- @disconnection_proc.call(conn) if @disconnection_proc && conn
87
- @allocated.delete(t)
86
+ oconn = conn
88
87
  conn = nil
88
+ @disconnection_proc.call(oconn) if @disconnection_proc && oconn
89
+ @allocated.delete(t)
89
90
  raise
90
91
  ensure
91
92
  sync{release(t)} if conn
data/lib/sequel/core.rb CHANGED
@@ -230,7 +230,7 @@ module Sequel
230
230
 
231
231
  # Converts the given +string+ into a +Time+ object.
232
232
  #
233
- # Sequel.string_to_datetime('10:20:30') # Time.parse('10:20:30')
233
+ # Sequel.string_to_time('10:20:30') # Time.parse('10:20:30')
234
234
  def self.string_to_time(string)
235
235
  begin
236
236
  Time.parse(string)
@@ -1,7 +1,7 @@
1
1
  module Sequel
2
2
  class Database
3
3
  # ---------------------
4
- # :section: Methods relating to adapters, connecting, disconnecting, and sharding
4
+ # :section: 4 - Methods relating to adapters, connecting, disconnecting, and sharding
5
5
  # This methods involve the Database's connection pool.
6
6
  # ---------------------
7
7
 
@@ -155,8 +155,8 @@ module Sequel
155
155
 
156
156
  # Disconnects all available connections from the connection pool. Any
157
157
  # connections currently in use will not be disconnected. Options:
158
- # * :servers - Should be a symbol specifing the server to disconnect from,
159
- # or an array of symbols to specify multiple servers.
158
+ # :servers :: Should be a symbol specifing the server to disconnect from,
159
+ # or an array of symbols to specify multiple servers.
160
160
  #
161
161
  # Example:
162
162
  #
@@ -1,7 +1,7 @@
1
1
  module Sequel
2
2
  class Database
3
3
  # ---------------------
4
- # :section: Methods that create datasets
4
+ # :section: 3 - Methods that create datasets
5
5
  # These methods all return instances of this database's dataset class.
6
6
  # ---------------------
7
7
 
@@ -1,7 +1,7 @@
1
1
  module Sequel
2
2
  class Database
3
3
  # ---------------------
4
- # :section: Methods that set defaults for created datasets
4
+ # :section: 5 - Methods that set defaults for created datasets
5
5
  # This methods change the default behavior of this database's datasets.
6
6
  # ---------------------
7
7
 
@@ -1,7 +1,7 @@
1
1
  module Sequel
2
2
  class Database
3
3
  # ---------------------
4
- # :section: Methods relating to logging
4
+ # :section: 6 - Methods relating to logging
5
5
  # This methods affect relating to the logging of executed SQL.
6
6
  # ---------------------
7
7
 
@@ -1,13 +1,13 @@
1
1
  module Sequel
2
2
  class Database
3
3
  # ---------------------
4
- # :section: Miscellaneous methods
4
+ # :section: 7 - Miscellaneous methods
5
5
  # These methods don't fit neatly into another category.
6
6
  # ---------------------
7
7
 
8
8
  # Converts a uri to an options hash. These options are then passed
9
9
  # to a newly created database object.
10
- def self.uri_to_options(uri) # :nodoc:
10
+ def self.uri_to_options(uri)
11
11
  { :user => uri.user,
12
12
  :password => uri.password,
13
13
  :host => uri.host,
@@ -181,12 +181,17 @@ module Sequel
181
181
  def database_error_classes
182
182
  []
183
183
  end
184
+
185
+ # Return true if exception represents a disconnect error, false otherwise.
186
+ def disconnect_error?(exception, opts)
187
+ opts[:disconnect]
188
+ end
184
189
 
185
190
  # Convert the given exception to a DatabaseError, keeping message
186
191
  # and traceback.
187
192
  def raise_error(exception, opts={})
188
193
  if !opts[:classes] || Array(opts[:classes]).any?{|c| exception.is_a?(c)}
189
- raise Sequel.convert_exception_class(exception, opts[:disconnect] ? DatabaseDisconnectError : DatabaseError)
194
+ raise Sequel.convert_exception_class(exception, disconnect_error?(exception, opts) ? DatabaseDisconnectError : DatabaseError)
190
195
  else
191
196
  raise exception
192
197
  end
@@ -250,9 +255,21 @@ module Sequel
250
255
  Float(value)
251
256
  end
252
257
 
253
- # Typecast the value to an Integer
254
- def typecast_value_integer(value)
255
- Integer(value)
258
+ # Used for checking/removing leading zeroes from strings so they don't get
259
+ # interpreted as octal.
260
+ LEADING_ZERO_RE = /\A0+(\d)/.freeze
261
+ if RUBY_VERSION >= '1.9'
262
+ # Typecast the value to an Integer
263
+ def typecast_value_integer(value)
264
+ (value.is_a?(String) && value =~ LEADING_ZERO_RE) ? Integer(value, 10) : Integer(value)
265
+ end
266
+ else
267
+ # Replacement string when replacing leading zeroes.
268
+ LEADING_ZERO_REP = "\\1".freeze
269
+ # Typecast the value to an Integer
270
+ def typecast_value_integer(value)
271
+ Integer(value.is_a?(String) ? value.sub(LEADING_ZERO_RE, LEADING_ZERO_REP) : value)
272
+ end
256
273
  end
257
274
 
258
275
  # Typecast the value to a String
@@ -1,7 +1,7 @@
1
1
  module Sequel
2
2
  class Database
3
3
  # ---------------------
4
- # :section: Methods that execute queries and/or return results
4
+ # :section: 1 - Methods that execute queries and/or return results
5
5
  # This methods generally execute SQL code on the database server.
6
6
  # ---------------------
7
7
 
@@ -82,12 +82,12 @@ module Sequel
82
82
  #
83
83
  # DB.get(1) # SELECT 1
84
84
  # # => 1
85
- # DB.get{version{}} # SELECT server_version()
85
+ # DB.get{server_version{}} # SELECT server_version()
86
86
  def get(*args, &block)
87
87
  dataset.get(*args, &block)
88
88
  end
89
89
 
90
- # Return a hash containing index information. Hash keys are index name symbols.
90
+ # Return a hash containing index information for the table. Hash keys are index name symbols.
91
91
  # Values are subhashes with two keys, :columns and :unique. The value of :columns
92
92
  # is an array of symbols of column names. The value of :unique is true or false
93
93
  # depending on if the index is unique.
@@ -110,7 +110,6 @@ module Sequel
110
110
  nil
111
111
  end
112
112
 
113
- # Parse the schema from the database.
114
113
  # Returns the schema for the given table as an array with all members being arrays of length 2,
115
114
  # the first member being the column name, and the second member being a hash of column information.
116
115
  # Available options are:
@@ -129,7 +128,8 @@ module Sequel
129
128
  # it means that primary key information is unavailable, not that the column
130
129
  # is not a primary key.
131
130
  # :ruby_default :: The database default for the column, as a ruby object. In many cases, complex
132
- # database defaults cannot be parsed into ruby objects.
131
+ # database defaults cannot be parsed into ruby objects, in which case nil will be
132
+ # used as the value.
133
133
  # :type :: A symbol specifying the type, such as :integer or :string.
134
134
  #
135
135
  # Example:
@@ -169,13 +169,14 @@ module Sequel
169
169
  # to the database.
170
170
  #
171
171
  # DB.table_exists?(:foo) # => false
172
+ # # SELECT * FROM foo LIMIT 1
172
173
  def table_exists?(name)
173
- begin
174
- from(name).first
175
- true
176
- rescue
177
- false
178
- end
174
+ sch, table_name = schema_and_table(name)
175
+ name = SQL::QualifiedIdentifier.new(sch, table_name) if sch
176
+ from(name).first
177
+ true
178
+ rescue
179
+ false
179
180
  end
180
181
 
181
182
  # Return all tables in the database as an array of symbols.
@@ -230,12 +231,12 @@ module Sequel
230
231
  yield(conn)
231
232
  rescue Exception => e
232
233
  rollback_transaction(t, opts) if t
233
- transaction_error(e)
234
+ transaction_error(e, :conn=>conn)
234
235
  ensure
235
236
  begin
236
237
  commit_or_rollback_transaction(e, t, opts)
237
238
  rescue Exception => e
238
- raise_error(e, :classes=>database_error_classes)
239
+ raise_error(e, :classes=>database_error_classes, :conn=>conn)
239
240
  ensure
240
241
  remove_transaction(t)
241
242
  end
@@ -490,8 +491,8 @@ module Sequel
490
491
  end
491
492
 
492
493
  # Raise a database error unless the exception is an Rollback.
493
- def transaction_error(e)
494
- raise_error(e, :classes=>database_error_classes) unless e.is_a?(Rollback)
494
+ def transaction_error(e, opts={})
495
+ raise_error(e, opts.merge(:classes=>database_error_classes)) unless e.is_a?(Rollback)
495
496
  end
496
497
  end
497
498
  end
@@ -1,7 +1,7 @@
1
1
  module Sequel
2
2
  class Database
3
3
  # ---------------------
4
- # :section: Methods that modify the database schema
4
+ # :section: 2 - Methods that modify the database schema
5
5
  # These methods execute code on the database that modifies the database's schema.
6
6
  # ---------------------
7
7
 
@@ -29,7 +29,7 @@ module Sequel
29
29
  # DB.add_column :items, :name, :text, :unique => true, :null => false
30
30
  # DB.add_column :items, :category, :text, :default => 'ruby'
31
31
  #
32
- # See alter_table.
32
+ # See <tt>alter_table</tt>.
33
33
  def add_column(table, *args)
34
34
  alter_table(table) {add_column(*args)}
35
35
  end
@@ -40,9 +40,9 @@ module Sequel
40
40
  # DB.add_index :posts, [:author, :title], :unique => true
41
41
  #
42
42
  # Options:
43
- # * :ignore_errors - Ignore any DatabaseErrors that are raised
43
+ # :ignore_errors :: Ignore any DatabaseErrors that are raised
44
44
  #
45
- # See alter_table.
45
+ # See <tt>alter_table</tt>.
46
46
  def add_index(table, columns, options={})
47
47
  e = options[:ignore_errors]
48
48
  begin
@@ -65,10 +65,10 @@ module Sequel
65
65
  # end
66
66
  #
67
67
  # Note that +add_column+ accepts all the options available for column
68
- # definitions using create_table, and +add_index+ accepts all the options
68
+ # definitions using <tt>create_table</tt>, and +add_index+ accepts all the options
69
69
  # available for index definition.
70
70
  #
71
- # See Schema::AlterTableGenerator and the {"Migrations and Schema Modification" guide}[link:files/doc/migration_rdoc.html].
71
+ # See <tt>Schema::AlterTableGenerator</tt> and the {"Migrations and Schema Modification" guide}[link:files/doc/migration_rdoc.html].
72
72
  def alter_table(name, generator=nil, &block)
73
73
  generator ||= Schema::AlterTableGenerator.new(self, &block)
74
74
  alter_table_sql_list(name, generator.operations).flatten.each {|sql| execute_ddl(sql)}
@@ -89,7 +89,7 @@ module Sequel
89
89
  # :temp :: Create the table as a temporary table.
90
90
  # :ignore_index_errors :: Ignore any errors when creating indexes.
91
91
  #
92
- # See Schema::Generator and the {"Migrations and Schema Modification" guide}[link:files/doc/migration_rdoc.html].
92
+ # See <tt>Schema::Generator</tt> and the {"Migrations and Schema Modification" guide}[link:files/doc/migration_rdoc.html].
93
93
  def create_table(name, options={}, &block)
94
94
  remove_cached_schema(name)
95
95
  options = {:generator=>options} if options.is_a?(Schema::Generator)
@@ -99,17 +99,22 @@ module Sequel
99
99
  nil
100
100
  end
101
101
 
102
- # Forcibly creates a table, attempting to drop it unconditionally (and catching any errors), then creating it.
102
+ # Forcibly create a table, attempting to drop it if it already exists, then creating it.
103
103
  #
104
104
  # DB.create_table!(:a){Integer :a}
105
- # # DROP TABLE a
105
+ # # SELECT * FROM a LIMIT a -- check existence
106
+ # # DROP TABLE a -- drop table if already exists
106
107
  # # CREATE TABLE a (a integer)
107
108
  def create_table!(name, options={}, &block)
108
- drop_table(name) rescue nil
109
+ drop_table(name) if table_exists?(name)
109
110
  create_table(name, options, &block)
110
111
  end
111
112
 
112
- # Creates the table unless the table already exists
113
+ # Creates the table unless the table already exists.
114
+ #
115
+ # DB.create_table?(:a){Integer :a}
116
+ # # SELECT * FROM a LIMIT a -- check existence
117
+ # # CREATE TABLE a (a integer) -- if it doesn't already exist
113
118
  def create_table?(name, options={}, &block)
114
119
  if supports_create_table_if_not_exists?
115
120
  create_table(name, options.merge(:if_not_exists=>true), &block)
@@ -142,7 +147,7 @@ module Sequel
142
147
  #
143
148
  # DB.drop_column :items, :category
144
149
  #
145
- # See alter_table.
150
+ # See <tt>alter_table</tt>.
146
151
  def drop_column(table, *args)
147
152
  alter_table(table) {drop_column(*args)}
148
153
  end
@@ -152,7 +157,7 @@ module Sequel
152
157
  # DB.drop_index :posts, :title
153
158
  # DB.drop_index :posts, [:author, :title]
154
159
  #
155
- # See alter_table.
160
+ # See <tt>alter_table</tt>.
156
161
  def drop_index(table, columns, options={})
157
162
  alter_table(table){drop_index(columns, options)}
158
163
  end
@@ -201,7 +206,7 @@ module Sequel
201
206
  #
202
207
  # DB.rename_column :items, :cntr, :counter
203
208
  #
204
- # See alter_table.
209
+ # See <tt>alter_table</tt>.
205
210
  def rename_column(table, *args)
206
211
  alter_table(table) {rename_column(*args)}
207
212
  end
@@ -210,7 +215,7 @@ module Sequel
210
215
  #
211
216
  # DB.set_column_default :items, :category, 'perl!'
212
217
  #
213
- # See alter_table.
218
+ # See <tt>alter_table</tt>.
214
219
  def set_column_default(table, *args)
215
220
  alter_table(table) {set_column_default(*args)}
216
221
  end
@@ -219,7 +224,7 @@ module Sequel
219
224
  #
220
225
  # DB.set_column_type :items, :price, :float
221
226
  #
222
- # See alter_table.
227
+ # See <tt>alter_table</tt>.
223
228
  def set_column_type(table, *args)
224
229
  alter_table(table) {set_column_type(*args)}
225
230
  end
@@ -1,7 +1,7 @@
1
1
  module Sequel
2
2
  class Dataset
3
3
  # ---------------------
4
- # :section: Methods that execute code on the database
4
+ # :section: 2 - Methods that execute code on the database
5
5
  # These methods all execute the dataset's SQL on the database.
6
6
  # They don't return modified datasets, so if used in a method chain
7
7
  # they should be the last method called.
@@ -248,14 +248,16 @@ module Sequel
248
248
  # the value of the primary key for the inserted row, but that is adapter dependent.
249
249
  #
250
250
  # +insert+ handles a number of different argument formats:
251
- # * No arguments, single empty hash - Uses DEFAULT VALUES
252
- # * Single hash - Most common format, treats keys as columns an values as values
253
- # * Single array - Treats entries as values, with no columns
254
- # * Two arrays - Treats first array as columns, second array as values
255
- # * Single Dataset - Treats as an insert based on a selection from the dataset given,
256
- # with no columns
257
- # * Array and dataset - Treats as an insert based on a selection from the dataset
258
- # given, with the columns given by the array.
251
+ # no arguments or single empty hash :: Uses DEFAULT VALUES
252
+ # single hash :: Most common format, treats keys as columns an values as values
253
+ # single array :: Treats entries as values, with no columns
254
+ # two arrays :: Treats first array as columns, second array as values
255
+ # single Dataset :: Treats as an insert based on a selection from the dataset given,
256
+ # with no columns
257
+ # array and dataset :: Treats as an insert based on a selection from the dataset
258
+ # given, with the columns given by the array.
259
+ #
260
+ # Examples:
259
261
  #
260
262
  # DB[:items].insert
261
263
  # # INSERT INTO items DEFAULT VALUES
@@ -310,7 +312,7 @@ module Sequel
310
312
  aggregate_dataset.get{max(column) - min(column)}
311
313
  end
312
314
 
313
- # Reverses the order and then runs first. Note that this
315
+ # Reverses the order and then runs #first with the given arguments and block. Note that this
314
316
  # will not necessarily give you the last record in the dataset,
315
317
  # unless you have an unambiguous order. If there is not
316
318
  # currently an order for this dataset, raises an +Error+.
@@ -400,13 +402,14 @@ module Sequel
400
402
  # Selects the column given (either as an argument or as a block), and
401
403
  # returns an array of all values of that column in the dataset. If you
402
404
  # give a block argument that returns an array with multiple entries,
403
- # the contents of the resulting array are undefined.
405
+ # the contents of the resulting array are undefined. Raises an Error
406
+ # if called with both an argument and a block.
404
407
  #
405
408
  # DB[:table].select_map(:id) # SELECT id FROM table
406
409
  # # => [3, 5, 8, 1, ...]
407
410
  #
408
- # DB[:table].select_map{abs(id)} # SELECT abs(id) FROM table
409
- # # => [3, 5, 8, 1, ...]
411
+ # DB[:table].select_map{id * 2} # SELECT (id * 2) FROM table
412
+ # # => [6, 10, 16, 2, ...]
410
413
  def select_map(column=nil, &block)
411
414
  ds = naked.ungraphed
412
415
  ds = if column
@@ -423,8 +426,8 @@ module Sequel
423
426
  # DB[:table].select_order_map(:id) # SELECT id FROM table ORDER BY id
424
427
  # # => [1, 2, 3, 4, ...]
425
428
  #
426
- # DB[:table].select_order_map{abs(id)} # SELECT abs(id) FROM table ORDER BY abs(id)
427
- # # => [1, 2, 3, 4, ...]
429
+ # DB[:table].select_order_map{abs(id)} # SELECT (id * 2) FROM table ORDER BY (id * 2)
430
+ # # => [2, 4, 6, 8, ...]
428
431
  def select_order_map(column=nil, &block)
429
432
  ds = naked.ungraphed
430
433
  ds = if column
@@ -522,7 +525,7 @@ module Sequel
522
525
  # DB[:table].update(:x=>nil) # UPDATE table SET x = NULL
523
526
  # # => 10
524
527
  #
525
- # DB[:table].update(:x=>:x+1, :y=>0) # UPDATE table SET x = (x + 1), :y = 0
528
+ # DB[:table].update(:x=>:x+1, :y=>0) # UPDATE table SET x = (x + 1), y = 0
526
529
  # # => 10
527
530
  def update(values={})
528
531
  execute_dui(update_sql(values))