class SidList
Constants
- VERSION
Attributes
Creates a list of objects (jobs, instances, etc.) indexed by id & status
Creates a list of objects (jobs, instances, etc.) indexed by id & status
Public Class Methods
# File lib/sid_list.rb, line 7 def initialize @list_by_id = Array.new() @list_by_status = Hash.new() end
Public Instance Methods
# File lib/sid_list.rb, line 56 def [] id @list_by_id[id] end
# File lib/sid_list.rb, line 60 def add obj if obj.is_a? Hash obj = new_obj obj end @list_by_id[obj.id] = obj # Add obj by id # Add obj by status. ensure_status_in_list is called to make sure that the status # has an array in @list_by_status. ensure_status_in_list(obj.status) << obj return self end
@option opts [Symbol] :noforce @option opts [Symbol] :old_status
# File lib/sid_list.rb, line 116 def change_status obj, new_status, opts={} if obj.is_a? Fixnum id = obj obj = self.find(id).first end # Delete Object from old_status # If old_status is given, it's easily done. # Otherwise, the object's status must be check to see if it's not the new one (and supose it's the old one). # If the status has already been changed, the Object is looked for in @list_by_status. # # In any case, we will proceed to the next method if the Object is not found and deleted. # # Maybe it would be easier just to delete and re-add the Object, but the status may have already changed. deleted = nil # Using opts[:old_status] if opts[:old_status] if @list_by_status[opts[:old_status]].delete(obj) deleted = true end # Delete status in @list_by_status if it's empty # Useful if status hasn't been already changed. if @list_by_status[opts[:old_status]].length == 0 @list_by_status.delete opts[:old_status] end end # Using obj.status unless deleted || obj.status == new_status status = obj.status # puts obj.status if @list_by_status[status].delete(obj) deleted = true end # Delete status in @list_by_status if it's empty if @list_by_status[status].length == 0 @list_by_status.delete status end end # Search through @list_by_status unless deleted catch :deleted do @list_by_status.each do |status, status_list| if status_list.include? obj @list_by_status[status].delete obj deleted = true # Delete status in @list_by_status if it's empty if @list_by_status[status].length == 0 @list_by_status.delete status end throw :deleted end end end end # Force status, avoidable with :noforce obj.status = new_status unless obj.status == new_status || opts[:noforce] # Only add again if deleted? # Maybe should add anyway. Or be strict and just allow adding with #add ensure_status_in_list(new_status) << obj if deleted # Return nil if it has not been deleted (and therefore, not added). return deleted end
# File lib/sid_list.rb, line 198 def compact @list_by_id.compact end
# File lib/sid_list.rb, line 189 def count @list_by_id.compact.count end
@overload delete(obj)
Deletes an object from the list. @param [Object] obj Object to be deleted.
@overload delete(id)
Deletes an object from the list using its id. @param [Fixnum] id Object's id.
@todo revise first part to get an optimum algorithm.
# File lib/sid_list.rb, line 83 def delete value if value.is_a? Fixnum id = value obj = @list_by_id[value] else obj = value id = obj.id value = nil end @list_by_id.delete_at(id) @list_by_status[obj.status].delete obj return self end
Finds objecst in the list based on any of its accessible attributes. If only a Fixnum is passed, it will be interpreted as an id search. @note the Object must respond to obj#attribute(). @return [Array] Objects found.
@params values [Hash] Params. for search. @params values [Fixnum] Id.
# File lib/sid_list.rb, line 19 def find values found = Array.new if values.is_a? Fixnum return @list_by_id[values] # values = {:id => values} elsif !values.is_a? Hash raise ArgumentError, 'Argument must be a Hash or a Fixnum.' end @list_by_status.each do |status, status_list| status_list.each do |obj| # Catch is now acting as an AND condition. # Maybe it would be a good idea to do it an AND # @todo make OR condition available catch :not_equal do values.each do |term, value| if obj.send(term)!= value throw :not_equal end end found << obj end end end # if found.length == 1 # found = found.first # end # Return just an array, even if it's empty! return found end
# File lib/sid_list.rb, line 193 def first i = @list_by_id.find_index { |x| x } @list_by_id[i] end
# File lib/sid_list.rb, line 202 def list_status *values @list_by_status.each do |stat, arr| puts "#{stat}:" arr.each do |obj| print "\t [#{obj.id}]" values.each do |v| print "\t #{obj.send v}" if obj.respond_to? v end print "\n" end end return nil end
Loads objects into list. Objects must be able to receive data in initialization, i.e. Object.new(:name => '', :id => '', …)
# File lib/sid_list.rb, line 101 def load load_objs.each do |obj| add obj end end
@todo better time options @todo find a way to move adding here without cycling again
# File lib/sid_list.rb, line 109 def update opts={} time = opts[:time]? opts[:time] : Time.now#.utc update_objs time end
Private Instance Methods
Updates/Edits an object that already exists. @note Object must respond to the hash's keys. Otherwise an exception will be raised. @param obj_data [Hash] new values for the object. @return obj [Object] edited Object. @return obj [NilClass] nil if no Object was found to be edited.
# File lib/sid_list.rb, line 304 def edit_obj obj_data obj = @list_by_id[obj_data[:id]] if obj if obj.respond_to? 'update_with_hash' obj.update_with_hash obj_data else obj_data.each do |key,value| obj.send("#{key}=", value) if obj.respond_to? key end end end return obj end
Returns the list for a given status. If there is no such status in list, it is added (as a new array). It also defines the method #{status}, that calls all the objects with that status, if it hasn't been already been defined. @note if a status has the same name as any of the methods defined in the class, it wont be overwritten. @param status [Symbol]
# File lib/sid_list.rb, line 325 def ensure_status_in_list status unless @list_by_status[status].is_a? Array @list_by_status[status] = Array.new end if !(status.is_a? Symbol || status.is_a?(String)) raise "Object's status has no name (status #{status} was passed)." end unless self.respond_to?(status) self.class.send(:define_method, status) do @list_by_status[status] end end return @list_by_status[status] end
@return [Array] data to be loaded into list @note This method must be overwritten to configure the list.
# File lib/sid_list.rb, line 229 def load_data raise 'StatusList#load_hash() has not been overwritten to allow data to be loaded into the list.' return Array.new end
# File lib/sid_list.rb, line 254 def load_objs list_data = load_data() obj_array = Array.new() list_data.each do |obj_data| obj_array << new_obj(obj_data) end return obj_array end
@param obj_data [Hash] data to be loaded to the Object. @return [Object] new Object the list is composed of. @note This method must be overwritten to configure the list.
# File lib/sid_list.rb, line 250 def new_obj obj_data raise 'StatusList#new_obj(obj_data)has not been overwritten to allow new objects to be created.' end
@return [Array] values to be updated/added. Please see example to see how this hash should be. @example update_hash
's return
update_hash(now) # => [{:id => 1, ...}, ...]
@note This method must be overwritten to configure the list.
# File lib/sid_list.rb, line 240 def update_data time raise 'StatusList#update_hash() has not been overwritten to allow data in the list to be updated.' return Array.new end
Uses update_hash
to get all objects to be added or edited. @since 0.0.4 no longer need :updated and :created @param time [Time] time to pass to update_hash
in order to get new changes.
# File lib/sid_list.rb, line 269 def update_objs time list_data = update_data(time) # @note the update can be taken care of in update_data if it returns nil. if list_data created_obj_array = Array.new() updated_obj_array = Array.new() list_data.each do |obj_data| if find obj_data[:id] edit_obj obj_data else add new_obj obj_data end end end # if list_data[:created] # list_data[:created].each do |obj_data| # add new_obj obj_data # end # end # if list_data[:updated] # list_data[:updated].each do |obj_data| # edit_obj obj_data # end # end end