Module: DataMapper::Adapters::Sql::Coersion

Defined in:
lib/data_mapper/adapters/sql/coersion.rb

Overview

Coersion is a mixin that allows for coercing database values to Ruby Types.

DESIGN: Probably should handle the opposite scenario here too. I believe that’s currently in DataMapper::Database, which is obviously not a very good spot for it.

Defined Under Namespace

Classes: CoersionError

Constant Summary collapse

TRUE_ALIASES =
['true'.freeze, 'TRUE'.freeze, '1'.freeze, 1]
FALSE_ALIASES =
[nil, '0'.freeze, 0]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



20
21
22
23
# File 'lib/data_mapper/adapters/sql/coersion.rb', line 20

def self.included(base)
  base.const_set('TRUE_ALIASES', TRUE_ALIASES.dup)
  base.const_set('FALSE_ALIASES', FALSE_ALIASES.dup)
end

Instance Method Details

#type_cast_boolean(raw_value) ⇒ Object



25
26
27
28
29
30
31
32
# File 'lib/data_mapper/adapters/sql/coersion.rb', line 25

def type_cast_boolean(raw_value)
  case raw_value
    when TrueClass, FalseClass then raw_value
    when *self::class::TRUE_ALIASES then true
    when *self::class::FALSE_ALIASES then false
    else "Can't type-cast #{raw_value.inspect} to a boolean"
  end
end

#type_cast_class(raw_value) ⇒ Object



46
47
48
49
# File 'lib/data_mapper/adapters/sql/coersion.rb', line 46

def type_cast_class(raw_value)
  return nil if raw_value.blank?
  Kernel::const_get(raw_value)
end

#type_cast_date(raw_value) ⇒ Object



86
87
88
89
90
91
92
93
94
95
# File 'lib/data_mapper/adapters/sql/coersion.rb', line 86

def type_cast_date(raw_value)
  return nil if raw_value.blank?
  
  case raw_value
    when Date then raw_value
    when DateTime, Time then Date::civil(raw_value.year, raw_value.month, raw_value.day)
    when String then Date::parse(raw_value)
    else raise CoersionError.new("Can't type-cast #{raw_value.inspect} to a date")
  end
end

#type_cast_datetime(raw_value) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/data_mapper/adapters/sql/coersion.rb', line 74

def type_cast_datetime(raw_value)
  return nil if raw_value.blank?
  
  case raw_value
    when "0000-00-00 00:00:00" then nil
    when DateTime then raw_value
    when Date then DateTime.new(raw_value) rescue nil
    when String then DateTime::parse(raw_value) rescue nil
    else raise CoersionError.new("Can't type-cast #{raw_value.inspect} to a datetime")
  end
end

#type_cast_decimal(raw_value) ⇒ Object



58
59
60
61
62
63
# File 'lib/data_mapper/adapters/sql/coersion.rb', line 58

def type_cast_decimal(raw_value)
  return nil if raw_value.blank?
  raw_value.to_d
rescue ArgumentError 
  nil 
end

#type_cast_float(raw_value) ⇒ Object



65
66
67
68
69
70
71
72
# File 'lib/data_mapper/adapters/sql/coersion.rb', line 65

def type_cast_float(raw_value)
  return nil if raw_value.blank?
  case raw_value
    when Float then raw_value
    when Numeric, String then raw_value.to_f
    else CoersionError.new("Can't type-cast #{raw_value.inspect} to a float")
  end
end

#type_cast_integer(raw_value) ⇒ Object



51
52
53
54
55
56
# File 'lib/data_mapper/adapters/sql/coersion.rb', line 51

def type_cast_integer(raw_value)
  return nil if raw_value.blank?
  raw_value.to_i
rescue ArgumentError
  nil
end

#type_cast_object(raw_value) ⇒ Object



97
98
99
100
101
102
103
104
105
# File 'lib/data_mapper/adapters/sql/coersion.rb', line 97

def type_cast_object(raw_value)
  return nil if raw_value.blank?

  begin
    YAML.load(raw_value)
  rescue
    raise CoersionError.new("Can't type-cast #{raw_value.inspect} to an object")
  end
end

#type_cast_string(raw_value) ⇒ Object



34
35
36
37
38
# File 'lib/data_mapper/adapters/sql/coersion.rb', line 34

def type_cast_string(raw_value)
  return nil if raw_value.blank?
  # type-cast values should be immutable for memory conservation
  raw_value
end

#type_cast_text(raw_value) ⇒ Object



40
41
42
43
44
# File 'lib/data_mapper/adapters/sql/coersion.rb', line 40

def type_cast_text(raw_value)
  return nil if raw_value.blank?
  # type-cast values should be immutable for memory conservation
  raw_value
end

#type_cast_value(type, raw_value) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/data_mapper/adapters/sql/coersion.rb', line 107

def type_cast_value(type, raw_value)
  return nil if raw_value.blank?
  
  case type
  when :string then type_cast_string(raw_value)
  when :text then type_cast_text(raw_value)
  when :boolean then type_cast_boolean(raw_value)
  when :class then type_cast_class(raw_value)
  when :integer then type_cast_integer(raw_value)
  when :decimal then type_cast_decimal(raw_value)
  when :float then type_cast_float(raw_value)
  when :datetime then type_cast_datetime(raw_value)
  when :date then type_cast_date(raw_value)
  when :object then type_cast_object(raw_value)
  else
    if respond_to?("type_cast_#{type}")
      send("type_cast_#{type}", raw_value)
    else
      raise "Don't know how to type-cast #{{ type => raw_value }.inspect }"
    end
  end
end