sobjectmodel 0.1.2
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 +7 -0
- data/lib/sobject_model/adapter/base.rb +34 -0
- data/lib/sobject_model/adapter/rest.rb +53 -0
- data/lib/sobject_model/adapter/sf.rb +52 -0
- data/lib/sobject_model/base_methods.rb +57 -0
- data/lib/sobject_model/class_definition.rb +100 -0
- data/lib/sobject_model/dml_methods.rb +37 -0
- data/lib/sobject_model/generator.rb +45 -0
- data/lib/sobject_model/query_condition.rb +189 -0
- data/lib/sobject_model/query_methods.rb +78 -0
- data/lib/sobject_model/rest/client.rb +60 -0
- data/lib/sobject_model/rest/errors.rb +19 -0
- data/lib/sobject_model/rest/http.rb +61 -0
- data/lib/sobject_model/rest/query_result.rb +66 -0
- data/lib/sobject_model/schema.rb +553 -0
- data/lib/sobject_model/support/console.rb +63 -0
- data/lib/sobject_model.rb +29 -0
- metadata +60 -0
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'net/http'
|
3
|
+
require 'json'
|
4
|
+
require 'cgi'
|
5
|
+
|
6
|
+
require_relative 'http'
|
7
|
+
require_relative 'query_result'
|
8
|
+
require_relative 'errors'
|
9
|
+
|
10
|
+
module SObjectModel
|
11
|
+
module Rest
|
12
|
+
class Client
|
13
|
+
attr_reader :instance_url, :access_token, :api_version
|
14
|
+
|
15
|
+
def initialize(instance_url:, access_token:, api_version:)
|
16
|
+
@instance_url = instance_url
|
17
|
+
@access_token = access_token
|
18
|
+
@api_version = api_version
|
19
|
+
@http = Http.new(instance_url, access_token)
|
20
|
+
end
|
21
|
+
|
22
|
+
def query(soql)
|
23
|
+
response = http.get "/services/data/v#{api_version}/query?q=#{CGI.escape(soql)}"
|
24
|
+
QueryResult.new(response)
|
25
|
+
end
|
26
|
+
|
27
|
+
def describe(object_type)
|
28
|
+
response = http.get "/services/data/v#{api_version}/sobjects/#{object_type.to_sym}/describe"
|
29
|
+
JSON.parse(response)
|
30
|
+
end
|
31
|
+
|
32
|
+
def find(object_type, id, fields: [])
|
33
|
+
query = fields.empty? ? '' : %|?fields=#{fields.map(&:to_s).join(',')}|
|
34
|
+
response = http.get "/services/data/v#{api_version}/sobjects/#{object_type}/#{id}#{query}"
|
35
|
+
JSON.parse(response)
|
36
|
+
end
|
37
|
+
|
38
|
+
def create(object_type, values)
|
39
|
+
response = http.post "/services/data/v#{api_version}/sobjects/#{object_type}/", values
|
40
|
+
JSON.parse(response)['id']
|
41
|
+
end
|
42
|
+
|
43
|
+
def update(object_type, id, values)
|
44
|
+
http.patch "/services/data/v#{api_version}/sobjects/#{object_type}/#{id}/", values
|
45
|
+
id
|
46
|
+
end
|
47
|
+
|
48
|
+
def delete(object_type, id)
|
49
|
+
http.delete "/services/data/v#{api_version}/sobjects/#{object_type}/#{id}/"
|
50
|
+
id
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def http
|
56
|
+
@http
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module SObjectModel
|
2
|
+
module Rest
|
3
|
+
class RecordNotFoundError < StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
class RequestError < StandardError
|
7
|
+
attr_reader :error_code, :error_message
|
8
|
+
def initialize(code, msg)
|
9
|
+
@error_code = code
|
10
|
+
@error_message = msg
|
11
|
+
super(to_s)
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
%|[#{@code}] #{@msg}|
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'net/http'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module SObjectModel
|
6
|
+
module Rest
|
7
|
+
class Http
|
8
|
+
attr_reader :instance_url, :access_token
|
9
|
+
|
10
|
+
def initialize(instance_url, access_token)
|
11
|
+
@instance_url = instance_url
|
12
|
+
@access_token = access_token
|
13
|
+
end
|
14
|
+
|
15
|
+
def get(path)
|
16
|
+
url = URI.parse(instance_url + path)
|
17
|
+
res = Net::HTTP.get(url, headers)
|
18
|
+
|
19
|
+
if res =~/errorCode/
|
20
|
+
err = JSON.parse(res).first
|
21
|
+
if err['errorCode'] == 'NOT_FOUND'
|
22
|
+
raise RecordNotFoundError.new
|
23
|
+
else
|
24
|
+
raise RequestError.new(err['errorCode'], err['message'])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
res
|
29
|
+
end
|
30
|
+
|
31
|
+
def post(path, data)
|
32
|
+
response = post_request(path, data)
|
33
|
+
response.body
|
34
|
+
end
|
35
|
+
|
36
|
+
def patch(path, data)
|
37
|
+
response = post_request(path + '?_HttpMethod=PATCH', data)
|
38
|
+
response.code
|
39
|
+
end
|
40
|
+
|
41
|
+
def delete(path)
|
42
|
+
response = post_request(path + '?_HttpMethod=DELETE', '')
|
43
|
+
response.code
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def headers
|
49
|
+
{ 'Authorization' => ('Bearer %{token}' % {token: access_token}), 'Content-Type' => 'application/json' }
|
50
|
+
end
|
51
|
+
|
52
|
+
def post_request(path, data)
|
53
|
+
url = URI.parse(instance_url + path)
|
54
|
+
response = Net::HTTP.post(url, JSON.dump(data), headers)
|
55
|
+
raise RequestError.new(response.code, response.message) if response.is_a?(Net::HTTPClientError) || response.is_a?(Net::HTTPServerError)
|
56
|
+
|
57
|
+
response
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module SObjectModel
|
2
|
+
module Rest
|
3
|
+
class QueryResult
|
4
|
+
def initialize(api_response)
|
5
|
+
@response = JSON.parse(api_response)
|
6
|
+
end
|
7
|
+
|
8
|
+
def total_size
|
9
|
+
@total_size ||= response['totalSize']
|
10
|
+
end
|
11
|
+
|
12
|
+
def done?
|
13
|
+
@done ||= response['done']
|
14
|
+
end
|
15
|
+
|
16
|
+
alias completed? done?
|
17
|
+
|
18
|
+
def next_records_url
|
19
|
+
@next_records_url ||= response['nextRecordsUrl']
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_records(model_class: nil)
|
23
|
+
records.each_with_object([]) do |h, a|
|
24
|
+
record = prepare_record(h)
|
25
|
+
a << (model_class ? model_class.new(**record) : record)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def response
|
32
|
+
@response
|
33
|
+
end
|
34
|
+
|
35
|
+
def records
|
36
|
+
@records ||= response['records']
|
37
|
+
end
|
38
|
+
|
39
|
+
def prepare_record(hash)
|
40
|
+
hash.delete 'attributes'
|
41
|
+
|
42
|
+
hash.keys.each do |k|
|
43
|
+
if parent?(hash[k])
|
44
|
+
hash[k] = prepare_record(hash[k])
|
45
|
+
elsif children?(hash[k])
|
46
|
+
hash[k] = hash[k]['records'].map{|h| prepare_record(h)}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
hash
|
51
|
+
end
|
52
|
+
|
53
|
+
def children?(h)
|
54
|
+
return false unless h.instance_of?(Hash)
|
55
|
+
|
56
|
+
h.has_key? 'records'
|
57
|
+
end
|
58
|
+
|
59
|
+
def parent?(h)
|
60
|
+
return false unless h.instance_of?(Hash)
|
61
|
+
|
62
|
+
h.has_key?('records') == false
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|