aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2006-07-08 20:35:56 +0000
committerJeremy Kemper <jeremy@bitsweat.net>2006-07-08 20:35:56 +0000
commit2a12b56841bd6fd3998050e7677a1b2c08257479 (patch)
tree4fcd51578ac322228b2f6a44ce2344ab309992aa /activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb
parent71234daef1517cf190adfc5978e56882d2a57ea6 (diff)
downloadrails-2a12b56841bd6fd3998050e7677a1b2c08257479.tar.gz
rails-2a12b56841bd6fd3998050e7677a1b2c08257479.tar.bz2
rails-2a12b56841bd6fd3998050e7677a1b2c08257479.zip
r4704@asus: jeremy | 2006-06-27 12:00:19 -0700
decimal r4705@asus: jeremy | 2006-06-27 12:20:47 -0700 current_adapter? checks whether any of its arguments is the name of the current adapter class r4834@asus: jeremy | 2006-07-08 13:08:24 -0700 Room to float. r4835@asus: jeremy | 2006-07-08 13:09:18 -0700 Give lock test a few chances. r4836@asus: jeremy | 2006-07-08 13:12:05 -0700 Numeric and decimal columns map to BigDecimal instead of Float. Those with scale 0 map to Integer. Closes #5454. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4596 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb')
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb81
1 files changed, 36 insertions, 45 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb
index 2e1ac2350b..04a6443159 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb
@@ -1,5 +1,8 @@
require 'active_record/connection_adapters/abstract_adapter'
+require 'bigdecimal'
+require 'bigdecimal/util'
+
# sqlserver_adapter.rb -- ActiveRecord adapter for Microsoft SQL Server
#
# Author: Joey Gibson <joey@joeygibson.com>
@@ -45,45 +48,37 @@ module ActiveRecord
end # class Base
module ConnectionAdapters
- class ColumnWithIdentity < Column# :nodoc:
- attr_reader :identity, :is_special, :scale
+ class SQLServerColumn < Column# :nodoc:
+ attr_reader :identity, :is_special
- def initialize(name, default, sql_type = nil, is_identity = false, null = true, scale_value = 0)
+ def initialize(name, default, sql_type = nil, identity = false, null = true) # TODO: check ok to remove scale_value = 0
super(name, default, sql_type, null)
- @identity = is_identity
- @is_special = sql_type =~ /text|ntext|image/i ? true : false
- @scale = scale_value
+ @identity = identity
+ @is_special = sql_type =~ /text|ntext|image/i
+ # TODO: check ok to remove @scale = scale_value
# SQL Server only supports limits on *char and float types
@limit = nil unless @type == :float or @type == :string
end
def simplified_type(field_type)
case field_type
- when /int|bigint|smallint|tinyint/i then :integer
- when /float|double|decimal|money|numeric|real|smallmoney/i then @scale == 0 ? :integer : :float
- when /datetime|smalldatetime/i then :datetime
- when /timestamp/i then :timestamp
- when /time/i then :time
- when /text|ntext/i then :text
- when /binary|image|varbinary/i then :binary
- when /char|nchar|nvarchar|string|varchar/i then :string
- when /bit/i then :boolean
- when /uniqueidentifier/i then :string
+ when /money/i then :decimal
+ when /image/i then :binary
+ when /bit/i then :boolean
+ when /uniqueidentifier/i then :string
+ else super
end
end
def type_cast(value)
return nil if value.nil? || value =~ /^\s*null\s*$/i
case type
- when :string then value
- when :integer then value == true || value == false ? value == true ? 1 : 0 : value.to_i
- when :float then value.to_f
when :datetime then cast_to_datetime(value)
when :timestamp then cast_to_time(value)
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 value.to_s == '1'
- else value
+ else super
end
end
@@ -184,12 +179,13 @@ module ActiveRecord
:text => { :name => "text" },
:integer => { :name => "int" },
:float => { :name => "float", :limit => 8 },
+ :decimal => { :name => "decimal" },
:datetime => { :name => "datetime" },
:timestamp => { :name => "datetime" },
:time => { :name => "datetime" },
:date => { :name => "datetime" },
- :binary => { :name => "image"},
- :boolean => { :name => "bit"}
+ :binary => { :name => "image" },
+ :boolean => { :name => "bit" }
}
end
@@ -240,7 +236,16 @@ module ActiveRecord
return [] if table_name.blank?
table_name = table_name.to_s if table_name.is_a?(Symbol)
table_name = table_name.split('.')[-1] unless table_name.nil?
- sql = "SELECT COLUMN_NAME as ColName, COLUMN_DEFAULT as DefaultValue, DATA_TYPE as ColType, IS_NULLABLE As IsNullable, COL_LENGTH('#{table_name}', COLUMN_NAME) as Length, COLUMNPROPERTY(OBJECT_ID('#{table_name}'), COLUMN_NAME, 'IsIdentity') as IsIdentity, NUMERIC_SCALE as Scale FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '#{table_name}'"
+ sql = "SELECT COLUMN_NAME as ColName,
+ COLUMN_DEFAULT as DefaultValue,
+ DATA_TYPE as ColType,
+ IS_NULLABLE As IsNullable,
+ COL_LENGTH('#{table_name}', COLUMN_NAME) as Length,
+ COLUMNPROPERTY(OBJECT_ID('#{table_name}'), COLUMN_NAME, 'IsIdentity') as IsIdentity,
+ NUMERIC_PRECISION as [Precision],
+ NUMERIC_SCALE as Scale
+ FROM INFORMATION_SCHEMA.COLUMNS
+ WHERE TABLE_NAME = '#{table_name}'"
# Comment out if you want to have the Columns select statment logged.
# Personally, I think it adds unnecessary bloat to the log.
# If you do comment it out, make sure to un-comment the "result" line that follows
@@ -249,10 +254,14 @@ module ActiveRecord
columns = []
result.each do |field|
default = field[:DefaultValue].to_s.gsub!(/[()\']/,"") =~ /null/ ? nil : field[:DefaultValue]
- type = "#{field[:ColType]}(#{field[:Length]})"
+ if field[:ColType] =~ /numeric|decimal/i
+ type = "#{field[:ColType]}(#{field[:Precision]},#{field[:Scale]})"
+ else
+ type = "#{field[:ColType]}(#{field[:Length]})"
+ end
is_identity = field[:IsIdentity] == 1
is_nullable = field[:IsNullable] == 'YES'
- columns << ColumnWithIdentity.new(field[:ColName], default, type, is_identity, is_nullable, field[:Scale])
+ columns << SQLServerColumn.new(field[:ColName], default, type, is_identity, is_nullable)
end
columns
end
@@ -336,19 +345,10 @@ module ActiveRecord
return value.quoted_id if value.respond_to?(:quoted_id)
case value
- when String
- if column && column.type == :binary && column.class.respond_to?(:string_to_binary)
- "'#{quote_string(column.class.string_to_binary(value))}'"
- else
- "'#{quote_string(value)}'"
- end
- when NilClass then "NULL"
when TrueClass then '1'
when FalseClass then '0'
- when Float, Fixnum, Bignum then value.to_s
- when Date then "'#{value.to_s}'"
when Time, DateTime then "'#{value.strftime("%Y-%m-%d %H:%M:%S")}'"
- else "'#{quote_string(value.to_yaml)}'"
+ else super
end
end
@@ -459,7 +459,7 @@ module ActiveRecord
end
def change_column(table_name, column_name, type, options = {}) #:nodoc:
- sql_commands = ["ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit])}"]
+ sql_commands = ["ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"]
if options[:default]
remove_default_constraint(table_name, column_name)
sql_commands << "ALTER TABLE #{table_name} ADD CONSTRAINT DF_#{table_name}_#{column_name} DEFAULT #{options[:default]} FOR #{column_name}"
@@ -485,15 +485,6 @@ module ActiveRecord
execute "DROP INDEX #{table_name}.#{quote_column_name(index_name(table_name, options))}"
end
- def type_to_sql(type, limit = nil) #:nodoc:
- native = native_database_types[type]
- # if there's no :limit in the default type definition, assume that type doesn't support limits
- limit = limit || native[:limit]
- column_type_sql = native[:name]
- column_type_sql << "(#{limit})" if limit
- column_type_sql
- end
-
private
def select(sql, name = nil)
rows = []