embulk-output-kintone 0.2.2 → 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/.github/workflows/ci.yml +52 -5
- data/README.md +3 -2
- data/build.gradle +1 -1
- data/classpath/{embulk-output-kintone-0.2.2.jar → embulk-output-kintone-0.3.0.jar} +0 -0
- data/src/main/java/org/embulk/output/kintone/KintoneColumnOption.java +0 -4
- data/src/main/java/org/embulk/output/kintone/KintoneColumnVisitor.java +24 -12
- data/src/main/java/org/embulk/output/kintone/KintoneOutputPlugin.java +6 -19
- data/src/main/java/org/embulk/output/kintone/KintonePageOutput.java +113 -151
- data/src/main/java/org/embulk/output/kintone/PluginTask.java +4 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2004bfc2e202eeb6c57f3149bc7311f90343a67e
|
4
|
+
data.tar.gz: 86e036bc863ac7d8ca632488d0eb84c645658c43
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 723f4b6b9e5341a7e0bef48c6de38528860985d46d9a139c2d3e133c59ab867c9a4507b0c98a431b5b654f332178f90038168bc0143d9d9dcb2916dfe1956e44
|
7
|
+
data.tar.gz: 84441877b034060e5876ae67d8afd1d01f15a91d1aab8a76065bd4549a85c7de1639b0557a814482edc8312bbc11cbcbdc0565fa87aedfb794493966064201b7
|
data/.github/workflows/ci.yml
CHANGED
@@ -1,13 +1,60 @@
|
|
1
|
-
name:
|
1
|
+
name: main
|
2
2
|
|
3
|
-
on:
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- 'master'
|
7
|
+
tags:
|
8
|
+
- '*'
|
9
|
+
pull_request:
|
10
|
+
branches:
|
11
|
+
- 'master'
|
12
|
+
types: [opened, synchronize]
|
4
13
|
|
5
14
|
jobs:
|
6
|
-
|
15
|
+
main:
|
7
16
|
runs-on: ubuntu-latest
|
8
17
|
steps:
|
9
18
|
- uses: actions/checkout@v2
|
10
|
-
-
|
19
|
+
- name: Set Up
|
20
|
+
uses: actions/setup-java@v1
|
11
21
|
with:
|
12
22
|
java-version: 1.8
|
13
|
-
|
23
|
+
|
24
|
+
- name: Test
|
25
|
+
run: ./gradlew test
|
26
|
+
|
27
|
+
- name: Build Gem
|
28
|
+
run: ./gradlew gem
|
29
|
+
|
30
|
+
- name: Set up JRuby
|
31
|
+
uses: ruby/setup-ruby@v1
|
32
|
+
with:
|
33
|
+
ruby-version: jruby
|
34
|
+
|
35
|
+
- name: Publish to GPR
|
36
|
+
if: startsWith( github.ref, 'refs/tags/' )
|
37
|
+
run: |
|
38
|
+
mkdir -p $HOME/.gem
|
39
|
+
touch $HOME/.gem/credentials
|
40
|
+
chmod 0600 $HOME/.gem/credentials
|
41
|
+
printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
42
|
+
gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} ./pkg/*.gem
|
43
|
+
env:
|
44
|
+
GEM_HOST_API_KEY: "Bearer ${{secrets.GITHUB_TOKEN}}"
|
45
|
+
OWNER: ${{ github.repository_owner }}
|
46
|
+
|
47
|
+
- name: Publish to RubyGems
|
48
|
+
if: startsWith( github.ref, 'refs/tags/' )
|
49
|
+
run: |
|
50
|
+
mkdir -p $HOME/.gem
|
51
|
+
touch $HOME/.gem/credentials
|
52
|
+
chmod 0600 $HOME/.gem/credentials
|
53
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
54
|
+
# TODO: If it is possible to accept input in the middle of a step, then the OTP Token should be inputted instead of generated.
|
55
|
+
gem install rotp -v 6.2.0
|
56
|
+
OTP_TOKEN=$(echo ${OTP_SECRET} | ruby -rtime -rrotp -e "puts ROTP::TOTP.new(STDIN.read.chomp, issuer: 'rubygems.org').at(Time.now)")
|
57
|
+
gem push --otp="${OTP_TOKEN}" ./pkg/*.gem
|
58
|
+
env:
|
59
|
+
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_API_KEY}}"
|
60
|
+
OTP_SECRET: "${{secrets.RUBYGEMS_OTP_SECRET}}"
|
data/README.md
CHANGED
@@ -17,11 +17,11 @@ kintone output plugin for Embulk stores app records from kintone.
|
|
17
17
|
- **basic_auth_password**: kintone basic auth password (string, optional)
|
18
18
|
- **guest_space_id**: kintone app belongs to guest space, guest space id is required. (integer, optional)
|
19
19
|
- **mode**: kintone mode (string, required)
|
20
|
+
- **update_key**: column name to set update key (string, required if mode is update or upsert)
|
20
21
|
- **column_options** advanced: a key-value pairs where key is a column name and value is options for the column.
|
21
22
|
- **field_code**: field code (string, required)
|
22
23
|
- **type**: field type (string, required)
|
23
24
|
- **timezone**: timezone to convert into `date` (string, default is `UTC`)
|
24
|
-
- **update_key**: update key (boolean, default is `false`)
|
25
25
|
- **val_sep**: Used to specify multiple checkbox values (string, default is `,`)
|
26
26
|
|
27
27
|
## Example
|
@@ -33,7 +33,8 @@ out:
|
|
33
33
|
username: username
|
34
34
|
password: password
|
35
35
|
app_id: 1
|
36
|
-
mode:
|
36
|
+
mode: upsert
|
37
|
+
update_key: id
|
37
38
|
column_options:
|
38
39
|
id: {field_code: "id", type: "NUMBER"}
|
39
40
|
name: {field_code: "name", type: "SINGLE_LINE_TEXT"}
|
data/build.gradle
CHANGED
Binary file
|
@@ -19,10 +19,6 @@ public interface KintoneColumnOption
|
|
19
19
|
@ConfigDefault("\"UTC\"")
|
20
20
|
public Optional<String> getTimezone();
|
21
21
|
|
22
|
-
@Config("update_key")
|
23
|
-
@ConfigDefault("false")
|
24
|
-
public boolean getUpdateKey();
|
25
|
-
|
26
22
|
@Config("val_sep")
|
27
23
|
@ConfigDefault("\",\"")
|
28
24
|
public String getValueSeparator();
|
@@ -22,6 +22,7 @@ import java.time.Instant;
|
|
22
22
|
import java.time.ZoneId;
|
23
23
|
import java.time.ZonedDateTime;
|
24
24
|
import java.util.Map;
|
25
|
+
import java.util.Objects;
|
25
26
|
|
26
27
|
public class KintoneColumnVisitor
|
27
28
|
implements ColumnVisitor
|
@@ -30,6 +31,7 @@ public class KintoneColumnVisitor
|
|
30
31
|
private Record record;
|
31
32
|
private UpdateKey updateKey;
|
32
33
|
private Map<String, KintoneColumnOption> columnOptions;
|
34
|
+
private String updateKeyName;
|
33
35
|
|
34
36
|
public KintoneColumnVisitor(PageReader pageReader,
|
35
37
|
Map<String, KintoneColumnOption> columnOptions)
|
@@ -38,6 +40,15 @@ public class KintoneColumnVisitor
|
|
38
40
|
this.columnOptions = columnOptions;
|
39
41
|
}
|
40
42
|
|
43
|
+
public KintoneColumnVisitor(PageReader pageReader,
|
44
|
+
Map<String, KintoneColumnOption> columnOptions,
|
45
|
+
String updateKeyName)
|
46
|
+
{
|
47
|
+
this.pageReader = pageReader;
|
48
|
+
this.columnOptions = columnOptions;
|
49
|
+
this.updateKeyName = updateKeyName;
|
50
|
+
}
|
51
|
+
|
41
52
|
public void setRecord(Record record)
|
42
53
|
{
|
43
54
|
this.record = record;
|
@@ -50,20 +61,17 @@ public class KintoneColumnVisitor
|
|
50
61
|
|
51
62
|
private void setValue(String fieldCode, Object value, FieldType type, boolean isUpdateKey)
|
52
63
|
{
|
53
|
-
if (value == null) {
|
54
|
-
return;
|
55
|
-
}
|
56
|
-
|
57
64
|
if (isUpdateKey && updateKey != null) {
|
58
65
|
updateKey
|
59
66
|
.setField(fieldCode)
|
60
|
-
.setValue(
|
67
|
+
.setValue(Objects.toString(value, ""));
|
61
68
|
}
|
62
|
-
String stringValue =
|
63
|
-
FieldValue fieldValue
|
69
|
+
String stringValue = Objects.toString(value, "");
|
70
|
+
FieldValue fieldValue;
|
64
71
|
switch (type) {
|
65
72
|
case NUMBER:
|
66
|
-
|
73
|
+
BigDecimal setValue = stringValue.equals("") ? null : new BigDecimal(stringValue);
|
74
|
+
fieldValue = new NumberFieldValue(setValue);
|
67
75
|
break;
|
68
76
|
case MULTI_LINE_TEXT:
|
69
77
|
fieldValue = new MultiLineTextFieldValue(stringValue);
|
@@ -133,11 +141,11 @@ public class KintoneColumnVisitor
|
|
133
141
|
|
134
142
|
private boolean isUpdateKey(Column column)
|
135
143
|
{
|
136
|
-
|
137
|
-
if (option == null) {
|
144
|
+
if (this.updateKeyName == null) {
|
138
145
|
return false;
|
139
146
|
}
|
140
|
-
|
147
|
+
|
148
|
+
return this.updateKeyName.equals(column.getName());
|
141
149
|
}
|
142
150
|
|
143
151
|
private String getValueSeparator(Column column)
|
@@ -162,7 +170,11 @@ public class KintoneColumnVisitor
|
|
162
170
|
{
|
163
171
|
String fieldCode = getFieldCode(column);
|
164
172
|
FieldType type = getType(column, FieldType.NUMBER);
|
165
|
-
|
173
|
+
if (pageReader.isNull(column)) {
|
174
|
+
setValue(fieldCode, null, type, isUpdateKey(column));
|
175
|
+
} else {
|
176
|
+
setValue(fieldCode, pageReader.getLong(column), type, isUpdateKey(column));
|
177
|
+
}
|
166
178
|
}
|
167
179
|
|
168
180
|
@Override
|
@@ -1,6 +1,7 @@
|
|
1
1
|
package org.embulk.output.kintone;
|
2
2
|
|
3
3
|
import org.embulk.config.ConfigDiff;
|
4
|
+
import org.embulk.config.ConfigException;
|
4
5
|
import org.embulk.config.ConfigSource;
|
5
6
|
import org.embulk.config.TaskReport;
|
6
7
|
import org.embulk.config.TaskSource;
|
@@ -50,32 +51,18 @@ public class KintoneOutputPlugin
|
|
50
51
|
KintoneMode mode = KintoneMode.getKintoneModeByValue(task.getMode());
|
51
52
|
switch (mode) {
|
52
53
|
case INSERT:
|
53
|
-
|
54
|
-
|
55
|
-
throw new IllegalArgumentException(
|
56
|
-
"when mode is insert, require no update_key.");
|
57
|
-
}
|
54
|
+
if (task.getUpdateKeyName().isPresent()) {
|
55
|
+
throw new ConfigException("when mode is insert, require no update_key.");
|
58
56
|
}
|
59
57
|
break;
|
60
58
|
case UPDATE:
|
61
59
|
case UPSERT:
|
62
|
-
|
63
|
-
|
64
|
-
if (option.getUpdateKey()) {
|
65
|
-
if (hasUpdateKey) {
|
66
|
-
throw new IllegalArgumentException(
|
67
|
-
"when mode is update and upsert, only one column can have an update_key.");
|
68
|
-
}
|
69
|
-
hasUpdateKey = true;
|
70
|
-
}
|
71
|
-
}
|
72
|
-
if (!hasUpdateKey) {
|
73
|
-
throw new IllegalArgumentException(
|
74
|
-
"when mode is update and upsert, require update_key.");
|
60
|
+
if (!task.getUpdateKeyName().isPresent()) {
|
61
|
+
throw new ConfigException("when mode is update or upsert, require update_key.");
|
75
62
|
}
|
76
63
|
break;
|
77
64
|
default:
|
78
|
-
throw new
|
65
|
+
throw new ConfigException(String.format(
|
79
66
|
"Unknown mode '%s'",
|
80
67
|
task.getMode()));
|
81
68
|
}
|
@@ -3,6 +3,7 @@ package org.embulk.output.kintone;
|
|
3
3
|
import com.kintone.client.KintoneClient;
|
4
4
|
import com.kintone.client.KintoneClientBuilder;
|
5
5
|
import com.kintone.client.api.record.GetRecordsByCursorResponseBody;
|
6
|
+
import com.kintone.client.model.record.FieldType;
|
6
7
|
import com.kintone.client.model.record.Record;
|
7
8
|
import com.kintone.client.model.record.RecordForUpdate;
|
8
9
|
import com.kintone.client.model.record.UpdateKey;
|
@@ -14,7 +15,6 @@ import org.embulk.spi.PageReader;
|
|
14
15
|
import org.embulk.spi.Schema;
|
15
16
|
import org.embulk.spi.TransactionalPageOutput;
|
16
17
|
|
17
|
-
import java.math.BigDecimal;
|
18
18
|
import java.util.ArrayList;
|
19
19
|
import java.util.Arrays;
|
20
20
|
import java.util.List;
|
@@ -23,6 +23,8 @@ import java.util.stream.Collectors;
|
|
23
23
|
public class KintonePageOutput
|
24
24
|
implements TransactionalPageOutput
|
25
25
|
{
|
26
|
+
public static final int UPSERT_BATCH_SIZE = 10000;
|
27
|
+
public static final int CHUNK_SIZE = 100;
|
26
28
|
private PageReader pageReader;
|
27
29
|
private PluginTask task;
|
28
30
|
private KintoneClient client;
|
@@ -136,7 +138,7 @@ public class KintonePageOutput
|
|
136
138
|
}
|
137
139
|
|
138
140
|
records.add(record);
|
139
|
-
if (records.size() ==
|
141
|
+
if (records.size() == CHUNK_SIZE) {
|
140
142
|
client.record().addRecords(task.getAppId(), records);
|
141
143
|
records.clear();
|
142
144
|
}
|
@@ -155,10 +157,16 @@ public class KintonePageOutput
|
|
155
157
|
{
|
156
158
|
execute(client -> {
|
157
159
|
try {
|
158
|
-
|
160
|
+
if (!task.getUpdateKeyName().isPresent()) {
|
161
|
+
// already validated in KintoneOutputPlugin.open()
|
162
|
+
throw new RuntimeException("unreachable error");
|
163
|
+
}
|
164
|
+
ArrayList<RecordForUpdate> updateRecords = new ArrayList<>();
|
159
165
|
pageReader.setPage(page);
|
166
|
+
|
160
167
|
KintoneColumnVisitor visitor = new KintoneColumnVisitor(pageReader,
|
161
|
-
task.getColumnOptions()
|
168
|
+
task.getColumnOptions(),
|
169
|
+
task.getUpdateKeyName().get());
|
162
170
|
while (pageReader.nextRecord()) {
|
163
171
|
Record record = new Record();
|
164
172
|
UpdateKey updateKey = new UpdateKey();
|
@@ -168,9 +176,13 @@ public class KintonePageOutput
|
|
168
176
|
column.visit(visitor);
|
169
177
|
}
|
170
178
|
|
179
|
+
if (updateKey.getValue() == "") {
|
180
|
+
continue;
|
181
|
+
}
|
182
|
+
|
171
183
|
record.removeField(updateKey.getField());
|
172
184
|
updateRecords.add(new RecordForUpdate(updateKey, record));
|
173
|
-
if (updateRecords.size() ==
|
185
|
+
if (updateRecords.size() == CHUNK_SIZE) {
|
174
186
|
client.record().updateRecords(task.getAppId(), updateRecords);
|
175
187
|
updateRecords.clear();
|
176
188
|
}
|
@@ -185,183 +197,133 @@ public class KintonePageOutput
|
|
185
197
|
});
|
186
198
|
}
|
187
199
|
|
188
|
-
private
|
200
|
+
private void upsertPage(final Page page)
|
189
201
|
{
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
List<Record> records = resp.getRecords();
|
200
|
-
allRecords.addAll(records);
|
202
|
+
execute(client -> {
|
203
|
+
try {
|
204
|
+
if (!task.getUpdateKeyName().isPresent()) {
|
205
|
+
// already validated in KintoneOutputPlugin.open()
|
206
|
+
throw new RuntimeException("unreachable error");
|
207
|
+
}
|
208
|
+
ArrayList<Record> records = new ArrayList<>();
|
209
|
+
ArrayList<UpdateKey> updateKeys = new ArrayList<>();
|
210
|
+
pageReader.setPage(page);
|
201
211
|
|
202
|
-
|
203
|
-
|
212
|
+
KintoneColumnVisitor visitor = new KintoneColumnVisitor(pageReader,
|
213
|
+
task.getColumnOptions(),
|
214
|
+
task.getUpdateKeyName().get());
|
215
|
+
while (pageReader.nextRecord()) {
|
216
|
+
Record record = new Record();
|
217
|
+
UpdateKey updateKey = new UpdateKey();
|
218
|
+
visitor.setRecord(record);
|
219
|
+
visitor.setUpdateKey(updateKey);
|
220
|
+
for (Column column : pageReader.getSchema().getColumns()) {
|
221
|
+
column.visit(visitor);
|
222
|
+
}
|
223
|
+
records.add(record);
|
224
|
+
updateKeys.add(updateKey);
|
225
|
+
|
226
|
+
if (records.size() == UPSERT_BATCH_SIZE) {
|
227
|
+
upsert(records, updateKeys);
|
228
|
+
records.clear();
|
229
|
+
updateKeys.clear();
|
230
|
+
}
|
231
|
+
}
|
232
|
+
if (records.size() > 0) {
|
233
|
+
upsert(records, updateKeys);
|
234
|
+
}
|
204
235
|
}
|
205
|
-
|
206
|
-
|
236
|
+
catch (Exception e) {
|
237
|
+
throw new RuntimeException("kintone throw exception", e);
|
238
|
+
}
|
239
|
+
});
|
207
240
|
}
|
208
241
|
|
209
|
-
|
242
|
+
private void upsert(ArrayList<Record> records, ArrayList<UpdateKey> updateKeys)
|
210
243
|
{
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
public void upsert(ArrayList<Record> records, ArrayList<UpdateKey> updateKeys)
|
215
|
-
{
|
216
|
-
if (records.size() != updateKeys.size()) {
|
217
|
-
throw new RuntimeException("records.size() != updateKeys.size()");
|
218
|
-
}
|
219
|
-
|
220
|
-
List<String> queryValues = updateKeys
|
221
|
-
.stream()
|
222
|
-
.map(k -> "\"" + k.getValue().toString() + "\"")
|
223
|
-
.collect(Collectors.toList());
|
224
|
-
List<T> updateKeyValues = getUpdateKeyValues(queryValues);
|
244
|
+
if (records.size() != updateKeys.size()) {
|
245
|
+
throw new RuntimeException("records.size() != updateKeys.size()");
|
246
|
+
}
|
225
247
|
|
226
|
-
|
227
|
-
ArrayList<RecordForUpdate> updateRecords = new ArrayList<RecordForUpdate>();
|
228
|
-
for (int i = 0; i < records.size(); i++) {
|
229
|
-
Record record = records.get(i);
|
230
|
-
UpdateKey updateKey = updateKeys.get(i);
|
248
|
+
List<Record> existingRecords = getExistingRecordsByUpdateKey(updateKeys);
|
231
249
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
insertRecords.add(record);
|
238
|
-
}
|
250
|
+
ArrayList<Record> insertRecords = new ArrayList<>();
|
251
|
+
ArrayList<RecordForUpdate> updateRecords = new ArrayList<>();
|
252
|
+
for (int i = 0; i < records.size(); i++) {
|
253
|
+
Record record = records.get(i);
|
254
|
+
UpdateKey updateKey = updateKeys.get(i);
|
239
255
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
updateRecords.clear();
|
247
|
-
}
|
256
|
+
if (existsRecord(existingRecords, updateKey)) {
|
257
|
+
record.removeField(updateKey.getField());
|
258
|
+
updateRecords.add(new RecordForUpdate(updateKey, record));
|
259
|
+
}
|
260
|
+
else {
|
261
|
+
insertRecords.add(record);
|
248
262
|
}
|
249
|
-
|
263
|
+
|
264
|
+
if (insertRecords.size() == CHUNK_SIZE) {
|
250
265
|
client.record().addRecords(task.getAppId(), insertRecords);
|
266
|
+
insertRecords.clear();
|
251
267
|
}
|
252
|
-
if (updateRecords.size()
|
268
|
+
else if (updateRecords.size() == CHUNK_SIZE) {
|
253
269
|
client.record().updateRecords(task.getAppId(), updateRecords);
|
270
|
+
updateRecords.clear();
|
254
271
|
}
|
255
272
|
}
|
256
|
-
|
257
|
-
|
258
|
-
{
|
259
|
-
execute(client -> {
|
260
|
-
try {
|
261
|
-
ArrayList<Record> records = new ArrayList<>();
|
262
|
-
ArrayList<UpdateKey> updateKeys = new ArrayList<>();
|
263
|
-
|
264
|
-
pageReader.setPage(page);
|
265
|
-
KintoneColumnVisitor visitor = new KintoneColumnVisitor(pageReader,
|
266
|
-
task.getColumnOptions());
|
267
|
-
while (pageReader.nextRecord()) {
|
268
|
-
Record record = new Record();
|
269
|
-
UpdateKey updateKey = new UpdateKey();
|
270
|
-
visitor.setRecord(record);
|
271
|
-
visitor.setUpdateKey(updateKey);
|
272
|
-
for (Column column : pageReader.getSchema().getColumns()) {
|
273
|
-
column.visit(visitor);
|
274
|
-
}
|
275
|
-
records.add(record);
|
276
|
-
updateKeys.add(updateKey);
|
277
|
-
|
278
|
-
if (records.size() == 10000) {
|
279
|
-
upsert(records, updateKeys);
|
280
|
-
records.clear();
|
281
|
-
updateKeys.clear();
|
282
|
-
}
|
283
|
-
}
|
284
|
-
if (records.size() > 0) {
|
285
|
-
upsert(records, updateKeys);
|
286
|
-
}
|
287
|
-
}
|
288
|
-
catch (Exception e) {
|
289
|
-
throw new RuntimeException("kintone throw exception", e);
|
290
|
-
}
|
291
|
-
});
|
292
|
-
}
|
293
|
-
}
|
294
|
-
|
295
|
-
class UpsertPageByStringKey extends UpsertPage<String>
|
296
|
-
{
|
297
|
-
private String fieldCode;
|
298
|
-
|
299
|
-
public UpsertPageByStringKey(String fieldCode)
|
300
|
-
{
|
301
|
-
this.fieldCode = fieldCode;
|
302
|
-
}
|
303
|
-
|
304
|
-
public List<String> getUpdateKeyValues(List<String> queryValues)
|
305
|
-
{
|
306
|
-
return getRecordsByUpdateKey(fieldCode, queryValues)
|
307
|
-
.stream()
|
308
|
-
.map(r -> r.getSingleLineTextFieldValue(fieldCode))
|
309
|
-
.collect(Collectors.toList());
|
273
|
+
if (insertRecords.size() > 0) {
|
274
|
+
client.record().addRecords(task.getAppId(), insertRecords);
|
310
275
|
}
|
311
|
-
|
312
|
-
|
313
|
-
{
|
314
|
-
return updateKeyValues.contains(record.getSingleLineTextFieldValue(fieldCode));
|
276
|
+
if (updateRecords.size() > 0) {
|
277
|
+
client.record().updateRecords(task.getAppId(), updateRecords);
|
315
278
|
}
|
316
279
|
}
|
317
280
|
|
318
|
-
class UpsertPageByNumberKey extends UpsertPage<BigDecimal>
|
319
|
-
{
|
320
|
-
private String fieldCode;
|
321
|
-
|
322
|
-
public UpsertPageByNumberKey(String fieldCode)
|
323
|
-
{
|
324
|
-
this.fieldCode = fieldCode;
|
325
|
-
}
|
326
281
|
|
327
|
-
|
328
|
-
|
329
|
-
|
282
|
+
private List<Record> getExistingRecordsByUpdateKey(ArrayList<UpdateKey> updateKeys)
|
283
|
+
{
|
284
|
+
String fieldCode = updateKeys.get(0).getField();
|
285
|
+
List<String> queryValues = updateKeys
|
330
286
|
.stream()
|
331
|
-
.
|
287
|
+
.filter(k -> k.getValue() != "")
|
288
|
+
.map(k -> "\"" + k.getValue().toString() + "\"")
|
332
289
|
.collect(Collectors.toList());
|
333
|
-
}
|
334
290
|
|
335
|
-
|
336
|
-
{
|
337
|
-
return
|
291
|
+
List<Record> allRecords = new ArrayList<>();
|
292
|
+
if (queryValues.isEmpty()) {
|
293
|
+
return allRecords;
|
338
294
|
}
|
339
|
-
|
295
|
+
String cursorId = client.record().createCursor(
|
296
|
+
task.getAppId(),
|
297
|
+
Arrays.asList(fieldCode),
|
298
|
+
fieldCode + " in (" + String.join(",", queryValues) + ")"
|
299
|
+
);
|
300
|
+
while (true) {
|
301
|
+
GetRecordsByCursorResponseBody resp = client.record().getRecordsByCursor(cursorId);
|
302
|
+
List<Record> records = resp.getRecords();
|
303
|
+
allRecords.addAll(records);
|
340
304
|
|
341
|
-
|
342
|
-
{
|
343
|
-
KintoneColumnOption updateKeyColumn = null;
|
344
|
-
for (KintoneColumnOption v : task.getColumnOptions().values()) {
|
345
|
-
if (v.getUpdateKey()) {
|
346
|
-
updateKeyColumn = v;
|
305
|
+
if (!resp.hasNext()) {
|
347
306
|
break;
|
348
307
|
}
|
349
308
|
}
|
350
|
-
|
351
|
-
|
352
|
-
}
|
309
|
+
return allRecords;
|
310
|
+
}
|
353
311
|
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
case
|
360
|
-
|
361
|
-
|
312
|
+
private boolean existsRecord(List<Record> distRecords, UpdateKey updateKey)
|
313
|
+
{
|
314
|
+
String fieldCode = updateKey.getField();
|
315
|
+
FieldType type = client.app().getFormFields(task.getAppId()).get(fieldCode).getType();
|
316
|
+
switch (type) {
|
317
|
+
case SINGLE_LINE_TEXT:
|
318
|
+
return distRecords
|
319
|
+
.stream()
|
320
|
+
.anyMatch(d -> d.getSingleLineTextFieldValue(fieldCode).equals(updateKey.getValue()));
|
321
|
+
case NUMBER:
|
322
|
+
return distRecords
|
323
|
+
.stream()
|
324
|
+
.anyMatch(d -> d.getNumberFieldValue(fieldCode).equals(updateKey.getValue()));
|
362
325
|
default:
|
363
326
|
throw new RuntimeException("The update_key must be 'SINGLE_LINE_TEXT' or 'NUMBER'.");
|
364
327
|
}
|
365
|
-
runner.run(page);
|
366
328
|
}
|
367
329
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: embulk-output-kintone
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- takeshi fujita
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-03-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,7 +52,7 @@ files:
|
|
52
52
|
- README.md
|
53
53
|
- Rakefile
|
54
54
|
- build.gradle
|
55
|
-
- classpath/embulk-output-kintone-0.
|
55
|
+
- classpath/embulk-output-kintone-0.3.0.jar
|
56
56
|
- config/checkstyle/checkstyle.xml
|
57
57
|
- config/checkstyle/default.xml
|
58
58
|
- gradle/wrapper/gradle-wrapper.jar
|