Class: ActiveRecord::ConnectionAdapters::SQLServerColumn

Inherits:
Column
  • Object
show all
Defined in:
lib/active_record/connection_adapters/sqlserver_adapter.rb

Overview

:nodoc:

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(info) ⇒ SQLServerColumn

Returns a new instance of SQLServerColumn.



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 138

def initialize(info)
  if info[:type] =~ /numeric|decimal/i
    type = "#{info[:type]}(#{info[:numeric_precision]},#{info[:numeric_scale]})"
  else
    type = "#{info[:type]}(#{info[:length]})"
  end
  super(info[:name], info[:default_value], type, info[:is_nullable] == 1)
  @identity = info[:is_identity]
  
  # TODO: Not sure if these should also be special: varbinary(max), nchar, nvarchar(max) 
  @is_special = ["text", "ntext", "image"].include?(info[:type])

  # Added nchar and nvarchar(max) for unicode types
  #  http://www.teratrax.com/sql_guide/data_types/sql_server_data_types.html
  @is_utf8 = type =~ /nvarchar|ntext|nchar|nvarchar(max)/i
  # TODO: check ok to remove @scale = scale_value
  @limit = nil unless limitable?(type)
end

Instance Attribute Details

#identityObject (readonly)

Returns the value of attribute identity.



136
137
138
# File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 136

def identity
  @identity
end

#is_specialObject (readonly)

Returns the value of attribute is_special.



136
137
138
# File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 136

def is_special
  @is_special
end

#is_utf8Object (readonly)

Returns the value of attribute is_utf8.



136
137
138
# File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 136

def is_utf8
  @is_utf8
end

Class Method Details

.binary_to_string(value) ⇒ Object



233
234
235
236
237
238
239
# File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 233

def binary_to_string(value)
  # Check if the value actually is hex output from the database
  # or an Active Record attribute that was just written.  If hex, pack the hex
  # characters into a string, otherwise return the value
  # TODO: This conversion is asymmetrical, and could corrupt data if the original data looked like hex. We need to avoid the guesswork
  value =~ /[^[:xdigit:]]/ ? value : [value].pack('H*')
end

.cast_to_datetime(value) ⇒ Object



196
197
198
199
200
201
202
# File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 196

def cast_to_datetime(value)
  return value.to_time if value.is_a?(DBI::Timestamp)
  return string_to_time(value) if value.is_a?(Time)
  return string_to_time(value) if value.is_a?(DateTime)
  return cast_to_time(value) if value.is_a?(String)
  value
end

.cast_to_time(value) ⇒ Object



204
205
206
207
208
209
# File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 204

def cast_to_time(value)
  return value if value.is_a?(Time)
  time_hash = Date._parse(value)
  time_hash[:sec_fraction] = 0 # REVISIT: microseconds(time_hash)
  new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction)) rescue nil
end

.string_to_binary(value) ⇒ Object

To insert into a SQL server binary column, the value must be converted to hex characters and prepended with 0x Example: INSERT into varbinarytable values (0x0) See the output of the stored procedure: ‘exec sp_datatype_info’ and note the literal prefix value of 0x for binary types



229
230
231
# File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 229

def string_to_binary(value)
 "0x#{value.unpack("H*")[0]}"
end

.string_to_time(value) ⇒ Object



211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 211

def string_to_time(value)
  if value.is_a?(DateTime) || value.is_a?(Time)
    # The DateTime comes in as '2008-08-08T17:57:28+00:00'
    # Original code was taking a UTC DateTime, ignored the time zone by
    # creating a localized Time object,  ex: 'FRI Aug 08 17:57:28 +04 2008'
    # Instead, let Time.parse translate the DateTime string including it's timezone
    # If Rails is UTC, call .utc, otherwise return a local time value
    return Base.default_timezone == :utc ? Time.parse(value.to_s).utc : Time.parse(value.to_s)
  else
    super
  end
end

Instance Method Details

#limitable?(type) ⇒ Boolean

Returns:

  • (Boolean)


157
158
159
160
161
# File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 157

def limitable?(type)
  # SQL Server only supports limits on *char and float types
  # although for schema dumping purposes it's useful to know that (big|small)int are 2|8 respectively.
  @type == :float || @type == :string || (@type == :integer && type =~ /^(big|small)int/)
end

#simplified_type(field_type) ⇒ Object



163
164
165
166
167
168
169
170
171
172
# File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 163

def simplified_type(field_type)
  case field_type
    when /real/i              then :float
    when /money/i             then :decimal
    when /image/i             then :binary
    when /bit/i               then :boolean
    when /uniqueidentifier/i  then :string
    else super
  end
end

#type_cast(value) ⇒ Object



174
175
176
177
178
179
180
181
182
183
# File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 174

def type_cast(value)
  return nil if value.nil?
  case type
  when :datetime  then self.class.cast_to_datetime(value)
  when :timestamp then self.class.cast_to_time(value)
  when :time      then self.class.cast_to_time(value)
  when :date      then self.class.cast_to_datetime(value)
  else super
  end
end

#type_cast_code(var_name) ⇒ Object



185
186
187
188
189
190
191
192
193
# File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 185

def type_cast_code(var_name)
  case type
  when :datetime  then "#{self.class.name}.cast_to_datetime(#{var_name})"
  when :timestamp then "#{self.class.name}.cast_to_time(#{var_name})"
  when :time      then "#{self.class.name}.cast_to_time(#{var_name})"
  when :date      then "#{self.class.name}.cast_to_datetime(#{var_name})"
  else super
  end
end