require 'nera_database' require 'nera_simulator' module NERA # The parameter tables are accessed from this class class ParameterRecords # keys of the parameter table ATTRIBUTES_PART = [ [:id, Integer], [:created_at, DateTime], [:updated_at, DateTime], [:in_trashbox?, Symbol] ] # :active or :trashbox # NERA::Database object @db # attributes (keys) @keys attr_reader :keys # simulator_specific keys @sim_class # argument is the path to database file def initialize( db_file, sim_records, sim_id) unless sim_records.is_a?( NERA::SimulatorRecords) raise ArgumentError, "The second argument must be an instance of NERA::SimualtorRecords. #{sim_records.inspect}" end unless sim_id.is_a?(Integer) raise ArgumentError, "sim_id must be an Integer. : #{sim_id.inspect}" end @sim_class = sim_records.get_class( sim_id) @keys = ATTRIBUTES_PART.map do |k| k[0] end sim_keys = @sim_class::Parameters.map do |x| x[0] end found = @keys.find do |a| sim_keys.include?(a) end if found raise ArgumentError, "Invalid class. This class has a parameter : #{found}" end @keys += sim_keys @db = NERA::Database.new( db_file, sim_id) @db.add_observer( sim_records) end # argument is the path to parameters.yml def set_yaml_file( yaml_path) @db.set_yaml_file( yaml_path) end # if file already exists, return false def self.create_table( db_file, sim_class) unless sim_class.superclass == NERA::Simulator raise ArgumentError, "Given simulator class is not a subclass of NERA::Simulator : #{sim_class}" end ks = ATTRIBUTES_PART.map do |k| k[0] end params = sim_class::Parameters.map do |x| x[0] end found = ks.find do |a| params.include?(a) end if found raise ArgumentError, "Invalid class. This class has a parameter : #{found}" end NERA::Database.create_table( db_file) end # def add( param_hash) # check the argument unless param_hash.is_a?(Hash) raise ArgumentError, "Argument must be a Hash." end # check the argument sim_keys = @sim_class::Parameters.map do |x| x[0] end param_hash.each_pair do |param,value| unless sim_keys.include?(param) raise ArgumentError, "The given parameter set has unknown key." end a = @sim_class::Parameters.find do |p| p[0] == param end unless value.is_a?( a[1] ) raise ArgumentError, "The given parameter set has invalid type." end end # check duplication found = @db.find_all do |rec| f = true @sim_class::Parameters.each do |p| # set default values rec[ p[0] ] = p[2] if rec[ p[0] ] == nil param_hash[ p[0] ] = p[2] if param_hash[ p[0]] == nil unless rec[p[0]] == param_hash[p[0]] f = false break end end f end if found # the given parameter set already exists. return nil end # add a parameter d = DateTime.now h = {:created_at => d, :updated_at => d, :in_trashbox? => :active} ps = param_hash.dup @sim_class::Parameters.each do |p| ps[ p[0]] = p[3] if ps[p[0]] == nil end h.merge!( ps) @db.add(h) end def list_all list = @db.find_all do |r| true end return list.to_a end def list_active list = @db.find_all do |r| r[:in_trashbox?] == :active end return list.to_a end def list_trashbox list = @db.find_all do |r| r[:in_trashbox?] == :trashbox end return list.to_a end def find_by_id( id) @db.find_by_id( id) end def update_to_state_active( id) raise ArgumentError unless id.is_a?(Integer) found = @db.find_by_id( id) return nil unless found return nil if found[:in_trashbox?] == :active found[:in_trashbox?] = :active @db.update( found) end def update_to_state_trashbox( id) raise ArgumentError unless id.is_a?(Integer) found = @db.find_by_id( id) return nil unless found return nil if found[:in_trashbox?] == :trashbox found[:in_trashbox?] = :trashbox @db.update( found) end def touch( id) raise ArgumentError unless id.is_a?(Integer) found = @db.find_by_id( id) return nil unless found found[:updated_at] = DateTime.now @db.update( found) end alias :update :touch def destroy( id) raise ArgumentError unless id.is_a?(Integer) found = @db.find_by_id( id) return nil if found == nil or found[:in_trashbox?] == :active @db.destroy(id) end def transaction @db.transaction{ yield } end end end