leap_salesforce 0.2.10 → 0.2.11
Sign up to get free protection for your applications and to get access to all the features.
- 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
|