Title: [755] trunk/activerecord-jdbc/lib/jdbc_adapter/jdbc_mssql.rb: Improve MsSQL by fixing some of the migration stuff
Revision
755
Author
olabini
Date
2007-09-27 06:49:06 -0400 (Thu, 27 Sep 2007)

Log Message

Improve MsSQL by fixing some of the migration stuff

Modified Paths


Diff

Modified: trunk/activerecord-jdbc/lib/jdbc_adapter/jdbc_mssql.rb (754 => 755)


--- trunk/activerecord-jdbc/lib/jdbc_adapter/jdbc_mssql.rb	2007-09-27 09:25:15 UTC (rev 754)
+++ trunk/activerecord-jdbc/lib/jdbc_adapter/jdbc_mssql.rb	2007-09-27 10:49:06 UTC (rev 755)
@@ -1,3 +1,22 @@
+module ::ActiveRecord
+  class Base
+    # After setting large objects to empty, write data back with a helper method
+    after_save :write_lobs
+    def write_lobs() #:nodoc:
+      if connection.is_a?(JdbcSpec::MsSQL)
+        self.class.columns.select { |c| c.sql_type =~ /image/i }.each { |c|
+          value = self[c.name]
+          value = value.to_yaml if unserializable_attribute?(c.name, c)
+          next if value.nil?  || (value == '')
+
+          connection.write_large_object(c.type == :binary, c.name, self.class.table_name, self.class.primary_key, quote_value(id), value)
+        }
+      end
+    end
+    private :write_lobs
+  end
+end
+
 module JdbcSpec
   module MsSQL
     def self.column_selector
@@ -38,7 +57,7 @@
         when :time      then cast_to_time(value)
         when :date      then cast_to_datetime(value)
         when :boolean   then value == true or (value =~ /^t(rue)?$/i) == 0 or unquote(value)=="1"
-        when :binary    then unquote value
+        when :binary    then value
         else value
         end
       end
@@ -71,26 +90,8 @@
       # These methods will only allow the adapter to insert binary data with a length of 7K or less
       # because of a SQL Server statement length policy.
       def self.string_to_binary(value)
-        value.gsub(/(\r|\n|\0|\x1a)/) do
-          case $1
-            when "\r"   then  "%00"
-            when "\n"   then  "%01"
-            when "\0"   then  "%02"
-            when "\x1a" then  "%03"
-          end
-        end
+        ''
       end
-
-      def self.binary_to_string(value)
-        value.gsub(/(%00|%01|%02|%03)/) do
-          case $1
-            when "%00"    then  "\r"
-            when "%01"    then  "\n"
-            when "%02\0"  then  "\0"
-            when "%03"    then  "\x1a"
-          end
-        end
-      end
     end
     
     def modify_types(tp)
@@ -105,6 +106,16 @@
       return value.quoted_id if value.respond_to?(:quoted_id)
 
       case value
+      when String, ActiveSupport::Multibyte::Chars
+        value = value.to_s
+        if column && column.type == :binary
+          "'#{quote_string(JdbcSpec::MsSQL::Column.string_to_binary(value))}'" # ' (for ruby-mode)
+        elsif column && [:integer, :float].include?(column.type)
+          value = column.type == :integer ? value.to_i : value.to_f
+          value.to_s
+        else
+          "'#{quote_string(value)}'" # ' (for ruby-mode)
+        end
         when TrueClass             then '1'
         when FalseClass            then '0'
         when Time, DateTime        then "'#{value.strftime("%Y%m%d %H:%M:%S")}'"
@@ -181,6 +192,16 @@
         execute "EXEC sp_rename '#{name}', '#{new_name}'"
       end
       
+      # Adds a new column to the named table.
+      # See TableDefinition#column for details of the options you can use.
+      def add_column(table_name, column_name, type, options = {})
+        add_column_sql = "ALTER TABLE #{table_name} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
+        add_column_options!(add_column_sql, options)
+        # TODO: Add support to mimic date columns, using constraints to mark them as such in the database
+        # add_column_sql << " CONSTRAINT ck__#{table_name}__#{column_name}__date_only CHECK ( CONVERT(CHAR(12), #{quote_column_name(column_name)}, 14)='00:00:00:000' )" if type == :date       
+        execute(add_column_sql)
+      end
+
       def rename_column(table, column, new_column_name)
         execute "EXEC sp_rename '#{table}.#{column}', '#{new_column_name}'"
       end
@@ -213,8 +234,9 @@
         execute "ALTER TABLE #{table_name} ADD CONSTRAINT DF_#{table_name}_#{column_name} DEFAULT #{quote(default, column_name)} FOR #{column_name}"
       end
       def remove_column(table_name, column_name)
+        remove_check_constraints(table_name, column_name)
         remove_default_constraint(table_name, column_name)
-        execute "ALTER TABLE #{table_name} DROP COLUMN #{column_name}"
+        execute "ALTER TABLE #{table_name} DROP COLUMN [#{column_name}]"
       end
       
       def remove_default_constraint(table_name, column_name)
@@ -223,6 +245,14 @@
           execute "ALTER TABLE #{table_name} DROP CONSTRAINT #{constraint["name"]}"
         }
       end
+
+      def remove_check_constraints(table_name, column_name)
+        # TODO remove all constraints in single method
+        constraints = select "SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE where TABLE_NAME = '#{table_name}' and COLUMN_NAME = '#{column_name}'"
+        constraints.each do |constraint|
+          execute "ALTER TABLE #{table_name} DROP CONSTRAINT #{constraint["CONSTRAINT_NAME"]}"
+        end
+      end
       
       def remove_index(table_name, options = {})
         execute "DROP INDEX #{table_name}.#{index_name(table_name, options)}"
_______________________________________________
Jruby-extras-devel mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/jruby-extras-devel

Reply via email to