restforce-db 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/restforce/db/accumulator.rb +13 -0
- data/lib/restforce/db/field_processor.rb +70 -0
- data/lib/restforce/db/instances/salesforce.rb +10 -0
- data/lib/restforce/db/record_types/salesforce.rb +2 -2
- data/lib/restforce/db/synchronizer.rb +2 -1
- data/lib/restforce/db/version.rb +1 -1
- data/lib/restforce/db.rb +1 -0
- data/test/cassettes/Restforce_DB_Associator/_run/given_a_BelongsTo_association/given_another_record_for_association/when_the_Salesforce_association_is_out_of_date/updates_the_association_ID_in_Salesforce.yml +135 -82
- data/test/cassettes/Restforce_DB_Associator/_run/given_a_BelongsTo_association/given_another_record_for_association/when_the_database_association_is_out_of_date/updates_the_associated_record_in_the_database.yml +152 -99
- data/test/cassettes/Restforce_DB_Cleaner/_run/given_a_synchronized_Salesforce_record/when_the_mapping_has_no_conditions/does_not_drop_the_synchronized_database_record.yml +120 -0
- data/test/cassettes/Restforce_DB_Cleaner/_run/given_a_synchronized_Salesforce_record/when_the_record_does_not_meet_the_mapping_conditions/for_a_non-Passive_strategy/drops_the_synchronized_database_record.yml +34 -36
- data/test/cassettes/Restforce_DB_Cleaner/_run/given_a_synchronized_Salesforce_record/when_the_record_meets_the_mapping_conditions/does_not_drop_the_synchronized_database_record.yml +35 -37
- data/test/cassettes/Restforce_DB_Initializer/_run/given_an_existing_database_record/for_an_Always_strategy/populates_Salesforce_with_the_new_record.yml +96 -44
- data/test/cassettes/Restforce_DB_Instances_Salesforce/_update_/updates_the_local_record_with_the_passed_attributes.yml +88 -35
- data/test/cassettes/Restforce_DB_Instances_Salesforce/_update_/updates_the_record_in_Salesforce_with_the_passed_attributes.yml +96 -43
- data/test/cassettes/Restforce_DB_RecordTypes_Salesforce/_create_/creates_a_record_in_Salesforce_from_the_passed_database_record_s_attributes.yml +81 -28
- data/test/cassettes/Restforce_DB_RecordTypes_Salesforce/_create_/updates_the_database_record_with_the_Salesforce_record_s_ID.yml +81 -28
- data/test/cassettes/Restforce_DB_Synchronizer/_run/given_a_Salesforce_record_with_an_associated_database_record/updates_the_database_record.yml +88 -35
- data/test/cassettes/Restforce_DB_Synchronizer/_run/given_a_Salesforce_record_with_an_associated_database_record/updates_the_salesforce_record.yml +96 -43
- data/test/lib/restforce/db/accumulator_test.rb +16 -0
- data/test/lib/restforce/db/cleaner_test.rb +15 -9
- data/test/lib/restforce/db/collector_test.rb +13 -15
- data/test/lib/restforce/db/field_processor_test.rb +51 -0
- data/test/lib/restforce/db/initializer_test.rb +10 -13
- data/test/lib/restforce/db/runner_cache_test.rb +1 -0
- data/test/support/utilities.rb +1 -0
- metadata +5 -3
- data/test/cassettes/Restforce_DB_Instances_Salesforce/_copy_/updates_the_record_with_the_attributes_from_the_copied_object.yml +0 -194
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd30e064e5e85ed7a3324e54e08797f34df84c84
|
4
|
+
data.tar.gz: 43bf5c31a7517094be1fbb875c701d9b580a4121
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c8c3b7f0ce2cd131c643f2d33f7c15c719b820522e67696bb6d6a4eeb9ef80a77d4a841d8a7d0bf7a8a66fd9caf252357e29cd245f4257823a9d85c55cb9e63
|
7
|
+
data.tar.gz: e75e5b35ed86a07426eea1926ae642d7176167a7de858934a3e251399efe0f85af30fca97e1ea12f93ff9fbcddf7bf925bd08221bb1158e9520987da5ea16d46
|
@@ -44,6 +44,19 @@ module Restforce
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
+
# Public: Do the canonical attributes stored in this Accumulator differ
|
48
|
+
# from those in the passed comparison Hash?
|
49
|
+
#
|
50
|
+
# comparison - A Hash mapping of attributes to values.
|
51
|
+
#
|
52
|
+
# Returns a Boolean.
|
53
|
+
def changed?(comparison)
|
54
|
+
attributes.any? do |attribute, value|
|
55
|
+
next unless comparison.key?(attribute)
|
56
|
+
comparison[attribute] != value
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
47
60
|
end
|
48
61
|
|
49
62
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Restforce
|
2
|
+
|
3
|
+
module DB
|
4
|
+
|
5
|
+
# Restforce::DB::FieldProcessor encapsulates logic for preventing
|
6
|
+
# information for unwriteable fields from being submitted to Salesforce.
|
7
|
+
class FieldProcessor
|
8
|
+
|
9
|
+
# Internal: Get a global cache with which to store/fetch the writable
|
10
|
+
# fields for each Salesforce SObject Type.
|
11
|
+
#
|
12
|
+
# Returns a Hash.
|
13
|
+
def self.field_cache
|
14
|
+
@field_cache ||= {}
|
15
|
+
end
|
16
|
+
|
17
|
+
# Internal: Clear out the global field cache.
|
18
|
+
#
|
19
|
+
# Returns nothing.
|
20
|
+
def self.reset
|
21
|
+
@field_cache = {}
|
22
|
+
end
|
23
|
+
|
24
|
+
# Public: Get a restricted version of the passed attributes Hash, with
|
25
|
+
# unwritable fields stripped out.
|
26
|
+
#
|
27
|
+
# sobject_type - A String name of an SObject Type in Salesforce.
|
28
|
+
# attributes - A Hash with keys corresponding to Salesforce field names.
|
29
|
+
#
|
30
|
+
# Returns a Hash.
|
31
|
+
def process(sobject_type, attributes)
|
32
|
+
attributes.each_with_object({}) do |(field, value), processed|
|
33
|
+
next unless writable?(sobject_type, field)
|
34
|
+
processed[field] = value
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
# Internal: Is the passed attribute writable for the passed SObject Type?
|
41
|
+
#
|
42
|
+
# sobject_type - A String name of an SObject Type in Salesforce.
|
43
|
+
# field - A String Salesforce field API name.
|
44
|
+
#
|
45
|
+
# Returns a Boolean.
|
46
|
+
def writable?(sobject_type, field)
|
47
|
+
field_statuses(sobject_type)[field]
|
48
|
+
end
|
49
|
+
|
50
|
+
# Internal: Get a collection of all fields for the passed Salesforce
|
51
|
+
# SObject Type, with an indication of whether or not they are writable.
|
52
|
+
#
|
53
|
+
# sobject_type - A String name of an SObject Type in Salesforce.
|
54
|
+
#
|
55
|
+
# Returns a Hash.
|
56
|
+
def field_statuses(sobject_type)
|
57
|
+
self.class.field_cache[sobject_type] ||= begin
|
58
|
+
fields = Restforce::DB.client.describe(sobject_type).fields
|
59
|
+
|
60
|
+
fields.each_with_object({}) do |field, output|
|
61
|
+
output[field["name"]] = field["updateable"]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -21,6 +21,16 @@ module Restforce
|
|
21
21
|
@record.Id
|
22
22
|
end
|
23
23
|
|
24
|
+
# Public: Update the instance with the passed attributes.
|
25
|
+
#
|
26
|
+
# attributes - A Hash mapping attribute names to values.
|
27
|
+
#
|
28
|
+
# Returns self.
|
29
|
+
# Raises if the update fails for any reason.
|
30
|
+
def update!(attributes)
|
31
|
+
super FieldProcessor.new.process(@record_type, attributes)
|
32
|
+
end
|
33
|
+
|
24
34
|
# Public: Get the time of the last update to this record.
|
25
35
|
#
|
26
36
|
# Returns a Time-compatible object.
|
@@ -17,8 +17,8 @@ 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
|
-
|
21
|
-
record_id = DB.client.create!(@record_type,
|
20
|
+
from_attributes = FieldProcessor.new.process(@record_type, from_record.attributes)
|
21
|
+
record_id = DB.client.create!(@record_type, from_attributes)
|
22
22
|
|
23
23
|
from_record.update!(@mapping.lookup_column => record_id).after_sync
|
24
24
|
|
@@ -49,10 +49,11 @@ module Restforce
|
|
49
49
|
#
|
50
50
|
# Returns nothing.
|
51
51
|
def update(instance, accumulator)
|
52
|
+
return unless accumulator.changed?(instance.attributes)
|
53
|
+
|
52
54
|
current_attributes = accumulator.current(instance.attributes)
|
53
55
|
attributes = @mapping.convert(instance.record_type, current_attributes)
|
54
56
|
|
55
|
-
return if attributes.empty?
|
56
57
|
instance.update!(attributes)
|
57
58
|
end
|
58
59
|
|
data/lib/restforce/db/version.rb
CHANGED
data/lib/restforce/db.rb
CHANGED
@@ -16,6 +16,7 @@ require "restforce/db/associations/foreign_key"
|
|
16
16
|
require "restforce/db/associations/has_many"
|
17
17
|
require "restforce/db/associations/has_one"
|
18
18
|
|
19
|
+
require "restforce/db/field_processor"
|
19
20
|
require "restforce/db/instances/base"
|
20
21
|
require "restforce/db/instances/active_record"
|
21
22
|
require "restforce/db/instances/salesforce"
|