lib/remi/transform.rb in remi-0.2.39 vs lib/remi/transform.rb in remi-0.2.40
- old
+ new
@@ -216,10 +216,11 @@
# Public: Parses a string and converts it to a date.
# This transform is metadata aware and will use :in_format metadata
# from the source
#
+ # type - Specify either :date, or :datetime type (default: date)
# in_format - The date format to use to convert the string (default: uses :in_format
# from the source metadata. If that is not defined, use '%Y-%m-%d').
# if_blank - Value to use if the the incoming value is blank (default: uses :if_blank
# from the source metadata. If that is not defined, use nil). If set to
# :high, then use the largest date, if set to :ow, use the lowest date.
@@ -230,24 +231,37 @@
#
# tform = ParseDate.new
# tform.source_metadata = { in_format: '%m/%d/%Y' }
# tform.to_proc.call('02/22/2013') # => Date.new(2013,2,22)
class ParseDate < Transform
- def initialize(*args, in_format: nil, if_blank: nil, **kargs, &block)
+ def initialize(*args, type: nil, in_format: nil, if_blank: nil, **kargs, &block)
super
+ @type = type
@in_format = in_format
@if_blank = if_blank
end
+ def type
+ @type ||= @source_metadata.fetch(:type, :date)
+ end
+
def in_format
- @in_format ||= @source_metadata.fetch(:in_format, '%Y-%m-%d')
+ @in_format ||= @source_metadata.fetch(:in_format, default_date_format)
end
def if_blank
@if_blank ||= @source_metadata.fetch(:if_blank, nil)
end
+ def default_date_format
+ if type == :datetime
+ '%Y-%m-%d %H:%M:%S'
+ else
+ '%Y-%m-%d'
+ end
+ end
+
def transform(value)
begin
if value.respond_to?(:strftime)
value
elsif value.blank? then
@@ -258,19 +272,23 @@
rescue ArgumentError => err
raise err, "Error parsing date (#{value.class}): '#{value}' with format #{in_format})"
end
end
+ def class_type
+ @class_type ||= type == :datetime ? Time : Date
+ end
+
def string_to_date(value)
- Date.strptime(value, in_format)
+ class_type.strptime(value, in_format)
end
def blank_handler(value)
if if_blank == :low
- Date.new(1900,01,01)
+ class_type.new(1900,01,01)
elsif if_blank == :high
- Date.new(2999,12,31)
+ class_type.new(2999,12,31)
elsif if_blank.respond_to? :call
if_blank.call(value)
else
if_blank
end
@@ -280,10 +298,11 @@
# Public: (Re)formats a date.
# This transform is metadata aware and will use :in_format/:out_format metadata
# from the source.
#
+ # type - Specify either :date, or :datetime type (default: date)
# in_format - The date format to used to parse the input value. If the input value
# is a date, then then parameter is ignored. (default: uses :in_format
# from the source metadata. If that is not defined, use '%Y-%m-%d')
# out_format - The date format applied to provide the resulting string. (default:
# uses :out_format from the source metadata. If that is not defined,
@@ -295,32 +314,49 @@
#
# tform = FormatDate.new
# tform.source_metadata = { in_format: '%m/%d/%Y', out_format: '%Y-%m-%d' }
# tform.to_proc.call('02/22/2013') # => "2013-02-22"
class FormatDate < Transform
- def initialize(*args, in_format: nil, out_format: nil, **kargs, &block)
+ def initialize(*args, type: nil, in_format: nil, out_format: nil, **kargs, &block)
super
+ @type = type
@in_format = in_format
@out_format = out_format
end
+ def type
+ @type ||= @source_metadata.fetch(:type, :date)
+ end
+
def in_format
- @in_format ||= @source_metadata.fetch(:in_format, '%Y-%m-%d')
+ @in_format ||= @source_metadata.fetch(:in_format, default_date_format)
end
def out_format
- @out_format ||= @source_metadata.fetch(:out_format, '%Y-%m-%d')
+ @out_format ||= @source_metadata.fetch(:out_format, default_date_format)
end
+ def default_date_format
+ if type == :datetime
+ '%Y-%m-%d %H:%M:%S'
+ else
+ '%Y-%m-%d'
+ end
+ end
+
+ def class_type
+ @class_type ||= type == :datetime ? Time : Date
+ end
+
def transform(value)
begin
if value.blank? then
''
elsif value.respond_to? :strftime
value.strftime(out_format)
else
- Date.strptime(value, in_format).strftime(out_format)
+ class_type.strptime(value, in_format).strftime(out_format)
end
rescue ArgumentError => err
raise err, "Error parsing date (#{value.class}): '#{value}' using the format #{in_format} => #{out_format}"
end
end
@@ -459,11 +495,11 @@
end
def if_blank
return @if_blank if @if_blank_set
@if_blank_set = true
- @if_blank = @source_metadata.fetch(:if_blank, nil)
+ @if_blank = @source_metadata.fetch(:if_blank, default_if_blank)
end
def blank_handler(value)
return value unless value.blank?
@@ -472,12 +508,16 @@
else
if_blank
end
end
+ def default_if_blank
+ type == :string ? '' : nil
+ end
+
def transform(value)
- if value.blank?
+ if value.blank? && type != :json
blank_handler(value)
else
case type
when :string
value
@@ -486,12 +526,18 @@
when :float
Float(value)
when :decimal
Float("%.#{scale}f" % Float(value))
when :date
- value.is_a?(Date) ? value : Date.strptime(value, in_format) # value.is_a?(Date) is only needed becuase we stub date types with actual dates, rather than strings like we probably should
+ value.is_a?(Date) ? value : Date.strptime(value, in_format)
when :datetime
- Time.strptime(value, in_format)
+ value.is_a?(Time) ? value : Time.strptime(value, in_format)
+ when :json
+ if value.blank? && value != [] && value != {}
+ blank_handler(value)
+ else
+ value.is_a?(Hash) || value.is_a?(Array) ? value : JSON.parse(value)
+ end
else
raise ArgumentError, "Unknown type enforcement: #{type}"
end
end
end