active_force 0.19.0 → 0.20.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/.gitignore +1 -0
- data/CHANGELOG.md +5 -0
- data/lib/active_force/bulk/records.rb +18 -1
- data/lib/active_force/query.rb +12 -4
- data/lib/active_force/version.rb +1 -1
- data/spec/active_force/bulk/record_spec.rb +22 -0
- data/spec/active_force/query_spec.rb +16 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1647fdc453090811c384514ae857c83b686dc966e2af5e47af3a6dc67e42059d
|
4
|
+
data.tar.gz: 515a98a5715c24359739d76730758b728a9cbf1b8c0cbf2b3c1bb5a355a21c9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48115b7a0df0201a24f477ba2f658e692824337a78c0d288afd3c056b42fccaaf065e1e3ab296fa16bda1f2f2eaf82ff1322adcea6d9d6a9f82c2318cea15d98
|
7
|
+
data.tar.gz: a7b6dacca6775374b089cc9022462c470d8103d63792c7e7668ccd3e082446b0429a2d54d0e3392694c0e25ea25139916d11bc9f0080659faea6e7eaa0e41541
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,11 @@
|
|
2
2
|
|
3
3
|
## Not released
|
4
4
|
|
5
|
+
## 0.20.0
|
6
|
+
|
7
|
+
- Change `.first` to not query the API if records have already been retrieved (https://github.com/Beyond-Finance/active_force/pull/73)
|
8
|
+
- Bugfix: Transform NULL values for SF Bulk API, which expects "#N/A" (https://github.com/Beyond-Finance/active_force/pull/74)
|
9
|
+
|
5
10
|
## 0.19.0
|
6
11
|
|
7
12
|
- Bulk API methods. (https://github.com/Beyond-Finance/active_force/pull/65)
|
@@ -3,6 +3,8 @@ require 'csv'
|
|
3
3
|
module ActiveForce
|
4
4
|
module Bulk
|
5
5
|
class Records
|
6
|
+
NULL_VALUE = '#N/A'.freeze
|
7
|
+
|
6
8
|
attr_reader :headers, :data
|
7
9
|
def initialize(headers:, data:)
|
8
10
|
@headers = headers
|
@@ -16,10 +18,25 @@ module ActiveForce
|
|
16
18
|
end
|
17
19
|
|
18
20
|
def self.parse_from_attributes(records)
|
21
|
+
# Sorting ensures that the headers line up with the values for the CSV
|
19
22
|
headers = records.first.keys.sort.map(&:to_s)
|
20
|
-
data = records.map
|
23
|
+
data = records.map do |r|
|
24
|
+
r.transform_values { |v| transform_value_for_sf(v) }.sort.pluck(-1)
|
25
|
+
end
|
21
26
|
new(headers: headers, data: data)
|
22
27
|
end
|
28
|
+
|
29
|
+
# SF expects a special value for setting a column to be NULL.
|
30
|
+
def self.transform_value_for_sf(value)
|
31
|
+
case value
|
32
|
+
when NilClass
|
33
|
+
NULL_VALUE
|
34
|
+
when Time
|
35
|
+
value.iso8601
|
36
|
+
else
|
37
|
+
value.to_s
|
38
|
+
end
|
39
|
+
end
|
23
40
|
end
|
24
41
|
end
|
25
42
|
end
|
data/lib/active_force/query.rb
CHANGED
@@ -78,7 +78,15 @@ module ActiveForce
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def first
|
81
|
-
|
81
|
+
if @records
|
82
|
+
clone_and_set_instance_variables(
|
83
|
+
size: 1,
|
84
|
+
records: [@records.first],
|
85
|
+
decorated_records: [@decorated_records&.first]
|
86
|
+
)
|
87
|
+
else
|
88
|
+
limit(1)
|
89
|
+
end
|
82
90
|
end
|
83
91
|
|
84
92
|
def last(limit = 1)
|
@@ -126,9 +134,9 @@ module ActiveForce
|
|
126
134
|
|
127
135
|
def clone_and_set_instance_variables instance_variable_hash={}
|
128
136
|
clone = self.clone
|
129
|
-
|
130
|
-
|
131
|
-
|
137
|
+
{ decorated_records: nil, records: nil }
|
138
|
+
.merge(instance_variable_hash)
|
139
|
+
.each { |k,v| clone.instance_variable_set("@#{k.to_s}", v) }
|
132
140
|
clone
|
133
141
|
end
|
134
142
|
end
|
data/lib/active_force/version.rb
CHANGED
@@ -9,11 +9,13 @@ describe ActiveForce::Bulk::Records do
|
|
9
9
|
%w[value3 value4],
|
10
10
|
]
|
11
11
|
end
|
12
|
+
|
12
13
|
describe '#to_csv' do
|
13
14
|
it 'returns CSV with headers' do
|
14
15
|
expect(subject.to_csv).to eq "header1,header2\nvalue1,value2\nvalue3,value4\n"
|
15
16
|
end
|
16
17
|
end
|
18
|
+
|
17
19
|
describe '::parse_from_attributes' do
|
18
20
|
subject { described_class.parse_from_attributes(attributes) }
|
19
21
|
let(:attributes) do
|
@@ -28,5 +30,25 @@ describe ActiveForce::Bulk::Records do
|
|
28
30
|
expect(records.headers).to eq headers
|
29
31
|
expect(records.data).to eq data
|
30
32
|
end
|
33
|
+
|
34
|
+
context 'when there are NULL values' do
|
35
|
+
let(:attributes) do
|
36
|
+
[
|
37
|
+
{ header1: nil, header2: 'value2'},
|
38
|
+
{ header1: 'value3', header2: nil},
|
39
|
+
]
|
40
|
+
end
|
41
|
+
let(:data) do
|
42
|
+
[
|
43
|
+
%w[#N/A value2],
|
44
|
+
%w[value3 #N/A],
|
45
|
+
]
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'substitutes the expected SF value for NULL' do
|
49
|
+
records = subject
|
50
|
+
expect(records.data).to eq data
|
51
|
+
end
|
52
|
+
end
|
31
53
|
end
|
32
54
|
end
|
@@ -165,6 +165,22 @@ describe ActiveForce::Query do
|
|
165
165
|
expect(query.to_s).to eq "SELECT Id, name, etc FROM table_name"
|
166
166
|
expect(new_query.to_s).to eq 'SELECT Id, name, etc FROM table_name LIMIT 1'
|
167
167
|
end
|
168
|
+
|
169
|
+
it "does not query if records have already been fetched" do
|
170
|
+
query = ActiveForce::Query.new 'table_name'
|
171
|
+
query.instance_variable_set(:@records, %w[foo bar])
|
172
|
+
query.instance_variable_set(:@decorated_records, %w[foo bar])
|
173
|
+
expect(query).not_to receive(:limit)
|
174
|
+
expect(query).to receive(:clone_and_set_instance_variables).with(size: 1, records: ['foo'], decorated_records: ['foo'])
|
175
|
+
query.first
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'queries the api if it has not been queried yet' do
|
179
|
+
query = ActiveForce::Query.new 'table_name'
|
180
|
+
query.instance_variable_set(:@records, nil)
|
181
|
+
expect(query).to receive(:limit)
|
182
|
+
query.first
|
183
|
+
end
|
168
184
|
end
|
169
185
|
|
170
186
|
describe '.last' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_force
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.20.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eloy Espinaco
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2023-11-
|
14
|
+
date: 2023-11-27 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: activemodel
|