sequel 3.6.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +28 -0
- data/Rakefile +12 -15
- data/doc/release_notes/3.7.0.txt +179 -0
- data/doc/virtual_rows.rdoc +3 -0
- data/lib/sequel/adapters/mysql.rb +8 -5
- data/lib/sequel/adapters/shared/mssql.rb +24 -15
- data/lib/sequel/adapters/shared/mysql.rb +16 -0
- data/lib/sequel/adapters/shared/oracle.rb +18 -0
- data/lib/sequel/adapters/shared/postgres.rb +59 -1
- data/lib/sequel/dataset/convenience.rb +58 -11
- data/lib/sequel/dataset/features.rb +5 -0
- data/lib/sequel/dataset/query.rb +3 -3
- data/lib/sequel/dataset/sql.rb +19 -2
- data/lib/sequel/extensions/schema_dumper.rb +6 -1
- data/lib/sequel/model/base.rb +40 -16
- data/lib/sequel/plugins/validation_helpers.rb +7 -2
- data/lib/sequel/sql.rb +22 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/postgres_spec.rb +16 -0
- data/spec/core/dataset_spec.rb +187 -0
- data/spec/core/expression_filters_spec.rb +25 -0
- data/spec/extensions/schema_dumper_spec.rb +6 -0
- data/spec/extensions/validation_helpers_spec.rb +35 -0
- data/spec/integration/dataset_test.rb +37 -0
- data/spec/model/model_spec.rb +26 -0
- data/spec/model/record_spec.rb +65 -3
- metadata +4 -3
- data/spec/spec.opts +0 -0
data/CHANGELOG
CHANGED
@@ -1,3 +1,31 @@
|
|
1
|
+
=== 3.7.0 (2009-12-01)
|
2
|
+
|
3
|
+
* Add Dataset#sequence to the shared Oracle Adapter, for returning autogenerated primary key values on insert (jeremyevans) (#280)
|
4
|
+
|
5
|
+
* Bring support for modifying joined datasets into Sequel proper, supported on MySQL and PostgreSQL (jeremyevans)
|
6
|
+
|
7
|
+
* No longer use native autoreconnection in the mysql adapter (jeremyevans)
|
8
|
+
|
9
|
+
* Add NULL, NOTNULL, TRUE, SQLTRUE, FALSE, and SQLFALSE constants (jeremyevans)
|
10
|
+
|
11
|
+
* Add Dataset #select_map, #select_order_map, and #select_hash (jeremyevans)
|
12
|
+
|
13
|
+
* Make Dataset#group_and_count handle arguments other than Symbols (jeremyevans)
|
14
|
+
|
15
|
+
* Add :only_if_modified option to validates_unique method in validation_helpers plugin (jeremyevans)
|
16
|
+
|
17
|
+
* Allow specifying the dataset alias via :alias option when using union/intersect/except (jeremyevans)
|
18
|
+
|
19
|
+
* Allow Model#destroy to take an options hash and respect a :transaction option (john_firebaugh)
|
20
|
+
|
21
|
+
* If a transaction is being used, raise_on_save_failure is false, and a before hook returns false, rollback the transaction (john_firebaugh, jeremyevans)
|
22
|
+
|
23
|
+
* In the schema_dumper, explicitly specify the :type option if it isn't Integer (jeremyevans)
|
24
|
+
|
25
|
+
* On postgres, use bigserial type if :type=>Bignum is given as an option to primary_key (jeremyevans)
|
26
|
+
|
27
|
+
* Use READ_DEFAULT_GROUP in the mysql adapter to load the options in the client section of the my.cnf file (crohr)
|
28
|
+
|
1
29
|
=== 3.6.0 (2009-11-02)
|
2
30
|
|
3
31
|
* Make the MSSQL shared adapter correctly parse the column schema information for tables in the non-default database schema (rohit.namjoshi)
|
data/Rakefile
CHANGED
@@ -55,11 +55,9 @@ task :uninstall=>[:clean] do
|
|
55
55
|
sh %{sudo gem uninstall #{NAME}}
|
56
56
|
end
|
57
57
|
|
58
|
-
desc "Upload sequel gem to
|
58
|
+
desc "Upload sequel gem to gemcutter"
|
59
59
|
task :release=>[:package] do
|
60
|
-
sh %{
|
61
|
-
sh %{rubyforge add_release sequel #{NAME} #{VERS.call} pkg/#{NAME}-#{VERS.call}.tgz}
|
62
|
-
sh %{rubyforge add_file sequel #{NAME} #{VERS.call} pkg/#{NAME}-#{VERS.call}.gem}
|
60
|
+
sh %{gem push pkg/#{NAME}-#{VERS.call}.gem}
|
63
61
|
end
|
64
62
|
|
65
63
|
### RDoc
|
@@ -116,7 +114,6 @@ begin
|
|
116
114
|
spec_opts = lambda do
|
117
115
|
lib_dir = File.join(File.dirname(__FILE__), 'lib')
|
118
116
|
ENV['RUBYLIB'] ? (ENV['RUBYLIB'] += ":#{lib_dir}") : (ENV['RUBYLIB'] = lib_dir)
|
119
|
-
File.read("spec/spec.opts").split("\n")
|
120
117
|
end
|
121
118
|
|
122
119
|
rcov_opts = lambda do
|
@@ -126,7 +123,7 @@ begin
|
|
126
123
|
desc "Run core and model specs with coverage"
|
127
124
|
Spec::Rake::SpecTask.new("spec_coverage") do |t|
|
128
125
|
t.spec_files = Dir["spec/{core,model}/*_spec.rb"]
|
129
|
-
|
126
|
+
spec_opts.call
|
130
127
|
t.rcov, t.rcov_opts = rcov_opts.call
|
131
128
|
end
|
132
129
|
|
@@ -134,44 +131,44 @@ begin
|
|
134
131
|
task :default => [:spec]
|
135
132
|
Spec::Rake::SpecTask.new("spec") do |t|
|
136
133
|
t.spec_files = Dir["spec/{core,model}/*_spec.rb"]
|
137
|
-
|
134
|
+
spec_opts.call
|
138
135
|
end
|
139
136
|
|
140
137
|
desc "Run core specs"
|
141
138
|
Spec::Rake::SpecTask.new("spec_core") do |t|
|
142
139
|
t.spec_files = Dir["spec/core/*_spec.rb"]
|
143
|
-
|
140
|
+
spec_opts.call
|
144
141
|
end
|
145
142
|
|
146
143
|
desc "Run model specs"
|
147
144
|
Spec::Rake::SpecTask.new("spec_model") do |t|
|
148
145
|
t.spec_files = Dir["spec/model/*_spec.rb"]
|
149
|
-
|
146
|
+
spec_opts.call
|
150
147
|
end
|
151
148
|
|
152
149
|
desc "Run extension/plugin specs"
|
153
150
|
Spec::Rake::SpecTask.new("spec_plugin") do |t|
|
154
151
|
t.spec_files = Dir["spec/extensions/*_spec.rb"]
|
155
|
-
|
152
|
+
spec_opts.call
|
156
153
|
end
|
157
154
|
|
158
155
|
desc "Run extention/plugin specs with coverage"
|
159
156
|
Spec::Rake::SpecTask.new("spec_plugin_cov") do |t|
|
160
157
|
t.spec_files = Dir["spec/extensions/*_spec.rb"]
|
161
|
-
|
158
|
+
spec_opts.call
|
162
159
|
t.rcov, t.rcov_opts = rcov_opts.call
|
163
160
|
end
|
164
161
|
|
165
162
|
desc "Run integration tests"
|
166
163
|
Spec::Rake::SpecTask.new("integration") do |t|
|
167
164
|
t.spec_files = Dir["spec/integration/*_test.rb"]
|
168
|
-
|
165
|
+
spec_opts.call
|
169
166
|
end
|
170
167
|
|
171
168
|
desc "Run integration tests with coverage"
|
172
169
|
Spec::Rake::SpecTask.new("integration_cov") do |t|
|
173
170
|
t.spec_files = Dir["spec/integration/*_test.rb"]
|
174
|
-
|
171
|
+
spec_opts.call
|
175
172
|
t.rcov, t.rcov_opts = rcov_opts.call
|
176
173
|
end
|
177
174
|
|
@@ -179,13 +176,13 @@ begin
|
|
179
176
|
desc "Run #{adapter} specs"
|
180
177
|
Spec::Rake::SpecTask.new("spec_#{adapter}") do |t|
|
181
178
|
t.spec_files = ["spec/adapters/#{adapter}_spec.rb"] + Dir["spec/integration/*_test.rb"]
|
182
|
-
|
179
|
+
spec_opts.call
|
183
180
|
end
|
184
181
|
|
185
182
|
desc "Run #{adapter} specs with coverage"
|
186
183
|
Spec::Rake::SpecTask.new("spec_#{adapter}_cov") do |t|
|
187
184
|
t.spec_files = ["spec/adapters/#{adapter}_spec.rb"] + Dir["spec/integration/*_test.rb"]
|
188
|
-
|
185
|
+
spec_opts.call
|
189
186
|
t.rcov, t.rcov_opts = rcov_opts.call
|
190
187
|
end
|
191
188
|
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
New Features
|
2
|
+
------------
|
3
|
+
|
4
|
+
* Sequel now has support for deleting and updating joined datasets
|
5
|
+
on MySQL and PostgreSQL. Previously, Sequel only supported this to
|
6
|
+
a limited extent on Microsoft SQL Server, and support there has been
|
7
|
+
improved as well.
|
8
|
+
|
9
|
+
This allows you to do:
|
10
|
+
|
11
|
+
DB.create_table!(:a){Integer :a; Integer :d}
|
12
|
+
DB.create_table!(:b){Integer :b; Integer :e}
|
13
|
+
DB.create_table!(:c){Integer :c; Integer :f}
|
14
|
+
|
15
|
+
# Insert some rows
|
16
|
+
|
17
|
+
ds = DB.from(:a, :b).
|
18
|
+
join(:c, :c=>:e.identifier).
|
19
|
+
where(:d=>:b)
|
20
|
+
ds.where(:f=>6).update(:a => 10)
|
21
|
+
ds.where(:f=>5).delete
|
22
|
+
|
23
|
+
Which will set the a column to 10 for all rows in table a, where
|
24
|
+
an associated row in table c (through table b) has a value of 6 for
|
25
|
+
column f. It will delete rows from table a where an associated row
|
26
|
+
in table c (through table b) has a value of 5 for column f.
|
27
|
+
|
28
|
+
Sequel assumes the that first FROM table is the table being
|
29
|
+
updated/deleted. MySQL and Microsoft SQL Server do not require
|
30
|
+
multiple FROM tables, but PostgreSQL does.
|
31
|
+
|
32
|
+
* Dataset #select_map, #select_order_map, and #select_hash
|
33
|
+
convenience methods were added for quickly creating arrays and
|
34
|
+
hashes from a dataset.
|
35
|
+
|
36
|
+
select_map and select_order_map both return arrays of values for the
|
37
|
+
column specified. The column can be specified either via an argument
|
38
|
+
or a block, similar to Dataset#get. Both accept any valid objects as
|
39
|
+
arguments.
|
40
|
+
|
41
|
+
select_hash returns a hash. It requires two symbol arguments, but
|
42
|
+
can handle implicit qualifiers or aliases in the symbols.
|
43
|
+
|
44
|
+
Neither of these methods offer any new functionality, they just cut
|
45
|
+
down on the number of required key strokes:
|
46
|
+
|
47
|
+
select_map(:column) # select(:column).map(:column)
|
48
|
+
select_order_map(:column) # select(:column).order(:column).
|
49
|
+
# map(:column)
|
50
|
+
select_hash(:key_column, :value_column)
|
51
|
+
# select(:key_column, :value_column).
|
52
|
+
# to_hash(:key_column, :value_column)
|
53
|
+
|
54
|
+
* The NULL, NOTNULL, TRUE, SQLTRUE, FALSE, and SQLFALSE constants
|
55
|
+
were added to Sequel::SQL::Constants. This allows you to do:
|
56
|
+
|
57
|
+
include Sequel::SQL::Constants
|
58
|
+
DB[:table].where(:a=>'1', :b=>NOTNULL)
|
59
|
+
|
60
|
+
Previously, the shortest way to do this was:
|
61
|
+
|
62
|
+
DB[:table].where(:a=>'1').exclude(:b=>nil)
|
63
|
+
|
64
|
+
It may make the code more descriptive:
|
65
|
+
|
66
|
+
DB[:table].where(:b=>NULL)
|
67
|
+
# compared to
|
68
|
+
DB[:table].where(:b=>nil)
|
69
|
+
|
70
|
+
This gives the option to use SQL terminology instead of ruby
|
71
|
+
terminology.
|
72
|
+
|
73
|
+
The other advantage of using the constants it that they handle
|
74
|
+
operators and methods like other Sequel::SQL objects:
|
75
|
+
|
76
|
+
NULL & SQLFALSE # BooleanExpression => "(NULL AND FALSE)"
|
77
|
+
nil & false # false
|
78
|
+
|
79
|
+
NULL + :a # NumericExpression => "(NULL + a)"
|
80
|
+
nil + :a # raises NoMethodError
|
81
|
+
NULL.sql_string + :a # StringExpression => "(NULL || a)"
|
82
|
+
NULL.as(:b) # AliasedExpression => "NULL AS b"
|
83
|
+
|
84
|
+
For complex systems that want to represent SQL boolean objects
|
85
|
+
in ruby (where you don't know exactly how they'll be used), using
|
86
|
+
the constants is recommended.
|
87
|
+
|
88
|
+
In order not to be too verbose, including Sequel::SQL::Constants
|
89
|
+
is recommended. It's not done by default, but you can still
|
90
|
+
reference the constants under the main Sequel module by default
|
91
|
+
(e.g. Sequel::NULL).
|
92
|
+
|
93
|
+
* The validates_unique method in the validation_helpers plugin now
|
94
|
+
supports an :only_if_modified option, which should speed up the
|
95
|
+
common case where the unique attribute is not modified for an
|
96
|
+
existing record. It's not on by default, since it's possible the
|
97
|
+
database could be changed between retrieving the model object and
|
98
|
+
updating it.
|
99
|
+
|
100
|
+
* The Dataest #union, #intersect, and #except methods now accept an
|
101
|
+
:alias option that it used as the alias for the returned dataset.
|
102
|
+
|
103
|
+
DB[:table].union(DB[:old_table], :alias=>:table)
|
104
|
+
|
105
|
+
* Model#destroy now supports a :transaction option, similar to
|
106
|
+
Model#save.
|
107
|
+
|
108
|
+
* The shared Oracle adapter now supports Dataset#sequence for
|
109
|
+
returning autogenerated primary key values on insert from a
|
110
|
+
related sequence.
|
111
|
+
|
112
|
+
This makes Oracle work correctly when using models, with
|
113
|
+
something like the following:
|
114
|
+
|
115
|
+
class Album < Sequel::Model
|
116
|
+
set_dataset dataset.sequence(:seq_albums_id)
|
117
|
+
end
|
118
|
+
|
119
|
+
You currently need to call Dataset#sequence in every model
|
120
|
+
class where the underlying table uses a sequence to generate
|
121
|
+
primary key values.
|
122
|
+
|
123
|
+
Other Improvements
|
124
|
+
------------------
|
125
|
+
|
126
|
+
* In Model #save and #destroy when using transactions and when
|
127
|
+
raise_on_save_failure is false, ensure that transactions are rolled
|
128
|
+
back if a before hook returns false.
|
129
|
+
|
130
|
+
* Dataset#group_and_count now handles arguments other than Symbols.
|
131
|
+
A previous change to the method raised an exception if a Symbol was
|
132
|
+
not provided. It also handles AliasedExpressions natively, so the
|
133
|
+
following works correctly:
|
134
|
+
|
135
|
+
DB[:table].group_and_count(:column.as(:alias))
|
136
|
+
|
137
|
+
* Sequel no longer uses native autoreconnection in the mysql adapter.
|
138
|
+
Native autoreconnection has problems with prepared statements,
|
139
|
+
where a new native connection is used behind Sequel's back, so
|
140
|
+
Sequel thinks the prepared statement has already been defined on
|
141
|
+
the connection, when it fact it hasn't. Any other changes that
|
142
|
+
affect the state of the connection will be lost when native
|
143
|
+
autoreconnection is used as well.
|
144
|
+
|
145
|
+
Sequel's connection pool already handles reconnection if it detects
|
146
|
+
a disconnection. This commit also adds an additional exception
|
147
|
+
message to recognize as a disconnect. If there other exception
|
148
|
+
messages related to disconnects, please post them on the Sequel
|
149
|
+
mailing list.
|
150
|
+
|
151
|
+
* The schema_dumper plugin now specifies the :type option for primary
|
152
|
+
key if it isn't Integer.
|
153
|
+
|
154
|
+
* On PostgreSQL, the bigserial type is used if :type=>Bignum is
|
155
|
+
given as an option to primary key. This makes it operate more
|
156
|
+
similarly to other adapters that support autoincrementing 64-bit
|
157
|
+
integer primary keys.
|
158
|
+
|
159
|
+
* The native mysql adapter will now attempt to load options in the
|
160
|
+
[client] section of the my.cnf file.
|
161
|
+
|
162
|
+
* The rake spec tasks for the project now work correctly with RSpec
|
163
|
+
1.2.9.
|
164
|
+
|
165
|
+
Backwards Compatibility
|
166
|
+
-----------------------
|
167
|
+
|
168
|
+
* Dataset::GET_ERROR_MSG and Dataset::MAP_ERROR_MSG constants were
|
169
|
+
removed. Both were replaced with Dataset::ARG_BLOCK_ERROR_MSG.
|
170
|
+
|
171
|
+
* The behavior of the Model#save_failure private instance method was
|
172
|
+
modified. It now always raises an exception, and validation
|
173
|
+
failures no longer call it.
|
174
|
+
|
175
|
+
* The internals of how autogenerated primary key metadata is stored
|
176
|
+
when creating tables on PostgreSQL has been modified.
|
177
|
+
|
178
|
+
* The native MySQL adapter no longer sets the OPT_LOCAL_INFILE option
|
179
|
+
to "client" on the native connection.
|
data/doc/virtual_rows.rdoc
CHANGED
@@ -15,6 +15,7 @@ called. This is best shown by example:
|
|
15
15
|
ds.filter{column > 1} # column > 1
|
16
16
|
ds.filter{table__column > 1} # table.column > 1
|
17
17
|
ds.filter{function(1) > 1} # function(1) > 1
|
18
|
+
ds.select{[column1, sum(column2).as(sum)]} # column1, sum(column2) AS sum
|
18
19
|
ds.select{version{}} # version()
|
19
20
|
ds.select{count(:*){}} # count(*)
|
20
21
|
ds.select{count(:distinct, col1){}} # count(DISTINCT col1)
|
@@ -54,3 +55,5 @@ that. If you want to create identifiers or qualified identifiers
|
|
54
55
|
with the same name as existing local variables, make sure ruby
|
55
56
|
knows it is a method call instead of a local variable reference
|
56
57
|
by not ommiting the parentheses at the end of the method call.
|
58
|
+
If you want to return multiple arguments (common for select and
|
59
|
+
order), have the block return an array of arguments.
|
@@ -11,13 +11,16 @@ module Sequel
|
|
11
11
|
# it returns the strings as is. It is false by default, which means that
|
12
12
|
# invalid dates and times will raise errors.
|
13
13
|
#
|
14
|
-
# Sequel::MySQL.convert_invalid_date_time =
|
14
|
+
# Sequel::MySQL.convert_invalid_date_time = nil
|
15
15
|
#
|
16
16
|
# Sequel converts the column type tinyint(1) to a boolean by default when
|
17
17
|
# using the native MySQL adapter. You can turn off the conversion to use
|
18
18
|
# tinyint as an integer:
|
19
19
|
#
|
20
|
-
# Sequel.convert_tinyint_to_bool = false
|
20
|
+
# Sequel::MySQL.convert_tinyint_to_bool = false
|
21
|
+
#
|
22
|
+
# In most cases these settings need to be made after the adapter has been
|
23
|
+
# loaded, since the Sequel::MySQL module probably won't exist before then.
|
21
24
|
module MySQL
|
22
25
|
# Mapping of type numbers to conversion procs
|
23
26
|
MYSQL_TYPES = {}
|
@@ -67,7 +70,7 @@ module Sequel
|
|
67
70
|
include Sequel::MySQL::DatabaseMethods
|
68
71
|
|
69
72
|
# Mysql::Error messages that indicate the current connection should be disconnected
|
70
|
-
MYSQL_DATABASE_DISCONNECT_ERRORS = /\A(Commands out of sync; you can't run this command now
|
73
|
+
MYSQL_DATABASE_DISCONNECT_ERRORS = /\A(Commands out of sync; you can't run this command now|Can't connect to local MySQL server through socket|MySQL server has gone away)/
|
71
74
|
|
72
75
|
set_adapter_scheme :mysql
|
73
76
|
|
@@ -93,7 +96,8 @@ module Sequel
|
|
93
96
|
def connect(server)
|
94
97
|
opts = server_opts(server)
|
95
98
|
conn = Mysql.init
|
96
|
-
|
99
|
+
# reads additional options defined under the [client] tag in the mysql configuration file
|
100
|
+
conn.options(Mysql::READ_DEFAULT_GROUP, "client")
|
97
101
|
if encoding = opts[:encoding] || opts[:charset]
|
98
102
|
# set charset _before_ the connect. using an option instead of "SET (NAMES|CHARACTER_SET_*)" works across reconnects
|
99
103
|
conn.options(Mysql::SET_CHARSET_NAME, encoding)
|
@@ -120,7 +124,6 @@ module Sequel
|
|
120
124
|
attr_accessor :prepared_statements
|
121
125
|
end
|
122
126
|
conn.prepared_statements = {}
|
123
|
-
conn.reconnect = true
|
124
127
|
conn
|
125
128
|
end
|
126
129
|
|
@@ -323,6 +323,11 @@ module Sequel
|
|
323
323
|
false
|
324
324
|
end
|
325
325
|
|
326
|
+
# MSSQL 2005+ supports modifying joined datasets
|
327
|
+
def supports_modifying_joins?
|
328
|
+
true
|
329
|
+
end
|
330
|
+
|
326
331
|
# MSSQL does not support multiple columns for the IN/NOT IN operators
|
327
332
|
def supports_multiple_column_in?
|
328
333
|
false
|
@@ -335,17 +340,26 @@ module Sequel
|
|
335
340
|
|
336
341
|
private
|
337
342
|
|
338
|
-
# MSSQL can modify joined datasets
|
339
|
-
def check_modification_allowed!
|
340
|
-
raise(InvalidOperation, "Grouped datasets cannot be modified") if opts[:group]
|
341
|
-
end
|
342
|
-
|
343
343
|
# MSSQL supports the OUTPUT clause for DELETE statements.
|
344
344
|
# It also allows prepending a WITH clause.
|
345
345
|
def delete_clause_methods
|
346
346
|
DELETE_CLAUSE_METHODS
|
347
347
|
end
|
348
348
|
|
349
|
+
# Only include the primary table in the main delete clause
|
350
|
+
def delete_from_sql(sql)
|
351
|
+
sql << " FROM #{source_list(@opts[:from][0..0])}"
|
352
|
+
end
|
353
|
+
|
354
|
+
# MSSQL supports FROM clauses in DELETE and UPDATE statements.
|
355
|
+
def delete_from2_sql(sql)
|
356
|
+
if joined_dataset?
|
357
|
+
select_from_sql(sql)
|
358
|
+
select_join_sql(sql)
|
359
|
+
end
|
360
|
+
end
|
361
|
+
alias update_from_sql delete_from2_sql
|
362
|
+
|
349
363
|
# Handle the with clause for delete, insert, and update statements
|
350
364
|
# to be the same as the insert statement.
|
351
365
|
def delete_with_sql(sql)
|
@@ -361,16 +375,6 @@ module Sequel
|
|
361
375
|
sprintf(".%03d", usec/1000)
|
362
376
|
end
|
363
377
|
|
364
|
-
# MSSQL supports FROM clauses in DELETE and UPDATE statements.
|
365
|
-
def from_sql(sql)
|
366
|
-
if (opts[:from].is_a?(Array) && opts[:from].size > 1) || opts[:join]
|
367
|
-
select_from_sql(sql)
|
368
|
-
select_join_sql(sql)
|
369
|
-
end
|
370
|
-
end
|
371
|
-
alias delete_from2_sql from_sql
|
372
|
-
alias update_from_sql from_sql
|
373
|
-
|
374
378
|
# MSSQL supports the OUTPUT clause for INSERT statements.
|
375
379
|
# It also allows prepending a WITH clause.
|
376
380
|
def insert_clause_methods
|
@@ -441,6 +445,11 @@ module Sequel
|
|
441
445
|
def update_clause_methods
|
442
446
|
UPDATE_CLAUSE_METHODS
|
443
447
|
end
|
448
|
+
|
449
|
+
# Only include the primary table in the main update clause
|
450
|
+
def update_table_sql(sql)
|
451
|
+
sql << " #{source_list(@opts[:from][0..0])}"
|
452
|
+
end
|
444
453
|
end
|
445
454
|
end
|
446
455
|
end
|
@@ -327,6 +327,11 @@ module Sequel
|
|
327
327
|
false
|
328
328
|
end
|
329
329
|
|
330
|
+
# MySQL supports modifying joined datasets
|
331
|
+
def supports_modifying_joins?
|
332
|
+
true
|
333
|
+
end
|
334
|
+
|
330
335
|
# MySQL does support fractional timestamps in literal timestamps, but it
|
331
336
|
# ignores them. Also, using them seems to cause problems on 1.9. Since
|
332
337
|
# they are ignored anyway, not using them is probably best.
|
@@ -347,6 +352,17 @@ module Sequel
|
|
347
352
|
def delete_clause_methods
|
348
353
|
DELETE_CLAUSE_METHODS
|
349
354
|
end
|
355
|
+
|
356
|
+
# Consider the first table in the joined dataset is the table to delete
|
357
|
+
# from, but include the others for the purposes of selecting rows.
|
358
|
+
def delete_from_sql(sql)
|
359
|
+
if joined_dataset?
|
360
|
+
sql << " #{source_list(@opts[:from][0..0])} FROM #{source_list(@opts[:from])}"
|
361
|
+
select_join_sql(sql)
|
362
|
+
else
|
363
|
+
super
|
364
|
+
end
|
365
|
+
end
|
350
366
|
|
351
367
|
# MySQL supports the IGNORE and ON DUPLICATE KEY UPDATE clauses for INSERT statements
|
352
368
|
def insert_clause_methods
|