sequel 3.7.0 → 3.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +50 -0
- data/doc/advanced_associations.rdoc +4 -3
- data/doc/release_notes/3.7.0.txt +2 -2
- data/doc/release_notes/3.8.0.txt +151 -0
- data/lib/sequel/adapters/jdbc.rb +10 -2
- data/lib/sequel/adapters/jdbc/h2.rb +14 -0
- data/lib/sequel/adapters/mysql.rb +36 -26
- data/lib/sequel/adapters/postgres.rb +27 -19
- data/lib/sequel/adapters/shared/mssql.rb +12 -4
- data/lib/sequel/adapters/shared/mysql.rb +16 -0
- data/lib/sequel/connection_pool.rb +178 -57
- data/lib/sequel/database.rb +60 -12
- data/lib/sequel/database/schema_generator.rb +1 -2
- data/lib/sequel/dataset.rb +10 -1
- data/lib/sequel/dataset/actions.rb +4 -8
- data/lib/sequel/dataset/convenience.rb +9 -2
- data/lib/sequel/dataset/query.rb +2 -5
- data/lib/sequel/dataset/sql.rb +0 -1
- data/lib/sequel/exceptions.rb +3 -3
- data/lib/sequel/metaprogramming.rb +4 -18
- data/lib/sequel/model/associations.rb +2 -2
- data/lib/sequel/model/base.rb +15 -18
- data/lib/sequel/model/default_inflections.rb +0 -1
- data/lib/sequel/model/plugins.rb +3 -2
- data/lib/sequel/plugins/boolean_readers.rb +3 -2
- data/lib/sequel/plugins/identity_map.rb +9 -0
- data/lib/sequel/plugins/validation_helpers.rb +8 -1
- data/lib/sequel/sql.rb +21 -11
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +7 -1
- data/spec/adapters/mysql_spec.rb +22 -0
- data/spec/core/connection_pool_spec.rb +211 -3
- data/spec/core/core_sql_spec.rb +7 -0
- data/spec/core/database_spec.rb +159 -7
- data/spec/core/dataset_spec.rb +33 -0
- data/spec/core/spec_helper.rb +1 -0
- data/spec/extensions/boolean_readers_spec.rb +6 -0
- data/spec/extensions/identity_map_spec.rb +29 -1
- data/spec/extensions/inflector_spec.rb +0 -1
- data/spec/extensions/validation_helpers_spec.rb +23 -0
- data/spec/integration/type_test.rb +1 -1
- metadata +131 -129
@@ -1,6 +1,5 @@
|
|
1
1
|
module Sequel
|
2
|
-
# The Schema module holds the schema generators
|
3
|
-
# to SQL DDL (Data Definition Language).
|
2
|
+
# The Schema module holds the schema generators.
|
4
3
|
module Schema
|
5
4
|
# Schema::Generator is an internal class that the user is not expected
|
6
5
|
# to instantiate directly. Instances are created by Database#create_table.
|
data/lib/sequel/dataset.rb
CHANGED
@@ -41,7 +41,7 @@ module Sequel
|
|
41
41
|
|
42
42
|
# Which options don't affect the SQL generation. Used by simple_select_all?
|
43
43
|
# to determine if this is a simple SELECT * FROM table.
|
44
|
-
NON_SQL_OPTIONS = [:server, :defaults, :overrides]
|
44
|
+
NON_SQL_OPTIONS = [:server, :defaults, :overrides, :graph, :eager_graph, :graph_aliases]
|
45
45
|
|
46
46
|
NOTIMPL_MSG = "This method must be overridden in Sequel adapters".freeze
|
47
47
|
WITH_SUPPORTED=:select_with_sql
|
@@ -120,6 +120,15 @@ module Sequel
|
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
123
|
+
# Yield a dataset for each server in the connection pool that is tied to that server.
|
124
|
+
# Intended for use in sharded environments where all servers need to be modified
|
125
|
+
# with the same data:
|
126
|
+
#
|
127
|
+
# DB[:configs].where(:key=>'setting').each_server{|ds| ds.update(:value=>'new_value')}
|
128
|
+
def each_server
|
129
|
+
db.servers.each{|s| yield server(s)}
|
130
|
+
end
|
131
|
+
|
123
132
|
# Returns a string representation of the dataset including the class name
|
124
133
|
# and the corresponding SQL select statement.
|
125
134
|
def inspect
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module Sequel
|
2
2
|
class Dataset
|
3
|
-
|
4
3
|
# Alias for insert, but not aliased directly so subclasses
|
5
4
|
# don't have to override both methods.
|
6
5
|
def <<(*args)
|
@@ -56,12 +55,10 @@ module Sequel
|
|
56
55
|
def each(&block)
|
57
56
|
if @opts[:graph]
|
58
57
|
graph_each(&block)
|
58
|
+
elsif row_proc = @row_proc
|
59
|
+
fetch_rows(select_sql){|r| yield row_proc.call(r)}
|
59
60
|
else
|
60
|
-
|
61
|
-
fetch_rows(select_sql){|r| yield row_proc.call(r)}
|
62
|
-
else
|
63
|
-
fetch_rows(select_sql, &block)
|
64
|
-
end
|
61
|
+
fetch_rows(select_sql, &block)
|
65
62
|
end
|
66
63
|
self
|
67
64
|
end
|
@@ -79,7 +76,7 @@ module Sequel
|
|
79
76
|
execute_insert(insert_sql(*values))
|
80
77
|
end
|
81
78
|
|
82
|
-
# Alias for
|
79
|
+
# Alias for update, but not aliased directly so subclasses
|
83
80
|
# don't have to override both methods.
|
84
81
|
def set(*args)
|
85
82
|
update(*args)
|
@@ -118,6 +115,5 @@ module Sequel
|
|
118
115
|
def execute_insert(sql, opts={}, &block)
|
119
116
|
@db.execute_insert(sql, default_server_opts(opts), &block)
|
120
117
|
end
|
121
|
-
|
122
118
|
end
|
123
119
|
end
|
@@ -194,10 +194,16 @@ module Sequel
|
|
194
194
|
end
|
195
195
|
end
|
196
196
|
|
197
|
+
# Returns a hash with key_column values as keys and value_column values as
|
198
|
+
# values. Similar to to_hash, but only selects the two columns.
|
197
199
|
def select_hash(key_column, value_column)
|
198
200
|
select(key_column, value_column).to_hash(hash_key_symbol(key_column), hash_key_symbol(value_column))
|
199
201
|
end
|
200
|
-
|
202
|
+
|
203
|
+
# Selects the column given (either as an argument or as a block), and
|
204
|
+
# returns an array of all values of that column in the dataset. If you
|
205
|
+
# give a block argument that returns an array with multiple entries,
|
206
|
+
# the contents of the resulting array are undefined.
|
201
207
|
def select_map(column=nil, &block)
|
202
208
|
ds = naked.ungraphed
|
203
209
|
ds = if column
|
@@ -208,7 +214,8 @@ module Sequel
|
|
208
214
|
end
|
209
215
|
ds.map{|r| r.values.first}
|
210
216
|
end
|
211
|
-
|
217
|
+
|
218
|
+
# The same as select_map, but in addition orders the array by the column.
|
212
219
|
def select_order_map(column=nil, &block)
|
213
220
|
ds = naked.ungraphed
|
214
221
|
ds = if column
|
data/lib/sequel/dataset/query.rb
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
module Sequel
|
2
2
|
class Dataset
|
3
|
-
|
4
|
-
FROM_SELF_KEEP_OPTS = [:graph, :eager_graph, :graph_aliases]
|
5
|
-
|
6
3
|
# Adds an further filter to an existing filter using AND. If no filter
|
7
4
|
# exists an error is raised. This method is identical to #filter except
|
8
5
|
# it expects an existing filter.
|
@@ -148,7 +145,7 @@ module Sequel
|
|
148
145
|
# ds.from_self(:alias=>:foo).sql #=> "SELECT * FROM (SELECT id, name FROM items ORDER BY name) AS foo"
|
149
146
|
def from_self(opts={})
|
150
147
|
fs = {}
|
151
|
-
@opts.keys.each{|k| fs[k] = nil unless
|
148
|
+
@opts.keys.each{|k| fs[k] = nil unless NON_SQL_OPTIONS.include?(k)}
|
152
149
|
clone(fs).from(opts[:alias] ? as(opts[:alias]) : self)
|
153
150
|
end
|
154
151
|
|
@@ -263,7 +260,7 @@ module Sequel
|
|
263
260
|
columns += Array(Sequel.virtual_row(&block)) if block
|
264
261
|
clone(:order => (columns.compact.empty?) ? nil : columns)
|
265
262
|
end
|
266
|
-
|
263
|
+
alias order_by order
|
267
264
|
|
268
265
|
# Returns a copy of the dataset with the order columns added
|
269
266
|
# to the existing order.
|
data/lib/sequel/dataset/sql.rb
CHANGED
data/lib/sequel/exceptions.rb
CHANGED
@@ -28,14 +28,14 @@ module Sequel
|
|
28
28
|
# Raised on an invalid operation, such as trying to update or delete
|
29
29
|
# a joined or grouped dataset.
|
30
30
|
class InvalidOperation < Error; end
|
31
|
-
|
31
|
+
|
32
32
|
# Raised when attempting an invalid type conversion.
|
33
33
|
class InvalidValue < Error ; end
|
34
|
-
|
34
|
+
|
35
35
|
# Raised when the connection pool cannot acquire a database connection
|
36
36
|
# before the timeout.
|
37
37
|
class PoolTimeout < Error ; end
|
38
|
-
|
38
|
+
|
39
39
|
# Exception that you should raise to signal a rollback of the current transaction.
|
40
40
|
# The transaction block will catch this exception, rollback the current transaction,
|
41
41
|
# and won't reraise it.
|
@@ -1,23 +1,9 @@
|
|
1
1
|
module Sequel
|
2
|
-
# Contains methods
|
2
|
+
# Contains meta_def method for adding methods to objects via blocks, used by some of Sequel's classes and objects.
|
3
3
|
module Metaprogramming
|
4
|
-
#
|
4
|
+
# Define a method with the given name and block body on the receiver.
|
5
5
|
def meta_def(name, &block)
|
6
|
-
|
7
|
-
end
|
8
|
-
|
9
|
-
private
|
10
|
-
|
11
|
-
# Evaluate the block in the context of the object's metaclass
|
12
|
-
def meta_eval(&block)
|
13
|
-
metaclass.instance_eval(&block)
|
14
|
-
end
|
15
|
-
|
16
|
-
# The hidden singleton lurks behind everyone
|
17
|
-
def metaclass
|
18
|
-
class << self
|
19
|
-
self
|
20
|
-
end
|
21
|
-
end
|
6
|
+
(class << self; self end).send(:define_method, name, &block)
|
7
|
+
end
|
22
8
|
end
|
23
9
|
end
|
@@ -461,7 +461,7 @@ module Sequel
|
|
461
461
|
# before a new item is added to the association.
|
462
462
|
# - :before_remove - Symbol, Proc, or array of both/either specifying a callback to call
|
463
463
|
# before an item is removed from the association.
|
464
|
-
# - :cartesian_product_number -
|
464
|
+
# - :cartesian_product_number - the number of joins completed by this association that could cause more
|
465
465
|
# than one row for each row in the current table (default: 0 for many_to_one associations,
|
466
466
|
# 1 for *_to_many associations).
|
467
467
|
# - :class - The associated class or its name. If not
|
@@ -1377,7 +1377,7 @@ module Sequel
|
|
1377
1377
|
|
1378
1378
|
# Make sure the association is valid for this model, and return the related AssociationReflection.
|
1379
1379
|
def check_association(model, association)
|
1380
|
-
raise(Sequel::Error,
|
1380
|
+
raise(Sequel::Error, "Invalid association #{association} for #{model.name}") unless reflection = model.association_reflection(association)
|
1381
1381
|
raise(Sequel::Error, "Eager loading is not allowed for #{model.name} association #{association}") if reflection[:allow_eager] == false
|
1382
1382
|
reflection
|
1383
1383
|
end
|
data/lib/sequel/model/base.rb
CHANGED
@@ -290,13 +290,7 @@ module Sequel
|
|
290
290
|
@dataset_methods.each{|meth, block| @dataset.meta_def(meth, &block)} if @dataset_methods
|
291
291
|
end
|
292
292
|
@dataset.model = self if @dataset.respond_to?(:model=)
|
293
|
-
|
294
|
-
@db_schema = (inherited ? superclass.db_schema : get_db_schema)
|
295
|
-
rescue Sequel::DatabaseConnectionError
|
296
|
-
raise
|
297
|
-
rescue
|
298
|
-
nil
|
299
|
-
end
|
293
|
+
check_non_connection_error{@db_schema = (inherited ? superclass.db_schema : get_db_schema)}
|
300
294
|
self
|
301
295
|
end
|
302
296
|
alias dataset= set_dataset
|
@@ -368,6 +362,17 @@ module Sequel
|
|
368
362
|
|
369
363
|
private
|
370
364
|
|
365
|
+
# Yield to the passed block and swallow all errors other than DatabaseConnectionErrors.
|
366
|
+
def check_non_connection_error
|
367
|
+
begin
|
368
|
+
yield
|
369
|
+
rescue Sequel::DatabaseConnectionError
|
370
|
+
raise
|
371
|
+
rescue
|
372
|
+
nil
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
371
376
|
# Create a column accessor for a column with a method name that is hard to use in ruby code.
|
372
377
|
def def_bad_column_accessor(column)
|
373
378
|
overridable_methods_module.module_eval do
|
@@ -399,15 +404,7 @@ module Sequel
|
|
399
404
|
ds_opts = dataset.opts
|
400
405
|
single_table = ds_opts[:from] && (ds_opts[:from].length == 1) \
|
401
406
|
&& !ds_opts.include?(:join) && !ds_opts.include?(:sql)
|
402
|
-
get_columns = proc
|
403
|
-
begin
|
404
|
-
columns
|
405
|
-
rescue Sequel::DatabaseConnectionError
|
406
|
-
raise
|
407
|
-
rescue
|
408
|
-
[]
|
409
|
-
end
|
410
|
-
end
|
407
|
+
get_columns = proc{check_non_connection_error{columns} || []}
|
411
408
|
if single_table && (schema_array = (db.schema(table_name, :reload=>reload) rescue nil))
|
412
409
|
schema_array.each{|k,v| schema_hash[k] = v}
|
413
410
|
if ds_opts.include?(:select)
|
@@ -576,7 +573,7 @@ module Sequel
|
|
576
573
|
# self.class.
|
577
574
|
alias_method :model, :class
|
578
575
|
|
579
|
-
# The
|
576
|
+
# The currently cached associations. A hash with the keys being the
|
580
577
|
# association name symbols and the values being the associated object
|
581
578
|
# or nil (many_to_one), or the array of associated objects (*_to_many).
|
582
579
|
def associations
|
@@ -904,7 +901,7 @@ module Sequel
|
|
904
901
|
|
905
902
|
# If transactions should be used, wrap the yield in a transaction block.
|
906
903
|
def checked_transaction(opts)
|
907
|
-
use_transaction?(opts)? db.transaction(opts){yield} : yield
|
904
|
+
use_transaction?(opts) ? db.transaction(opts){yield} : yield
|
908
905
|
end
|
909
906
|
|
910
907
|
# Default inspection output for the values hash, overwrite to change what #inspect displays.
|
data/lib/sequel/model/plugins.rb
CHANGED
@@ -5,8 +5,9 @@ module Sequel
|
|
5
5
|
# Plugins should be modules with one of the following conditions:
|
6
6
|
# * A singleton method named apply, which takes a model,
|
7
7
|
# additional arguments, and an optional block. This is called
|
8
|
-
#
|
9
|
-
#
|
8
|
+
# the first time the plugin is loaded for this model (unless it was
|
9
|
+
# already loaded by an ancestor class), with the arguments
|
10
|
+
# and block provided to the call to Model.plugin.
|
10
11
|
# * A module inside the plugin module named InstanceMethods,
|
11
12
|
# which will be included in the model class.
|
12
13
|
# * A module inside the plugin module named ClassMethods,
|
@@ -15,7 +15,7 @@ module Sequel
|
|
15
15
|
module BooleanReaders
|
16
16
|
# Default proc for determining if given column is a boolean, which
|
17
17
|
# just checks that the :type is boolean.
|
18
|
-
DEFAULT_BOOLEAN_ATTRIBUTE_PROC = lambda{|c| db_schema[c][:type] == :boolean}
|
18
|
+
DEFAULT_BOOLEAN_ATTRIBUTE_PROC = lambda{|c| s = db_schema[c] and s[:type] == :boolean}
|
19
19
|
|
20
20
|
# Add the boolean_attribute? class method to the model, and create
|
21
21
|
# attribute? boolean reader methods for the class's columns if the class has a dataset.
|
@@ -44,7 +44,8 @@ module Sequel
|
|
44
44
|
# Add attribute? methods for all of the boolean attributes for this model.
|
45
45
|
def create_boolean_readers
|
46
46
|
im = instance_methods.collect{|x| x.to_s}
|
47
|
-
|
47
|
+
cs = columns rescue return
|
48
|
+
cs.each{|c| create_boolean_reader(c) if boolean_attribute?(c) && !im.include?("#{c}?")}
|
48
49
|
end
|
49
50
|
end
|
50
51
|
end
|
@@ -80,6 +80,15 @@ module Sequel
|
|
80
80
|
end
|
81
81
|
|
82
82
|
module InstanceMethods
|
83
|
+
# Remove instances from the identity map cache if they are deleted.
|
84
|
+
def delete
|
85
|
+
super
|
86
|
+
if idm = model.identity_map
|
87
|
+
idm.delete(model.identity_map_key(pk))
|
88
|
+
end
|
89
|
+
self
|
90
|
+
end
|
91
|
+
|
83
92
|
# Merge the current values into the values provided in the row, ensuring
|
84
93
|
# that current values are not overridden by new values.
|
85
94
|
def merge_db_update(row)
|
@@ -54,6 +54,7 @@ module Sequel
|
|
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"}},
|
57
|
+
:type=>{:message=>lambda{|klass| "is not a #{klass}"}},
|
57
58
|
:presence=>{:message=>lambda{"is not present"}},
|
58
59
|
:unique=>{:message=>lambda{'is already taken'}}
|
59
60
|
}
|
@@ -110,7 +111,7 @@ module Sequel
|
|
110
111
|
def validates_not_string(atts, opts={})
|
111
112
|
validatable_attributes_for_type(:not_string, atts, opts){|a,v,m| validation_error_message(m, (db_schema[a]||{})[:type]) if v.is_a?(String)}
|
112
113
|
end
|
113
|
-
|
114
|
+
|
114
115
|
# Check attribute value(s) string representation is a valid float.
|
115
116
|
def validates_numeric(atts, opts={})
|
116
117
|
validatable_attributes_for_type(:numeric, atts, opts) do |a,v,m|
|
@@ -122,6 +123,12 @@ module Sequel
|
|
122
123
|
end
|
123
124
|
end
|
124
125
|
end
|
126
|
+
|
127
|
+
# Check if value is an instance of a class
|
128
|
+
def validates_type(klass, atts, opts={})
|
129
|
+
klass = klass.to_s.constantize if klass.is_a?(String) || klass.is_a?(Symbol)
|
130
|
+
validatable_attributes_for_type(:type, atts, opts){|a,v,m| validation_error_message(m, klass) if v && !v.is_a?(klass)}
|
131
|
+
end
|
125
132
|
|
126
133
|
# Check attribute value(s) is not considered blank by the database, but allow false values.
|
127
134
|
def validates_presence(atts, opts={})
|
data/lib/sequel/sql.rb
CHANGED
@@ -36,6 +36,16 @@ module Sequel
|
|
36
36
|
|
37
37
|
# Base class for all SQL fragments
|
38
38
|
class Expression
|
39
|
+
# all instance variables declared to be readers are to be used for comparison.
|
40
|
+
def self.attr_reader(*args)
|
41
|
+
super
|
42
|
+
comparison_attrs.concat args
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.comparison_attrs
|
46
|
+
@comparison_attrs ||= self == Expression ? [] : superclass.comparison_attrs.clone
|
47
|
+
end
|
48
|
+
|
39
49
|
# Create a to_s instance method that takes a dataset, and calls
|
40
50
|
# the method provided on the dataset with args as the argument (self by default).
|
41
51
|
# Used to DRY up some code.
|
@@ -54,6 +64,13 @@ module Sequel
|
|
54
64
|
def sql_literal(ds)
|
55
65
|
to_s(ds)
|
56
66
|
end
|
67
|
+
|
68
|
+
# Returns true if the receiver is the same expression as the
|
69
|
+
# the +other+ expression.
|
70
|
+
def eql?(other)
|
71
|
+
other.is_a?(self.class) && !self.class.comparison_attrs.find {|a| send(a) != other.send(a)}
|
72
|
+
end
|
73
|
+
alias == eql?
|
57
74
|
end
|
58
75
|
|
59
76
|
# Represents a complex SQL expression, with a given operator and one
|
@@ -74,10 +91,10 @@ module Sequel
|
|
74
91
|
:'!~*' => :'~*', :NOT => :NOOP, :NOOP => :NOT, :ILIKE => :'NOT ILIKE',
|
75
92
|
:'NOT ILIKE'=>:ILIKE}
|
76
93
|
|
77
|
-
# Mathematical Operators used in NumericMethods
|
94
|
+
# Standard Mathematical Operators used in NumericMethods
|
78
95
|
MATHEMATICAL_OPERATORS = [:+, :-, :/, :*]
|
79
96
|
|
80
|
-
# Mathematical Operators used in NumericMethods
|
97
|
+
# Bitwise Mathematical Operators used in NumericMethods
|
81
98
|
BITWISE_OPERATORS = [:&, :|, :^, :<<, :>>]
|
82
99
|
|
83
100
|
# Inequality Operators used in InequalityMethods
|
@@ -125,13 +142,6 @@ module Sequel
|
|
125
142
|
@op = op
|
126
143
|
@args = args
|
127
144
|
end
|
128
|
-
|
129
|
-
# Returns true if the receiver is the same expression as the
|
130
|
-
# the +other+ expression.
|
131
|
-
def eql?(other)
|
132
|
-
other.is_a?(self.class) && @op.eql?(other.op) && @args.eql?(other.args)
|
133
|
-
end
|
134
|
-
alias == eql?
|
135
145
|
|
136
146
|
to_s_method :complex_expression_sql, '@op, @args'
|
137
147
|
end
|
@@ -548,7 +558,7 @@ module Sequel
|
|
548
558
|
include SubscriptMethods
|
549
559
|
end
|
550
560
|
|
551
|
-
# Represents constants or psuedo-constants (e.g. CURRENT_DATE) in SQL
|
561
|
+
# Represents constants or psuedo-constants (e.g. CURRENT_DATE) in SQL.
|
552
562
|
class Constant < GenericExpression
|
553
563
|
# Create an object with the given table
|
554
564
|
def initialize(constant)
|
@@ -567,7 +577,7 @@ module Sequel
|
|
567
577
|
end
|
568
578
|
|
569
579
|
# Represents inverse boolean constants (currently only NOTNULL). A
|
570
|
-
# special class to allow for special behavior
|
580
|
+
# special class to allow for special behavior.
|
571
581
|
class NegativeBooleanConstant < BooleanConstant
|
572
582
|
to_s_method :negative_boolean_constant_sql, '@constant'
|
573
583
|
end
|
data/lib/sequel/version.rb
CHANGED
data/spec/adapters/mssql_spec.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'spec_helper.rb')
|
2
2
|
|
3
|
+
require ENV['SEQUEL_MSSQL_SPEC_REQUIRE'] if ENV['SEQUEL_MSSQL_SPEC_REQUIRE']
|
4
|
+
|
3
5
|
unless defined?(MSSQL_DB)
|
4
6
|
MSSQL_URL = 'jdbc:sqlserver://localhost;integratedSecurity=true;database=sandbox' unless defined? MSSQL_URL
|
5
7
|
MSSQL_DB = Sequel.connect(ENV['SEQUEL_MSSQL_SPEC_DB']||MSSQL_URL)
|
@@ -332,9 +334,13 @@ context "MSSSQL::Dataset#insert" do
|
|
332
334
|
specify "should have insert_select return nil if disable_insert_output is used" do
|
333
335
|
@ds.disable_insert_output.insert_select(:value=>10).should == nil
|
334
336
|
end
|
337
|
+
|
338
|
+
specify "should have insert_select return nil if the server version is not 2005+" do
|
339
|
+
@ds.meta_def(:server_version){8000760}
|
340
|
+
@ds.insert_select(:value=>10).should == nil
|
341
|
+
end
|
335
342
|
|
336
343
|
specify "should have insert_select insert the record and return the inserted record" do
|
337
|
-
@ds.meta_def(:server_version){80201}
|
338
344
|
h = @ds.insert_select(:value=>10)
|
339
345
|
h[:value].should == 10
|
340
346
|
@ds.first(:xid=>h[:xid])[:value].should == 10
|