sequel 4.21.0 → 4.22.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|