sequel 5.8.0 → 5.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +30 -0
- data/doc/release_notes/5.9.0.txt +99 -0
- data/doc/testing.rdoc +10 -10
- data/lib/sequel/adapters/ado.rb +1 -1
- data/lib/sequel/adapters/amalgalite.rb +1 -1
- data/lib/sequel/adapters/jdbc.rb +19 -7
- data/lib/sequel/adapters/jdbc/oracle.rb +1 -1
- data/lib/sequel/adapters/jdbc/postgresql.rb +0 -5
- data/lib/sequel/adapters/postgres.rb +3 -3
- data/lib/sequel/adapters/shared/access.rb +5 -6
- data/lib/sequel/adapters/shared/mysql.rb +28 -2
- data/lib/sequel/adapters/shared/postgres.rb +16 -6
- data/lib/sequel/adapters/shared/sqlite.rb +1 -1
- data/lib/sequel/adapters/sqlanywhere.rb +1 -1
- data/lib/sequel/adapters/sqlite.rb +2 -2
- data/lib/sequel/connection_pool.rb +2 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +12 -4
- data/lib/sequel/connection_pool/threaded.rb +19 -7
- data/lib/sequel/core.rb +1 -1
- data/lib/sequel/database/connecting.rb +6 -6
- data/lib/sequel/database/misc.rb +3 -3
- data/lib/sequel/database/query.rb +2 -2
- data/lib/sequel/database/schema_generator.rb +9 -3
- data/lib/sequel/database/schema_methods.rb +12 -5
- data/lib/sequel/dataset/features.rb +5 -0
- data/lib/sequel/dataset/misc.rb +1 -1
- data/lib/sequel/dataset/prepared_statements.rb +4 -4
- data/lib/sequel/dataset/query.rb +5 -0
- data/lib/sequel/dataset/sql.rb +8 -6
- data/lib/sequel/extensions/escaped_like.rb +100 -0
- data/lib/sequel/extensions/eval_inspect.rb +3 -1
- data/lib/sequel/extensions/looser_typecasting.rb +3 -3
- data/lib/sequel/extensions/pg_extended_date_support.rb +23 -10
- data/lib/sequel/model/associations.rb +18 -4
- data/lib/sequel/model/base.rb +9 -2
- data/lib/sequel/plugins/defaults_setter.rb +1 -1
- data/lib/sequel/plugins/many_through_many.rb +1 -1
- data/lib/sequel/plugins/nested_attributes.rb +2 -2
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +2 -2
- data/lib/sequel/plugins/rcte_tree.rb +5 -7
- data/lib/sequel/plugins/sharding.rb +2 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +1 -1
- data/lib/sequel/plugins/tree.rb +2 -2
- data/lib/sequel/plugins/validation_class_methods.rb +1 -1
- data/lib/sequel/sql.rb +2 -2
- data/lib/sequel/version.rb +4 -1
- data/spec/adapters/mysql_spec.rb +24 -0
- data/spec/adapters/postgres_spec.rb +9 -9
- data/spec/adapters/sqlite_spec.rb +10 -10
- data/spec/core/connection_pool_spec.rb +22 -0
- data/spec/core/database_spec.rb +6 -6
- data/spec/core/dataset_spec.rb +16 -5
- data/spec/core/expression_filters_spec.rb +1 -1
- data/spec/core/schema_spec.rb +1 -1
- data/spec/core/version_spec.rb +7 -0
- data/spec/extensions/connection_expiration_spec.rb +20 -2
- data/spec/extensions/connection_validator_spec.rb +20 -3
- data/spec/extensions/escaped_like_spec.rb +40 -0
- data/spec/extensions/eval_inspect_spec.rb +1 -1
- data/spec/extensions/nested_attributes_spec.rb +6 -0
- data/spec/extensions/pg_array_spec.rb +13 -13
- data/spec/extensions/pg_auto_constraint_validations_spec.rb +0 -1
- data/spec/extensions/pg_range_spec.rb +1 -1
- data/spec/extensions/schema_dumper_spec.rb +2 -2
- data/spec/extensions/sql_expr_spec.rb +1 -1
- data/spec/extensions/string_agg_spec.rb +1 -1
- data/spec/extensions/timestamps_spec.rb +2 -2
- data/spec/extensions/validation_helpers_spec.rb +1 -1
- data/spec/integration/associations_test.rb +12 -0
- data/spec/integration/dataset_test.rb +21 -0
- data/spec/integration/type_test.rb +4 -4
- data/spec/model/base_spec.rb +9 -0
- data/spec/model/eager_loading_spec.rb +25 -0
- data/spec/model/record_spec.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49e114f3c425c0cdcd798fdcb170ac2112fada51077235f8e53b3d9a3940954a
|
4
|
+
data.tar.gz: db61fd6ab89b98c48fd2461f500db1f35afd2624808721733a8efbdc4c14a9ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff2793a7d47c0fe5ff7669ef248cd2c66bd1761f36a9ca0d2742adb8ee59be88a12264df0155864e7ac34f2795ff8f1a633d4e97fc87bcd9bb7976e93b67615b
|
7
|
+
data.tar.gz: a5996916449312e4a83ecc1e4bdaf2a3789c98321fa622389d675b3b6caf5cc84ce9e413198c2d875d0963ac07b7f3b59f2e80cd50b7eb9f45110b1f87263489
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,33 @@
|
|
1
|
+
=== 5.9.0 (2018-06-01)
|
2
|
+
|
3
|
+
* Support generated columns on MySQL 5.7+ and MariaDB 5.2+ (wjordan, jeremyevans) (#1517)
|
4
|
+
|
5
|
+
* Add escaped_like extension for creation of LIKE expressions with placeholders in the pattern without access to a dataset (jeremyevans)
|
6
|
+
|
7
|
+
* Modify jdbc adapter exception handling to work around ::NativeException deprecation in JRuby 9.2 (jeremyevans)
|
8
|
+
|
9
|
+
* Work around broken BC date handling in JRuby 9.2.0.0 (jeremyevans)
|
10
|
+
|
11
|
+
* Switch use of BigDecimal.new() to BigDecimal(), since the former is deprecated (jeremyevans)
|
12
|
+
|
13
|
+
* Add Sequel::VERSION_NUMBER for easier version comparisons (jeremyevans)
|
14
|
+
|
15
|
+
* Add Model.has_dataset? to determine if the model class has a dataset (AlexWayfer) (#1508)
|
16
|
+
|
17
|
+
* Support use of LIKE with ANY function on PostgreSQL by avoiding unnecessary use of ESCAPE syntax (jeremyevans)
|
18
|
+
|
19
|
+
* Disconnect connections left allocated by dead threads instead of returning the connections to the pool (jeremyevans)
|
20
|
+
|
21
|
+
* Make both threaded connection pools avoid disconnecting connections while holding the connection pool mutex (jeremyevans)
|
22
|
+
|
23
|
+
* Don't deadlock when disconnecting connections in the sharded_threaded connection pool when using connection_validator or connection_expiration extensions (jeremyevans)
|
24
|
+
|
25
|
+
* Don't modify hash argument passed in Model.nested_attributes in the nested_attributes plugin (jeremyevans)
|
26
|
+
|
27
|
+
* Avoid unnecessary hash creation in many places (jeremyevans)
|
28
|
+
|
29
|
+
* Fix duplicate objects in nested associations when eager_graphing cascaded many_to_one=>one_to_many associations (jeremyevans)
|
30
|
+
|
1
31
|
=== 5.8.0 (2018-05-01)
|
2
32
|
|
3
33
|
* Don't mark SQLAnywhere as supporting WITH in INSERT statement (jeremyevans)
|
@@ -0,0 +1,99 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* An escaped_like extension has been added, for the creation of
|
4
|
+
LIKE/ILIKE expressions with placeholders in patterns without
|
5
|
+
access to a dataset. This adds escaped_like and escaped_ilike
|
6
|
+
methods to the same Sequel expression objects that support like
|
7
|
+
and ilike. These methods take two arguments, the first being
|
8
|
+
the pattern, with ? placeholders, and the second being the
|
9
|
+
placeholder value (which can be an array for multiple
|
10
|
+
placeholders):
|
11
|
+
|
12
|
+
Sequel.extension :escaped_like
|
13
|
+
DB[:table].where{string_column.escaped_like('?%', user_input)}
|
14
|
+
# user_input is 'foo':
|
15
|
+
# SELECT * FROM table WHERE string_column LIKE 'foo%'
|
16
|
+
# user_input is '%foo':
|
17
|
+
# SELECT * FROM table WHERE string_column LIKE '\%foo%'
|
18
|
+
|
19
|
+
* Generated columns on MySQL 5.7+ and MariaDB 5.2+ are now supported
|
20
|
+
using the :generated_always_as option when creating the column.
|
21
|
+
The :generated_type option can also be used to specify the type of
|
22
|
+
generated column (virtual or stored). Examples:
|
23
|
+
|
24
|
+
DB.add_column :t, :c, Integer, generated_always_as: Sequel[:a]+'b'
|
25
|
+
# ALTER TABLE `t` ADD COLUMN `c` varchar(255)
|
26
|
+
# GENERATED ALWAYS AS (CONCAT(`a`, 'b'))
|
27
|
+
|
28
|
+
DB.add_column :t, :c, Integer, generated_always_as: Sequel[:a]+'b',
|
29
|
+
generated_type: :virtual
|
30
|
+
# ALTER TABLE `t` ADD COLUMN `c` varchar(255)
|
31
|
+
# GENERATED ALWAYS AS (CONCAT(`a`, 'b')) VIRTUAL
|
32
|
+
|
33
|
+
DB.add_column :t, :c, Integer, generated_always_as: Sequel[:a]+'b',
|
34
|
+
generated_type: :stored
|
35
|
+
# ALTER TABLE `t` ADD COLUMN `c` varchar(255)
|
36
|
+
# GENERATED ALWAYS AS (CONCAT(`a`, 'b')) STORED
|
37
|
+
|
38
|
+
* Sequel::Model.has_dataset? has been added for checking whether the
|
39
|
+
model class has an associated dataset. This will generally be true
|
40
|
+
for most model classes, but will be false for abstract model
|
41
|
+
classes (such as Sequel::Model itself).
|
42
|
+
|
43
|
+
* Sequel::VERSION_NUMBER has been added for easier future version
|
44
|
+
comparisons. The version number for 5.9.0 is 50090.
|
45
|
+
|
46
|
+
= Other Improvements
|
47
|
+
|
48
|
+
* When disconnecting connections in the threaded connection pools,
|
49
|
+
the disconnection is performed without holding the connection
|
50
|
+
pool mutex, since disconnection may block.
|
51
|
+
|
52
|
+
* The sharded threaded connection pool no longer deadlocks when
|
53
|
+
disconnecting connections if the connection_validator or
|
54
|
+
connection_expiration extension is used.
|
55
|
+
|
56
|
+
* If a thread dies and does not check a connection back into the
|
57
|
+
connection pool, Sequel now disconnects the connection when it
|
58
|
+
detects the dead thread, instead of assuming the connection is
|
59
|
+
safe to be reused.
|
60
|
+
|
61
|
+
* When using eager_graph with cascaded associations, a unique
|
62
|
+
object is now used instead of a shared object in cases where
|
63
|
+
using a shared object may cause further cascaded associated
|
64
|
+
objects to be duplicated.
|
65
|
+
|
66
|
+
* On PostgreSQL, the ESCAPE modifier to the LIKE/ILIKE operators is
|
67
|
+
no longer used, since the default ESCAPE value is the one Sequel
|
68
|
+
uses. This change was made in order to allow the LIKE/ILIKE
|
69
|
+
operators to work with the ANY function, as PostgreSQL does not
|
70
|
+
support the use of the ESCAPE modifier in such cases.
|
71
|
+
|
72
|
+
* A hash argument passed to Model.nested_attributes in the
|
73
|
+
nested_attributes plugin is now no longer modified.
|
74
|
+
|
75
|
+
* Internal data structures for eager and eager_graph datasets are now
|
76
|
+
frozen to avoid unintentional modification.
|
77
|
+
|
78
|
+
* Nondeterministic behavior in Database#foreign_key_list with the
|
79
|
+
:reverse option on PostgreSQL is now avoided by using an
|
80
|
+
unambiguous order.
|
81
|
+
|
82
|
+
* Performance has been improved slightly by avoiding unnecessary
|
83
|
+
hash allocations.
|
84
|
+
|
85
|
+
* Performance has been improved slightly by using while instead
|
86
|
+
of Kernel#loop.
|
87
|
+
|
88
|
+
* BigDecimal() is now used instead of BigDecimal.new(), as the
|
89
|
+
latter has been deprecated.
|
90
|
+
|
91
|
+
* The jdbc adapter now avoids referencing ::NativeException on JRuby
|
92
|
+
9.2+, since JRuby has deprecated it. It is still used on older
|
93
|
+
versions of JRuby, since some JRuby 1.7 code may still require it.
|
94
|
+
|
95
|
+
* Sequel now works around multiple Date/Time conversion bugs in
|
96
|
+
JRuby 9.2.0.0 for BC dates in the pg_extended_date_support
|
97
|
+
extension. These bugs have already been fixed in JRuby, and
|
98
|
+
the workarounds will be removed after the release of JRuby
|
99
|
+
9.2.1.0.
|
data/doc/testing.rdoc
CHANGED
@@ -13,7 +13,7 @@ These run each test in its own transaction, the recommended way to test.
|
|
13
13
|
require 'minitest/hooks/default'
|
14
14
|
class Minitest::HooksSpec
|
15
15
|
def around
|
16
|
-
|
16
|
+
DB.transaction(:rollback=>:always, :auto_savepoint=>true){super}
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -21,7 +21,7 @@ These run each test in its own transaction, the recommended way to test.
|
|
21
21
|
|
22
22
|
class Minitest::Spec
|
23
23
|
def run(*args, &block)
|
24
|
-
|
24
|
+
DB.transaction(:rollback=>:always, :auto_savepoint=>true){super}
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -30,7 +30,7 @@ These run each test in its own transaction, the recommended way to test.
|
|
30
30
|
# Use this class as the base class for your tests
|
31
31
|
class SequelTestCase < Minitest::Test
|
32
32
|
def run(*args, &block)
|
33
|
-
|
33
|
+
DB.transaction(:rollback=>:always, :auto_savepoint=>true){super}
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -46,7 +46,7 @@ These run each test in its own transaction, the recommended way to test.
|
|
46
46
|
|
47
47
|
You can use the Sequel.transaction method to run a transaction on multiple databases, rolling all of them back. Instead of:
|
48
48
|
|
49
|
-
|
49
|
+
DB.transaction(:rollback=>:always)
|
50
50
|
|
51
51
|
Use Sequel.transaction with an array of databases:
|
52
52
|
|
@@ -66,11 +66,11 @@ Example:
|
|
66
66
|
require 'minitest/hooks/default'
|
67
67
|
class Minitest::HooksSpec
|
68
68
|
def around
|
69
|
-
|
69
|
+
DB.transaction(:rollback=>:always, :savepoint=>true, :auto_savepoint=>true){super}
|
70
70
|
end
|
71
71
|
|
72
72
|
def around_all
|
73
|
-
|
73
|
+
DB.transaction(:rollback=>:always){super}
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
@@ -90,9 +90,9 @@ The order in which you delete/truncate the tables is important if you are using
|
|
90
90
|
|
91
91
|
describe "some test suite" do
|
92
92
|
after do
|
93
|
-
[:table1, :table2].each{|x|
|
93
|
+
[:table1, :table2].each{|x| DB.from(x).truncate}
|
94
94
|
# or
|
95
|
-
[:table1, :table2].each{|x|
|
95
|
+
[:table1, :table2].each{|x| DB.from(x).delete}
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
@@ -100,9 +100,9 @@ The order in which you delete/truncate the tables is important if you are using
|
|
100
100
|
|
101
101
|
class SomeTestClass < Minitest::Test
|
102
102
|
def teardown
|
103
|
-
[:table1, :table2].each{|x|
|
103
|
+
[:table1, :table2].each{|x| DB.from(x).truncate}
|
104
104
|
# or
|
105
|
-
[:table1, :table2].each{|x|
|
105
|
+
[:table1, :table2].each{|x| DB.from(x).delete}
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
data/lib/sequel/adapters/ado.rb
CHANGED
data/lib/sequel/adapters/jdbc.rb
CHANGED
@@ -17,7 +17,19 @@ module Sequel
|
|
17
17
|
# Contains procs keyed on subadapter type that extend the
|
18
18
|
# given database object so it supports the correct database type.
|
19
19
|
DATABASE_SETUP = {}
|
20
|
+
|
21
|
+
# Create custom NativeException alias for nicer access, and also so that
|
22
|
+
# JRuby 9.2+ so it doesn't use the deprecated ::NativeException
|
23
|
+
NativeException = java.lang.Exception
|
20
24
|
|
25
|
+
# Default database error classes
|
26
|
+
DATABASE_ERROR_CLASSES = [NativeException]
|
27
|
+
if JRUBY_VERSION < '9.2'
|
28
|
+
# On JRuby <9.2, still include ::NativeException, as it is still needed in some cases
|
29
|
+
DATABASE_ERROR_CLASSES << ::NativeException
|
30
|
+
end
|
31
|
+
DATABASE_ERROR_CLASSES.freeze
|
32
|
+
|
21
33
|
# Allow loading the necessary JDBC support via a gem.
|
22
34
|
def self.load_gem(name)
|
23
35
|
begin
|
@@ -68,7 +80,7 @@ module Sequel
|
|
68
80
|
end
|
69
81
|
def RubyBigDecimal(r, i)
|
70
82
|
if v = r.getBigDecimal(i)
|
71
|
-
BigDecimal
|
83
|
+
::Kernel::BigDecimal(v.to_string)
|
72
84
|
end
|
73
85
|
end
|
74
86
|
def RubyBlob(r, i)
|
@@ -168,7 +180,7 @@ module Sequel
|
|
168
180
|
last_insert_id(conn, opts)
|
169
181
|
end
|
170
182
|
end
|
171
|
-
rescue
|
183
|
+
rescue *DATABASE_ERROR_CLASSES => e
|
172
184
|
raise_error(e)
|
173
185
|
ensure
|
174
186
|
cps.close
|
@@ -189,7 +201,7 @@ module Sequel
|
|
189
201
|
JavaSQL::DriverManager.setLoginTimeout(opts[:login_timeout]) if opts[:login_timeout]
|
190
202
|
raise StandardError, "skipping regular connection" if opts[:jdbc_properties]
|
191
203
|
JavaSQL::DriverManager.getConnection(*args)
|
192
|
-
rescue
|
204
|
+
rescue StandardError, *DATABASE_ERROR_CLASSES => e
|
193
205
|
raise e unless driver
|
194
206
|
# If the DriverManager can't get the connection - use the connect
|
195
207
|
# method of the driver. (This happens under Tomcat for instance)
|
@@ -203,7 +215,7 @@ module Sequel
|
|
203
215
|
c = driver.new.connect(args[0], props)
|
204
216
|
raise(Sequel::DatabaseError, 'driver.new.connect returned nil: probably bad JDBC connection string') unless c
|
205
217
|
c
|
206
|
-
rescue
|
218
|
+
rescue StandardError, *DATABASE_ERROR_CLASSES => e2
|
207
219
|
if e2.respond_to?(:message=) && e2.message != e.message
|
208
220
|
e2.message = "#{e2.message}\n#{e.class.name}: #{e.message}"
|
209
221
|
end
|
@@ -355,7 +367,7 @@ module Sequel
|
|
355
367
|
end
|
356
368
|
|
357
369
|
def database_error_classes
|
358
|
-
|
370
|
+
DATABASE_ERROR_CLASSES
|
359
371
|
end
|
360
372
|
|
361
373
|
def database_exception_sqlstate(exception, opts)
|
@@ -436,7 +448,7 @@ module Sequel
|
|
436
448
|
log_connection_yield(msg, conn, args){cps.executeUpdate}
|
437
449
|
end
|
438
450
|
end
|
439
|
-
rescue
|
451
|
+
rescue *DATABASE_ERROR_CLASSES => e
|
440
452
|
raise_error(e)
|
441
453
|
ensure
|
442
454
|
cps.close unless name
|
@@ -661,7 +673,7 @@ module Sequel
|
|
661
673
|
def statement(conn)
|
662
674
|
stmt = conn.createStatement
|
663
675
|
yield stmt
|
664
|
-
rescue
|
676
|
+
rescue *DATABASE_ERROR_CLASSES => e
|
665
677
|
raise_error(e)
|
666
678
|
ensure
|
667
679
|
stmt.close if stmt
|
@@ -135,11 +135,6 @@ module Sequel
|
|
135
135
|
|
136
136
|
private
|
137
137
|
|
138
|
-
DATABASE_ERROR_CLASSES = [NativeException].freeze
|
139
|
-
def database_error_classes
|
140
|
-
DATABASE_ERROR_CLASSES
|
141
|
-
end
|
142
|
-
|
143
138
|
def disconnect_error?(exception, opts)
|
144
139
|
super || exception.message =~ /\A(This connection has been closed\.|FATAL: terminating connection due to administrator command|An I\/O error occurred while sending to the backend\.)\z/
|
145
140
|
end
|
@@ -271,7 +271,7 @@ module Sequel
|
|
271
271
|
def error_info(e)
|
272
272
|
e = e.wrapped_exception if e.is_a?(DatabaseError)
|
273
273
|
r = e.result
|
274
|
-
|
274
|
+
{
|
275
275
|
:schema => r.error_field(::PG::PG_DIAG_SCHEMA_NAME),
|
276
276
|
:table => r.error_field(::PG::PG_DIAG_TABLE_NAME),
|
277
277
|
:column => r.error_field(::PG::PG_DIAG_COLUMN_NAME),
|
@@ -449,7 +449,7 @@ module Sequel
|
|
449
449
|
raise Error, 'calling #listen with :loop requires a block' unless block
|
450
450
|
loop_call = l.respond_to?(:call)
|
451
451
|
catch(:stop) do
|
452
|
-
|
452
|
+
while true
|
453
453
|
t = timeout_block ? [timeout_block.call] : []
|
454
454
|
conn.wait_for_notify(*t, &block)
|
455
455
|
l.call(conn) if loop_call
|
@@ -712,7 +712,7 @@ module Sequel
|
|
712
712
|
yield_hash_rows(res, cols){|h| yield h}
|
713
713
|
return if res.ntuples < rows_per_fetch
|
714
714
|
end
|
715
|
-
|
715
|
+
while true
|
716
716
|
execute(fetch_sql) do |res|
|
717
717
|
yield_hash_rows(res, cols){|h| yield h}
|
718
718
|
return if res.ntuples < rows_per_fetch
|
@@ -109,12 +109,6 @@ module Sequel
|
|
109
109
|
complex_expression_sql_append(sql, :LIKE, args)
|
110
110
|
when :'NOT ILIKE'
|
111
111
|
complex_expression_sql_append(sql, :'NOT LIKE', args)
|
112
|
-
when :LIKE, :'NOT LIKE'
|
113
|
-
sql << '('
|
114
|
-
literal_append(sql, args[0])
|
115
|
-
sql << ' ' << op.to_s << ' '
|
116
|
-
literal_append(sql, args[1])
|
117
|
-
sql << ')'
|
118
112
|
when :'!='
|
119
113
|
sql << '('
|
120
114
|
literal_append(sql, args[0])
|
@@ -240,6 +234,11 @@ module Sequel
|
|
240
234
|
end
|
241
235
|
end
|
242
236
|
|
237
|
+
# Access doesn't support ESCAPE for LIKE.
|
238
|
+
def requires_like_escape?
|
239
|
+
false
|
240
|
+
end
|
241
|
+
|
243
242
|
# Access requires parentheses when joining more than one table
|
244
243
|
def select_from_sql(sql)
|
245
244
|
if f = @opts[:from]
|
@@ -19,7 +19,7 @@ module Sequel
|
|
19
19
|
include Sequel::Database::SplitAlterTable
|
20
20
|
|
21
21
|
CAST_TYPES = {String=>:CHAR, Integer=>:SIGNED, Time=>:DATETIME, DateTime=>:DATETIME, Numeric=>:DECIMAL, BigDecimal=>:DECIMAL, File=>:BINARY}.freeze
|
22
|
-
COLUMN_DEFINITION_ORDER = [:collate, :null, :default, :unique, :primary_key, :auto_increment, :references].freeze
|
22
|
+
COLUMN_DEFINITION_ORDER = [:generated, :collate, :null, :default, :unique, :primary_key, :auto_increment, :references].freeze
|
23
23
|
|
24
24
|
# Set the default charset used for CREATE TABLE. You can pass the
|
25
25
|
# :charset option to create_table to override this setting.
|
@@ -137,6 +137,11 @@ module Sequel
|
|
137
137
|
true
|
138
138
|
end
|
139
139
|
|
140
|
+
# Generated columns are supported in MariaDB 5.2.0+ and MySQL 5.7.6+.
|
141
|
+
def supports_generated_columns?
|
142
|
+
server_version >= (mariadb? ? 50200 : 50706)
|
143
|
+
end
|
144
|
+
|
140
145
|
# MySQL 5+ supports prepared transactions (two-phase commit) using XA
|
141
146
|
def supports_prepared_transactions?
|
142
147
|
server_version >= 50000
|
@@ -331,6 +336,23 @@ module Sequel
|
|
331
336
|
end
|
332
337
|
end
|
333
338
|
|
339
|
+
# Add generation clause SQL fragment to column creation SQL.
|
340
|
+
def column_definition_generated_sql(sql, column)
|
341
|
+
if (generated_expression = column[:generated_always_as])
|
342
|
+
sql << " GENERATED ALWAYS AS (#{literal(generated_expression)})"
|
343
|
+
case (type = column[:generated_type])
|
344
|
+
when nil
|
345
|
+
# none, database default
|
346
|
+
when :virtual
|
347
|
+
sql << " VIRTUAL"
|
348
|
+
when :stored
|
349
|
+
sql << (mariadb? ? " PERSISTENT" : " STORED")
|
350
|
+
else
|
351
|
+
raise Error, "unsupported :generated_type option: #{type.inspect}"
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
334
356
|
def column_definition_order
|
335
357
|
COLUMN_DEFINITION_ORDER
|
336
358
|
end
|
@@ -473,7 +495,11 @@ module Sequel
|
|
473
495
|
metadata_dataset.with_sql("DESCRIBE ?", table).map do |row|
|
474
496
|
extra = row.delete(:Extra)
|
475
497
|
if row[:primary_key] = row.delete(:Key) == 'PRI'
|
476
|
-
row[:auto_increment] = !!(extra.to_s =~ /auto_increment/
|
498
|
+
row[:auto_increment] = !!(extra.to_s =~ /auto_increment/i)
|
499
|
+
end
|
500
|
+
if supports_generated_columns?
|
501
|
+
# Extra field contains VIRTUAL or PERSISTENT for generated columns
|
502
|
+
row[:generated] = !!(extra.to_s =~ /VIRTUAL|STORED|PERSISTENT/i)
|
477
503
|
end
|
478
504
|
row[:allow_null] = row.delete(:Null) == 'YES'
|
479
505
|
row[:default] = row.delete(:Default)
|