sequel 3.6.0 → 3.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|