composite_primary_keys 8.1.1 → 8.1.2
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/History.rdoc +4 -1
- data/lib/composite_primary_keys.rb +5 -1
- data/lib/composite_primary_keys/arel/visitors/to_sql.rb +24 -0
- data/lib/composite_primary_keys/associations/association_scope.rb +32 -58
- data/lib/composite_primary_keys/associations/join_dependency/join_association.rb +22 -22
- data/lib/composite_primary_keys/associations/preloader/association.rb +12 -6
- data/lib/composite_primary_keys/associations/preloader/belongs_to.rb +19 -19
- data/lib/composite_primary_keys/attribute_methods/primary_key.rb +1 -2
- data/lib/composite_primary_keys/attribute_methods/read.rb +2 -2
- data/lib/composite_primary_keys/attribute_methods/write.rb +1 -1
- data/lib/composite_primary_keys/composite_predicates.rb +55 -50
- data/lib/composite_primary_keys/composite_relation.rb +48 -48
- data/lib/composite_primary_keys/connection_adapters/abstract/connection_specification_changes.rb +2 -2
- data/lib/composite_primary_keys/connection_adapters/postgresql_adapter.rb +19 -46
- data/lib/composite_primary_keys/connection_adapters/sqlserver_adapter.rb +8 -4
- data/lib/composite_primary_keys/fixtures.rb +26 -22
- data/lib/composite_primary_keys/locking/optimistic.rb +54 -55
- data/lib/composite_primary_keys/relation.rb +15 -8
- data/lib/composite_primary_keys/relation/batches.rb +23 -19
- data/lib/composite_primary_keys/relation/calculations.rb +4 -2
- data/lib/composite_primary_keys/relation/finder_methods.rb +33 -27
- data/lib/composite_primary_keys/relation/predicate_builder.rb +18 -3
- data/lib/composite_primary_keys/relation/query_methods.rb +41 -41
- data/lib/composite_primary_keys/sanitization.rb +7 -5
- data/lib/composite_primary_keys/validations/uniqueness.rb +20 -16
- data/lib/composite_primary_keys/version.rb +1 -1
- data/tasks/databases/oracle.rake +27 -25
- data/tasks/databases/oracle_enhanced.rake +27 -0
- data/test/connections/databases.ci.yml +15 -15
- data/test/connections/native_oracle/connection.rb +11 -11
- data/test/connections/native_oracle_enhanced/connection.rb +16 -16
- data/test/fixtures/comment.rb +7 -7
- data/test/fixtures/db_definitions/db2-create-tables.sql +126 -126
- data/test/fixtures/db_definitions/db2-drop-tables.sql +18 -18
- data/test/fixtures/db_definitions/oracle.drop.sql +48 -45
- data/test/fixtures/db_definitions/oracle.sql +236 -223
- data/test/fixtures/dorm.rb +2 -2
- data/test/fixtures/membership.rb +6 -6
- data/test/fixtures/membership_statuses.yml +16 -16
- data/test/fixtures/memberships.yml +10 -10
- data/test/fixtures/product_tariffs.yml +14 -14
- data/test/fixtures/reference_code.rb +7 -7
- data/test/fixtures/restaurants_suburb.rb +2 -2
- data/test/fixtures/suburb.rb +5 -5
- data/test/fixtures/topic.rb +5 -5
- data/test/fixtures/topic_source.rb +6 -6
- data/test/fixtures/topic_sources.yml +3 -3
- data/test/fixtures/topics.yml +8 -8
- data/test/fixtures/users.yml +10 -10
- data/test/test_attribute_methods.rb +63 -63
- data/test/test_calculations.rb +42 -37
- data/test/test_callbacks.rb +99 -99
- data/test/test_delete.rb +28 -21
- data/test/test_delete_all.rb +5 -4
- data/test/test_dumpable.rb +15 -15
- data/test/test_nested_attributes.rb +124 -124
- data/test/test_optimistic.rb +18 -18
- data/test/test_polymorphic.rb +1 -1
- data/test/test_predicates.rb +40 -40
- data/test/test_santiago.rb +23 -23
- data/test/test_suite.rb +34 -34
- data/test/test_touch.rb +23 -23
- data/test/test_update.rb +71 -71
- metadata +9 -8
- data/lib/composite_primary_keys/model_schema.rb +0 -15
| @@ -1,48 +1,48 @@ | |
| 1 | 
            -
            module CompositePrimaryKeys
         | 
| 2 | 
            -
              module CompositeRelation
         | 
| 3 | 
            -
                include CompositePrimaryKeys::ActiveRecord::Batches
         | 
| 4 | 
            -
                include CompositePrimaryKeys::ActiveRecord::Calculations
         | 
| 5 | 
            -
                include CompositePrimaryKeys::ActiveRecord::FinderMethods
         | 
| 6 | 
            -
                include CompositePrimaryKeys::ActiveRecord::QueryMethods
         | 
| 7 | 
            -
             | 
| 8 | 
            -
                def delete(id_or_array)
         | 
| 9 | 
            -
                  # CPK
         | 
| 10 | 
            -
                  if self.composite?
         | 
| 11 | 
            -
                    id_or_array = if id_or_array.is_a?(CompositePrimaryKeys::CompositeKeys)
         | 
| 12 | 
            -
                                    [id_or_array]
         | 
| 13 | 
            -
                                  else
         | 
| 14 | 
            -
                                    Array(id_or_array)
         | 
| 15 | 
            -
                                  end
         | 
| 16 | 
            -
             | 
| 17 | 
            -
                    id_or_array.each do |id|
         | 
| 18 | 
            -
                      # Is the passed in id actually a record?
         | 
| 19 | 
            -
                      id = id.kind_of?(::ActiveRecord::Base) ? id.id : id
         | 
| 20 | 
            -
                      where(cpk_id_predicate(table, self.primary_key, id)).delete_all
         | 
| 21 | 
            -
                    end
         | 
| 22 | 
            -
                  else
         | 
| 23 | 
            -
                    where(primary_key => id_or_array).delete_all
         | 
| 24 | 
            -
                  end
         | 
| 25 | 
            -
                end
         | 
| 26 | 
            -
             | 
| 27 | 
            -
                def destroy(id_or_array)
         | 
| 28 | 
            -
                  # Without CPK:
         | 
| 29 | 
            -
                  #if id.is_a?(Array)
         | 
| 30 | 
            -
                  #  id.map { |one_id| destroy(one_id) }
         | 
| 31 | 
            -
                  #else
         | 
| 32 | 
            -
                  #  find(id).destroy
         | 
| 33 | 
            -
                  #end
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                  id_or_array = if id_or_array.kind_of?(CompositePrimaryKeys::CompositeKeys)
         | 
| 36 | 
            -
                    [id_or_array]
         | 
| 37 | 
            -
                  else
         | 
| 38 | 
            -
                    Array(id_or_array)
         | 
| 39 | 
            -
                  end
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                  id_or_array.each do |id|
         | 
| 42 | 
            -
                    where(cpk_id_predicate(table, self.primary_key, id)).each do |record|
         | 
| 43 | 
            -
                      record.destroy
         | 
| 44 | 
            -
                    end
         | 
| 45 | 
            -
                  end
         | 
| 46 | 
            -
                end
         | 
| 47 | 
            -
              end
         | 
| 48 | 
            -
            end
         | 
| 1 | 
            +
            module CompositePrimaryKeys
         | 
| 2 | 
            +
              module CompositeRelation
         | 
| 3 | 
            +
                include CompositePrimaryKeys::ActiveRecord::Batches
         | 
| 4 | 
            +
                include CompositePrimaryKeys::ActiveRecord::Calculations
         | 
| 5 | 
            +
                include CompositePrimaryKeys::ActiveRecord::FinderMethods
         | 
| 6 | 
            +
                include CompositePrimaryKeys::ActiveRecord::QueryMethods
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                def delete(id_or_array)
         | 
| 9 | 
            +
                  # CPK
         | 
| 10 | 
            +
                  if self.composite?
         | 
| 11 | 
            +
                    id_or_array = if id_or_array.is_a?(CompositePrimaryKeys::CompositeKeys)
         | 
| 12 | 
            +
                                    [id_or_array]
         | 
| 13 | 
            +
                                  else
         | 
| 14 | 
            +
                                    Array(id_or_array)
         | 
| 15 | 
            +
                                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                    id_or_array.each do |id|
         | 
| 18 | 
            +
                      # Is the passed in id actually a record?
         | 
| 19 | 
            +
                      id = id.kind_of?(::ActiveRecord::Base) ? id.id : id
         | 
| 20 | 
            +
                      where(cpk_id_predicate(table, self.primary_key, id)).delete_all
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
                  else
         | 
| 23 | 
            +
                    where(primary_key => id_or_array).delete_all
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def destroy(id_or_array)
         | 
| 28 | 
            +
                  # Without CPK:
         | 
| 29 | 
            +
                  #if id.is_a?(Array)
         | 
| 30 | 
            +
                  #  id.map { |one_id| destroy(one_id) }
         | 
| 31 | 
            +
                  #else
         | 
| 32 | 
            +
                  #  find(id).destroy
         | 
| 33 | 
            +
                  #end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  id_or_array = if id_or_array.kind_of?(CompositePrimaryKeys::CompositeKeys)
         | 
| 36 | 
            +
                    [id_or_array]
         | 
| 37 | 
            +
                  else
         | 
| 38 | 
            +
                    Array(id_or_array)
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  id_or_array.each do |id|
         | 
| 42 | 
            +
                    where(cpk_id_predicate(table, self.primary_key, id)).each do |record|
         | 
| 43 | 
            +
                      record.destroy
         | 
| 44 | 
            +
                    end
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
              end
         | 
| 48 | 
            +
            end
         | 
    
        data/lib/composite_primary_keys/connection_adapters/abstract/connection_specification_changes.rb
    CHANGED
    
    | @@ -1,10 +1,10 @@ | |
| 1 1 | 
             
            module ActiveRecord
         | 
| 2 2 | 
             
              class Base
         | 
| 3 3 | 
             
                def self.load_cpk_adapter(adapter)
         | 
| 4 | 
            -
                  if  | 
| 4 | 
            +
                  if adapter.to_s =~ /postgresql/ || adapter.to_s =~ /postgis/
         | 
| 5 5 | 
             
                    require "composite_primary_keys/connection_adapters/postgresql_adapter.rb"
         | 
| 6 6 | 
             
                  end
         | 
| 7 | 
            -
                  if  | 
| 7 | 
            +
                  if adapter.to_s =~ /sqlserver/
         | 
| 8 8 | 
             
                    require "composite_primary_keys/connection_adapters/sqlserver_adapter.rb"
         | 
| 9 9 | 
             
                  end
         | 
| 10 10 | 
             
                end
         | 
| @@ -1,46 +1,19 @@ | |
| 1 | 
            -
            module ActiveRecord
         | 
| 2 | 
            -
              module ConnectionAdapters
         | 
| 3 | 
            -
                 | 
| 4 | 
            -
                   | 
| 5 | 
            -
                     | 
| 6 | 
            -
                      #  | 
| 7 | 
            -
                       | 
| 8 | 
            -
                       | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
                       | 
| 13 | 
            -
             | 
| 14 | 
            -
                       | 
| 15 | 
            -
                     | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
                  def sql_for_insert(sql, pk, id_value, sequence_name, binds)
         | 
| 22 | 
            -
                    unless pk
         | 
| 23 | 
            -
                      # Extract the table from the insert sql. Yuck.
         | 
| 24 | 
            -
                      table_ref = extract_table_ref_from_insert_sql(sql)
         | 
| 25 | 
            -
                      pk = primary_key(table_ref) if table_ref
         | 
| 26 | 
            -
                    end
         | 
| 27 | 
            -
             | 
| 28 | 
            -
                    # CPK
         | 
| 29 | 
            -
                    # sql = "#{sql} RETURNING #{quote_column_name(pk)}" if pk
         | 
| 30 | 
            -
                    sql = "#{sql} RETURNING #{quote_column_names(pk)}" if pk
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                    [sql, binds]
         | 
| 33 | 
            -
                  end
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                  # Returns a single value if query returns a single element
         | 
| 36 | 
            -
                  # otherwise returns an array coresponding to the composite keys
         | 
| 37 | 
            -
                  #
         | 
| 38 | 
            -
                  def last_inserted_id(result)
         | 
| 39 | 
            -
                    row = result && result.rows.first
         | 
| 40 | 
            -
                    if Array === row
         | 
| 41 | 
            -
                      row.size == 1 ? row[0] : row
         | 
| 42 | 
            -
                    end
         | 
| 43 | 
            -
                  end
         | 
| 44 | 
            -
                end
         | 
| 45 | 
            -
              end
         | 
| 46 | 
            -
            end
         | 
| 1 | 
            +
            module ActiveRecord
         | 
| 2 | 
            +
              module ConnectionAdapters
         | 
| 3 | 
            +
                module PostgreSQL
         | 
| 4 | 
            +
                  module Quoting
         | 
| 5 | 
            +
                    def quote_column_name(name)
         | 
| 6 | 
            +
                      # CPK
         | 
| 7 | 
            +
                      # PGconn.quote_ident(name.to_s)
         | 
| 8 | 
            +
                      if name.is_a?(Array)
         | 
| 9 | 
            +
                        name.map do |column|
         | 
| 10 | 
            +
                          PGconn.quote_ident(column.to_s)
         | 
| 11 | 
            +
                        end.join(', ')
         | 
| 12 | 
            +
                      else
         | 
| 13 | 
            +
                        PGconn.quote_ident(name.to_s)
         | 
| 14 | 
            +
                      end
         | 
| 15 | 
            +
                    end
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
            end
         | 
| @@ -3,15 +3,19 @@ module ActiveRecord | |
| 3 3 | 
             
                class SQLServerAdapter
         | 
| 4 4 | 
             
                  def sql_for_insert(sql, pk, id_value, sequence_name, binds)
         | 
| 5 5 | 
             
                    sql = if pk && self.class.use_output_inserted
         | 
| 6 | 
            -
                      #  | 
| 6 | 
            +
                      # CPK
         | 
| 7 | 
            +
                      # quoted_pk = SQLServer::Utils.extract_identifiers(pk).quoted
         | 
| 8 | 
            +
                      # sql.insert sql.index(/ (DEFAULT )?VALUES/), " OUTPUT INSERTED.#{quoted_pk}"
         | 
| 7 9 | 
             
                      quoted_pks = [pk].flatten.map {|pk| "INSERTED.#{SQLServer::Utils.extract_identifiers(pk).quoted}"}
         | 
| 8 10 | 
             
                      sql.insert sql.index(/ (DEFAULT )?VALUES/), " OUTPUT #{quoted_pks.join(", ")}"
         | 
| 9 | 
            -
            #          p sql
         | 
| 10 11 | 
             
                    else
         | 
| 11 12 | 
             
                      "#{sql}; SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident"
         | 
| 12 13 | 
             
                    end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                    # CPK
         | 
| 16 | 
            +
                    # super
         | 
| 13 17 | 
             
                    [sql, binds]
         | 
| 14 18 | 
             
                  end
         | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 17 21 | 
             
            end
         | 
| @@ -1,22 +1,26 @@ | |
| 1 | 
            -
            module ActiveRecord
         | 
| 2 | 
            -
              class Fixture
         | 
| 3 | 
            -
                def find
         | 
| 4 | 
            -
                  if model_class
         | 
| 5 | 
            -
                    # CPK
         | 
| 6 | 
            -
                    # model_class. | 
| 7 | 
            -
                     | 
| 8 | 
            -
                     | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
                   | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 19 | 
            -
                   | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 1 | 
            +
            module ActiveRecord
         | 
| 2 | 
            +
              class Fixture
         | 
| 3 | 
            +
                def find
         | 
| 4 | 
            +
                  if model_class
         | 
| 5 | 
            +
                    # CPK
         | 
| 6 | 
            +
                    # model_class.unscoped do
         | 
| 7 | 
            +
                    #   model_class.find(fixture[model_class.primary_key])
         | 
| 8 | 
            +
                    # end
         | 
| 9 | 
            +
                    model_class.unscoped do
         | 
| 10 | 
            +
                      ids = self.ids(model_class.primary_key)
         | 
| 11 | 
            +
                      model_class.find(ids)
         | 
| 12 | 
            +
                    end
         | 
| 13 | 
            +
                  else
         | 
| 14 | 
            +
                    raise FixtureClassNotFound, "No class attached to find."
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def ids(key)
         | 
| 19 | 
            +
                  if key.is_a? Array
         | 
| 20 | 
            +
                    key.map {|a_key| fixture[a_key.to_s] }
         | 
| 21 | 
            +
                  else
         | 
| 22 | 
            +
                    fixture[key]
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
| @@ -1,55 +1,54 @@ | |
| 1 | 
            -
              module ActiveRecord
         | 
| 2 | 
            -
                module Locking
         | 
| 3 | 
            -
                  module Optimistic
         | 
| 4 | 
            -
                    private
         | 
| 5 | 
            -
                      def _update_record(attribute_names = @attributes.keys) #:nodoc:
         | 
| 6 | 
            -
                        return super unless locking_enabled?
         | 
| 7 | 
            -
                        return 0 if attribute_names.empty?
         | 
| 8 | 
            -
             | 
| 9 | 
            -
                        lock_col = self.class.locking_column
         | 
| 10 | 
            -
                        previous_lock_value = send(lock_col).to_i
         | 
| 11 | 
            -
                        increment_lock
         | 
| 12 | 
            -
             | 
| 13 | 
            -
                        attribute_names += [lock_col]
         | 
| 14 | 
            -
                        attribute_names.uniq!
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                        begin
         | 
| 17 | 
            -
                          relation = self.class.unscoped
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                          if self.composite?
         | 
| 20 | 
            -
                             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
                            ). | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
                                 | 
| 32 | 
            -
             | 
| 33 | 
            -
                            ). | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 46 | 
            -
             | 
| 47 | 
            -
                         | 
| 48 | 
            -
             | 
| 49 | 
            -
                           | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 54 | 
            -
             | 
| 55 | 
            -
              end
         | 
| 1 | 
            +
              module ActiveRecord
         | 
| 2 | 
            +
                module Locking
         | 
| 3 | 
            +
                  module Optimistic
         | 
| 4 | 
            +
                    private
         | 
| 5 | 
            +
                      def _update_record(attribute_names = @attributes.keys) #:nodoc:
         | 
| 6 | 
            +
                        return super unless locking_enabled?
         | 
| 7 | 
            +
                        return 0 if attribute_names.empty?
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                        lock_col = self.class.locking_column
         | 
| 10 | 
            +
                        previous_lock_value = send(lock_col).to_i
         | 
| 11 | 
            +
                        increment_lock
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                        attribute_names += [lock_col]
         | 
| 14 | 
            +
                        attribute_names.uniq!
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                        begin
         | 
| 17 | 
            +
                          relation = self.class.unscoped
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                          if self.composite?
         | 
| 20 | 
            +
                            affected_rows = relation.where(
         | 
| 21 | 
            +
                                relation.cpk_id_predicate(relation.table, self.class.primary_key, id_was)
         | 
| 22 | 
            +
                            ).where(
         | 
| 23 | 
            +
                                lock_col => previous_lock_value
         | 
| 24 | 
            +
                            ).update_all(
         | 
| 25 | 
            +
                                Hash[attributes_for_update(attribute_names).map do |name|
         | 
| 26 | 
            +
                                       [name, _read_attribute(name)]
         | 
| 27 | 
            +
                                     end]
         | 
| 28 | 
            +
                            )
         | 
| 29 | 
            +
                          else
         | 
| 30 | 
            +
                            affected_rows = relation.where(
         | 
| 31 | 
            +
                                self.class.primary_key => id,
         | 
| 32 | 
            +
                                lock_col => previous_lock_value,
         | 
| 33 | 
            +
                            ).update_all(
         | 
| 34 | 
            +
                                Hash[attributes_for_update(attribute_names).map do |name|
         | 
| 35 | 
            +
                                     [name, _read_attribute(name)]
         | 
| 36 | 
            +
                                   end]
         | 
| 37 | 
            +
                            )
         | 
| 38 | 
            +
                          end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                          unless affected_rows == 1
         | 
| 41 | 
            +
                            raise ActiveRecord::StaleObjectError.new(self, "update")
         | 
| 42 | 
            +
                          end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                          affected_rows
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                        # If something went wrong, revert the version.
         | 
| 47 | 
            +
                        rescue Exception
         | 
| 48 | 
            +
                          send(lock_col + '=', previous_lock_value)
         | 
| 49 | 
            +
                          raise
         | 
| 50 | 
            +
                      end
         | 
| 51 | 
            +
                    end
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
            end
         | 
| @@ -16,20 +16,23 @@ module ActiveRecord | |
| 16 16 | 
             
                  extend CompositePrimaryKeys::CompositeRelation
         | 
| 17 17 | 
             
                end
         | 
| 18 18 |  | 
| 19 | 
            -
                # CPK adds this so that it finds the Equality nodes beneath the And node:
         | 
| 20 | 
            -
                # equalities = where_values.grep(Arel::Nodes::Equality).find_all { |node|
         | 
| 21 | 
            -
                #  node.left.relation.name == table_name
         | 
| 22 | 
            -
                # }
         | 
| 23 19 | 
             
                alias :where_values_hash_without_cpk :where_values_hash
         | 
| 24 20 | 
             
                def where_values_hash(relation_table_name = table_name)
         | 
| 25 | 
            -
                   | 
| 21 | 
            +
                  # CPK
         | 
| 22 | 
            +
                  nodes_from_and = where_values.grep(Arel::Nodes::And).map { |and_node|
         | 
| 23 | 
            +
                    and_node.children.grep(Arel::Nodes::Equality)
         | 
| 24 | 
            +
                  }.flatten
         | 
| 26 25 |  | 
| 26 | 
            +
                  # CPK
         | 
| 27 | 
            +
                  # equalities = where_values.grep(Arel::Nodes::Equality).find_all { |node|
         | 
| 28 | 
            +
                  #   node.left.relation.name == relation_table_name
         | 
| 29 | 
            +
                  # }
         | 
| 27 30 | 
             
                  equalities = (nodes_from_and + where_values.grep(Arel::Nodes::Equality)).find_all { |node|
         | 
| 28 31 | 
             
                    node.left.relation.name == relation_table_name
         | 
| 29 32 | 
             
                  }
         | 
| 30 33 |  | 
| 31 34 | 
             
                  binds = Hash[bind_values.find_all(&:first).map { |column, v| [column.name, v] }]
         | 
| 32 | 
            -
             | 
| 35 | 
            +
             | 
| 33 36 | 
             
                  Hash[equalities.map { |where|
         | 
| 34 37 | 
             
                    name = where.left.name
         | 
| 35 38 | 
             
                    [name, binds.fetch(name.to_s) {
         | 
| @@ -48,6 +51,7 @@ module ActiveRecord | |
| 48 51 | 
             
                  # CPK
         | 
| 49 52 | 
             
                  um = if self.composite?
         | 
| 50 53 | 
             
                    relation = @klass.unscoped.where(cpk_id_predicate(@klass.arel_table, @klass.primary_key, id_was || id))
         | 
| 54 | 
            +
             | 
| 51 55 | 
             
                    relation.arel.compile_update(substitutes, @klass.primary_key)
         | 
| 52 56 | 
             
                  else
         | 
| 53 57 | 
             
                    scope = @klass.unscoped
         | 
| @@ -55,8 +59,11 @@ module ActiveRecord | |
| 55 59 | 
             
                    if @klass.finder_needs_type_condition?
         | 
| 56 60 | 
             
                      scope.unscope!(where: @klass.inheritance_column)
         | 
| 57 61 | 
             
                    end
         | 
| 58 | 
            -
             | 
| 59 | 
            -
                    scope.where(@klass. | 
| 62 | 
            +
             | 
| 63 | 
            +
                    relation = scope.where(@klass.primary_key => (id_was || id))
         | 
| 64 | 
            +
                    binds += relation.bind_values
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                    relation.arel.compile_update(substitutes, @klass.primary_key)
         | 
| 60 67 | 
             
                  end
         | 
| 61 68 |  | 
| 62 69 | 
             
                  @klass.connection.update(
         | 
| @@ -2,33 +2,39 @@ module CompositePrimaryKeys | |
| 2 2 | 
             
              module ActiveRecord
         | 
| 3 3 | 
             
                module Batches
         | 
| 4 4 | 
             
                  def find_in_batches(options = {})
         | 
| 5 | 
            +
                    options.assert_valid_keys(:start, :batch_size)
         | 
| 6 | 
            +
             | 
| 5 7 | 
             
                    relation = self
         | 
| 8 | 
            +
                    start = options[:start]
         | 
| 9 | 
            +
                    batch_size = options[:batch_size] || 1000
         | 
| 6 10 |  | 
| 7 | 
            -
                    unless  | 
| 8 | 
            -
                       | 
| 11 | 
            +
                    unless block_given?
         | 
| 12 | 
            +
                      return to_enum(:find_in_batches, options) do
         | 
| 13 | 
            +
                        total = start ? where(table[primary_key].gteq(start)).size : size
         | 
| 14 | 
            +
                        (total - 1).div(batch_size) + 1
         | 
| 15 | 
            +
                      end
         | 
| 9 16 | 
             
                    end
         | 
| 10 17 |  | 
| 11 | 
            -
                    if  | 
| 12 | 
            -
                       | 
| 13 | 
            -
                      raise "You can't specify a limit, it's forced to be the batch_size"  if options[:limit].present?
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                      relation = apply_finder_options(finder_options)
         | 
| 18 | 
            +
                    if logger && (arel.orders.present? || arel.taken.present?)
         | 
| 19 | 
            +
                      logger.warn("Scoped order and limit are ignored, it's forced to be batch order and batch size")
         | 
| 16 20 | 
             
                    end
         | 
| 17 21 |  | 
| 18 | 
            -
                    start = options.delete(:start).to_i
         | 
| 19 | 
            -
                    batch_size = options.delete(:batch_size) || 1000
         | 
| 20 | 
            -
             | 
| 21 22 | 
             
                    relation = relation.reorder(batch_order).limit(batch_size)
         | 
| 22 23 |  | 
| 23 24 | 
             
                    # CPK
         | 
| 24 | 
            -
                    # records = relation.where(table[primary_key].gteq(start)). | 
| 25 | 
            -
                    records =  | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 25 | 
            +
                    # records = start ? relation.where(table[primary_key].gteq(start)).to_a : relation.to_a
         | 
| 26 | 
            +
                    records = if start
         | 
| 27 | 
            +
                                self.primary_key.reduce(relation) do |rel, key|
         | 
| 28 | 
            +
                                  rel.where(table[key].gteq(start))
         | 
| 29 | 
            +
                                end
         | 
| 30 | 
            +
                              else
         | 
| 31 | 
            +
                                relation.to_a
         | 
| 32 | 
            +
                              end
         | 
| 28 33 |  | 
| 29 34 | 
             
                    while records.any?
         | 
| 30 35 | 
             
                      records_size = records.size
         | 
| 31 36 | 
             
                      primary_key_offset = records.last.id
         | 
| 37 | 
            +
                      raise "Primary key not included in the custom select clause" unless primary_key_offset
         | 
| 32 38 |  | 
| 33 39 | 
             
                      yield records
         | 
| 34 40 |  | 
| @@ -51,11 +57,9 @@ module CompositePrimaryKeys | |
| 51 57 |  | 
| 52 58 | 
             
                          Arel::Nodes::Grouping.new(and_clause)
         | 
| 53 59 | 
             
                        end.reduce(:or)
         | 
| 54 | 
            -
             | 
| 55 | 
            -
                        records = relation.where(query)
         | 
| 56 | 
            -
                      else
         | 
| 57 | 
            -
                        raise "Primary key not included in the custom select clause"
         | 
| 58 60 | 
             
                      end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                      records = relation.where(query)
         | 
| 59 63 | 
             
                    end
         | 
| 60 64 | 
             
                  end
         | 
| 61 65 |  | 
| @@ -70,7 +74,7 @@ module CompositePrimaryKeys | |
| 70 74 |  | 
| 71 75 | 
             
                  def batch_order
         | 
| 72 76 | 
             
                    # CPK
         | 
| 73 | 
            -
                    #"#{quoted_table_name}.#{quoted_primary_key} ASC"
         | 
| 77 | 
            +
                    # "#{quoted_table_name}.#{quoted_primary_key} ASC"
         | 
| 74 78 | 
             
                    self.primary_key.map do |key|
         | 
| 75 79 | 
             
                      "#{quoted_table_name}.#{key} ASC"
         | 
| 76 80 | 
             
                    end.join(",")
         |