restforce-db 2.2.4 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 101dbf60ce313b7325e3713435eb75b2cbcefdea
4
- data.tar.gz: ae166d81a7584b57b12f5af4c5068f0440122f96
3
+ metadata.gz: 5c353c4cf61985f49453aeb607bbf74ed3cff9d6
4
+ data.tar.gz: 125d5f6afbdb7c2d3701828cfc788877ca15498f
5
5
  SHA512:
6
- metadata.gz: 2bbf27fb680e0ea7eeec3d93c462da66559d1b49f256487c9b01e51cf0579d7738872e6adfdb070ede3035e67774fadd254b9170a26efd3684a2b492cc551810
7
- data.tar.gz: 1344c43c3cf944623b341cc29c37b0a6dab30b723786e1d7b1f6f4a4d6d113cd6fd74acda2efc6ee905289b3643a6f5188ce02118001911d03870885b2bfa6e6
6
+ metadata.gz: 51401160d558e087e8996c711b50df3f2e7eb2c68a2f45bbed155d0bcba0c13e14dc4450cf3c1516ee34b369511caea47a7e6e51a4c19cf83ea62cd7c73d6f2f
7
+ data.tar.gz: 0fd4b9fce1deebb8569657431a8d130e8d9a0abc556c5a31acdd917975a7e55df17e0a750881e08e243d1c5bb64a4d2145ffd81a22ba7f304ba654da6b9df12f
data/lib/restforce/db.rb CHANGED
@@ -31,7 +31,8 @@ require "restforce/db/strategies/always"
31
31
  require "restforce/db/strategies/associated"
32
32
  require "restforce/db/strategies/passive"
33
33
 
34
- require "restforce/db/runner_cache"
34
+ require "restforce/db/record_cache"
35
+ require "restforce/db/timestamp_cache"
35
36
  require "restforce/db/runner"
36
37
 
37
38
  require "restforce/db/accumulator"
@@ -40,6 +40,8 @@ module Restforce
40
40
  #
41
41
  # Returns nothing.
42
42
  def verify_associations(instance)
43
+ return unless instance.synced?
44
+
43
45
  database_instance, salesforce_instance =
44
46
  case instance
45
47
  when Restforce::DB::Instances::Salesforce
@@ -54,6 +54,8 @@ module Restforce
54
54
  #
55
55
  # Returns nothing.
56
56
  def accumulate(instance)
57
+ return unless @runner.changed?(instance)
58
+
57
59
  accumulated_changes[key_for(instance)].store(
58
60
  instance.last_update,
59
61
  instance.attributes,
@@ -42,6 +42,7 @@ module Restforce
42
42
  def create_in_database(instance)
43
43
  return unless @strategy.build?(instance)
44
44
  @mapping.database_record_type.create!(instance)
45
+ @runner.cache_timestamp instance
45
46
  rescue ActiveRecord::ActiveRecordError => e
46
47
  DB.logger.error(SynchronizationError.new(e, instance))
47
48
  end
@@ -56,6 +57,7 @@ module Restforce
56
57
  def create_in_salesforce(instance)
57
58
  return if instance.synced?
58
59
  @mapping.salesforce_record_type.create!(instance)
60
+ @runner.cache_timestamp instance
59
61
  rescue Faraday::Error::ClientError => e
60
62
  DB.logger.error(SynchronizationError.new(e, instance))
61
63
  end
@@ -2,14 +2,14 @@ module Restforce
2
2
 
3
3
  module DB
4
4
 
5
- # Restforce::DB::RunnerCache serves as a means of caching the collections of
5
+ # Restforce::DB::RecordCache serves as a means of caching the collections of
6
6
  # recently-updated database and Salesforce instances for passed mappings.
7
7
  # The general goal is to avoid making repetitive Salesforce API calls or
8
8
  # database queries, and ensure a consistent list of objects during a
9
9
  # synchronization run.
10
- class RunnerCache
10
+ class RecordCache
11
11
 
12
- # Public: Initialize a new Restforce::DB::RunnerCache.
12
+ # Public: Initialize a new Restforce::DB::RecordCache.
13
13
  def initialize
14
14
  reset
15
15
  end
@@ -10,6 +10,13 @@ module Restforce
10
10
  attr_reader :last_run
11
11
  attr_accessor :before, :after
12
12
 
13
+ extend Forwardable
14
+ def_delegators(
15
+ :@timestamp_cache,
16
+ :cache_timestamp,
17
+ :changed?,
18
+ )
19
+
13
20
  # Public: Initialize a new Restforce::DB::Runner.
14
21
  #
15
22
  # delay - A Numeric offet to apply to all record lookups. Can be
@@ -19,7 +26,8 @@ module Restforce
19
26
  def initialize(delay = 0, last_run_time = DB.last_run)
20
27
  @delay = delay
21
28
  @last_run = last_run_time
22
- @cache = RunnerCache.new
29
+ @record_cache = RecordCache.new
30
+ @timestamp_cache = TimestampCache.new
23
31
  end
24
32
 
25
33
  # Public: Indicate that a new phase of the run is beginning. Updates the
@@ -27,7 +35,9 @@ module Restforce
27
35
  #
28
36
  # Returns the new run Time.
29
37
  def tick!
30
- @cache.reset
38
+ @record_cache.reset
39
+ @timestamp_cache.reset
40
+
31
41
  run_time = Time.now
32
42
 
33
43
  @before = run_time - @delay
@@ -54,7 +64,7 @@ module Restforce
54
64
  #
55
65
  # Returns an Enumerator yielding Restforce::DB::Instances::Salesforces.
56
66
  def salesforce_instances
57
- @cache.collection(@mapping, :salesforce_record_type, options)
67
+ @record_cache.collection(@mapping, :salesforce_record_type, options)
58
68
  end
59
69
 
60
70
  # Public: Iterate through recently-updated records for the database model
@@ -62,7 +72,7 @@ module Restforce
62
72
  #
63
73
  # Returns an Enumerator yielding Restforce::DB::Instances::ActiveRecords.
64
74
  def database_instances
65
- @cache.collection(@mapping, :database_record_type, options)
75
+ @record_cache.collection(@mapping, :database_record_type, options)
66
76
  end
67
77
 
68
78
  private
@@ -11,8 +11,9 @@ module Restforce
11
11
  # Public: Initialize a new Restforce::DB::Synchronizer.
12
12
  #
13
13
  # mapping - A Restforce::DB::Mapping.
14
- def initialize(mapping)
14
+ def initialize(mapping, runner = Runner.new)
15
15
  @mapping = mapping
16
+ @runner = runner
16
17
  end
17
18
 
18
19
  # Public: Synchronize records for the current mapping from a Hash of
@@ -67,6 +68,7 @@ module Restforce
67
68
  attributes = @mapping.convert(instance.record_type, current_attributes)
68
69
 
69
70
  instance.update!(attributes)
71
+ @runner.cache_timestamp instance
70
72
  rescue ActiveRecord::ActiveRecordError, Faraday::Error::ClientError => e
71
73
  DB.logger.error(SynchronizationError.new(e, instance))
72
74
  end
@@ -0,0 +1,89 @@
1
+ module Restforce
2
+
3
+ module DB
4
+
5
+ # Restforce::DB::TimestampCache serves to cache the timestamps of the most
6
+ # recent known updates to records through the Restforce::DB system. It
7
+ # allows for more intelligent decision-making regarding what constitutes
8
+ # "stale" data during a synchronization.
9
+ #
10
+ # While we can tell which user _triggered_ the most recent changes to a
11
+ # record in Salesforce, we can't tell if any modifications to that record
12
+ # were a result of a background Apex trigger or workflow (which apply any
13
+ # changes as if they were the user whose actions initiated the callback).
14
+ #
15
+ # In order to distinguish between updates made _by_ the worker and updates
16
+ # made _in response to_ changes by the worker, we have to check the
17
+ # record's update timestamp against the timestamp of the last known update
18
+ # made by the system. This class serves as a mechanism to track the values
19
+ # for this comparison.
20
+ class TimestampCache
21
+
22
+ # Public: Initialize a new Restforce::DB::TimestampCache.
23
+ def initialize
24
+ reset
25
+ end
26
+
27
+ # Public: Add a known update timestamp to the cache for the passed object.
28
+ #
29
+ # instance - A Restforce::DB::Instances::Base.
30
+ #
31
+ # Returns an Array of Restforce::DB::Instances::Base.
32
+ def cache_timestamp(instance)
33
+ @cache[key_for(instance)] = instance.last_update
34
+ end
35
+
36
+ # Public: Get the most recently-stored timestamp for the passed object.
37
+ # Falls back to the retired timestamps to ensure that this run is aware of
38
+ # the modifications made during the previous run.
39
+ #
40
+ # instance - A Restforce::DB::Instances::Base.
41
+ #
42
+ # Returns a Time or nil.
43
+ def timestamp(instance)
44
+ key = key_for(instance)
45
+ @cache.fetch(key) { @retired_cache[key] }
46
+ end
47
+
48
+ # Public: Has the passed instance been modified since the last known
49
+ # system-triggered update? This accounts for changes possibly introduced
50
+ # by callbacks and triggers.
51
+ #
52
+ # instance - A Restforce::DB::Instances::Base.
53
+ #
54
+ # Returns a Boolean.
55
+ def changed?(instance)
56
+ return true unless instance.updated_internally?
57
+
58
+ last_update = timestamp(instance)
59
+ return true unless last_update
60
+
61
+ instance.last_update > last_update
62
+ end
63
+
64
+ # Public: Reset the cache. Expires the previously-cached timestamps, and
65
+ # retires the currently-cached timestamps to ensure that they are only
66
+ # factored into the current synchronization run.
67
+ #
68
+ # Returns nothing.
69
+ def reset
70
+ @retired_cache = @cache || {}
71
+ @cache = {}
72
+ end
73
+
74
+ private
75
+
76
+ # Internal: Get a unique cache key for the passed instance.
77
+ #
78
+ # instance - A Restforce::DB::Instances::Base.
79
+ #
80
+ # Returns an Object.
81
+ def key_for(instance)
82
+ [instance.class, instance.id]
83
+ end
84
+
85
+ end
86
+
87
+ end
88
+
89
+ end
@@ -3,7 +3,7 @@ module Restforce
3
3
  # :nodoc:
4
4
  module DB
5
5
 
6
- VERSION = "2.2.4"
6
+ VERSION = "2.3.0"
7
7
 
8
8
  end
9
9
 
@@ -10,8 +10,11 @@ module Restforce
10
10
  # Raises on update error.
11
11
  def update!(attributes)
12
12
  ensure_id
13
- @client.update!(sobject_type, attributes.merge("Id" => self.Id))
13
+ response = @client.api_patch("sobjects/#{sobject_type}/#{self.Id}", attributes)
14
+ update_time = response.env.response_headers["date"]
15
+
14
16
  merge!(attributes)
17
+ merge!("SystemModstamp" => update_time)
15
18
  end
16
19
 
17
20
  end
@@ -21,10 +21,10 @@ http_interactions:
21
21
  message: OK
22
22
  headers:
23
23
  Date:
24
- - Mon, 08 Jun 2015 22:12:26 GMT
24
+ - Wed, 10 Jun 2015 20:32:44 GMT
25
25
  Set-Cookie:
26
- - BrowserId=IUZDct2tRqSbtEnKBAjLkA;Path=/;Domain=.salesforce.com;Expires=Fri,
27
- 07-Aug-2015 22:12:26 GMT
26
+ - BrowserId=9Hgb4W9BTOiz0oOQfDpBJQ;Path=/;Domain=.salesforce.com;Expires=Sun,
27
+ 09-Aug-2015 20:32:44 GMT
28
28
  Expires:
29
29
  - Thu, 01 Jan 1970 00:00:00 GMT
30
30
  Pragma:
@@ -37,9 +37,9 @@ http_interactions:
37
37
  - chunked
38
38
  body:
39
39
  encoding: ASCII-8BIT
40
- string: '{"id":"https://login.salesforce.com/id/00D1a000000H3O9EAK/0051a000000UGT8AAO","issued_at":"1433801546572","token_type":"Bearer","instance_url":"https://<host>","signature":"eWPqcCY6D2iKBFJv8pRBafWGp81i1uiYtMQhH3ams1A=","access_token":"00D1a000000H3O9!AQ4AQH0rZGqBVji7vO4sB8J1_YW.g5S2vIbe9IaUgwHpwLPEdpfIcj9Ngpc2CndFvJZMwVIIp15.yQQOil19Qc2MuedbnlQz"}'
40
+ string: '{"id":"https://login.salesforce.com/id/00D1a000000H3O9EAK/0051a000000UGT8AAO","issued_at":"1433968364523","token_type":"Bearer","instance_url":"https://<host>","signature":"zcpougnZQ2racBXMLaAcuvkzZwe1/RR0A8tzoGprA3A=","access_token":"00D1a000000H3O9!AQ4AQGzO6cHltgvJmAqci.NyJL0_69pRzwnlpfIuBhSFZZ9eTNfL3boDM7Q1rZgxPeBiO43MEzeFl0F6uHCKElAgVLWxmICJ"}'
41
41
  http_version:
42
- recorded_at: Mon, 08 Jun 2015 22:12:28 GMT
42
+ recorded_at: Wed, 10 Jun 2015 20:32:44 GMT
43
43
  - request:
44
44
  method: post
45
45
  uri: https://<host>/services/data/<api_version>/sobjects/CustomObject__c
@@ -52,7 +52,7 @@ http_interactions:
52
52
  Content-Type:
53
53
  - application/json
54
54
  Authorization:
55
- - OAuth 00D1a000000H3O9!AQ4AQH0rZGqBVji7vO4sB8J1_YW.g5S2vIbe9IaUgwHpwLPEdpfIcj9Ngpc2CndFvJZMwVIIp15.yQQOil19Qc2MuedbnlQz
55
+ - OAuth 00D1a000000H3O9!AQ4AQGzO6cHltgvJmAqci.NyJL0_69pRzwnlpfIuBhSFZZ9eTNfL3boDM7Q1rZgxPeBiO43MEzeFl0F6uHCKElAgVLWxmICJ
56
56
  Accept-Encoding:
57
57
  - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
58
58
  Accept:
@@ -63,28 +63,28 @@ http_interactions:
63
63
  message: Created
64
64
  headers:
65
65
  Date:
66
- - Mon, 08 Jun 2015 22:12:26 GMT
66
+ - Wed, 10 Jun 2015 20:32:45 GMT
67
67
  Set-Cookie:
68
- - BrowserId=2hj5KwxMTnyS57eKQkeL-A;Path=/;Domain=.salesforce.com;Expires=Fri,
69
- 07-Aug-2015 22:12:26 GMT
68
+ - BrowserId=6Kjpln3uTfWvUxegpDoqzg;Path=/;Domain=.salesforce.com;Expires=Sun,
69
+ 09-Aug-2015 20:32:45 GMT
70
70
  Expires:
71
71
  - Thu, 01 Jan 1970 00:00:00 GMT
72
72
  Sforce-Limit-Info:
73
- - api-usage=9/15000
73
+ - api-usage=26/15000
74
74
  Location:
75
- - "/services/data/<api_version>/sobjects/CustomObject__c/a001a000001cF4vAAE"
75
+ - "/services/data/<api_version>/sobjects/CustomObject__c/a001a000001cNTxAAM"
76
76
  Content-Type:
77
77
  - application/json;charset=UTF-8
78
78
  Transfer-Encoding:
79
79
  - chunked
80
80
  body:
81
81
  encoding: ASCII-8BIT
82
- string: '{"id":"a001a000001cF4vAAE","success":true,"errors":[]}'
82
+ string: '{"id":"a001a000001cNTxAAM","success":true,"errors":[]}'
83
83
  http_version:
84
- recorded_at: Mon, 08 Jun 2015 22:12:28 GMT
84
+ recorded_at: Wed, 10 Jun 2015 20:32:45 GMT
85
85
  - request:
86
86
  method: get
87
- uri: https://<host>/services/data/<api_version>/query?q=select%20Id,%20SystemModstamp,%20LastModifiedById,%20Name,%20Example_Field__c%20from%20CustomObject__c%20where%20Id%20=%20%27a001a000001cF4vAAE%27
87
+ uri: https://<host>/services/data/<api_version>/query?q=select%20Id,%20SystemModstamp,%20LastModifiedById,%20Name,%20Example_Field__c%20from%20CustomObject__c%20where%20Id%20=%20%27a001a000001cNTxAAM%27
88
88
  body:
89
89
  encoding: US-ASCII
90
90
  string: ''
@@ -92,7 +92,7 @@ http_interactions:
92
92
  User-Agent:
93
93
  - Faraday v0.9.1
94
94
  Authorization:
95
- - OAuth 00D1a000000H3O9!AQ4AQH0rZGqBVji7vO4sB8J1_YW.g5S2vIbe9IaUgwHpwLPEdpfIcj9Ngpc2CndFvJZMwVIIp15.yQQOil19Qc2MuedbnlQz
95
+ - OAuth 00D1a000000H3O9!AQ4AQGzO6cHltgvJmAqci.NyJL0_69pRzwnlpfIuBhSFZZ9eTNfL3boDM7Q1rZgxPeBiO43MEzeFl0F6uHCKElAgVLWxmICJ
96
96
  Accept-Encoding:
97
97
  - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
98
98
  Accept:
@@ -103,24 +103,24 @@ http_interactions:
103
103
  message: OK
104
104
  headers:
105
105
  Date:
106
- - Mon, 08 Jun 2015 22:12:26 GMT
106
+ - Wed, 10 Jun 2015 20:32:46 GMT
107
107
  Set-Cookie:
108
- - BrowserId=_JZ2ryP4TlOZ6qkKrYZrkw;Path=/;Domain=.salesforce.com;Expires=Fri,
109
- 07-Aug-2015 22:12:26 GMT
108
+ - BrowserId=C41i4AOPQL2EQtrWf-LKkQ;Path=/;Domain=.salesforce.com;Expires=Sun,
109
+ 09-Aug-2015 20:32:46 GMT
110
110
  Expires:
111
111
  - Thu, 01 Jan 1970 00:00:00 GMT
112
112
  Sforce-Limit-Info:
113
- - api-usage=8/15000
113
+ - api-usage=26/15000
114
114
  Content-Type:
115
115
  - application/json;charset=UTF-8
116
116
  Transfer-Encoding:
117
117
  - chunked
118
118
  body:
119
119
  encoding: ASCII-8BIT
120
- string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"CustomObject__c","url":"/services/data/<api_version>/sobjects/CustomObject__c/a001a000001cF4vAAE"},"Id":"a001a000001cF4vAAE","SystemModstamp":"2015-06-08T22:12:26.000+0000","LastModifiedById":"0051a000000UGT8AAO","Name":"Custom
120
+ string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"CustomObject__c","url":"/services/data/<api_version>/sobjects/CustomObject__c/a001a000001cNTxAAM"},"Id":"a001a000001cNTxAAM","SystemModstamp":"2015-06-10T20:32:45.000+0000","LastModifiedById":"0051a000000UGT8AAO","Name":"Custom
121
121
  object","Example_Field__c":"Some sample text"}]}'
122
122
  http_version:
123
- recorded_at: Mon, 08 Jun 2015 22:12:28 GMT
123
+ recorded_at: Wed, 10 Jun 2015 20:32:46 GMT
124
124
  - request:
125
125
  method: get
126
126
  uri: https://<host>/services/data/<api_version>/query?q=select%20Id,%20SystemModstamp,%20LastModifiedById,%20Name,%20Example_Field__c%20from%20CustomObject__c
@@ -131,7 +131,7 @@ http_interactions:
131
131
  User-Agent:
132
132
  - Faraday v0.9.1
133
133
  Authorization:
134
- - OAuth 00D1a000000H3O9!AQ4AQH0rZGqBVji7vO4sB8J1_YW.g5S2vIbe9IaUgwHpwLPEdpfIcj9Ngpc2CndFvJZMwVIIp15.yQQOil19Qc2MuedbnlQz
134
+ - OAuth 00D1a000000H3O9!AQ4AQGzO6cHltgvJmAqci.NyJL0_69pRzwnlpfIuBhSFZZ9eTNfL3boDM7Q1rZgxPeBiO43MEzeFl0F6uHCKElAgVLWxmICJ
135
135
  Accept-Encoding:
136
136
  - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
137
137
  Accept:
@@ -142,27 +142,103 @@ http_interactions:
142
142
  message: OK
143
143
  headers:
144
144
  Date:
145
- - Mon, 08 Jun 2015 22:12:27 GMT
145
+ - Wed, 10 Jun 2015 20:32:47 GMT
146
146
  Set-Cookie:
147
- - BrowserId=4BMkj87_RF2aLa2fDpaD5Q;Path=/;Domain=.salesforce.com;Expires=Fri,
148
- 07-Aug-2015 22:12:27 GMT
147
+ - BrowserId=xpCMtB2bSyaAx3uzaOnq1A;Path=/;Domain=.salesforce.com;Expires=Sun,
148
+ 09-Aug-2015 20:32:47 GMT
149
149
  Expires:
150
150
  - Thu, 01 Jan 1970 00:00:00 GMT
151
151
  Sforce-Limit-Info:
152
- - api-usage=8/15000
152
+ - api-usage=26/15000
153
153
  Content-Type:
154
154
  - application/json;charset=UTF-8
155
155
  Transfer-Encoding:
156
156
  - chunked
157
157
  body:
158
158
  encoding: ASCII-8BIT
159
- string: '{"totalSize":2,"done":true,"records":[{"attributes":{"type":"CustomObject__c","url":"/services/data/<api_version>/sobjects/CustomObject__c/a001a000001a60JAAQ"},"Id":"a001a000001a60JAAQ","SystemModstamp":"2015-05-18T22:46:05.000+0000","LastModifiedById":"0051a000000UGT8AAO","Name":"SAMPLE","Example_Field__c":null},{"attributes":{"type":"CustomObject__c","url":"/services/data/<api_version>/sobjects/CustomObject__c/a001a000001cF4vAAE"},"Id":"a001a000001cF4vAAE","SystemModstamp":"2015-06-08T22:12:26.000+0000","LastModifiedById":"0051a000000UGT8AAO","Name":"Custom
159
+ string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"CustomObject__c","url":"/services/data/<api_version>/sobjects/CustomObject__c/a001a000001cNTxAAM"},"Id":"a001a000001cNTxAAM","SystemModstamp":"2015-06-10T20:32:45.000+0000","LastModifiedById":"0051a000000UGT8AAO","Name":"Custom
160
160
  object","Example_Field__c":"Some sample text"}]}'
161
161
  http_version:
162
- recorded_at: Mon, 08 Jun 2015 22:12:28 GMT
162
+ recorded_at: Wed, 10 Jun 2015 20:32:47 GMT
163
+ - request:
164
+ method: get
165
+ uri: https://<host>/services/data/<api_version>/
166
+ body:
167
+ encoding: US-ASCII
168
+ string: ''
169
+ headers:
170
+ User-Agent:
171
+ - Faraday v0.9.1
172
+ Authorization:
173
+ - OAuth 00D1a000000H3O9!AQ4AQGzO6cHltgvJmAqci.NyJL0_69pRzwnlpfIuBhSFZZ9eTNfL3boDM7Q1rZgxPeBiO43MEzeFl0F6uHCKElAgVLWxmICJ
174
+ Accept-Encoding:
175
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
176
+ Accept:
177
+ - "*/*"
178
+ response:
179
+ status:
180
+ code: 200
181
+ message: OK
182
+ headers:
183
+ Date:
184
+ - Wed, 10 Jun 2015 20:32:48 GMT
185
+ Set-Cookie:
186
+ - BrowserId=QD5WY6z2Qiq-7x6swz6Uhg;Path=/;Domain=.salesforce.com;Expires=Sun,
187
+ 09-Aug-2015 20:32:48 GMT
188
+ Expires:
189
+ - Thu, 01 Jan 1970 00:00:00 GMT
190
+ Sforce-Limit-Info:
191
+ - api-usage=26/15000
192
+ Content-Type:
193
+ - application/json;charset=UTF-8
194
+ Transfer-Encoding:
195
+ - chunked
196
+ body:
197
+ encoding: ASCII-8BIT
198
+ string: '{"limits":"/services/data/<api_version>/limits","sobjects":"/services/data/<api_version>/sobjects","connect":"/services/data/<api_version>/connect","query":"/services/data/<api_version>/query","theme":"/services/data/<api_version>/theme","queryAll":"/services/data/<api_version>/queryAll","tooling":"/services/data/<api_version>/tooling","chatter":"/services/data/<api_version>/chatter","analytics":"/services/data/<api_version>/analytics","recent":"/services/data/<api_version>/recent","commerce":"/services/data/<api_version>/commerce","licensing":"/services/data/<api_version>/licensing","identity":"https://login.salesforce.com/id/00D1a000000H3O9EAK/0051a000000UGT8AAO","flexiPage":"/services/data/<api_version>/flexiPage","search":"/services/data/<api_version>/search","quickActions":"/services/data/<api_version>/quickActions","appMenu":"/services/data/<api_version>/appMenu"}'
199
+ http_version:
200
+ recorded_at: Wed, 10 Jun 2015 20:32:48 GMT
201
+ - request:
202
+ method: get
203
+ uri: https://login.salesforce.com/id/00D1a000000H3O9EAK/0051a000000UGT8AAO
204
+ body:
205
+ encoding: US-ASCII
206
+ string: ''
207
+ headers:
208
+ User-Agent:
209
+ - Faraday v0.9.1
210
+ Authorization:
211
+ - OAuth 00D1a000000H3O9!AQ4AQGzO6cHltgvJmAqci.NyJL0_69pRzwnlpfIuBhSFZZ9eTNfL3boDM7Q1rZgxPeBiO43MEzeFl0F6uHCKElAgVLWxmICJ
212
+ Accept-Encoding:
213
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
214
+ Accept:
215
+ - "*/*"
216
+ response:
217
+ status:
218
+ code: 200
219
+ message: OK
220
+ headers:
221
+ Date:
222
+ - Wed, 10 Jun 2015 20:32:48 GMT
223
+ - Wed, 10 Jun 2015 20:32:48 GMT
224
+ Set-Cookie:
225
+ - BrowserId=rzInOdn_Sj-cfQNluztySw;Path=/;Domain=.salesforce.com;Expires=Sun,
226
+ 09-Aug-2015 20:32:48 GMT
227
+ Expires:
228
+ - Thu, 01 Jan 1970 00:00:00 GMT
229
+ Content-Type:
230
+ - application/json;charset=UTF-8
231
+ Transfer-Encoding:
232
+ - chunked
233
+ body:
234
+ encoding: ASCII-8BIT
235
+ string: '{"id":"https://login.salesforce.com/id/00D1a000000H3O9EAK/0051a000000UGT8AAO","asserted_user":true,"user_id":"0051a000000UGT8AAO","organization_id":"00D1a000000H3O9EAK","username":"andrew+salesforce@tablexi.com","nick_name":"andrew+salesforce1.42656567106328E12","display_name":"Andrew
236
+ Horner","email":"andrew@tablexi.com","email_verified":true,"first_name":"Andrew","last_name":"Horner","timezone":"America/Los_Angeles","photos":{"picture":"https://c.na24.content.force.com/profilephoto/005/F","thumbnail":"https://c.na24.content.force.com/profilephoto/005/T"},"addr_street":null,"addr_city":null,"addr_state":null,"addr_country":"US","addr_zip":"60661","mobile_phone":null,"mobile_phone_verified":false,"status":{"created_date":null,"body":null},"urls":{"enterprise":"https://<host>/services/Soap/c/{version}/00D1a000000H3O9","metadata":"https://<host>/services/Soap/m/{version}/00D1a000000H3O9","partner":"https://<host>/services/Soap/u/{version}/00D1a000000H3O9","rest":"https://<host>/services/data/v{version}/","sobjects":"https://<host>/services/data/v{version}/sobjects/","search":"https://<host>/services/data/v{version}/search/","query":"https://<host>/services/data/v{version}/query/","recent":"https://<host>/services/data/v{version}/recent/","profile":"https://<host>/0051a000000UGT8AAO","feeds":"https://<host>/services/data/v{version}/chatter/feeds","groups":"https://<host>/services/data/v{version}/chatter/groups","users":"https://<host>/services/data/v{version}/chatter/users","feed_items":"https://<host>/services/data/v{version}/chatter/feed-items"},"active":true,"user_type":"STANDARD","language":"en_US","locale":"en_US","utcOffset":-28800000,"last_modified_date":"2015-03-17T04:14:23.000+0000","is_app_installed":true}'
237
+ http_version:
238
+ recorded_at: Wed, 10 Jun 2015 20:32:48 GMT
163
239
  - request:
164
240
  method: delete
165
- uri: https://<host>/services/data/<api_version>/sobjects/CustomObject__c/a001a000001cF4vAAE
241
+ uri: https://<host>/services/data/<api_version>/sobjects/CustomObject__c/a001a000001cNTxAAM
166
242
  body:
167
243
  encoding: US-ASCII
168
244
  string: ''
@@ -170,7 +246,7 @@ http_interactions:
170
246
  User-Agent:
171
247
  - Faraday v0.9.1
172
248
  Authorization:
173
- - OAuth 00D1a000000H3O9!AQ4AQH0rZGqBVji7vO4sB8J1_YW.g5S2vIbe9IaUgwHpwLPEdpfIcj9Ngpc2CndFvJZMwVIIp15.yQQOil19Qc2MuedbnlQz
249
+ - OAuth 00D1a000000H3O9!AQ4AQGzO6cHltgvJmAqci.NyJL0_69pRzwnlpfIuBhSFZZ9eTNfL3boDM7Q1rZgxPeBiO43MEzeFl0F6uHCKElAgVLWxmICJ
174
250
  Accept-Encoding:
175
251
  - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
176
252
  Accept:
@@ -181,17 +257,17 @@ http_interactions:
181
257
  message: No Content
182
258
  headers:
183
259
  Date:
184
- - Mon, 08 Jun 2015 22:12:27 GMT
260
+ - Wed, 10 Jun 2015 20:32:49 GMT
185
261
  Set-Cookie:
186
- - BrowserId=cRMxZ9gSSN2YVrMFxyeCEw;Path=/;Domain=.salesforce.com;Expires=Fri,
187
- 07-Aug-2015 22:12:27 GMT
262
+ - BrowserId=-imEDwZ0TCanwP026i4teQ;Path=/;Domain=.salesforce.com;Expires=Sun,
263
+ 09-Aug-2015 20:32:49 GMT
188
264
  Expires:
189
265
  - Thu, 01 Jan 1970 00:00:00 GMT
190
266
  Sforce-Limit-Info:
191
- - api-usage=9/15000
267
+ - api-usage=26/15000
192
268
  body:
193
269
  encoding: UTF-8
194
270
  string: ''
195
271
  http_version:
196
- recorded_at: Mon, 08 Jun 2015 22:12:28 GMT
272
+ recorded_at: Wed, 10 Jun 2015 20:32:49 GMT
197
273
  recorded_with: VCR 2.9.3
@@ -21,10 +21,10 @@ http_interactions:
21
21
  message: OK
22
22
  headers:
23
23
  Date:
24
- - Mon, 08 Jun 2015 22:12:45 GMT
24
+ - Wed, 10 Jun 2015 20:32:51 GMT
25
25
  Set-Cookie:
26
- - BrowserId=WKJBDf2wS9yoOjMIgd5GVg;Path=/;Domain=.salesforce.com;Expires=Fri,
27
- 07-Aug-2015 22:12:45 GMT
26
+ - BrowserId=VUztcA6iRlGDBRaknItakA;Path=/;Domain=.salesforce.com;Expires=Sun,
27
+ 09-Aug-2015 20:32:51 GMT
28
28
  Expires:
29
29
  - Thu, 01 Jan 1970 00:00:00 GMT
30
30
  Pragma:
@@ -37,9 +37,9 @@ http_interactions:
37
37
  - chunked
38
38
  body:
39
39
  encoding: ASCII-8BIT
40
- string: '{"id":"https://login.salesforce.com/id/00D1a000000H3O9EAK/0051a000000UGT8AAO","issued_at":"1433801565981","token_type":"Bearer","instance_url":"https://<host>","signature":"tcufiqR1IVzUzMvBFfvPgcLtI2Xh/s0F+UZJ22yVee0=","access_token":"00D1a000000H3O9!AQ4AQH0rZGqBVji7vO4sB8J1_YW.g5S2vIbe9IaUgwHpwLPEdpfIcj9Ngpc2CndFvJZMwVIIp15.yQQOil19Qc2MuedbnlQz"}'
40
+ string: '{"id":"https://login.salesforce.com/id/00D1a000000H3O9EAK/0051a000000UGT8AAO","issued_at":"1433968371999","token_type":"Bearer","instance_url":"https://<host>","signature":"Gdo4VHqHus3ySFTTeVS1NBTTeTOcpAxwrCNjZIJrh9E=","access_token":"00D1a000000H3O9!AQ4AQGzO6cHltgvJmAqci.NyJL0_69pRzwnlpfIuBhSFZZ9eTNfL3boDM7Q1rZgxPeBiO43MEzeFl0F6uHCKElAgVLWxmICJ"}'
41
41
  http_version:
42
- recorded_at: Mon, 08 Jun 2015 22:12:47 GMT
42
+ recorded_at: Wed, 10 Jun 2015 20:32:52 GMT
43
43
  - request:
44
44
  method: post
45
45
  uri: https://<host>/services/data/<api_version>/sobjects/CustomObject__c
@@ -52,7 +52,7 @@ http_interactions:
52
52
  Content-Type:
53
53
  - application/json
54
54
  Authorization:
55
- - OAuth 00D1a000000H3O9!AQ4AQH0rZGqBVji7vO4sB8J1_YW.g5S2vIbe9IaUgwHpwLPEdpfIcj9Ngpc2CndFvJZMwVIIp15.yQQOil19Qc2MuedbnlQz
55
+ - OAuth 00D1a000000H3O9!AQ4AQGzO6cHltgvJmAqci.NyJL0_69pRzwnlpfIuBhSFZZ9eTNfL3boDM7Q1rZgxPeBiO43MEzeFl0F6uHCKElAgVLWxmICJ
56
56
  Accept-Encoding:
57
57
  - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
58
58
  Accept:
@@ -63,28 +63,28 @@ http_interactions:
63
63
  message: Created
64
64
  headers:
65
65
  Date:
66
- - Mon, 08 Jun 2015 22:12:46 GMT
66
+ - Wed, 10 Jun 2015 20:32:52 GMT
67
67
  Set-Cookie:
68
- - BrowserId=bxs8gUr1T-2ytKX8wxVUrQ;Path=/;Domain=.salesforce.com;Expires=Fri,
69
- 07-Aug-2015 22:12:46 GMT
68
+ - BrowserId=OK9bQk3lSAytj-uLDKBRzg;Path=/;Domain=.salesforce.com;Expires=Sun,
69
+ 09-Aug-2015 20:32:52 GMT
70
70
  Expires:
71
71
  - Thu, 01 Jan 1970 00:00:00 GMT
72
72
  Sforce-Limit-Info:
73
- - api-usage=29/15000
73
+ - api-usage=26/15000
74
74
  Location:
75
- - "/services/data/<api_version>/sobjects/CustomObject__c/a001a000001cF5tAAE"
75
+ - "/services/data/<api_version>/sobjects/CustomObject__c/a001a000001cNU2AAM"
76
76
  Content-Type:
77
77
  - application/json;charset=UTF-8
78
78
  Transfer-Encoding:
79
79
  - chunked
80
80
  body:
81
81
  encoding: ASCII-8BIT
82
- string: '{"id":"a001a000001cF5tAAE","success":true,"errors":[]}'
82
+ string: '{"id":"a001a000001cNU2AAM","success":true,"errors":[]}'
83
83
  http_version:
84
- recorded_at: Mon, 08 Jun 2015 22:12:47 GMT
84
+ recorded_at: Wed, 10 Jun 2015 20:32:53 GMT
85
85
  - request:
86
86
  method: get
87
- uri: https://<host>/services/data/<api_version>/query?q=select%20Id,%20SystemModstamp,%20LastModifiedById,%20Name,%20Example_Field__c%20from%20CustomObject__c%20where%20Id%20=%20%27a001a000001cF5tAAE%27
87
+ uri: https://<host>/services/data/<api_version>/query?q=select%20Id,%20SystemModstamp,%20LastModifiedById,%20Name,%20Example_Field__c%20from%20CustomObject__c%20where%20Id%20=%20%27a001a000001cNU2AAM%27
88
88
  body:
89
89
  encoding: US-ASCII
90
90
  string: ''
@@ -92,7 +92,7 @@ http_interactions:
92
92
  User-Agent:
93
93
  - Faraday v0.9.1
94
94
  Authorization:
95
- - OAuth 00D1a000000H3O9!AQ4AQH0rZGqBVji7vO4sB8J1_YW.g5S2vIbe9IaUgwHpwLPEdpfIcj9Ngpc2CndFvJZMwVIIp15.yQQOil19Qc2MuedbnlQz
95
+ - OAuth 00D1a000000H3O9!AQ4AQGzO6cHltgvJmAqci.NyJL0_69pRzwnlpfIuBhSFZZ9eTNfL3boDM7Q1rZgxPeBiO43MEzeFl0F6uHCKElAgVLWxmICJ
96
96
  Accept-Encoding:
97
97
  - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
98
98
  Accept:
@@ -103,10 +103,10 @@ http_interactions:
103
103
  message: OK
104
104
  headers:
105
105
  Date:
106
- - Mon, 08 Jun 2015 22:12:46 GMT
106
+ - Wed, 10 Jun 2015 20:32:53 GMT
107
107
  Set-Cookie:
108
- - BrowserId=vQbLE1ABSQuNHocFh6nwqg;Path=/;Domain=.salesforce.com;Expires=Fri,
109
- 07-Aug-2015 22:12:46 GMT
108
+ - BrowserId=-asaRzgaTIeZsCe8KyGMdg;Path=/;Domain=.salesforce.com;Expires=Sun,
109
+ 09-Aug-2015 20:32:53 GMT
110
110
  Expires:
111
111
  - Thu, 01 Jan 1970 00:00:00 GMT
112
112
  Sforce-Limit-Info:
@@ -117,10 +117,10 @@ http_interactions:
117
117
  - chunked
118
118
  body:
119
119
  encoding: ASCII-8BIT
120
- string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"CustomObject__c","url":"/services/data/<api_version>/sobjects/CustomObject__c/a001a000001cF5tAAE"},"Id":"a001a000001cF5tAAE","SystemModstamp":"2015-06-08T22:12:46.000+0000","LastModifiedById":"0051a000000UGT8AAO","Name":"Custom
120
+ string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"CustomObject__c","url":"/services/data/<api_version>/sobjects/CustomObject__c/a001a000001cNU2AAM"},"Id":"a001a000001cNU2AAM","SystemModstamp":"2015-06-10T20:32:52.000+0000","LastModifiedById":"0051a000000UGT8AAO","Name":"Custom
121
121
  object","Example_Field__c":"Some sample text"}]}'
122
122
  http_version:
123
- recorded_at: Mon, 08 Jun 2015 22:12:47 GMT
123
+ recorded_at: Wed, 10 Jun 2015 20:32:53 GMT
124
124
  - request:
125
125
  method: get
126
126
  uri: https://<host>/services/data/<api_version>/query?q=select%20Id,%20SystemModstamp,%20LastModifiedById,%20Name,%20Example_Field__c%20from%20CustomObject__c
@@ -131,7 +131,7 @@ http_interactions:
131
131
  User-Agent:
132
132
  - Faraday v0.9.1
133
133
  Authorization:
134
- - OAuth 00D1a000000H3O9!AQ4AQH0rZGqBVji7vO4sB8J1_YW.g5S2vIbe9IaUgwHpwLPEdpfIcj9Ngpc2CndFvJZMwVIIp15.yQQOil19Qc2MuedbnlQz
134
+ - OAuth 00D1a000000H3O9!AQ4AQGzO6cHltgvJmAqci.NyJL0_69pRzwnlpfIuBhSFZZ9eTNfL3boDM7Q1rZgxPeBiO43MEzeFl0F6uHCKElAgVLWxmICJ
135
135
  Accept-Encoding:
136
136
  - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
137
137
  Accept:
@@ -142,27 +142,103 @@ http_interactions:
142
142
  message: OK
143
143
  headers:
144
144
  Date:
145
- - Mon, 08 Jun 2015 22:12:46 GMT
145
+ - Wed, 10 Jun 2015 20:32:54 GMT
146
146
  Set-Cookie:
147
- - BrowserId=q3u3iCrgSqaR3zeQeQ284Q;Path=/;Domain=.salesforce.com;Expires=Fri,
148
- 07-Aug-2015 22:12:46 GMT
147
+ - BrowserId=E_Ig06iqR46y3L2bOPDuqg;Path=/;Domain=.salesforce.com;Expires=Sun,
148
+ 09-Aug-2015 20:32:54 GMT
149
149
  Expires:
150
150
  - Thu, 01 Jan 1970 00:00:00 GMT
151
151
  Sforce-Limit-Info:
152
- - api-usage=27/15000
152
+ - api-usage=29/15000
153
153
  Content-Type:
154
154
  - application/json;charset=UTF-8
155
155
  Transfer-Encoding:
156
156
  - chunked
157
157
  body:
158
158
  encoding: ASCII-8BIT
159
- string: '{"totalSize":2,"done":true,"records":[{"attributes":{"type":"CustomObject__c","url":"/services/data/<api_version>/sobjects/CustomObject__c/a001a000001a60JAAQ"},"Id":"a001a000001a60JAAQ","SystemModstamp":"2015-05-18T22:46:05.000+0000","LastModifiedById":"0051a000000UGT8AAO","Name":"SAMPLE","Example_Field__c":null},{"attributes":{"type":"CustomObject__c","url":"/services/data/<api_version>/sobjects/CustomObject__c/a001a000001cF5tAAE"},"Id":"a001a000001cF5tAAE","SystemModstamp":"2015-06-08T22:12:46.000+0000","LastModifiedById":"0051a000000UGT8AAO","Name":"Custom
159
+ string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"CustomObject__c","url":"/services/data/<api_version>/sobjects/CustomObject__c/a001a000001cNU2AAM"},"Id":"a001a000001cNU2AAM","SystemModstamp":"2015-06-10T20:32:52.000+0000","LastModifiedById":"0051a000000UGT8AAO","Name":"Custom
160
160
  object","Example_Field__c":"Some sample text"}]}'
161
161
  http_version:
162
- recorded_at: Mon, 08 Jun 2015 22:12:48 GMT
162
+ recorded_at: Wed, 10 Jun 2015 20:32:54 GMT
163
+ - request:
164
+ method: get
165
+ uri: https://<host>/services/data/<api_version>/
166
+ body:
167
+ encoding: US-ASCII
168
+ string: ''
169
+ headers:
170
+ User-Agent:
171
+ - Faraday v0.9.1
172
+ Authorization:
173
+ - OAuth 00D1a000000H3O9!AQ4AQGzO6cHltgvJmAqci.NyJL0_69pRzwnlpfIuBhSFZZ9eTNfL3boDM7Q1rZgxPeBiO43MEzeFl0F6uHCKElAgVLWxmICJ
174
+ Accept-Encoding:
175
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
176
+ Accept:
177
+ - "*/*"
178
+ response:
179
+ status:
180
+ code: 200
181
+ message: OK
182
+ headers:
183
+ Date:
184
+ - Wed, 10 Jun 2015 20:32:55 GMT
185
+ Set-Cookie:
186
+ - BrowserId=zGfAmh7wQiaDTLAhC3fFlA;Path=/;Domain=.salesforce.com;Expires=Sun,
187
+ 09-Aug-2015 20:32:55 GMT
188
+ Expires:
189
+ - Thu, 01 Jan 1970 00:00:00 GMT
190
+ Sforce-Limit-Info:
191
+ - api-usage=28/15000
192
+ Content-Type:
193
+ - application/json;charset=UTF-8
194
+ Transfer-Encoding:
195
+ - chunked
196
+ body:
197
+ encoding: ASCII-8BIT
198
+ string: '{"limits":"/services/data/<api_version>/limits","sobjects":"/services/data/<api_version>/sobjects","connect":"/services/data/<api_version>/connect","query":"/services/data/<api_version>/query","theme":"/services/data/<api_version>/theme","queryAll":"/services/data/<api_version>/queryAll","tooling":"/services/data/<api_version>/tooling","chatter":"/services/data/<api_version>/chatter","analytics":"/services/data/<api_version>/analytics","recent":"/services/data/<api_version>/recent","commerce":"/services/data/<api_version>/commerce","licensing":"/services/data/<api_version>/licensing","identity":"https://login.salesforce.com/id/00D1a000000H3O9EAK/0051a000000UGT8AAO","flexiPage":"/services/data/<api_version>/flexiPage","search":"/services/data/<api_version>/search","quickActions":"/services/data/<api_version>/quickActions","appMenu":"/services/data/<api_version>/appMenu"}'
199
+ http_version:
200
+ recorded_at: Wed, 10 Jun 2015 20:32:55 GMT
201
+ - request:
202
+ method: get
203
+ uri: https://login.salesforce.com/id/00D1a000000H3O9EAK/0051a000000UGT8AAO
204
+ body:
205
+ encoding: US-ASCII
206
+ string: ''
207
+ headers:
208
+ User-Agent:
209
+ - Faraday v0.9.1
210
+ Authorization:
211
+ - OAuth 00D1a000000H3O9!AQ4AQGzO6cHltgvJmAqci.NyJL0_69pRzwnlpfIuBhSFZZ9eTNfL3boDM7Q1rZgxPeBiO43MEzeFl0F6uHCKElAgVLWxmICJ
212
+ Accept-Encoding:
213
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
214
+ Accept:
215
+ - "*/*"
216
+ response:
217
+ status:
218
+ code: 200
219
+ message: OK
220
+ headers:
221
+ Date:
222
+ - Wed, 10 Jun 2015 20:32:55 GMT
223
+ - Wed, 10 Jun 2015 20:32:55 GMT
224
+ Set-Cookie:
225
+ - BrowserId=Y6ll11VqRRum-UtA8HbU_Q;Path=/;Domain=.salesforce.com;Expires=Sun,
226
+ 09-Aug-2015 20:32:55 GMT
227
+ Expires:
228
+ - Thu, 01 Jan 1970 00:00:00 GMT
229
+ Content-Type:
230
+ - application/json;charset=UTF-8
231
+ Transfer-Encoding:
232
+ - chunked
233
+ body:
234
+ encoding: ASCII-8BIT
235
+ string: '{"id":"https://login.salesforce.com/id/00D1a000000H3O9EAK/0051a000000UGT8AAO","asserted_user":true,"user_id":"0051a000000UGT8AAO","organization_id":"00D1a000000H3O9EAK","username":"andrew+salesforce@tablexi.com","nick_name":"andrew+salesforce1.42656567106328E12","display_name":"Andrew
236
+ Horner","email":"andrew@tablexi.com","email_verified":true,"first_name":"Andrew","last_name":"Horner","timezone":"America/Los_Angeles","photos":{"picture":"https://c.na24.content.force.com/profilephoto/005/F","thumbnail":"https://c.na24.content.force.com/profilephoto/005/T"},"addr_street":null,"addr_city":null,"addr_state":null,"addr_country":"US","addr_zip":"60661","mobile_phone":null,"mobile_phone_verified":false,"status":{"created_date":null,"body":null},"urls":{"enterprise":"https://<host>/services/Soap/c/{version}/00D1a000000H3O9","metadata":"https://<host>/services/Soap/m/{version}/00D1a000000H3O9","partner":"https://<host>/services/Soap/u/{version}/00D1a000000H3O9","rest":"https://<host>/services/data/v{version}/","sobjects":"https://<host>/services/data/v{version}/sobjects/","search":"https://<host>/services/data/v{version}/search/","query":"https://<host>/services/data/v{version}/query/","recent":"https://<host>/services/data/v{version}/recent/","profile":"https://<host>/0051a000000UGT8AAO","feeds":"https://<host>/services/data/v{version}/chatter/feeds","groups":"https://<host>/services/data/v{version}/chatter/groups","users":"https://<host>/services/data/v{version}/chatter/users","feed_items":"https://<host>/services/data/v{version}/chatter/feed-items"},"active":true,"user_type":"STANDARD","language":"en_US","locale":"en_US","utcOffset":-28800000,"last_modified_date":"2015-03-17T04:14:23.000+0000","is_app_installed":true}'
237
+ http_version:
238
+ recorded_at: Wed, 10 Jun 2015 20:32:55 GMT
163
239
  - request:
164
240
  method: delete
165
- uri: https://<host>/services/data/<api_version>/sobjects/CustomObject__c/a001a000001cF5tAAE
241
+ uri: https://<host>/services/data/<api_version>/sobjects/CustomObject__c/a001a000001cNU2AAM
166
242
  body:
167
243
  encoding: US-ASCII
168
244
  string: ''
@@ -170,7 +246,7 @@ http_interactions:
170
246
  User-Agent:
171
247
  - Faraday v0.9.1
172
248
  Authorization:
173
- - OAuth 00D1a000000H3O9!AQ4AQH0rZGqBVji7vO4sB8J1_YW.g5S2vIbe9IaUgwHpwLPEdpfIcj9Ngpc2CndFvJZMwVIIp15.yQQOil19Qc2MuedbnlQz
249
+ - OAuth 00D1a000000H3O9!AQ4AQGzO6cHltgvJmAqci.NyJL0_69pRzwnlpfIuBhSFZZ9eTNfL3boDM7Q1rZgxPeBiO43MEzeFl0F6uHCKElAgVLWxmICJ
174
250
  Accept-Encoding:
175
251
  - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
176
252
  Accept:
@@ -181,17 +257,17 @@ http_interactions:
181
257
  message: No Content
182
258
  headers:
183
259
  Date:
184
- - Mon, 08 Jun 2015 22:12:46 GMT
260
+ - Wed, 10 Jun 2015 20:32:56 GMT
185
261
  Set-Cookie:
186
- - BrowserId=k05v9q6lRV6J82d_MPkehw;Path=/;Domain=.salesforce.com;Expires=Fri,
187
- 07-Aug-2015 22:12:46 GMT
262
+ - BrowserId=VBeEZYY_S0m1i9-4L3t9Nw;Path=/;Domain=.salesforce.com;Expires=Sun,
263
+ 09-Aug-2015 20:32:56 GMT
188
264
  Expires:
189
265
  - Thu, 01 Jan 1970 00:00:00 GMT
190
266
  Sforce-Limit-Info:
191
- - api-usage=24/15000
267
+ - api-usage=29/15000
192
268
  body:
193
269
  encoding: UTF-8
194
270
  string: ''
195
271
  http_version:
196
- recorded_at: Mon, 08 Jun 2015 22:12:48 GMT
272
+ recorded_at: Wed, 10 Jun 2015 20:32:56 GMT
197
273
  recorded_with: VCR 2.9.3
@@ -21,10 +21,10 @@ http_interactions:
21
21
  message: OK
22
22
  headers:
23
23
  Date:
24
- - Mon, 08 Jun 2015 22:12:26 GMT
24
+ - Wed, 10 Jun 2015 20:32:39 GMT
25
25
  Set-Cookie:
26
- - BrowserId=FXMQW0CNQ-CxdRdIg0pZyw;Path=/;Domain=.salesforce.com;Expires=Fri,
27
- 07-Aug-2015 22:12:26 GMT
26
+ - BrowserId=OzqGjtRRQqOYsArDRNVlkA;Path=/;Domain=.salesforce.com;Expires=Sun,
27
+ 09-Aug-2015 20:32:39 GMT
28
28
  Expires:
29
29
  - Thu, 01 Jan 1970 00:00:00 GMT
30
30
  Pragma:
@@ -37,9 +37,9 @@ http_interactions:
37
37
  - chunked
38
38
  body:
39
39
  encoding: ASCII-8BIT
40
- string: '{"id":"https://login.salesforce.com/id/00D1a000000H3O9EAK/0051a000000UGT8AAO","issued_at":"1433801546149","token_type":"Bearer","instance_url":"https://<host>","signature":"OpfQrQSzS7CXjr7GajZRRWSr46FQiYAZKJajUpjOWBU=","access_token":"00D1a000000H3O9!AQ4AQH0rZGqBVji7vO4sB8J1_YW.g5S2vIbe9IaUgwHpwLPEdpfIcj9Ngpc2CndFvJZMwVIIp15.yQQOil19Qc2MuedbnlQz"}'
40
+ string: '{"id":"https://login.salesforce.com/id/00D1a000000H3O9EAK/0051a000000UGT8AAO","issued_at":"1433968359761","token_type":"Bearer","instance_url":"https://<host>","signature":"V0sVcn9qlcfjabLoXSB5KJgn+fLZCa+yElZIcLic0Nc=","access_token":"00D1a000000H3O9!AQ4AQGzO6cHltgvJmAqci.NyJL0_69pRzwnlpfIuBhSFZZ9eTNfL3boDM7Q1rZgxPeBiO43MEzeFl0F6uHCKElAgVLWxmICJ"}'
41
41
  http_version:
42
- recorded_at: Mon, 08 Jun 2015 22:12:27 GMT
42
+ recorded_at: Wed, 10 Jun 2015 20:32:39 GMT
43
43
  - request:
44
44
  method: get
45
45
  uri: https://<host>/services/data/<api_version>/query?q=select%20Id,%20SystemModstamp,%20LastModifiedById,%20Name,%20Example_Field__c%20from%20CustomObject__c
@@ -50,7 +50,7 @@ http_interactions:
50
50
  User-Agent:
51
51
  - Faraday v0.9.1
52
52
  Authorization:
53
- - OAuth 00D1a000000H3O9!AQ4AQH0rZGqBVji7vO4sB8J1_YW.g5S2vIbe9IaUgwHpwLPEdpfIcj9Ngpc2CndFvJZMwVIIp15.yQQOil19Qc2MuedbnlQz
53
+ - OAuth 00D1a000000H3O9!AQ4AQGzO6cHltgvJmAqci.NyJL0_69pRzwnlpfIuBhSFZZ9eTNfL3boDM7Q1rZgxPeBiO43MEzeFl0F6uHCKElAgVLWxmICJ
54
54
  Accept-Encoding:
55
55
  - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
56
56
  Accept:
@@ -61,21 +61,21 @@ http_interactions:
61
61
  message: OK
62
62
  headers:
63
63
  Date:
64
- - Mon, 08 Jun 2015 22:12:26 GMT
64
+ - Wed, 10 Jun 2015 20:32:40 GMT
65
65
  Set-Cookie:
66
- - BrowserId=dM5SIvpNQp6Hdo3R5FfeWw;Path=/;Domain=.salesforce.com;Expires=Fri,
67
- 07-Aug-2015 22:12:26 GMT
66
+ - BrowserId=xfRCkoPlRqmvZ0Tzaw788w;Path=/;Domain=.salesforce.com;Expires=Sun,
67
+ 09-Aug-2015 20:32:40 GMT
68
68
  Expires:
69
69
  - Thu, 01 Jan 1970 00:00:00 GMT
70
70
  Sforce-Limit-Info:
71
- - api-usage=10/15000
71
+ - api-usage=26/15000
72
72
  Content-Type:
73
73
  - application/json;charset=UTF-8
74
74
  Transfer-Encoding:
75
75
  - chunked
76
76
  body:
77
77
  encoding: ASCII-8BIT
78
- string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"CustomObject__c","url":"/services/data/<api_version>/sobjects/CustomObject__c/a001a000001a60JAAQ"},"Id":"a001a000001a60JAAQ","SystemModstamp":"2015-05-18T22:46:05.000+0000","LastModifiedById":"0051a000000UGT8AAO","Name":"SAMPLE","Example_Field__c":null}]}'
78
+ string: '{"totalSize":0,"done":true,"records":[]}'
79
79
  http_version:
80
- recorded_at: Mon, 08 Jun 2015 22:12:27 GMT
80
+ recorded_at: Wed, 10 Jun 2015 20:32:40 GMT
81
81
  recorded_with: VCR 2.9.3
@@ -0,0 +1,158 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://<host>/services/oauth2/token
6
+ body:
7
+ encoding: US-ASCII
8
+ string: grant_type=password&client_id=<client_id>&client_secret=<client_secret>&username=<username>&password=<password><security_token>
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.9.1
12
+ Content-Type:
13
+ - application/x-www-form-urlencoded
14
+ Accept-Encoding:
15
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
16
+ Accept:
17
+ - "*/*"
18
+ response:
19
+ status:
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ Date:
24
+ - Wed, 10 Jun 2015 20:35:23 GMT
25
+ Set-Cookie:
26
+ - BrowserId=BVq3r9U3TByDBBgjrX9ZwQ;Path=/;Domain=.salesforce.com;Expires=Sun,
27
+ 09-Aug-2015 20:35:23 GMT
28
+ Expires:
29
+ - Thu, 01 Jan 1970 00:00:00 GMT
30
+ Pragma:
31
+ - no-cache
32
+ Cache-Control:
33
+ - no-cache, no-store
34
+ Content-Type:
35
+ - application/json;charset=UTF-8
36
+ Transfer-Encoding:
37
+ - chunked
38
+ body:
39
+ encoding: ASCII-8BIT
40
+ string: '{"id":"https://login.salesforce.com/id/00D1a000000H3O9EAK/0051a000000UGT8AAO","issued_at":"1433968523424","token_type":"Bearer","instance_url":"https://<host>","signature":"aFumcItqbbwyu+qYnEKWruhzcfirRdtUAenArGDX2b4=","access_token":"00D1a000000H3O9!AQ4AQGzO6cHltgvJmAqci.NyJL0_69pRzwnlpfIuBhSFZZ9eTNfL3boDM7Q1rZgxPeBiO43MEzeFl0F6uHCKElAgVLWxmICJ"}'
41
+ http_version:
42
+ recorded_at: Wed, 10 Jun 2015 20:35:23 GMT
43
+ - request:
44
+ method: post
45
+ uri: https://<host>/services/data/<api_version>/sobjects/CustomObject__c
46
+ body:
47
+ encoding: UTF-8
48
+ string: '{"Name":"Custom object","Example_Field__c":"Some sample text"}'
49
+ headers:
50
+ User-Agent:
51
+ - Faraday v0.9.1
52
+ Content-Type:
53
+ - application/json
54
+ Authorization:
55
+ - OAuth 00D1a000000H3O9!AQ4AQGzO6cHltgvJmAqci.NyJL0_69pRzwnlpfIuBhSFZZ9eTNfL3boDM7Q1rZgxPeBiO43MEzeFl0F6uHCKElAgVLWxmICJ
56
+ Accept-Encoding:
57
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
58
+ Accept:
59
+ - "*/*"
60
+ response:
61
+ status:
62
+ code: 201
63
+ message: Created
64
+ headers:
65
+ Date:
66
+ - Wed, 10 Jun 2015 20:35:24 GMT
67
+ Set-Cookie:
68
+ - BrowserId=pLhYUJXqRiWwbQfqKyu2vA;Path=/;Domain=.salesforce.com;Expires=Sun,
69
+ 09-Aug-2015 20:35:24 GMT
70
+ Expires:
71
+ - Thu, 01 Jan 1970 00:00:00 GMT
72
+ Sforce-Limit-Info:
73
+ - api-usage=37/15000
74
+ Location:
75
+ - "/services/data/<api_version>/sobjects/CustomObject__c/a001a000001cNUCAA2"
76
+ Content-Type:
77
+ - application/json;charset=UTF-8
78
+ Transfer-Encoding:
79
+ - chunked
80
+ body:
81
+ encoding: ASCII-8BIT
82
+ string: '{"id":"a001a000001cNUCAA2","success":true,"errors":[]}'
83
+ http_version:
84
+ recorded_at: Wed, 10 Jun 2015 20:35:24 GMT
85
+ - request:
86
+ method: get
87
+ uri: https://<host>/services/data/<api_version>/query?q=select%20Id,%20SystemModstamp,%20LastModifiedById,%20Name,%20Example_Field__c%20from%20CustomObject__c
88
+ body:
89
+ encoding: US-ASCII
90
+ string: ''
91
+ headers:
92
+ User-Agent:
93
+ - Faraday v0.9.1
94
+ Authorization:
95
+ - OAuth 00D1a000000H3O9!AQ4AQGzO6cHltgvJmAqci.NyJL0_69pRzwnlpfIuBhSFZZ9eTNfL3boDM7Q1rZgxPeBiO43MEzeFl0F6uHCKElAgVLWxmICJ
96
+ Accept-Encoding:
97
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
98
+ Accept:
99
+ - "*/*"
100
+ response:
101
+ status:
102
+ code: 200
103
+ message: OK
104
+ headers:
105
+ Date:
106
+ - Wed, 10 Jun 2015 20:35:25 GMT
107
+ Set-Cookie:
108
+ - BrowserId=lDZ7sSyzSJymo8s8p2dGAA;Path=/;Domain=.salesforce.com;Expires=Sun,
109
+ 09-Aug-2015 20:35:25 GMT
110
+ Expires:
111
+ - Thu, 01 Jan 1970 00:00:00 GMT
112
+ Sforce-Limit-Info:
113
+ - api-usage=37/15000
114
+ Content-Type:
115
+ - application/json;charset=UTF-8
116
+ Transfer-Encoding:
117
+ - chunked
118
+ body:
119
+ encoding: ASCII-8BIT
120
+ string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"CustomObject__c","url":"/services/data/<api_version>/sobjects/CustomObject__c/a001a000001cNUCAA2"},"Id":"a001a000001cNUCAA2","SystemModstamp":"2015-06-10T20:35:24.000+0000","LastModifiedById":"0051a000000UGT8AAO","Name":"Custom
121
+ object","Example_Field__c":"Some sample text"}]}'
122
+ http_version:
123
+ recorded_at: Wed, 10 Jun 2015 20:35:25 GMT
124
+ - request:
125
+ method: delete
126
+ uri: https://<host>/services/data/<api_version>/sobjects/CustomObject__c/a001a000001cNUCAA2
127
+ body:
128
+ encoding: US-ASCII
129
+ string: ''
130
+ headers:
131
+ User-Agent:
132
+ - Faraday v0.9.1
133
+ Authorization:
134
+ - OAuth 00D1a000000H3O9!AQ4AQGzO6cHltgvJmAqci.NyJL0_69pRzwnlpfIuBhSFZZ9eTNfL3boDM7Q1rZgxPeBiO43MEzeFl0F6uHCKElAgVLWxmICJ
135
+ Accept-Encoding:
136
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
137
+ Accept:
138
+ - "*/*"
139
+ response:
140
+ status:
141
+ code: 204
142
+ message: No Content
143
+ headers:
144
+ Date:
145
+ - Wed, 10 Jun 2015 20:35:26 GMT
146
+ Set-Cookie:
147
+ - BrowserId=Fz1dEybBSvuz5XHirYZyng;Path=/;Domain=.salesforce.com;Expires=Sun,
148
+ 09-Aug-2015 20:35:26 GMT
149
+ Expires:
150
+ - Thu, 01 Jan 1970 00:00:00 GMT
151
+ Sforce-Limit-Info:
152
+ - api-usage=37/15000
153
+ body:
154
+ encoding: UTF-8
155
+ string: ''
156
+ http_version:
157
+ recorded_at: Wed, 10 Jun 2015 20:35:26 GMT
158
+ recorded_with: VCR 2.9.3
@@ -85,5 +85,19 @@ describe Restforce::DB::Collector do
85
85
  end
86
86
  end
87
87
 
88
+ describe "when the record has not been updated outside of the system" do
89
+ subject do
90
+ Restforce::DB::Runner.stub_any_instance(:changed?, false) do
91
+ collector.run
92
+ end
93
+ end
94
+
95
+ before { salesforce_id }
96
+
97
+ it "does not collect any changes" do
98
+ expect(subject[key]).to_be :empty?
99
+ end
100
+ end
101
+
88
102
  end
89
103
  end
@@ -1,11 +1,11 @@
1
1
  require_relative "../../../test_helper"
2
2
 
3
- describe Restforce::DB::RunnerCache do
3
+ describe Restforce::DB::RecordCache do
4
4
 
5
5
  configure!
6
6
  mappings!
7
7
 
8
- let(:cache) { Restforce::DB::RunnerCache.new }
8
+ let(:cache) { Restforce::DB::RecordCache.new }
9
9
 
10
10
  describe "#collection" do
11
11
  let(:object) { mapping.database_model.create! }
@@ -0,0 +1,86 @@
1
+ require_relative "../../../test_helper"
2
+
3
+ describe Restforce::DB::TimestampCache do
4
+
5
+ configure!
6
+
7
+ let(:cache) { Restforce::DB::TimestampCache.new }
8
+
9
+ let(:timestamp) { Time.now }
10
+ let(:id) { "some-id" }
11
+ let(:instance_class) { Struct.new(:id, :last_update) }
12
+ let(:instance) { instance_class.new(id, timestamp) }
13
+
14
+ describe "#cache_timestamp" do
15
+ before { cache.cache_timestamp instance }
16
+
17
+ it "stores the update timestamp in the cache" do
18
+ expect(cache.timestamp(instance)).to_equal timestamp
19
+ end
20
+ end
21
+
22
+ describe "#changed?" do
23
+ let(:new_instance) { instance_class.new(id, timestamp) }
24
+
25
+ describe "when the passed instance was not internally updated" do
26
+ before do
27
+ def new_instance.updated_internally?
28
+ false
29
+ end
30
+ end
31
+
32
+ it "returns true" do
33
+ expect(cache).to_be :changed?, new_instance
34
+ end
35
+ end
36
+
37
+ describe "when the passed instance was internally updated" do
38
+ before do
39
+ def new_instance.updated_internally?
40
+ true
41
+ end
42
+ end
43
+
44
+ describe "but no update timestamp is cached" do
45
+
46
+ it "returns true" do
47
+ expect(cache).to_be :changed?, new_instance
48
+ end
49
+ end
50
+
51
+ describe "and a recent timestamp is cached" do
52
+ before { cache.cache_timestamp instance }
53
+
54
+ it "returns false" do
55
+ expect(cache).to_not_be :changed?, new_instance
56
+ end
57
+ end
58
+
59
+ describe "and a stale timestamp is cached" do
60
+ let(:new_instance) { instance_class.new(id, timestamp + 1) }
61
+ before { cache.cache_timestamp instance }
62
+
63
+ it "returns true" do
64
+ expect(cache).to_be :changed?, new_instance
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ describe "#reset" do
71
+ before do
72
+ cache.cache_timestamp instance
73
+ cache.reset
74
+ end
75
+
76
+ it "retires recently-stored timestamps" do
77
+ expect(cache.timestamp(instance)).to_equal timestamp
78
+ end
79
+
80
+ it "expires retired timestamps" do
81
+ cache.reset
82
+ expect(cache.timestamp(instance)).to_be_nil
83
+ end
84
+ end
85
+
86
+ end
@@ -36,7 +36,6 @@ class Salesforce
36
36
  #
37
37
  # Returns nothing.
38
38
  def self.clean!
39
- # raise Salesforce.records.inspect unless Salesforce.records.empty?
40
39
  Salesforce.records.each do |entry|
41
40
  Restforce::DB.client.destroy entry[0], entry[1]
42
41
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restforce-db
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.4
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Horner
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-06-10 00:00:00.000000000 Z
11
+ date: 2015-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -231,18 +231,19 @@ files:
231
231
  - lib/restforce/db/mapping.rb
232
232
  - lib/restforce/db/model.rb
233
233
  - lib/restforce/db/railtie.rb
234
+ - lib/restforce/db/record_cache.rb
234
235
  - lib/restforce/db/record_types/active_record.rb
235
236
  - lib/restforce/db/record_types/base.rb
236
237
  - lib/restforce/db/record_types/salesforce.rb
237
238
  - lib/restforce/db/registry.rb
238
239
  - lib/restforce/db/runner.rb
239
- - lib/restforce/db/runner_cache.rb
240
240
  - lib/restforce/db/strategies/always.rb
241
241
  - lib/restforce/db/strategies/associated.rb
242
242
  - lib/restforce/db/strategies/passive.rb
243
243
  - lib/restforce/db/strategy.rb
244
244
  - lib/restforce/db/synchronization_error.rb
245
245
  - lib/restforce/db/synchronizer.rb
246
+ - lib/restforce/db/timestamp_cache.rb
246
247
  - lib/restforce/db/tracker.rb
247
248
  - lib/restforce/db/version.rb
248
249
  - lib/restforce/db/worker.rb
@@ -286,6 +287,7 @@ files:
286
287
  - test/cassettes/Restforce_DB_Collector/_run/given_a_Salesforce_record_with_an_associated_database_record/returns_the_attributes_from_both_records.yml
287
288
  - test/cassettes/Restforce_DB_Collector/_run/given_an_existing_Salesforce_record/returns_the_attributes_from_the_Salesforce_record.yml
288
289
  - test/cassettes/Restforce_DB_Collector/_run/given_an_existing_database_record/returns_the_attributes_from_the_database_record.yml
290
+ - test/cassettes/Restforce_DB_Collector/_run/when_the_record_has_not_been_updated_outside_of_the_system/does_not_collect_any_changes.yml
289
291
  - test/cassettes/Restforce_DB_Initializer/_run/given_an_existing_Salesforce_record/for_a_Passive_strategy/does_not_create_a_database_record.yml
290
292
  - test/cassettes/Restforce_DB_Initializer/_run/given_an_existing_Salesforce_record/for_an_Always_strategy/creates_a_matching_database_record.yml
291
293
  - test/cassettes/Restforce_DB_Initializer/_run/given_an_existing_database_record/for_an_Always_strategy/populates_Salesforce_with_the_new_record.yml
@@ -332,16 +334,17 @@ files:
332
334
  - test/lib/restforce/db/instances/salesforce_test.rb
333
335
  - test/lib/restforce/db/mapping_test.rb
334
336
  - test/lib/restforce/db/model_test.rb
337
+ - test/lib/restforce/db/record_cache_test.rb
335
338
  - test/lib/restforce/db/record_types/active_record_test.rb
336
339
  - test/lib/restforce/db/record_types/salesforce_test.rb
337
340
  - test/lib/restforce/db/registry_test.rb
338
- - test/lib/restforce/db/runner_cache_test.rb
339
341
  - test/lib/restforce/db/runner_test.rb
340
342
  - test/lib/restforce/db/strategies/always_test.rb
341
343
  - test/lib/restforce/db/strategies/associated_test.rb
342
344
  - test/lib/restforce/db/strategies/passive_test.rb
343
345
  - test/lib/restforce/db/strategy_test.rb
344
346
  - test/lib/restforce/db/synchronizer_test.rb
347
+ - test/lib/restforce/db/timestamp_cache_test.rb
345
348
  - test/lib/restforce/db/tracker_test.rb
346
349
  - test/lib/restforce/db_test.rb
347
350
  - test/support/active_record.rb
@@ -372,7 +375,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
372
375
  version: '0'
373
376
  requirements: []
374
377
  rubyforge_project:
375
- rubygems_version: 2.4.5
378
+ rubygems_version: 2.4.6
376
379
  signing_key:
377
380
  specification_version: 4
378
381
  summary: Bind your database to Salesforce data