Title: [461] trunk/activerecord-jdbc/lib/jdbc_adapter: Make remove_column work correctly on Derby
Revision
461
Author
olabini
Date
2007-04-18 13:29:31 -0400 (Wed, 18 Apr 2007)

Log Message

Make remove_column work correctly on Derby

Modified Paths


Added Paths

Diff

Modified: trunk/activerecord-jdbc/lib/jdbc_adapter/jdbc_derby.rb (460 => 461)


--- trunk/activerecord-jdbc/lib/jdbc_adapter/jdbc_derby.rb	2007-04-18 16:13:32 UTC (rev 460)
+++ trunk/activerecord-jdbc/lib/jdbc_adapter/jdbc_derby.rb	2007-04-18 17:29:31 UTC (rev 461)
@@ -1,3 +1,5 @@
+require 'jdbc_adapter/missing_functionality_helper'
+
 module JdbcSpec
   module Derby
     module Column
@@ -34,6 +36,8 @@
       end
     end
 
+    include JdbcSpec::MissingFunctionalityHelper
+    
     def modify_types(tp)
       tp[:primary_key] = "int generated by default as identity NOT NULL PRIMARY KEY"
       tp[:integer][:limit] = nil
@@ -70,6 +74,10 @@
       @limit = @offset = nil
     end
 
+    def primary_key(table_name) #:nodoc:
+      primary_keys(table_name).first
+    end
+
     def remove_index(table_name, options) #:nodoc:
       execute "DROP INDEX #{index_name(table_name, options)}"
     end
@@ -87,7 +95,10 @@
       begin
         execute "ALTER TABLE #{table_name} DROP COLUMN #{column_name} RESTRICT"
       rescue
-        raise NotImplementedError, "remove_column is not support on this Derby version"
+        alter_table(table_name) do |definition|
+          definition.columns.delete(definition[column_name])
+        end
+#        raise NotImplementedError, "remove_column is not support on this Derby version"
       end
     end
     

Added: trunk/activerecord-jdbc/lib/jdbc_adapter/missing_functionality_helper.rb (0 => 461)


--- trunk/activerecord-jdbc/lib/jdbc_adapter/missing_functionality_helper.rb	                        (rev 0)
+++ trunk/activerecord-jdbc/lib/jdbc_adapter/missing_functionality_helper.rb	2007-04-18 17:29:31 UTC (rev 461)
@@ -0,0 +1,71 @@
+module JdbcSpec
+  module MissingFunctionalityHelper
+    #Taken from SQLite adapter
+
+    def alter_table(table_name, options = {}) #:nodoc:
+      altered_table_name = "altered_#{table_name}"
+      caller = lambda {|definition| yield definition if block_given?}
+
+      transaction do
+        move_table(table_name, altered_table_name)
+        move_table(altered_table_name, table_name, &caller)
+      end
+    end
+    
+    def move_table(from, to, options = {}, &block) #:nodoc:
+      copy_table(from, to, options, &block)
+      drop_table(from)
+    end
+
+    def copy_table(from, to, options = {}) #:nodoc:
+      create_table(to, options) do |@definition|
+        columns(from).each do |column|
+          column_name = options[:rename] ?
+          (options[:rename][column.name] ||
+           options[:rename][column.name.to_sym] ||
+           column.name) : column.name
+
+          @definition.column(column_name, column.type, 
+                             :limit => column.limit, :default => column.default,
+                             :null => column.null)
+        end
+        @definition.primary_key(primary_key(from))
+        yield @definition if block_given?
+      end
+      
+      copy_table_indexes(from, to)
+      copy_table_contents(from, to, 
+                          @definition.columns.map {|column| column.name}, 
+                          options[:rename] || {})
+    end
+    
+    def copy_table_indexes(from, to) #:nodoc:
+      indexes(from).each do |index|
+        name = index.name
+        if to == "altered_#{from}"
+          name = "temp_#{name}"
+        elsif from == "altered_#{to}"
+          name = name[5..-1]
+        end
+        
+        # index name can't be the same
+        opts = { :name => name.gsub(/_(#{from})_/, "_#{to}_") }
+        opts[:unique] = true if index.unique
+        add_index(to, index.columns, opts)
+      end
+    end
+    
+    def copy_table_contents(from, to, columns, rename = {}) #:nodoc:
+      column_mappings = Hash[*columns.map {|name| [name, name]}.flatten]
+      rename.inject(column_mappings) {|map, a| map[a.last] = a.first; map}
+      from_columns = columns(from).collect {|col| col.name}
+      columns = columns.find_all{|col| from_columns.include?(column_mappings[col])}
+      execute("SELECT * FROM #{from}").each do |row|
+        sql = "INSERT INTO #{to} ("+columns*','+") VALUES ("            
+        sql << columns.map {|col| quote row[column_mappings[col]]} * ', '
+        sql << ')'
+        execute sql
+      end
+    end
+  end
+end
_______________________________________________
Jruby-extras-devel mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/jruby-extras-devel

Reply via email to