sobjectmodel 0.1.2

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