Skip to content

Commit 6ed8417

Browse files
committed
Merge commit 'jrafanie/master'
2 parents 8c837d7 + fc08426 commit 6ed8417

File tree

1 file changed

+39
-23
lines changed

1 file changed

+39
-23
lines changed

lib/active_record/connection_adapters/sqlserver_adapter.rb

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def self.construct_finder_sql_for_association_limiting(options, join_dependency)
9292
module ConnectionAdapters
9393
class SQLServerColumn < Column# :nodoc:
9494
attr_reader :identity, :is_special, :is_utf8
95-
95+
9696
def initialize(info)
9797
if info[:type] =~ /numeric|decimal/i
9898
type = "#{info[:type]}(#{info[:numeric_precision]},#{info[:numeric_scale]})"
@@ -101,8 +101,13 @@ def initialize(info)
101101
end
102102
super(info[:name], info[:default_value], type, info[:is_nullable] == 1)
103103
@identity = info[:is_identity]
104+
105+
# TODO: Not sure if these should also be special: varbinary(max), nchar, nvarchar(max)
104106
@is_special = ["text", "ntext", "image"].include?(info[:type])
105-
@is_utf8 = type =~ /nvarchar|ntext/i
107+
108+
# Added nchar and nvarchar(max) for unicode types
109+
# http://www.teratrax.com/sql_guide/data_types/sql_server_data_types.html
110+
@is_utf8 = type =~ /nvarchar|ntext|nchar|nvarchar(max)/i
106111
# TODO: check ok to remove @scale = scale_value
107112
@limit = nil unless limitable?(type)
108113
end
@@ -148,22 +153,9 @@ def type_cast_code(var_name)
148153
class << self
149154
def cast_to_datetime(value)
150155
return value.to_time if value.is_a?(DBI::Timestamp)
151-
152-
if value.is_a?(Time)
153-
if value.year != 0 and value.month != 0 and value.day != 0
154-
return value
155-
else
156-
return new_time(2000, 1, 1, value.hour, value.min, value.sec) rescue nil
157-
end
158-
end
159-
160-
if value.is_a?(DateTime)
161-
return new_time(value.year, value.mon, value.mday, value.hour, value.min, value.sec)
162-
#return DateTime.new(value.year, value.mon, value.day, value.hour, value.min, value.sec)
163-
end
164-
156+
return string_to_time(value) if value.is_a?(Time)
157+
return string_to_time(value) if value.is_a?(DateTime)
165158
return cast_to_time(value) if value.is_a?(String)
166-
167159
value
168160
end
169161

@@ -174,10 +166,14 @@ def cast_to_time(value)
174166
new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction)) rescue nil
175167
end
176168

177-
# TODO: Find less hack way to convert DateTime objects into Times
178169
def string_to_time(value)
179-
if value.is_a?(DateTime)
180-
return new_time(value.year, value.mon, value.day, value.hour, value.min, value.sec)
170+
if value.is_a?(DateTime) || value.is_a?(Time)
171+
# The DateTime comes in as '2008-08-08T17:57:28+00:00'
172+
# Original code was taking a UTC DateTime, ignored the time zone by
173+
# creating a localized Time object, ex: 'FRI Aug 08 17:57:28 +04 2008'
174+
# Instead, let Time.parse translate the DateTime string including it's timezone
175+
# If Rails is UTC, call .utc, otherwise return a local time value
176+
return Base.default_timezone == :utc ? Time.parse(value.to_s).utc : Time.parse(value.to_s)
181177
else
182178
super
183179
end
@@ -250,20 +246,23 @@ def initialize(connection, logger, connection_options=nil)
250246
super(connection, logger)
251247
@connection_options = connection_options
252248
end
253-
249+
254250
def native_database_types
251+
# support for varchar(max) and varbinary(max) for text and binary cols if our version is 9 (2005)
252+
txt = database_version_major >= 9 ? "varchar(max)" : "text"
253+
bin = database_version_major >= 9 ? "varbinary(max)" : "image"
255254
{
256255
:primary_key => "int NOT NULL IDENTITY(1, 1) PRIMARY KEY",
257256
:string => { :name => "varchar", :limit => 255 },
258-
:text => { :name => "text" },
257+
:text => { :name => txt },
259258
:integer => { :name => "int" },
260259
:float => { :name => "float", :limit => 8 },
261260
:decimal => { :name => "decimal" },
262261
:datetime => { :name => "datetime" },
263262
:timestamp => { :name => "datetime" },
264263
:time => { :name => "datetime" },
265264
:date => { :name => "datetime" },
266-
:binary => { :name => "image"},
265+
:binary => { :name => bin },
267266
:boolean => { :name => "bit"}
268267
}
269268
end
@@ -272,6 +271,23 @@ def adapter_name
272271
'SQLServer'
273272
end
274273

274+
def database_version
275+
# returns string such as:
276+
# "Microsoft SQL Server 2000 - 8.00.2039 (Intel X86) \n\tMay 3 2005 23:18:38 \n\tCopyright (c) 1988-2003 Microsoft Corporation\n\tEnterprise Edition on Windows NT 5.2 (Build 3790: )\n"
277+
# "Microsoft SQL Server 2005 - 9.00.3215.00 (Intel X86) \n\tDec 8 2007 18:51:32 \n\tCopyright (c) 1988-2005 Microsoft Corporation\n\tStandard Edition on Windows NT 5.2 (Build 3790: Service Pack 2)\n"
278+
return select_value("SELECT @@version")
279+
end
280+
281+
def database_version_year
282+
# returns 2000 or 2005
283+
return $1.to_i if database_version =~ /(2000|2005) - (\d+)\./
284+
end
285+
286+
def database_version_major
287+
# returns 8 or 9
288+
return $2.to_i if database_version =~ /(2000|2005) - (\d+)\./
289+
end
290+
275291
def supports_migrations? #:nodoc:
276292
true
277293
end

0 commit comments

Comments
 (0)