embulk-output-kintone 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 59e8a8850c43f8ff293ca6b63d908f6e7e04b1ac
4
- data.tar.gz: 42f8ae842db0e3177b1123dc45dd7919f2cb903d
3
+ metadata.gz: 2004bfc2e202eeb6c57f3149bc7311f90343a67e
4
+ data.tar.gz: 86e036bc863ac7d8ca632488d0eb84c645658c43
5
5
  SHA512:
6
- metadata.gz: 447d0a6901e2bf7d4993fb9f20291f236199bd53e3ae4924b85444c64e8b4fa78a2bccf3c42083edde6c6d863953a6d6f1e70be4d629dd7f35ddc63ab81276de
7
- data.tar.gz: 8a6fb5c6cde0a75377b95641cadacc243ca7ab0ddd03d641df37f055c574a33552bd045b13cfa6236f49d570188c490d83dedb5715bd2908a53746af721c060c
6
+ metadata.gz: 723f4b6b9e5341a7e0bef48c6de38528860985d46d9a139c2d3e133c59ab867c9a4507b0c98a431b5b654f332178f90038168bc0143d9d9dcb2916dfe1956e44
7
+ data.tar.gz: 84441877b034060e5876ae67d8afd1d01f15a91d1aab8a76065bd4549a85c7de1639b0557a814482edc8312bbc11cbcbdc0565fa87aedfb794493966064201b7
@@ -1,13 +1,60 @@
1
- name: Java CI
1
+ name: main
2
2
 
3
- on: [push, pull_request]
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
- build:
15
+ main:
7
16
  runs-on: ubuntu-latest
8
17
  steps:
9
18
  - uses: actions/checkout@v2
10
- - uses: actions/setup-java@v1
19
+ - name: Set Up
20
+ uses: actions/setup-java@v1
11
21
  with:
12
22
  java-version: 1.8
13
- - run: ./gradlew build
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: insert
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
@@ -14,7 +14,7 @@ configurations {
14
14
  provided
15
15
  }
16
16
 
17
- version = "0.2.2"
17
+ version = "0.3.0"
18
18
 
19
19
  sourceCompatibility = 1.8
20
20
  targetCompatibility = 1.8
@@ -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(String.valueOf(value));
67
+ .setValue(Objects.toString(value, ""));
61
68
  }
62
- String stringValue = String.valueOf(value);
63
- FieldValue fieldValue = null;
69
+ String stringValue = Objects.toString(value, "");
70
+ FieldValue fieldValue;
64
71
  switch (type) {
65
72
  case NUMBER:
66
- fieldValue = new NumberFieldValue(new BigDecimal(stringValue));
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
- KintoneColumnOption option = columnOptions.get(column.getName());
137
- if (option == null) {
144
+ if (this.updateKeyName == null) {
138
145
  return false;
139
146
  }
140
- return option.getUpdateKey();
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
- setValue(fieldCode, pageReader.getLong(column), type, isUpdateKey(column));
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
- for (KintoneColumnOption option : options) {
54
- if (option.getUpdateKey()) {
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
- boolean hasUpdateKey = false;
63
- for (KintoneColumnOption option : options) {
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 IllegalArgumentException(String.format(
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() == 100) {
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
- ArrayList<RecordForUpdate> updateRecords = new ArrayList<RecordForUpdate>();
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() == 100) {
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 List<Record> getRecordsByUpdateKey(String fieldCode, List<String> queryValues)
200
+ private void upsertPage(final Page page)
189
201
  {
190
- List<Record> allRecords = new ArrayList<Record>();
191
- List<String> fields = Arrays.asList(fieldCode);
192
- String cursorId = client.record().createCursor(
193
- task.getAppId(),
194
- fields,
195
- fieldCode + " in (" + String.join(",", queryValues) + ")"
196
- );
197
- while (true) {
198
- GetRecordsByCursorResponseBody resp = client.record().getRecordsByCursor(cursorId);
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
- if (!resp.hasNext()) {
203
- break;
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
- return allRecords;
236
+ catch (Exception e) {
237
+ throw new RuntimeException("kintone throw exception", e);
238
+ }
239
+ });
207
240
  }
208
241
 
209
- abstract class UpsertPage<T>
242
+ private void upsert(ArrayList<Record> records, ArrayList<UpdateKey> updateKeys)
210
243
  {
211
- public abstract List<T> getUpdateKeyValues(List<String> queryValues);
212
- public abstract boolean existsRecord(List<T> updateKeyValues, Record record);
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
- ArrayList<Record> insertRecords = new ArrayList<>();
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
- if (existsRecord(updateKeyValues, record)) {
233
- record.removeField(updateKey.getField());
234
- updateRecords.add(new RecordForUpdate(updateKey, record));
235
- }
236
- else {
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
- if (insertRecords.size() == 100) {
241
- client.record().addRecords(task.getAppId(), insertRecords);
242
- insertRecords.clear();
243
- }
244
- else if (updateRecords.size() == 100) {
245
- client.record().updateRecords(task.getAppId(), updateRecords);
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
- if (insertRecords.size() > 0) {
263
+
264
+ if (insertRecords.size() == CHUNK_SIZE) {
250
265
  client.record().addRecords(task.getAppId(), insertRecords);
266
+ insertRecords.clear();
251
267
  }
252
- if (updateRecords.size() > 0) {
268
+ else if (updateRecords.size() == CHUNK_SIZE) {
253
269
  client.record().updateRecords(task.getAppId(), updateRecords);
270
+ updateRecords.clear();
254
271
  }
255
272
  }
256
-
257
- public void run(final Page page)
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
- public boolean existsRecord(List<String> updateKeyValues, Record record)
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
- public List<BigDecimal> getUpdateKeyValues(List<String> queryValues)
328
- {
329
- return getRecordsByUpdateKey(fieldCode, queryValues)
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
- .map(r -> r.getNumberFieldValue(fieldCode))
287
+ .filter(k -> k.getValue() != "")
288
+ .map(k -> "\"" + k.getValue().toString() + "\"")
332
289
  .collect(Collectors.toList());
333
- }
334
290
 
335
- public boolean existsRecord(List<BigDecimal> updateKeyValues, Record record)
336
- {
337
- return updateKeyValues.contains(record.getNumberFieldValue(fieldCode));
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
- private void upsertPage(final Page page)
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
- if (updateKeyColumn == null) {
351
- throw new RuntimeException("when mode is upsert, require update_key");
352
- }
309
+ return allRecords;
310
+ }
353
311
 
354
- UpsertPage runner;
355
- switch(updateKeyColumn.getType()) {
356
- case "SINGLE_LINE_TEXT":
357
- runner = new UpsertPageByStringKey(updateKeyColumn.getFieldCode());
358
- break;
359
- case "NUMBER":
360
- runner = new UpsertPageByNumberKey(updateKeyColumn.getFieldCode());
361
- break;
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
  }
@@ -47,4 +47,8 @@ public interface PluginTask
47
47
  @Config("mode")
48
48
  @ConfigDefault("insert")
49
49
  public String getMode();
50
+
51
+ @Config("update_key")
52
+ @ConfigDefault("null")
53
+ Optional<String> getUpdateKeyName();
50
54
  }
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.2.2
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: 2020-11-18 00:00:00.000000000 Z
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.2.2.jar
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