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