embulk-output-kintone 0.2.0 → 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: 12c249d873d4feb22cad46c5d7bd8858f21c6138
4
- data.tar.gz: fe0ff0d7a8433caa4afe30a90c2acd7bdffb73ac
3
+ metadata.gz: 2004bfc2e202eeb6c57f3149bc7311f90343a67e
4
+ data.tar.gz: 86e036bc863ac7d8ca632488d0eb84c645658c43
5
5
  SHA512:
6
- metadata.gz: 6f6a9c530c8c9ea1b3324aace5dbac3a9cbb6eaf9a800a064942f1229565a86cfb0ad51bd95ce53cadfc014320981c4e126addf699a32e16b90e7667a2745004
7
- data.tar.gz: 96f86db9027769370cf6af39f2ff157d7ca6b691d1712fa2ec112e04a464dc87e6db5b3d664ef45d69db73f213ce5e7007f0321c86809a5d5d17c11b1bb0479f
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.0"
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,36 +61,31 @@ 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
- else {
63
- String stringValue = String.valueOf(value);
64
- FieldValue fieldValue = null;
65
- switch (type) {
66
- case NUMBER:
67
- fieldValue = new NumberFieldValue(new BigDecimal(stringValue));
68
- break;
69
- case MULTI_LINE_TEXT:
70
- fieldValue = new MultiLineTextFieldValue(stringValue);
71
- break;
72
- case DROP_DOWN:
73
- fieldValue = new DropDownFieldValue(stringValue);
74
- break;
75
- case LINK:
76
- fieldValue = new LinkFieldValue(stringValue);
77
- break;
78
- default:
79
- fieldValue = new SingleLineTextFieldValue(stringValue);
80
- }
81
- record.putField(fieldCode, fieldValue);
69
+ String stringValue = Objects.toString(value, "");
70
+ FieldValue fieldValue;
71
+ switch (type) {
72
+ case NUMBER:
73
+ BigDecimal setValue = stringValue.equals("") ? null : new BigDecimal(stringValue);
74
+ fieldValue = new NumberFieldValue(setValue);
75
+ break;
76
+ case MULTI_LINE_TEXT:
77
+ fieldValue = new MultiLineTextFieldValue(stringValue);
78
+ break;
79
+ case DROP_DOWN:
80
+ fieldValue = new DropDownFieldValue(stringValue);
81
+ break;
82
+ case LINK:
83
+ fieldValue = new LinkFieldValue(stringValue);
84
+ break;
85
+ default:
86
+ fieldValue = new SingleLineTextFieldValue(stringValue);
82
87
  }
88
+ record.putField(fieldCode, fieldValue);
83
89
  }
84
90
 
85
91
  private void setTimestampValue(String fieldCode, Instant instant, ZoneId zoneId, FieldType type)
@@ -135,11 +141,11 @@ public class KintoneColumnVisitor
135
141
 
136
142
  private boolean isUpdateKey(Column column)
137
143
  {
138
- KintoneColumnOption option = columnOptions.get(column.getName());
139
- if (option == null) {
144
+ if (this.updateKeyName == null) {
140
145
  return false;
141
146
  }
142
- return option.getUpdateKey();
147
+
148
+ return this.updateKeyName.equals(column.getName());
143
149
  }
144
150
 
145
151
  private String getValueSeparator(Column column)
@@ -164,7 +170,11 @@ public class KintoneColumnVisitor
164
170
  {
165
171
  String fieldCode = getFieldCode(column);
166
172
  FieldType type = getType(column, FieldType.NUMBER);
167
- 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
+ }
168
178
  }
169
179
 
170
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,17 +15,16 @@ 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
- import java.util.HashMap;
21
20
  import java.util.List;
22
- import java.util.Map;
23
21
  import java.util.stream.Collectors;
24
22
 
25
23
  public class KintonePageOutput
26
24
  implements TransactionalPageOutput
27
25
  {
26
+ public static final int UPSERT_BATCH_SIZE = 10000;
27
+ public static final int CHUNK_SIZE = 100;
28
28
  private PageReader pageReader;
29
29
  private PluginTask task;
30
30
  private KintoneClient client;
@@ -138,7 +138,7 @@ public class KintonePageOutput
138
138
  }
139
139
 
140
140
  records.add(record);
141
- if (records.size() == 100) {
141
+ if (records.size() == CHUNK_SIZE) {
142
142
  client.record().addRecords(task.getAppId(), records);
143
143
  records.clear();
144
144
  }
@@ -157,10 +157,16 @@ public class KintonePageOutput
157
157
  {
158
158
  execute(client -> {
159
159
  try {
160
- 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<>();
161
165
  pageReader.setPage(page);
166
+
162
167
  KintoneColumnVisitor visitor = new KintoneColumnVisitor(pageReader,
163
- task.getColumnOptions());
168
+ task.getColumnOptions(),
169
+ task.getUpdateKeyName().get());
164
170
  while (pageReader.nextRecord()) {
165
171
  Record record = new Record();
166
172
  UpdateKey updateKey = new UpdateKey();
@@ -170,9 +176,13 @@ public class KintonePageOutput
170
176
  column.visit(visitor);
171
177
  }
172
178
 
179
+ if (updateKey.getValue() == "") {
180
+ continue;
181
+ }
182
+
173
183
  record.removeField(updateKey.getField());
174
184
  updateRecords.add(new RecordForUpdate(updateKey, record));
175
- if (updateRecords.size() == 100) {
185
+ if (updateRecords.size() == CHUNK_SIZE) {
176
186
  client.record().updateRecords(task.getAppId(), updateRecords);
177
187
  updateRecords.clear();
178
188
  }
@@ -187,150 +197,133 @@ public class KintonePageOutput
187
197
  });
188
198
  }
189
199
 
190
- private List<Record> getAllRecords(String fieldCode)
200
+ private void upsertPage(final Page page)
191
201
  {
192
- List<Record> allRecords = new ArrayList<Record>();
193
- List<String> fields = Arrays.asList(fieldCode);
194
- String cursorId = client.record().createCursor(task.getAppId(), fields, null);
195
- while (true) {
196
- GetRecordsByCursorResponseBody resp = client.record().getRecordsByCursor(cursorId);
197
- List<Record> records = resp.getRecords();
198
- allRecords.addAll(records);
199
-
200
- if (!resp.hasNext()) {
201
- break;
202
- }
203
- }
204
- return allRecords;
205
- }
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);
206
211
 
207
- abstract class UpsertPage<T>
208
- {
209
- public abstract List<T> getUpdateKeyValues();
210
- public abstract boolean existsRecord(List<T> updateKeyValues, Record record);
211
-
212
- public void run(final Page page)
213
- {
214
- execute(client -> {
215
- try {
216
- List<T> updateKeyValues = getUpdateKeyValues();
217
-
218
- ArrayList<Record> insertRecords = new ArrayList<>();
219
- ArrayList<RecordForUpdate> updateRecords = new ArrayList<RecordForUpdate>();
220
- pageReader.setPage(page);
221
- KintoneColumnVisitor visitor = new KintoneColumnVisitor(pageReader,
222
- task.getColumnOptions());
223
- while (pageReader.nextRecord()) {
224
- Record record = new Record();
225
- UpdateKey updateKey = new UpdateKey();
226
- visitor.setRecord(record);
227
- visitor.setUpdateKey(updateKey);
228
- for (Column column : pageReader.getSchema().getColumns()) {
229
- column.visit(visitor);
230
- }
231
-
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
- }
239
-
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
- }
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);
248
222
  }
223
+ records.add(record);
224
+ updateKeys.add(updateKey);
249
225
 
250
- if (insertRecords.size() > 0) {
251
- client.record().addRecords(task.getAppId(), insertRecords);
252
- }
253
- if (updateRecords.size() > 0) {
254
- client.record().updateRecords(task.getAppId(), updateRecords);
226
+ if (records.size() == UPSERT_BATCH_SIZE) {
227
+ upsert(records, updateKeys);
228
+ records.clear();
229
+ updateKeys.clear();
255
230
  }
256
231
  }
257
- catch (Exception e) {
258
- throw new RuntimeException("kintone throw exception", e);
232
+ if (records.size() > 0) {
233
+ upsert(records, updateKeys);
259
234
  }
260
- });
261
- }
235
+ }
236
+ catch (Exception e) {
237
+ throw new RuntimeException("kintone throw exception", e);
238
+ }
239
+ });
262
240
  }
263
241
 
264
- class UpsertPageByStringKey extends UpsertPage<String>
242
+ private void upsert(ArrayList<Record> records, ArrayList<UpdateKey> updateKeys)
265
243
  {
266
- private String fieldCode;
267
-
268
- public UpsertPageByStringKey(String fieldCode)
269
- {
270
- this.fieldCode = fieldCode;
244
+ if (records.size() != updateKeys.size()) {
245
+ throw new RuntimeException("records.size() != updateKeys.size()");
271
246
  }
272
247
 
273
- public List<String> getUpdateKeyValues()
274
- {
275
- return getAllRecords(fieldCode)
276
- .stream()
277
- .map(r -> r.getSingleLineTextFieldValue(fieldCode))
278
- .collect(Collectors.toList());
279
- }
248
+ List<Record> existingRecords = getExistingRecordsByUpdateKey(updateKeys);
280
249
 
281
- public boolean existsRecord(List<String> updateKeyValues, Record record)
282
- {
283
- return updateKeyValues.contains(record.getSingleLineTextFieldValue(fieldCode));
284
- }
285
- }
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);
286
255
 
287
- class UpsertPageByNumberKey extends UpsertPage<BigDecimal>
288
- {
289
- private String fieldCode;
256
+ if (existsRecord(existingRecords, updateKey)) {
257
+ record.removeField(updateKey.getField());
258
+ updateRecords.add(new RecordForUpdate(updateKey, record));
259
+ }
260
+ else {
261
+ insertRecords.add(record);
262
+ }
290
263
 
291
- public UpsertPageByNumberKey(String fieldCode)
292
- {
293
- this.fieldCode = fieldCode;
264
+ if (insertRecords.size() == CHUNK_SIZE) {
265
+ client.record().addRecords(task.getAppId(), insertRecords);
266
+ insertRecords.clear();
267
+ }
268
+ else if (updateRecords.size() == CHUNK_SIZE) {
269
+ client.record().updateRecords(task.getAppId(), updateRecords);
270
+ updateRecords.clear();
271
+ }
272
+ }
273
+ if (insertRecords.size() > 0) {
274
+ client.record().addRecords(task.getAppId(), insertRecords);
275
+ }
276
+ if (updateRecords.size() > 0) {
277
+ client.record().updateRecords(task.getAppId(), updateRecords);
294
278
  }
279
+ }
280
+
295
281
 
296
- public List<BigDecimal> getUpdateKeyValues()
297
- {
298
- return getAllRecords(fieldCode)
282
+ private List<Record> getExistingRecordsByUpdateKey(ArrayList<UpdateKey> updateKeys)
283
+ {
284
+ String fieldCode = updateKeys.get(0).getField();
285
+ List<String> queryValues = updateKeys
299
286
  .stream()
300
- .map(r -> r.getNumberFieldValue(fieldCode))
287
+ .filter(k -> k.getValue() != "")
288
+ .map(k -> "\"" + k.getValue().toString() + "\"")
301
289
  .collect(Collectors.toList());
302
- }
303
290
 
304
- public boolean existsRecord(List<BigDecimal> updateKeyValues, Record record)
305
- {
306
- return updateKeyValues.contains(record.getNumberFieldValue(fieldCode));
291
+ List<Record> allRecords = new ArrayList<>();
292
+ if (queryValues.isEmpty()) {
293
+ return allRecords;
307
294
  }
308
- }
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);
309
304
 
310
- private void upsertPage(final Page page)
311
- {
312
- KintoneColumnOption updateKeyColumn = null;
313
- for (KintoneColumnOption v : task.getColumnOptions().values()) {
314
- if (v.getUpdateKey()) {
315
- updateKeyColumn = v;
305
+ if (!resp.hasNext()) {
316
306
  break;
317
307
  }
318
308
  }
319
- if (updateKeyColumn == null) {
320
- throw new RuntimeException("when mode is upsert, require update_key");
321
- }
309
+ return allRecords;
310
+ }
322
311
 
323
- UpsertPage runner;
324
- switch(updateKeyColumn.getType()) {
325
- case "SINGLE_LINE_TEXT":
326
- runner = new UpsertPageByStringKey(updateKeyColumn.getFieldCode());
327
- break;
328
- case "NUMBER":
329
- runner = new UpsertPageByNumberKey(updateKeyColumn.getFieldCode());
330
- 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()));
331
325
  default:
332
326
  throw new RuntimeException("The update_key must be 'SINGLE_LINE_TEXT' or 'NUMBER'.");
333
327
  }
334
- runner.run(page);
335
328
  }
336
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.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: 2020-09-25 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.0.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