diff options
author | Carl Lerche <carllerche@mac.com> | 2010-03-12 12:51:20 -0800 |
---|---|---|
committer | Carl Lerche <carllerche@mac.com> | 2010-03-12 12:52:07 -0800 |
commit | 83c27c0b5e2e341307b7a160d831fb930a9552b4 (patch) | |
tree | fc41004d425cbc9827e82f550959ed40e8c12978 /lib/arel/algebra | |
parent | 602722922c8365afcb3e9bed3721d61756322353 (diff) | |
download | rails-83c27c0b5e2e341307b7a160d831fb930a9552b4.tar.gz rails-83c27c0b5e2e341307b7a160d831fb930a9552b4.tar.bz2 rails-83c27c0b5e2e341307b7a160d831fb930a9552b4.zip |
Attributes should be typed
Diffstat (limited to 'lib/arel/algebra')
-rw-r--r-- | lib/arel/algebra/attributes.rb | 7 | ||||
-rw-r--r-- | lib/arel/algebra/attributes/attribute.rb (renamed from lib/arel/algebra/attribute.rb) | 31 | ||||
-rw-r--r-- | lib/arel/algebra/attributes/boolean.rb | 20 | ||||
-rw-r--r-- | lib/arel/algebra/attributes/decimal.rb | 9 | ||||
-rw-r--r-- | lib/arel/algebra/attributes/float.rb | 9 | ||||
-rw-r--r-- | lib/arel/algebra/attributes/integer.rb | 10 | ||||
-rw-r--r-- | lib/arel/algebra/attributes/string.rb | 10 | ||||
-rw-r--r-- | lib/arel/algebra/attributes/time.rb | 6 |
8 files changed, 102 insertions, 0 deletions
diff --git a/lib/arel/algebra/attributes.rb b/lib/arel/algebra/attributes.rb new file mode 100644 index 0000000000..98302b6b18 --- /dev/null +++ b/lib/arel/algebra/attributes.rb @@ -0,0 +1,7 @@ +require "arel/algebra/attributes/attribute" +require "arel/algebra/attributes/boolean" +require "arel/algebra/attributes/decimal" +require "arel/algebra/attributes/float" +require "arel/algebra/attributes/integer" +require "arel/algebra/attributes/string" +require "arel/algebra/attributes/time"
\ No newline at end of file diff --git a/lib/arel/algebra/attribute.rb b/lib/arel/algebra/attributes/attribute.rb index 40a7d61a53..f4cec828e3 100644 --- a/lib/arel/algebra/attribute.rb +++ b/lib/arel/algebra/attributes/attribute.rb @@ -1,6 +1,7 @@ require 'set' module Arel + class TypecastError < StandardError ; end class Attribute attributes :relation, :name, :alias, :ancestor deriving :== @@ -146,5 +147,35 @@ module Arel alias_method :to_ordering, :asc end include Orderings + + module Types + def type_cast(value) + if root == self + raise NotImplementedError, "#type_cast should be implemented in a subclass." + else + root.type_cast(value) + end + end + + def type_cast_to_numeric(value, method) + return unless value + if value.respond_to?(:to_str) + if value.to_str =~ /\A(-?(?:0|[1-9]\d*)(?:\.\d+)?|(?:\.\d+))\z/ + $1.send(method) + else + value + end + elsif value.respond_to?(method) + value.send(method) + else + raise typecast_error(value) + end + end + + def typecast_error(value) + raise TypecastError, "could not typecast #{value.inspect} to #{self.class.name.split('::').last}" + end + end + include Types end end diff --git a/lib/arel/algebra/attributes/boolean.rb b/lib/arel/algebra/attributes/boolean.rb new file mode 100644 index 0000000000..0ca7cd6d24 --- /dev/null +++ b/lib/arel/algebra/attributes/boolean.rb @@ -0,0 +1,20 @@ +module Arel + module Attributes + class Boolean < Attribute + def type_cast(value) + case value + when true, false then value + when nil then options[:allow_nil] ? nil : false + when 1 then true + when 0 then false + else + case value.to_s.downcase.strip + when 'true' then true + when 'false' then false + else raise typecast_error(value) + end + end + end + end + end +end diff --git a/lib/arel/algebra/attributes/decimal.rb b/lib/arel/algebra/attributes/decimal.rb new file mode 100644 index 0000000000..bf6587fa34 --- /dev/null +++ b/lib/arel/algebra/attributes/decimal.rb @@ -0,0 +1,9 @@ +module Arel + module Attributes + class Decimal < Attribute + def type_cast(val) + type_cast_to_numeric(val, :to_d) + end + end + end +end diff --git a/lib/arel/algebra/attributes/float.rb b/lib/arel/algebra/attributes/float.rb new file mode 100644 index 0000000000..01c95e69f9 --- /dev/null +++ b/lib/arel/algebra/attributes/float.rb @@ -0,0 +1,9 @@ +module Arel + module Attributes + class Float < Attribute + def type_cast(val) + type_cast_to_numeric(val, :to_f) + end + end + end +end diff --git a/lib/arel/algebra/attributes/integer.rb b/lib/arel/algebra/attributes/integer.rb new file mode 100644 index 0000000000..9a564565ff --- /dev/null +++ b/lib/arel/algebra/attributes/integer.rb @@ -0,0 +1,10 @@ +module Arel + module Attributes + class Integer < Attribute + def type_cast(val) + type_cast_to_numeric(val, :to_i) + end + end + end +end +
\ No newline at end of file diff --git a/lib/arel/algebra/attributes/string.rb b/lib/arel/algebra/attributes/string.rb new file mode 100644 index 0000000000..5ea91a59d8 --- /dev/null +++ b/lib/arel/algebra/attributes/string.rb @@ -0,0 +1,10 @@ +module Arel + module Attributes + class String < Attribute + def type_cast(value) + return unless value + value.to_s + end + end + end +end diff --git a/lib/arel/algebra/attributes/time.rb b/lib/arel/algebra/attributes/time.rb new file mode 100644 index 0000000000..7a2de726c8 --- /dev/null +++ b/lib/arel/algebra/attributes/time.rb @@ -0,0 +1,6 @@ +module Arel + module Attributes + class Time < Attribute + end + end +end |