sobjectmodel 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|