sequel 4.0.0 → 4.1.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.
- checksums.yaml +4 -4
- data/CHANGELOG +32 -0
- data/doc/active_record.rdoc +2 -2
- data/doc/cheat_sheet.rdoc +0 -5
- data/doc/opening_databases.rdoc +3 -2
- data/doc/prepared_statements.rdoc +6 -0
- data/doc/release_notes/4.1.0.txt +85 -0
- data/doc/schema_modification.rdoc +9 -2
- data/lib/sequel/adapters/jdbc.rb +5 -0
- data/lib/sequel/adapters/mysql2.rb +24 -3
- data/lib/sequel/adapters/odbc.rb +6 -4
- data/lib/sequel/adapters/postgres.rb +25 -0
- data/lib/sequel/adapters/shared/mysql.rb +4 -29
- data/lib/sequel/adapters/shared/postgres.rb +14 -3
- data/lib/sequel/adapters/shared/sqlite.rb +4 -0
- data/lib/sequel/adapters/utils/replace.rb +36 -0
- data/lib/sequel/database/query.rb +1 -0
- data/lib/sequel/database/schema_generator.rb +12 -5
- data/lib/sequel/database/schema_methods.rb +2 -0
- data/lib/sequel/dataset/features.rb +5 -0
- data/lib/sequel/extensions/pg_json_ops.rb +0 -6
- data/lib/sequel/model/associations.rb +1 -1
- data/lib/sequel/plugins/instance_filters.rb +11 -1
- data/lib/sequel/plugins/pg_typecast_on_load.rb +3 -2
- data/lib/sequel/plugins/prepared_statements.rb +38 -9
- data/lib/sequel/plugins/update_primary_key.rb +10 -0
- data/lib/sequel/sql.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mysql_spec.rb +1 -22
- data/spec/adapters/postgres_spec.rb +79 -2
- data/spec/core/database_spec.rb +10 -0
- data/spec/core/dataset_spec.rb +8 -3
- data/spec/core/expression_filters_spec.rb +1 -1
- data/spec/core/schema_spec.rb +17 -2
- data/spec/extensions/caching_spec.rb +2 -2
- data/spec/extensions/hook_class_methods_spec.rb +0 -4
- data/spec/extensions/instance_filters_spec.rb +22 -0
- data/spec/extensions/migration_spec.rb +5 -5
- data/spec/extensions/nested_attributes_spec.rb +4 -4
- data/spec/extensions/prepared_statements_spec.rb +37 -26
- data/spec/extensions/update_primary_key_spec.rb +13 -0
- data/spec/integration/dataset_test.rb +36 -0
- data/spec/model/associations_spec.rb +20 -2
- data/spec/model/hooks_spec.rb +1 -7
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a449facae4b3dcc14c19ce0f524ca2025db4c74e
|
4
|
+
data.tar.gz: 19e4bbb80143055d03da8134f6308363ff8e2406
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 68c5cbe1672f325a040584b37b78188c34322b6505b7b267d61d7103ee8a3f2364e335324f330a4c63e239eb21896c66242c9c62de91b2052d6bc2ad03289dcf
|
7
|
+
data.tar.gz: 0ee8a1dbc5118fa916c90f112142b3580b2dbbfb4a5eca8f3f5924b510043e488cfbc2d1f1335db587a30b8dfe3a3b02754b46586ce770a38b6bc76ddb004fd0
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,35 @@
|
|
1
|
+
=== 4.1.0 (2013-08-01)
|
2
|
+
|
3
|
+
* Support :inherits option in Database#create_table on PostgreSQL, for table inheritance (jeremyevans)
|
4
|
+
|
5
|
+
* Handle dropping indexes for schema qualified tables on PostgreSQL (jeremyevans)
|
6
|
+
|
7
|
+
* Add Database#error_info on PostgreSQL 9.3+ if pg-0.16.0+ is used, to get a hash of metadata for a given database exception (jeremyevans)
|
8
|
+
|
9
|
+
* Allow prepared_statements plugin to work with instance_filters and update_primary_key plugins (jeremyevans)
|
10
|
+
|
11
|
+
* Support deferrable exclusion constraints on PostgreSQL using the :deferrable option (mfoody) (#687)
|
12
|
+
|
13
|
+
* Make Database#run and #<< accept SQL::PlaceholderLiteralString values (jeremyevans)
|
14
|
+
|
15
|
+
* Deprecate :driver option in odbc adapter since it appears to be broken (jeremyevans)
|
16
|
+
|
17
|
+
* Support :drvconnect option in odbc adapter for supplying the ODBC connection string directly (jeremyevans)
|
18
|
+
|
19
|
+
* Support mysql2 0.3.12+ result streaming via Dataset#stream (jeremyevans)
|
20
|
+
|
21
|
+
* Convert Java::JavaUtil::HashMap to ruby Hash in jdbc adapter, for better handling of PostgreSQL hstore type (jeremyevans) (#686)
|
22
|
+
|
23
|
+
* Raise NoMatchingRow if calling add_association with a primary key value that doesn't match an existing row (jeremyevans)
|
24
|
+
|
25
|
+
* Allow PostgreSQL add_constraint to support :not_valid option (jeremyevans)
|
26
|
+
|
27
|
+
* Allow CHECK constraints to have options by using an options hash as the constraint name (jeremyevans)
|
28
|
+
|
29
|
+
* Correctly raise error when using an invalid virtual row block function call (jeremyevans)
|
30
|
+
|
31
|
+
* Support REPLACE on SQLite via Dataset#replace and #multi_replace (etehtsea) (#681)
|
32
|
+
|
1
33
|
=== 4.0.0 (2013-07-01)
|
2
34
|
|
3
35
|
* Correctly parse composite primary keys on SQLite 3.7.16+ (jeremyevans)
|
data/doc/active_record.rdoc
CHANGED
@@ -742,12 +742,12 @@ ActiveRecord Method :: Notes, Workarounds
|
|
742
742
|
<tt>clear_active_connections!</tt> :: Sequel doesn't leak connections like ActiveRecord, so you don't need to worry about this
|
743
743
|
<tt>clear_reloadable_connections!</tt> :: Sequel doesn't leak connections like ActiveRecord, so you don't need to worry about this
|
744
744
|
+content_columns+ :: Not needed internally, you can probably do <tt>Album.columns.map{|x| x.to_s}.delete_if{|x| x == Album.primary_key || x =~ /_(id|count)\z/}</tt>
|
745
|
-
+decrement_counter+ :: <tt>Album.where(:id=>:id).update(:counter_name
|
745
|
+
+decrement_counter+ :: <tt>Album.where(:id=>:id).update(:counter_name=>Sequel.-(:counter_name, 1))</tt>
|
746
746
|
+define_attribute_methods+, +define_read_methods+ :: <tt>def_column_accessor(*columns)</tt>, a private method
|
747
747
|
<tt>descends_from_active_record?</tt> :: Not needed internally, if using single table inheritance, <tt>Album.sti_dataset.model == Album</tt>
|
748
748
|
+find_each+, +find_in_batches+ :: Use the +pagination+ extension
|
749
749
|
<tt>generated_methods?</tt> :: No equivalent
|
750
|
-
+increment_counter+ :: <tt>Album.where(:id=>:id).update(:counter_name
|
750
|
+
+increment_counter+ :: <tt>Album.where(:id=>:id).update(:counter_name=>Sequel.+(:counter_name, 1))</tt>
|
751
751
|
<tt>instance_method_already_implemented?</tt> :: No equivalent, Sequel does not create column accessors that override other methods, it just skips them.
|
752
752
|
<tt>match_attribute_method?</tt> :: No equivalent
|
753
753
|
+readonly_attributes+ :: No equivalent
|
data/doc/cheat_sheet.rdoc
CHANGED
@@ -166,11 +166,6 @@ Without a filename argument, the sqlite adapter will setup a new sqlite database
|
|
166
166
|
|
167
167
|
DB.drop_table :items
|
168
168
|
|
169
|
-
DB.create_table :test do
|
170
|
-
String :zipcode
|
171
|
-
enum :system, :elements => ['mac', 'linux', 'windows']
|
172
|
-
end
|
173
|
-
|
174
169
|
== Aliasing
|
175
170
|
|
176
171
|
DB[:items].select(Sequel.as(:name, :item_name))
|
data/doc/opening_databases.rdoc
CHANGED
@@ -321,8 +321,9 @@ The :database option given ODBC database should be the DSN (Descriptive Service
|
|
321
321
|
|
322
322
|
The :host and :port options are not respected. The following additional options are supported:
|
323
323
|
|
324
|
-
:db_type :: Can be specified as 'mssql' or '
|
325
|
-
:
|
324
|
+
:db_type :: Can be specified as 'mssql', 'progress', or 'db2' to use SQL syntax specific to those databases.
|
325
|
+
:drvconnect :: Can be given an ODBC connection string, and will use ODBC::Database#drvconnect to
|
326
|
+
do the connection. Typical usage would be: <tt>Sequel.odbc(:drvconnect=>'driver={...};...')</tt>
|
326
327
|
|
327
328
|
=== openbase
|
328
329
|
|
@@ -31,6 +31,12 @@ placeholders, e.g.:
|
|
31
31
|
|
32
32
|
ds = DB[:items].where(:name=>:$n)
|
33
33
|
|
34
|
+
You can use these placeholders in most places where you can use the value
|
35
|
+
directly. For example, if you want to use placeholders while also using
|
36
|
+
raw SQL, you can do:
|
37
|
+
|
38
|
+
ds = DB["SELECT * FROM items WHERE name = ?", :$n]
|
39
|
+
|
34
40
|
== Bound Variables
|
35
41
|
|
36
42
|
Using bound variables for this query is simple:
|
@@ -0,0 +1,85 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* Database#run and #<< now accept SQL::PlaceholderLiteralString
|
4
|
+
objects, allowing you to more easily run arbitrary DDL queries with
|
5
|
+
placeholders:
|
6
|
+
|
7
|
+
DB.run Sequel.lit("CREATE TABLE ? (? integer)", :table, :column)
|
8
|
+
|
9
|
+
* You can now provide options for check constraints by calling the
|
10
|
+
constraint/add_constraint methods with a hash as the first argument.
|
11
|
+
On PostgreSQL, you can now use the :not_valid option for check
|
12
|
+
constraints, so they are enforced for inserts and updates, but
|
13
|
+
not for existing rows.
|
14
|
+
|
15
|
+
DB.create_table(:table) do
|
16
|
+
...
|
17
|
+
constraint({:name=>:constraint_name, :not_valid=>true}) do
|
18
|
+
column_name > 10
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
* Dataset#stream has been added to the mysql2 adapter, and will have
|
23
|
+
the dataset stream results if used with mysql2 0.3.12+. This
|
24
|
+
allows you to process large datasets without keeping the entire
|
25
|
+
dataset in memory.
|
26
|
+
|
27
|
+
DB[:large_table].stream.each{|r| ...}
|
28
|
+
|
29
|
+
* Database#error_info has been added to the postgres adapter. It
|
30
|
+
is supported on PostgreSQL 9.3+ if pg-0.16.0+ is used as the
|
31
|
+
underlying driver, and it gives you a hash of metadata related
|
32
|
+
to the exception:
|
33
|
+
|
34
|
+
DB[:table_name].insert(1) rescue DB.error_info($!)
|
35
|
+
# => {:schema=>"public", :table=>"table_name", :column=>nil,
|
36
|
+
:constraint=>"constraint_name", :type=>nil}
|
37
|
+
|
38
|
+
* The :deferrable option is now supported when adding exclusion
|
39
|
+
constraints on PostgreSQL, to allow setting up deferred exclusion
|
40
|
+
constraints.
|
41
|
+
|
42
|
+
* The :inherits option is now supported in Database#create_table on
|
43
|
+
PostgreSQL, for table inheritance:
|
44
|
+
|
45
|
+
DB.create_table(:t1, :inherits=>:t0){}
|
46
|
+
# CREATE TABLE t1 () INHERITS (t0)
|
47
|
+
|
48
|
+
* Dataset#replace and #multi_replace are now supported on SQLite,
|
49
|
+
just as they have been previously on MySQL.
|
50
|
+
|
51
|
+
* In the jdbc adapter, Java::JavaUtil::HashMap objects are now
|
52
|
+
converted to ruby Hash objects. This is to make it easier to
|
53
|
+
handle the PostgreSQL hstore type when using the jdbc/postgres
|
54
|
+
adapter.
|
55
|
+
|
56
|
+
* The odbc adapter now supports a :drvconnect option that accepts
|
57
|
+
an ODBC connection string that is passed to ruby-odbc verbatim.
|
58
|
+
|
59
|
+
= Other Improvements
|
60
|
+
|
61
|
+
* The prepared_statements plugin no longer breaks the
|
62
|
+
instance_filters and update_primary_key plugins.
|
63
|
+
|
64
|
+
* Dropping indexes for tables in a specific schema is now supported
|
65
|
+
on PostgreSQL. Sequel now explicitly specifies the same schema
|
66
|
+
as the table when dropping such indexes.
|
67
|
+
|
68
|
+
* Calling Model#add_association methods with a primary key value
|
69
|
+
now raises a Sequel::NoMatchingRow if there is no object in the
|
70
|
+
associated table with that primary key. Previously, this
|
71
|
+
situation was not handled and resulted in a NoMethodError being
|
72
|
+
raised later.
|
73
|
+
|
74
|
+
* When an invalid virtual row block function call is detected, an
|
75
|
+
error is now properly raised. Previously, the error was not
|
76
|
+
raised until the SQL was produced for the query.
|
77
|
+
|
78
|
+
= Backwards Compatibility
|
79
|
+
|
80
|
+
* The :driver option to the odbc adapter is deprecated and will be
|
81
|
+
removed in a future version. It is thought to be broken, and
|
82
|
+
users wanting to use DSN-less connections should use the new
|
83
|
+
:drvconnect option.
|
84
|
+
|
85
|
+
* The Postgres::ArrayOp#text_op private method has been removed.
|
@@ -88,6 +88,9 @@ method, the fourth argument is the options hash. The following options are supp
|
|
88
88
|
:primary_key :: Mark this column as the primary key. This is used instead of the
|
89
89
|
primary key method if you want a non-autoincrementing primary key.
|
90
90
|
:primary_key_constraint_name :: The name to give the primary key constraint.
|
91
|
+
:type :: Overrides the type given as the method name or a separate argument.
|
92
|
+
Not usually used by +column+ itself, but often by other methods such
|
93
|
+
as +primary_key+ or +foreign_key+.
|
91
94
|
:unique :: Mark the column as unique, generally has the same effect as
|
92
95
|
creating a unique index on the column.
|
93
96
|
:unique_constraint_name :: The name to give the unique key constraint.
|
@@ -137,12 +140,16 @@ as it's third argument. A simple example is:
|
|
137
140
|
String :name
|
138
141
|
end
|
139
142
|
|
140
|
-
+foreign_key+ accepts
|
143
|
+
+foreign_key+ accepts the same options as +column+. For example, to have a unique foreign key with varchar(16) type:
|
144
|
+
|
145
|
+
foreign_key :column_name, :unique=>true, :type=>'varchar(16)'
|
146
|
+
|
147
|
+
+foreign_key+ also accepts some specific options:
|
141
148
|
|
142
149
|
:deferrable :: Makes the foreign key constraint checks deferrable, so they aren't checked
|
143
150
|
until the end of the transaction.
|
144
151
|
:foreign_key_constraint_name :: The name to give the foreign key constraint.
|
145
|
-
:key ::
|
152
|
+
:key :: The column in the associated table
|
146
153
|
that this column references. Unnecessary if this column
|
147
154
|
references the primary key of the associated table, at least
|
148
155
|
on most databases.
|
data/lib/sequel/adapters/jdbc.rb
CHANGED
@@ -696,6 +696,7 @@ module Sequel
|
|
696
696
|
JAVA_BIG_DECIMAL = Java::JavaMath::BigDecimal
|
697
697
|
JAVA_BYTE_ARRAY = Java::byte[]
|
698
698
|
JAVA_UUID = Java::JavaUtil::UUID
|
699
|
+
JAVA_HASH_MAP = Java::JavaUtil::HashMap
|
699
700
|
|
700
701
|
# Handle type conversions for common Java types.
|
701
702
|
class TYPE_TRANSLATOR
|
@@ -717,6 +718,7 @@ module Sequel
|
|
717
718
|
lines
|
718
719
|
end
|
719
720
|
def uuid(v) v.to_string end
|
721
|
+
def hash_map(v) v.to_hash end
|
720
722
|
end
|
721
723
|
TYPE_TRANSLATOR_INSTANCE = tt = TYPE_TRANSLATOR.new
|
722
724
|
|
@@ -730,6 +732,7 @@ module Sequel
|
|
730
732
|
BLOB_METHOD = tt.method(:blob)
|
731
733
|
CLOB_METHOD = tt.method(:clob)
|
732
734
|
UUID_METHOD = tt.method(:uuid)
|
735
|
+
HASH_MAP_METHOD = tt.method(:hash_map)
|
733
736
|
|
734
737
|
# Convert the given Java timestamp to an instance of Sequel.datetime_class.
|
735
738
|
def convert_type_timestamp(v)
|
@@ -759,6 +762,8 @@ module Sequel
|
|
759
762
|
CLOB_METHOD
|
760
763
|
when JAVA_UUID
|
761
764
|
UUID_METHOD
|
765
|
+
when JAVA_HASH_MAP
|
766
|
+
HASH_MAP_METHOD
|
762
767
|
else
|
763
768
|
false
|
764
769
|
end
|
@@ -72,9 +72,23 @@ module Sequel
|
|
72
72
|
# yield the connection if a block is given.
|
73
73
|
def _execute(conn, sql, opts)
|
74
74
|
begin
|
75
|
-
|
75
|
+
stream = opts[:stream]
|
76
|
+
r = log_yield((log_sql = opts[:log_sql]) ? sql + log_sql : sql){conn.query(sql, :database_timezone => timezone, :application_timezone => Sequel.application_timezone, :stream=>stream)}
|
76
77
|
if opts[:type] == :select
|
77
|
-
|
78
|
+
if r
|
79
|
+
if stream
|
80
|
+
begin
|
81
|
+
r2 = yield r
|
82
|
+
ensure
|
83
|
+
# If r2 is nil, it means the block did not exit normally,
|
84
|
+
# so the rest of the results must be drained to prevent
|
85
|
+
# "commands out of sync" errors.
|
86
|
+
r.each{} unless r2
|
87
|
+
end
|
88
|
+
else
|
89
|
+
yield r
|
90
|
+
end
|
91
|
+
end
|
78
92
|
elsif block_given?
|
79
93
|
yield conn
|
80
94
|
end
|
@@ -145,6 +159,13 @@ module Sequel
|
|
145
159
|
self
|
146
160
|
end
|
147
161
|
|
162
|
+
# Return a clone of the dataset that will stream rows when iterating
|
163
|
+
# over the result set, so it can handle large datasets that
|
164
|
+
# won't fit in memory (Requires mysql 0.3.12 to have an effect).
|
165
|
+
def stream
|
166
|
+
clone(:stream=>true)
|
167
|
+
end
|
168
|
+
|
148
169
|
private
|
149
170
|
|
150
171
|
# Whether to cast tinyint(1) columns to integer instead of boolean.
|
@@ -156,7 +177,7 @@ module Sequel
|
|
156
177
|
|
157
178
|
# Set the :type option to :select if it hasn't been set.
|
158
179
|
def execute(sql, opts=OPTS, &block)
|
159
|
-
super(sql, {:type=>:select}.merge(opts), &block)
|
180
|
+
super(sql, {:type=>:select, :stream=>@opts[:stream]}.merge(opts), &block)
|
160
181
|
end
|
161
182
|
|
162
183
|
# Handle correct quoting of strings using ::Mysql2::Client#escape.
|
data/lib/sequel/adapters/odbc.rb
CHANGED
@@ -11,7 +11,10 @@ module Sequel
|
|
11
11
|
|
12
12
|
def connect(server)
|
13
13
|
opts = server_opts(server)
|
14
|
-
if opts.include?
|
14
|
+
conn = if opts.include?(:drvconnect)
|
15
|
+
::ODBC::Database.new.drvconnect(opts[:drvconnect])
|
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.")
|
15
18
|
drv = ::ODBC::Driver.new
|
16
19
|
drv.name = 'Sequel ODBC Driver130'
|
17
20
|
opts.each do |param, value|
|
@@ -20,10 +23,9 @@ module Sequel
|
|
20
23
|
end
|
21
24
|
drv.attrs[param.to_s.upcase] = value.to_s
|
22
25
|
end
|
23
|
-
|
24
|
-
conn = db.drvconnect(drv)
|
26
|
+
::ODBC::Database.new.drvconnect(drv)
|
25
27
|
else
|
26
|
-
|
28
|
+
::ODBC::connect(opts[:database], opts[:user], opts[:password])
|
27
29
|
end
|
28
30
|
conn.autocommit = true
|
29
31
|
conn
|
@@ -276,6 +276,31 @@ module Sequel
|
|
276
276
|
rescue PGError, IOError
|
277
277
|
end
|
278
278
|
end
|
279
|
+
|
280
|
+
if SEQUEL_POSTGRES_USES_PG && Object.const_defined?(:PG) && ::PG.const_defined?(:Constants) && ::PG::Constants.const_defined?(:PG_DIAG_SCHEMA_NAME)
|
281
|
+
# Return a hash of information about the related PGError (or Sequel::DatabaseError that
|
282
|
+
# wraps a PGError), with the following entries:
|
283
|
+
#
|
284
|
+
# :schema :: The schema name related to the error
|
285
|
+
# :table :: The table name related to the error
|
286
|
+
# :column :: the column name related to the error
|
287
|
+
# :constraint :: The constraint name related to the error
|
288
|
+
# :type :: The datatype name related to the error
|
289
|
+
#
|
290
|
+
# This requires a PostgreSQL 9.3+ server and 9.3+ client library,
|
291
|
+
# and ruby-pg 0.16.0+ to be supported.
|
292
|
+
def error_info(e)
|
293
|
+
e = e.wrapped_exception if e.is_a?(DatabaseError)
|
294
|
+
r = e.result
|
295
|
+
h = {}
|
296
|
+
h[:schema] = r.error_field(::PG::PG_DIAG_SCHEMA_NAME)
|
297
|
+
h[:table] = r.error_field(::PG::PG_DIAG_TABLE_NAME)
|
298
|
+
h[:column] = r.error_field(::PG::PG_DIAG_COLUMN_NAME)
|
299
|
+
h[:constraint] = r.error_field(::PG::PG_DIAG_CONSTRAINT_NAME)
|
300
|
+
h[:type] = r.error_field(::PG::PG_DIAG_DATATYPE_NAME)
|
301
|
+
h
|
302
|
+
end
|
303
|
+
end
|
279
304
|
|
280
305
|
# Execute the given SQL with the given args on an available connection.
|
281
306
|
def execute(sql, opts=OPTS, &block)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
Sequel.require 'adapters/utils/split_alter_table'
|
2
|
+
Sequel.require 'adapters/utils/replace'
|
2
3
|
|
3
4
|
module Sequel
|
4
5
|
Dataset::NON_SQL_OPTIONS << :insert_ignore
|
@@ -532,7 +533,6 @@ module Sequel
|
|
532
533
|
PAREN_CLOSE = Dataset::PAREN_CLOSE
|
533
534
|
NOT_SPACE = Dataset::NOT_SPACE
|
534
535
|
FROM = Dataset::FROM
|
535
|
-
INSERT = Dataset::INSERT
|
536
536
|
COMMA = Dataset::COMMA
|
537
537
|
LIMIT = Dataset::LIMIT
|
538
538
|
GROUP_BY = Dataset::GROUP_BY
|
@@ -552,7 +552,6 @@ module Sequel
|
|
552
552
|
EMPTY_COLUMNS = " ()".freeze
|
553
553
|
EMPTY_VALUES = " VALUES ()".freeze
|
554
554
|
IGNORE = " IGNORE".freeze
|
555
|
-
REPLACE = 'REPLACE'.freeze
|
556
555
|
ON_DUPLICATE_KEY_UPDATE = " ON DUPLICATE KEY UPDATE ".freeze
|
557
556
|
EQ_VALUES = '=VALUES('.freeze
|
558
557
|
EQ = '='.freeze
|
@@ -565,7 +564,9 @@ module Sequel
|
|
565
564
|
QUAD_BACKSLASH = "\\\\\\\\".freeze
|
566
565
|
BLOB_START = "0x".freeze
|
567
566
|
HSTAR = "H*".freeze
|
568
|
-
|
567
|
+
|
568
|
+
include Sequel::Dataset::Replace
|
569
|
+
|
569
570
|
# MySQL specific syntax for LIKE/REGEXP searches, as well as
|
570
571
|
# string concatenation.
|
571
572
|
def complex_expression_sql_append(sql, op, args)
|
@@ -647,11 +648,6 @@ module Sequel
|
|
647
648
|
SQL::PlaceholderLiteralString.new((opts[:boolean] ? MATCH_AGAINST_BOOLEAN : MATCH_AGAINST), [Array(cols), terms])
|
648
649
|
end
|
649
650
|
|
650
|
-
# MySQL allows HAVING clause on ungrouped datasets.
|
651
|
-
def having(*cond, &block)
|
652
|
-
_filter(:having, *cond, &block)
|
653
|
-
end
|
654
|
-
|
655
651
|
# Transforms an CROSS JOIN to an INNER JOIN if the expr is not nil.
|
656
652
|
# Raises an error on use of :full_outer type, since MySQL doesn't support it.
|
657
653
|
def join_table(type, table, expr=nil, opts=OPTS, &block)
|
@@ -719,23 +715,7 @@ module Sequel
|
|
719
715
|
def quoted_identifier_append(sql, c)
|
720
716
|
sql << BACKTICK << c.to_s.gsub(BACKTICK_RE, DOUBLE_BACKTICK) << BACKTICK
|
721
717
|
end
|
722
|
-
|
723
|
-
# Execute a REPLACE statement on the database.
|
724
|
-
def replace(*values)
|
725
|
-
execute_insert(replace_sql(*values))
|
726
|
-
end
|
727
718
|
|
728
|
-
# MySQL specific syntax for REPLACE (aka UPSERT, or update if exists,
|
729
|
-
# insert if it doesn't).
|
730
|
-
def replace_sql(*values)
|
731
|
-
clone(:replace=>true).insert_sql(*values)
|
732
|
-
end
|
733
|
-
|
734
|
-
# Replace multiple rows in a single query.
|
735
|
-
def multi_replace(*values)
|
736
|
-
clone(:replace=>true).multi_insert(*values)
|
737
|
-
end
|
738
|
-
|
739
719
|
# MySQL can emulate DISTINCT ON with its non-standard GROUP BY implementation,
|
740
720
|
# though the rows returned cannot be made deterministic through ordering.
|
741
721
|
def supports_distinct_on?
|
@@ -832,11 +812,6 @@ module Sequel
|
|
832
812
|
sql << IGNORE if opts[:update_ignore]
|
833
813
|
end
|
834
814
|
|
835
|
-
# If this is an replace instead of an insert, use replace instead
|
836
|
-
def insert_insert_sql(sql)
|
837
|
-
sql << (@opts[:replace] ? REPLACE : INSERT)
|
838
|
-
end
|
839
|
-
|
840
815
|
# MySQL supports INSERT ... ON DUPLICATE KEY UPDATE
|
841
816
|
def insert_on_duplicate_key_update_sql(sql)
|
842
817
|
if update_cols = opts[:on_duplicate_key_update]
|
@@ -636,8 +636,10 @@ module Sequel
|
|
636
636
|
case constraint[:type]
|
637
637
|
when :exclude
|
638
638
|
elements = constraint[:elements].map{|c, op| "#{literal(c)} WITH #{op}"}.join(', ')
|
639
|
-
"#{"CONSTRAINT #{quote_identifier(constraint[:name])} " if constraint[:name]}EXCLUDE USING #{constraint[:using]||'gist'} (#{elements})#{" WHERE #{filter_expr(constraint[:where])}" if constraint[:where]}"
|
640
|
-
|
639
|
+
sql = "#{"CONSTRAINT #{quote_identifier(constraint[:name])} " if constraint[:name]}EXCLUDE USING #{constraint[:using]||'gist'} (#{elements})#{" WHERE #{filter_expr(constraint[:where])}" if constraint[:where]}"
|
640
|
+
constraint_deferrable_sql_append(sql, constraint[:deferrable])
|
641
|
+
sql
|
642
|
+
when :foreign_key, :check
|
641
643
|
sql = super
|
642
644
|
if constraint[:not_valid]
|
643
645
|
sql << " NOT VALID"
|
@@ -768,6 +770,14 @@ module Sequel
|
|
768
770
|
"CREATE #{temp_or_unlogged_sql}TABLE#{' IF NOT EXISTS' if options[:if_not_exists]} #{options[:temp] ? quote_identifier(name) : quote_schema_table(name)}"
|
769
771
|
end
|
770
772
|
|
773
|
+
def create_table_sql(name, generator, options)
|
774
|
+
sql = super
|
775
|
+
if inherits = options[:inherits]
|
776
|
+
sql << " INHERITS (#{Array(inherits).map{|t| quote_schema_table(t)}.join(', ')})"
|
777
|
+
end
|
778
|
+
sql
|
779
|
+
end
|
780
|
+
|
771
781
|
# Use a PostgreSQL-specific create table generator
|
772
782
|
def create_table_generator_class
|
773
783
|
Postgres::CreateTableGenerator
|
@@ -797,7 +807,8 @@ module Sequel
|
|
797
807
|
|
798
808
|
# Support :if_exists, :cascade, and :concurrently options.
|
799
809
|
def drop_index_sql(table, op)
|
800
|
-
|
810
|
+
sch, _ = schema_and_table(table)
|
811
|
+
"DROP INDEX#{' CONCURRENTLY' if op[:concurrently]}#{' IF EXISTS' if op[:if_exists]} #{"#{quote_identifier(sch)}." if sch}#{quote_identifier(op[:name] || default_index_name(table, op[:columns]))}#{' CASCADE' if op[:cascade]}"
|
801
812
|
end
|
802
813
|
|
803
814
|
# SQL for dropping a procedural language from the database.
|