File 0002-Use-faster-group-columns-if-not-running-on-postgresq.patch of Package rubygem-acts-as-taggable-on
From c31c2e53b1cb8484ad466c3fbb853f2e665c2390 Mon Sep 17 00:00:00 2001
From: Tom-Eric <ik@tom-eric.info>
Date: Wed, 19 May 2010 15:49:40 +0200
Subject: [PATCH 2/9] Use faster group columns if not running on postgresql
---
.../acts_as_taggable_on/collection.rb | 7 ++++---
.../acts_as_taggable_on/core.rb | 17 ++++++++++++++---
.../acts_as_taggable_on/related.rb | 8 ++++++--
lib/acts_as_taggable_on/tag.rb | 6 +++++-
4 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb b/lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb
index 4f0a486..bf33a15 100644
--- a/lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb
+++ b/lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb
@@ -91,7 +91,6 @@ module ActsAsTaggableOn::Taggable
joins = joins.reverse if ActiveRecord::VERSION::MAJOR < 3
-
## Generate scope:
scope = ActsAsTaggableOn::Tag.scoped(:select => "#{ActsAsTaggableOn::Tag.table_name}.*, COUNT(*) AS count").order(options[:order]).limit(options[:limit])
@@ -104,6 +103,8 @@ module ActsAsTaggableOn::Taggable
at_most = sanitize_sql(['COUNT(*) <= ?', options.delete(:at_most)]) if options[:at_most]
having = [at_least, at_most].compact.join(' AND ')
+ group_columns = ActsAsTaggableOn::Tag.using_postgresql? ? grouped_column_names_for(ActsAsTaggableOn::Tag) : "#{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key}"
+
if ActiveRecord::VERSION::MAJOR >= 3
# Append the current scope to the scope, because we can't use scope(:find) in RoR 3.0 anymore:
scoped_select = "#{table_name}.#{primary_key}"
@@ -111,10 +112,10 @@ module ActsAsTaggableOn::Taggable
# We have having() in RoR 3.0 so use it:
having = having.blank? ? "COUNT(*) > 0" : "COUNT(*) > 0 AND #{having}"
- scope = scope.group(grouped_column_names_for(ActsAsTaggableOn::Tag)).having(having)
+ scope = scope.group(group_columns).having(having)
else
# Having is not available in 2.3.x:
- group_by = "#{grouped_column_names_for(ActsAsTaggableOn::Tag)} HAVING COUNT(*) > 0"
+ group_by = "#{group_columns} HAVING COUNT(*) > 0"
group_by << " AND #{having}" unless having.blank?
scope = scope.group(group_by)
end
diff --git a/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb b/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb
index 3347cb6..46d22bb 100644
--- a/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb
+++ b/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb
@@ -110,7 +110,9 @@ module ActsAsTaggableOn::Taggable
" ON #{taggings_alias}.taggable_id = #{table_name}.#{primary_key}" +
" AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)}"
- group = "#{grouped_column_names_for(self)} HAVING COUNT(#{taggings_alias}.taggable_id) = #{tags.size}"
+
+ group_columns = ActsAsTaggableOn::Tag.using_postgresql? ? grouped_column_names_for(self) : "#{table_name}.#{primary_key}"
+ group = "#{group_columns} HAVING COUNT(#{taggings_alias}.taggable_id) = #{tags.size}"
end
@@ -176,8 +178,17 @@ module ActsAsTaggableOn::Taggable
tag_table_name = ActsAsTaggableOn::Tag.table_name
tagging_table_name = ActsAsTaggableOn::Tagging.table_name
- opts = ["#{tagging_table_name}.context = ?", context.to_s]
- base_tags.where(opts).order("max(#{tagging_table_name}.created_at)").group("#{tag_table_name}.id, #{tag_table_name}.name").all
+ opts = ["#{tagging_table_name}.context = ?", context.to_s]
+ scope = base_tags.where(opts)
+
+ if ActsAsTaggableOn::Tag.using_postgresql?
+ group_columns = grouped_column_names_for(ActsAsTaggableOn::Tag)
+ scope = scope.order("max(#{tagging_table_name}.created_at)").group(group_columns)
+ else
+ scope = scope.group("#{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key}")
+ end
+
+ scope.all
end
##
diff --git a/lib/acts_as_taggable_on/acts_as_taggable_on/related.rb b/lib/acts_as_taggable_on/acts_as_taggable_on/related.rb
index 6788850..92ba3dc 100644
--- a/lib/acts_as_taggable_on/acts_as_taggable_on/related.rb
+++ b/lib/acts_as_taggable_on/acts_as_taggable_on/related.rb
@@ -42,10 +42,12 @@ module ActsAsTaggableOn::Taggable
exclude_self = "#{klass.table_name}.id != #{id} AND" if self.class == klass
+ group_columns = ActsAsTaggableOn::Tag.using_postgresql? ? grouped_column_names_for(klass) : "#{klass.table_name}.#{klass.primary_key}"
+
klass.scoped({ :select => "#{klass.table_name}.*, COUNT(#{ActsAsTaggableOn::Tag.table_name}.id) AS count",
:from => "#{klass.table_name}, #{ActsAsTaggableOn::Tag.table_name}, #{ActsAsTaggableOn::Tagging.table_name}",
:conditions => ["#{exclude_self} #{klass.table_name}.id = #{ActsAsTaggableOn::Tagging.table_name}.taggable_id AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = '#{klass.to_s}' AND #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id AND #{ActsAsTaggableOn::Tag.table_name}.name IN (?) AND #{ActsAsTaggableOn::Tagging.table_name}.context = ?", tags_to_find, result_context],
- :group => grouped_column_names_for(klass),
+ :group => group_columns,
:order => "count DESC" }.update(options))
end
@@ -54,10 +56,12 @@ module ActsAsTaggableOn::Taggable
exclude_self = "#{klass.table_name}.id != #{id} AND" if self.class == klass
+group_columns = ActsAsTaggableOn::Tag.using_postgresql? ? grouped_column_names_for(klass) : "#{klass.table_name}.#{klass.primary_key}"
+
klass.scoped({ :select => "#{klass.table_name}.*, COUNT(#{ActsAsTaggableOn::Tag.table_name}.id) AS count",
:from => "#{klass.table_name}, #{ActsAsTaggableOn::Tag.table_name}, #{ActsAsTaggableOn::Tagging.table_name}",
:conditions => ["#{exclude_self} #{klass.table_name}.id = #{ActsAsTaggableOn::Tagging.table_name}.taggable_id AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = '#{klass.to_s}' AND #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id AND #{ActsAsTaggableOn::Tag.table_name}.name IN (?)", tags_to_find],
- :group => grouped_column_names_for(klass),
+ :group => group_columns,
:order => "count DESC" }.update(options))
end
end
diff --git a/lib/acts_as_taggable_on/tag.rb b/lib/acts_as_taggable_on/tag.rb
index 3350f15..99d0959 100644
--- a/lib/acts_as_taggable_on/tag.rb
+++ b/lib/acts_as_taggable_on/tag.rb
@@ -14,6 +14,10 @@ module ActsAsTaggableOn
validates_uniqueness_of :name
### SCOPES:
+
+ def self.using_postgresql?
+ connection.adapter_name == 'PostgreSQL'
+ end
def self.named(name)
where(["name #{like_operator} ?", name])
@@ -66,7 +70,7 @@ module ActsAsTaggableOn
class << self
private
def like_operator
- connection.adapter_name == 'PostgreSQL' ? 'ILIKE' : 'LIKE'
+ using_postgresql? ? 'ILIKE' : 'LIKE'
end
end
--
1.7.1