Permalink
Browse files

Add support for PostgreSQL

I'm not happy with the way I came up with to get the indexes for Postgres, but it's very difficult.
  • Loading branch information...
1 parent ab0eb46 commit 15b71c4ef093a3f93200b2dcd1aed3f8ca381fb5 @look look committed Feb 5, 2010
Showing with 47 additions and 14 deletions.
  1. +45 −9 lib/acts_as_archive/base/table.rb
  2. +2 −5 spec/spec_helper.rb
@@ -10,16 +10,16 @@ def self.included(base)
end
module ClassMethods
-
+
def archive_table_exists?
connection.table_exists?("archived_#{table_name}")
end
-
+
def create_archive_table
if table_exists? && !archive_table_exists?
connection.execute(%{
CREATE TABLE archived_#{table_name}
- ENGINE=InnoDB
+ #{"ENGINE=InnoDB" if connection.class.to_s == "ActiveRecord::ConnectionAdapters::MysqlAdapter"}
AS SELECT * from #{table_name}
WHERE false;
})
@@ -29,13 +29,11 @@ def create_archive_table
end
end
end
-
+
def create_archive_indexes
if archive_table_exists?
- indexes = "SHOW INDEX FROM archived_#{table_name}"
- indexes = connection.select_all(indexes).collect do |r|
- r["Column_name"]
- end
+ indexes = archive_table_indexed_columns
+
(archive_indexes - indexes).each do |index|
connection.add_index("archived_#{table_name}", index)
end
@@ -44,7 +42,8 @@ def create_archive_indexes
end
end
end
-
+
+
def migrate_from_acts_as_paranoid
if column_names.include?('deleted_at')
if table_exists? && archive_table_exists?
@@ -56,6 +55,43 @@ def migrate_from_acts_as_paranoid
end
end
end
+
+ private
+
+ def archive_table_indexed_columns
+ case connection.class.to_s
+ when "ActiveRecord::ConnectionAdapters::MysqlAdapter"
+ index_query = "SHOW INDEX FROM archived_#{table_name}"
+ indexes = connection.select_all(index_query).collect do |r|
+ r["Column_name"]
+ end
+ when "ActiveRecord::ConnectionAdapters::PostgreSQLAdapter"
+ #postgresql is...slightly...more complicated
+ index_query = <<EOS
+SELECT c2.relname as index_name
+FROM pg_catalog.pg_class c,
+ pg_catalog.pg_class c2,
+ pg_catalog.pg_index i
+WHERE c.oid = (SELECT c.oid
+ FROM pg_catalog.pg_class c
+ WHERE c.relname ~ '^(archived_#{table_name})$')
+AND c.oid = i.indrelid
+AND i.indexrelid = c2.oid
+EOS
+ indexes = connection.select_all(index_query).collect do |r|
+ r["index_name"]
+ end
+
+ # HACK: reverse engineer the column name
+ # This sucks, but acts_as_archive only adds indexes on single columns anyway so it should work OK
+ # and getting the columns indexed is INCREDIBLY complicated in PostgreSQL.
+ indexes.map do |index|
+ index.split("_on_").last
+ end
+ else
+ raise "Unsupported Database"
+ end
+ end
end
module InstanceMethods
View
@@ -47,7 +47,7 @@ def create_records(klass=Article, values={})
end
end
connection.execute(%{
- INSERT INTO #{table} (#{cols.collect { |c| "`#{c}`" }.join(', ')})
+ INSERT INTO #{table} (#{cols.collect { |c| "#{c}" }.join(', ')})
VALUES (#{vals.join(', ')})
})
klass.find(x)
@@ -85,10 +85,7 @@ def establish_test_db
end
def indexes
- query = "SHOW INDEX FROM archived_#{Article.table_name}"
- connection.select_all(query).collect do |r|
- r["Column_name"]
- end
+ Article.send(:archive_table_indexed_columns)
end
def migrate_up(directory='migrate')

0 comments on commit 15b71c4

Please sign in to comment.