Module: CheapImports::CheapImportsClassMethods

Defined in:
lib/cheap_imports/cheap_imports.rb

Instance Method Summary collapse

Instance Method Details

#delete_prior(imported_at) ⇒ Object



73
74
75
# File 'lib/cheap_imports/cheap_imports.rb', line 73

def delete_prior(imported_at)
  delete_all "imported_at < '#{imported_at}'" if column_names.include?("imported_at")
end

#fetch_default_hash(raw, style) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/cheap_imports/cheap_imports.rb', line 77

def fetch_default_hash(raw, style)
  hash = {}
  columns.each do |c|
    column_name = c.name.to_sym
    next if column_name == :id
    keys = @recognizable_hashes[style].keys
    
    raw_value = nil
    if keys.include?(column_name)
      raw_value = value_of_from(column_name, raw)
    elsif keys.include?("#{name.downcase}_#{column_name}".to_sym)
      raw_value = value_of_from("#{name.downcase}_#{column_name}".to_sym, raw)
    end
    next if raw_value.nil?

    value = nil

    # ActiveRecord uses type, DataMapper uses e.g. DataMapper::Resource::String
    type = (c.type || c.class.name.split('::').last).to_s.downcase 
    case type
    when "string", "text", "integer", "boolean"
      if raw_value === ""
        value = nil
      else
        value = raw_value
      end
    when "date", "datetime", "time"
      date_format_string = @recognizable_hashes[style]["#{column_name}_format".to_sym]
      date_format_string ||= @recognizable_hashes[style]["#{name.downcase}_#{column_name}_format".to_sym]
      raise "nil date_format_string for #{style} #{column_name}" if date_format_string.empty?
      begin
        # TODO support for TimeWithZone, make date format string optional with smarter parsing
        value = Date.strptime(raw_value, date_format_string) if type === "date"
        value = DateTime.strptime(raw_value, date_format_string) if type === "datetime"
        value = Time.strptime(raw_value, date_format_string) if type === "time"
      rescue ArgumentError
        value = nil
      end
    when "float", "decimal"
      value = BigDecimal.new(raw_value.gsub(/[^0-9\.\-]/, ''))
    else
      raise "unhandled type: #{c.type.to_s.downcase}"
    end
    hash[column_name] = value
  end
  hash
end

#import(raw, args) ⇒ Object

Don’t override this. You probably want to override import_rash instead.



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/cheap_imports/cheap_imports.rb', line 52

def import(raw, args)
  style = recognize_hash_style(raw)

  # Want to be able to access this data in the raw hash using either the native
  # key or our nicer symbolic key.
  @recognizable_hashes[style].each do |k, v|
    raw[k] = raw[v]
  end

  hash = fetch_default_hash(raw, style)
  hash[:imported_at] = args[:imported_at] if column_names.include?("imported_at")
  hash[:history] = "Imported from #{style.to_s} at #{args[:imported_at].to_s}." if column_names.include?("history")
  hash[:source] = style.to_s if column_names.include?("source")
  import_rash(raw, args, style, hash)
end

#import_rash(raw, args, style, hash) ⇒ Object



68
69
70
71
# File 'lib/cheap_imports/cheap_imports.rb', line 68

def import_rash(raw, args, style, hash)
  delete_prior hash[:imported_at]
  create(hash)
end

#imports(hash) ⇒ Object

Add a new import definition.

imports :my_descriptive_hash_name =>

:database_column_name => "CORRESPONDING_TABLE_HEADER_TEXT"



46
47
48
49
# File 'lib/cheap_imports/cheap_imports.rb', line 46

def imports(hash)
  init_recognizable_hashes
  @recognizable_hashes.merge!(hash)
end

#init_recognizable_hashesObject



27
28
29
30
31
32
33
34
35
# File 'lib/cheap_imports/cheap_imports.rb', line 27

def init_recognizable_hashes
  default_hash = {}
  column_names.each do |n|
    next if n === 'id'
    default_hash[n.to_sym] = n
  end
  raise "default hash is empty" if default_hash.empty?
  @recognizable_hashes ||= {:default => default_hash}
end

#recognizable_hashesObject



37
38
39
# File 'lib/cheap_imports/cheap_imports.rb', line 37

def recognizable_hashes
  @recognizable_hashes
end

#recognize_hash_style(raw_hash, debug = false) ⇒ Object

Can we import this type of hash? All classes have a default hash so we can always import data which was previously exported from the database. TODO Get rid of nasty workaround for dated_on_format keys. Return the name of style, or false if no style is matched.



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/cheap_imports/cheap_imports.rb', line 137

def recognize_hash_style(raw_hash, debug = false)
  @recognizable_hashes.each do |s, h|
    puts "trying style: #{s} in class #{self.name}" if debug
    
    match = true
    h.each do |k, v|
      this_key_matches = (raw_hash.has_key?(v.to_s) || v.to_s =~ /^\%/)
      puts "key: #{k} matches: #{this_key_matches}" if debug
      match = match && this_key_matches
    end
    
    puts "overall match: #{match}" if debug
    return s if match
  end
  false
end

#value_of_from(field_name, value_hash) ⇒ Object

Fetch a row from the raw value hash.



126
127
128
129
130
131
# File 'lib/cheap_imports/cheap_imports.rb', line 126

def value_of_from(field_name, value_hash)
  specification = @recognizable_hashes[recognize_hash_style(value_hash)]
  raise "specification hash should not be nil!" if specification.nil?
  value = value_hash[specification[field_name]].to_s.strip
  block_given? ? yield(value) : value
end