sequel 4.21.0 → 4.22.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.
- checksums.yaml +4 -4
- data/CHANGELOG +32 -0
- data/README.rdoc +3 -4
- data/doc/opening_databases.rdoc +10 -75
- data/doc/release_notes/4.22.0.txt +72 -0
- data/lib/sequel/adapters/ado/access.rb +1 -1
- data/lib/sequel/adapters/cubrid.rb +3 -3
- data/lib/sequel/adapters/db2.rb +1 -0
- data/lib/sequel/adapters/dbi.rb +1 -0
- data/lib/sequel/adapters/fdbsql.rb +3 -2
- data/lib/sequel/adapters/firebird.rb +1 -0
- data/lib/sequel/adapters/ibmdb.rb +1 -21
- data/lib/sequel/adapters/informix.rb +1 -0
- data/lib/sequel/adapters/jdbc.rb +37 -49
- data/lib/sequel/adapters/jdbc/fdbsql.rb +1 -0
- data/lib/sequel/adapters/mysql.rb +5 -3
- data/lib/sequel/adapters/mysql2.rb +5 -2
- data/lib/sequel/adapters/odbc.rb +8 -4
- data/lib/sequel/adapters/openbase.rb +1 -0
- data/lib/sequel/adapters/oracle.rb +3 -46
- data/lib/sequel/adapters/postgres.rb +3 -36
- data/lib/sequel/adapters/shared/access.rb +1 -1
- data/lib/sequel/adapters/shared/fdbsql.rb +3 -3
- data/lib/sequel/adapters/shared/mssql.rb +1 -1
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +12 -44
- data/lib/sequel/adapters/shared/oracle.rb +6 -2
- data/lib/sequel/adapters/shared/postgres.rb +6 -6
- data/lib/sequel/adapters/shared/sqlite.rb +1 -1
- data/lib/sequel/adapters/sqlite.rb +3 -46
- data/lib/sequel/adapters/tinytds.rb +12 -28
- data/lib/sequel/adapters/utils/pg_types.rb +1 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +63 -16
- data/lib/sequel/connection_pool/threaded.rb +72 -18
- data/lib/sequel/core.rb +1 -1
- data/lib/sequel/database/connecting.rb +2 -2
- data/lib/sequel/database/misc.rb +5 -5
- data/lib/sequel/database/query.rb +3 -2
- data/lib/sequel/database/schema_generator.rb +19 -19
- data/lib/sequel/database/schema_methods.rb +2 -2
- data/lib/sequel/database/transactions.rb +3 -3
- data/lib/sequel/dataset/actions.rb +18 -8
- data/lib/sequel/dataset/graph.rb +2 -2
- data/lib/sequel/dataset/prepared_statements.rb +28 -1
- data/lib/sequel/dataset/query.rb +7 -7
- data/lib/sequel/exceptions.rb +27 -24
- data/lib/sequel/extensions/_pretty_table.rb +1 -1
- data/lib/sequel/extensions/constraint_validations.rb +2 -2
- data/lib/sequel/extensions/date_arithmetic.rb +2 -2
- data/lib/sequel/extensions/pg_array.rb +10 -1
- data/lib/sequel/extensions/pg_row.rb +1 -1
- data/lib/sequel/extensions/pg_static_cache_updater.rb +1 -1
- data/lib/sequel/extensions/schema_dumper.rb +8 -8
- data/lib/sequel/extensions/split_array_nil.rb +1 -1
- data/lib/sequel/model.rb +1 -1
- data/lib/sequel/model/associations.rb +18 -11
- data/lib/sequel/model/base.rb +15 -15
- data/lib/sequel/model/exceptions.rb +11 -2
- data/lib/sequel/plugins/accessed_columns.rb +1 -1
- data/lib/sequel/plugins/auto_validations.rb +1 -1
- data/lib/sequel/plugins/boolean_readers.rb +1 -1
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -7
- data/lib/sequel/plugins/composition.rb +1 -1
- data/lib/sequel/plugins/constraint_validations.rb +2 -2
- data/lib/sequel/plugins/csv_serializer.rb +171 -0
- data/lib/sequel/plugins/dirty.rb +2 -2
- data/lib/sequel/plugins/hook_class_methods.rb +1 -1
- data/lib/sequel/plugins/instance_hooks.rb +1 -1
- data/lib/sequel/plugins/many_through_many.rb +1 -1
- data/lib/sequel/plugins/nested_attributes.rb +5 -5
- data/lib/sequel/plugins/pg_array_associations.rb +4 -4
- data/lib/sequel/plugins/prepared_statements.rb +2 -2
- data/lib/sequel/plugins/prepared_statements_safe.rb +1 -1
- data/lib/sequel/plugins/serialization.rb +6 -6
- data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
- data/lib/sequel/plugins/sharding.rb +3 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +5 -13
- data/lib/sequel/plugins/static_cache.rb +2 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +1 -1
- data/lib/sequel/plugins/tree.rb +1 -1
- data/lib/sequel/plugins/validation_class_methods.rb +2 -2
- data/lib/sequel/plugins/validation_helpers.rb +4 -4
- data/lib/sequel/plugins/xml_serializer.rb +3 -3
- data/lib/sequel/sql.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/postgres_spec.rb +17 -0
- data/spec/core/connection_pool_spec.rb +1 -1
- data/spec/core/dataset_spec.rb +22 -0
- data/spec/extensions/auto_validations_spec.rb +1 -1
- data/spec/extensions/blacklist_security_spec.rb +2 -2
- data/spec/extensions/csv_serializer_spec.rb +173 -0
- data/spec/extensions/json_serializer_spec.rb +2 -2
- data/spec/extensions/nested_attributes_spec.rb +9 -9
- data/spec/extensions/pg_array_spec.rb +5 -0
- data/spec/extensions/single_table_inheritance_spec.rb +21 -0
- data/spec/extensions/touch_spec.rb +1 -1
- data/spec/extensions/tree_spec.rb +4 -0
- data/spec/extensions/xml_serializer_spec.rb +3 -3
- data/spec/integration/prepared_statement_test.rb +1 -1
- data/spec/integration/schema_test.rb +7 -0
- data/spec/integration/type_test.rb +2 -2
- data/spec/model/associations_spec.rb +108 -14
- data/spec/model/base_spec.rb +8 -8
- data/spec/model/record_spec.rb +7 -7
- metadata +6 -2
data/lib/sequel/plugins/dirty.rb
CHANGED
|
@@ -201,9 +201,9 @@ module Sequel
|
|
|
201
201
|
# Duplicate internal data structures
|
|
202
202
|
def initialize_copy(other)
|
|
203
203
|
super
|
|
204
|
-
@initial_values = other.initial_values
|
|
204
|
+
@initial_values = Hash[other.initial_values]
|
|
205
205
|
@missing_initial_values = other.send(:missing_initial_values).dup
|
|
206
|
-
@previous_changes = other.previous_changes
|
|
206
|
+
@previous_changes = Hash[other.previous_changes] if other.previous_changes
|
|
207
207
|
self
|
|
208
208
|
end
|
|
209
209
|
|
|
@@ -63,7 +63,7 @@ module Sequel
|
|
|
63
63
|
#
|
|
64
64
|
# class MyModel
|
|
65
65
|
# add_hook_type :before_move_to
|
|
66
|
-
# before_move_to(:check_move_allowed
|
|
66
|
+
# before_move_to(:check_move_allowed, &:allow_move?)
|
|
67
67
|
# def move_to(there)
|
|
68
68
|
# return if before_move_to == false
|
|
69
69
|
# # move MyModel object to there
|
|
@@ -82,7 +82,7 @@ module Sequel
|
|
|
82
82
|
|
|
83
83
|
# Run all hook blocks of the given hook type.
|
|
84
84
|
def run_after_instance_hooks(hook)
|
|
85
|
-
instance_hooks(hook).each
|
|
85
|
+
instance_hooks(hook).each(&:call)
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
# Run all hook blocks of the given hook type. If a hook block returns false,
|
|
@@ -263,7 +263,7 @@ module Sequel
|
|
|
263
263
|
select_all(egds.first_source).
|
|
264
264
|
select_append(*associated_key_array)
|
|
265
265
|
egds = opts.apply_eager_graph_limit_strategy(egls, egds)
|
|
266
|
-
ds.graph(egds, associated_key_array.map
|
|
266
|
+
ds.graph(egds, associated_key_array.map(&:alias).zip(Array(lpkcs)) + conditions, :qualify=>:deep, :table_alias=>eo[:table_alias], :implicit_qualifier=>iq, :join_type=>eo[:join_type]||join_type, :join_only=>eo[:join_only], :from_self_alias=>eo[:from_self_alias], :select=>select||orig_egds.columns, &graph_block)
|
|
267
267
|
else
|
|
268
268
|
opts.edges.each do |t|
|
|
269
269
|
ds = ds.graph(t[:table], t.fetch(:only_conditions, (Array(t[:right]).zip(Array(t[:left])) + t[:conditions])), :select=>false, :table_alias=>ds.unused_table_alias(t[:table]), :join_type=>eo[:join_type]||t[:join_type], :join_only=>eo[:join_only], :qualify=>:deep, :implicit_qualifier=>iq, :from_self_alias=>eo[:from_self_alias], &t[:block])
|
|
@@ -137,7 +137,7 @@ module Sequel
|
|
|
137
137
|
def set_nested_attributes(assoc, obj, opts=OPTS)
|
|
138
138
|
raise(Error, "no association named #{assoc} for #{model.inspect}") unless ref = model.association_reflection(assoc)
|
|
139
139
|
raise(Error, "nested attributes are not enabled for association #{assoc} for #{model.inspect}") unless meta = ref[:nested_attributes]
|
|
140
|
-
meta = meta.merge(opts)
|
|
140
|
+
meta = Hash[meta].merge!(opts)
|
|
141
141
|
meta[:reflection] = ref
|
|
142
142
|
if ref.returns_array?
|
|
143
143
|
nested_attributes_list_setter(meta, obj)
|
|
@@ -195,7 +195,7 @@ module Sequel
|
|
|
195
195
|
# If there is a limit on the nested attributes for this association,
|
|
196
196
|
# make sure the length of the attributes_list is not greater than the limit.
|
|
197
197
|
def nested_attributes_list_setter(meta, attributes_list)
|
|
198
|
-
attributes_list = attributes_list.sort_by
|
|
198
|
+
attributes_list = attributes_list.sort_by(&:to_s).map{|k,v| v} if attributes_list.is_a?(Hash)
|
|
199
199
|
if (limit = meta[:limit]) && attributes_list.length > limit
|
|
200
200
|
raise(Error, "number of nested attributes (#{attributes_list.length}) exceeds the limit (#{limit})")
|
|
201
201
|
end
|
|
@@ -254,10 +254,10 @@ module Sequel
|
|
|
254
254
|
reflection = meta[:reflection]
|
|
255
255
|
klass = reflection.associated_class
|
|
256
256
|
sym_keys = Array(klass.primary_key)
|
|
257
|
-
str_keys = sym_keys.map
|
|
257
|
+
str_keys = sym_keys.map(&:to_s)
|
|
258
258
|
if (pk = attributes.values_at(*sym_keys)).all? || (pk = attributes.values_at(*str_keys)).all?
|
|
259
|
-
pk = pk.map
|
|
260
|
-
obj = Array(send(reflection[:name])).find{|x| Array(x.pk).map
|
|
259
|
+
pk = pk.map(&:to_s)
|
|
260
|
+
obj = Array(send(reflection[:name])).find{|x| Array(x.pk).map(&:to_s) == pk}
|
|
261
261
|
end
|
|
262
262
|
if obj
|
|
263
263
|
attributes = attributes.dup.delete_if{|k,v| str_keys.include? k.to_s}
|
|
@@ -312,7 +312,7 @@ module Sequel
|
|
|
312
312
|
opts[:eager_loader] ||= proc do |eo|
|
|
313
313
|
id_map = eo[:id_map]
|
|
314
314
|
|
|
315
|
-
eager_load_results(opts, eo.merge(:loader=>false)) do |assoc_record|
|
|
315
|
+
eager_load_results(opts, Hash[eo].merge!(:loader=>false)) do |assoc_record|
|
|
316
316
|
if pks ||= assoc_record.get_column_value(key)
|
|
317
317
|
pks.each do |pkv|
|
|
318
318
|
next unless objects = id_map[pkv]
|
|
@@ -348,7 +348,7 @@ module Sequel
|
|
|
348
348
|
|
|
349
349
|
opts[:eager_grapher] ||= proc do |eo|
|
|
350
350
|
ds = eo[:self]
|
|
351
|
-
ds = ds.graph(eager_graph_dataset(opts, eo), conditions, eo.merge(:select=>select, :join_type=>eo[:join_type]||join_type, :qualify=>:deep, :from_self_alias=>eo[:from_self_alias]), &graph_block)
|
|
351
|
+
ds = ds.graph(eager_graph_dataset(opts, eo), conditions, Hash[eo].merge!(:select=>select, :join_type=>eo[:join_type]||join_type, :qualify=>:deep, :from_self_alias=>eo[:from_self_alias]), &graph_block)
|
|
352
352
|
ds
|
|
353
353
|
end
|
|
354
354
|
|
|
@@ -402,7 +402,7 @@ module Sequel
|
|
|
402
402
|
end
|
|
403
403
|
end
|
|
404
404
|
|
|
405
|
-
eager_load_results(opts, eo.merge(:id_map=>id_map)) do |assoc_record|
|
|
405
|
+
eager_load_results(opts, Hash[eo].merge!(:id_map=>id_map)) do |assoc_record|
|
|
406
406
|
if objects = id_map[assoc_record.get_column_value(pkm)]
|
|
407
407
|
objects.each do |object|
|
|
408
408
|
object.associations[name].push(assoc_record)
|
|
@@ -435,7 +435,7 @@ module Sequel
|
|
|
435
435
|
|
|
436
436
|
opts[:eager_grapher] ||= proc do |eo|
|
|
437
437
|
ds = eo[:self]
|
|
438
|
-
ds = ds.graph(eager_graph_dataset(opts, eo), conditions, eo.merge(:select=>select, :join_type=>eo[:join_type]||join_type, :qualify=>:deep, :from_self_alias=>eo[:from_self_alias]), &graph_block)
|
|
438
|
+
ds = ds.graph(eager_graph_dataset(opts, eo), conditions, Hash[eo].merge!(:select=>select, :join_type=>eo[:join_type]||join_type, :qualify=>:deep, :from_self_alias=>eo[:from_self_alias]), &graph_block)
|
|
439
439
|
ds
|
|
440
440
|
end
|
|
441
441
|
|
|
@@ -72,7 +72,7 @@ module Sequel
|
|
|
72
72
|
|
|
73
73
|
# Return a sorted array of columns for use as a hash key.
|
|
74
74
|
def prepared_columns(cols)
|
|
75
|
-
RUBY_VERSION >= '1.9' ? cols.sort : cols.sort_by
|
|
75
|
+
RUBY_VERSION >= '1.9' ? cols.sort : cols.sort_by(&:to_s)
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
# Return a prepared statement that can be used to delete a row from this model's dataset.
|
|
@@ -194,7 +194,7 @@ module Sequel
|
|
|
194
194
|
# Use a prepared statement to update this model's columns in the database.
|
|
195
195
|
def _update_without_checking(columns)
|
|
196
196
|
if use_prepared_statements_for?(:update)
|
|
197
|
-
model.send(:prepared_update, columns.keys).call(columns.merge(pk_hash))
|
|
197
|
+
model.send(:prepared_update, columns.keys).call(Hash[columns].merge!(pk_hash))
|
|
198
198
|
else
|
|
199
199
|
super
|
|
200
200
|
end
|
|
@@ -36,8 +36,8 @@ module Sequel
|
|
|
36
36
|
# # Register custom serializer/deserializer pair, if desired
|
|
37
37
|
# require 'sequel/plugins/serialization'
|
|
38
38
|
# Sequel::Plugins::Serialization.register_format(:reverse,
|
|
39
|
-
# lambda
|
|
40
|
-
# lambda
|
|
39
|
+
# lambda(&:reverse),
|
|
40
|
+
# lambda(&:reverse))
|
|
41
41
|
#
|
|
42
42
|
# class User < Sequel::Model
|
|
43
43
|
# # Built-in format support when loading the plugin
|
|
@@ -51,7 +51,7 @@ module Sequel
|
|
|
51
51
|
# serialize_attributes :reverse, :password
|
|
52
52
|
#
|
|
53
53
|
# # Use a custom serializer/deserializer pair without registering
|
|
54
|
-
# serialize_attributes [lambda
|
|
54
|
+
# serialize_attributes [lambda(&:reverse), lambda(&:reverse)], :password
|
|
55
55
|
# end
|
|
56
56
|
# user = User.create
|
|
57
57
|
# user.permissions = { :global => 'read-only' }
|
|
@@ -106,7 +106,7 @@ module Sequel
|
|
|
106
106
|
end
|
|
107
107
|
end
|
|
108
108
|
end)
|
|
109
|
-
register_format(:yaml, lambda
|
|
109
|
+
register_format(:yaml, lambda(&:to_yaml), lambda{|v| YAML.load(v)})
|
|
110
110
|
register_format(:json, lambda{|v| Sequel.object_to_json(v)}, lambda{|v| Sequel.parse_json(v)})
|
|
111
111
|
|
|
112
112
|
module ClassMethods
|
|
@@ -129,7 +129,7 @@ module Sequel
|
|
|
129
129
|
def serialize_attributes(format, *columns)
|
|
130
130
|
if format.is_a?(Symbol)
|
|
131
131
|
unless format = REGISTERED_FORMATS[format]
|
|
132
|
-
raise(Error, "Unsupported serialization format: #{format} (valid formats: #{REGISTERED_FORMATS.keys.map
|
|
132
|
+
raise(Error, "Unsupported serialization format: #{format} (valid formats: #{REGISTERED_FORMATS.keys.map(&:inspect).join})")
|
|
133
133
|
end
|
|
134
134
|
end
|
|
135
135
|
serializer, deserializer = format
|
|
@@ -212,7 +212,7 @@ module Sequel
|
|
|
212
212
|
# Dup the deserialized values when duping model instance.
|
|
213
213
|
def initialize_copy(other)
|
|
214
214
|
super
|
|
215
|
-
@deserialized_values = other.deserialized_values
|
|
215
|
+
@deserialized_values = Hash[other.deserialized_values]
|
|
216
216
|
self
|
|
217
217
|
end
|
|
218
218
|
|
|
@@ -59,7 +59,7 @@ module Sequel
|
|
|
59
59
|
# # and :key_map taking a class object and returning the column
|
|
60
60
|
# # value to use
|
|
61
61
|
# Employee.plugin :single_table_inheritance, :type,
|
|
62
|
-
# :model_map=>proc
|
|
62
|
+
# :model_map=>proc(&:reverse),
|
|
63
63
|
# :key_map=>proc{|klass| klass.name.reverse}
|
|
64
64
|
#
|
|
65
65
|
# # You can use the same class for multiple values.
|
|
@@ -147,27 +147,19 @@ module Sequel
|
|
|
147
147
|
# This defaults to a lookup in the key map.
|
|
148
148
|
attr_reader :sti_key_chooser
|
|
149
149
|
|
|
150
|
+
Plugins.inherited_instance_variables(self, :@sti_dataset=>nil, :@sti_key=>nil, :@sti_key_map=>nil, :@sti_model_map=>nil, :@sti_key_chooser=>nil)
|
|
151
|
+
|
|
150
152
|
# Copy the necessary attributes to the subclasses, and filter the
|
|
151
153
|
# subclass's dataset based on the sti_kep_map entry for the class.
|
|
152
154
|
def inherited(subclass)
|
|
153
155
|
super
|
|
154
|
-
|
|
155
|
-
sd = sti_dataset
|
|
156
|
-
skm = sti_key_map
|
|
157
|
-
smm = sti_model_map
|
|
158
|
-
skc = sti_key_chooser
|
|
159
|
-
key = Array(skm[subclass]).dup
|
|
156
|
+
key = Array(sti_key_map[subclass]).dup
|
|
160
157
|
sti_subclass_added(key)
|
|
161
158
|
rp = dataset.row_proc
|
|
162
|
-
subclass.set_dataset(
|
|
159
|
+
subclass.set_dataset(sti_dataset.filter(SQL::QualifiedIdentifier.new(sti_dataset.first_source_alias, sti_key)=>key), :inherited=>true)
|
|
163
160
|
subclass.instance_eval do
|
|
164
161
|
dataset.row_proc = rp
|
|
165
|
-
@sti_key = sk
|
|
166
162
|
@sti_key_array = key
|
|
167
|
-
@sti_dataset = sd
|
|
168
|
-
@sti_key_map = skm
|
|
169
|
-
@sti_model_map = smm
|
|
170
|
-
@sti_key_chooser = skc
|
|
171
163
|
self.simple_table = nil
|
|
172
164
|
end
|
|
173
165
|
end
|
|
@@ -111,7 +111,7 @@ module Sequel
|
|
|
111
111
|
def to_hash(key_column = nil, value_column = nil)
|
|
112
112
|
if key_column.nil? && value_column.nil?
|
|
113
113
|
if @static_cache_frozen
|
|
114
|
-
return cache
|
|
114
|
+
return Hash[cache]
|
|
115
115
|
else
|
|
116
116
|
key_column = primary_key
|
|
117
117
|
end
|
|
@@ -198,7 +198,7 @@ module Sequel
|
|
|
198
198
|
if @static_cache_frozen
|
|
199
199
|
o
|
|
200
200
|
elsif o
|
|
201
|
-
call(o.values
|
|
201
|
+
call(Hash[o.values])
|
|
202
202
|
end
|
|
203
203
|
end
|
|
204
204
|
end
|
|
@@ -53,7 +53,7 @@ module Sequel
|
|
|
53
53
|
name = opts[:name]
|
|
54
54
|
if !associations.include?(name) && retrieved_by && !frozen?
|
|
55
55
|
begin
|
|
56
|
-
retrieved_by.send(:eager_load, retrieved_with.reject
|
|
56
|
+
retrieved_by.send(:eager_load, retrieved_with.reject(&:frozen?), name=>{})
|
|
57
57
|
rescue Sequel::UndefinedAssociation
|
|
58
58
|
# This can happen if class table inheritance is used and the association
|
|
59
59
|
# is only defined in a subclass. This particular instance can use the
|
data/lib/sequel/plugins/tree.rb
CHANGED
|
@@ -182,8 +182,8 @@ module Sequel
|
|
|
182
182
|
blk = if (i = opts[:if]) || (am = opts[:allow_missing]) || (an = opts[:allow_nil]) || (ab = opts[:allow_blank])
|
|
183
183
|
proc do |o,a,v|
|
|
184
184
|
next if i && !validation_if_proc(o, i)
|
|
185
|
-
next if an && Array(v).all?
|
|
186
|
-
next if ab && Array(v).all?
|
|
185
|
+
next if an && Array(v).all?(&:nil?)
|
|
186
|
+
next if ab && Array(v).all?(&:blank?)
|
|
187
187
|
next if am && Array(a).all?{|x| !o.values.has_key?(x)}
|
|
188
188
|
block.call(o,a,v)
|
|
189
189
|
end
|
|
@@ -156,7 +156,7 @@ module Sequel
|
|
|
156
156
|
def validates_schema_types(atts=keys, opts=OPTS)
|
|
157
157
|
Array(atts).each do |k|
|
|
158
158
|
if type = schema_type_class(k)
|
|
159
|
-
validates_type(type, k, {:allow_nil=>true}.merge(opts))
|
|
159
|
+
validates_type(type, k, {:allow_nil=>true}.merge!(opts))
|
|
160
160
|
end
|
|
161
161
|
end
|
|
162
162
|
end
|
|
@@ -224,7 +224,7 @@ module Sequel
|
|
|
224
224
|
def validates_unique(*atts)
|
|
225
225
|
opts = default_validation_helpers_options(:unique)
|
|
226
226
|
if atts.last.is_a?(Hash)
|
|
227
|
-
opts = opts.merge(atts.pop)
|
|
227
|
+
opts = Hash[opts].merge!(atts.pop)
|
|
228
228
|
end
|
|
229
229
|
message = validation_error_message(opts[:message])
|
|
230
230
|
where = opts[:where]
|
|
@@ -237,7 +237,7 @@ module Sequel
|
|
|
237
237
|
where.call(ds, self, arr)
|
|
238
238
|
else
|
|
239
239
|
vals = arr.map{|x| get_column_value(x)}
|
|
240
|
-
next if vals.any?
|
|
240
|
+
next if vals.any?(&:nil?)
|
|
241
241
|
ds.where(arr.zip(vals))
|
|
242
242
|
end
|
|
243
243
|
ds = yield(ds) if block_given?
|
|
@@ -279,7 +279,7 @@ module Sequel
|
|
|
279
279
|
# Merge the given options with the default options for the given type
|
|
280
280
|
# and call validatable_attributes with the merged options.
|
|
281
281
|
def validatable_attributes_for_type(type, atts, opts, &block)
|
|
282
|
-
validatable_attributes(atts, default_validation_helpers_options(type).merge(opts), &block)
|
|
282
|
+
validatable_attributes(atts, Hash[default_validation_helpers_options(type)].merge!(opts), &block)
|
|
283
283
|
end
|
|
284
284
|
|
|
285
285
|
# The validation error message to use, as a string. If message
|
|
@@ -113,17 +113,17 @@ module Sequel
|
|
|
113
113
|
module XmlSerializer
|
|
114
114
|
module ClassMethods
|
|
115
115
|
# Proc that camelizes the input string, used for the :camelize option
|
|
116
|
-
CAMELIZE = proc
|
|
116
|
+
CAMELIZE = proc(&:camelize)
|
|
117
117
|
|
|
118
118
|
# Proc that dasherizes the input string, used for the :dasherize option
|
|
119
|
-
DASHERIZE = proc
|
|
119
|
+
DASHERIZE = proc(&:dasherize)
|
|
120
120
|
|
|
121
121
|
# Proc that returns the input string as is, used if
|
|
122
122
|
# no :name_proc, :dasherize, or :camelize option is used.
|
|
123
123
|
IDENTITY = proc{|s| s}
|
|
124
124
|
|
|
125
125
|
# Proc that underscores the input string, used for the :underscore option
|
|
126
|
-
UNDERSCORE = proc
|
|
126
|
+
UNDERSCORE = proc(&:underscore)
|
|
127
127
|
|
|
128
128
|
# Return an array of instances of this class based on
|
|
129
129
|
# the provided XML.
|
data/lib/sequel/sql.rb
CHANGED
|
@@ -1378,7 +1378,7 @@ module Sequel
|
|
|
1378
1378
|
|
|
1379
1379
|
# Return a new function call with the given opts merged into the current opts.
|
|
1380
1380
|
def with_opts(opts)
|
|
1381
|
-
self.class.new!(name, args, @opts.merge(opts))
|
|
1381
|
+
self.class.new!(name, args, Hash[@opts].merge!(opts))
|
|
1382
1382
|
end
|
|
1383
1383
|
end
|
|
1384
1384
|
|
data/lib/sequel/version.rb
CHANGED
|
@@ -3,7 +3,7 @@ module Sequel
|
|
|
3
3
|
MAJOR = 4
|
|
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 = 22
|
|
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
|
|
@@ -2162,6 +2162,23 @@ describe 'PostgreSQL array handling' do
|
|
|
2162
2162
|
end
|
|
2163
2163
|
end
|
|
2164
2164
|
|
|
2165
|
+
specify 'convert ruby array :default values' do
|
|
2166
|
+
@db.create_table!(:items) do
|
|
2167
|
+
column :n, 'integer[]', :default=>[]
|
|
2168
|
+
end
|
|
2169
|
+
@ds.insert
|
|
2170
|
+
@ds.count.should == 1
|
|
2171
|
+
if @native
|
|
2172
|
+
rs = @ds.all
|
|
2173
|
+
rs.should == [{:n=>[]}]
|
|
2174
|
+
rs.first.values.each{|v| v.should_not be_a_kind_of(Array)}
|
|
2175
|
+
rs.first.values.each{|v| v.to_a.should be_a_kind_of(Array)}
|
|
2176
|
+
@ds.delete
|
|
2177
|
+
@ds.insert(rs.first)
|
|
2178
|
+
@ds.all.should == rs
|
|
2179
|
+
end
|
|
2180
|
+
end
|
|
2181
|
+
|
|
2165
2182
|
specify 'insert and retrieve custom array types' do
|
|
2166
2183
|
int2vector = Class.new do
|
|
2167
2184
|
attr_reader :array
|
|
@@ -33,7 +33,7 @@ describe "ConnectionPool options" do
|
|
|
33
33
|
cpool = Sequel::ConnectionPool.get_pool(mock_db.call, {:max_connections=>'5', :pool_timeout=>'3', :pool_sleep_time=>'0.01'})
|
|
34
34
|
cpool.max_size.should == 5
|
|
35
35
|
cpool.instance_variable_get(:@timeout).should == 3
|
|
36
|
-
cpool.instance_variable_get(:@sleep_time).should == 0.01
|
|
36
|
+
cpool.instance_variable_get(:@sleep_time).should == 0.01 unless cpool.class::USE_WAITER
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
specify "should raise an error unless size is positive" do
|
data/spec/core/dataset_spec.rb
CHANGED
|
@@ -1758,6 +1758,17 @@ describe "Dataset#to_hash" do
|
|
|
1758
1758
|
@d.to_hash(:b).should == {4 => {:a => 2, :b => 4}, 8 => {:a => 6, :b => 8}, 12 => {:a => 10, :b => 12}}
|
|
1759
1759
|
@d.to_hash([:a, :b]).should == {[2, 4] => {:a => 2, :b => 4}, [6, 8] => {:a => 6, :b => 8}, [10, 12] => {:a => 10, :b => 12}}
|
|
1760
1760
|
end
|
|
1761
|
+
|
|
1762
|
+
specify "should handle a single composite key when using a row_proc" do
|
|
1763
|
+
c = @d.row_proc = Class.new do
|
|
1764
|
+
def self.call(h); new(h); end
|
|
1765
|
+
def initialize(h); @h = h; end
|
|
1766
|
+
def [](k) @h[k]; end
|
|
1767
|
+
def h; @h; end
|
|
1768
|
+
def ==(o) @h == o.h; end
|
|
1769
|
+
end
|
|
1770
|
+
@d.to_hash([:a, :b]).should == {[1, 2] => c.call(:a => 1, :b => 2), [3, 4] => c.call(:a => 3, :b => 4), [5, 6] => c.call(:a => 5, :b => 6)}
|
|
1771
|
+
end
|
|
1761
1772
|
end
|
|
1762
1773
|
|
|
1763
1774
|
describe "Dataset#to_hash_groups" do
|
|
@@ -1797,6 +1808,17 @@ describe "Dataset#to_hash_groups" do
|
|
|
1797
1808
|
@d.to_hash_groups(:b).should == {4 => [{:a => 2, :b => 4}], 8 => [{:a => 6, :b => 8}, {:a => 14, :b => 8}], 12 => [{:a => 2, :b => 12}]}
|
|
1798
1809
|
@d.to_hash_groups([:a, :b]).should == {[2, 4] => [{:a => 2, :b => 4}], [6, 8] => [{:a => 6, :b => 8}], [2, 12] => [{:a => 2, :b => 12}], [14, 8] => [{:a => 14, :b => 8}]}
|
|
1799
1810
|
end
|
|
1811
|
+
|
|
1812
|
+
specify "should handle a single composite key when using a row_proc" do
|
|
1813
|
+
c = @d.row_proc = Class.new do
|
|
1814
|
+
def self.call(h); new(h); end
|
|
1815
|
+
def initialize(h); @h = h; end
|
|
1816
|
+
def [](k) @h[k]; end
|
|
1817
|
+
def h; @h; end
|
|
1818
|
+
def ==(o) @h == o.h; end
|
|
1819
|
+
end
|
|
1820
|
+
@d.to_hash_groups([:a, :b]).should == {[1, 2] => [c.call(:a => 1, :b => 2)], [3, 4] => [c.call(:a => 3, :b => 4)], [1, 6] => [c.call(:a => 1, :b => 6)], [7, 4] => [c.call(:a => 7, :b => 4)]}
|
|
1821
|
+
end
|
|
1800
1822
|
end
|
|
1801
1823
|
|
|
1802
1824
|
describe "Dataset#distinct" do
|