restforce-db 0.2.3 → 0.3.0
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 +4 -4
- data/README.md +39 -8
- data/lib/restforce/db/instances/active_record.rb +0 -9
- data/lib/restforce/db/instances/base.rb +7 -5
- data/lib/restforce/db/instances/salesforce.rb +0 -9
- data/lib/restforce/db/mapping.rb +91 -31
- data/lib/restforce/db/model.rb +5 -20
- data/lib/restforce/db/record_types/active_record.rb +38 -5
- data/lib/restforce/db/record_types/base.rb +2 -2
- data/lib/restforce/db/record_types/salesforce.rb +3 -3
- data/lib/restforce/db/version.rb +1 -1
- data/lib/restforce/db/worker.rb +7 -10
- data/lib/restforce/db.rb +0 -1
- data/test/cassettes/Restforce_DB/accessing_Salesforce/uses_the_configured_credentials.yml +5 -5
- data/test/cassettes/Restforce_DB_Instances_Salesforce/_copy_/updates_the_record_with_the_attributes_from_the_copied_object.yml +36 -35
- data/test/cassettes/Restforce_DB_Instances_Salesforce/_update_/updates_the_local_record_with_the_passed_attributes.yml +34 -33
- data/test/cassettes/Restforce_DB_Instances_Salesforce/_update_/updates_the_record_in_Salesforce_with_the_passed_attributes.yml +45 -44
- data/test/cassettes/Restforce_DB_RecordTypes_Salesforce/_create_/creates_a_record_in_Salesforce_from_the_passed_database_record_s_attributes.yml +28 -28
- data/test/cassettes/Restforce_DB_RecordTypes_Salesforce/_create_/updates_the_database_record_with_the_Salesforce_record_s_ID.yml +28 -28
- data/test/cassettes/Restforce_DB_RecordTypes_Salesforce/_find/finds_existing_records_in_Salesforce.yml +29 -28
- data/test/cassettes/Restforce_DB_RecordTypes_Salesforce/_find/returns_nil_when_no_matching_record_exists.yml +12 -12
- data/test/cassettes/Restforce_DB_Synchronizer/_run/given_a_Salesforce_record_with_an_associated_database_record/when_synchronization_is_stale/updates_the_database_record.yml +36 -36
- data/test/cassettes/Restforce_DB_Synchronizer/_run/given_a_Salesforce_record_with_an_associated_database_record/when_synchronization_is_up-to-date/does_not_update_the_database_record.yml +28 -104
- data/test/cassettes/Restforce_DB_Synchronizer/_run/given_an_existing_Salesforce_record/{populates_the_database_with_the_new_record.yml → for_a_non-root_mapping/does_not_create_a_database_record.yml} +28 -28
- data/test/cassettes/Restforce_DB_Synchronizer/_run/given_an_existing_Salesforce_record/for_a_root_mapping/creates_a_matching_database_record.yml +158 -0
- data/test/cassettes/Restforce_DB_Synchronizer/_run/given_an_existing_database_record/populates_Salesforce_with_the_new_record.yml +44 -44
- data/test/lib/restforce/db/instances/active_record_test.rb +4 -2
- data/test/lib/restforce/db/instances/salesforce_test.rb +5 -6
- data/test/lib/restforce/db/mapping_test.rb +40 -15
- data/test/lib/restforce/db/model_test.rb +6 -23
- data/test/lib/restforce/db/record_types/active_record_test.rb +45 -17
- data/test/lib/restforce/db/record_types/salesforce_test.rb +6 -7
- data/test/lib/restforce/db/synchronizer_test.rb +31 -17
- data/test/support/active_record.rb +20 -1
- data/test/support/utilities.rb +29 -0
- data/test/test_helper.rb +0 -12
- metadata +4 -4
- data/lib/restforce/db/record_type.rb +0 -77
- data/test/lib/restforce/db/record_type_test.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b41ed218d9bcffc70f1d5d8f52a141debf89d99
|
4
|
+
data.tar.gz: 2a353f19c80633f4773f3810c0b9df921ee339ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5388edf3a22a22f6a5d50b61f438dd4ecb304175733c78ab0bcbd08cd7084df64e5006bea3c8256e4a248a0dcad127e9daec73e2515d3d7eeaa1a04792c4360c
|
7
|
+
data.tar.gz: cd9cafc0c560e850a40a4dc9cb1f6f185e39a53d1ae56df29395175a6c0779e091c636e5189218163f01c046818dbba84d82073e5b315ced162def4ec3bf07af
|
data/README.md
CHANGED
@@ -31,33 +31,64 @@ In order to keep your database records in sync with Salesforce, the table will n
|
|
31
31
|
|
32
32
|
### Register a mapping
|
33
33
|
|
34
|
-
To register a Salesforce mapping in an `ActiveRecord` model, you need to add a few lines of DSL-style code to
|
34
|
+
To register a Salesforce mapping in an `ActiveRecord` model, you'll need to add a few lines of DSL-style code to the relevant class definitions:
|
35
35
|
|
36
36
|
```ruby
|
37
|
-
class
|
37
|
+
class Restaurant < ActiveRecord::Base
|
38
38
|
|
39
39
|
include Restforce::DB::Model
|
40
|
+
has_one :specialty, class_name: "Dish"
|
41
|
+
|
42
|
+
sync_with(
|
43
|
+
"Restaurants__c",
|
44
|
+
fields: {
|
45
|
+
name: "Name",
|
46
|
+
style: "Style__c",
|
47
|
+
},
|
48
|
+
associations: {
|
49
|
+
specialty: "Specialty__c",
|
50
|
+
},
|
51
|
+
root: true,
|
52
|
+
)
|
40
53
|
|
41
|
-
|
54
|
+
end
|
55
|
+
|
56
|
+
class Dish < ActiveRecord::Base
|
42
57
|
|
58
|
+
include Restforce::DB::Model
|
59
|
+
belongs_to :restaurant
|
60
|
+
|
61
|
+
sync_with(
|
62
|
+
"Dish__c",
|
63
|
+
fields: {
|
64
|
+
name: "Name",
|
65
|
+
ingredient: "Ingredient__c",
|
66
|
+
},
|
67
|
+
)
|
43
68
|
end
|
44
69
|
```
|
45
70
|
|
46
|
-
This will automatically register the
|
71
|
+
This will automatically register the models with entries in the `Restforce::DB::Mapping` collection. This collection defines the manner in which the database and Salesforce systems will be synchronized.
|
72
|
+
|
73
|
+
There are a few options to be aware of when describing a mapping:
|
74
|
+
|
75
|
+
- `fields`: These are direct field-to-field mappings. The keys should line up with your ActiveRecord attribute names, while the values should line up with the matching field names in Salesforce.
|
76
|
+
- `associations`: These are mappings of ActiveRecord associations to Salesforce lookups. Associations defined here will be built as part of the creation process for a newly-synced record.
|
77
|
+
- `root`: When `true`, all records of the associated type will be synchronized from Salesforce into the database and vice-versa. When `false` or `nil`, records will still be updated, but can only be created through associations (see just above).
|
47
78
|
|
48
79
|
### Run the daemon
|
49
80
|
|
50
|
-
To actually perform
|
81
|
+
To actually perform this system synchronization, you'll want to run the binstub installed through the generator (see above). This will daemonize a process which loops repeatedly to continuously synchronize your database and your Salesforce account, according to the established mappings.
|
51
82
|
|
52
|
-
|
83
|
+
$ bundle exec bin/restforce-db start
|
53
84
|
|
54
85
|
By default, this will load the credentials at the same location the generator installed them. You can explicitly pass the location of your configuration file with the `-c` option:
|
55
86
|
|
56
|
-
|
87
|
+
$ bundle exec bin/restforce-db -c /path/to/my/config.yml start
|
57
88
|
|
58
89
|
For additional information and a full set of options, you can run:
|
59
90
|
|
60
|
-
|
91
|
+
$ bundle exec bin/restforce-db -h
|
61
92
|
|
62
93
|
## Development
|
63
94
|
|
@@ -12,9 +12,11 @@ module Restforce
|
|
12
12
|
|
13
13
|
# Public: Initialize a new Restforce::DB::Instances::Base instance.
|
14
14
|
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
|
15
|
+
# record_type - A String or Class describing the record's type.
|
16
|
+
# record - The Salesforce or database record to manage.
|
17
|
+
# mapping - An instance of Restforce::DB::Mapping.
|
18
|
+
def initialize(record_type, record, mapping = nil)
|
19
|
+
@record_type = record_type
|
18
20
|
@record = record
|
19
21
|
@mapping = mapping
|
20
22
|
end
|
@@ -40,7 +42,7 @@ module Restforce
|
|
40
42
|
# Returns self.
|
41
43
|
# Raises if the update fails for any reason.
|
42
44
|
def copy!(from_record)
|
43
|
-
update! @mapping.convert(
|
45
|
+
update! @mapping.convert(@record_type, from_record.attributes)
|
44
46
|
end
|
45
47
|
|
46
48
|
# Public: Get a Hash mapping the configured attributes names to their
|
@@ -48,7 +50,7 @@ module Restforce
|
|
48
50
|
#
|
49
51
|
# Returns a Hash.
|
50
52
|
def attributes
|
51
|
-
@mapping.attributes(
|
53
|
+
@mapping.attributes(@record_type) { |attribute| record.send(attribute) }
|
52
54
|
end
|
53
55
|
|
54
56
|
# Public: Has this record been synced with Salesforce?
|
data/lib/restforce/db/mapping.rb
CHANGED
@@ -7,26 +7,65 @@ module Restforce
|
|
7
7
|
# attributes from one to the other.
|
8
8
|
class Mapping
|
9
9
|
|
10
|
-
|
10
|
+
class << self
|
11
|
+
|
12
|
+
include Enumerable
|
13
|
+
attr_accessor :collection
|
14
|
+
|
15
|
+
# Public: Get the Restforce::DB::Mapping entry for the specified
|
16
|
+
# database model.
|
17
|
+
#
|
18
|
+
# database_model - A Class compatible with ActiveRecord::Base.
|
19
|
+
#
|
20
|
+
# Returns a Restforce::DB::Mapping.
|
21
|
+
def [](database_model)
|
22
|
+
collection[database_model]
|
23
|
+
end
|
24
|
+
|
25
|
+
# Public: Iterate through all registered Restforce::DB::Mappings.
|
26
|
+
#
|
27
|
+
# Yields one Mapping for each database-to-Salesforce mapping.
|
28
|
+
# Returns nothing.
|
29
|
+
def each
|
30
|
+
collection.each do |database_model, record_type|
|
31
|
+
yield database_model.name, record_type
|
32
|
+
end
|
33
|
+
end
|
11
34
|
|
12
|
-
# Public: Initialize a new Restforce::DB::Mapping.
|
13
|
-
#
|
14
|
-
# mappings - A Hash, with keys corresponding to the names of Ruby object
|
15
|
-
# attributes, and the values of those keys corresponding to the
|
16
|
-
# names of the related Salesforce fields.
|
17
|
-
def initialize(mappings = {})
|
18
|
-
@mappings = mappings
|
19
35
|
end
|
20
36
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
37
|
+
self.collection ||= {}
|
38
|
+
|
39
|
+
attr_reader :database_record_type, :salesforce_record_type, :associations
|
40
|
+
attr_writer :root
|
41
|
+
|
42
|
+
# Public: Initialize a new Restforce::DB::Mapping.
|
26
43
|
#
|
27
|
-
#
|
28
|
-
|
29
|
-
|
44
|
+
# database_model - A Class compatible with ActiveRecord::Base.
|
45
|
+
# salesforce_model - A String name of an object type in Salesforce.
|
46
|
+
# options - A Hash of mapping attributes. Currently supported
|
47
|
+
# keys are:
|
48
|
+
# :fields - A Hash of mappings between database
|
49
|
+
# columns and fields in Salesforce.
|
50
|
+
# :associations - A Hash of mappings between Active
|
51
|
+
# Record association names and the
|
52
|
+
# corresponding Salesforce Lookup name.
|
53
|
+
# :root - A Boolean reflecting whether or not
|
54
|
+
# this is a root-level mapping.
|
55
|
+
def initialize(database_model, salesforce_model, options = {})
|
56
|
+
@database_record_type = RecordTypes::ActiveRecord.new(database_model, self)
|
57
|
+
@salesforce_record_type = RecordTypes::Salesforce.new(salesforce_model, self)
|
58
|
+
|
59
|
+
@fields = options.fetch(:fields) { {} }
|
60
|
+
@associations = options.fetch(:associations) { {} }
|
61
|
+
@root = options.fetch(:root) { false }
|
62
|
+
|
63
|
+
@types = {
|
64
|
+
database_model => :database,
|
65
|
+
salesforce_model => :salesforce,
|
66
|
+
}
|
67
|
+
|
68
|
+
self.class.collection[database_model] = self
|
30
69
|
end
|
31
70
|
|
32
71
|
# Public: Get a list of the relevant Salesforce field names for this
|
@@ -34,7 +73,7 @@ module Restforce
|
|
34
73
|
#
|
35
74
|
# Returns an Array.
|
36
75
|
def salesforce_fields
|
37
|
-
@
|
76
|
+
@fields.values + @associations.values
|
38
77
|
end
|
39
78
|
|
40
79
|
# Public: Get a list of the relevant database column names for this
|
@@ -42,26 +81,36 @@ module Restforce
|
|
42
81
|
#
|
43
82
|
# Returns an Array.
|
44
83
|
def database_fields
|
45
|
-
@
|
84
|
+
@fields.keys
|
85
|
+
end
|
86
|
+
|
87
|
+
# Public: Is this a root-level mapping? Used to determine whether or not
|
88
|
+
# to trigger the creation of "missing" database records.
|
89
|
+
#
|
90
|
+
# Returns a Boolean.
|
91
|
+
def root?
|
92
|
+
@root
|
46
93
|
end
|
47
94
|
|
48
95
|
# Public: Build a normalized Hash of attributes from the appropriate set
|
49
96
|
# of mappings. The keys of the resulting mapping Hash will correspond to
|
50
97
|
# the database column names.
|
51
98
|
#
|
52
|
-
# in_format - A
|
53
|
-
#
|
99
|
+
# in_format - A String or Class reflecting the record type from which the
|
100
|
+
# attribute Hash is being compiled.
|
54
101
|
#
|
55
102
|
# Yields the attribute name.
|
56
103
|
# Returns a Hash.
|
57
104
|
def attributes(from_format)
|
58
105
|
use_mappings =
|
59
|
-
case from_format
|
106
|
+
case @types[from_format]
|
60
107
|
when :salesforce
|
61
|
-
@
|
108
|
+
@fields
|
62
109
|
when :database
|
63
110
|
# Generate a mapping of database column names to record attributes.
|
64
111
|
database_fields.zip(database_fields)
|
112
|
+
else
|
113
|
+
raise ArgumentError
|
65
114
|
end
|
66
115
|
|
67
116
|
use_mappings.each_with_object({}) do |(attribute, mapping), values|
|
@@ -72,33 +121,44 @@ module Restforce
|
|
72
121
|
# Public: Convert a Hash of attributes to a format compatible with a
|
73
122
|
# specific platform.
|
74
123
|
#
|
75
|
-
# to_format - A
|
76
|
-
#
|
77
|
-
# attributes - A Hash, with keys corresponding to the
|
78
|
-
#
|
124
|
+
# to_format - A String or Class reflecting the record type for which the
|
125
|
+
# attribute Hash is being compiled.
|
126
|
+
# attributes - A Hash of attributes, with keys corresponding to the
|
127
|
+
# normalized attribute names.
|
79
128
|
#
|
80
129
|
# Examples
|
81
130
|
#
|
82
|
-
# mapping = Mapping.new(some_key: "
|
83
|
-
#
|
131
|
+
# mapping = Mapping.new(MyClass, "Object__c", some_key: "SomeField__c")
|
132
|
+
#
|
133
|
+
# mapping.convert("Object__c", some_key: "some value")
|
84
134
|
# # => { "Some_Field__c" => "some value" }
|
85
135
|
#
|
86
|
-
# mapping.convert(
|
136
|
+
# mapping.convert(MyClass, some_key: "some other value")
|
87
137
|
# # => { some_key: "some other value" }
|
88
138
|
#
|
89
139
|
# Returns a Hash.
|
90
140
|
def convert(to_format, attributes)
|
91
|
-
case to_format
|
141
|
+
case @types[to_format]
|
92
142
|
when :database
|
93
143
|
attributes.dup
|
94
144
|
when :salesforce
|
95
|
-
@
|
145
|
+
@fields.each_with_object({}) do |(attribute, mapping), converted|
|
96
146
|
next unless attributes.key?(attribute)
|
97
147
|
converted[mapping] = attributes[attribute]
|
98
148
|
end
|
149
|
+
else
|
150
|
+
raise ArgumentError
|
99
151
|
end
|
100
152
|
end
|
101
153
|
|
154
|
+
# Public: Get a Synchronizer for the record types captured by this
|
155
|
+
# Mapping.
|
156
|
+
#
|
157
|
+
# Returns a Restforce::DB::Synchronizer.
|
158
|
+
def synchronizer
|
159
|
+
@synchronizer ||= Synchronizer.new(@database_record_type, @salesforce_record_type)
|
160
|
+
end
|
161
|
+
|
102
162
|
end
|
103
163
|
|
104
164
|
end
|
data/lib/restforce/db/model.rb
CHANGED
@@ -15,30 +15,15 @@ module Restforce
|
|
15
15
|
# :nodoc:
|
16
16
|
module ClassMethods
|
17
17
|
|
18
|
-
# Public: Initializes a Restforce::DB::
|
18
|
+
# Public: Initializes a Restforce::DB::Mapping defining this model's
|
19
19
|
# relationship to a Salesforce object type.
|
20
20
|
#
|
21
21
|
# salesforce_model - A String name of an object type in Salesforce.
|
22
|
-
#
|
23
|
-
# fields in Salesforce.
|
22
|
+
# options - A Hash of options to pass through to the Mapping.
|
24
23
|
#
|
25
|
-
# Returns a Restforce::DB::
|
26
|
-
def
|
27
|
-
|
28
|
-
self,
|
29
|
-
salesforce_model,
|
30
|
-
mappings,
|
31
|
-
)
|
32
|
-
end
|
33
|
-
|
34
|
-
# Public: Append the passed mappings to this model.
|
35
|
-
#
|
36
|
-
# mappings - A Hash of database column names mapped to Salesforce
|
37
|
-
# fields.
|
38
|
-
#
|
39
|
-
# Returns nothing.
|
40
|
-
def add_mappings(mappings)
|
41
|
-
RecordType[self].add_mappings(mappings)
|
24
|
+
# Returns a Restforce::DB::Mapping.
|
25
|
+
def sync_with(salesforce_model, **options)
|
26
|
+
Mapping.new(self, salesforce_model, options)
|
42
27
|
end
|
43
28
|
|
44
29
|
end
|
@@ -17,11 +17,17 @@ module Restforce
|
|
17
17
|
# Returns a Restforce::DB::Instances::ActiveRecord instance.
|
18
18
|
# Raises on any validation or database error.
|
19
19
|
def create!(from_record)
|
20
|
-
attributes = @mapping.convert(
|
20
|
+
attributes = @mapping.convert(@record_type, from_record.attributes)
|
21
21
|
|
22
|
-
record = @record_type.
|
22
|
+
record = @record_type.new(attributes.merge(salesforce_id: from_record.id))
|
23
|
+
@mapping.associations.each do |association, lookup|
|
24
|
+
lookup_id = from_record.record.send(lookup)
|
25
|
+
associated = record.send("build_#{association}")
|
26
|
+
build_association associated, lookup_id
|
27
|
+
end
|
28
|
+
record.save!
|
23
29
|
|
24
|
-
Instances::ActiveRecord.new(record, @mapping).after_sync
|
30
|
+
Instances::ActiveRecord.new(@record_type, record, @mapping).after_sync
|
25
31
|
end
|
26
32
|
|
27
33
|
# Public: Find the instance of this ActiveRecord model corresponding to
|
@@ -34,7 +40,7 @@ module Restforce
|
|
34
40
|
record = @record_type.find_by(salesforce_id: id)
|
35
41
|
return nil unless record
|
36
42
|
|
37
|
-
Instances::ActiveRecord.new(record, @mapping)
|
43
|
+
Instances::ActiveRecord.new(@record_type, record, @mapping)
|
38
44
|
end
|
39
45
|
|
40
46
|
# Public: Iterate through all recently-updated ActiveRecord records of
|
@@ -55,7 +61,7 @@ module Restforce
|
|
55
61
|
scope = scope.where("updated_at < ?", options[:before]) if options[:before]
|
56
62
|
|
57
63
|
scope.find_each do |record|
|
58
|
-
yield Instances::ActiveRecord.new(record, @mapping)
|
64
|
+
yield Instances::ActiveRecord.new(@record_type, record, @mapping)
|
59
65
|
end
|
60
66
|
end
|
61
67
|
|
@@ -71,6 +77,33 @@ module Restforce
|
|
71
77
|
@record_type.exists?(salesforce_id: record.id)
|
72
78
|
end
|
73
79
|
|
80
|
+
# Internal: Assemble an associated record, using the data from the
|
81
|
+
# Salesforce record corresponding to a specific lookup ID.
|
82
|
+
#
|
83
|
+
# TODO: With some refactoring using ActiveRecord inflections, this
|
84
|
+
# should be possible to handle as a recursive call to the configured
|
85
|
+
# Mapping's database record type. Right now, nested associations are
|
86
|
+
# ignored.
|
87
|
+
#
|
88
|
+
# associated - The associatd database record.
|
89
|
+
# lookup_id - A Salesforce ID corresponding to the record type in the
|
90
|
+
# Mapping defined for the associated database model.
|
91
|
+
#
|
92
|
+
# Returns a Boolean.
|
93
|
+
def build_association(associated, lookup_id)
|
94
|
+
mapping = Mapping[associated.class]
|
95
|
+
|
96
|
+
salesforce_instance = mapping.salesforce_record_type.find(lookup_id)
|
97
|
+
attributes = mapping.convert(associated.class, salesforce_instance.attributes)
|
98
|
+
|
99
|
+
associated.assign_attributes(
|
100
|
+
attributes.merge(
|
101
|
+
salesforce_id: lookup_id,
|
102
|
+
synchronized_at: Time.now,
|
103
|
+
),
|
104
|
+
)
|
105
|
+
end
|
106
|
+
|
74
107
|
end
|
75
108
|
|
76
109
|
end
|
@@ -12,7 +12,7 @@ module Restforce
|
|
12
12
|
#
|
13
13
|
# record_type - The name or class of the system record type.
|
14
14
|
# mapping - A Restforce::DB::Mapping.
|
15
|
-
def initialize(record_type, mapping =
|
15
|
+
def initialize(record_type, mapping = nil)
|
16
16
|
@record_type = record_type
|
17
17
|
@mapping = mapping
|
18
18
|
end
|
@@ -27,7 +27,7 @@ module Restforce
|
|
27
27
|
def sync!(from_record)
|
28
28
|
if synced?(from_record)
|
29
29
|
update!(from_record)
|
30
|
-
|
30
|
+
elsif @mapping.root?
|
31
31
|
create!(from_record)
|
32
32
|
end
|
33
33
|
end
|
@@ -17,7 +17,7 @@ module Restforce
|
|
17
17
|
# Returns a Restforce::DB::Instances::Salesforce instance.
|
18
18
|
# Raises on any error from Salesforce.
|
19
19
|
def create!(from_record)
|
20
|
-
attributes = @mapping.convert(
|
20
|
+
attributes = @mapping.convert(@record_type, from_record.attributes)
|
21
21
|
record_id = DB.client.create!(@record_type, attributes)
|
22
22
|
|
23
23
|
from_record.update!(salesforce_id: record_id).after_sync
|
@@ -37,7 +37,7 @@ module Restforce
|
|
37
37
|
|
38
38
|
return unless record
|
39
39
|
|
40
|
-
Instances::Salesforce.new(record, @mapping)
|
40
|
+
Instances::Salesforce.new(@record_type, record, @mapping)
|
41
41
|
end
|
42
42
|
|
43
43
|
# Public: Iterate through all Salesforce records of this type.
|
@@ -61,7 +61,7 @@ module Restforce
|
|
61
61
|
query = "select #{lookups} from #{@record_type}#{constraints}"
|
62
62
|
|
63
63
|
DB.client.query(query).each do |record|
|
64
|
-
yield Instances::Salesforce.new(record, @mapping)
|
64
|
+
yield Instances::Salesforce.new(@record_type, record, @mapping)
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
data/lib/restforce/db/version.rb
CHANGED
data/lib/restforce/db/worker.rb
CHANGED
@@ -73,10 +73,7 @@ module Restforce
|
|
73
73
|
|
74
74
|
loop do
|
75
75
|
runtime = Benchmark.realtime { perform }
|
76
|
-
|
77
|
-
if runtime < @interval && !stop?
|
78
|
-
sleep(@interval - runtime)
|
79
|
-
end
|
76
|
+
sleep(@interval - runtime) if runtime < @interval && !stop?
|
80
77
|
|
81
78
|
break if stop?
|
82
79
|
end
|
@@ -99,8 +96,8 @@ module Restforce
|
|
99
96
|
# Returns nothing.
|
100
97
|
def perform
|
101
98
|
track do
|
102
|
-
Restforce::DB::
|
103
|
-
synchronize name,
|
99
|
+
Restforce::DB::Mapping.each do |name, mapping|
|
100
|
+
synchronize name, mapping
|
104
101
|
end
|
105
102
|
end
|
106
103
|
end
|
@@ -132,13 +129,13 @@ module Restforce
|
|
132
129
|
# Internal: Synchronize the objects in the database and Salesforce
|
133
130
|
# corresponding to the passed record type.
|
134
131
|
#
|
135
|
-
# name
|
136
|
-
#
|
132
|
+
# name - The String name of the record type to synchronize.
|
133
|
+
# mapping - A Restforce::DB::Mapping.
|
137
134
|
#
|
138
135
|
# Returns a Boolean.
|
139
|
-
def synchronize(name,
|
136
|
+
def synchronize(name, mapping)
|
140
137
|
log " SYNCHRONIZE #{name}"
|
141
|
-
runtime =
|
138
|
+
runtime = Benchmark.realtime { mapping.synchronizer.run }
|
142
139
|
log format(" COMPLETE after %.4f", runtime)
|
143
140
|
|
144
141
|
return true
|
data/lib/restforce/db.rb
CHANGED
@@ -21,10 +21,10 @@ http_interactions:
|
|
21
21
|
message: OK
|
22
22
|
headers:
|
23
23
|
Date:
|
24
|
-
-
|
24
|
+
- Thu, 26 Mar 2015 10:20:18 GMT
|
25
25
|
Set-Cookie:
|
26
|
-
- BrowserId=
|
27
|
-
|
26
|
+
- BrowserId=OGFSgeFMR5uovzRw9T5zQw;Path=/;Domain=.salesforce.com;Expires=Mon,
|
27
|
+
25-May-2015 10:20:18 GMT
|
28
28
|
Expires:
|
29
29
|
- Thu, 01 Jan 1970 00:00:00 GMT
|
30
30
|
Pragma:
|
@@ -37,7 +37,7 @@ 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":"
|
40
|
+
string: '{"id":"https://login.salesforce.com/id/00D1a000000H3O9EAK/0051a000000UGT8AAO","issued_at":"1427365218093","token_type":"Bearer","instance_url":"https://<host>","signature":"zr8yut/9lhLfOwHlsCXPJ635XLUaIg62ecMRMW7mAV4=","access_token":"00D1a000000H3O9!AQ4AQFqDs34WtnS6RDwxyGdLSPYE_cFTuNjjnDvX2HbNhGMu917m6JyqchGFbdiOruyd5Z.w7uN.ogsJF4_8TMMzdt2fw7OZ"}'
|
41
41
|
http_version:
|
42
|
-
recorded_at:
|
42
|
+
recorded_at: Thu, 26 Mar 2015 10:20:18 GMT
|
43
43
|
recorded_with: VCR 2.9.3
|