sequel 3.5.0 → 3.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +108 -0
- data/README.rdoc +25 -14
- data/Rakefile +20 -1
- data/doc/advanced_associations.rdoc +61 -64
- data/doc/cheat_sheet.rdoc +16 -7
- data/doc/opening_databases.rdoc +3 -3
- data/doc/prepared_statements.rdoc +1 -1
- data/doc/reflection.rdoc +2 -1
- data/doc/release_notes/3.6.0.txt +366 -0
- data/doc/schema.rdoc +19 -14
- data/lib/sequel/adapters/amalgalite.rb +5 -27
- data/lib/sequel/adapters/jdbc.rb +13 -3
- data/lib/sequel/adapters/jdbc/h2.rb +17 -0
- data/lib/sequel/adapters/jdbc/mysql.rb +20 -7
- data/lib/sequel/adapters/mysql.rb +4 -3
- data/lib/sequel/adapters/oracle.rb +1 -1
- data/lib/sequel/adapters/postgres.rb +87 -28
- data/lib/sequel/adapters/shared/mssql.rb +47 -6
- data/lib/sequel/adapters/shared/mysql.rb +12 -31
- data/lib/sequel/adapters/shared/postgres.rb +15 -12
- data/lib/sequel/adapters/shared/sqlite.rb +18 -0
- data/lib/sequel/adapters/sqlite.rb +1 -16
- data/lib/sequel/connection_pool.rb +1 -1
- data/lib/sequel/core.rb +1 -1
- data/lib/sequel/database.rb +1 -1
- data/lib/sequel/database/schema_generator.rb +2 -0
- data/lib/sequel/database/schema_sql.rb +1 -1
- data/lib/sequel/dataset.rb +5 -179
- data/lib/sequel/dataset/actions.rb +123 -0
- data/lib/sequel/dataset/convenience.rb +18 -10
- data/lib/sequel/dataset/features.rb +65 -0
- data/lib/sequel/dataset/prepared_statements.rb +29 -23
- data/lib/sequel/dataset/query.rb +429 -0
- data/lib/sequel/dataset/sql.rb +67 -435
- data/lib/sequel/model/associations.rb +77 -13
- data/lib/sequel/model/base.rb +30 -8
- data/lib/sequel/model/errors.rb +4 -4
- data/lib/sequel/plugins/caching.rb +38 -15
- data/lib/sequel/plugins/force_encoding.rb +18 -7
- data/lib/sequel/plugins/hook_class_methods.rb +4 -0
- data/lib/sequel/plugins/many_through_many.rb +1 -1
- data/lib/sequel/plugins/nested_attributes.rb +40 -11
- data/lib/sequel/plugins/serialization.rb +17 -3
- data/lib/sequel/plugins/validation_helpers.rb +65 -18
- data/lib/sequel/sql.rb +23 -1
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +96 -10
- data/spec/adapters/mysql_spec.rb +19 -0
- data/spec/adapters/postgres_spec.rb +65 -2
- data/spec/adapters/sqlite_spec.rb +10 -0
- data/spec/core/core_sql_spec.rb +9 -0
- data/spec/core/database_spec.rb +8 -4
- data/spec/core/dataset_spec.rb +122 -29
- data/spec/core/expression_filters_spec.rb +17 -0
- data/spec/extensions/caching_spec.rb +43 -3
- data/spec/extensions/force_encoding_spec.rb +43 -1
- data/spec/extensions/nested_attributes_spec.rb +55 -2
- data/spec/extensions/validation_helpers_spec.rb +71 -0
- data/spec/integration/associations_test.rb +281 -0
- data/spec/integration/dataset_test.rb +383 -9
- data/spec/integration/eager_loader_test.rb +0 -65
- data/spec/integration/model_test.rb +110 -0
- data/spec/integration/plugin_test.rb +306 -0
- data/spec/integration/prepared_statement_test.rb +32 -0
- data/spec/integration/schema_test.rb +8 -3
- data/spec/integration/spec_helper.rb +1 -25
- data/spec/model/association_reflection_spec.rb +38 -0
- data/spec/model/associations_spec.rb +184 -8
- data/spec/model/eager_loading_spec.rb +23 -0
- data/spec/model/model_spec.rb +8 -0
- data/spec/model/record_spec.rb +84 -1
- metadata +9 -2
@@ -1,4 +1,7 @@
|
|
1
1
|
module Sequel
|
2
|
+
Dataset::NON_SQL_OPTIONS << :insert_ignore
|
3
|
+
Dataset::NON_SQL_OPTIONS << :on_duplicate_key_update
|
4
|
+
|
2
5
|
module MySQL
|
3
6
|
class << self
|
4
7
|
# Set the default options used for CREATE TABLE
|
@@ -311,37 +314,7 @@ module Sequel
|
|
311
314
|
# MySQL specific syntax for REPLACE (aka UPSERT, or update if exists,
|
312
315
|
# insert if it doesn't).
|
313
316
|
def replace_sql(*values)
|
314
|
-
|
315
|
-
if values.empty?
|
316
|
-
"REPLACE INTO #{from} DEFAULT VALUES"
|
317
|
-
else
|
318
|
-
values = values[0] if values.size == 1
|
319
|
-
|
320
|
-
case values
|
321
|
-
when Array
|
322
|
-
if values.empty?
|
323
|
-
"REPLACE INTO #{from} DEFAULT VALUES"
|
324
|
-
else
|
325
|
-
"REPLACE INTO #{from} VALUES #{literal(values)}"
|
326
|
-
end
|
327
|
-
when Hash
|
328
|
-
if values.empty?
|
329
|
-
"REPLACE INTO #{from} DEFAULT VALUES"
|
330
|
-
else
|
331
|
-
fl, vl = [], []
|
332
|
-
values.each {|k, v| fl << literal(k.is_a?(String) ? k.to_sym : k); vl << literal(v)}
|
333
|
-
"REPLACE INTO #{from} (#{fl.join(COMMA_SEPARATOR)}) VALUES (#{vl.join(COMMA_SEPARATOR)})"
|
334
|
-
end
|
335
|
-
when Dataset
|
336
|
-
"REPLACE INTO #{from} #{literal(values)}"
|
337
|
-
else
|
338
|
-
if values.respond_to?(:values)
|
339
|
-
replace_sql(values.values)
|
340
|
-
else
|
341
|
-
"REPLACE INTO #{from} VALUES (#{literal(values)})"
|
342
|
-
end
|
343
|
-
end
|
344
|
-
end
|
317
|
+
clone(:replace=>true).insert_sql(*values)
|
345
318
|
end
|
346
319
|
|
347
320
|
# does not support DISTINCT ON
|
@@ -360,6 +333,13 @@ module Sequel
|
|
360
333
|
def supports_timestamp_usecs?
|
361
334
|
false
|
362
335
|
end
|
336
|
+
|
337
|
+
protected
|
338
|
+
|
339
|
+
# If this is an replace instead of an insert, use replace instead
|
340
|
+
def _insert_sql
|
341
|
+
@opts[:replace] ? clause_sql(:replace) : super
|
342
|
+
end
|
363
343
|
|
364
344
|
private
|
365
345
|
|
@@ -372,6 +352,7 @@ module Sequel
|
|
372
352
|
def insert_clause_methods
|
373
353
|
INSERT_CLAUSE_METHODS
|
374
354
|
end
|
355
|
+
alias replace_clause_methods insert_clause_methods
|
375
356
|
|
376
357
|
# MySQL doesn't use the SQL standard DEFAULT VALUES.
|
377
358
|
def insert_columns_sql(sql)
|
@@ -1,4 +1,6 @@
|
|
1
1
|
module Sequel
|
2
|
+
Dataset::NON_SQL_OPTIONS << :disable_insert_returning
|
3
|
+
|
2
4
|
# Top level module for holding all PostgreSQL-related modules and classes
|
3
5
|
# for Sequel. There are a few module level accessors that are added via
|
4
6
|
# metaprogramming. These are:
|
@@ -601,7 +603,7 @@ module Sequel
|
|
601
603
|
return @prepared_sql if @prepared_sql
|
602
604
|
super
|
603
605
|
if @prepared_type == :insert and !@opts[:disable_insert_returning] and server_version >= 80200
|
604
|
-
@prepared_sql = insert_returning_pk_sql(
|
606
|
+
@prepared_sql = insert_returning_pk_sql(*@prepared_modify_values)
|
605
607
|
meta_def(:insert_returning_pk_sql){|*args| prepared_sql}
|
606
608
|
end
|
607
609
|
@prepared_sql
|
@@ -672,17 +674,18 @@ module Sequel
|
|
672
674
|
naked.clone(default_server_opts(:sql=>insert_returning_sql(nil, *values))).single_record
|
673
675
|
end
|
674
676
|
|
675
|
-
# Locks
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
677
|
+
# Locks all tables in the dataset's FROM clause (but not in JOINs) with
|
678
|
+
# the specified mode (e.g. 'EXCLUSIVE'). If a block is given, starts
|
679
|
+
# a new transaction, locks the table, and yields. If a block is not given
|
680
|
+
# just locks the tables. Note that PostgreSQL will probably raise an error
|
681
|
+
# if you lock the table outside of an existing transaction. Returns nil.
|
682
|
+
def lock(mode, opts={})
|
683
|
+
if block_given? # perform locking inside a transaction and yield to block
|
684
|
+
@db.transaction(opts){lock(mode, opts); yield}
|
685
|
+
else
|
686
|
+
@db.execute(LOCK % [source_list(@opts[:from]), mode], opts) # lock without a transaction
|
685
687
|
end
|
688
|
+
nil
|
686
689
|
end
|
687
690
|
|
688
691
|
# For PostgreSQL version > 8.2, allow inserting multiple rows at once.
|
@@ -705,7 +708,7 @@ module Sequel
|
|
705
708
|
|
706
709
|
# Return a clone of the dataset with an addition named window that can be referenced in window functions.
|
707
710
|
def window(name, opts)
|
708
|
-
clone(:window=>(@opts[:
|
711
|
+
clone(:window=>(@opts[:window]||[]) + [[name, SQL::Window.new(opts)]])
|
709
712
|
end
|
710
713
|
|
711
714
|
private
|
@@ -265,6 +265,19 @@ module Sequel
|
|
265
265
|
@opts[:where] ? super : filter(1=>1).delete
|
266
266
|
end
|
267
267
|
|
268
|
+
# Return an array of strings specifying a query explanation for a SELECT of the
|
269
|
+
# current dataset.
|
270
|
+
def explain
|
271
|
+
db.send(:metadata_dataset).clone(:sql=>"EXPLAIN #{select_sql}").
|
272
|
+
map{|x| "#{x[:addr]}|#{x[:opcode]}|#{(1..5).map{|i| x[:"p#{i}"]}.join('|')}|#{x[:comment]}"}
|
273
|
+
end
|
274
|
+
|
275
|
+
# HAVING requires GROUP BY on SQLite
|
276
|
+
def having(*cond, &block)
|
277
|
+
raise(InvalidOperation, "Can only specify a HAVING clause on a grouped dataset") unless @opts[:group]
|
278
|
+
super
|
279
|
+
end
|
280
|
+
|
268
281
|
# SQLite uses the nonstandard ` (backtick) for quoting identifiers.
|
269
282
|
def quoted_identifier(c)
|
270
283
|
"`#{c}`"
|
@@ -280,6 +293,11 @@ module Sequel
|
|
280
293
|
false
|
281
294
|
end
|
282
295
|
|
296
|
+
# SQLite does not support multiple columns for the IN/NOT IN operators
|
297
|
+
def supports_multiple_column_in?
|
298
|
+
false
|
299
|
+
end
|
300
|
+
|
283
301
|
# SQLite supports timezones in literal timestamps, since it stores them
|
284
302
|
# as text.
|
285
303
|
def supports_timestamp_timezones?
|
@@ -122,7 +122,6 @@ module Sequel
|
|
122
122
|
class Dataset < Sequel::Dataset
|
123
123
|
include ::Sequel::SQLite::DatasetMethods
|
124
124
|
|
125
|
-
EXPLAIN = 'EXPLAIN %s'.freeze
|
126
125
|
PREPARED_ARG_PLACEHOLDER = ':'.freeze
|
127
126
|
|
128
127
|
# SQLite already supports named bind arguments, so use directly.
|
@@ -172,20 +171,6 @@ module Sequel
|
|
172
171
|
end
|
173
172
|
end
|
174
173
|
|
175
|
-
# Prepare an unnamed statement of the given type and call it with the
|
176
|
-
# given values.
|
177
|
-
def call(type, hash, values=nil, &block)
|
178
|
-
prepare(type, nil, values).call(hash, &block)
|
179
|
-
end
|
180
|
-
|
181
|
-
# Return an array of strings specifying a query explanation for the
|
182
|
-
# current dataset.
|
183
|
-
def explain
|
184
|
-
res = []
|
185
|
-
@db.result_set(EXPLAIN % select_sql(opts), nil) {|r| res << r}
|
186
|
-
res
|
187
|
-
end
|
188
|
-
|
189
174
|
# Yield a hash for each row in the dataset.
|
190
175
|
def fetch_rows(sql)
|
191
176
|
execute(sql) do |result|
|
@@ -203,7 +188,7 @@ module Sequel
|
|
203
188
|
# Prepare the given type of query with the given name and store
|
204
189
|
# it in the database. Note that a new native prepared statement is
|
205
190
|
# created on each call to this prepared statement.
|
206
|
-
def prepare(type, name=nil, values
|
191
|
+
def prepare(type, name=nil, *values)
|
207
192
|
ps = to_prepared_statement(type, values)
|
208
193
|
ps.extend(PreparedStatementMethods)
|
209
194
|
db.prepared_statements[name] = ps if name
|
@@ -11,7 +11,7 @@ class Sequel::ConnectionPool
|
|
11
11
|
# The maximum number of connections.
|
12
12
|
attr_reader :max_size
|
13
13
|
|
14
|
-
# The mutex that protects access to the other internal
|
14
|
+
# The mutex that protects access to the other internal variables. You must use
|
15
15
|
# this if you want to manipulate the variables safely.
|
16
16
|
attr_reader :mutex
|
17
17
|
|
data/lib/sequel/core.rb
CHANGED
@@ -249,7 +249,7 @@ module Sequel
|
|
249
249
|
|
250
250
|
require(%w"metaprogramming sql connection_pool exceptions dataset database timezones version")
|
251
251
|
require(%w"schema_generator schema_methods schema_sql", 'database')
|
252
|
-
require(%w"convenience graph prepared_statements sql", 'dataset')
|
252
|
+
require(%w"actions convenience features graph prepared_statements query sql", 'dataset')
|
253
253
|
require('core_sql') if !defined?(::SEQUEL_NO_CORE_EXTENSIONS) && !ENV.has_key?('SEQUEL_NO_CORE_EXTENSIONS')
|
254
254
|
|
255
255
|
# Add the database adapter class methods to Sequel via metaprogramming
|
data/lib/sequel/database.rb
CHANGED
@@ -78,6 +78,8 @@ module Sequel
|
|
78
78
|
# See Schema::SQL#on_delete_clause for options.
|
79
79
|
# * :size - The size of the column, generally used with string
|
80
80
|
# columns to specify the maximum number of characters the column will hold.
|
81
|
+
# An array of two integers can be provided to set the size and the
|
82
|
+
# precision, respectively, of decimal columns.
|
81
83
|
# * :unique - Mark the column as unique, generally has the same effect as
|
82
84
|
# creating a unique index on the column.
|
83
85
|
# * :unsigned - Make the column type unsigned, only useful for integer
|
@@ -159,7 +159,7 @@ module Sequel
|
|
159
159
|
elsif index[:where]
|
160
160
|
raise Error, "Partial indexes are not supported for this database"
|
161
161
|
else
|
162
|
-
"CREATE #{'UNIQUE ' if index[:unique]}INDEX #{quote_identifier(index_name)} ON #{
|
162
|
+
"CREATE #{'UNIQUE ' if index[:unique]}INDEX #{quote_identifier(index_name)} ON #{quote_schema_table(table_name)} #{literal(index[:columns])}"
|
163
163
|
end
|
164
164
|
end
|
165
165
|
|
data/lib/sequel/dataset.rb
CHANGED
@@ -20,17 +20,6 @@ module Sequel
|
|
20
20
|
#
|
21
21
|
# Datasets are Enumerable objects, so they can be manipulated using any
|
22
22
|
# of the Enumerable methods, such as map, inject, etc.
|
23
|
-
#
|
24
|
-
# === Methods added via metaprogramming
|
25
|
-
#
|
26
|
-
# Some methods are added via metaprogramming:
|
27
|
-
#
|
28
|
-
# * ! methods - These methods are the same as their non-! counterparts,
|
29
|
-
# but they modify the receiver instead of returning a modified copy
|
30
|
-
# of the dataset.
|
31
|
-
# * inner_join, full_outer_join, right_outer_join, left_outer_join -
|
32
|
-
# This methods are shortcuts to join_table with the join type
|
33
|
-
# already specified.
|
34
23
|
class Dataset
|
35
24
|
extend Metaprogramming
|
36
25
|
include Metaprogramming
|
@@ -50,6 +39,10 @@ module Sequel
|
|
50
39
|
set_defaults set_graph_aliases set_overrides unfiltered ungraphed ungrouped union
|
51
40
|
unlimited unordered where with with_recursive with_sql'.collect{|x| x.to_sym}
|
52
41
|
|
42
|
+
# Which options don't affect the SQL generation. Used by simple_select_all?
|
43
|
+
# to determine if this is a simple SELECT * FROM table.
|
44
|
+
NON_SQL_OPTIONS = [:server, :defaults, :overrides]
|
45
|
+
|
53
46
|
NOTIMPL_MSG = "This method must be overridden in Sequel adapters".freeze
|
54
47
|
WITH_SUPPORTED=:select_with_sql
|
55
48
|
|
@@ -103,12 +96,6 @@ module Sequel
|
|
103
96
|
|
104
97
|
### Instance Methods ###
|
105
98
|
|
106
|
-
# Alias for insert, but not aliased directly so subclasses
|
107
|
-
# don't have to override both methods.
|
108
|
-
def <<(*args)
|
109
|
-
insert(*args)
|
110
|
-
end
|
111
|
-
|
112
99
|
# Return the dataset as an aliased expression with the given alias. You can
|
113
100
|
# use this as a FROM or JOIN dataset, or as a column if this dataset
|
114
101
|
# returns a single row and column.
|
@@ -116,16 +103,6 @@ module Sequel
|
|
116
103
|
::Sequel::SQL::AliasedExpression.new(self, aliaz)
|
117
104
|
end
|
118
105
|
|
119
|
-
# Returns an array with all records in the dataset. If a block is given,
|
120
|
-
# the array is iterated over after all items have been loaded.
|
121
|
-
def all(&block)
|
122
|
-
a = []
|
123
|
-
each{|r| a << r}
|
124
|
-
post_load(a)
|
125
|
-
a.each(&block) if block
|
126
|
-
a
|
127
|
-
end
|
128
|
-
|
129
106
|
# Returns a new clone of the dataset with with the given options merged.
|
130
107
|
# If the options changed include options in COLUMN_CHANGE_OPTS, the cached
|
131
108
|
# columns are deleted.
|
@@ -136,30 +113,6 @@ module Sequel
|
|
136
113
|
c
|
137
114
|
end
|
138
115
|
|
139
|
-
# Returns the columns in the result set in order.
|
140
|
-
# If the columns are currently cached, returns the cached value. Otherwise,
|
141
|
-
# a SELECT query is performed to get a single row. Adapters are expected
|
142
|
-
# to fill the columns cache with the column information when a query is performed.
|
143
|
-
# If the dataset does not have any rows, this may be an empty array depending on how
|
144
|
-
# the adapter is programmed.
|
145
|
-
#
|
146
|
-
# If you are looking for all columns for a single table and maybe some information about
|
147
|
-
# each column (e.g. type), see Database#schema.
|
148
|
-
def columns
|
149
|
-
return @columns if @columns
|
150
|
-
ds = unfiltered.unordered.clone(:distinct => nil, :limit => 1)
|
151
|
-
ds.each{break}
|
152
|
-
@columns = ds.instance_variable_get(:@columns)
|
153
|
-
@columns || []
|
154
|
-
end
|
155
|
-
|
156
|
-
# Remove the cached list of columns and do a SELECT query to find
|
157
|
-
# the columns.
|
158
|
-
def columns!
|
159
|
-
@columns = nil
|
160
|
-
columns
|
161
|
-
end
|
162
|
-
|
163
116
|
# Add a mutation method to this dataset instance.
|
164
117
|
def def_mutation_method(*meths)
|
165
118
|
meths.each do |meth|
|
@@ -167,44 +120,6 @@ module Sequel
|
|
167
120
|
end
|
168
121
|
end
|
169
122
|
|
170
|
-
# Deletes the records in the dataset. The returned value is generally the
|
171
|
-
# number of records deleted, but that is adapter dependent. See delete_sql.
|
172
|
-
def delete
|
173
|
-
execute_dui(delete_sql)
|
174
|
-
end
|
175
|
-
|
176
|
-
# Iterates over the records in the dataset as they are yielded from the
|
177
|
-
# database adapter, and returns self.
|
178
|
-
#
|
179
|
-
# Note that this method is not safe to use on many adapters if you are
|
180
|
-
# running additional queries inside the provided block. If you are
|
181
|
-
# running queries inside the block, you use should all instead of each.
|
182
|
-
def each(&block)
|
183
|
-
if @opts[:graph]
|
184
|
-
graph_each(&block)
|
185
|
-
else
|
186
|
-
if row_proc = @row_proc
|
187
|
-
fetch_rows(select_sql){|r| yield row_proc.call(r)}
|
188
|
-
else
|
189
|
-
fetch_rows(select_sql, &block)
|
190
|
-
end
|
191
|
-
end
|
192
|
-
self
|
193
|
-
end
|
194
|
-
|
195
|
-
# Executes a select query and fetches records, passing each record to the
|
196
|
-
# supplied block. The yielded records should be hashes with symbol keys.
|
197
|
-
def fetch_rows(sql, &block)
|
198
|
-
raise NotImplementedError, NOTIMPL_MSG
|
199
|
-
end
|
200
|
-
|
201
|
-
# Inserts values into the associated table. The returned value is generally
|
202
|
-
# the value of the primary key for the inserted row, but that is adapter dependent.
|
203
|
-
# See insert_sql.
|
204
|
-
def insert(*values)
|
205
|
-
execute_insert(insert_sql(*values))
|
206
|
-
end
|
207
|
-
|
208
123
|
# Returns a string representation of the dataset including the class name
|
209
124
|
# and the corresponding SQL select statement.
|
210
125
|
def inspect
|
@@ -219,17 +134,6 @@ module Sequel
|
|
219
134
|
ds
|
220
135
|
end
|
221
136
|
|
222
|
-
# Whether this dataset quotes identifiers.
|
223
|
-
def quote_identifiers?
|
224
|
-
@quote_identifiers
|
225
|
-
end
|
226
|
-
|
227
|
-
# Whether the dataset requires SQL standard datetimes (false by default,
|
228
|
-
# as most allow strings with ISO 8601 format.
|
229
|
-
def requires_sql_standard_datetimes?
|
230
|
-
false
|
231
|
-
end
|
232
|
-
|
233
137
|
# Set the server for this dataset to use. Used to pick a specific database
|
234
138
|
# shard to run a query against, or to override the default (which is SELECT uses
|
235
139
|
# :read_only database and all other queries use the :default database).
|
@@ -237,12 +141,6 @@ module Sequel
|
|
237
141
|
clone(:server=>servr)
|
238
142
|
end
|
239
143
|
|
240
|
-
# Alias for set, but not aliased directly so subclasses
|
241
|
-
# don't have to override both methods.
|
242
|
-
def set(*args)
|
243
|
-
update(*args)
|
244
|
-
end
|
245
|
-
|
246
144
|
# Set the default values for insert and update statements. The values hash passed
|
247
145
|
# to insert or update are merged into this hash.
|
248
146
|
def set_defaults(hash)
|
@@ -255,57 +153,6 @@ module Sequel
|
|
255
153
|
clone(:overrides=>hash.merge(@opts[:overrides]||{}))
|
256
154
|
end
|
257
155
|
|
258
|
-
# Whether the dataset supports common table expressions (the WITH clause).
|
259
|
-
def supports_cte?
|
260
|
-
select_clause_methods.include?(WITH_SUPPORTED)
|
261
|
-
end
|
262
|
-
|
263
|
-
# Whether the dataset supports the DISTINCT ON clause, true by default.
|
264
|
-
def supports_distinct_on?
|
265
|
-
true
|
266
|
-
end
|
267
|
-
|
268
|
-
# Whether the dataset supports the INTERSECT and EXCEPT compound operations, true by default.
|
269
|
-
def supports_intersect_except?
|
270
|
-
true
|
271
|
-
end
|
272
|
-
|
273
|
-
# Whether the dataset supports the INTERSECT ALL and EXCEPT ALL compound operations, true by default.
|
274
|
-
def supports_intersect_except_all?
|
275
|
-
true
|
276
|
-
end
|
277
|
-
|
278
|
-
# Whether the dataset supports the IS TRUE syntax.
|
279
|
-
def supports_is_true?
|
280
|
-
true
|
281
|
-
end
|
282
|
-
|
283
|
-
# Whether the dataset supports timezones in literal timestamps
|
284
|
-
def supports_timestamp_timezones?
|
285
|
-
false
|
286
|
-
end
|
287
|
-
|
288
|
-
# Whether the dataset supports fractional seconds in literal timestamps
|
289
|
-
def supports_timestamp_usecs?
|
290
|
-
true
|
291
|
-
end
|
292
|
-
|
293
|
-
# Whether the dataset supports window functions.
|
294
|
-
def supports_window_functions?
|
295
|
-
false
|
296
|
-
end
|
297
|
-
|
298
|
-
# Truncates the dataset. Returns nil.
|
299
|
-
def truncate
|
300
|
-
execute_ddl(truncate_sql)
|
301
|
-
end
|
302
|
-
|
303
|
-
# Updates values for the dataset. The returned value is generally the
|
304
|
-
# number of rows updated, but that is adapter dependent. See update_sql.
|
305
|
-
def update(values={})
|
306
|
-
execute_dui(update_sql(values))
|
307
|
-
end
|
308
|
-
|
309
156
|
# Add the mutation methods via metaprogramming
|
310
157
|
def_mutation_method(*MUTATION_METHODS)
|
311
158
|
|
@@ -318,7 +165,7 @@ module Sequel
|
|
318
165
|
|
319
166
|
# Whether this dataset is a simple SELECT * FROM table.
|
320
167
|
def simple_select_all?
|
321
|
-
o = @opts.reject{|k,v| v.nil?}
|
168
|
+
o = @opts.reject{|k,v| v.nil? || NON_SQL_OPTIONS.include?(k)}
|
322
169
|
o.length == 1 && (f = o[:from]) && f.length == 1 && f.first.is_a?(Symbol)
|
323
170
|
end
|
324
171
|
|
@@ -329,27 +176,6 @@ module Sequel
|
|
329
176
|
{:server=>@opts[:server] || :default}.merge(opts)
|
330
177
|
end
|
331
178
|
|
332
|
-
# Execute the given SQL on the database using execute.
|
333
|
-
def execute(sql, opts={}, &block)
|
334
|
-
@db.execute(sql, {:server=>@opts[:server] || :read_only}.merge(opts), &block)
|
335
|
-
end
|
336
|
-
|
337
|
-
# Execute the given SQL on the database using execute_ddl.
|
338
|
-
def execute_ddl(sql, opts={}, &block)
|
339
|
-
@db.execute_ddl(sql, default_server_opts(opts), &block)
|
340
|
-
nil
|
341
|
-
end
|
342
|
-
|
343
|
-
# Execute the given SQL on the database using execute_dui.
|
344
|
-
def execute_dui(sql, opts={}, &block)
|
345
|
-
@db.execute_dui(sql, default_server_opts(opts), &block)
|
346
|
-
end
|
347
|
-
|
348
|
-
# Execute the given SQL on the database using execute_insert.
|
349
|
-
def execute_insert(sql, opts={}, &block)
|
350
|
-
@db.execute_insert(sql, default_server_opts(opts), &block)
|
351
|
-
end
|
352
|
-
|
353
179
|
# Modify the identifier returned from the database based on the
|
354
180
|
# identifier_output_method.
|
355
181
|
def input_identifier(v)
|