Module: CompositePrimaryKeys::ActiveRecord::Calculations::ClassMethods
- Defined in:
- lib/composite_primary_keys/calculations.rb
Instance Method Summary collapse
Instance Method Details
#construct_calculation_sql(operation, column_name, options) ⇒ Object
:nodoc:
10 11 12 13 14 15 16 17 18 19 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 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/composite_primary_keys/calculations.rb', line 10 def construct_calculation_sql(operation, column_name, ) #:nodoc: operation = operation.to_s.downcase = .symbolize_keys scope = scope(:find) merged_includes = merge_includes(scope ? scope[:include] : [], [:include]) aggregate_alias = column_alias_for(operation, column_name) use_workaround = !connection.supports_count_distinct? && [:distinct] && operation.to_s.downcase == 'count' join_dependency = nil if merged_includes.any? && operation.to_s.downcase == 'count' [:distinct] = true use_workaround = !connection.supports_count_distinct? column_name = [:select] || primary_key.map{ |part| "#{quoted_table_name}.#{connection.quote_column_name(part)}"}.join(',') end sql = "SELECT #{operation}(#{'DISTINCT ' if [:distinct]}#{column_name}) AS #{aggregate_alias}" # A (slower) workaround if we're using a backend, like sqlite, that doesn't support COUNT DISTINCT. sql = "SELECT COUNT(*) AS #{aggregate_alias}" if use_workaround sql << ", #{connection.quote_column_name([:group_field])} AS #{[:group_alias]}" if [:group] sql << " FROM (SELECT DISTINCT #{column_name}" if use_workaround sql << " FROM #{quoted_table_name} " if merged_includes.any? join_dependency = ::ActiveRecord::Associations::ClassMethods::JoinDependency.new(self, merged_includes, [:joins]) sql << join_dependency.join_associations.collect{|join| join.association_join }.join end add_joins!(sql, [:joins], scope) add_conditions!(sql, [:conditions], scope) add_limited_ids_condition!(sql, , join_dependency) if \ join_dependency && !using_limitable_reflections?(join_dependency.reflections) && ((scope && scope[:limit]) || [:limit]) if [:group] group_key = connection.adapter_name == 'FrontBase' ? :group_alias : :group_field sql << " GROUP BY #{connection.quote_column_name([group_key])} " end if [:group] && [:having] # FrontBase requires identifiers in the HAVING clause and chokes on function calls if connection.adapter_name == 'FrontBase' [:having].downcase! [:having].gsub!(/#{operation}\s*\(\s*#{column_name}\s*\)/, aggregate_alias) end sql << " HAVING #{[:having]} " end sql << " ORDER BY #{[:order]} " if [:order] add_limit!(sql, , scope) sql << ') w1' if use_workaround # assign a dummy table name as required for postgresql sql end |