sequel 3.19.0 → 3.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +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
|