class Flextures::Loader

data loader

Constants

COMPLETER

column set default value

FORMATS
PARENT

base configurations





TRANSLATER

colum data translate

Public Class Methods

cache?(params) click to toggle source
# File lib/flextures/flextures_loader.rb, line 136
def self.cache?(params)
  return unless params.first.is_a?(Hash)

  param = params.first
  param[:cache] == true
end
create_filter(klass, factory, filename, ext, options) click to toggle source

return flextures data translate filter translate filter is some functions

  1. column value is fill, if colum is not nullable

  2. factory filter

@params [ActiveRecord::Base] klass ActiveRecord model data @params [Proc] factory FactoryFilter @params [String] filename @params [Symbol] ext file type (:csv or :yml) @params [Hash] options other options @return [Proc] translate filter

# File lib/flextures/flextures_loader.rb, line 367
def self.create_filter(klass, factory, filename, ext, options)
  columns = klass.columns
  # data translate array to hash
  column_hash = columns.reduce({}) { |h,col| h[col.name] = col; h }
  translaters = column_hash.reduce({}){ |h,(k,col)| h[k] = col.translater(klass); h }
  strict_filter = ->(o,h){
    # if value is not 'nil', value translate suitable form
    h.each { |k,v| v.nil? || o[k] = translaters[k]&.call(v) }
    # call FactoryFilter
    factory.call(*[o, filename, ext][0, factory.arity]) if factory and !options[:unfilter]
    o
  }

  return strict_filter if options[:strict]==true

  lack_columns = columns.reject { |c| c.null and c.default }.map{ |o| o.name.to_sym }
  # default value shound not be null columns
  not_nullable_columns = columns.reject(&:null).map(&:name)
  completers = column_hash.reduce({}){ |h,(k,col)| h[k] = col.completer(klass); h }
  # receives hased data and translate ActiveRecord Model data
  # loose filter correct error values
  # strict filter don't correct errora values and raise error
  loose_filter = ->(o,h){
    h.reject! { |k,v| options[:minus].include?(k) } if options[:minus]
    # if column name is not include database table columns, those names delete
    h.select! { |k,v| column_hash[k] }
    strict_filter.call(o,h)
    # set default value if value is 'nil'
    not_nullable_columns.each { |k| o[k].nil? && o[k] = completers[k]&.call }
    # fill span values if column is not exist
    lack_columns.each { |k| o[k].nil? && o[k] = completers[k]&.call }
    o
  }
end
create_model_filter(format, file_name, type) click to toggle source

create filter and table info

# File lib/flextures/flextures_loader.rb, line 342
def self.create_model_filter(format, file_name, type)
  table_name = format[:table].to_s
  klass = PARENT::create_model(table_name)
  # if you use 'rails3_acts_as_paranoid' gem, that is not delete data 'delete_all' method
  klass.send(klass.respond_to?(:delete_all!) ? :delete_all! : :delete_all)

  filter = ->(h){
    filter = create_filter(klass, LoadFilter[table_name.to_sym], file_name, type, format)
    o = klass.new
    o = filter.call(o, h)
    o
  }
  [klass, filter]
end
file_exist(format, type = %i[csv yml]) click to toggle source

parse format option and return load file info @param [Hash] format load file format informations @return [Array] [file_name, filt_type(:csv or :yml)]

# File lib/flextures/flextures_loader.rb, line 313
def self.file_exist(format, type = %i[csv yml])
  table_name = format[:table].to_s
  file_name = (format[:file] || format[:table]).to_s
  base_dir_name = Flextures::Configuration.load_directory
  self.stair_list(format[:dir], format[:stair]).each do |dir|
    file_path = File.join(base_dir_name, dir, file_name)
    formats = FORMATS.select { |fmt| (type & fmt).present? }
    formats.each do |fmt|
      return ["#{file_path}.#{fmt.join('.')}", *fmt] if File.exist?("#{file_path}.#{fmt.join('.')}")
    end
  end
  ["#{File.join(base_dir_name, file_name)}.csv", nil]
end
file_loadable?(format, file_name) click to toggle source

file load check @return [Bool] lodable is 'true'

# File lib/flextures/flextures_loader.rb, line 329
def self.file_loadable?(format, file_name)
  return unless File.exist?(file_name)
  puts "try loading #{file_name}" if !format[:silent] and ![:fun].include?(format[:loader])
  true
end
flextures(*fixtures) click to toggle source

load fixture datas

example: flextures :all # load all table data flextures :users, :items # load table data, received arguments flextures :users => :users2 # :table_name => :file_name

@params [Hash] fixtures load table data

# File lib/flextures/flextures_loader.rb, line 196
def self.flextures(*fixtures)
  loader = Flextures::Loader::Instance.new
  loader.loads(*fixtures)
end
load(format, type = %i[csv yml]) click to toggle source

load fixture data fixture file prefer YAML to CSV @params [Hash] format file load format(table name, file name, options…)

# File lib/flextures/flextures_loader.rb, line 213
def self.load(format, type = %i[csv yml])
  file_name, *exts = file_exist(format, type)
  format[:erb] = exts.include?(:erb)
  method = exts.find { |k| type.include?(k) }

  return unless self.file_loadable?(format, file_name)

  klass, filter = self.create_model_filter(format, file_name, method)

  case method
  when :csv
    self.load_csv(format, klass, filter, file_name)
  when :yml
    self.load_yml(format, klass, filter, file_name)
  else
    puts "Warning: #{file_name} is not exist!" unless format[:silent]
  end
end
load_csv(format, klass, filter, file_name) click to toggle source
# File lib/flextures/flextures_loader.rb, line 242
def self.load_csv(format, klass, filter, file_name)
  file = self.load_file(format, file_name)
  attributes = klass.columns.map(&:name)
  ActiveRecord::Base.transaction do
    csv = SmarterCSV.process(file.path)
    keys = csv.first.keys.map(&:to_s)
    warning("CSV", attributes, keys) unless format[:silent]
    csv.each do |row|
      h = row.reduce({}){ |h,(k,v)| h[k.to_s]=v; h }
      o = filter.call(h)
      o.save(validate: false)
    end
  end
  file_name
end
load_file(format, file_name) click to toggle source
# File lib/flextures/flextures_loader.rb, line 232
def self.load_file(format, file_name)
  file = nil
  if format[:erb]
    str = File.open(file_name){ |f| f.read }
    file = ERB.new(str).result
  else
    file = File.open(file_name)
  end
end
load_yml(format, klass, filter, file_name) click to toggle source
# File lib/flextures/flextures_loader.rb, line 258
def self.load_yml(format, klass, filter, file_name)
  file = self.load_file(format, file_name)
  yaml = YAML.load(file)

  return false unless yaml # if file is empty

  attributes = klass.columns.map(&:name)
  ActiveRecord::Base.transaction do
    yaml.each do |k,h|
      warning("YAML", attributes, h.keys) unless format[:silent]

      o = filter.call(h)
      o.save(validate: false)
    end
  end
  file_name
end
loading_order() click to toggle source

@return [Proc] order rule block (user Array#sort methd)

# File lib/flextures/flextures_loader.rb, line 202
def self.loading_order
  ->(a,b) do
    a = Flextures::Configuration.table_load_order.index(a) || -1
    b = Flextures::Configuration.table_load_order.index(b) || -1
    b <=> a
  end
end
new(*_) click to toggle source
# File lib/flextures/flextures_loader.rb, line 118
def initialize(*_)
  # 読み込み状態を持っておく
  @options = {}
  @already_loaded_fixtures = {}
end
parse_controller_option(options) click to toggle source

if parameter include controller, action value load directroy is change spec/fixtures/:controller_name/:action_name/ @return [String] directory path

# File lib/flextures/flextures_loader.rb, line 280
def self.parse_controller_option(options)
  controller_dir = ["controllers"]
  controller_dir<< options[:controller] if options[:controller]
  controller_dir<< options[:action]     if options[:controller] and options[:action]
  File.join(*controller_dir)
end
parse_flextures_options(base_options, *fixtures) click to toggle source

parse flextures function arguments @params [Hash] fixtures function arguments @return [Array] formatted load options

# File lib/flextures/flextures_loader.rb, line 173
def self.parse_flextures_options(base_options, *fixtures)
  options = {}
  options = fixtures.shift if fixtures.size > 1 and fixtures.first.is_a?(Hash)

  options[:dir] = self.parse_controller_option(options) if options[:controller]
  options[:dir] = self.parse_model_options(options)     if options[:model]

  # :all value load all loadable fixtures
  fixtures = Flextures::deletable_tables if fixtures.size==1 and :all == fixtures.first
  last_hash = fixtures.last.is_a?(Hash) ? fixtures.pop : {}
  load_hash = fixtures.reduce({}){ |h,name| h[name.to_sym] = name.to_s; h } # if name is string is buged
  load_hash.merge!(last_hash)
  load_hash.map { |k,v| { table: k, file: v, loader: :fun }.merge(base_options).merge(options) }
end
parse_model_options(options) click to toggle source

if parameter include controller, action value load directroy is change spec/fixtures/:model_name/:method_name/ @return [String] directory path

# File lib/flextures/flextures_loader.rb, line 291
def self.parse_model_options(options)
  model_dir = ["models"]
  model_dir<< options[:model]  if options[:model]
  model_dir<< options[:method] if options[:model] and options[:method]
  File.join(*model_dir)
end
stair_list(dir, stair=true) click to toggle source

example: self.create_stair_list(“foo/bar/baz”) return [“foo/bar/baz”,“foo/bar”,“foo”,“”]

# File lib/flextures/flextures_loader.rb, line 301
def self.stair_list(dir, stair=true)
  return [dir.to_s] unless stair

  l = []
  dir.to_s.split("/").reduce([]){ |a,d| a<< d; l.unshift(a.join("/")); a }
  l<< ""
  l
end
warning(format, attributes, keys) click to toggle source

print warinig message that lack or not exist colum names

# File lib/flextures/flextures_loader.rb, line 336
def self.warning(format, attributes, keys)
  (attributes-keys).each { |name| puts "Warning: #{format} colum is missing! [#{name}]" }
  (keys-attributes).each { |name| puts "Warning: #{format} colum is left over! [#{name}]" }
end

Public Instance Methods

delete_options() click to toggle source

called by Rspec or Should after filter reflesh options

# File lib/flextures/flextures_loader.rb, line 160
def delete_options
  @options = {}
end
equal_table_data?(src, dst) click to toggle source

compare

# File lib/flextures/flextures_loader.rb, line 144
def equal_table_data?(src, dst)
  return false unless src.is_a?(Hash)
  return false unless dst.is_a?(Hash)

  (src.to_a - dst.to_a).empty?
end
flextures_options() click to toggle source

return current option status @return [Hash] current option status

# File lib/flextures/flextures_loader.rb, line 166
def flextures_options
  @options
end
load(params) click to toggle source
# File lib/flextures/flextures_loader.rb, line 132
def load(params)
  self.class.load(params)
end
loads(*fixtures) click to toggle source
# File lib/flextures/flextures_loader.rb, line 124
def loads(*fixtures)
  # キャッシュが有効 ∧ 呼んだ事無いファイル
  load_list = self.class.parse_flextures_options(@options, *fixtures)
  load_list.sort(&self.class.loading_order).each do |params|
    load(params)
  end
end
set_options(options) click to toggle source

called by Rspec or Should set options @params [Hash] options exmple : { cashe: true, dir: “models/users” }

# File lib/flextures/flextures_loader.rb, line 154
def set_options(options)
  @options.merge!(options)
end