Module: DataShift::Querying

Extended by:
Delimiters, Logging
Includes:
Delimiters, Logging
Included in:
LoaderBase
Defined in:
lib/datashift/querying.rb

Instance Attribute Summary

Attributes included from Delimiters

#attribute_list_end, #attribute_list_start, #csv_delimiter, #key_value_sep, #text_delim

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Logging

logdir, logdir=, logger, verbose

Methods included from Delimiters

column_delim, column_delim=, eol, multi_assoc_delim, multi_assoc_delim=, multi_facet_delim, multi_value_delim, multi_value_delim=, name_value_delim, name_value_delim=, setmulti_facet_delim

Class Method Details

.where_field_and_values(method_binding, inbound_data) ⇒ Object

Return arrays ‘where’ clause field(s), and the value(s) to search for

If not contained within inbound_data, check the Inbound Column headings

Where field embedded in row ,takes precedence over field in column heading

Treat rest of the node as the value to use in the where clause e.g

price:0.99 =>  Product.where( price: 0.99)

Column headings will be used, if the row only contains data e.g

0.99


37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/datashift/querying.rb', line 37

def self.where_field_and_values(method_binding, inbound_data)

  part1, part2 = inbound_data.split(name_value_delim)

  heading_lookups = method_binding.inbound_column.lookup_list

  if (part1.nil? || part1.empty?) && (part2.nil? || part2.empty?)

    # Column completely empty - check for lookup supplied via the
    # inbound column headers/config

    # TODO: - how best to support multipel lookup fields?
    # part1 = heading_lookups.collect {|lookup| lookup.field }
    part1 = heading_lookups.find_by_operator
    part2 = heading_lookups.collect(&:value)

  elsif part2.nil? || part2.empty?

    # Only **value(s)** in column, so use field from header/config field

    logger.debug("No part2e [#{part1}][#{part1.class}] - [#{part2}][#{part2.class}]")

    part2 = part1.split(multi_value_delim)
    part1 = method_binding.inbound_column.find_by_operator

  else
    part2 = part2.split(multi_value_delim)

  end

  logger.debug("Where clause [#{part1}][#{part1.class}] - [#{part2}][#{part2.class}]")

  [part1, [*part2]]
end

Instance Method Details

#find_or_new(klass, condition_hash = {}) ⇒ Object



151
152
153
154
155
156
157
# File 'lib/datashift/querying.rb', line 151

def find_or_new( klass, condition_hash = {} )
  records = klass.where(condition_hash).all

  return records.first if records.any?

  klass.new
end

#get_record_by(klazz, field, search_term, split_on = ' ', options = {}) ⇒ Object

Find a record for model klazz, looking up on field containing search_terms Responds to global Options :

:add_prefix     : Add a prefix to each search term
:case_sensitive : Default is a case insensitive lookup.
:use_like       : Attempts a lookup using like and x% rather than equality

Returns nil if no record found



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/datashift/querying.rb', line 102

def get_record_by(klazz, field, search_term, split_on = ' ', options = {})

  split_on_prefix = options[:add_prefix]

  find_search_term = split_on_prefix ? "#{split_on_prefix}#{search_term}" : search_term

  logger.info("Scanning for record where #{klazz}.#{field} ~=  #{find_search_term}")

  begin

    record = search_for_record(klazz, field, find_search_term)

    unless record
      logger.info("Nothing found - trying split file_name to terms on [#{split_on}]")

      # try individual portions of search_term, front -> back i.e "A_B_C_D" => A, B, C etc
      search_term.split(split_on).each do |str|
        find_search_term = split_on_prefix ? "#{split_on_prefix}#{str}" : str
        logger.info("Scanning by term for record where #{field} ~=  #{find_search_term}")
        record = search_for_record(klazz, field, find_search_term, options)
        break if record
      end
    end

    # this time try incrementally scanning i.e "A_B_C_D" => A, A_B, A_B_C etc
    search_term.split(split_on).inject('') do |str, term|
      z = split_on_prefix ? "#{split_on_prefix}#{str}#{split_on}#{term}" : "#{str}#{split_on}#{term}"
      record = search_for_record(klazz, field, z, options)
      break if record
      term
    end unless record

    return record
  rescue => e
    logger.error("Exception attempting to find a record for [#{search_term}] on #{klazz}.#{field}")
    logger.error e.backtrace
    logger.error e.inspect
    return nil
  end
end

#get_record_by!(klazz, field, search_terms, split_on = ' ', options = {}) ⇒ Object

Raises:

  • (RecordNotFound)


143
144
145
146
147
148
149
# File 'lib/datashift/querying.rb', line 143

def get_record_by!(klazz, field, search_terms, split_on = ' ', options = {} )
  x = get_record_by(klazz, field, search_terms, split_on, options)

  raise RecordNotFound, "No #{klazz} record found for [#{search_terms}] on #{field}" unless x

  x
end

#search_for_record(klazz, field, search_term, options = {}) ⇒ Object

Options:

:case_sensitive   : Default is a case insensitive lookup.
:use_like         : Attempts a lookup using ike and x% rather than equality


77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/datashift/querying.rb', line 77

def search_for_record(klazz, field, search_term, options = {})

  begin
    return klazz.send("find_by_#{field}", search_term) if options[:case_sensitive]

    return klazz.where("#{field} like ?", "#{search_term}%").first if options[:use_like]

    return klazz.where("lower(#{field}) = ?", search_term.downcase).first
  rescue => e
    logger.error("Querying - Failed to find a record for [#{search_term}] on #{klazz}.#{field}")
    logger.error e.inspect
    logger.error e.backtrace.last
  end

  nil
end