sequel 3.0.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +100 -0
- data/README.rdoc +3 -3
- data/bin/sequel +102 -19
- data/doc/reflection.rdoc +83 -0
- data/doc/release_notes/3.1.0.txt +406 -0
- data/lib/sequel/adapters/ado.rb +11 -0
- data/lib/sequel/adapters/amalgalite.rb +5 -20
- data/lib/sequel/adapters/do.rb +44 -36
- data/lib/sequel/adapters/firebird.rb +29 -43
- data/lib/sequel/adapters/jdbc.rb +17 -27
- data/lib/sequel/adapters/mysql.rb +35 -40
- data/lib/sequel/adapters/odbc.rb +4 -23
- data/lib/sequel/adapters/oracle.rb +22 -19
- data/lib/sequel/adapters/postgres.rb +6 -15
- data/lib/sequel/adapters/shared/mssql.rb +1 -1
- data/lib/sequel/adapters/shared/mysql.rb +29 -10
- data/lib/sequel/adapters/shared/oracle.rb +6 -8
- data/lib/sequel/adapters/shared/postgres.rb +28 -72
- data/lib/sequel/adapters/shared/sqlite.rb +5 -3
- data/lib/sequel/adapters/sqlite.rb +5 -20
- data/lib/sequel/adapters/utils/savepoint_transactions.rb +80 -0
- data/lib/sequel/adapters/utils/unsupported.rb +0 -12
- data/lib/sequel/core.rb +12 -3
- data/lib/sequel/core_sql.rb +1 -8
- data/lib/sequel/database.rb +107 -43
- data/lib/sequel/database/schema_generator.rb +1 -0
- data/lib/sequel/database/schema_methods.rb +38 -4
- data/lib/sequel/dataset.rb +6 -0
- data/lib/sequel/dataset/convenience.rb +2 -2
- data/lib/sequel/dataset/graph.rb +2 -2
- data/lib/sequel/dataset/prepared_statements.rb +3 -8
- data/lib/sequel/dataset/sql.rb +93 -19
- data/lib/sequel/extensions/blank.rb +2 -1
- data/lib/sequel/extensions/inflector.rb +4 -3
- data/lib/sequel/extensions/migration.rb +13 -2
- data/lib/sequel/extensions/pagination.rb +4 -0
- data/lib/sequel/extensions/pretty_table.rb +4 -0
- data/lib/sequel/extensions/query.rb +4 -0
- data/lib/sequel/extensions/schema_dumper.rb +100 -24
- data/lib/sequel/extensions/string_date_time.rb +3 -4
- data/lib/sequel/model.rb +2 -1
- data/lib/sequel/model/associations.rb +96 -38
- data/lib/sequel/model/base.rb +14 -14
- data/lib/sequel/model/plugins.rb +32 -21
- data/lib/sequel/plugins/caching.rb +13 -15
- data/lib/sequel/plugins/identity_map.rb +107 -0
- data/lib/sequel/plugins/lazy_attributes.rb +65 -0
- data/lib/sequel/plugins/many_through_many.rb +188 -0
- data/lib/sequel/plugins/schema.rb +13 -0
- data/lib/sequel/plugins/serialization.rb +53 -37
- data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
- data/lib/sequel/plugins/tactical_eager_loading.rb +61 -0
- data/lib/sequel/plugins/validation_class_methods.rb +28 -7
- data/lib/sequel/plugins/validation_helpers.rb +31 -24
- data/lib/sequel/sql.rb +16 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/ado_spec.rb +47 -1
- data/spec/adapters/firebird_spec.rb +39 -36
- data/spec/adapters/mysql_spec.rb +25 -9
- data/spec/adapters/postgres_spec.rb +11 -24
- data/spec/core/database_spec.rb +54 -13
- data/spec/core/dataset_spec.rb +147 -29
- data/spec/core/object_graph_spec.rb +6 -1
- data/spec/core/schema_spec.rb +34 -0
- data/spec/core/spec_helper.rb +0 -2
- data/spec/extensions/caching_spec.rb +7 -0
- data/spec/extensions/identity_map_spec.rb +158 -0
- data/spec/extensions/lazy_attributes_spec.rb +113 -0
- data/spec/extensions/many_through_many_spec.rb +813 -0
- data/spec/extensions/migration_spec.rb +4 -4
- data/spec/extensions/schema_dumper_spec.rb +114 -13
- data/spec/extensions/schema_spec.rb +19 -3
- data/spec/extensions/serialization_spec.rb +28 -0
- data/spec/extensions/single_table_inheritance_spec.rb +25 -1
- data/spec/extensions/spec_helper.rb +2 -7
- data/spec/extensions/tactical_eager_loading_spec.rb +65 -0
- data/spec/extensions/validation_class_methods_spec.rb +10 -5
- data/spec/integration/dataset_test.rb +39 -6
- data/spec/integration/eager_loader_test.rb +7 -7
- data/spec/integration/spec_helper.rb +0 -1
- data/spec/integration/transaction_test.rb +28 -1
- data/spec/model/association_reflection_spec.rb +29 -3
- data/spec/model/associations_spec.rb +1 -0
- data/spec/model/eager_loading_spec.rb +70 -1
- data/spec/model/plugins_spec.rb +236 -50
- data/spec/model/spec_helper.rb +0 -2
- metadata +18 -5
@@ -1,5 +1,13 @@
|
|
1
1
|
module Sequel
|
2
2
|
module Plugins
|
3
|
+
# Sequel's built in schema plugin allows you to define your schema
|
4
|
+
# directly in the model using Model.set_schema (which takes a block
|
5
|
+
# similar to Database#create_table), and use Model.create_table to
|
6
|
+
# create a table using the schema information.
|
7
|
+
#
|
8
|
+
# This plugin is mostly suited to test code. If there is any
|
9
|
+
# chance that your application's schema could change, you should
|
10
|
+
# be using the migration extension instead.
|
3
11
|
module Schema
|
4
12
|
module ClassMethods
|
5
13
|
# Creates table, using the column information from set_schema.
|
@@ -15,6 +23,11 @@ module Sequel
|
|
15
23
|
drop_table rescue nil
|
16
24
|
create_table
|
17
25
|
end
|
26
|
+
|
27
|
+
# Creates the table unless the table already exists
|
28
|
+
def create_table?
|
29
|
+
create_table unless table_exists?
|
30
|
+
end
|
18
31
|
|
19
32
|
# Drops table.
|
20
33
|
def drop_table
|
@@ -21,47 +21,59 @@ module Sequel
|
|
21
21
|
module Serialization
|
22
22
|
# Set up the column readers to do deserialization and the column writers
|
23
23
|
# to save the value in deserialized_values.
|
24
|
-
def self.apply(model,
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
InstanceMethods.module_eval do
|
31
|
-
columns.each do |column|
|
32
|
-
define_method(column) do
|
33
|
-
if deserialized_values.has_key?(column)
|
34
|
-
deserialized_values[column]
|
35
|
-
else
|
36
|
-
deserialized_values[column] = deserialize_value(@values[column])
|
37
|
-
end
|
38
|
-
end
|
39
|
-
define_method("#{column}=") do |v|
|
40
|
-
changed_columns << column unless changed_columns.include?(column)
|
41
|
-
deserialized_values[column] = v
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
24
|
+
def self.apply(model, *args)
|
25
|
+
model.instance_eval{@serialization_map = {}}
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.configure(model, format=nil, *columns)
|
29
|
+
model.serialize_attributes(format, *columns) unless columns.empty?
|
46
30
|
end
|
47
31
|
|
48
32
|
module ClassMethods
|
49
|
-
#
|
50
|
-
|
51
|
-
|
52
|
-
# The columns to serialize
|
53
|
-
attr_reader :serialized_columns
|
33
|
+
# A map of the serialized columns for this model. Keys are column
|
34
|
+
# symbols, values are serialization formats (:marshal or :yaml).
|
35
|
+
attr_reader :serialization_map
|
54
36
|
|
55
37
|
# Copy the serialization format and columns to serialize into the subclass.
|
56
38
|
def inherited(subclass)
|
57
39
|
super
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
40
|
+
sm = serialization_map.dup
|
41
|
+
subclass.instance_eval{@serialization_map = sm}
|
42
|
+
end
|
43
|
+
|
44
|
+
# The first value in the serialization map. This is only for
|
45
|
+
# backwards compatibility, use serialization_map in new code.
|
46
|
+
def serialization_format
|
47
|
+
serialization_map.values.first
|
48
|
+
end
|
49
|
+
|
50
|
+
# Create instance level reader that deserializes column values on request,
|
51
|
+
# and instance level writer that stores new deserialized value in deserialized
|
52
|
+
# columns
|
53
|
+
def serialize_attributes(format, *columns)
|
54
|
+
raise(Error, "Unsupported serialization format (#{format}), should be :marshal or :yaml") unless [:marshal, :yaml].include?(format)
|
55
|
+
raise(Error, "No columns given. The serialization plugin requires you specify which columns to serialize") if columns.empty?
|
56
|
+
columns.each do |column|
|
57
|
+
serialization_map[column] = format
|
58
|
+
define_method(column) do
|
59
|
+
if deserialized_values.has_key?(column)
|
60
|
+
deserialized_values[column]
|
61
|
+
else
|
62
|
+
deserialized_values[column] = deserialize_value(column, @values[column])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
define_method("#{column}=") do |v|
|
66
|
+
changed_columns << column unless changed_columns.include?(column)
|
67
|
+
deserialized_values[column] = v
|
68
|
+
end
|
63
69
|
end
|
64
70
|
end
|
71
|
+
|
72
|
+
# The columns that will be serialized. This is only for
|
73
|
+
# backwards compatibility, use serialization_map in new code.
|
74
|
+
def serialized_columns
|
75
|
+
serialization_map.keys
|
76
|
+
end
|
65
77
|
end
|
66
78
|
|
67
79
|
module InstanceMethods
|
@@ -78,7 +90,7 @@ module Sequel
|
|
78
90
|
def before_save
|
79
91
|
super
|
80
92
|
deserialized_values.each do |k,v|
|
81
|
-
@values[k] = serialize_value(v)
|
93
|
+
@values[k] = serialize_value(k, v)
|
82
94
|
end
|
83
95
|
end
|
84
96
|
|
@@ -91,24 +103,28 @@ module Sequel
|
|
91
103
|
private
|
92
104
|
|
93
105
|
# Deserialize the column from either marshal or yaml format
|
94
|
-
def deserialize_value(v)
|
106
|
+
def deserialize_value(column, v)
|
95
107
|
return v if v.nil?
|
96
|
-
case model.
|
108
|
+
case model.serialization_map[column]
|
97
109
|
when :marshal
|
98
110
|
Marshal.load(v.unpack('m')[0]) rescue Marshal.load(v)
|
99
111
|
when :yaml
|
100
112
|
YAML.load v if v
|
113
|
+
else
|
114
|
+
raise Error, "Bad serialization format (#{model.serialization_map[column].inspect}) for column #{column.inspect}"
|
101
115
|
end
|
102
116
|
end
|
103
117
|
|
104
118
|
# Serialize the column to either marshal or yaml format
|
105
|
-
def serialize_value(v)
|
119
|
+
def serialize_value(column, v)
|
106
120
|
return v if v.nil?
|
107
|
-
case model.
|
121
|
+
case model.serialization_map[column]
|
108
122
|
when :marshal
|
109
123
|
[Marshal.dump(v)].pack('m')
|
110
124
|
when :yaml
|
111
125
|
v.to_yaml
|
126
|
+
else
|
127
|
+
raise Error, "Bad serialization format (#{model.serialization_map[column].inspect}) for column #{column.inspect}"
|
112
128
|
end
|
113
129
|
end
|
114
130
|
end
|
@@ -18,7 +18,7 @@ module Sequel
|
|
18
18
|
# Set the sti_key and sti_dataset for the model, and change the
|
19
19
|
# dataset's row_proc so that the dataset yields objects of varying classes,
|
20
20
|
# where the class used has the same name as the key field.
|
21
|
-
def self.
|
21
|
+
def self.configure(model, key)
|
22
22
|
m = model.method(:constantize)
|
23
23
|
model.instance_eval do
|
24
24
|
@sti_key = key
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Sequel
|
2
|
+
module Plugins
|
3
|
+
# The tactical_eager_loading plugin allows you to eagerly load
|
4
|
+
# an association for all objects retrieved from the same dataset
|
5
|
+
# without calling eager on the dataset. If you attempt to load
|
6
|
+
# associated objects for a record and the association for that
|
7
|
+
# object is currently not cached, it assumes you want to get
|
8
|
+
# the associated objects for all objects retrieved with the dataset that
|
9
|
+
# retrieved the current object.
|
10
|
+
#
|
11
|
+
# Tactical eager loading only takes affect if you retrieved the
|
12
|
+
# current object with Dataset#all, it doesn't work if you
|
13
|
+
# retrieved the current object with Dataset#each.
|
14
|
+
#
|
15
|
+
# Basically, this allows the following code to issue only two queries:
|
16
|
+
#
|
17
|
+
# Album.filter{id<100}.all do |a|
|
18
|
+
# a.artists
|
19
|
+
# end
|
20
|
+
module TacticalEagerLoading
|
21
|
+
module InstanceMethods
|
22
|
+
# The dataset that retrieved this object, set if the object was
|
23
|
+
# reteived via Dataset#all with an active identity map.
|
24
|
+
attr_accessor :retrieved_by
|
25
|
+
|
26
|
+
# All model objects retrieved with this object, set if the object was
|
27
|
+
# reteived via Dataset#all with an active identity map.
|
28
|
+
attr_accessor :retrieved_with
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
# If there is an active identity map and the association is not in the
|
33
|
+
# associations cache and the object was reteived via Dataset#all,
|
34
|
+
# eagerly load the association for all model objects retrieved with the
|
35
|
+
# current object.
|
36
|
+
def load_associated_objects(opts, reload=false)
|
37
|
+
name = opts[:name]
|
38
|
+
if !associations.include?(name) && retrieved_by
|
39
|
+
retrieved_by.send(:eager_load, retrieved_with, name=>{})
|
40
|
+
end
|
41
|
+
super
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module DatasetMethods
|
46
|
+
private
|
47
|
+
|
48
|
+
# If there is an active identity map, set the reteived_with attribute for the object
|
49
|
+
# with the current dataset and array of all objects.
|
50
|
+
def post_load(objects)
|
51
|
+
super
|
52
|
+
objects.each do |o|
|
53
|
+
next unless o.is_a?(Sequel::Model)
|
54
|
+
o.retrieved_by = self
|
55
|
+
o.retrieved_with = objects
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -1,9 +1,26 @@
|
|
1
1
|
module Sequel
|
2
|
-
|
2
|
+
extension :blank
|
3
3
|
|
4
4
|
module Plugins
|
5
|
+
# Sequel's built-in validation_class_methods plugin adds backwards compatibility
|
6
|
+
# for the legacy class-level validation methods (e.g. validates_presence_of :column).
|
7
|
+
#
|
8
|
+
# It is recommended to use the validation_helpers plugin instead of this one,
|
9
|
+
# as it is less complex and more flexible.
|
5
10
|
module ValidationClassMethods
|
11
|
+
# Setup the validations hash for the given model.
|
12
|
+
def self.apply(model)
|
13
|
+
model.class_eval do
|
14
|
+
@validation_mutex = Mutex.new
|
15
|
+
@validations = {}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
6
19
|
module ClassMethods
|
20
|
+
# A hash of associations for this model class. Keys are column symbols,
|
21
|
+
# values are arrays of validation procs.
|
22
|
+
attr_reader :validations
|
23
|
+
|
7
24
|
# The Generator class is used to generate validation definitions using
|
8
25
|
# the validates {} idiom.
|
9
26
|
class Generator
|
@@ -23,6 +40,15 @@ module Sequel
|
|
23
40
|
def has_validations?
|
24
41
|
!validations.empty?
|
25
42
|
end
|
43
|
+
|
44
|
+
# Setup the validations hash in the subclass
|
45
|
+
def inherited(subclass)
|
46
|
+
super
|
47
|
+
subclass.class_eval do
|
48
|
+
@validation_mutex = Mutex.new
|
49
|
+
@validations = {}
|
50
|
+
end
|
51
|
+
end
|
26
52
|
|
27
53
|
# Instructs the model to skip validations defined in superclasses
|
28
54
|
def skip_superclass_validations
|
@@ -146,7 +172,7 @@ module Sequel
|
|
146
172
|
end
|
147
173
|
tag = opts[:tag]
|
148
174
|
atts.each do |a|
|
149
|
-
a_vals = validations[a]
|
175
|
+
a_vals = @validation_mutex.synchronize{validations[a] ||= []}
|
150
176
|
if tag && (old = a_vals.find{|x| x[0] == tag})
|
151
177
|
old[1] = blk
|
152
178
|
else
|
@@ -348,11 +374,6 @@ module Sequel
|
|
348
374
|
end
|
349
375
|
end
|
350
376
|
|
351
|
-
# Returns the validations hash for the class.
|
352
|
-
def validations
|
353
|
-
@validations ||= Hash.new {|h, k| h[k] = []}
|
354
|
-
end
|
355
|
-
|
356
377
|
private
|
357
378
|
|
358
379
|
# Removes and returns the last member of the array if it is a hash. Otherwise,
|
@@ -1,30 +1,37 @@
|
|
1
1
|
module Sequel
|
2
2
|
module Plugins
|
3
|
+
# The validation_helpers plugin contains instance method equivalents for most of the legacy
|
4
|
+
# class-level validations. The names and APIs are different, though. Example:
|
5
|
+
#
|
6
|
+
# class Album < Sequel::Model
|
7
|
+
# plugin :validation_helpers
|
8
|
+
# def validate
|
9
|
+
# validates_min_length 1, :num_tracks
|
10
|
+
# end
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# The validates_unique validation has a unique API, but the other validations have
|
14
|
+
# the API explained here:
|
15
|
+
#
|
16
|
+
# Arguments:
|
17
|
+
# * atts - Single attribute symbol or an array of attribute symbols specifying the
|
18
|
+
# attribute(s) to validate.
|
19
|
+
# Options:
|
20
|
+
# * :allow_blank - Whether to skip the validation if the value is blank. You should
|
21
|
+
# make sure all objects respond to blank if you use this option, which you can do by
|
22
|
+
# requiring 'sequel/extensions/blank'
|
23
|
+
# * :allow_missing - Whether to skip the validation if the attribute isn't a key in the
|
24
|
+
# values hash. This is different from allow_nil, because Sequel only sends the attributes
|
25
|
+
# in the values when doing an insert or update. If the attribute is not present, Sequel
|
26
|
+
# doesn't specify it, so the database will use the table's default value. This is different
|
27
|
+
# from having an attribute in values with a value of nil, which Sequel will send as NULL.
|
28
|
+
# If your database table has a non NULL default, this may be a good option to use. You
|
29
|
+
# don't want to use allow_nil, because if the attribute is in values but has a value nil,
|
30
|
+
# Sequel will attempt to insert a NULL value into the database, instead of using the
|
31
|
+
# database's default.
|
32
|
+
# * :allow_nil - Whether to skip the validation if the value is nil.
|
33
|
+
# * :message - The message to use
|
3
34
|
module ValidationHelpers
|
4
|
-
# ValidationHelpers contains instance method equivalents for most of the previous
|
5
|
-
# default validations. The names and APIs have changed, though.
|
6
|
-
#
|
7
|
-
# The validates_unique validation has a unique API, but the other validations have
|
8
|
-
# the API explained here:
|
9
|
-
#
|
10
|
-
# Arguments:
|
11
|
-
# * atts - Single attribute symbol or an array of attribute symbols specifying the
|
12
|
-
# attribute(s) to validate.
|
13
|
-
# Options:
|
14
|
-
# * :allow_blank - Whether to skip the validation if the value is blank. You should
|
15
|
-
# make sure all objects respond to blank if you use this option, which you can do by
|
16
|
-
# requiring 'sequel/extensions/blank'
|
17
|
-
# * :allow_missing - Whether to skip the validation if the attribute isn't a key in the
|
18
|
-
# values hash. This is different from allow_nil, because Sequel only sends the attributes
|
19
|
-
# in the values when doing an insert or update. If the attribute is not present, Sequel
|
20
|
-
# doesn't specify it, so the database will use the table's default value. This is different
|
21
|
-
# from having an attribute in values with a value of nil, which Sequel will send as NULL.
|
22
|
-
# If your database table has a non NULL default, this may be a good option to use. You
|
23
|
-
# don't want to use allow_nil, because if the attribute is in values but has a value nil,
|
24
|
-
# Sequel will attempt to insert a NULL value into the database, instead of using the
|
25
|
-
# database's default.
|
26
|
-
# * :allow_nil - Whether to skip the validation if the value is nil.
|
27
|
-
# * :message - The message to use
|
28
35
|
module InstanceMethods
|
29
36
|
# Check that the attribute values are the given exact length.
|
30
37
|
def validates_exact_length(exact, atts, opts={})
|
data/lib/sequel/sql.rb
CHANGED
@@ -351,10 +351,22 @@ module Sequel
|
|
351
351
|
end
|
352
352
|
end
|
353
353
|
|
354
|
+
# Methods that create Subscripts (SQL array accesses).
|
355
|
+
module SubscriptMethods
|
356
|
+
# Return an SQL array subscript with the given arguments.
|
357
|
+
#
|
358
|
+
# :array.sql_subscript(1) # SQL: array[1]
|
359
|
+
# :array.sql_subscript(1, 2) # SQL: array[1, 2]
|
360
|
+
def sql_subscript(*sub)
|
361
|
+
Subscript.new(self, sub.flatten)
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
354
365
|
class ComplexExpression
|
355
366
|
include AliasMethods
|
356
367
|
include CastMethods
|
357
368
|
include OrderMethods
|
369
|
+
include SubscriptMethods
|
358
370
|
end
|
359
371
|
|
360
372
|
class GenericExpression
|
@@ -365,6 +377,7 @@ module Sequel
|
|
365
377
|
include BooleanMethods
|
366
378
|
include NumericMethods
|
367
379
|
include StringMethods
|
380
|
+
include SubscriptMethods
|
368
381
|
include InequalityMethods
|
369
382
|
end
|
370
383
|
|
@@ -709,6 +722,9 @@ module Sequel
|
|
709
722
|
# ruby array of all two pairs as an SQL array instead of an ordered
|
710
723
|
# hash-like conditions specifier.
|
711
724
|
class SQLArray < Expression
|
725
|
+
# The array of objects this SQLArray wraps
|
726
|
+
attr_reader :array
|
727
|
+
|
712
728
|
# Create an object with the given array.
|
713
729
|
def initialize(array)
|
714
730
|
@array = array
|
data/lib/sequel/version.rb
CHANGED
data/spec/adapters/ado_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'spec_helper.rb')
|
2
2
|
|
3
3
|
unless defined?(ADO_DB)
|
4
|
-
ADO_DB = Sequel.ado(:host => 'MY_SQL_SERVER', :database => 'MyDB', :user => '
|
4
|
+
ADO_DB = Sequel.ado(:host => 'MY_SQL_SERVER', :database => 'MyDB', :user => 'my_usr', :password => 'my_pwd')
|
5
5
|
end
|
6
6
|
|
7
7
|
context "An ADO dataset" do
|
@@ -14,6 +14,52 @@ context "An ADO dataset" do
|
|
14
14
|
ADO_DB[:items].all
|
15
15
|
}.should_not raise_error
|
16
16
|
end
|
17
|
+
|
18
|
+
describe 'setting the :command_timeout option' do
|
19
|
+
before(:each) do
|
20
|
+
@conn_options = {:host => 'MY_SQL_SERVER',
|
21
|
+
:database => 'MyDB',
|
22
|
+
:user => 'my_usr',
|
23
|
+
:password => 'my_pwd',
|
24
|
+
:command_timeout => 120}
|
25
|
+
end
|
26
|
+
|
27
|
+
specify 'it should set the CommandTimeout parameter on the ADO handle' do
|
28
|
+
db = Sequel::ADO::Database.new(@conn_options)
|
29
|
+
db.connect(@conn_options).CommandTimeout.should == 120
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'when the :command_timeout option is not implicitly set' do
|
34
|
+
before(:each) do
|
35
|
+
@conn_options = {:host => 'MY_SQL_SERVER',
|
36
|
+
:database => 'MyDB',
|
37
|
+
:user => 'my_usr',
|
38
|
+
:password => 'my_pwd'}
|
39
|
+
end
|
40
|
+
|
41
|
+
specify 'it should remain as the default of 30 seconds' do
|
42
|
+
db = Sequel::ADO::Database.new(@conn_options)
|
43
|
+
db.connect(@conn_options).CommandTimeout.should == 30
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'setting the :provider option' do
|
48
|
+
before(:each) do
|
49
|
+
@conn_options = {:host => 'MY_SQL_SERVER',
|
50
|
+
:database => 'MyDB',
|
51
|
+
:user => 'my_usr',
|
52
|
+
:password => 'my_pwd',
|
53
|
+
:provider => "SQLOLEDB"}
|
54
|
+
end
|
55
|
+
|
56
|
+
specify 'it should set the CommandTimeout parameter on the ADO handle' do
|
57
|
+
db = Sequel::ADO::Database.new(@conn_options)
|
58
|
+
db.connect(@conn_options).Provider.should match /sqloledb/i
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
17
63
|
end
|
18
64
|
|
19
65
|
context "An MSSQL dataset" do
|