Postgres adapter, and make migration 022 db-agnostic
authorAndy Allan <gravitystorm@gmail.com>
Mon, 10 Nov 2008 19:14:00 +0000 (19:14 +0000)
committerAndy Allan <gravitystorm@gmail.com>
Mon, 10 Nov 2008 19:14:00 +0000 (19:14 +0000)
db/migrate/022_order_relation_members.rb
lib/migrate.rb

index e3820d4e610ce5a4cca6573f3b1293216f6755ad..5500edfcfbf4ac42e9a35e9d754dfdc049a96a47 100644 (file)
@@ -8,26 +8,26 @@ class OrderRelationMembers < ActiveRecord::Migration
     # update the sequence column with default (partial) ordering by 
     # element ID. the sequence ID is a smaller int type, so we can't
     # just copy the member_id.
-    ActiveRecord::Base.connection().execute("update relation_members set sequence_id = mod(member_id, 16384)")
+    execute("update relation_members set sequence_id = mod(member_id, 16384)")
 
     # need to update the primary key to include the sequence number, 
     # otherwise the primary key will barf when we have repeated members.
     # mysql barfs on this anyway, so we need a single command. this may
     # not work in postgres... needs testing.
-    ActiveRecord::Base.connection().execute("alter table relation_members drop primary key, add primary key (id, version, member_type, member_id, member_role, sequence_id)")
+    alter_primary_key("relation_members", [:id, :version, :member_type, :member_id, :member_role, :sequence_id])
 
     # do the same for the current tables
     add_column(:current_relation_members, :sequence_id, :integer,
                :default => 0, :null => false)
-    ActiveRecord::Base.connection().execute("update current_relation_members set sequence_id = mod(member_id, 16384)")
-    ActiveRecord::Base.connection().execute("alter table current_relation_members drop primary key, add primary key (id, member_type, member_id, member_role, sequence_id)")
+    execute("update current_relation_members set sequence_id = mod(member_id, 16384)")
+    alter_primary_key("current_relation_members", [:id, :member_type, :member_id, :member_role, :sequence_id])
   end
 
   def self.down
-    ActiveRecord::Base.connection().execute("alter table current_relation_members drop primary key, add primary key (id, member_type, member_id, member_role)")
+    alter_primary_key("current_relation_members", [:id, :member_type, :member_id, :member_role])
     remove_column :relation_members, :sequence_id
 
-    ActiveRecord::Base.connection().execute("alter table relation_members drop primary key, add primary key (id, version, member_type, member_id, member_role)")
+    alter_primary_key("relation_members", [:id, :version, :member_type, :member_id, :member_role])
     remove_column :current_relation_members, :sequence_id
   end
 end
index 38f8db6b3e28cd40e16e78a46088d7c24264c539..3b1e46fb8fb608f48b0be269a0533f0cc597122b 100644 (file)
@@ -38,7 +38,9 @@ module ActiveRecord
     end
 
     class MysqlAdapter
-      alias_method :old_native_database_types, :native_database_types
+      if MysqlAdapter.public_instance_methods(false).include?('native_database_types')
+        alias_method :old_native_database_types, :native_database_types
+      end
 
       def native_database_types
         types = old_native_database_types
@@ -78,7 +80,7 @@ module ActiveRecord
       def innodb_option
         return "ENGINE=InnoDB"
       end
+
       def change_engine (table_name, engine)
         execute "ALTER TABLE #{table_name} ENGINE = #{engine}"
       end
@@ -90,6 +92,60 @@ module ActiveRecord
       def alter_column_nwr_enum (table_name, column)
         execute "alter table #{table_name} change column #{column} #{column} enum('node','way','relation');"
       end
+
+      def alter_primary_key(table_name, new_columns)
+        execute("alter table #{table_name} drop primary key, add primary key (#{new_columns.join(',')})")
+      end
+    end
+
+    class PostgreSQLAdapter
+      if PostgreSQLAdapter.public_instance_methods(false).include?('native_database_types')
+        alias_method :old_native_database_types, :native_database_types
+      end
+
+      def native_database_types
+        types = old_native_database_types
+        types[:double] = { :name => "double precision" }
+        types[:bigint_pk] = { :name => "bigserial PRIMARY KEY" }
+        types[:bigint_pk_64] = { :name => "bigserial PRIMARY KEY" }
+        types[:bigint_auto_64] = { :name => "bigint" } #fixme: need autoincrement?
+        types[:bigint_auto_11] = { :name => "bigint" } #fixme: need autoincrement?
+        types[:bigint_auto_20] = { :name => "bigint" } #fixme: need autoincrement?
+        types[:four_byte_unsigned] = { :name => "bigint" } # meh
+        types
+      end
+
+      def myisam_table
+        return { :id => false, :force => true, :options => ""}
+      end
+
+      def innodb_table
+        return { :id => false, :force => true, :options => ""}
+      end
+
+      def innodb_option
+        return ""
+      end
+      def change_engine (table_name, engine)
+      end
+
+      def add_fulltext_index (table_name, column)
+        execute "CREATE INDEX #{table_name}_#{column}_idx on #{table_name} (#{column})"
+      end
+
+      def alter_column_nwr_enum (table_name, column)
+        response = select_one("select count(*) as count from pg_type where typname = 'nwr_enum'")
+        if response['count'] == "0" #yep, as a string
+          execute "create type nwr_enum as ENUM ('node', 'way', 'relation')"
+        end
+        execute        "alter table #{table_name} drop #{column}"
+        execute "alter table #{table_name} add #{column} nwr_enum"
+      end
+
+      def alter_primary_key(table_name, new_columns)
+        execute "alter table #{table_name} drop constraint #{table_name}_pkey; alter table #{table_name} add primary key (#{new_columns.join(',')})"
+      end
     end
   end
 end