lib/beso/job.rb in beso-0.0.1 vs lib/beso/job.rb in beso-0.1.0
- old
+ new
@@ -1,51 +1,94 @@
-require 'comma'
-
module Beso
class Job
- def initialize( name, options )
- @name = name.to_sym
+ def initialize( event, options )
+ @event = event.to_sym
@table = options.delete :table
+ @since = options.delete :since
@props = { }
+ @extra = options
end
+ attr_reader :event
- def prop( sym, *args, &block )
- # TODO this is weak, find a better way
- # to do what you mean to do
- args[ 0 ] = "Prop:#{args[ 0 ] || sym.to_s.titleize}"
+ def identity( value=nil, &block )
+ @identity = value || block
+ end
- @props[ sym.to_sym ] = [ args, block ]
+ def timestamp( value )
+ raise InvalidTimestampError unless value.is_a?(Symbol)
+ @timestamp = value
end
- def to_csv
- model_class.class_exec( event_title ) do |event|
- define_method( :event_title ) { event }
- end
+ def prop( name, value=nil, &block )
+ raise TooManyPropertiesError if @props.length == 10
+ @props[ name.to_sym ] = value || block || name.to_sym
+ end
- model_class.instance_exec( @name, @props ) do |name, props|
- comma name do
- id 'Identity'
- created_at 'Timestamp' do |m|
- m.to_i
- end
- event_title 'Event'
+ def to_csv( options={} )
+ raise MissingIdentityError if @identity.nil?
+ raise MissingTimestampError if @timestamp.nil?
- props.each do |sym, (args, block)|
- self.send sym, *args, &block
- end
+ @since ||= options.delete :since
+
+ relation = model_class.where( "#{@timestamp} >= ?", @since || first_timestamp )
+
+ return nil if relation.empty?
+
+ Beso::CSV.generate( @extra.merge( options ) ) do |csv|
+ csv << ( required_headers + custom_headers )
+
+ relation.each do |model|
+ csv << ( required_columns( model ) + custom_columns( model ) )
end
end
+ end
- model_class.all.to_comma @name
+ def first_timestamp
+ model_class.minimum @timestamp
end
+ def last_timestamp
+ model_class.maximum @timestamp
+ end
+
protected
+ def required_headers
+ %w| Identity Timestamp Event |
+ end
+
+ def custom_headers
+ @props.keys.map { |name| "Prop:#{name.to_s.titleize}" }
+ end
+
+ def required_columns( model )
+ [ ].tap do |row|
+ row << block_or_value( @identity, model )
+ row << model.send( @timestamp ).to_i
+ row << event_title
+ end
+ end
+
+ def custom_columns( model )
+ @props.values.map { |value| block_or_value( value, model ) }
+ end
+
def event_title
- @name.to_s.titleize
+ @event.to_s.titleize
end
def model_class
@table.to_s.classify.constantize
+ end
+
+ def block_or_value( value, model )
+ case value
+ when Symbol
+ model.send value
+ when Proc
+ value.call model
+ else
+ value
+ end
end
end
end