sequel 3.19.0 → 3.20.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +16 -0
- data/doc/opening_databases.rdoc +14 -0
- data/doc/release_notes/3.20.0.txt +41 -0
- data/lib/sequel/adapters/ado.rb +11 -5
- data/lib/sequel/adapters/jdbc.rb +1 -0
- data/lib/sequel/adapters/mysql.rb +3 -3
- data/lib/sequel/adapters/shared/access.rb +52 -0
- data/lib/sequel/adapters/shared/mysql.rb +6 -2
- data/lib/sequel/adapters/swift.rb +9 -10
- data/lib/sequel/adapters/swift/postgres.rb +3 -5
- data/lib/sequel/adapters/swift/sqlite.rb +31 -0
- data/lib/sequel/model/associations.rb +2 -2
- data/lib/sequel/model/exceptions.rb +3 -0
- data/lib/sequel/plugins/tactical_eager_loading.rb +8 -1
- data/lib/sequel/plugins/validation_class_methods.rb +4 -2
- data/lib/sequel/plugins/validation_helpers.rb +5 -2
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mysql_spec.rb +18 -0
- data/spec/adapters/sqlite_spec.rb +1 -1
- data/spec/core/connection_pool_spec.rb +1 -1
- data/spec/extensions/validation_class_methods_spec.rb +14 -0
- data/spec/extensions/validation_helpers_spec.rb +14 -0
- data/spec/integration/plugin_test.rb +4 -0
- data/spec/integration/prepared_statement_test.rb +2 -2
- data/spec/integration/type_test.rb +3 -3
- metadata +8 -4
data/CHANGELOG
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
=== 3.20.0 (2011-02-01)
|
2
|
+
|
3
|
+
* Allow a :partial option to Database#indexes on MySQL to include partial indexes (roland.swingler) (#324)
|
4
|
+
|
5
|
+
* Add a SQLite subadapter to the swift adapter, now that swift supports it (jeremyevans)
|
6
|
+
|
7
|
+
* Update swift adapter to support swift 0.8.1, older versions no longer supported (jeremyevans)
|
8
|
+
|
9
|
+
* Allow setting arbitrary JDBC properties in the jdbc adapter with the :jdbc_properties option (jeremyevans)
|
10
|
+
|
11
|
+
* Use a better error message if a validates_max_length validation is applied to a nil value (jeremyevans) (#322)
|
12
|
+
|
13
|
+
* Add some basic Microsoft Access support to the ado adapter, autoincrementing primary keys now work (jeremyevans)
|
14
|
+
|
15
|
+
* Make class_table_inheritance plugin handle subclass associations better (jeremyevans) (#320)
|
16
|
+
|
1
17
|
=== 3.19.0 (2011-01-03)
|
2
18
|
|
3
19
|
* Handle Date and DateTime types in prepared statements when using the jdbc adapter (jeremyevans)
|
data/doc/opening_databases.rdoc
CHANGED
@@ -113,6 +113,18 @@ many things will be broken. The SQLNCLI10 provider appears to work well if you
|
|
113
113
|
are connecting to Microsoft SQL Server, but it is not the default as that would
|
114
114
|
break backwards compatability.
|
115
115
|
|
116
|
+
Example connections:
|
117
|
+
|
118
|
+
# SQL Server
|
119
|
+
Sequel.connect('ado:///sequel_test?host=server%5cdb_instance')
|
120
|
+
Sequel.connect('ado://user:password@server/database?host=server%5cdb_instance&provider=SQLNCLI10')
|
121
|
+
# Access 2007
|
122
|
+
Sequel.ado(:conn_string=>'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=drive:\\path\\filename.accdb')
|
123
|
+
# Access 2000
|
124
|
+
Sequel.ado(:conn_string=>'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=drive:\\path\\filename.mdb')
|
125
|
+
# Excel 2000 (for table names, use a dollar after the sheet name, e.g. Sheet1$)
|
126
|
+
Sequel.ado(:conn_string=>'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=drive:\\path\\filename.xls;Extended Properties=Excel 8.0;')
|
127
|
+
|
116
128
|
=== amalgalite
|
117
129
|
|
118
130
|
Amalgalite is an ruby extension that provides self contained access to SQLite,
|
@@ -254,6 +266,8 @@ The following additional options are supported:
|
|
254
266
|
* :encoding - Specify the encoding/character set to use for the connection.
|
255
267
|
* :socket - Can be used to specify a Unix socket file to connect to instead of a TCP host and port.
|
256
268
|
* :timeout - Sets the wait_timeout for the connection, defaults to 1 month.
|
269
|
+
* :read_timeout - Set the timeout in seconds for reading back results to a query.
|
270
|
+
* :connect_timeout - Set the timeout in seconds before a connection attempt is abandoned.
|
257
271
|
|
258
272
|
=== odbc
|
259
273
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* The swift adapter now supports an SQLite subadapter. Use the
|
4
|
+
:db_type => 'sqlite' option when connecting. You can use an
|
5
|
+
in memory database with the following connection string:
|
6
|
+
|
7
|
+
swift:///?database=:memory:&db_type=sqlite
|
8
|
+
|
9
|
+
* Arbitrary JDBC properties can now be set in the JDBC adapter
|
10
|
+
using the :jdbc_properties option when connecting. The value
|
11
|
+
of this option should be a hash where keys and values are JDBC
|
12
|
+
property keys and values.
|
13
|
+
|
14
|
+
* Basic Microsoft Access support was added to the ado adapter.
|
15
|
+
The creation of autoincrementing primary key integers now works,
|
16
|
+
and identifiers are now quoted with [].
|
17
|
+
|
18
|
+
* The Database#indexes method now supports a :partial option when
|
19
|
+
connecting to MySQL, which makes it include partial indexes (which
|
20
|
+
are usually excluded).
|
21
|
+
|
22
|
+
= Other Improvements
|
23
|
+
|
24
|
+
* The class_table_inheritance plugin now handles subclass
|
25
|
+
associations better. Previously, the implicit eager loading code
|
26
|
+
had issues when you called an association method that only existed
|
27
|
+
in the subclass.
|
28
|
+
|
29
|
+
* The error message used when a validates_max_length validation is
|
30
|
+
applied to a nil column value has been improved. You can override
|
31
|
+
the message yourself using the :nil_message option.
|
32
|
+
|
33
|
+
* The read_timeout and connect_timeout options now work correctly in
|
34
|
+
the mysql adapter.
|
35
|
+
|
36
|
+
* Another MySQL disconnect error message is now recognized.
|
37
|
+
|
38
|
+
= Backwards Compatibility
|
39
|
+
|
40
|
+
* The swift adapter was upgraded to support swift 0.8.1. Older
|
41
|
+
versions of swift are no longer supported.
|
data/lib/sequel/adapters/ado.rb
CHANGED
@@ -8,11 +8,17 @@ module Sequel
|
|
8
8
|
|
9
9
|
def initialize(opts)
|
10
10
|
super
|
11
|
-
@opts[:
|
12
|
-
|
13
|
-
|
14
|
-
Sequel
|
15
|
-
|
11
|
+
case @opts[:conn_string]
|
12
|
+
when /Microsoft\.(Jet|ACE)\.OLEDB/io
|
13
|
+
Sequel.ts_require 'adapters/shared/access'
|
14
|
+
extend Sequel::Access::DatabaseMethods
|
15
|
+
when nil
|
16
|
+
@opts[:driver] ||= 'SQL Server'
|
17
|
+
case @opts[:driver]
|
18
|
+
when 'SQL Server'
|
19
|
+
Sequel.ts_require 'adapters/ado/mssql'
|
20
|
+
extend Sequel::ADO::MSSQL::DatabaseMethods
|
21
|
+
end
|
16
22
|
end
|
17
23
|
end
|
18
24
|
|
data/lib/sequel/adapters/jdbc.rb
CHANGED
@@ -168,6 +168,7 @@ module Sequel
|
|
168
168
|
props.setProperty("user", opts[:user])
|
169
169
|
props.setProperty("password", opts[:password])
|
170
170
|
end
|
171
|
+
opts[:jdbc_properties].each{|k,v| props.setProperty(k.to_s, v)} if opts[:jdbc_properties]
|
171
172
|
begin
|
172
173
|
driver.new.connect(args[0], props)
|
173
174
|
rescue => e2
|
@@ -86,7 +86,7 @@ module Sequel
|
|
86
86
|
include Sequel::MySQL::DatabaseMethods
|
87
87
|
|
88
88
|
# Mysql::Error messages that indicate the current connection should be disconnected
|
89
|
-
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)/
|
89
|
+
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|Lost connection to MySQL server during query)/
|
90
90
|
|
91
91
|
set_adapter_scheme :mysql
|
92
92
|
|
@@ -128,10 +128,10 @@ module Sequel
|
|
128
128
|
# encoding we want to use, but this can be overridden by READ_DEFAULT_GROUP.
|
129
129
|
conn.options(Mysql::SET_CHARSET_NAME, encoding)
|
130
130
|
end
|
131
|
-
if read_timeout = opts[:read_timeout] and Mysql::
|
131
|
+
if read_timeout = opts[:read_timeout] and defined? Mysql::OPT_READ_TIMEOUT
|
132
132
|
conn.options(Mysql::OPT_READ_TIMEOUT, read_timeout)
|
133
133
|
end
|
134
|
-
if connect_timeout = opts[:connect_timeout] and Mysql::
|
134
|
+
if connect_timeout = opts[:connect_timeout] and defined? Mysql::OPT_CONNECT_TIMEOUT
|
135
135
|
conn.options(Mysql::OPT_CONNECT_TIMEOUT, connect_timeout)
|
136
136
|
end
|
137
137
|
conn.real_connect(
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Sequel
|
2
|
+
module Access
|
3
|
+
module DatabaseMethods
|
4
|
+
def database_type
|
5
|
+
:access
|
6
|
+
end
|
7
|
+
|
8
|
+
def dataset(opts = nil)
|
9
|
+
ds = super
|
10
|
+
ds.extend(DatasetMethods)
|
11
|
+
ds
|
12
|
+
end
|
13
|
+
|
14
|
+
# Doesn't work, due to security restrictions on MSysObjects
|
15
|
+
def tables
|
16
|
+
from(:MSysObjects).filter(:Type=>1, :Flags=>0).select_map(:Name).map{|x| x.to_sym}
|
17
|
+
end
|
18
|
+
|
19
|
+
def serial_primary_key_options
|
20
|
+
{:primary_key => true, :type=>:Counter}
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def identifier_input_method_default
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def identifier_output_method_default
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module DatasetMethods
|
35
|
+
SELECT_CLAUSE_METHODS = Dataset.clause_methods(:select, %w'limit distinct columns from join where group order having compounds')
|
36
|
+
|
37
|
+
def supports_intersect_except?
|
38
|
+
false
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def quoted_identifier(v)
|
44
|
+
"[#{v}]"
|
45
|
+
end
|
46
|
+
|
47
|
+
def select_clause_methods
|
48
|
+
SELECT_CLAUSE_METHODS
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -49,7 +49,11 @@ module Sequel
|
|
49
49
|
:mysql
|
50
50
|
end
|
51
51
|
|
52
|
-
# Use SHOW INDEX FROM to get the index information for the
|
52
|
+
# Use SHOW INDEX FROM to get the index information for the
|
53
|
+
# table.
|
54
|
+
#
|
55
|
+
# By default partial indexes are not included, you can use the
|
56
|
+
# option :partial to override this.
|
53
57
|
def indexes(table, opts={})
|
54
58
|
indexes = {}
|
55
59
|
remove_indexes = []
|
@@ -59,7 +63,7 @@ module Sequel
|
|
59
63
|
name = r[:Key_name]
|
60
64
|
next if name == PRIMARY
|
61
65
|
name = m.call(name)
|
62
|
-
remove_indexes << name if r[:Sub_part]
|
66
|
+
remove_indexes << name if r[:Sub_part] && ! opts[:partial]
|
63
67
|
i = indexes[name] ||= {:columns=>[], :unique=>r[:Non_unique] != 1}
|
64
68
|
i[:columns] << m.call(r[:Column_name])
|
65
69
|
end
|
@@ -22,6 +22,11 @@ module Sequel
|
|
22
22
|
db.extend(Sequel::Swift::MySQL::DatabaseMethods)
|
23
23
|
db.swift_class = ::Swift::DB::Mysql
|
24
24
|
end,
|
25
|
+
:sqlite=>proc do |db|
|
26
|
+
Sequel.ts_require 'adapters/swift/sqlite'
|
27
|
+
db.extend(Sequel::Swift::SQLite::DatabaseMethods)
|
28
|
+
db.swift_class = ::Swift::DB::Sqlite3
|
29
|
+
end,
|
25
30
|
}
|
26
31
|
|
27
32
|
class Database < Sequel::Database
|
@@ -45,7 +50,7 @@ module Sequel
|
|
45
50
|
raise(Error, "No :db_type option specified")
|
46
51
|
end
|
47
52
|
else
|
48
|
-
raise(Error, ":db_type option not valid, should be postgres or
|
53
|
+
raise(Error, ":db_type option not valid, should be postgres, mysql, or sqlite")
|
49
54
|
end
|
50
55
|
end
|
51
56
|
|
@@ -63,14 +68,11 @@ module Sequel
|
|
63
68
|
def execute(sql, opts={})
|
64
69
|
synchronize(opts[:server]) do |conn|
|
65
70
|
begin
|
66
|
-
res =
|
67
|
-
log_yield(sql){conn.execute(sql); res = conn.results}
|
71
|
+
res = log_yield(sql){conn.execute(sql)}
|
68
72
|
yield res if block_given?
|
69
73
|
nil
|
70
74
|
rescue SwiftError => e
|
71
75
|
raise_error(e)
|
72
|
-
ensure
|
73
|
-
res.finish if res
|
74
76
|
end
|
75
77
|
end
|
76
78
|
end
|
@@ -80,7 +82,7 @@ module Sequel
|
|
80
82
|
def execute_dui(sql, opts={})
|
81
83
|
synchronize(opts[:server]) do |conn|
|
82
84
|
begin
|
83
|
-
log_yield(sql){conn.execute(sql)}
|
85
|
+
log_yield(sql){conn.execute(sql).rows}
|
84
86
|
rescue SwiftError => e
|
85
87
|
raise_error(e)
|
86
88
|
end
|
@@ -92,12 +94,9 @@ module Sequel
|
|
92
94
|
def execute_insert(sql, opts={})
|
93
95
|
synchronize(opts[:server]) do |conn|
|
94
96
|
begin
|
95
|
-
|
96
|
-
log_yield(sql){conn.execute(sql); (res = conn.results).insert_id}
|
97
|
+
log_yield(sql){conn.execute(sql).insert_id}
|
97
98
|
rescue SwiftError => e
|
98
99
|
raise_error(e)
|
99
|
-
ensure
|
100
|
-
res.finish if res
|
101
100
|
end
|
102
101
|
end
|
103
102
|
end
|
@@ -50,13 +50,11 @@ module Sequel
|
|
50
50
|
def execute(sql, opts={})
|
51
51
|
synchronize(opts[:server]) do |conn|
|
52
52
|
begin
|
53
|
-
conn.execute(sql)
|
54
|
-
res = conn.results
|
53
|
+
res = conn.execute(sql)
|
55
54
|
yield res if block_given?
|
55
|
+
nil
|
56
56
|
rescue SwiftError => e
|
57
57
|
raise_error(e)
|
58
|
-
ensure
|
59
|
-
res.finish if res
|
60
58
|
end
|
61
59
|
end
|
62
60
|
end
|
@@ -66,7 +64,7 @@ module Sequel
|
|
66
64
|
def execute_dui(sql, opts={})
|
67
65
|
synchronize(opts[:server]) do |conn|
|
68
66
|
begin
|
69
|
-
conn.execute(sql)
|
67
|
+
conn.execute(sql).rows
|
70
68
|
rescue SwiftError => e
|
71
69
|
raise_error(e)
|
72
70
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
Sequel.require 'adapters/shared/sqlite'
|
2
|
+
|
3
|
+
module Sequel
|
4
|
+
module Swift
|
5
|
+
# Database and Dataset instance methods for SQLite specific
|
6
|
+
# support via Swift.
|
7
|
+
module SQLite
|
8
|
+
# Database instance methods for SQLite databases accessed via Swift.
|
9
|
+
module DatabaseMethods
|
10
|
+
include Sequel::SQLite::DatabaseMethods
|
11
|
+
|
12
|
+
# Return instance of Sequel::Swift::SQL::Dataset with the given opts.
|
13
|
+
def dataset(opts=nil)
|
14
|
+
Sequel::Swift::SQLite::Dataset.new(self, opts)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Dataset class for SQLite datasets accessed via Swift.
|
19
|
+
class Dataset < Swift::Dataset
|
20
|
+
include Sequel::SQLite::DatasetMethods
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# Use Swift's escape method for quoting.
|
25
|
+
def literal_string(s)
|
26
|
+
db.synchronize{|c| "#{c.escape(s)}"}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -1473,7 +1473,7 @@ module Sequel
|
|
1473
1473
|
|
1474
1474
|
# Make sure the association is valid for this model, and return the related AssociationReflection.
|
1475
1475
|
def check_association(model, association)
|
1476
|
-
raise(Sequel::
|
1476
|
+
raise(Sequel::UndefinedAssociation, "Invalid association #{association} for #{model.name}") unless reflection = model.association_reflection(association)
|
1477
1477
|
raise(Sequel::Error, "Eager loading is not allowed for #{model.name} association #{association}") if reflection[:allow_eager] == false
|
1478
1478
|
reflection
|
1479
1479
|
end
|
@@ -1538,7 +1538,7 @@ module Sequel
|
|
1538
1538
|
# specific foreign/primary key
|
1539
1539
|
key_hash = {}
|
1540
1540
|
# Reflections for all associations to eager load
|
1541
|
-
reflections = eager_assoc.keys.collect{|assoc| model.association_reflection(assoc)}
|
1541
|
+
reflections = eager_assoc.keys.collect{|assoc| model.association_reflection(assoc) || (raise Sequel::UndefinedAssociation, "Model: #{self}, Association: #{assoc}")}
|
1542
1542
|
|
1543
1543
|
# Populate keys to monitor
|
1544
1544
|
reflections.each{|reflection| key_hash[reflection.eager_loader_key] ||= Hash.new{|h,k| h[k] = []}}
|
@@ -6,6 +6,9 @@ module Sequel
|
|
6
6
|
# modify a single row.
|
7
7
|
class NoExistingObject < Error; end
|
8
8
|
|
9
|
+
# Raised when an undefined association is used when eager loading.
|
10
|
+
class UndefinedAssociation < Error; end
|
11
|
+
|
9
12
|
# Exception class raised when +raise_on_save_failure+ is set and validation fails
|
10
13
|
class ValidationFailed < Error
|
11
14
|
def initialize(errors)
|
@@ -44,7 +44,14 @@ module Sequel
|
|
44
44
|
def load_associated_objects(opts, reload=false)
|
45
45
|
name = opts[:name]
|
46
46
|
if !associations.include?(name) && retrieved_by
|
47
|
-
|
47
|
+
begin
|
48
|
+
retrieved_by.send(:eager_load, retrieved_with, name=>{})
|
49
|
+
rescue Sequel::UndefinedAssociation
|
50
|
+
# This can happen if class table inheritance is used and the association
|
51
|
+
# is only defined in a subclass. This particular instance can use the
|
52
|
+
# association, but it can't be eagerly loaded as the parent class doesn't
|
53
|
+
# have access to the association, and that's the class doing the eager loading.
|
54
|
+
end
|
48
55
|
end
|
49
56
|
super
|
50
57
|
end
|
@@ -232,15 +232,17 @@ module Sequel
|
|
232
232
|
# Possible Options:
|
233
233
|
# * :is - The exact size required for the value to be valid (no default)
|
234
234
|
# * :maximum - The maximum size allowed for the value (no default)
|
235
|
-
# * :message - The message to use (no default, overrides :too_long, :too_short, and :wrong_length
|
235
|
+
# * :message - The message to use (no default, overrides :nil_message, :too_long, :too_short, and :wrong_length
|
236
236
|
# options if present)
|
237
237
|
# * :minimum - The minimum size allowed for the value (no default)
|
238
|
+
# * :nil_message - The message to use use if :maximum option is used and the value is nil (default: 'is not present')
|
238
239
|
# * :too_long - The message to use use if it the value is too long (default: 'is too long')
|
239
240
|
# * :too_short - The message to use use if it the value is too short (default: 'is too short')
|
240
241
|
# * :within - The array/range that must include the size of the value for it to be valid (no default)
|
241
242
|
# * :wrong_length - The message to use use if it the value is not valid (default: 'is the wrong length')
|
242
243
|
def validates_length_of(*atts)
|
243
244
|
opts = {
|
245
|
+
:nil_message => 'is not present',
|
244
246
|
:too_long => 'is too long',
|
245
247
|
:too_short => 'is too short',
|
246
248
|
:wrong_length => 'is the wrong length'
|
@@ -251,7 +253,7 @@ module Sequel
|
|
251
253
|
atts << opts
|
252
254
|
validates_each(*atts) do |o, a, v|
|
253
255
|
if m = opts[:maximum]
|
254
|
-
o.errors.add(a, opts[:message] || opts[:too_long]) unless v && v.size <= m
|
256
|
+
o.errors.add(a, opts[:message] || (v ? opts[:too_long] : opts[:nil_message])) unless v && v.size <= m
|
255
257
|
end
|
256
258
|
if m = opts[:minimum]
|
257
259
|
o.errors.add(a, opts[:message] || opts[:too_short]) unless v && v.size >= m
|
@@ -50,7 +50,7 @@ module Sequel
|
|
50
50
|
:includes=>{:message=>lambda{|set| "is not in range or set: #{set.inspect}"}},
|
51
51
|
:integer=>{:message=>lambda{"is not a number"}},
|
52
52
|
:length_range=>{:message=>lambda{|range| "is too short or too long"}},
|
53
|
-
:max_length=>{:message=>lambda{|max| "is longer than #{max} characters"}},
|
53
|
+
:max_length=>{:message=>lambda{|max| "is longer than #{max} characters"}, :nil_message=>lambda{"is not present"}},
|
54
54
|
:min_length=>{:message=>lambda{|min| "is shorter than #{min} characters"}},
|
55
55
|
:not_string=>{:message=>lambda{|type| type ? "is not a valid #{type}" : "is a string"}},
|
56
56
|
:numeric=>{:message=>lambda{"is not a number"}},
|
@@ -93,8 +93,11 @@ module Sequel
|
|
93
93
|
end
|
94
94
|
|
95
95
|
# Check that the attribute values are not longer than the given max length.
|
96
|
+
#
|
97
|
+
# Accepts a :nil_message option that is the error message to use when the
|
98
|
+
# value is nil instead of being too long.
|
96
99
|
def validates_max_length(max, atts, opts={})
|
97
|
-
validatable_attributes_for_type(:max_length, atts, opts){|a,v,m| validation_error_message(m, max) unless v && v.length <= max}
|
100
|
+
validatable_attributes_for_type(:max_length, atts, opts){|a,v,m| v ? validation_error_message(m, max) : validation_error_message(opts[:nil_message] || DEFAULT_OPTIONS[:max_length][:nil_message]) unless v && v.length <= max}
|
98
101
|
end
|
99
102
|
|
100
103
|
# Check that the attribute values are not shorter than the given min length.
|
data/lib/sequel/version.rb
CHANGED
@@ -3,7 +3,7 @@ module Sequel
|
|
3
3
|
MAJOR = 3
|
4
4
|
# The minor version of Sequel. Bumped for every non-patch level
|
5
5
|
# release, generally around once a month.
|
6
|
-
MINOR =
|
6
|
+
MINOR = 20
|
7
7
|
# The tiny version of Sequel. Usually 0, only bumped for bugfix
|
8
8
|
# releases that fix regressions from previous versions.
|
9
9
|
TINY = 0
|
data/spec/adapters/mysql_spec.rb
CHANGED
@@ -565,6 +565,18 @@ if %w'localhost 127.0.0.1 ::1'.include?(MYSQL_URI.host) and MYSQL_DB.adapter_sch
|
|
565
565
|
end
|
566
566
|
end
|
567
567
|
|
568
|
+
context "A MySQL database" do
|
569
|
+
specify "should accept a read_timeout option when connecting" do
|
570
|
+
db = Sequel.connect(MYSQL_DB.opts.merge(:read_timeout=>22342))
|
571
|
+
proc {db.test_connection}.should_not raise_error
|
572
|
+
end
|
573
|
+
|
574
|
+
specify "should accept a connect_timeout option when connecting" do
|
575
|
+
db = Sequel.connect(MYSQL_DB.opts.merge(:connect_timeout=>22342))
|
576
|
+
proc {db.test_connection}.should_not raise_error
|
577
|
+
end
|
578
|
+
end
|
579
|
+
|
568
580
|
context "A grouped MySQL dataset" do
|
569
581
|
before do
|
570
582
|
MYSQL_DB[:test2].delete
|
@@ -648,6 +660,12 @@ context "A MySQL database" do
|
|
648
660
|
@db << "CREATE INDEX posts_id_index ON posts (id(10))"
|
649
661
|
@db.indexes(:posts).should == {}
|
650
662
|
end
|
663
|
+
|
664
|
+
specify "should dump partial indexes if :partial option is set to true" do
|
665
|
+
@db.create_table(:posts){text :id}
|
666
|
+
@db << "CREATE INDEX posts_id_index ON posts (id(10))"
|
667
|
+
@db.indexes(:posts, :partial => true).should == {:posts_id_index => {:columns => [:id], :unique => false}}
|
668
|
+
end
|
651
669
|
end
|
652
670
|
|
653
671
|
context "MySQL::Dataset#insert and related methods" do
|
@@ -98,7 +98,7 @@ context "An SQLite database" do
|
|
98
98
|
proc {@db.temp_store = :invalid}.should raise_error(Sequel::Error)
|
99
99
|
end
|
100
100
|
|
101
|
-
cspecify "should support timestamps and datetimes and respect datetime_class", :do, :jdbc, :amalgalite do
|
101
|
+
cspecify "should support timestamps and datetimes and respect datetime_class", :do, :jdbc, :amalgalite, :swift do
|
102
102
|
@db.create_table!(:time){timestamp :t; datetime :d}
|
103
103
|
t1 = Time.at(1)
|
104
104
|
@db[:time] << {:t => t1, :d => t1}
|
@@ -168,7 +168,7 @@ context "A connection pool with a max size of 1" do
|
|
168
168
|
cc,c1, c2 = nil
|
169
169
|
|
170
170
|
t1 = Thread.new {@pool.hold {|c| cc = c; c1 = c.dup; while c == 'herro';sleep 0.01;end}}
|
171
|
-
sleep 0.
|
171
|
+
sleep 0.03
|
172
172
|
cc.should == 'herro'
|
173
173
|
c1.should == 'herro'
|
174
174
|
|
@@ -341,6 +341,20 @@ describe Sequel::Model do
|
|
341
341
|
@m.should be_valid
|
342
342
|
@m.value = '123456'
|
343
343
|
@m.should_not be_valid
|
344
|
+
@m.errors[:value].should == ['is too long']
|
345
|
+
@m.value = nil
|
346
|
+
@m.should_not be_valid
|
347
|
+
@m.errors[:value].should == ['is not present']
|
348
|
+
end
|
349
|
+
|
350
|
+
specify "should validate length_of with maximum using customized error messages" do
|
351
|
+
@c.validates_length_of :value, :maximum => 5, :too_long=>'tl', :nil_message=>'np'
|
352
|
+
@m.value = '123456'
|
353
|
+
@m.should_not be_valid
|
354
|
+
@m.errors[:value].should == ['tl']
|
355
|
+
@m.value = nil
|
356
|
+
@m.should_not be_valid
|
357
|
+
@m.errors[:value].should == ['np']
|
344
358
|
end
|
345
359
|
|
346
360
|
specify "should validate length_of with minimum" do
|
@@ -210,6 +210,20 @@ describe "Sequel::Plugins::ValidationHelpers" do
|
|
210
210
|
@m.should be_valid
|
211
211
|
@m.value = '123456'
|
212
212
|
@m.should_not be_valid
|
213
|
+
@m.errors[:value].should == ['is longer than 5 characters']
|
214
|
+
@m.value = nil
|
215
|
+
@m.should_not be_valid
|
216
|
+
@m.errors[:value].should == ['is not present']
|
217
|
+
end
|
218
|
+
|
219
|
+
specify "should support validates_max_length with nil value" do
|
220
|
+
@c.set_validations{validates_max_length(5, :value, :message=>'tl', :nil_message=>'np')}
|
221
|
+
@m.value = '123456'
|
222
|
+
@m.should_not be_valid
|
223
|
+
@m.errors[:value].should == ['tl']
|
224
|
+
@m.value = nil
|
225
|
+
@m.should_not be_valid
|
226
|
+
@m.errors[:value].should == ['np']
|
213
227
|
end
|
214
228
|
|
215
229
|
specify "should support validates_min_length" do
|
@@ -90,6 +90,10 @@ describe "Class Table Inheritance Plugin" do
|
|
90
90
|
@db[:employees][:id=>i].should == nil
|
91
91
|
end
|
92
92
|
|
93
|
+
specify "should handle associations only defined in subclasses" do
|
94
|
+
Employee.filter(:id=>@i2).all.first.manager.id.should == @i4
|
95
|
+
end
|
96
|
+
|
93
97
|
# See http://www.sqlite.org/src/tktview/3338b3fa19ac4abee6c475126a2e6d9d61f26ab1
|
94
98
|
cspecify "should insert rows into all tables", :sqlite do
|
95
99
|
e = Executive.create(:name=>'Ex2', :num_managers=>8, :num_staff=>9)
|
@@ -251,11 +251,11 @@ describe "Bound Argument Types" do
|
|
251
251
|
@ds.filter(:t=>@ds.ba(:$x, :timestamp)).prepare(:first, :ps_time).call(:x=>@vs[:t])[:t].should == @vs[:t]
|
252
252
|
end
|
253
253
|
|
254
|
-
cspecify "should handle blob type", [:swift]
|
254
|
+
cspecify "should handle blob type", [:swift] do
|
255
255
|
@ds.filter(:file=>@ds.ba(:$x, :bytea)).prepare(:first, :ps_blob).call(:x=>@vs[:file])[:file].should == @vs[:file]
|
256
256
|
end
|
257
257
|
|
258
|
-
|
258
|
+
cspecify "should handle float type", [:swift, :sqlite] do
|
259
259
|
@ds.filter(:f=>@ds.ba(:$x, :"double precision")).prepare(:first, :ps_float).call(:x=>@vs[:f])[:f].should == @vs[:f]
|
260
260
|
end
|
261
261
|
|
@@ -39,13 +39,13 @@ describe "Supported types" do
|
|
39
39
|
ds.all.should == [{:number=>2**34}]
|
40
40
|
end
|
41
41
|
|
42
|
-
|
42
|
+
cspecify "should support generic float type", [:swift, :sqlite] do
|
43
43
|
ds = create_items_table_with_column(:number, Float)
|
44
44
|
ds.insert(:number => 2.1)
|
45
45
|
ds.all.should == [{:number=>2.1}]
|
46
46
|
end
|
47
47
|
|
48
|
-
cspecify "should support generic numeric type", [:odbc, :mssql] do
|
48
|
+
cspecify "should support generic numeric type", [:odbc, :mssql], [:swift, :sqlite] do
|
49
49
|
ds = create_items_table_with_column(:number, Numeric, :size=>[15, 10])
|
50
50
|
ds.insert(:number => BigDecimal.new('2.123456789'))
|
51
51
|
ds.all.should == [{:number=>BigDecimal.new('2.123456789')}]
|
@@ -79,7 +79,7 @@ describe "Supported types" do
|
|
79
79
|
ds.first[:tim].strftime('%Y%m%d%H%M%S').should == t.strftime('%Y%m%d%H%M%S')
|
80
80
|
end
|
81
81
|
|
82
|
-
cspecify "should support generic file type", [:do], [:odbc, :mssql], [:mysql2], [:swift]
|
82
|
+
cspecify "should support generic file type", [:do], [:odbc, :mssql], [:mysql2], [:swift] do
|
83
83
|
ds = create_items_table_with_column(:name, File)
|
84
84
|
ds.insert(:name => ("a\0"*300).to_sequel_blob)
|
85
85
|
ds.all.should == [{:name=>("a\0"*300).to_sequel_blob}]
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 87
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 3
|
8
|
-
-
|
8
|
+
- 20
|
9
9
|
- 0
|
10
|
-
version: 3.
|
10
|
+
version: 3.20.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jeremy Evans
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-01
|
18
|
+
date: 2011-02-01 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -83,6 +83,7 @@ extra_rdoc_files:
|
|
83
83
|
- doc/release_notes/3.17.0.txt
|
84
84
|
- doc/release_notes/3.18.0.txt
|
85
85
|
- doc/release_notes/3.19.0.txt
|
86
|
+
- doc/release_notes/3.20.0.txt
|
86
87
|
files:
|
87
88
|
- MIT-LICENSE
|
88
89
|
- CHANGELOG
|
@@ -133,6 +134,7 @@ files:
|
|
133
134
|
- doc/release_notes/3.17.0.txt
|
134
135
|
- doc/release_notes/3.18.0.txt
|
135
136
|
- doc/release_notes/3.19.0.txt
|
137
|
+
- doc/release_notes/3.20.0.txt
|
136
138
|
- doc/sharding.rdoc
|
137
139
|
- doc/sql.rdoc
|
138
140
|
- doc/virtual_rows.rdoc
|
@@ -311,12 +313,14 @@ files:
|
|
311
313
|
- lib/sequel/adapters/shared/postgres.rb
|
312
314
|
- lib/sequel/adapters/shared/progress.rb
|
313
315
|
- lib/sequel/adapters/shared/sqlite.rb
|
316
|
+
- lib/sequel/adapters/shared/access.rb
|
314
317
|
- lib/sequel/adapters/sqlite.rb
|
315
318
|
- lib/sequel/adapters/utils/stored_procedures.rb
|
316
319
|
- lib/sequel/adapters/mysql2.rb
|
317
320
|
- lib/sequel/adapters/swift.rb
|
318
321
|
- lib/sequel/adapters/swift/mysql.rb
|
319
322
|
- lib/sequel/adapters/swift/postgres.rb
|
323
|
+
- lib/sequel/adapters/swift/sqlite.rb
|
320
324
|
- lib/sequel/connection_pool.rb
|
321
325
|
- lib/sequel/connection_pool/sharded_single.rb
|
322
326
|
- lib/sequel/connection_pool/sharded_threaded.rb
|