embulk-output-kintone 1.0.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (184) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +65 -1
  3. data/build.gradle +1 -0
  4. data/classpath/commons-csv-1.9.0.jar +0 -0
  5. data/classpath/embulk-output-kintone-1.2.0.jar +0 -0
  6. data/classpath/externalsortinginjava-0.6.2.jar +0 -0
  7. data/classpath/{shadow-kintone-java-client-1.0.0-all.jar → shadow-kintone-java-client-1.2.0-all.jar} +0 -0
  8. data/src/main/java/org/embulk/output/kintone/KintoneClient.java +117 -0
  9. data/src/main/java/org/embulk/output/kintone/KintoneColumnOption.java +5 -0
  10. data/src/main/java/org/embulk/output/kintone/KintoneColumnType.java +226 -5
  11. data/src/main/java/org/embulk/output/kintone/KintoneColumnVisitor.java +82 -13
  12. data/src/main/java/org/embulk/output/kintone/KintoneMode.java +52 -4
  13. data/src/main/java/org/embulk/output/kintone/KintoneOutputPlugin.java +12 -20
  14. data/src/main/java/org/embulk/output/kintone/KintonePageOutput.java +123 -127
  15. data/src/main/java/org/embulk/output/kintone/KintoneSortColumn.java +33 -0
  16. data/src/main/java/org/embulk/output/kintone/PluginTask.java +32 -0
  17. data/src/main/java/org/embulk/output/kintone/deserializer/DeserializeApplier.java +19 -0
  18. data/src/main/java/org/embulk/output/kintone/deserializer/DeserializeException.java +7 -0
  19. data/src/main/java/org/embulk/output/kintone/deserializer/Deserializer.java +279 -0
  20. data/src/main/java/org/embulk/output/kintone/record/Id.java +18 -0
  21. data/src/main/java/org/embulk/output/kintone/record/IdOrUpdateKey.java +45 -0
  22. data/src/main/java/org/embulk/output/kintone/record/Skip.java +14 -0
  23. data/src/main/java/org/embulk/output/kintone/reducer/CSVInputColumnVisitor.java +78 -0
  24. data/src/main/java/org/embulk/output/kintone/reducer/CSVOutputColumnVisitor.java +79 -0
  25. data/src/main/java/org/embulk/output/kintone/reducer/ReduceException.java +11 -0
  26. data/src/main/java/org/embulk/output/kintone/reducer/ReduceType.java +190 -0
  27. data/src/main/java/org/embulk/output/kintone/reducer/ReducedPageOutput.java +100 -0
  28. data/src/main/java/org/embulk/output/kintone/reducer/Reducer.java +355 -0
  29. data/src/main/java/org/embulk/output/kintone/util/Lazy.java +20 -0
  30. data/src/test/java/org/embulk/output/kintone/KintoneClientTest.java +139 -0
  31. data/src/test/java/org/embulk/output/kintone/KintoneColumnOptionBuilder.java +7 -0
  32. data/src/test/java/org/embulk/output/kintone/KintoneColumnTypeTest.java +194 -0
  33. data/src/test/java/org/embulk/output/kintone/KintoneColumnVisitorTest.java +183 -64
  34. data/src/test/java/org/embulk/output/kintone/KintoneColumnVisitorVerifier.java +19 -9
  35. data/src/test/java/org/embulk/output/kintone/KintonePageOutputVerifier.java +120 -51
  36. data/src/test/java/org/embulk/output/kintone/MockClient.java +112 -0
  37. data/src/test/java/org/embulk/output/kintone/TestKintoneOutputPlugin.java +147 -22
  38. data/src/test/java/org/embulk/output/kintone/TestTaskMode.java +1 -0
  39. data/src/test/java/org/embulk/output/kintone/TestTaskReduce.java +47 -0
  40. data/src/test/java/org/embulk/output/kintone/TestTaskReduceException.java +50 -0
  41. data/src/test/java/org/embulk/output/kintone/TestTaskReduceSubtable.java +47 -0
  42. data/src/test/java/org/embulk/output/kintone/TestTaskSkip.java +80 -0
  43. data/src/test/java/org/embulk/output/kintone/TestTaskSkipId.java +80 -0
  44. data/src/test/java/org/embulk/output/kintone/deserializer/DeserializerTest.java +165 -0
  45. data/src/test/java/org/embulk/output/kintone/reducer/ReduceTypeTest.java +154 -0
  46. data/src/test/resources/org/embulk/output/kintone/client/config.yml +1 -0
  47. data/src/test/resources/org/embulk/output/kintone/task/config.yml +2 -1
  48. data/src/test/resources/org/embulk/output/kintone/task/mode/config.yml +6 -0
  49. data/src/test/resources/org/embulk/output/kintone/task/mode/input.csv +7 -7
  50. data/src/test/resources/org/embulk/output/kintone/task/mode/insert_add_records.jsonl +6 -6
  51. data/src/test/resources/org/embulk/output/kintone/task/mode/{insert_add_ignore_nulls_records.jsonl → insert_ignore_nulls_add_records.jsonl} +2 -2
  52. data/src/test/resources/org/embulk/output/kintone/task/mode/{insert_add_prefer_nulls_records.jsonl → insert_prefer_nulls_add_records.jsonl} +6 -6
  53. data/src/test/resources/org/embulk/output/kintone/task/mode/{update_update_ignore_nulls_records.jsonl → update_ignore_nulls_update_records.jsonl} +2 -2
  54. data/src/test/resources/org/embulk/output/kintone/task/mode/{update_update_prefer_nulls_records.jsonl → update_prefer_nulls_update_records.jsonl} +3 -3
  55. data/src/test/resources/org/embulk/output/kintone/task/mode/update_update_records.jsonl +6 -6
  56. data/src/test/resources/org/embulk/output/kintone/task/mode/{upsert_add_records.jsonl → upsert_never_skip_add_records.jsonl} +2 -2
  57. data/src/test/resources/org/embulk/output/kintone/task/mode/upsert_never_skip_double_single_line_text_add_values.json +1 -0
  58. data/src/test/resources/org/embulk/output/kintone/task/mode/{upsert_update_ignore_nulls_records.jsonl → upsert_never_skip_ignore_nulls_update_records.jsonl} +2 -2
  59. data/src/test/resources/org/embulk/output/kintone/task/mode/{upsert_add_prefer_nulls_records.jsonl → upsert_never_skip_prefer_nulls_add_records.jsonl} +3 -3
  60. data/src/test/resources/org/embulk/output/kintone/task/mode/{upsert_update_prefer_nulls_records.jsonl → upsert_never_skip_prefer_nulls_update_records.jsonl} +3 -3
  61. data/src/test/resources/org/embulk/output/kintone/task/mode/{upsert_update_records.jsonl → upsert_never_skip_update_records.jsonl} +4 -4
  62. data/src/test/resources/org/embulk/output/kintone/task/reduce/config.yml +171 -0
  63. data/src/test/resources/org/embulk/output/kintone/task/reduce/input.csv +7 -0
  64. data/src/test/resources/org/embulk/output/kintone/task/reduce/insert_add_records.jsonl +6 -0
  65. data/src/test/resources/org/embulk/output/kintone/task/reduce/insert_ignore_nulls_add_records.jsonl +6 -0
  66. data/src/test/resources/org/embulk/output/kintone/task/reduce/insert_prefer_nulls_add_records.jsonl +6 -0
  67. data/src/test/resources/org/embulk/output/kintone/task/reduce/update_ignore_nulls_update_records.jsonl +3 -0
  68. data/src/test/resources/org/embulk/output/kintone/task/reduce/update_prefer_nulls_update_records.jsonl +3 -0
  69. data/src/test/resources/org/embulk/output/kintone/task/reduce/update_update_records.jsonl +6 -0
  70. data/src/test/resources/org/embulk/output/kintone/task/reduce/upsert_never_skip_add_records.jsonl +2 -0
  71. data/src/test/resources/org/embulk/output/kintone/task/reduce/upsert_never_skip_double_single_line_text_add_values.json +1 -0
  72. data/src/test/resources/org/embulk/output/kintone/task/reduce/upsert_never_skip_double_single_line_text_values.json +1 -0
  73. data/src/test/resources/org/embulk/output/kintone/task/reduce/upsert_never_skip_ignore_nulls_add_records.jsonl +3 -0
  74. data/src/test/resources/org/embulk/output/kintone/task/reduce/upsert_never_skip_ignore_nulls_double_single_line_text_values.json +1 -0
  75. data/src/test/resources/org/embulk/output/kintone/task/reduce/upsert_never_skip_ignore_nulls_update_records.jsonl +3 -0
  76. data/src/test/resources/org/embulk/output/kintone/task/reduce/upsert_never_skip_prefer_nulls_add_records.jsonl +3 -0
  77. data/src/test/resources/org/embulk/output/kintone/task/reduce/upsert_never_skip_prefer_nulls_double_single_line_text_values.json +1 -0
  78. data/src/test/resources/org/embulk/output/kintone/task/reduce/upsert_never_skip_prefer_nulls_update_records.jsonl +3 -0
  79. data/src/test/resources/org/embulk/output/kintone/task/reduce/upsert_never_skip_update_records.jsonl +4 -0
  80. data/src/test/resources/org/embulk/output/kintone/task/reduce_exception/config.yml +36 -0
  81. data/src/test/resources/org/embulk/output/kintone/task/reduce_exception/derived_columns.json +1 -0
  82. data/src/test/resources/org/embulk/output/kintone/task/reduce_exception/input.csv +13 -0
  83. data/src/test/resources/org/embulk/output/kintone/task/reduce_exception/insert_add_records.jsonl +2 -0
  84. data/src/test/resources/org/embulk/output/kintone/task/reduce_exception/update_update_records.jsonl +2 -0
  85. data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/config.yml +343 -0
  86. data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/derived_columns.json +1 -0
  87. data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/input.csv +13 -0
  88. data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/insert_add_records.jsonl +6 -0
  89. data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/insert_ignore_nulls_add_records.jsonl +6 -0
  90. data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/insert_prefer_nulls_add_records.jsonl +6 -0
  91. data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/update_ignore_nulls_update_records.jsonl +3 -0
  92. data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/update_prefer_nulls_update_records.jsonl +3 -0
  93. data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/update_update_records.jsonl +6 -0
  94. data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/upsert_never_skip_double_single_line_text_values.json +1 -0
  95. data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/upsert_never_skip_ignore_nulls_add_records.jsonl +3 -0
  96. data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/upsert_never_skip_ignore_nulls_double_single_line_text_values.json +1 -0
  97. data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/upsert_never_skip_ignore_nulls_update_records.jsonl +3 -0
  98. data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/upsert_never_skip_prefer_nulls_add_records.jsonl +3 -0
  99. data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/upsert_never_skip_prefer_nulls_double_single_line_text_values.json +1 -0
  100. data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/upsert_never_skip_prefer_nulls_update_records.jsonl +3 -0
  101. data/src/test/resources/org/embulk/output/kintone/task/reduce_subtable/upsert_never_skip_update_records.jsonl +6 -0
  102. data/src/test/resources/org/embulk/output/kintone/task/skip/config.yml +1 -0
  103. data/src/test/resources/org/embulk/output/kintone/task/skip/input.csv +7 -0
  104. data/src/test/resources/org/embulk/output/kintone/task/skip/insert_add_records.jsonl +6 -0
  105. data/src/test/resources/org/embulk/output/kintone/task/skip/insert_always_skip_add_records.jsonl +6 -0
  106. data/src/test/resources/org/embulk/output/kintone/task/skip/insert_always_skip_prefer_nulls_add_records.jsonl +6 -0
  107. data/src/test/resources/org/embulk/output/kintone/task/skip/insert_never_skip_add_records.jsonl +6 -0
  108. data/src/test/resources/org/embulk/output/kintone/task/skip/insert_never_skip_prefer_nulls_add_records.jsonl +6 -0
  109. data/src/test/resources/org/embulk/output/kintone/task/skip/insert_prefer_nulls_add_records.jsonl +6 -0
  110. data/src/test/resources/org/embulk/output/kintone/task/skip/update_always_skip_long_number_add_values.json +1 -0
  111. data/src/test/resources/org/embulk/output/kintone/task/skip/update_always_skip_long_number_values.json +1 -0
  112. data/src/test/resources/org/embulk/output/kintone/task/skip/update_always_skip_prefer_nulls_long_number_add_values.json +1 -0
  113. data/src/test/resources/org/embulk/output/kintone/task/skip/update_always_skip_prefer_nulls_long_number_values.json +1 -0
  114. data/src/test/resources/org/embulk/output/kintone/task/skip/update_always_skip_prefer_nulls_update_records.jsonl +2 -0
  115. data/src/test/resources/org/embulk/output/kintone/task/skip/update_always_skip_update_records.jsonl +5 -0
  116. data/src/test/resources/org/embulk/output/kintone/task/skip/update_never_skip_update_records.jsonl +6 -0
  117. data/src/test/resources/org/embulk/output/kintone/task/skip/update_prefer_nulls_update_records.jsonl +3 -0
  118. data/src/test/resources/org/embulk/output/kintone/task/skip/update_update_records.jsonl +6 -0
  119. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_add_records.jsonl +1 -0
  120. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_always_skip_prefer_nulls_string_single_line_text_add_values.json +1 -0
  121. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_always_skip_prefer_nulls_string_single_line_text_values.json +1 -0
  122. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_always_skip_prefer_nulls_update_records.jsonl +2 -0
  123. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_always_skip_string_single_line_text_add_values.json +1 -0
  124. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_always_skip_string_single_line_text_values.json +1 -0
  125. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_always_skip_update_records.jsonl +2 -0
  126. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_never_skip_add_records.jsonl +4 -0
  127. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_never_skip_prefer_nulls_add_records.jsonl +4 -0
  128. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_never_skip_prefer_nulls_string_single_line_text_add_values.json +1 -0
  129. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_never_skip_prefer_nulls_string_single_line_text_values.json +1 -0
  130. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_never_skip_prefer_nulls_update_records.jsonl +2 -0
  131. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_never_skip_string_single_line_text_add_values.json +1 -0
  132. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_never_skip_string_single_line_text_values.json +1 -0
  133. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_never_skip_update_records.jsonl +2 -0
  134. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_prefer_nulls_add_records.jsonl +1 -0
  135. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_prefer_nulls_string_single_line_text_add_values.json +1 -0
  136. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_prefer_nulls_string_single_line_text_values.json +1 -0
  137. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_prefer_nulls_update_records.jsonl +2 -0
  138. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_string_single_line_text_add_values.json +1 -0
  139. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_string_single_line_text_values.json +1 -0
  140. data/src/test/resources/org/embulk/output/kintone/task/skip/upsert_update_records.jsonl +2 -0
  141. data/src/test/resources/org/embulk/output/kintone/task/skip_id/config.yml +1 -0
  142. data/src/test/resources/org/embulk/output/kintone/task/skip_id/input.csv +7 -0
  143. data/src/test/resources/org/embulk/output/kintone/task/skip_id/insert_add_records.jsonl +6 -0
  144. data/src/test/resources/org/embulk/output/kintone/task/skip_id/insert_always_skip_add_records.jsonl +6 -0
  145. data/src/test/resources/org/embulk/output/kintone/task/skip_id/insert_always_skip_prefer_nulls_add_records.jsonl +6 -0
  146. data/src/test/resources/org/embulk/output/kintone/task/skip_id/insert_never_skip_add_records.jsonl +6 -0
  147. data/src/test/resources/org/embulk/output/kintone/task/skip_id/insert_never_skip_prefer_nulls_add_records.jsonl +6 -0
  148. data/src/test/resources/org/embulk/output/kintone/task/skip_id/insert_prefer_nulls_add_records.jsonl +6 -0
  149. data/src/test/resources/org/embulk/output/kintone/task/skip_id/update_always_skip__id_add_values.json +1 -0
  150. data/src/test/resources/org/embulk/output/kintone/task/skip_id/update_always_skip__id_values.json +1 -0
  151. data/src/test/resources/org/embulk/output/kintone/task/skip_id/update_always_skip_prefer_nulls__id_add_values.json +1 -0
  152. data/src/test/resources/org/embulk/output/kintone/task/skip_id/update_always_skip_prefer_nulls__id_values.json +1 -0
  153. data/src/test/resources/org/embulk/output/kintone/task/skip_id/update_always_skip_prefer_nulls_update_records.jsonl +2 -0
  154. data/src/test/resources/org/embulk/output/kintone/task/skip_id/update_always_skip_update_records.jsonl +5 -0
  155. data/src/test/resources/org/embulk/output/kintone/task/skip_id/update_never_skip_update_records.jsonl +6 -0
  156. data/src/test/resources/org/embulk/output/kintone/task/skip_id/update_prefer_nulls_update_records.jsonl +3 -0
  157. data/src/test/resources/org/embulk/output/kintone/task/skip_id/update_update_records.jsonl +6 -0
  158. data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert__id_add_values.json +1 -0
  159. data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert__id_values.json +1 -0
  160. data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_always_skip__id_add_values.json +1 -0
  161. data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_always_skip__id_values.json +1 -0
  162. data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_always_skip_prefer_nulls__id_add_values.json +1 -0
  163. data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_always_skip_prefer_nulls__id_values.json +1 -0
  164. data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_always_skip_prefer_nulls_update_records.jsonl +2 -0
  165. data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_always_skip_update_records.jsonl +5 -0
  166. data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_never_skip__id_add_values.json +1 -0
  167. data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_never_skip__id_values.json +1 -0
  168. data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_never_skip_add_records.jsonl +1 -0
  169. data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_never_skip_prefer_nulls__id_add_values.json +1 -0
  170. data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_never_skip_prefer_nulls__id_values.json +1 -0
  171. data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_never_skip_prefer_nulls_add_records.jsonl +4 -0
  172. data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_never_skip_prefer_nulls_update_records.jsonl +2 -0
  173. data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_never_skip_update_records.jsonl +5 -0
  174. data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_prefer_nulls__id_add_values.json +1 -0
  175. data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_prefer_nulls__id_values.json +1 -0
  176. data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_prefer_nulls_add_records.jsonl +3 -0
  177. data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_prefer_nulls_update_records.jsonl +2 -0
  178. data/src/test/resources/org/embulk/output/kintone/task/skip_id/upsert_update_records.jsonl +5 -0
  179. metadata +163 -17
  180. data/classpath/embulk-output-kintone-1.0.0.jar +0 -0
  181. /data/src/test/resources/org/embulk/output/kintone/task/mode/{values.json → upsert_never_skip_double_single_line_text_values.json} +0 -0
  182. /data/src/test/resources/org/embulk/output/kintone/task/mode/{upsert_add_ignore_nulls_records.jsonl → upsert_never_skip_ignore_nulls_add_records.jsonl} +0 -0
  183. /data/src/test/resources/org/embulk/output/kintone/task/mode/{values_ignore_nulls.json → upsert_never_skip_ignore_nulls_double_single_line_text_values.json} +0 -0
  184. /data/src/test/resources/org/embulk/output/kintone/task/mode/{values_prefer_nulls.json → upsert_never_skip_prefer_nulls_double_single_line_text_values.json} +0 -0
@@ -4,7 +4,12 @@ import com.kintone.client.model.record.FieldValue;
4
4
  import com.kintone.client.model.record.Record;
5
5
  import com.kintone.client.model.record.UpdateKey;
6
6
  import java.time.Instant;
7
+ import java.util.Arrays;
8
+ import java.util.List;
7
9
  import java.util.Map;
10
+ import java.util.Set;
11
+ import org.embulk.output.kintone.record.Id;
12
+ import org.embulk.output.kintone.record.IdOrUpdateKey;
8
13
  import org.embulk.spi.Column;
9
14
  import org.embulk.spi.ColumnVisitor;
10
15
  import org.embulk.spi.PageReader;
@@ -13,32 +18,41 @@ import org.msgpack.value.Value;
13
18
  import org.msgpack.value.ValueFactory;
14
19
 
15
20
  public class KintoneColumnVisitor implements ColumnVisitor {
21
+ private static final List<String> BUILTIN_FIELD_CODES = Arrays.asList(Id.FIELD, "$revision");
16
22
  private final PageReader reader;
23
+ private final Set<Column> derived;
17
24
  private final Map<String, KintoneColumnOption> options;
18
25
  private final boolean preferNulls;
19
26
  private final boolean ignoreNulls;
27
+ private final String reduceKeyName;
20
28
  private final String updateKeyName;
21
29
  private Record record;
22
- private UpdateKey updateKey;
30
+ private IdOrUpdateKey idOrUpdateKey;
23
31
 
24
32
  public KintoneColumnVisitor(
25
33
  PageReader reader,
34
+ Set<Column> derived,
26
35
  Map<String, KintoneColumnOption> options,
27
36
  boolean preferNulls,
28
- boolean ignoreNulls) {
29
- this(reader, options, preferNulls, ignoreNulls, null);
37
+ boolean ignoreNulls,
38
+ String reduceKeyName) {
39
+ this(reader, derived, options, preferNulls, ignoreNulls, reduceKeyName, null);
30
40
  }
31
41
 
32
42
  public KintoneColumnVisitor(
33
43
  PageReader reader,
44
+ Set<Column> derived,
34
45
  Map<String, KintoneColumnOption> options,
35
46
  boolean preferNulls,
36
47
  boolean ignoreNulls,
48
+ String reduceKeyName,
37
49
  String updateKeyName) {
38
50
  this.reader = reader;
51
+ this.derived = derived;
39
52
  this.options = options;
40
53
  this.preferNulls = preferNulls;
41
54
  this.ignoreNulls = ignoreNulls;
55
+ this.reduceKeyName = reduceKeyName;
42
56
  this.updateKeyName = updateKeyName;
43
57
  }
44
58
 
@@ -46,19 +60,22 @@ public class KintoneColumnVisitor implements ColumnVisitor {
46
60
  this.record = record;
47
61
  }
48
62
 
49
- public void setUpdateKey(UpdateKey updateKey) {
50
- this.updateKey = updateKey;
63
+ public void setIdOrUpdateKey(IdOrUpdateKey idOrUpdateKey) {
64
+ this.idOrUpdateKey = idOrUpdateKey;
51
65
  }
52
66
 
53
67
  @Override
54
68
  public void booleanColumn(Column column) {
55
- if (isIgnoreNull(column)) {
69
+ if (isReduced(column) || isIgnoreNull(column)) {
56
70
  return;
57
71
  }
58
72
  KintoneColumnOption option = getOption(column);
59
73
  UpdateKey updateKey = getUpdateKey(column);
60
74
  KintoneColumnType type = KintoneColumnType.getType(option, KintoneColumnType.NUMBER);
61
75
  String fieldCode = getFieldCode(column);
76
+ if (isBuiltin(fieldCode)) {
77
+ return;
78
+ }
62
79
  if (isPreferNull(column)) {
63
80
  setNull(type, fieldCode, updateKey);
64
81
  } else if (reader.isNull(column)) {
@@ -70,13 +87,21 @@ public class KintoneColumnVisitor implements ColumnVisitor {
70
87
 
71
88
  @Override
72
89
  public void longColumn(Column column) {
73
- if (isIgnoreNull(column)) {
90
+ if (isReduced(column) || isIgnoreNull(column)) {
91
+ return;
92
+ }
93
+ Id id = getId(column);
94
+ if (id != null) {
95
+ setIdValue(id, column);
74
96
  return;
75
97
  }
76
98
  KintoneColumnOption option = getOption(column);
77
99
  UpdateKey updateKey = getUpdateKey(column);
78
100
  KintoneColumnType type = KintoneColumnType.getType(option, KintoneColumnType.NUMBER);
79
101
  String fieldCode = getFieldCode(column);
102
+ if (isBuiltin(fieldCode)) {
103
+ return;
104
+ }
80
105
  if (isPreferNull(column)) {
81
106
  setNull(type, fieldCode, updateKey);
82
107
  } else if (reader.isNull(column)) {
@@ -88,13 +113,16 @@ public class KintoneColumnVisitor implements ColumnVisitor {
88
113
 
89
114
  @Override
90
115
  public void doubleColumn(Column column) {
91
- if (isIgnoreNull(column)) {
116
+ if (isReduced(column) || isIgnoreNull(column)) {
92
117
  return;
93
118
  }
94
119
  KintoneColumnOption option = getOption(column);
95
120
  UpdateKey updateKey = getUpdateKey(column);
96
121
  KintoneColumnType type = KintoneColumnType.getType(option, KintoneColumnType.NUMBER);
97
122
  String fieldCode = getFieldCode(column);
123
+ if (isBuiltin(fieldCode)) {
124
+ return;
125
+ }
98
126
  if (isPreferNull(column)) {
99
127
  setNull(type, fieldCode, updateKey);
100
128
  } else if (reader.isNull(column)) {
@@ -106,7 +134,7 @@ public class KintoneColumnVisitor implements ColumnVisitor {
106
134
 
107
135
  @Override
108
136
  public void stringColumn(Column column) {
109
- if (isIgnoreNull(column)) {
137
+ if (isReduced(column) || isIgnoreNull(column)) {
110
138
  return;
111
139
  }
112
140
  KintoneColumnOption option = getOption(column);
@@ -115,6 +143,9 @@ public class KintoneColumnVisitor implements ColumnVisitor {
115
143
  updateKey != null ? KintoneColumnType.SINGLE_LINE_TEXT : KintoneColumnType.MULTI_LINE_TEXT;
116
144
  KintoneColumnType type = KintoneColumnType.getType(option, defaultType);
117
145
  String fieldCode = getFieldCode(column);
146
+ if (isBuiltin(fieldCode)) {
147
+ return;
148
+ }
118
149
  if (isPreferNull(column)) {
119
150
  setNull(type, fieldCode, updateKey);
120
151
  } else if (reader.isNull(column)) {
@@ -126,13 +157,16 @@ public class KintoneColumnVisitor implements ColumnVisitor {
126
157
 
127
158
  @Override
128
159
  public void timestampColumn(Column column) {
129
- if (isIgnoreNull(column)) {
160
+ if (isReduced(column) || isIgnoreNull(column)) {
130
161
  return;
131
162
  }
132
163
  KintoneColumnOption option = getOption(column);
133
164
  UpdateKey updateKey = getUpdateKey(column);
134
165
  KintoneColumnType type = KintoneColumnType.getType(option, KintoneColumnType.DATETIME);
135
166
  String fieldCode = getFieldCode(column);
167
+ if (isBuiltin(fieldCode)) {
168
+ return;
169
+ }
136
170
  if (isPreferNull(column)) {
137
171
  setNull(type, fieldCode, updateKey);
138
172
  } else if (reader.isNull(column)) {
@@ -144,13 +178,18 @@ public class KintoneColumnVisitor implements ColumnVisitor {
144
178
 
145
179
  @Override
146
180
  public void jsonColumn(Column column) {
147
- if (isIgnoreNull(column)) {
181
+ if (isReduced(column) || isIgnoreNull(column)) {
148
182
  return;
149
183
  }
150
184
  KintoneColumnOption option = getOption(column);
151
185
  UpdateKey updateKey = getUpdateKey(column);
152
- KintoneColumnType type = KintoneColumnType.getType(option, KintoneColumnType.MULTI_LINE_TEXT);
186
+ KintoneColumnType defaultType =
187
+ isDerived(column) ? KintoneColumnType.SUBTABLE : KintoneColumnType.MULTI_LINE_TEXT;
188
+ KintoneColumnType type = KintoneColumnType.getType(option, defaultType);
153
189
  String fieldCode = getFieldCode(column);
190
+ if (isBuiltin(fieldCode)) {
191
+ return;
192
+ }
154
193
  if (isPreferNull(column)) {
155
194
  setNull(type, fieldCode, updateKey);
156
195
  } else if (reader.isNull(column)) {
@@ -160,6 +199,16 @@ public class KintoneColumnVisitor implements ColumnVisitor {
160
199
  }
161
200
  }
162
201
 
202
+ private void setIdValue(Id id, Column column) {
203
+ if (isPreferNull(column)) {
204
+ id.setValue(null);
205
+ } else if (reader.isNull(column)) {
206
+ id.setValue(0L);
207
+ } else {
208
+ id.setValue(reader.getLong(column));
209
+ }
210
+ }
211
+
163
212
  private void setNull(KintoneColumnType type, String fieldCode, UpdateKey updateKey) {
164
213
  if (updateKey != null) {
165
214
  type.setUpdateKey(updateKey, fieldCode);
@@ -254,8 +303,24 @@ public class KintoneColumnVisitor implements ColumnVisitor {
254
303
  return options.get(column.getName());
255
304
  }
256
305
 
306
+ private Id getId(Column column) {
307
+ return column.getName().equals(updateKeyName) && updateKeyName.equals(Id.FIELD)
308
+ ? idOrUpdateKey.getId()
309
+ : null;
310
+ }
311
+
257
312
  private UpdateKey getUpdateKey(Column column) {
258
- return updateKeyName != null && updateKeyName.equals(column.getName()) ? updateKey : null;
313
+ return column.getName().equals(updateKeyName) && !updateKeyName.equals(Id.FIELD)
314
+ ? idOrUpdateKey.getUpdateKey()
315
+ : null;
316
+ }
317
+
318
+ private boolean isReduced(Column column) {
319
+ return reduceKeyName != null && column.getName().matches("^.*\\..*$");
320
+ }
321
+
322
+ private boolean isDerived(Column column) {
323
+ return reduceKeyName != null && derived.contains(column);
259
324
  }
260
325
 
261
326
  private boolean isIgnoreNull(Column column) {
@@ -265,4 +330,8 @@ public class KintoneColumnVisitor implements ColumnVisitor {
265
330
  private boolean isPreferNull(Column column) {
266
331
  return preferNulls && reader.isNull(column);
267
332
  }
333
+
334
+ private static boolean isBuiltin(String fieldCode) {
335
+ return BUILTIN_FIELD_CODES.contains(fieldCode);
336
+ }
268
337
  }
@@ -1,23 +1,71 @@
1
1
  package org.embulk.output.kintone;
2
2
 
3
+ import java.util.function.Consumer;
3
4
  import org.embulk.config.ConfigException;
5
+ import org.embulk.output.kintone.record.Id;
6
+ import org.embulk.output.kintone.record.Skip;
7
+ import org.embulk.spi.Page;
4
8
 
5
9
  public enum KintoneMode {
6
- INSERT("insert"),
7
- UPDATE("update"),
8
- UPSERT("upsert");
10
+ INSERT("insert") {
11
+ @Override
12
+ public void validate(PluginTask task, KintoneClient client) {
13
+ if (task.getUpdateKeyName().isPresent()) {
14
+ throw new ConfigException("When mode is insert, require no update_key.");
15
+ }
16
+ }
17
+
18
+ @Override
19
+ public void add(Page page, Skip skip, KintonePageOutput output) {
20
+ output.insertPage(page);
21
+ }
22
+ },
23
+ UPDATE("update") {
24
+ @Override
25
+ public void validate(PluginTask task, KintoneClient client) {
26
+ if (!task.getUpdateKeyName().isPresent() && client.getColumn(Id.FIELD) == null) {
27
+ throw new ConfigException("When mode is update, require update_key or id column.");
28
+ }
29
+ client.validateIdOrUpdateKey(task.getUpdateKeyName().orElse(Id.FIELD));
30
+ }
31
+
32
+ @Override
33
+ public void add(Page page, Skip skip, KintonePageOutput output) {
34
+ Consumer<Page> consumer = skip == Skip.ALWAYS ? output::upsertPage : output::updatePage;
35
+ consumer.accept(page);
36
+ }
37
+ },
38
+ UPSERT("upsert") {
39
+ @Override
40
+ public void validate(PluginTask task, KintoneClient client) {
41
+ if (!task.getUpdateKeyName().isPresent() && client.getColumn(Id.FIELD) == null) {
42
+ throw new ConfigException("When mode is upsert, require update_key or id column.");
43
+ }
44
+ client.validateIdOrUpdateKey(task.getUpdateKeyName().orElse(Id.FIELD));
45
+ }
46
+
47
+ @Override
48
+ public void add(Page page, Skip skip, KintonePageOutput output) {
49
+ output.upsertPage(page);
50
+ }
51
+ };
9
52
  private final String value;
10
53
 
11
54
  KintoneMode(String value) {
12
55
  this.value = value;
13
56
  }
14
57
 
58
+ public abstract void validate(PluginTask task, KintoneClient client);
59
+
60
+ public abstract void add(Page page, Skip skip, KintonePageOutput output);
61
+
15
62
  @Override
16
63
  public String toString() {
17
64
  return value;
18
65
  }
19
66
 
20
- public static KintoneMode getKintoneModeByValue(String value) {
67
+ public static KintoneMode of(PluginTask task) {
68
+ String value = task.getMode();
21
69
  for (KintoneMode mode : values()) {
22
70
  if (mode.toString().equals(value)) {
23
71
  return mode;
@@ -1,11 +1,13 @@
1
1
  package org.embulk.output.kintone;
2
2
 
3
+ import java.util.Collections;
3
4
  import java.util.List;
4
5
  import org.embulk.config.ConfigDiff;
5
- import org.embulk.config.ConfigException;
6
6
  import org.embulk.config.ConfigSource;
7
7
  import org.embulk.config.TaskReport;
8
8
  import org.embulk.config.TaskSource;
9
+ import org.embulk.output.kintone.reducer.ReducedPageOutput;
10
+ import org.embulk.output.kintone.reducer.Reducer;
9
11
  import org.embulk.spi.Exec;
10
12
  import org.embulk.spi.OutputPlugin;
11
13
  import org.embulk.spi.Schema;
@@ -16,8 +18,12 @@ public class KintoneOutputPlugin implements OutputPlugin {
16
18
  public ConfigDiff transaction(
17
19
  ConfigSource config, Schema schema, int taskCount, OutputPlugin.Control control) {
18
20
  PluginTask task = config.loadConfig(PluginTask.class);
19
- control.run(task.dump());
20
- return Exec.newConfigDiff();
21
+ task.setDerivedColumns(Collections.emptySet());
22
+ List<TaskReport> taskReports = control.run(task.dump());
23
+ return task.getReduceKeyName().isPresent()
24
+ ? new Reducer(task, schema)
25
+ .reduce(taskReports, schema.lookupColumn(task.getReduceKeyName().get()))
26
+ : Exec.newConfigDiff();
21
27
  }
22
28
 
23
29
  @Override
@@ -33,22 +39,8 @@ public class KintoneOutputPlugin implements OutputPlugin {
33
39
  @Override
34
40
  public TransactionalPageOutput open(TaskSource taskSource, Schema schema, int taskIndex) {
35
41
  PluginTask task = taskSource.loadTask(PluginTask.class);
36
- KintoneMode mode = KintoneMode.getKintoneModeByValue(task.getMode());
37
- switch (mode) {
38
- case INSERT:
39
- if (task.getUpdateKeyName().isPresent()) {
40
- throw new ConfigException("when mode is insert, require no update_key.");
41
- }
42
- break;
43
- case UPDATE:
44
- case UPSERT:
45
- if (!task.getUpdateKeyName().isPresent()) {
46
- throw new ConfigException("when mode is update or upsert, require update_key.");
47
- }
48
- break;
49
- default:
50
- throw new ConfigException(String.format("Unknown mode '%s'", task.getMode()));
51
- }
52
- return new KintonePageOutput(task, schema);
42
+ return task.getReduceKeyName().isPresent()
43
+ ? new ReducedPageOutput(schema, taskIndex)
44
+ : new KintonePageOutput(task, schema);
53
45
  }
54
46
  }