class LeapSalesforce::Soql

Handles interaction with Soql, mapping ruby to soql query strings

Attributes

soql_table[RW]

@return [SoqlData] Soql table

Public Class Methods

new(soql_table) click to toggle source

@param [SoqlData] soql_table Object mapping to a Salesforce table

# File lib/leap_salesforce/soql_data/soql.rb, line 10
def initialize(soql_table)
  self.soql_table = soql_table
  @default_filter = soql_table.instance_variable_get(:@default_filter)
  @soql_object_name = soql_table.soql_object_name
end

Public Instance Methods

condition_for(field_name, value) click to toggle source

Returns SOQL condition for value passed to be used in SOQL query @example Greater than or equal to yesterday's date

condition_for("<=#{Time.mktime(2019,1,1)}") # => '<= 2019-01-01T00:00:00.000Z'

@param [String] field_name Backend field name @param [String, Object] value Value to search for. Certain characters modify this to be more of a complex

check. Object will be converted String if not already one

@return [String] Condition criteria to match value using SOQL

# File lib/leap_salesforce/soql_data/soql.rb, line 119
def condition_for(field_name, value)
  value = value.nil? ? 'null' : value.to_s
  operator, value = case value[0]
                    when '>', '<', '!', 'I' then extract_comparator(value)
                    when '~' then ['LIKE', value[1..-1]]
                    else ['=', value]
                    end
  case soql_table.type_for(field_name)
  when 'boolean', 'double', 'int' then "#{operator} #{value}"
  when 'date', 'datetime', 'time'
    unless value.type_of_time?
      raise LeapSalesforce::RequestError,
            "Value '#{value}' cannot be interpreted as date for #{field_name}"
    end
    "#{operator} #{value.to_zulu_date_string}"
  else # string, picklist, reference, id, textarea
    return "#{operator} #{value}" if operator.end_with?('IN') || value == 'null'

    "#{operator} '#{value}'"
  end
end
created_date() click to toggle source

@return [String] Created date if present

# File lib/leap_salesforce/soql_data/soql.rb, line 85
def created_date
  'CreatedDate' if field_names.include?('CreatedDate')
end
data_from_url(url, lookup) click to toggle source

@param [Hash] lookup Hash representing look up performed @param [String] url Url to get

# File lib/leap_salesforce/soql_data/soql.rb, line 60
def data_from_url(url, lookup)
  soql_table.new("Id at #{url}", method: :get, suburl: url)
rescue NoElementAtPath
  raise NoElementAtPath, "No result found for '#{lookup}' under user #{LeapSalesforce.api_user}"
end
extract_comparator(value) click to toggle source

@param [String] value Value to extract comparator for @return [Array] Extract of operator, value, taking >, >, >= from string and rest of string

# File lib/leap_salesforce/soql_data/soql.rb, line 143
def extract_comparator(value)
  if value[1] == '='
    [value[0..1], value[2..-1]]
  elsif value[0..2] == '!IN'
    ['NOT IN', value[3..-1].to_soql_array]
  elsif value[0..1] == 'IN'
    ['IN', value[2..-1].to_soql_array]
  elsif value[0] == 'I' # 'N' not 2nd character
    ['=', value]
  elsif value[0] == '!'
    remaining = value[1..-1] == 'nil' ? 'null' : value[1..-1]
    ['!=', remaining]
  else
    [value[0], value[1..-1]]
  end
end
field_names() click to toggle source

@return [Array]

# File lib/leap_salesforce/soql_data/soql.rb, line 90
def field_names
  soql_table.field_names
end
lookup_id(lookup) click to toggle source

Find the Salesforce object using the lookup query provided. When id is returned it will look up the id directly, otherwise it will return an object referring to the list of results returned @return [> SoqlData] SoqlData object that is the result of looking up id based on lookup criteria

# File lib/leap_salesforce/soql_data/soql.rb, line 20
def lookup_id(lookup)
  teardown = lookup.delete(:teardown)
  wait = lookup.delete(:wait)
  SoqlHandler.new("Query on #{self}").use
  result = if lookup.key? :Id
             soql_table.new("Lookup id: #{lookup[:Id]}", method: :get, suburl: "sobjects/#{@soql_object_name}/#{lookup[:Id]}")
           else
             query soql_id(lookup), wait: wait
           end
  SoqlData.ids_to_delete[self] = id if teardown
  result
end
map_key(key) click to toggle source

Map key to a field name if used directly or field defined through 'soql_element' @param [Symbol, String] key Key to map to Table field name @return [String] Field name of Salesforce entity to use

# File lib/leap_salesforce/soql_data/soql.rb, line 97
def map_key(key)
  if field_names.include?(key.to_s)
    key.to_s
  elsif field_names.include?(key.to_s.camelize)
    key.to_s.camelize
  else
    soql_instance = soql_table.new
    return soql_instance.send("#{key}_element") if soql_instance.respond_to?("#{key}_element")

    raise LeapSalesforce::RequestError, "#{key} not in #{self}. " \
    " Must be one of #{field_names} or a field name described in" \
    " #{self}::FieldNames"
  end
end
query(soql_query, wait: false) click to toggle source

Perform SOQL query against Salesforce Url encoding needs to be used when searching for special characters (+ => '%2B') (see www.w3schools.com/tags/ref_urlencode.asp) @param [String] soql_query String representing SOQL query @param [Boolean] wait Whether to wait for record if no result returned @example Find an account with test organisation name

my_query = "SELECT Name from Account WHERE Name = 'TEST Org 001'"
query my_query # => "SELECT+Name+from+Account+WHERE+Name+=+'TEST+Org+001'"

@return [self] Exchange object from which JSON response can be obtained (i.e, with exchange.response)

# File lib/leap_salesforce/soql_data/soql.rb, line 48
def query(soql_query, wait: false)
  rest_query = soql_query.gsub('%', '%25').gsub('+', '%2B').tr(' ', '+')
  query_object = soql_table.new("SOQL Query: #{soql_query}", method: :get, suburl: "query/?q=#{rest_query}")
  return query_object unless wait

  query_object.until(timeout: 20, interval: 1) do
    response.body.include? '"url"' # Could be waiting for element to be created
  end
end
soql_id(lookup) click to toggle source

@param [Hash] lookup Hash to find Soql object via @return [String] String to find soql object based on criteria

# File lib/leap_salesforce/soql_data/soql.rb, line 35
def soql_id(lookup)
  "SELECT Id FROM #{@soql_object_name} #{soql_lookup_filter(lookup)}"
end
soql_lookup_filter(lookup) click to toggle source

For dates (ending with .000Z), query is always greater than @param [Hash] lookup Hash to look up values according to @return [String] SOQL query to filter results

# File lib/leap_salesforce/soql_data/soql.rb, line 69
def soql_lookup_filter(lookup)
  limit = lookup.delete(:limit)
  @default_filter ||= lookup.delete(:order_by) || created_date
  conditional = ''
  lookup.each do |key, value|
    conditional_term = conditional.empty? ? 'WHERE' : 'AND'
    key_used = map_key key
    conditional += "#{conditional_term} #{key_used} #{condition_for(key_used, value)} "
  end
  query = conditional
  query += "ORDER BY #{@default_filter} DESC NULLS FIRST" if @default_filter
  query += " LIMIT #{limit}" if limit
  query
end