leap_salesforce 0.2.10 → 0.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.idea/leap-salesforce.iml +1 -2
- data/ChangeLog +6 -0
- data/leap_salesforce.gemspec +0 -1
- data/lib/leap_salesforce/ext/string.rb +9 -1
- data/lib/leap_salesforce/soql_data/soql.rb +155 -0
- data/lib/leap_salesforce/soql_data/soql_data.rb +4 -1
- data/lib/leap_salesforce/soql_data/soql_global_object_data.rb +16 -146
- data/lib/leap_salesforce/version.rb +1 -1
- metadata +3 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b9b7865d552e1f591be39301e900859d3e00bd0d196b00af5190a6f8f6d480f9
|
4
|
+
data.tar.gz: 1e0755eaa5d99e2fc71083b994597df3bb9711fd6dd2dfd40026d68821ce196e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f2a4b2d52ac9fea1b4407505075ee4d5cc9fb48c82d578af16a332725b149f50423ec993145c629211c7bb8466a4913050bb3d50670141efce109a86d919c6d1
|
7
|
+
data.tar.gz: 0fb073f6652bd70c1278ad8f61d78b8f3a8a90f00704afb4d6acaf71d060f52ee2a24ba55bc7aa518e29c5275395c0647e2dc175a0dc9829444156396ebb2f34
|
data/.idea/leap-salesforce.iml
CHANGED
@@ -54,7 +54,7 @@
|
|
54
54
|
<orderEntry type="library" scope="PROVIDED" name="rainbow (v3.0.0, RVM: ruby-2.6.5) [gem]" level="application" />
|
55
55
|
<orderEntry type="library" scope="PROVIDED" name="rake (v13.0.0, RVM: ruby-2.6.5) [gem]" level="application" />
|
56
56
|
<orderEntry type="library" scope="PROVIDED" name="random-port (v0.5.1, RVM: ruby-2.6.5) [gem]" level="application" />
|
57
|
-
<orderEntry type="library" scope="PROVIDED" name="require_all (
|
57
|
+
<orderEntry type="library" scope="PROVIDED" name="require_all (v3.0.0, RVM: ruby-2.6.5) [gem]" level="application" />
|
58
58
|
<orderEntry type="library" scope="PROVIDED" name="rest-client (v2.1.0, RVM: ruby-2.6.5) [gem]" level="application" />
|
59
59
|
<orderEntry type="library" scope="PROVIDED" name="rspec (v3.9.0, RVM: ruby-2.6.5) [gem]" level="application" />
|
60
60
|
<orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.8.2, RVM: ruby-2.6.5) [gem]" level="application" />
|
@@ -64,7 +64,6 @@
|
|
64
64
|
<orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.8.3, RVM: ruby-2.6.5) [gem]" level="application" />
|
65
65
|
<orderEntry type="library" scope="PROVIDED" name="rubocop (v0.75.1, RVM: ruby-2.6.5) [gem]" level="application" />
|
66
66
|
<orderEntry type="library" scope="PROVIDED" name="ruby-progressbar (v1.10.1, RVM: ruby-2.6.5) [gem]" level="application" />
|
67
|
-
<orderEntry type="library" scope="PROVIDED" name="rubykeyword (v0.0.4, RVM: ruby-2.6.5) [gem]" level="application" />
|
68
67
|
<orderEntry type="library" scope="PROVIDED" name="savon (v2.12.0, RVM: ruby-2.6.5) [gem]" level="application" />
|
69
68
|
<orderEntry type="library" scope="PROVIDED" name="sinatra (v2.0.4, RVM: ruby-2.6.5) [gem]" level="application" />
|
70
69
|
<orderEntry type="library" scope="PROVIDED" name="sinatra-basic-auth (v0.1.0, RVM: ruby-2.6.5) [gem]" level="application" />
|
data/ChangeLog
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
Version 0.2.11
|
2
|
+
* Bug fix
|
3
|
+
* Remove 'rubykeyword' gem's adding 'seek' to Sting which broke 'rubyzip' gem
|
4
|
+
* Enhancement
|
5
|
+
* Don't retry when a valid exception is returned (this makes things inefficient)
|
6
|
+
|
1
7
|
Version 0.2.10
|
2
8
|
* Enhancement
|
3
9
|
* LeapSalesforce::Users
|
data/leap_salesforce.gemspec
CHANGED
@@ -40,7 +40,6 @@ It reads the Metadata from Salesforce and creates the foundation for API tests.'
|
|
40
40
|
spec.add_dependency 'rake'
|
41
41
|
spec.add_dependency 'require_all'
|
42
42
|
spec.add_dependency 'rubocop'
|
43
|
-
spec.add_dependency 'rubykeyword'
|
44
43
|
spec.add_dependency 'soaspec', '>= 0.3.0'
|
45
44
|
spec.add_dependency 'thor'
|
46
45
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'nori/core_ext'
|
4
|
-
require 'rubykeyword'
|
5
4
|
require 'humanize'
|
6
5
|
require 'active_support/core_ext/string'
|
7
6
|
require 'date'
|
@@ -9,6 +8,10 @@ require 'json'
|
|
9
8
|
|
10
9
|
# Override string object to provide convenience methods for Strings
|
11
10
|
class String
|
11
|
+
# @return [Array] List of ruby keywords
|
12
|
+
KEYWORDS = %w[BEGIN END __ENCODING__ __END__ __FILE__ __LINE__ alias and begin break case class def defined?
|
13
|
+
do else elsif end ensure false for if in module next nil not or redo rescue retry return
|
14
|
+
self super then true undef unless until when while yield private].freeze
|
12
15
|
# @note This removes '?' which is allowed in a method but is not desired for automatic creation of their names
|
13
16
|
# in the way that is being used here
|
14
17
|
# @return [String] Convert string to something that would be friendly to use as in Ruby
|
@@ -104,4 +107,9 @@ class String
|
|
104
107
|
joined = arr.join("', '")
|
105
108
|
"('#{joined}')"
|
106
109
|
end
|
110
|
+
|
111
|
+
# @return [Boolean] Whether string is a Ruby keyword
|
112
|
+
def keyword?
|
113
|
+
KEYWORDS.include? self
|
114
|
+
end
|
107
115
|
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LeapSalesforce
|
4
|
+
# Handles interaction with Soql, mapping ruby to soql query strings
|
5
|
+
class Soql
|
6
|
+
# @return [String] Soql table
|
7
|
+
attr_accessor :soql_table
|
8
|
+
|
9
|
+
def initialize(soql_table)
|
10
|
+
self.soql_table = soql_table
|
11
|
+
@default_filter = soql_table.instance_variable_get(:@default_filter)
|
12
|
+
@soql_object_name = soql_table.soql_object_name
|
13
|
+
end
|
14
|
+
|
15
|
+
# This will be inefficient if an Id is passed
|
16
|
+
# @return [> SoqlData] SoqlData object that is the result of looking up id based on lookup criteria
|
17
|
+
def lookup_id(lookup)
|
18
|
+
teardown = lookup.delete(:teardown)
|
19
|
+
wait = lookup.delete(:wait)
|
20
|
+
SoqlHandler.new("Query on #{self}").use
|
21
|
+
result = if lookup.key? :Id
|
22
|
+
soql_table.new("Lookup id: #{lookup[:Id]}", method: :get, suburl: "sobjects/#{@soql_object_name}/#{lookup[:Id]}")
|
23
|
+
else
|
24
|
+
query soql_id(lookup), wait: wait
|
25
|
+
end
|
26
|
+
SoqlData.ids_to_delete[self] = id if teardown
|
27
|
+
result
|
28
|
+
end
|
29
|
+
|
30
|
+
# @param [Hash] lookup Hash to find Soql object via
|
31
|
+
# @return [String] String to find soql object based on criteria
|
32
|
+
def soql_id(lookup)
|
33
|
+
"SELECT Id FROM #{@soql_object_name} #{soql_lookup_filter(lookup)}"
|
34
|
+
end
|
35
|
+
|
36
|
+
# Url encoding needs to be used when searching for special characters (+ => '%2B')
|
37
|
+
# (see https://www.w3schools.com/tags/ref_urlencode.asp)
|
38
|
+
# @param [String] soql_query String representing SOQL query
|
39
|
+
# @param [Boolean] wait Whether to wait for record if no result returned
|
40
|
+
# @example Find an account with test organisation name
|
41
|
+
# my_query = "SELECT Name from Account WHERE Name = 'TEST Org 001'"
|
42
|
+
# query my_query # => "SELECT+Name+from+Account+WHERE+Name+=+'TEST+Org+001'"
|
43
|
+
# @return [self] Exchange object from which JSON response can be obtained (i.e, with exchange.response)
|
44
|
+
def query(soql_query, wait: false)
|
45
|
+
rest_query = soql_query.gsub('%', '%25').gsub('+', '%2B').tr(' ', '+')
|
46
|
+
query_object = soql_table.new("SOQL Query: #{soql_query}", method: :get, suburl: "query/?q=#{rest_query}")
|
47
|
+
return query_object unless wait
|
48
|
+
|
49
|
+
query_object.until(timeout: 20, interval: 1) do
|
50
|
+
response.body.include? '"url"' # Could be waiting for element to be created
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# @param [Hash] lookup Hash representing look up performed
|
55
|
+
# @param [String] url Url to get
|
56
|
+
def data_from_url(url, lookup)
|
57
|
+
soql_table.new("Id at #{url}", method: :get, suburl: url.split("v#{SoqlHandler.api_version}/").last)
|
58
|
+
rescue NoElementAtPath
|
59
|
+
raise NoElementAtPath, "No result found for #{lookup} under user #{LeapSalesforce.api_user}"
|
60
|
+
end
|
61
|
+
|
62
|
+
# For dates (ending with .000Z), query is always greater than
|
63
|
+
# @param [Hash] lookup Hash to look up values according to
|
64
|
+
# @return [String] SOQL query to filter results
|
65
|
+
def soql_lookup_filter(lookup)
|
66
|
+
limit = lookup.delete(:limit)
|
67
|
+
@default_filter ||= lookup.delete(:order_by) || created_date
|
68
|
+
conditional = ''
|
69
|
+
lookup.each do |key, value|
|
70
|
+
conditional_term = conditional.empty? ? 'WHERE' : 'AND'
|
71
|
+
key_used = map_key key
|
72
|
+
conditional += "#{conditional_term} #{key_used} #{condition_for(key_used, value)} "
|
73
|
+
end
|
74
|
+
query = conditional
|
75
|
+
query += "ORDER BY #{@default_filter} DESC NULLS FIRST" if @default_filter
|
76
|
+
query += " LIMIT #{limit}" if limit
|
77
|
+
query
|
78
|
+
end
|
79
|
+
|
80
|
+
# @return [String] Created date if present
|
81
|
+
def created_date
|
82
|
+
'CreatedDate' if field_names.include?('CreatedDate')
|
83
|
+
end
|
84
|
+
|
85
|
+
# @return [Array]
|
86
|
+
def field_names
|
87
|
+
soql_table.field_names
|
88
|
+
end
|
89
|
+
|
90
|
+
# Map key to a field name if used directly or field defined through 'soql_element'
|
91
|
+
# @param [Symbol, String] key Key to map to Table field name
|
92
|
+
# @return [String] Field name of Salesforce entity to use
|
93
|
+
def map_key(key)
|
94
|
+
if field_names.include?(key.to_s)
|
95
|
+
key.to_s
|
96
|
+
elsif field_names.include?(key.to_s.camelize)
|
97
|
+
key.to_s.camelize
|
98
|
+
else
|
99
|
+
soql_instance = soql_table.new
|
100
|
+
return soql_instance.send("#{key}_element") if soql_instance.respond_to?("#{key}_element")
|
101
|
+
|
102
|
+
raise LeapSalesforce::RequestError, "#{key} not in #{self}. " \
|
103
|
+
" Must be one of #{field_names} or a field name described in" \
|
104
|
+
" #{self}::FieldNames"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Returns SOQL condition for value passed to be used in SOQL query
|
109
|
+
# @example Greater than or equal to yesterday's date
|
110
|
+
# condition_for("<=#{Time.mktime(2019,1,1)}") # => '<= 2019-01-01T00:00:00.000Z'
|
111
|
+
# @param [String] field_name Backend field name
|
112
|
+
# @param [String, Object] value Value to search for. Certain characters modify this to be more of a complex
|
113
|
+
# check. Object will be converted String if not already one
|
114
|
+
# @return [String] Condition criteria to match value using SOQL
|
115
|
+
def condition_for(field_name, value)
|
116
|
+
value = value.nil? ? 'null' : value.to_s
|
117
|
+
operator, value = case value[0]
|
118
|
+
when '>', '<', '!', 'I' then extract_comparator(value)
|
119
|
+
when '~' then ['LIKE', value[1..-1]]
|
120
|
+
else ['=', value]
|
121
|
+
end
|
122
|
+
case soql_table.type_for(field_name)
|
123
|
+
when 'boolean', 'double', 'int' then "#{operator} #{value}"
|
124
|
+
when 'date', 'datetime', 'time'
|
125
|
+
unless value.type_of_time?
|
126
|
+
raise LeapSalesforce::RequestError,
|
127
|
+
"Value '#{value}' cannot be interpreted as date for #{field_name}"
|
128
|
+
end
|
129
|
+
"#{operator} #{value.to_zulu_date_string}"
|
130
|
+
else # string, picklist, reference, id, textarea
|
131
|
+
return "#{operator} #{value}" if operator.end_with?('IN') || value == 'null'
|
132
|
+
|
133
|
+
"#{operator} '#{value}'"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# @param [String] value Value to extract comparator for
|
138
|
+
# @return [Array] Extract of operator, value, taking >, >, >= from string and rest of string
|
139
|
+
def extract_comparator(value)
|
140
|
+
if value[1] == '='
|
141
|
+
[value[0..1], value[2..-1]]
|
142
|
+
elsif value[0..2] == '!IN'
|
143
|
+
['NOT IN', value[3..-1].to_soql_array]
|
144
|
+
elsif value[0..1] == 'IN'
|
145
|
+
['IN', value[2..-1].to_soql_array]
|
146
|
+
elsif value[0] == 'I' # 'N' not 2nd character
|
147
|
+
['=', value]
|
148
|
+
elsif value[0] == '!'
|
149
|
+
['!=', value[1..-1]]
|
150
|
+
else
|
151
|
+
[value[0], value[1..-1]]
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'launchy'
|
4
|
+
require_relative 'soql'
|
4
5
|
require_relative 'meta_data_handler'
|
5
6
|
require_relative 'soql_handler'
|
6
7
|
require_relative 'soql_global_data'
|
@@ -11,6 +12,8 @@ require_relative 'soql_enum'
|
|
11
12
|
require_relative 'soql_settings'
|
12
13
|
|
13
14
|
# Represents an API interaction via SOQL queries with the Salesforce database
|
15
|
+
# Usually this class is inherited by a class that represents a particular object,
|
16
|
+
# the only exception being the singleton methods in 'SoqlGlobalData'
|
14
17
|
class SoqlData < Exchange
|
15
18
|
include DataRelationships
|
16
19
|
extend SoqlGlobalData
|
@@ -66,7 +69,7 @@ class SoqlData < Exchange
|
|
66
69
|
# @return [String] User used to make api calls
|
67
70
|
attr_accessor :api_user
|
68
71
|
|
69
|
-
|
72
|
+
define_method('retry_for_success?') { false }
|
70
73
|
|
71
74
|
# Api username below references stored variable through ERB so this can be changed at run time (otherwise user would be fixed)
|
72
75
|
default_handler SoqlHandler, 'Factory', api_user: '<%= LeapSalesforce.api_user %>'
|
@@ -3,6 +3,9 @@
|
|
3
3
|
require_relative 'tooling'
|
4
4
|
|
5
5
|
# Methods for working with instances of global to soql objects, not global overall
|
6
|
+
# Some of these are called internally by methods on an instance of SoqlData, for instance,
|
7
|
+
# case = Case.create
|
8
|
+
# case.update # => This will call Case.update passing it's own id
|
6
9
|
# See https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_sobject_describe.htm
|
7
10
|
module SoqlGlobalObjectData
|
8
11
|
include LeapSalesforce::Tooling
|
@@ -13,61 +16,6 @@ module SoqlGlobalObjectData
|
|
13
16
|
# @param [String] _id Id of record being deleted
|
14
17
|
def remove_dependent_records(_id); end
|
15
18
|
|
16
|
-
# Return key and value to look up for a provided hash
|
17
|
-
# @return [Array] Array with [column_to_lookup, value_to_look_for]
|
18
|
-
def extract_lookup(lookup)
|
19
|
-
raise 'Need to pass to Soql object key value pair to look up by' unless lookup.first.is_a? Array
|
20
|
-
|
21
|
-
lookup_key, lookup_value = lookup.first
|
22
|
-
raise 'Need to set lookup_key' unless lookup_key
|
23
|
-
|
24
|
-
[lookup_key, lookup_value]
|
25
|
-
end
|
26
|
-
|
27
|
-
# Url enconding needs to be used when searching for special characters (+ => '%2B')
|
28
|
-
# (see https://www.w3schools.com/tags/ref_urlencode.asp)
|
29
|
-
# @param [String] soql_query String representing SOQL query
|
30
|
-
# @param [Boolean] wait Whether to wait for record if no result returned
|
31
|
-
# @example Find an account with test organisation name
|
32
|
-
# my_query = "SELECT Name from Account WHERE Name = 'TEST Org 001'"
|
33
|
-
# query my_query # => "SELECT+Name+from+Account+WHERE+Name+=+'TEST+Org+001'"
|
34
|
-
# @return [self] Exchange object from which JSON response can be obtained (i.e, with exchange.response)
|
35
|
-
def query(soql_query, wait: false)
|
36
|
-
rest_query = soql_query.gsub('%', '%25').gsub('+', '%2B').tr(' ', '+')
|
37
|
-
if wait
|
38
|
-
new("SOQL Query: #{soql_query}", method: :get, suburl: "query/?q=#{rest_query}").until(timeout: 20, interval: 1) do
|
39
|
-
response.body.include? '"url"' # Could be waiting for element to be created
|
40
|
-
end
|
41
|
-
else
|
42
|
-
new("SOQL Query: #{soql_query}", method: :get, suburl: "query/?q=#{rest_query}")
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# @param [Hash] lookup Hash representing look up performed
|
47
|
-
# @param [String] url Url to get
|
48
|
-
def data_from_url(url, lookup)
|
49
|
-
new("Id at #{url}", method: :get, suburl: url.split("v#{SoqlHandler.api_version}/").last)
|
50
|
-
rescue NoElementAtPath
|
51
|
-
raise NoElementAtPath, "No result found for #{lookup} under user #{LeapSalesforce.api_user}"
|
52
|
-
end
|
53
|
-
|
54
|
-
# For dates (ending with .000Z), query is always greater than
|
55
|
-
# @param [Hash] lookup Hash to look up values according to
|
56
|
-
# @return [String] SOQL query to filter results
|
57
|
-
def soql_lookup_filter(lookup)
|
58
|
-
limit = lookup.delete(:limit)
|
59
|
-
@default_filter ||= 'CreatedDate'
|
60
|
-
conditional = ''
|
61
|
-
lookup.each do |key, value|
|
62
|
-
conditional_term = conditional.empty? ? 'WHERE' : 'AND'
|
63
|
-
key_used = map_key key
|
64
|
-
conditional += "#{conditional_term} #{key_used} #{condition_for(key_used, value)} "
|
65
|
-
end
|
66
|
-
query = conditional + "ORDER BY #{@default_filter} DESC NULLS FIRST"
|
67
|
-
query += " LIMIT #{limit}" if limit
|
68
|
-
query
|
69
|
-
end
|
70
|
-
|
71
19
|
# Find the data for a single SoqlObject using the calling class's table.
|
72
20
|
# Will get the latest created date.
|
73
21
|
# @example Get a contact where LastName is 'Bob' using backend name
|
@@ -78,49 +26,35 @@ module SoqlGlobalObjectData
|
|
78
26
|
# Contact.find CreatedDate: "<#{10.days.ago}"
|
79
27
|
# @param [Hash] lookup Key value pair unique to Salesforce to query for
|
80
28
|
# @option lookup [Boolean] :teardown Whether to remove id after scenario finished
|
81
|
-
# @return [
|
29
|
+
# @return [< SoqlData] Instance of itself storing reference to found object
|
82
30
|
def find(lookup)
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
wait: wait
|
91
|
-
data_from_url initial_query['$..url'], lookup
|
92
|
-
end
|
93
|
-
SoqlData.ids_to_delete[self] = instance_to_get[:id] if teardown
|
94
|
-
instance_to_get
|
31
|
+
id_lookup = soql.lookup_id lookup
|
32
|
+
lookup.key?(:Id) ? id_lookup : soql.data_from_url(id_lookup['$..url'], lookup)
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [LeapSalesforce::Soql] Object to handle Soql interactions
|
36
|
+
def soql
|
37
|
+
@soql ||= LeapSalesforce::Soql.new(self)
|
95
38
|
end
|
96
39
|
|
97
40
|
# @deprecated
|
98
41
|
# Get details of itself by searching for it's id
|
99
42
|
# Store response within itself
|
100
|
-
# @return [
|
43
|
+
# @return [< SoqlData] Exchange with details of data
|
101
44
|
def get(lookup)
|
102
45
|
LeapSalesforce.logger.warn "Method 'get' called when it is deprecated" \
|
103
46
|
" from #{caller_locations[0]}"
|
104
47
|
find(lookup)
|
105
48
|
end
|
106
49
|
|
107
|
-
# @return [self] SoqlData object that is the result of looking up id based on lookup criteria
|
108
|
-
def lookup_id(lookup)
|
109
|
-
teardown = lookup.delete(:teardown)
|
110
|
-
SoqlHandler.new("Query on #{self}").use
|
111
|
-
result = query "SELECT Id FROM #{soql_object_name} #{soql_lookup_filter(lookup)}", wait: false
|
112
|
-
SoqlData.ids_to_delete[self] = id if teardown
|
113
|
-
result
|
114
|
-
end
|
115
|
-
|
116
50
|
# @return [String] Id that matches filter
|
117
51
|
def id_where(lookup)
|
118
|
-
lookup_id(lookup).id
|
52
|
+
soql.lookup_id(lookup).id
|
119
53
|
end
|
120
54
|
|
121
55
|
# @return [Boolean] Whether any result for lookup
|
122
56
|
def any?(lookup)
|
123
|
-
lookup_id(lookup)[:totalSize] != 0
|
57
|
+
soql.lookup_id(lookup)[:totalSize] != 0
|
124
58
|
end
|
125
59
|
|
126
60
|
alias any_where? any?
|
@@ -133,7 +67,7 @@ module SoqlGlobalObjectData
|
|
133
67
|
def ids_where(lookup)
|
134
68
|
lookup[:limit] ||= nil # Don't limit results returned
|
135
69
|
SoqlHandler.new("Each Id where #{self}").use
|
136
|
-
results = query
|
70
|
+
results = soql.query soql.soql_id(lookup), wait: false
|
137
71
|
ids = results.ids
|
138
72
|
if block_given?
|
139
73
|
ids.each { |id| yield(id) }
|
@@ -169,7 +103,7 @@ module SoqlGlobalObjectData
|
|
169
103
|
data = data.transform_values do |value|
|
170
104
|
value.is_a?(Time) ? value.salesforce_format : value
|
171
105
|
end
|
172
|
-
data.transform_keys! { |key| map_key(key) } # Map keys to valid field names
|
106
|
+
data.transform_keys! { |key| soql.map_key(key) } # Map keys to valid field names
|
173
107
|
SoqlHandler.new("Update #{id}").use
|
174
108
|
update = new("Update #{self}, #{id} with '#{data}'", method: :patch,
|
175
109
|
suburl: "sobjects/#{soql_object_name}/#{id}", body: data)
|
@@ -218,70 +152,6 @@ module SoqlGlobalObjectData
|
|
218
152
|
define_method("#{name}_element") { backend_name }
|
219
153
|
end
|
220
154
|
|
221
|
-
# Map key to a field name if used directly or field defined through 'soql_element'
|
222
|
-
# @param [Symbol, String] key Key to map to Table field name
|
223
|
-
# @return [String] Field name of Salesforce entity to use
|
224
|
-
def map_key(key)
|
225
|
-
if field_names.include?(key.to_s)
|
226
|
-
key.to_s
|
227
|
-
elsif field_names.include?(key.to_s.camelize)
|
228
|
-
key.to_s.camelize
|
229
|
-
else
|
230
|
-
return new.send("#{key}_element") if new.respond_to?("#{key}_element")
|
231
|
-
|
232
|
-
raise LeapSalesforce::RequestError, "#{key} not in #{self}. " \
|
233
|
-
" Must be one of #{field_names} or a field name described in" \
|
234
|
-
" #{self}::FieldNames"
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
# Returns SOQL condition for value passed to be used in SOQL query
|
239
|
-
# @example Greater than or equal to yesterday's date
|
240
|
-
# condition_for("<=#{Time.mktime(2019,1,1)}") # => '<= 2019-01-01T00:00:00.000Z'
|
241
|
-
# @param [String] field_name Backend field name
|
242
|
-
# @param [String, Object] value Value to search for. Certain characters modify this to be more of a complex
|
243
|
-
# check. Object will be converted String if not already one
|
244
|
-
# @return [String] Condition criteria to match value using SOQL
|
245
|
-
def condition_for(field_name, value)
|
246
|
-
value = value.nil? ? 'null' : value.to_s
|
247
|
-
operator, value = case value[0]
|
248
|
-
when '>', '<', '!', 'I' then extract_comparator(value)
|
249
|
-
when '~' then ['LIKE', value[1..-1]]
|
250
|
-
else ['=', value]
|
251
|
-
end
|
252
|
-
case type_for(field_name)
|
253
|
-
when 'boolean', 'double', 'int' then "#{operator} #{value}"
|
254
|
-
when 'date', 'datetime', 'time'
|
255
|
-
unless value.type_of_time?
|
256
|
-
raise LeapSalesforce::RequestError,
|
257
|
-
"Value '#{value}' cannot be interpreted as date for #{field_name}"
|
258
|
-
end
|
259
|
-
"#{operator} #{value.to_zulu_date_string}"
|
260
|
-
else # string, picklist, reference, id, textarea
|
261
|
-
return "#{operator} #{value}" if operator.end_with?('IN') || value == 'null'
|
262
|
-
|
263
|
-
"#{operator} '#{value}'"
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
# @param [String] value Value to extract comparator for
|
268
|
-
# @return [Array] Extract of operator, value, taking >, >, >= from string and rest of string
|
269
|
-
def extract_comparator(value)
|
270
|
-
if value[1] == '='
|
271
|
-
[value[0..1], value[2..-1]]
|
272
|
-
elsif value[0..2] == '!IN'
|
273
|
-
['NOT IN', value[3..-1].to_soql_array]
|
274
|
-
elsif value[0..1] == 'IN'
|
275
|
-
['IN', value[2..-1].to_soql_array]
|
276
|
-
elsif value[0] == 'I' # 'N' not 2nd character
|
277
|
-
['=', value]
|
278
|
-
elsif value[0] == '!'
|
279
|
-
['!=', value[1..-1]]
|
280
|
-
else
|
281
|
-
[value[0], value[1..-1]]
|
282
|
-
end
|
283
|
-
end
|
284
|
-
|
285
155
|
private
|
286
156
|
|
287
157
|
# Raise error if incorrect type passed
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: leap_salesforce
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- IQA
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-10-
|
12
|
+
date: 2019-10-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -207,20 +207,6 @@ dependencies:
|
|
207
207
|
- - ">="
|
208
208
|
- !ruby/object:Gem::Version
|
209
209
|
version: '0'
|
210
|
-
- !ruby/object:Gem::Dependency
|
211
|
-
name: rubykeyword
|
212
|
-
requirement: !ruby/object:Gem::Requirement
|
213
|
-
requirements:
|
214
|
-
- - ">="
|
215
|
-
- !ruby/object:Gem::Version
|
216
|
-
version: '0'
|
217
|
-
type: :runtime
|
218
|
-
prerelease: false
|
219
|
-
version_requirements: !ruby/object:Gem::Requirement
|
220
|
-
requirements:
|
221
|
-
- - ">="
|
222
|
-
- !ruby/object:Gem::Version
|
223
|
-
version: '0'
|
224
210
|
- !ruby/object:Gem::Dependency
|
225
211
|
name: soaspec
|
226
212
|
requirement: !ruby/object:Gem::Requirement
|
@@ -327,6 +313,7 @@ files:
|
|
327
313
|
- lib/leap_salesforce/rake/sfdx.rake
|
328
314
|
- lib/leap_salesforce/soql_data/data_relationships.rb
|
329
315
|
- lib/leap_salesforce/soql_data/meta_data_handler.rb
|
316
|
+
- lib/leap_salesforce/soql_data/soql.rb
|
330
317
|
- lib/leap_salesforce/soql_data/soql_data.rb
|
331
318
|
- lib/leap_salesforce/soql_data/soql_enum.rb
|
332
319
|
- lib/leap_salesforce/soql_data/soql_global_data.rb
|