]> git.openstreetmap.org Git - rails.git/blobdiff - vendor/gems/composite_primary_keys-2.2.2/lib/composite_primary_keys/associations.rb
Remove ancient (and unused) composite_primary_keys gem
[rails.git] / vendor / gems / composite_primary_keys-2.2.2 / lib / composite_primary_keys / associations.rb
diff --git a/vendor/gems/composite_primary_keys-2.2.2/lib/composite_primary_keys/associations.rb b/vendor/gems/composite_primary_keys-2.2.2/lib/composite_primary_keys/associations.rb
deleted file mode 100644 (file)
index 6b63664..0000000
+++ /dev/null
@@ -1,428 +0,0 @@
-module CompositePrimaryKeys
-  module ActiveRecord
-    module Associations
-      def self.append_features(base)
-        super
-        base.send(:extend, ClassMethods)
-      end
-
-      # Composite key versions of Association functions
-      module ClassMethods
-
-        def construct_counter_sql_with_included_associations(options, join_dependency)
-          scope = scope(:find)
-          sql = "SELECT COUNT(DISTINCT #{quoted_table_columns(primary_key)})"
-
-          # A (slower) workaround if we're using a backend, like sqlite, that doesn't support COUNT DISTINCT.
-          if !self.connection.supports_count_distinct?
-            sql = "SELECT COUNT(*) FROM (SELECT DISTINCT #{quoted_table_columns(primary_key)}"
-          end
-          
-          sql << " FROM #{quoted_table_name} "
-          sql << join_dependency.join_associations.collect{|join| join.association_join }.join
-
-          add_joins!(sql, options[:joins], scope)
-          add_conditions!(sql, options[:conditions], scope)
-          add_limited_ids_condition!(sql, options, join_dependency) if !using_limitable_reflections?(join_dependency.reflections) && ((scope && scope[:limit]) || options[:limit])
-
-          add_limit!(sql, options, scope) if using_limitable_reflections?(join_dependency.reflections)
-
-          if !self.connection.supports_count_distinct?
-            sql << ")"
-          end
-
-          return sanitize_sql(sql)
-        end
-
-        def construct_finder_sql_with_included_associations(options, join_dependency)
-          scope = scope(:find)
-          sql = "SELECT #{column_aliases(join_dependency)} FROM #{(scope && scope[:from]) || options[:from] || quoted_table_name} "
-          sql << join_dependency.join_associations.collect{|join| join.association_join }.join
-
-          add_joins!(sql, options[:joins], scope)
-          add_conditions!(sql, options[:conditions], scope)
-          add_limited_ids_condition!(sql, options, join_dependency) if !using_limitable_reflections?(join_dependency.reflections) && options[:limit]
-
-          sql << "ORDER BY #{options[:order]} " if options[:order]
-
-          add_limit!(sql, options, scope) if using_limitable_reflections?(join_dependency.reflections)
-
-          return sanitize_sql(sql)
-        end
-
-        def table_columns(columns)
-          columns.collect {|column| "#{self.quoted_table_name}.#{connection.quote_column_name(column)}"}
-        end
-
-        def quoted_table_columns(columns)
-          table_columns(columns).join(ID_SEP)
-        end
-
-      end
-
-    end
-  end
-end
-
-module ActiveRecord::Associations::ClassMethods
-  class JoinDependency
-    def construct_association(record, join, row)
-      case join.reflection.macro
-        when :has_many, :has_and_belongs_to_many
-          collection = record.send(join.reflection.name)
-          collection.loaded
-
-          join_aliased_primary_keys = join.active_record.composite? ?
-            join.aliased_primary_key : [join.aliased_primary_key]
-          return nil if
-            record.id.to_s != join.parent.record_id(row).to_s or not
-            join_aliased_primary_keys.select {|key| row[key].nil?}.blank?
-          association = join.instantiate(row)
-          collection.target.push(association) unless collection.target.include?(association)
-        when :has_one, :belongs_to
-          return if record.id.to_s != join.parent.record_id(row).to_s or
-                    [*join.aliased_primary_key].any? { |key| row[key].nil? }
-          association = join.instantiate(row)
-          record.send("set_#{join.reflection.name}_target", association)
-        else
-          raise ConfigurationError, "unknown macro: #{join.reflection.macro}"
-      end
-      return association
-    end
-
-    class JoinBase
-      def aliased_primary_key
-        active_record.composite? ?
-          primary_key.inject([]) {|aliased_keys, key| aliased_keys << "#{ aliased_prefix }_r#{aliased_keys.length}"} :
-          "#{ aliased_prefix }_r0"
-      end
-
-      def record_id(row)
-        active_record.composite? ?
-          aliased_primary_key.map {|key| row[key]}.to_composite_ids :
-          row[aliased_primary_key]
-      end
-
-      def column_names_with_alias
-        unless @column_names_with_alias
-          @column_names_with_alias = []
-          keys = active_record.composite? ? primary_key.map(&:to_s) : [primary_key]
-          (keys + (column_names - keys)).each_with_index do |column_name, i|
-            @column_names_with_alias << [column_name, "#{ aliased_prefix }_r#{ i }"]
-          end
-        end
-        return @column_names_with_alias
-      end
-    end
-
-    class JoinAssociation < JoinBase
-      alias single_association_join association_join
-      def association_join
-        reflection.active_record.composite? ? composite_association_join : single_association_join
-      end
-
-      def composite_association_join
-        join = case reflection.macro
-          when :has_and_belongs_to_many
-            " LEFT OUTER JOIN %s ON %s " % [
-              table_alias_for(options[:join_table], aliased_join_table_name),
-                composite_join_clause(
-                  full_keys(aliased_join_table_name, options[:foreign_key] || reflection.active_record.to_s.classify.foreign_key),
-                  full_keys(reflection.active_record.table_name, reflection.active_record.primary_key)
-                )
-              ] +
-             " LEFT OUTER JOIN %s ON %s " % [
-                table_name_and_alias,
-                composite_join_clause(
-                  full_keys(aliased_table_name, klass.primary_key),
-                  full_keys(aliased_join_table_name, options[:association_foreign_key] || klass.table_name.classify.foreign_key)
-                )
-              ]
-          when :has_many, :has_one
-            case
-              when reflection.macro == :has_many && reflection.options[:through]
-                through_conditions = through_reflection.options[:conditions] ? "AND #{interpolate_sql(sanitize_sql(through_reflection.options[:conditions]))}" : ''
-                if through_reflection.options[:as] # has_many :through against a polymorphic join
-                  raise AssociationNotSupported, "Polymorphic joins not supported for composite keys"
-                else
-                  if source_reflection.macro == :has_many && source_reflection.options[:as]
-                    raise AssociationNotSupported, "Polymorphic joins not supported for composite keys"
-                  else
-                    case source_reflection.macro
-                      when :belongs_to
-                        first_key  = primary_key
-                        second_key = options[:foreign_key] || klass.to_s.classify.foreign_key
-                      when :has_many
-                        first_key  = through_reflection.klass.to_s.classify.foreign_key
-                        second_key = options[:foreign_key] || primary_key
-                    end
-
-                    " LEFT OUTER JOIN %s ON %s "  % [
-                      table_alias_for(through_reflection.klass.table_name, aliased_join_table_name),
-                       composite_join_clause(
-                         full_keys(aliased_join_table_name, through_reflection.primary_key_name),
-                         full_keys(parent.aliased_table_name, parent.primary_key)
-                       )
-                     ] +
-                     " LEFT OUTER JOIN %s ON %s " % [
-                       table_name_and_alias,
-                       composite_join_clause(
-                         full_keys(aliased_table_name, first_key),
-                         full_keys(aliased_join_table_name, second_key)
-                       )
-                    ]
-                  end
-                end
-
-              when reflection.macro == :has_many && reflection.options[:as]
-                raise AssociationNotSupported, "Polymorphic joins not supported for composite keys"
-              when reflection.macro == :has_one && reflection.options[:as]
-                raise AssociationNotSupported, "Polymorphic joins not supported for composite keys"
-              else
-                foreign_key = options[:foreign_key] || reflection.active_record.name.foreign_key
-                " LEFT OUTER JOIN %s ON %s " % [
-                  table_name_and_alias,
-                  composite_join_clause(
-                    full_keys(aliased_table_name, foreign_key),
-                    full_keys(parent.aliased_table_name, parent.primary_key)),
-                ]
-            end
-          when :belongs_to
-            " LEFT OUTER JOIN %s ON %s " % [
-               table_name_and_alias,
-               composite_join_clause(
-                 full_keys(aliased_table_name, reflection.klass.primary_key),
-                 full_keys(parent.aliased_table_name, options[:foreign_key] || klass.to_s.foreign_key)),
-              ]
-          else
-            ""
-        end || ''
-        join << %(AND %s.%s = %s ) % [
-          aliased_table_name,
-          reflection.active_record.connection.quote_column_name(reflection.active_record.inheritance_column),
-          klass.connection.quote(klass.name)] unless klass.descends_from_active_record?
-        join << "AND #{interpolate_sql(sanitize_sql(reflection.options[:conditions]))} " if reflection.options[:conditions]
-        join
-      end
-
-      def full_keys(table_name, keys)
-        connection = reflection.active_record.connection
-        quoted_table_name = connection.quote_table_name(table_name)
-        if keys.is_a?(Array) 
-          keys.collect {|key| "#{quoted_table_name}.#{connection.quote_column_name(key)}"}.join(CompositePrimaryKeys::ID_SEP) 
-        else
-          "#{quoted_table_name}.#{connection.quote_column_name(keys)}"
-        end
-      end
-
-      def composite_join_clause(full_keys1, full_keys2)
-        full_keys1 = full_keys1.split(CompositePrimaryKeys::ID_SEP) if full_keys1.is_a?(String)
-        full_keys2 = full_keys2.split(CompositePrimaryKeys::ID_SEP) if full_keys2.is_a?(String)
-        where_clause = [full_keys1, full_keys2].transpose.map do |key1, key2|
-          "#{key1}=#{key2}"
-        end.join(" AND ")
-        "(#{where_clause})"
-      end
-    end
-  end
-end
-
-module ActiveRecord::Associations
-  class AssociationProxy #:nodoc:
-
-    def composite_where_clause(full_keys, ids)
-      full_keys = full_keys.split(CompositePrimaryKeys::ID_SEP) if full_keys.is_a?(String)
-
-      if ids.is_a?(String)
-        ids = [[ids]]
-      elsif not ids.first.is_a?(Array) # if single comp key passed, turn into an array of 1
-        ids = [ids.to_composite_ids]
-      end
-
-      where_clause = ids.map do |id_set|
-        transposed = id_set.size == 1 ? [[full_keys, id_set.first]] : [full_keys, id_set].transpose
-        transposed.map do |full_key, id|
-          "#{full_key.to_s}=#{@reflection.klass.sanitize(id)}"
-        end.join(" AND ")
-      end.join(") OR (")
-
-      "(#{where_clause})"
-    end
-
-    def composite_join_clause(full_keys1, full_keys2)
-      full_keys1 = full_keys1.split(CompositePrimaryKeys::ID_SEP) if full_keys1.is_a?(String)
-      full_keys2 = full_keys2.split(CompositePrimaryKeys::ID_SEP) if full_keys2.is_a?(String)
-
-      where_clause = [full_keys1, full_keys2].transpose.map do |key1, key2|
-        "#{key1}=#{key2}"
-      end.join(" AND ")
-
-      "(#{where_clause})"
-    end
-
-    def full_composite_join_clause(table1, full_keys1, table2, full_keys2)
-      connection = @reflection.active_record.connection
-      full_keys1 = full_keys1.split(CompositePrimaryKeys::ID_SEP) if full_keys1.is_a?(String)
-      full_keys2 = full_keys2.split(CompositePrimaryKeys::ID_SEP) if full_keys2.is_a?(String)
-
-      quoted1 = connection.quote_table_name(table1)
-      quoted2 = connection.quote_table_name(table2)
-      
-      where_clause = [full_keys1, full_keys2].transpose.map do |key_pair|
-        "#{quoted1}.#{connection.quote_column_name(key_pair.first)}=#{quoted2}.#{connection.quote_column_name(key_pair.last)}"
-      end.join(" AND ")
-
-      "(#{where_clause})"
-    end
-
-    def full_keys(table_name, keys)
-      connection = @reflection.active_record.connection
-      quoted_table_name = connection.quote_table_name(table_name)
-      keys = keys.split(CompositePrimaryKeys::ID_SEP) if keys.is_a?(String)
-      if keys.is_a?(Array) 
-        keys.collect {|key| "#{quoted_table_name}.#{connection.quote_column_name(key)}"}.join(CompositePrimaryKeys::ID_SEP) 
-      else
-        "#{quoted_table_name}.#{connection.quote_column_name(keys)}"
-      end
-    end
-
-    def full_columns_equals(table_name, keys, quoted_ids)
-      connection = @reflection.active_record.connection
-      quoted_table_name = connection.quote_table_name(table_name)
-      if keys.is_a?(Symbol) or (keys.is_a?(String) and keys == keys.to_s.split(CompositePrimaryKeys::ID_SEP))
-        return "#{quoted_table_name}.#{connection.quote_column_name(keys)} = #{quoted_ids}"
-      end
-      keys = keys.split(CompositePrimaryKeys::ID_SEP) if keys.is_a?(String)
-      quoted_ids = quoted_ids.split(CompositePrimaryKeys::ID_SEP) if quoted_ids.is_a?(String)
-      keys_ids = [keys, quoted_ids].transpose
-      keys_ids.collect {|key, id| "(#{quoted_table_name}.#{connection.quote_column_name(key)} = #{id})"}.join(' AND ')
-    end 
-
-    def set_belongs_to_association_for(record)
-      if @reflection.options[:as]
-        record["#{@reflection.options[:as]}_id"]   = @owner.id unless @owner.new_record?
-        record["#{@reflection.options[:as]}_type"] = @owner.class.base_class.name.to_s
-      else
-        key_values = @reflection.primary_key_name.to_s.split(CompositePrimaryKeys::ID_SEP).zip([@owner.id].flatten)
-        key_values.each{|key, value| record[key] = value} unless @owner.new_record?
-      end
-    end
-  end
-
-  class HasAndBelongsToManyAssociation < AssociationCollection #:nodoc:
-    def construct_sql
-      @reflection.options[:finder_sql] &&= interpolate_sql(@reflection.options[:finder_sql])
-
-      if @reflection.options[:finder_sql]
-        @finder_sql = @reflection.options[:finder_sql]
-      else
-        @finder_sql = full_columns_equals(@reflection.options[:join_table], @reflection.primary_key_name, @owner.quoted_id)
-        @finder_sql << " AND (#{conditions})" if conditions
-      end
-
-      @join_sql = "INNER JOIN #{@reflection.active_record.connection.quote_table_name(@reflection.options[:join_table])} ON " +
-      full_composite_join_clause(@reflection.klass.table_name, @reflection.klass.primary_key, @reflection.options[:join_table], @reflection.association_foreign_key)
-    end
-  end
-
-  class HasManyAssociation < AssociationCollection #:nodoc:
-    def construct_sql
-      case
-        when @reflection.options[:finder_sql]
-          @finder_sql = interpolate_sql(@reflection.options[:finder_sql])
-
-        when @reflection.options[:as]
-          @finder_sql = 
-            "#{@reflection.klass.quoted_table_name}.#{@reflection.options[:as]}_id = #{@owner.quoted_id} AND " + 
-            "#{@reflection.klass.quoted_table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote_value(@owner.class.base_class.name.to_s)}"
-          @finder_sql << " AND (#{conditions})" if conditions
-
-        else
-          @finder_sql = full_columns_equals(@reflection.klass.table_name, @reflection.primary_key_name, @owner.quoted_id)
-          @finder_sql << " AND (#{conditions})" if conditions
-      end
-
-      if @reflection.options[:counter_sql]
-        @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
-      elsif @reflection.options[:finder_sql]
-        # replace the SELECT clause with COUNT(*), preserving any hints within /* ... */
-        @reflection.options[:counter_sql] = @reflection.options[:finder_sql].sub(/SELECT (\/\*.*?\*\/ )?(.*)\bFROM\b/im) { "SELECT #{$1}COUNT(*) FROM" }
-        @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
-      else
-        @counter_sql = @finder_sql
-      end
-    end
-
-    def delete_records(records)
-      if @reflection.options[:dependent]
-        records.each { |r| r.destroy }
-      else
-        connection = @reflection.active_record.connection
-        field_names = @reflection.primary_key_name.split(',')
-        field_names.collect! {|n| connection.quote_column_name(n) + " = NULL"}
-        records.each do |r|
-          where_clause = nil
-          
-          if r.quoted_id.to_s.include?(CompositePrimaryKeys::ID_SEP)
-            where_clause_terms = [@reflection.klass.primary_key, r.quoted_id].transpose.map do |pair|
-              "(#{connection.quote_column_name(pair[0])} = #{pair[1]})"
-            end
-            where_clause = where_clause_terms.join(" AND ")
-          else
-            where_clause = connection.quote_column_name(@reflection.klass.primary_key) + ' = ' +  r.quoted_id
-          end
-          
-          @reflection.klass.update_all(  field_names.join(',') , where_clause)
-        end
-      end
-    end
-  end
-
-  class HasOneAssociation < BelongsToAssociation #:nodoc:
-    def construct_sql
-      case
-        when @reflection.options[:as]
-          @finder_sql = 
-            "#{@reflection.klass.quoted_table_name}.#{@reflection.options[:as]}_id = #{@owner.quoted_id} AND " + 
-            "#{@reflection.klass.quoted_table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote_value(@owner.class.base_class.name.to_s)}"
-        else
-          @finder_sql = full_columns_equals(@reflection.klass.table_name, @reflection.primary_key_name, @owner.quoted_id)
-      end
-
-      @finder_sql << " AND (#{conditions})" if conditions
-    end
-  end
-
-  class HasManyThroughAssociation < HasManyAssociation #:nodoc:
-    def construct_conditions_with_composite_keys
-      if @reflection.through_reflection.options[:as]
-        construct_conditions_without_composite_keys
-      else
-        conditions = full_columns_equals(@reflection.through_reflection.table_name, @reflection.through_reflection.primary_key_name, @owner.quoted_id)
-        conditions << " AND (#{sql_conditions})" if sql_conditions
-        conditions
-      end
-    end
-    alias_method_chain :construct_conditions, :composite_keys
-
-    def construct_joins_with_composite_keys(custom_joins = nil)
-      if @reflection.through_reflection.options[:as] || @reflection.source_reflection.options[:as]
-        construct_joins_without_composite_keys(custom_joins)
-      else
-        if @reflection.source_reflection.macro == :belongs_to
-          reflection_primary_key = @reflection.klass.primary_key
-          source_primary_key     = @reflection.source_reflection.primary_key_name
-        else
-          reflection_primary_key = @reflection.source_reflection.primary_key_name
-          source_primary_key     = @reflection.klass.primary_key
-        end
-
-        "INNER JOIN %s ON %s #{@reflection.options[:joins]} #{custom_joins}" % [
-          @reflection.through_reflection.quoted_table_name,
-          composite_join_clause(full_keys(@reflection.table_name, reflection_primary_key), full_keys(@reflection.through_reflection.table_name, source_primary_key))
-        ]
-      end
-    end
-    alias_method_chain :construct_joins, :composite_keys
-  end
-end