sequel 4.18.0 → 4.19.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 +18 -0
 - data/MIT-LICENSE +1 -1
 - data/doc/advanced_associations.rdoc +1 -1
 - data/doc/association_basics.rdoc +55 -34
 - data/doc/model_hooks.rdoc +7 -5
 - data/doc/release_notes/4.19.0.txt +45 -0
 - data/doc/validations.rdoc +4 -0
 - data/lib/sequel/adapters/shared/mysql.rb +5 -3
 - data/lib/sequel/adapters/shared/sqlanywhere.rb +3 -2
 - data/lib/sequel/dataset/sql.rb +1 -1
 - data/lib/sequel/extensions/migration.rb +12 -8
 - data/lib/sequel/model/associations.rb +24 -24
 - data/lib/sequel/model/base.rb +39 -8
 - data/lib/sequel/plugins/accessed_columns.rb +61 -0
 - data/lib/sequel/plugins/association_pks.rb +4 -4
 - data/lib/sequel/plugins/boolean_readers.rb +1 -1
 - data/lib/sequel/plugins/class_table_inheritance.rb +1 -1
 - data/lib/sequel/plugins/column_conflicts.rb +93 -0
 - data/lib/sequel/plugins/composition.rb +3 -3
 - data/lib/sequel/plugins/dirty.rb +6 -6
 - data/lib/sequel/plugins/json_serializer.rb +1 -1
 - data/lib/sequel/plugins/list.rb +4 -4
 - data/lib/sequel/plugins/mssql_optimistic_locking.rb +1 -1
 - data/lib/sequel/plugins/nested_attributes.rb +2 -2
 - data/lib/sequel/plugins/optimistic_locking.rb +3 -3
 - data/lib/sequel/plugins/pg_array_associations.rb +23 -23
 - data/lib/sequel/plugins/prepared_statements_associations.rb +1 -1
 - data/lib/sequel/plugins/rcte_tree.rb +2 -2
 - data/lib/sequel/plugins/serialization.rb +1 -1
 - data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
 - data/lib/sequel/plugins/timestamps.rb +2 -2
 - data/lib/sequel/plugins/typecast_on_load.rb +1 -1
 - data/lib/sequel/plugins/validation_class_methods.rb +4 -4
 - data/lib/sequel/plugins/validation_helpers.rb +2 -2
 - data/lib/sequel/version.rb +1 -1
 - data/spec/core/dataset_spec.rb +7 -0
 - data/spec/extensions/accessed_columns_spec.rb +51 -0
 - data/spec/extensions/column_conflicts_spec.rb +55 -0
 - data/spec/extensions/hook_class_methods_spec.rb +18 -5
 - data/spec/extensions/migration_spec.rb +4 -1
 - data/spec/extensions/static_cache_spec.rb +3 -3
 - data/spec/model/hooks_spec.rb +76 -9
 - data/spec/model/record_spec.rb +43 -2
 - metadata +8 -2
 
| 
         @@ -94,7 +94,7 @@ module Sequel 
     | 
|
| 
       94 
94 
     | 
    
         
             
                    # many_to_pg_array associations can have associated objects as long as they have
         
     | 
| 
       95 
95 
     | 
    
         
             
                    # a primary key.
         
     | 
| 
       96 
96 
     | 
    
         
             
                    def can_have_associated_objects?(obj)
         
     | 
| 
       97 
     | 
    
         
            -
                      obj. 
     | 
| 
      
 97 
     | 
    
         
            +
                      obj.get_column_value(self[:primary_key])
         
     | 
| 
       98 
98 
     | 
    
         
             
                    end
         
     | 
| 
       99 
99 
     | 
    
         | 
| 
       100 
100 
     | 
    
         
             
                    # Assume that the key in the associated table uses a version of the current
         
     | 
| 
         @@ -195,7 +195,7 @@ module Sequel 
     | 
|
| 
       195 
195 
     | 
    
         
             
                    # pg_array_to_many associations can only have associated objects if
         
     | 
| 
       196 
196 
     | 
    
         
             
                    # the array field is not nil or empty.
         
     | 
| 
       197 
197 
     | 
    
         
             
                    def can_have_associated_objects?(obj)
         
     | 
| 
       198 
     | 
    
         
            -
                      v = obj. 
     | 
| 
      
 198 
     | 
    
         
            +
                      v = obj.get_column_value(self[:key])
         
     | 
| 
       199 
199 
     | 
    
         
             
                      v && !v.empty?
         
     | 
| 
       200 
200 
     | 
    
         
             
                    end
         
     | 
| 
       201 
201 
     | 
    
         | 
| 
         @@ -307,13 +307,13 @@ module Sequel 
     | 
|
| 
       307 
307 
     | 
    
         
             
                      key_column = opts[:key_column] ||= opts[:key]
         
     | 
| 
       308 
308 
     | 
    
         
             
                      opts[:after_load].unshift(:array_uniq!) if opts[:uniq]
         
     | 
| 
       309 
309 
     | 
    
         
             
                      opts[:dataset] ||= lambda do
         
     | 
| 
       310 
     | 
    
         
            -
                        opts.associated_dataset.where(Sequel.pg_array_op(opts.predicate_key).contains(Sequel.pg_array([ 
     | 
| 
      
 310 
     | 
    
         
            +
                        opts.associated_dataset.where(Sequel.pg_array_op(opts.predicate_key).contains(Sequel.pg_array([get_column_value(pk)], opts.array_type)))
         
     | 
| 
       311 
311 
     | 
    
         
             
                      end
         
     | 
| 
       312 
312 
     | 
    
         
             
                      opts[:eager_loader] ||= proc do |eo|
         
     | 
| 
       313 
313 
     | 
    
         
             
                        id_map = eo[:id_map]
         
     | 
| 
       314 
314 
     | 
    
         | 
| 
       315 
315 
     | 
    
         
             
                        eager_load_results(opts, eo.merge(:loader=>false)) do |assoc_record|
         
     | 
| 
       316 
     | 
    
         
            -
                          if pks ||= assoc_record. 
     | 
| 
      
 316 
     | 
    
         
            +
                          if pks ||= assoc_record.get_column_value(key)
         
     | 
| 
       317 
317 
     | 
    
         
             
                            pks.each do |pkv|
         
     | 
| 
       318 
318 
     | 
    
         
             
                              next unless objects = id_map[pkv]
         
     | 
| 
       319 
319 
     | 
    
         
             
                              objects.each do |object| 
         
     | 
| 
         @@ -358,23 +358,23 @@ module Sequel 
     | 
|
| 
       358 
358 
     | 
    
         
             
                      save_opts[:raise_on_failure] = opts[:raise_on_save_failure] != false
         
     | 
| 
       359 
359 
     | 
    
         | 
| 
       360 
360 
     | 
    
         
             
                      opts[:adder] ||= proc do |o|
         
     | 
| 
       361 
     | 
    
         
            -
                        if array = o. 
     | 
| 
       362 
     | 
    
         
            -
                          array <<  
     | 
| 
      
 361 
     | 
    
         
            +
                        if array = o.get_column_value(key)
         
     | 
| 
      
 362 
     | 
    
         
            +
                          array << get_column_value(pk)
         
     | 
| 
       363 
363 
     | 
    
         
             
                        else
         
     | 
| 
       364 
     | 
    
         
            -
                          o. 
     | 
| 
      
 364 
     | 
    
         
            +
                          o.set_column_value("#{key}=", Sequel.pg_array([get_column_value(pk)], opts.array_type))
         
     | 
| 
       365 
365 
     | 
    
         
             
                        end
         
     | 
| 
       366 
366 
     | 
    
         
             
                        o.save(save_opts)
         
     | 
| 
       367 
367 
     | 
    
         
             
                      end
         
     | 
| 
       368 
368 
     | 
    
         | 
| 
       369 
369 
     | 
    
         
             
                      opts[:remover] ||= proc do |o|
         
     | 
| 
       370 
     | 
    
         
            -
                        if (array = o. 
     | 
| 
       371 
     | 
    
         
            -
                          array.delete( 
     | 
| 
      
 370 
     | 
    
         
            +
                        if (array = o.get_column_value(key)) && !array.empty?
         
     | 
| 
      
 371 
     | 
    
         
            +
                          array.delete(get_column_value(pk))
         
     | 
| 
       372 
372 
     | 
    
         
             
                          o.save(save_opts)
         
     | 
| 
       373 
373 
     | 
    
         
             
                        end
         
     | 
| 
       374 
374 
     | 
    
         
             
                      end
         
     | 
| 
       375 
375 
     | 
    
         | 
| 
       376 
376 
     | 
    
         
             
                      opts[:clearer] ||= proc do
         
     | 
| 
       377 
     | 
    
         
            -
                        opts.associated_dataset.where(Sequel.pg_array_op(key).contains([ 
     | 
| 
      
 377 
     | 
    
         
            +
                        opts.associated_dataset.where(Sequel.pg_array_op(key).contains([get_column_value(pk)])).update(key=>Sequel.function(:array_remove, key, get_column_value(pk)))
         
     | 
| 
       378 
378 
     | 
    
         
             
                      end
         
     | 
| 
       379 
379 
     | 
    
         
             
                    end
         
     | 
| 
       380 
380 
     | 
    
         | 
| 
         @@ -387,7 +387,7 @@ module Sequel 
     | 
|
| 
       387 
387 
     | 
    
         
             
                      opts[:eager_loader_key] = nil
         
     | 
| 
       388 
388 
     | 
    
         
             
                      opts[:after_load].unshift(:array_uniq!) if opts[:uniq]
         
     | 
| 
       389 
389 
     | 
    
         
             
                      opts[:dataset] ||= lambda do
         
     | 
| 
       390 
     | 
    
         
            -
                        opts.associated_dataset.where(opts.predicate_key=> 
     | 
| 
      
 390 
     | 
    
         
            +
                        opts.associated_dataset.where(opts.predicate_key=>get_column_value(key).to_a)
         
     | 
| 
       391 
391 
     | 
    
         
             
                      end
         
     | 
| 
       392 
392 
     | 
    
         
             
                      opts[:eager_loader] ||= proc do |eo|
         
     | 
| 
       393 
393 
     | 
    
         
             
                        rows = eo[:rows]
         
     | 
| 
         @@ -395,7 +395,7 @@ module Sequel 
     | 
|
| 
       395 
395 
     | 
    
         
             
                        pkm = opts.primary_key_method
         
     | 
| 
       396 
396 
     | 
    
         | 
| 
       397 
397 
     | 
    
         
             
                        rows.each do |object|
         
     | 
| 
       398 
     | 
    
         
            -
                          if associated_pks = object. 
     | 
| 
      
 398 
     | 
    
         
            +
                          if associated_pks = object.get_column_value(key)
         
     | 
| 
       399 
399 
     | 
    
         
             
                            associated_pks.each do |apk|
         
     | 
| 
       400 
400 
     | 
    
         
             
                              (id_map[apk] ||= []) << object
         
     | 
| 
       401 
401 
     | 
    
         
             
                            end
         
     | 
| 
         @@ -403,7 +403,7 @@ module Sequel 
     | 
|
| 
       403 
403 
     | 
    
         
             
                        end
         
     | 
| 
       404 
404 
     | 
    
         | 
| 
       405 
405 
     | 
    
         
             
                        eager_load_results(opts, eo.merge(:id_map=>id_map)) do |assoc_record|
         
     | 
| 
       406 
     | 
    
         
            -
                          if objects = id_map[assoc_record. 
     | 
| 
      
 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)
         
     | 
| 
       409 
409 
     | 
    
         
             
                            end
         
     | 
| 
         @@ -451,26 +451,26 @@ module Sequel 
     | 
|
| 
       451 
451 
     | 
    
         
             
                      end
         
     | 
| 
       452 
452 
     | 
    
         | 
| 
       453 
453 
     | 
    
         
             
                      opts[:adder] ||= proc do |o|
         
     | 
| 
       454 
     | 
    
         
            -
                        opk = o. 
     | 
| 
       455 
     | 
    
         
            -
                        if array =  
     | 
| 
      
 454 
     | 
    
         
            +
                        opk = o.get_column_value(opts.primary_key) 
         
     | 
| 
      
 455 
     | 
    
         
            +
                        if array = get_column_value(key)
         
     | 
| 
       456 
456 
     | 
    
         
             
                          modified!(key)
         
     | 
| 
       457 
457 
     | 
    
         
             
                          array << opk
         
     | 
| 
       458 
458 
     | 
    
         
             
                        else
         
     | 
| 
       459 
     | 
    
         
            -
                           
     | 
| 
      
 459 
     | 
    
         
            +
                          set_column_value("#{key}=", Sequel.pg_array([opk], opts.array_type))
         
     | 
| 
       460 
460 
     | 
    
         
             
                        end
         
     | 
| 
       461 
461 
     | 
    
         
             
                        save_after_modify.call(self) if save_after_modify
         
     | 
| 
       462 
462 
     | 
    
         
             
                      end
         
     | 
| 
       463 
463 
     | 
    
         | 
| 
       464 
464 
     | 
    
         
             
                      opts[:remover] ||= proc do |o|
         
     | 
| 
       465 
     | 
    
         
            -
                        if (array =  
     | 
| 
      
 465 
     | 
    
         
            +
                        if (array = get_column_value(key)) && !array.empty?
         
     | 
| 
       466 
466 
     | 
    
         
             
                          modified!(key)
         
     | 
| 
       467 
     | 
    
         
            -
                          array.delete(o. 
     | 
| 
      
 467 
     | 
    
         
            +
                          array.delete(o.get_column_value(opts.primary_key))
         
     | 
| 
       468 
468 
     | 
    
         
             
                          save_after_modify.call(self) if save_after_modify
         
     | 
| 
       469 
469 
     | 
    
         
             
                        end
         
     | 
| 
       470 
470 
     | 
    
         
             
                      end
         
     | 
| 
       471 
471 
     | 
    
         | 
| 
       472 
472 
     | 
    
         
             
                      opts[:clearer] ||= proc do
         
     | 
| 
       473 
     | 
    
         
            -
                        if (array =  
     | 
| 
      
 473 
     | 
    
         
            +
                        if (array = get_column_value(key)) && !array.empty?
         
     | 
| 
       474 
474 
     | 
    
         
             
                          modified!(key)
         
     | 
| 
       475 
475 
     | 
    
         
             
                          array.clear
         
     | 
| 
       476 
476 
     | 
    
         
             
                          save_after_modify.call(self) if save_after_modify
         
     | 
| 
         @@ -488,11 +488,11 @@ module Sequel 
     | 
|
| 
       488 
488 
     | 
    
         
             
                      key = ref[:key]
         
     | 
| 
       489 
489 
     | 
    
         
             
                      expr = case obj
         
     | 
| 
       490 
490 
     | 
    
         
             
                      when Sequel::Model
         
     | 
| 
       491 
     | 
    
         
            -
                        if (assoc_pks = obj. 
     | 
| 
      
 491 
     | 
    
         
            +
                        if (assoc_pks = obj.get_column_value(key)) && !assoc_pks.empty?
         
     | 
| 
       492 
492 
     | 
    
         
             
                          Sequel.expr(pk=>assoc_pks.to_a)
         
     | 
| 
       493 
493 
     | 
    
         
             
                        end
         
     | 
| 
       494 
494 
     | 
    
         
             
                      when Array
         
     | 
| 
       495 
     | 
    
         
            -
                        if (assoc_pks = obj.map{|o| o. 
     | 
| 
      
 495 
     | 
    
         
            +
                        if (assoc_pks = obj.map{|o| o.get_column_value(key)}.flatten.compact.uniq) && !assoc_pks.empty?
         
     | 
| 
       496 
496 
     | 
    
         
             
                          Sequel.expr(pk=>assoc_pks)
         
     | 
| 
       497 
497 
     | 
    
         
             
                        end
         
     | 
| 
       498 
498 
     | 
    
         
             
                      when Sequel::Dataset
         
     | 
| 
         @@ -508,11 +508,11 @@ module Sequel 
     | 
|
| 
       508 
508 
     | 
    
         
             
                      key = ref.qualify(model.table_name, ref[:key_column])
         
     | 
| 
       509 
509 
     | 
    
         
             
                      expr = case obj
         
     | 
| 
       510 
510 
     | 
    
         
             
                      when Sequel::Model
         
     | 
| 
       511 
     | 
    
         
            -
                        if pkv = obj. 
     | 
| 
      
 511 
     | 
    
         
            +
                        if pkv = obj.get_column_value(ref.primary_key_method)
         
     | 
| 
       512 
512 
     | 
    
         
             
                          Sequel.pg_array_op(key).contains(Sequel.pg_array([pkv], ref.array_type))
         
     | 
| 
       513 
513 
     | 
    
         
             
                        end
         
     | 
| 
       514 
514 
     | 
    
         
             
                      when Array
         
     | 
| 
       515 
     | 
    
         
            -
                        if (pkvs = obj.map{|o| o. 
     | 
| 
      
 515 
     | 
    
         
            +
                        if (pkvs = obj.map{|o| o.get_column_value(ref.primary_key_method)}.compact) && !pkvs.empty?
         
     | 
| 
       516 
516 
     | 
    
         
             
                          Sequel.pg_array(key).overlaps(Sequel.pg_array(pkvs, ref.array_type))
         
     | 
| 
       517 
517 
     | 
    
         
             
                        end
         
     | 
| 
       518 
518 
     | 
    
         
             
                      when Sequel::Dataset
         
     | 
| 
         @@ -28,7 +28,7 @@ module Sequel 
     | 
|
| 
       28 
28 
     | 
    
         
             
                    # Return a bound variable hash that maps the keys in +ks+ (qualified by the +table+)
         
     | 
| 
       29 
29 
     | 
    
         
             
                    # to the values of the results of sending the methods in +vs+.
         
     | 
| 
       30 
30 
     | 
    
         
             
                    def association_bound_variable_hash(table, ks, vs)
         
     | 
| 
       31 
     | 
    
         
            -
                      Hash[*ks.zip(vs).map{|k, v| [:"#{table}.#{k}",  
     | 
| 
      
 31 
     | 
    
         
            +
                      Hash[*ks.zip(vs).map{|k, v| [:"#{table}.#{k}", get_column_value(v)]}.flatten]
         
     | 
| 
       32 
32 
     | 
    
         
             
                    end
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
34 
     | 
    
         
             
                    # Given an association reflection, return a bound variable hash for the given
         
     | 
| 
         @@ -148,7 +148,7 @@ module Sequel 
     | 
|
| 
       148 
148 
     | 
    
         
             
                    a[:read_only] = true unless a.has_key?(:read_only)
         
     | 
| 
       149 
149 
     | 
    
         
             
                    a[:eager_loader_key] = key
         
     | 
| 
       150 
150 
     | 
    
         
             
                    a[:dataset] ||= proc do
         
     | 
| 
       151 
     | 
    
         
            -
                      base_ds = model.filter(prkey_array.zip(key_array.map{|k|  
     | 
| 
      
 151 
     | 
    
         
            +
                      base_ds = model.filter(prkey_array.zip(key_array.map{|k| get_column_value(k)}))
         
     | 
| 
       152 
152 
     | 
    
         
             
                      recursive_ds = model.join(t, key_array.zip(prkey_array))
         
     | 
| 
       153 
153 
     | 
    
         
             
                      if c = a[:conditions]
         
     | 
| 
       154 
154 
     | 
    
         
             
                        (base_ds, recursive_ds) = [base_ds, recursive_ds].collect do |ds|
         
     | 
| 
         @@ -243,7 +243,7 @@ module Sequel 
     | 
|
| 
       243 
243 
     | 
    
         
             
                    d[:read_only] = true unless d.has_key?(:read_only)
         
     | 
| 
       244 
244 
     | 
    
         
             
                    la = d[:level_alias] ||= :x_level_x
         
     | 
| 
       245 
245 
     | 
    
         
             
                    d[:dataset] ||= proc do
         
     | 
| 
       246 
     | 
    
         
            -
                      base_ds = model.filter(key_array.zip(prkey_array.map{|k|  
     | 
| 
      
 246 
     | 
    
         
            +
                      base_ds = model.filter(key_array.zip(prkey_array.map{|k| get_column_value(k)}))
         
     | 
| 
       247 
247 
     | 
    
         
             
                      recursive_ds = model.join(t, prkey_array.zip(key_array))
         
     | 
| 
       248 
248 
     | 
    
         
             
                      if c = d[:conditions]
         
     | 
| 
       249 
249 
     | 
    
         
             
                        (base_ds, recursive_ds) = [base_ds, recursive_ds].collect do |ds|
         
     | 
| 
         @@ -163,7 +163,7 @@ module Sequel 
     | 
|
| 
       163 
163 
     | 
    
         
             
                            end
         
     | 
| 
       164 
164 
     | 
    
         
             
                          end
         
     | 
| 
       165 
165 
     | 
    
         
             
                          define_method("#{column}=") do |v| 
         
     | 
| 
       166 
     | 
    
         
            -
                            if !changed_columns.include?(column) && (new? ||  
     | 
| 
      
 166 
     | 
    
         
            +
                            if !changed_columns.include?(column) && (new? || get_column_value(column) != v)
         
     | 
| 
       167 
167 
     | 
    
         
             
                              changed_columns << column
         
     | 
| 
       168 
168 
     | 
    
         
             
                            end
         
     | 
| 
       169 
169 
     | 
    
         | 
| 
         @@ -220,7 +220,7 @@ module Sequel 
     | 
|
| 
       220 
220 
     | 
    
         
             
                    # Set the sti_key column based on the sti_key_map.
         
     | 
| 
       221 
221 
     | 
    
         
             
                    def _before_validation
         
     | 
| 
       222 
222 
     | 
    
         
             
                      if new? && !self[model.sti_key]
         
     | 
| 
       223 
     | 
    
         
            -
                         
     | 
| 
      
 223 
     | 
    
         
            +
                        set_column_value("#{model.sti_key}=", model.sti_key_chooser.call(self))
         
     | 
| 
       224 
224 
     | 
    
         
             
                      end
         
     | 
| 
       225 
225 
     | 
    
         
             
                      super
         
     | 
| 
       226 
226 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -79,7 +79,7 @@ module Sequel 
     | 
|
| 
       79 
79 
     | 
    
         
             
                    def set_create_timestamp(time=nil)
         
     | 
| 
       80 
80 
     | 
    
         
             
                      field = model.create_timestamp_field
         
     | 
| 
       81 
81 
     | 
    
         
             
                      meth = :"#{field}="
         
     | 
| 
       82 
     | 
    
         
            -
                       
     | 
| 
      
 82 
     | 
    
         
            +
                      set_column_value(meth, time||=model.dataset.current_datetime) if respond_to?(field) && respond_to?(meth) && (model.create_timestamp_overwrite? || get_column_value(field).nil?)
         
     | 
| 
       83 
83 
     | 
    
         
             
                      set_update_timestamp(time) if model.set_update_timestamp_on_create?
         
     | 
| 
       84 
84 
     | 
    
         
             
                    end
         
     | 
| 
       85 
85 
     | 
    
         | 
| 
         @@ -87,7 +87,7 @@ module Sequel 
     | 
|
| 
       87 
87 
     | 
    
         
             
                    # object has a setter method for the update timestamp field.
         
     | 
| 
       88 
88 
     | 
    
         
             
                    def set_update_timestamp(time=nil)
         
     | 
| 
       89 
89 
     | 
    
         
             
                      meth = :"#{model.update_timestamp_field}="
         
     | 
| 
       90 
     | 
    
         
            -
                       
     | 
| 
      
 90 
     | 
    
         
            +
                      set_column_value(meth, time||model.dataset.current_datetime) if respond_to?(meth)
         
     | 
| 
       91 
91 
     | 
    
         
             
                    end
         
     | 
| 
       92 
92 
     | 
    
         
             
                  end
         
     | 
| 
       93 
93 
     | 
    
         
             
                end
         
     | 
| 
         @@ -103,9 +103,9 @@ module Sequel 
     | 
|
| 
       103 
103 
     | 
    
         
             
                      validations.each do |att, procs|
         
     | 
| 
       104 
104 
     | 
    
         
             
                        v = case att
         
     | 
| 
       105 
105 
     | 
    
         
             
                        when Array
         
     | 
| 
       106 
     | 
    
         
            -
                          att.collect{|a| o. 
     | 
| 
      
 106 
     | 
    
         
            +
                          att.collect{|a| o.get_column_value(a)}
         
     | 
| 
       107 
107 
     | 
    
         
             
                        else
         
     | 
| 
       108 
     | 
    
         
            -
                          o. 
     | 
| 
      
 108 
     | 
    
         
            +
                          o.get_column_value(att)
         
     | 
| 
       109 
109 
     | 
    
         
             
                        end
         
     | 
| 
       110 
110 
     | 
    
         
             
                        procs.each {|tag, p| p.call(o, att, v)}
         
     | 
| 
       111 
111 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -150,7 +150,7 @@ module Sequel 
     | 
|
| 
       150 
150 
     | 
    
         
             
                      reflect_validation(:confirmation, opts, atts)
         
     | 
| 
       151 
151 
     | 
    
         
             
                      atts << opts
         
     | 
| 
       152 
152 
     | 
    
         
             
                      validates_each(*atts) do |o, a, v|
         
     | 
| 
       153 
     | 
    
         
            -
                        o.errors.add(a, opts[:message]) unless v == o. 
     | 
| 
      
 153 
     | 
    
         
            +
                        o.errors.add(a, opts[:message]) unless v == o.get_column_value(:"#{a}_confirmation")
         
     | 
| 
       154 
154 
     | 
    
         
             
                      end
         
     | 
| 
       155 
155 
     | 
    
         
             
                    end
         
     | 
| 
       156 
156 
     | 
    
         | 
| 
         @@ -418,7 +418,7 @@ module Sequel 
     | 
|
| 
       418 
418 
     | 
    
         
             
                    def validation_if_proc(o, i)
         
     | 
| 
       419 
419 
     | 
    
         
             
                      case i
         
     | 
| 
       420 
420 
     | 
    
         
             
                      when Symbol
         
     | 
| 
       421 
     | 
    
         
            -
                        o. 
     | 
| 
      
 421 
     | 
    
         
            +
                        o.get_column_value(i)
         
     | 
| 
       422 
422 
     | 
    
         
             
                      when Proc
         
     | 
| 
       423 
423 
     | 
    
         
             
                        o.instance_eval(&i)
         
     | 
| 
       424 
424 
     | 
    
         
             
                      else
         
     | 
| 
         @@ -236,7 +236,7 @@ module Sequel 
     | 
|
| 
       236 
236 
     | 
    
         
             
                        ds = if where
         
     | 
| 
       237 
237 
     | 
    
         
             
                          where.call(ds, self, arr)
         
     | 
| 
       238 
238 
     | 
    
         
             
                        else
         
     | 
| 
       239 
     | 
    
         
            -
                          vals = arr.map{|x|  
     | 
| 
      
 239 
     | 
    
         
            +
                          vals = arr.map{|x| get_column_value(x)}
         
     | 
| 
       240 
240 
     | 
    
         
             
                          next if vals.any?{|v| v.nil?}
         
     | 
| 
       241 
241 
     | 
    
         
             
                          ds.where(arr.zip(vals))
         
     | 
| 
       242 
242 
     | 
    
         
             
                        end
         
     | 
| 
         @@ -267,7 +267,7 @@ module Sequel 
     | 
|
| 
       267 
267 
     | 
    
         
             
                      am, an, ab, m = opts.values_at(:allow_missing, :allow_nil, :allow_blank, :message)
         
     | 
| 
       268 
268 
     | 
    
         
             
                      Array(atts).each do |a|
         
     | 
| 
       269 
269 
     | 
    
         
             
                        next if am && !values.has_key?(a)
         
     | 
| 
       270 
     | 
    
         
            -
                        v =  
     | 
| 
      
 270 
     | 
    
         
            +
                        v = get_column_value(a)
         
     | 
| 
       271 
271 
     | 
    
         
             
                        next if an && v.nil?
         
     | 
| 
       272 
272 
     | 
    
         
             
                        next if ab && v.respond_to?(:blank?) && v.blank?
         
     | 
| 
       273 
273 
     | 
    
         
             
                        if message = yield(a, v, m)
         
     | 
    
        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 = 19
         
     | 
| 
       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/core/dataset_spec.rb
    CHANGED
    
    | 
         @@ -2619,6 +2619,13 @@ describe "Dataset compound operations" do 
     | 
|
| 
       2619 
2619 
     | 
    
         
             
                  "SELECT * FROM (SELECT * FROM (SELECT * FROM test ORDER BY a LIMIT 2) AS t1 UNION SELECT * FROM (SELECT * FROM test ORDER BY b LIMIT 3) AS t1) AS t1 ORDER BY c LIMIT 4"
         
     | 
| 
       2620 
2620 
     | 
    
         
             
              end
         
     | 
| 
       2621 
2621 
     | 
    
         | 
| 
      
 2622 
     | 
    
         
            +
              specify "should handle raw SQL datasets properly when using UNION, INTERSECT, or EXCEPT" do
         
     | 
| 
      
 2623 
     | 
    
         
            +
                @dataset = Sequel.mock['SELECT 1']
         
     | 
| 
      
 2624 
     | 
    
         
            +
                @dataset.union(@dataset).sql.should == "SELECT * FROM (SELECT * FROM (SELECT 1) AS t1 UNION SELECT * FROM (SELECT 1) AS t1) AS t1"
         
     | 
| 
      
 2625 
     | 
    
         
            +
                @dataset.intersect(@dataset).sql.should == "SELECT * FROM (SELECT * FROM (SELECT 1) AS t1 INTERSECT SELECT * FROM (SELECT 1) AS t1) AS t1"
         
     | 
| 
      
 2626 
     | 
    
         
            +
                @dataset.except(@dataset).sql.should == "SELECT * FROM (SELECT * FROM (SELECT 1) AS t1 EXCEPT SELECT * FROM (SELECT 1) AS t1) AS t1"
         
     | 
| 
      
 2627 
     | 
    
         
            +
              end
         
     | 
| 
      
 2628 
     | 
    
         
            +
             
     | 
| 
       2622 
2629 
     | 
    
         
             
              specify "should hoist WITH clauses in given dataset if dataset doesn't support WITH in subselect" do
         
     | 
| 
       2623 
2630 
     | 
    
         
             
                ds = Sequel.mock.dataset
         
     | 
| 
       2624 
2631 
     | 
    
         
             
                meta_def(ds, :supports_cte?){true}
         
     | 
| 
         @@ -0,0 +1,51 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe "accessed_columns plugin" do
         
     | 
| 
      
 4 
     | 
    
         
            +
              before do
         
     | 
| 
      
 5 
     | 
    
         
            +
                @db = Sequel.mock(:fetch=>{:name=>'a', :b=>'c'}, :numrows=>1)
         
     | 
| 
      
 6 
     | 
    
         
            +
                @c = Class.new(Sequel::Model(@db[:test]))
         
     | 
| 
      
 7 
     | 
    
         
            +
                @c.columns :name, :b
         
     | 
| 
      
 8 
     | 
    
         
            +
                @c.plugin :accessed_columns
         
     | 
| 
      
 9 
     | 
    
         
            +
                @o = @c.new
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              it "should record columns accessed" do
         
     | 
| 
      
 13 
     | 
    
         
            +
                @o.accessed_columns.should == []
         
     | 
| 
      
 14 
     | 
    
         
            +
                @o.name
         
     | 
| 
      
 15 
     | 
    
         
            +
                @o.accessed_columns.should == [:name]
         
     | 
| 
      
 16 
     | 
    
         
            +
                @o.name
         
     | 
| 
      
 17 
     | 
    
         
            +
                @o.accessed_columns.should == [:name]
         
     | 
| 
      
 18 
     | 
    
         
            +
                @o.b
         
     | 
| 
      
 19 
     | 
    
         
            +
                @o.accessed_columns.sort_by{|s| s.to_s}.should == [:b, :name]
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              it "should clear accessed columns when refreshing" do
         
     | 
| 
      
 23 
     | 
    
         
            +
                @o.name
         
     | 
| 
      
 24 
     | 
    
         
            +
                @o.refresh
         
     | 
| 
      
 25 
     | 
    
         
            +
                @o.accessed_columns.should == []
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              it "should clear accessed columns when saving" do
         
     | 
| 
      
 29 
     | 
    
         
            +
                @o.name
         
     | 
| 
      
 30 
     | 
    
         
            +
                @o.save
         
     | 
| 
      
 31 
     | 
    
         
            +
                @o.accessed_columns.should == []
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
              it "should work when duping and cloning instances" do
         
     | 
| 
      
 35 
     | 
    
         
            +
                @o.name
         
     | 
| 
      
 36 
     | 
    
         
            +
                o = @o.dup
         
     | 
| 
      
 37 
     | 
    
         
            +
                @o.accessed_columns.should == [:name]
         
     | 
| 
      
 38 
     | 
    
         
            +
                @o.b
         
     | 
| 
      
 39 
     | 
    
         
            +
                @o.accessed_columns.sort_by{|s| s.to_s}.should == [:b, :name]
         
     | 
| 
      
 40 
     | 
    
         
            +
                o.accessed_columns.should == [:name]
         
     | 
| 
      
 41 
     | 
    
         
            +
                o2 = o.clone
         
     | 
| 
      
 42 
     | 
    
         
            +
                o2.refresh
         
     | 
| 
      
 43 
     | 
    
         
            +
                o.accessed_columns.should == [:name]
         
     | 
| 
      
 44 
     | 
    
         
            +
                o2.accessed_columns.should == []
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              it "should not raise exceptions when object is frozen" do
         
     | 
| 
      
 48 
     | 
    
         
            +
                @o.freeze
         
     | 
| 
      
 49 
     | 
    
         
            +
                proc{@o.name}.should_not raise_error
         
     | 
| 
      
 50 
     | 
    
         
            +
              end
         
     | 
| 
      
 51 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,55 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe "column_conflicts plugin" do
         
     | 
| 
      
 4 
     | 
    
         
            +
              before do
         
     | 
| 
      
 5 
     | 
    
         
            +
                @db = Sequel.mock
         
     | 
| 
      
 6 
     | 
    
         
            +
                @c = Class.new(Sequel::Model(@db[:test]))
         
     | 
| 
      
 7 
     | 
    
         
            +
                @c.columns :model, :use_transactions, :foo
         
     | 
| 
      
 8 
     | 
    
         
            +
                @c.plugin :column_conflicts
         
     | 
| 
      
 9 
     | 
    
         
            +
                @o = @c.load(:model=>1, :use_transactions=>2, :foo=>4)
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              it "should have mass assignment work correctly" do
         
     | 
| 
      
 13 
     | 
    
         
            +
                @o.set_fields({:use_transactions=>3}, [:use_transactions])
         
     | 
| 
      
 14 
     | 
    
         
            +
                @o.get_column_value(:use_transactions).should == 3
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              it "should handle both symbols and strings" do
         
     | 
| 
      
 18 
     | 
    
         
            +
                @o.get_column_value(:model).should == 1
         
     | 
| 
      
 19 
     | 
    
         
            +
                @o.get_column_value("model").should == 1
         
     | 
| 
      
 20 
     | 
    
         
            +
                @o.set_column_value(:use_transactions=, 3)
         
     | 
| 
      
 21 
     | 
    
         
            +
                @o.get_column_value(:use_transactions).should == 3
         
     | 
| 
      
 22 
     | 
    
         
            +
                @o.set_column_value(:use_transactions=, 4)
         
     | 
| 
      
 23 
     | 
    
         
            +
                @o.get_column_value(:use_transactions).should == 4
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              it "should allow manual setting of conflicted columns" do
         
     | 
| 
      
 27 
     | 
    
         
            +
                @c.send(:define_method, :foo){raise}
         
     | 
| 
      
 28 
     | 
    
         
            +
                @c.get_column_conflict!(:foo)
         
     | 
| 
      
 29 
     | 
    
         
            +
                @o.get_column_value(:foo).should == 4
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                @c.send(:define_method, :model=){raise}
         
     | 
| 
      
 32 
     | 
    
         
            +
                @c.set_column_conflict!(:model)
         
     | 
| 
      
 33 
     | 
    
         
            +
                @o.set_column_value(:model=, 2).should == 2
         
     | 
| 
      
 34 
     | 
    
         
            +
                @o.get_column_value(:model).should == 2
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
              it "should work correctly in subclasses" do
         
     | 
| 
      
 38 
     | 
    
         
            +
                @o = Class.new(@c).load(:model=>1, :use_transactions=>2)
         
     | 
| 
      
 39 
     | 
    
         
            +
                @o.get_column_value(:model).should == 1
         
     | 
| 
      
 40 
     | 
    
         
            +
                @o.get_column_value("model").should == 1
         
     | 
| 
      
 41 
     | 
    
         
            +
                @o.set_column_value(:use_transactions=, 3)
         
     | 
| 
      
 42 
     | 
    
         
            +
                @o.get_column_value(:use_transactions).should == 3
         
     | 
| 
      
 43 
     | 
    
         
            +
                @o.set_column_value(:use_transactions=, 4)
         
     | 
| 
      
 44 
     | 
    
         
            +
                @o.get_column_value(:use_transactions).should == 4
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              it "should work correctly for dataset changes" do
         
     | 
| 
      
 48 
     | 
    
         
            +
                ds = @db[:test]
         
     | 
| 
      
 49 
     | 
    
         
            +
                def ds.columns; [:object_id] end
         
     | 
| 
      
 50 
     | 
    
         
            +
                @c.dataset = ds
         
     | 
| 
      
 51 
     | 
    
         
            +
                o = @c.load(:object_id=>3)
         
     | 
| 
      
 52 
     | 
    
         
            +
                o.get_column_value(:object_id).should == 3
         
     | 
| 
      
 53 
     | 
    
         
            +
                o.object_id.should_not == 3
         
     | 
| 
      
 54 
     | 
    
         
            +
              end
         
     | 
| 
      
 55 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -184,7 +184,13 @@ describe "Model#before_create && Model#after_create" do 
     | 
|
| 
       184 
184 
     | 
    
         | 
| 
       185 
185 
     | 
    
         
             
              specify ".create should cancel the save and raise an error if before_create returns false and raise_on_save_failure is true" do
         
     | 
| 
       186 
186 
     | 
    
         
             
                @c.before_create{false}
         
     | 
| 
       187 
     | 
    
         
            -
                proc{@c.create(:x => 2)}.should raise_error(Sequel:: 
     | 
| 
      
 187 
     | 
    
         
            +
                proc{@c.create(:x => 2)}.should raise_error(Sequel::HookFailed)
         
     | 
| 
      
 188 
     | 
    
         
            +
                DB.sqls.should == []
         
     | 
| 
      
 189 
     | 
    
         
            +
              end
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
              specify ".create should cancel the save and raise an error if before_create calls cancel_action and raise_on_save_failure is true" do
         
     | 
| 
      
 192 
     | 
    
         
            +
                @c.before_create{cancel_action}
         
     | 
| 
      
 193 
     | 
    
         
            +
                proc{@c.create(:x => 2)}.should raise_error(Sequel::HookFailed)
         
     | 
| 
       188 
194 
     | 
    
         
             
                DB.sqls.should == []
         
     | 
| 
       189 
195 
     | 
    
         
             
              end
         
     | 
| 
       190 
196 
     | 
    
         | 
| 
         @@ -194,6 +200,13 @@ describe "Model#before_create && Model#after_create" do 
     | 
|
| 
       194 
200 
     | 
    
         
             
                @c.create(:x => 2).should == nil
         
     | 
| 
       195 
201 
     | 
    
         
             
                DB.sqls.should == []
         
     | 
| 
       196 
202 
     | 
    
         
             
              end
         
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
              specify ".create should cancel the save and return nil if before_create calls cancel_action and raise_on_save_failure is false" do
         
     | 
| 
      
 205 
     | 
    
         
            +
                @c.before_create{cancel_action}
         
     | 
| 
      
 206 
     | 
    
         
            +
                @c.raise_on_save_failure = false
         
     | 
| 
      
 207 
     | 
    
         
            +
                @c.create(:x => 2).should == nil
         
     | 
| 
      
 208 
     | 
    
         
            +
                DB.sqls.should == []
         
     | 
| 
      
 209 
     | 
    
         
            +
              end
         
     | 
| 
       197 
210 
     | 
    
         
             
            end
         
     | 
| 
       198 
211 
     | 
    
         | 
| 
       199 
212 
     | 
    
         
             
            describe "Model#before_update && Model#after_update" do
         
     | 
| 
         @@ -214,7 +227,7 @@ describe "Model#before_update && Model#after_update" do 
     | 
|
| 
       214 
227 
     | 
    
         | 
| 
       215 
228 
     | 
    
         
             
              specify "#save should cancel the save and raise an error if before_update returns false and raise_on_save_failure is true" do
         
     | 
| 
       216 
229 
     | 
    
         
             
                @c.before_update{false}
         
     | 
| 
       217 
     | 
    
         
            -
                proc{@c.load(:id => 2233).save}.should raise_error(Sequel:: 
     | 
| 
      
 230 
     | 
    
         
            +
                proc{@c.load(:id => 2233).save}.should raise_error(Sequel::HookFailed)
         
     | 
| 
       218 
231 
     | 
    
         
             
                DB.sqls.should == []
         
     | 
| 
       219 
232 
     | 
    
         
             
              end
         
     | 
| 
       220 
233 
     | 
    
         | 
| 
         @@ -252,7 +265,7 @@ describe "Model#before_save && Model#after_save" do 
     | 
|
| 
       252 
265 
     | 
    
         | 
| 
       253 
266 
     | 
    
         
             
              specify "#save should cancel the save and raise an error if before_save returns false and raise_on_save_failure is true" do
         
     | 
| 
       254 
267 
     | 
    
         
             
                @c.before_save{false}
         
     | 
| 
       255 
     | 
    
         
            -
                proc{@c.load(:id => 2233).save}.should raise_error(Sequel:: 
     | 
| 
      
 268 
     | 
    
         
            +
                proc{@c.load(:id => 2233).save}.should raise_error(Sequel::HookFailed)
         
     | 
| 
       256 
269 
     | 
    
         
             
                DB.sqls.should == []
         
     | 
| 
       257 
270 
     | 
    
         
             
              end
         
     | 
| 
       258 
271 
     | 
    
         | 
| 
         @@ -282,7 +295,7 @@ describe "Model#before_destroy && Model#after_destroy" do 
     | 
|
| 
       282 
295 
     | 
    
         | 
| 
       283 
296 
     | 
    
         
             
              specify "#destroy should cancel the destroy and raise an error if before_destroy returns false and raise_on_save_failure is true" do
         
     | 
| 
       284 
297 
     | 
    
         
             
                @c.before_destroy{false}
         
     | 
| 
       285 
     | 
    
         
            -
                proc{@c.load(:id => 2233).destroy}.should raise_error(Sequel:: 
     | 
| 
      
 298 
     | 
    
         
            +
                proc{@c.load(:id => 2233).destroy}.should raise_error(Sequel::HookFailed)
         
     | 
| 
       286 
299 
     | 
    
         
             
                DB.sqls.should == []
         
     | 
| 
       287 
300 
     | 
    
         
             
              end
         
     | 
| 
       288 
301 
     | 
    
         | 
| 
         @@ -336,7 +349,7 @@ describe "Model#before_validation && Model#after_validation" do 
     | 
|
| 
       336 
349 
     | 
    
         | 
| 
       337 
350 
     | 
    
         
             
              specify "#save should cancel the save and raise an error if before_validation returns false and raise_on_save_failure is true" do
         
     | 
| 
       338 
351 
     | 
    
         
             
                @c.before_validation{false}
         
     | 
| 
       339 
     | 
    
         
            -
                proc{@c.load(:id => 2233).save}.should raise_error(Sequel:: 
     | 
| 
      
 352 
     | 
    
         
            +
                proc{@c.load(:id => 2233).save}.should raise_error(Sequel::HookFailed)
         
     | 
| 
       340 
353 
     | 
    
         
             
                DB.sqls.should == []
         
     | 
| 
       341 
354 
     | 
    
         
             
              end
         
     | 
| 
       342 
355 
     | 
    
         |