embulk-output-oracle 0.6.3 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +43 -0
  3. data/build.gradle +2 -2
  4. data/classpath/{embulk-output-jdbc-0.6.3.jar → embulk-output-jdbc-0.6.4.jar} +0 -0
  5. data/classpath/embulk-output-oracle-0.6.4.jar +0 -0
  6. data/lib/embulk/native/x86_64-linux/libembulk-output-oracle-oci.so +0 -0
  7. data/lib/embulk/native/x86_64-windows/embulk-output-oracle-oci.dll +0 -0
  8. data/src/main/cpp/common/embulk-output-oracle-oci.cpp +27 -0
  9. data/src/main/cpp/linux/build.sh +15 -0
  10. data/src/main/cpp/windows/build.bat +26 -0
  11. data/src/main/cpp/windows/dllmain.cpp +25 -0
  12. data/src/main/cpp/windows/embulk-output-oracle-oci.sln +20 -0
  13. data/src/main/cpp/windows/embulk-output-oracle-oci.vcxproj +171 -0
  14. data/src/main/java/org/embulk/output/oracle/DirectBatchInsert.java +5 -39
  15. data/src/main/java/org/embulk/output/oracle/oci/BulkOCI.java +15 -0
  16. data/src/main/java/org/embulk/output/oracle/oci/OCI.java +1 -0
  17. data/src/main/java/org/embulk/output/oracle/oci/OCIManager.java +3 -2
  18. data/src/main/java/org/embulk/output/oracle/oci/OCIWrapper.java +103 -37
  19. data/src/main/java/org/embulk/output/oracle/oci/PrimitiveBulkOCI.java +47 -0
  20. data/src/main/java/org/embulk/output/oracle/oci/RowBuffer.java +50 -46
  21. data/src/main/java/org/embulk/output/oracle/oci/TableDefinition.java +9 -0
  22. data/src/test/java/org/embulk/output/oracle/OracleOutputPluginTest.java +622 -133
  23. data/src/test/resources/oracle/data/test3/test3.csv +9999 -0
  24. data/src/test/resources/oracle/yml/test-insert-direct-oci-method-large.yml +29 -0
  25. metadata +19 -8
  26. data/classpath/embulk-output-oracle-0.6.3.jar +0 -0
  27. data/src/test/java/org/embulk/output/oracle/OracleOutputPluginTestImpl.java +0 -620
@@ -40,4 +40,13 @@ public class TableDefinition
40
40
  {
41
41
  return columns[index];
42
42
  }
43
+
44
+ public int getRowSize()
45
+ {
46
+ int rowSize = 0;
47
+ for (ColumnDefinition column : columns) {
48
+ rowSize += column.getDataSize();
49
+ }
50
+ return rowSize;
51
+ }
43
52
  }
@@ -1,39 +1,43 @@
1
1
  package org.embulk.output.oracle;
2
2
 
3
+ import static org.junit.Assert.assertEquals;
4
+ import static org.junit.Assert.fail;
5
+
3
6
  import java.io.File;
4
- import java.lang.reflect.Method;
5
- import java.net.URL;
6
- import java.util.ArrayList;
7
- import java.util.Arrays;
7
+ import java.lang.reflect.Constructor;
8
+ import java.math.BigDecimal;
9
+ import java.sql.Connection;
10
+ import java.sql.DriverManager;
11
+ import java.sql.ResultSet;
12
+ import java.sql.SQLException;
13
+ import java.sql.Timestamp;
14
+ import java.text.DateFormat;
15
+ import java.text.ParseException;
16
+ import java.text.SimpleDateFormat;
17
+ import java.util.Date;
18
+ import java.util.Iterator;
8
19
  import java.util.List;
20
+ import java.util.TimeZone;
9
21
 
22
+ import org.embulk.exec.PartialExecutionException;
10
23
  import org.embulk.input.filesplit.LocalFileSplitInputPlugin;
24
+ import org.embulk.output.AbstractJdbcOutputPluginTest;
25
+ import org.embulk.output.OracleOutputPlugin;
11
26
  import org.embulk.output.tester.EmbulkPluginTester;
12
- import org.embulk.plugin.PluginClassLoader;
13
27
  import org.embulk.spi.InputPlugin;
14
28
  import org.embulk.spi.OutputPlugin;
15
29
  import org.junit.BeforeClass;
16
30
  import org.junit.Test;
17
31
 
18
32
 
19
- public class OracleOutputPluginTest
33
+ public class OracleOutputPluginTest extends AbstractJdbcOutputPluginTest
20
34
  {
21
- private static class NamedObject
22
- {
23
- public final String name;
24
- public final Object value;
25
- public NamedObject(String name, Object value)
26
- {
27
- this.name = name;
28
- this.value = value;
29
- }
30
- }
31
-
32
- private static List<NamedObject> testObjects = new ArrayList<NamedObject>();
33
- private static NamedObject test12c;
34
- private static NamedObject test11g;
35
+ private static boolean canTest;
35
36
  private static EmbulkPluginTester tester = new EmbulkPluginTester();
36
-
37
+ static {
38
+ tester.addPlugin(OutputPlugin.class, "oracle", OracleOutputPlugin.class);
39
+ tester.addPlugin(InputPlugin.class, "filesplit", LocalFileSplitInputPlugin.class);
40
+ }
37
41
 
38
42
  @BeforeClass
39
43
  public static void beforeClass() throws Exception
@@ -43,255 +47,740 @@ public class OracleOutputPluginTest
43
47
  System.setProperty("file.encoding", "MS932");
44
48
  }
45
49
 
46
- tester.addPlugin(InputPlugin.class, "filesplit", LocalFileSplitInputPlugin.class);
47
-
48
- test12c = createTest("oracle12", "/driver/12c/ojdbc7.jar");
49
- if (test12c == null) {
50
- System.out.println("Warning: you should put ojdbc7.jar (version 12c) on 'test/resources/driver/12c' directory.");
51
- } else {
52
- testObjects.add(test12c);
50
+ try {
51
+ Class.forName("oracle.jdbc.OracleDriver");
52
+ } catch (ClassNotFoundException | NoClassDefFoundError e) {
53
+ System.err.println("Warning: you should put 'ojdbc7.jar' in 'embulk-input-oracle/driver' directory in order to test.");
54
+ return;
53
55
  }
54
56
 
55
- test11g = createTest("oracle11", "/driver/11g/ojdbc6.jar");
56
- if (test11g == null) {
57
- System.out.println("Warning: you should put ojdbc6.jar (version 11g Release 2) on 'test/resources/driver/11g' directory.");
58
- } else {
59
- testObjects.add(test11g);
57
+ try (Connection connection = new OracleOutputPluginTest().connect()) {
58
+ String version = connection.getMetaData().getDriverVersion();
59
+ System.out.println("Driver version = " + version);
60
+ canTest = true;
61
+
62
+ } catch (SQLException e) {
63
+ System.err.println(e);
64
+ System.err.println("Warning: prepare a schema on Oracle 12c (database = 'TESTDB', user = 'TEST_USER', password = 'test_pw', charset = UTF-8).");
65
+ // for example
66
+ // CREATE USER EMBULK_USER IDENTIFIED BY "embulk_pw";
67
+ // GRANT DBA TO EMBULK_USER;
60
68
  }
61
69
  }
62
70
 
63
- private static NamedObject createTest(String pluginName, String jdbcDriverPath) throws Exception
71
+ @Test
72
+ public void testInsert() throws Exception
64
73
  {
65
- // Load OracleOutputPluginTestImpl, Oracle JDBC Driver, embulk-output-oracle by another ClassLoader
66
- // in order to test for different driver versions.
67
-
68
- List<URL> urls = new ArrayList<URL>();
69
-
70
- File testRoot = new File(OracleOutputPluginTest.class.getResource("/oracle/").toURI()).getParentFile();
71
- String pluginClassName = "org.embulk.output.OracleOutputPlugin";
72
- URL pluginClassUrl = OracleOutputPluginTest.class.getResource("/" +pluginClassName.replace('.', '/') + ".class");
73
- File root = new File(pluginClassUrl.toURI()).getParentFile().getParentFile().getParentFile().getParentFile();
74
-
75
- urls.add(root.toURI().toURL());
76
- urls.add(testRoot.toURI().toURL());
77
-
78
- URL jdbcDriverUrl = OracleOutputPluginTest.class.getResource(jdbcDriverPath);
79
- if (jdbcDriverUrl == null) {
80
- return null;
74
+ if (!canTest) {
75
+ return;
81
76
  }
82
77
 
83
- urls.add(jdbcDriverUrl);
84
- ClassLoader classLoader = new PluginClassLoader(urls, OracleOutputPluginTest.class.getClassLoader(),
85
- Arrays.asList(EmbulkPluginTester.class.getPackage().getName()), new ArrayList<String>());
86
- Thread.currentThread().setContextClassLoader(classLoader);
87
- tester.addPlugin(OutputPlugin.class, pluginName, classLoader.loadClass(pluginClassName));
78
+ String table = "TEST1";
88
79
 
89
- Class<?> testClass = classLoader.loadClass(OracleOutputPluginTest.class.getName() + "Impl");
90
- final Object testObject = testClass.newInstance();
91
- invoke(testObject, "setTester", tester);
92
- invoke(testObject, "setPluginName", pluginName);
80
+ dropTable(table);
81
+ createTable(table);
93
82
 
94
- final String version = (String)invoke(testObject, "beforeClass");
95
- if (version == null) {
96
- return null;
97
- }
98
- return new NamedObject(version, testObject);
99
- }
83
+ run("/oracle/yml/test-insert.yml");
100
84
 
101
- private static void invoke(String methodName) throws Exception
102
- {
103
- for (NamedObject testObject : testObjects) {
104
- invoke(testObject, methodName);
105
- }
85
+ assertTable(table);
106
86
  }
107
87
 
108
- private static Object invoke(NamedObject testObject, String methodName) throws Exception
88
+ @Test
89
+ public void testInsertCreate() throws Exception
109
90
  {
110
- if (testObject != null) {
111
- System.out.println("*** " + testObject.name + " ***");
112
- return invoke(testObject.value, methodName);
91
+ if (!canTest) {
92
+ return;
113
93
  }
114
- return null;
115
- }
116
94
 
117
- private static Object invoke(Object testObject, String methodName, Object... arguments) throws Exception
118
- {
119
- if (testObject != null) {
120
- Thread.currentThread().setContextClassLoader(testObject.getClass().getClassLoader());
121
- Class<?>[] parameterTypes = new Class<?>[arguments.length];
122
- for (int i = 0; i < arguments.length; i++) {
123
- parameterTypes[i] = arguments[i].getClass();
124
- }
125
- Method method = testObject.getClass().getMethod(methodName, parameterTypes);
126
- return method.invoke(testObject, arguments);
127
- }
128
- return null;
129
- }
95
+ String table = "TEST1";
130
96
 
131
- @Test
132
- public void testInsert() throws Exception
133
- {
134
- // cannot test with Oracle 11g JDBC driver for Oracle 12c,
135
- // because the driver returns sqlType=1111 for NCHAR/NVARCHAR2,
136
- // and ColumnSetterFactory#newCoalesceColumnSetter throws Exception.
137
- // even if setting {value_type: string} for NCHAR/NVARCHAR2,
138
- // PreparedStatement#setNull(parameterIndex, sqlType=1111) throws Exception.
139
- invoke(test12c, "testInsert");
140
- }
97
+ dropTable(table);
141
98
 
142
- @Test
143
- public void testInsertCreate() throws Exception
144
- {
145
- invoke("testInsertCreate");
99
+ run("/oracle/yml/test-insert.yml");
100
+
101
+ assertGeneratedTable1(table);
146
102
  }
147
103
 
148
104
  @Test
149
105
  public void testInsertEmpty() throws Exception
150
106
  {
151
- invoke(test12c, "testInsertEmpty");
107
+ if (!canTest) {
108
+ return;
109
+ }
110
+
111
+ String table = "TEST1";
112
+
113
+ dropTable(table);
114
+ createTable(table);
115
+
116
+ new File(convertPath("/oracle/data/"), "test2").mkdir();
117
+ run("/oracle/yml/test-insert-empty.yml");
118
+
119
+ assertTableEmpty(table);
152
120
  }
153
121
 
154
122
  @Test
155
123
  public void testTruncateInsert() throws Exception
156
124
  {
157
- invoke(test12c, "testTruncateInsert");
125
+ if (!canTest) {
126
+ return;
127
+ }
128
+
129
+ String table = "TEST1";
130
+
131
+ dropTable(table);
132
+ createTable(table);
133
+ insertRecord(table);
134
+
135
+ run("/oracle/yml/test-truncate-insert.yml");
136
+
137
+ assertTable(table);
158
138
  }
159
139
 
160
140
  @Test
161
141
  public void testTruncateInsertOCIMethod() throws Exception
162
142
  {
163
- invoke(test12c, "testTruncateInsertOCIMethod");
143
+ if (!canTest) {
144
+ return;
145
+ }
146
+
147
+ String table = "TEST1";
148
+
149
+ dropTable(table);
150
+ createTable(table);
151
+ insertRecord(table);
152
+
153
+ run("/oracle/yml/test-truncate-insert-oci-method.yml");
154
+
155
+ assertTable(table);
164
156
  }
165
157
 
166
158
  @Test
167
159
  public void testTruncateInsertCreate() throws Exception
168
160
  {
169
- invoke("testTruncateInsertCreate");
161
+ if (!canTest) {
162
+ return;
163
+ }
164
+
165
+ String table = "TEST1";
166
+
167
+ dropTable(table);
168
+
169
+ run("/oracle/yml/test-truncate-insert.yml");
170
+
171
+ assertGeneratedTable1(table);
170
172
  }
171
173
 
172
174
  @Test
173
175
  public void testInsertDirect() throws Exception
174
176
  {
175
- invoke(test12c, "testInsertDirect");
177
+ if (!canTest) {
178
+ return;
179
+ }
180
+
181
+ String table = "TEST1";
182
+
183
+ dropTable(table);
184
+ createTable(table);
185
+
186
+ run("/oracle/yml/test-insert-direct.yml");
187
+
188
+ assertTable(table);
176
189
  }
177
190
 
178
191
  @Test
179
192
  public void testInsertDirectDuplicate() throws Exception
180
193
  {
181
- invoke(test12c, "testInsertDirectDuplicate");
194
+ if (!canTest) {
195
+ return;
196
+ }
197
+
198
+ String table = "TEST1";
199
+
200
+ dropTable(table);
201
+ createTable(table);
202
+ insertRecord(table, "A002");
203
+
204
+ try {
205
+ run("/oracle/yml/test-insert-direct.yml");
206
+ fail("Exception expected.");
207
+ } catch (Exception e) {
208
+ System.out.println(e);
209
+ }
182
210
  }
183
211
 
184
212
  @Test
185
- public void testInsertDirectCreate() throws Exception
213
+ public void testInsertDirectEmpty() throws Exception
186
214
  {
187
- invoke("testInsertDirectCreate");
215
+ if (!canTest) {
216
+ return;
217
+ }
218
+
219
+ String table = "TEST1";
220
+
221
+ dropTable(table);
222
+ createTable(table);
223
+
224
+ new File(convertPath("/oracle/data/"), "test2").mkdir();
225
+ run("/oracle/yml/test-insert-direct-empty.yml");
226
+
227
+ assertTableEmpty(table);
188
228
  }
189
229
 
190
230
  @Test
191
- public void testInsertDirectEmpty() throws Exception
231
+ public void testInsertDirectCreate() throws Exception
192
232
  {
193
- invoke(test12c, "testInsertDirectEmpty");
233
+ if (!canTest) {
234
+ return;
235
+ }
236
+
237
+ String table = "TEST1";
238
+
239
+ dropTable(table);
240
+
241
+ run("/oracle/yml/test-insert-direct.yml");
242
+
243
+ assertGeneratedTable1(table);
194
244
  }
195
245
 
196
246
  @Test
197
247
  public void testInsertDirectDirectMethod() throws Exception
198
248
  {
199
- invoke(test12c, "testInsertDirectDirectMethod");
249
+ if (!canTest) {
250
+ return;
251
+ }
252
+
253
+ String table = "TEST1";
254
+
255
+ dropTable(table);
256
+ createTable(table);
257
+
258
+ try {
259
+ run("/oracle/yml/test-insert-direct-direct-method.yml");
260
+ } catch (PartialExecutionException e) {
261
+ if (e.getCause() != null && e.getCause().getClass().equals(RuntimeException.class)
262
+ && e.getCause().getCause() != null && e.getCause().getCause().getClass().equals(AssertionError.class)) {
263
+ // ignore error
264
+ e.printStackTrace();
265
+ System.err.println("The 'direct' mode works if running embulk directly, but fails if using EmbulkPluginTester.");
266
+ return;
267
+ }
268
+ throw e;
269
+ }
270
+
271
+ assertTable(table);
200
272
  }
201
273
 
202
274
  @Test
203
275
  public void testInsertDirectOCIMethod() throws Exception
204
276
  {
205
- invoke(test12c, "testInsertDirectOCIMethod");
277
+ if (!canTest) {
278
+ return;
279
+ }
280
+
281
+ String table = "TEST1";
282
+
283
+ dropTable(table);
284
+ createTable(table);
285
+
286
+ run("/oracle/yml/test-insert-direct-oci-method.yml");
287
+
288
+ assertTable(table);
289
+ }
290
+
291
+ @Test
292
+ public void testInsertDirectOCIMethodLarge() throws Exception
293
+ {
294
+ if (!canTest) {
295
+ return;
296
+ }
297
+
298
+ String table = "TEST1";
299
+
300
+ dropTable(table);
301
+ createTable(table);
302
+
303
+ run("/oracle/yml/test-insert-direct-oci-method-large.yml");
304
+
305
+ List<List<Object>> rows = select(table);
306
+ assertEquals(9999, rows.size());
307
+ for (int i = 0; i < rows.size(); i++) {
308
+ assertEquals(String.format("%04d", i + 1), rows.get(i).get(0));
309
+ }
206
310
  }
207
311
 
208
312
  @Test
209
313
  public void testInsertDirectOCIMethodDuplicate() throws Exception
210
314
  {
211
- invoke(test12c, "testInsertDirectOCIMethodDuplicate");
315
+ if (!canTest) {
316
+ return;
317
+ }
318
+
319
+ String table = "TEST1";
320
+
321
+ dropTable(table);
322
+ createTable(table);
323
+ insertRecord(table, "A002");
324
+
325
+ try {
326
+ run("/oracle/yml/test-insert-direct-oci-method.yml");
327
+ fail("Exception expected.");
328
+ } catch (Exception e) {
329
+ System.out.println(e);
330
+ }
212
331
  }
213
332
 
214
333
  @Test
215
334
  public void testInsertDirectOCIMethodMultibyte() throws Exception
216
335
  {
217
- invoke(test12c, "testInsertDirectOCIMethodMultibyte");
336
+ if (!canTest) {
337
+ return;
338
+ }
339
+
340
+ String table = "TEST1";
341
+
342
+ dropTable(table);
343
+ createTable(table);
344
+
345
+ run("/oracle/yml/test-insert-direct-oci-method-multibyte.yml");
346
+
347
+ assertTable(table);
218
348
  }
219
349
 
220
350
  @Test
221
351
  public void testInsertDirectOCIMethodMultibyteDuplicate() throws Exception
222
352
  {
223
- invoke(test12c, "testInsertDirectOCIMethodMultibyteDuplicate");
353
+ if (!canTest) {
354
+ return;
355
+ }
356
+
357
+ String table = "TEST1";
358
+
359
+ dropTable(table);
360
+ createTable(table);
361
+ insertRecord(table, "A002");
362
+
363
+ try {
364
+ run("/oracle/yml/test-insert-direct-oci-method-multibyte.yml");
365
+ fail("Exception expected.");
366
+ } catch (Exception e) {
367
+ System.out.println(e);
368
+ }
224
369
  }
225
370
 
226
371
  @Test
227
372
  public void testInsertDirectOCIMethodSplit() throws Exception
228
373
  {
229
- invoke(test12c, "testInsertDirectOCIMethodSplit");
374
+ if (!canTest) {
375
+ return;
376
+ }
377
+
378
+ String table = "TEST1";
379
+
380
+ dropTable(table);
381
+ createTable(table);
382
+
383
+ run("/oracle/yml/test-insert-direct-oci-method-split.yml");
384
+
385
+ assertTable(table);
230
386
  }
231
387
 
232
388
  @Test
233
389
  public void testUrl() throws Exception
234
390
  {
235
- invoke(test12c, "testUrl");
391
+ if (!canTest) {
392
+ return;
393
+ }
394
+
395
+ String table = "TEST1";
396
+
397
+ dropTable(table);
398
+ createTable(table);
399
+
400
+ run("/oracle/yml/test-url.yml");
401
+
402
+ assertTable(table);
236
403
  }
237
404
 
238
405
  @Test
239
406
  public void testLowerTable() throws Exception
240
407
  {
241
- invoke(test12c, "testLowerTable");
408
+ if (!canTest) {
409
+ return;
410
+ }
411
+
412
+ String table = "TEST1";
413
+
414
+ dropTable(table);
415
+ createTable(table);
416
+
417
+ run("/oracle/yml/test-lower-table.yml");
418
+
419
+ assertTable(table);
242
420
  }
243
421
 
244
422
  @Test
245
423
  public void testLowerColumn() throws Exception
246
424
  {
247
- invoke(test12c, "testLowerColumn");
425
+ if (!canTest) {
426
+ return;
427
+ }
428
+
429
+ String table = "TEST1";
430
+
431
+ dropTable(table);
432
+ createTable(table);
433
+
434
+ run("/oracle/yml/test-lower-column.yml");
435
+
436
+ assertTable(table);
248
437
  }
249
438
 
250
439
  @Test
251
440
  public void testLowerColumnOptions() throws Exception
252
441
  {
253
- invoke(test12c, "testLowerColumnOptions");
442
+ if (!canTest) {
443
+ return;
444
+ }
445
+
446
+ String table = "TEST1";
447
+
448
+ dropTable(table);
449
+ createTable(table);
450
+
451
+ run("/oracle/yml/test-lower-column-options.yml");
452
+
453
+ assertTable(table);
254
454
  }
255
455
 
256
456
  @Test
257
457
  public void testReplace() throws Exception
258
458
  {
259
- invoke(test12c, "testReplace");
459
+ if (!canTest) {
460
+ return;
461
+ }
462
+
463
+ String table = "TEST1";
464
+
465
+ dropTable(table);
466
+ createTable(table);
467
+
468
+ run("/oracle/yml/test-replace.yml");
469
+
470
+ assertGeneratedTable2(table);
260
471
  }
261
472
 
262
473
  @Test
263
474
  public void testReplaceOCIMethod() throws Exception
264
475
  {
265
- invoke(test12c, "testReplaceOCIMethod");
476
+ if (!canTest) {
477
+ return;
478
+ }
479
+
480
+ String table = "TEST1";
481
+
482
+ dropTable(table);
483
+ createTable(table);
484
+
485
+ run("/oracle/yml/test-replace-oci-method.yml");
486
+
487
+ assertGeneratedTable2(table);
266
488
  }
267
489
 
268
490
  @Test
269
491
  public void testReplaceEmpty() throws Exception
270
492
  {
271
- invoke(test12c, "testReplaceEmpty");
493
+ if (!canTest) {
494
+ return;
495
+ }
496
+
497
+ String table = "TEST1";
498
+
499
+ dropTable(table);
500
+ createTable(table);
501
+
502
+ run("/oracle/yml/test-replace-empty.yml");
503
+
504
+ assertTableEmpty(table);
505
+ }
506
+
507
+ @Test
508
+ public void testReplaceCreate() throws Exception
509
+ {
510
+ if (!canTest) {
511
+ return;
512
+ }
513
+
514
+ String table = "TEST1";
515
+
516
+ dropTable(table);
517
+
518
+ run("/oracle/yml/test-replace.yml");
519
+
520
+ assertGeneratedTable2(table);
272
521
  }
273
522
 
523
+
274
524
  @Test
275
525
  public void testReplaceLongName() throws Exception
276
526
  {
277
- invoke(test12c, "testReplaceLongName");
527
+ if (!canTest) {
528
+ return;
529
+ }
530
+
531
+ String table = "TEST12345678901234567890123456";
532
+
533
+ dropTable(table);
534
+ createTable(table);
535
+
536
+ run("/oracle/yml/test-replace-long-name.yml");
537
+
538
+ assertGeneratedTable2(table);
278
539
  }
279
540
 
280
541
  @Test
281
542
  public void testReplaceLongNameMultibyte() throws Exception
282
543
  {
283
- invoke(test12c, "testReplaceLongNameMultibyte");
544
+ if (!canTest) {
545
+ return;
546
+ }
547
+
548
+ String table = "TEST123456789012345678";
549
+
550
+ run("/oracle/yml/test-replace-long-name-multibyte.yml");
551
+
552
+ assertGeneratedTable2(table);
284
553
  }
285
554
 
286
555
  @Test
287
- public void testReplaceCreate() throws Exception
556
+ public void testStringTimestamp() throws Exception
288
557
  {
289
- invoke(test12c, "testReplaceCreate");
558
+ if (!canTest) {
559
+ return;
560
+ }
561
+
562
+ String table = "TEST1";
563
+
564
+ dropTable(table);
565
+ createTable(table);
566
+
567
+ run("/oracle/yml/test-string-timestamp.yml");
568
+
569
+ assertTable(table);
290
570
  }
291
571
 
292
- @Test
293
- public void testStringTimestamp() throws Exception
572
+ private void createTable(String table) throws SQLException
294
573
  {
295
- invoke(test12c, "testStringTimestamp");
574
+ String sql = String.format("CREATE TABLE %s ("
575
+ + "ID CHAR(4),"
576
+ + "VARCHAR2_ITEM VARCHAR2(6),"
577
+ + "NVARCHAR2_ITEM NVARCHAR2(6),"
578
+ + "INTEGER_ITEM NUMBER(4,0),"
579
+ + "NUMBER_ITEM NUMBER(10,2),"
580
+ + "DATE_ITEM DATE,"
581
+ + "TIMESTAMP_ITEM TIMESTAMP,"
582
+ + "PRIMARY KEY (ID))", table);
583
+ executeSQL(sql);
296
584
  }
585
+
586
+ private void insertRecord(String table) throws SQLException
587
+ {
588
+ insertRecord(table, "9999");
589
+ }
590
+
591
+ private void insertRecord(String table, String id) throws SQLException
592
+ {
593
+ executeSQL(String.format("INSERT INTO %s VALUES('%s', NULL, NULL, NULL, NULL, NULL, NULL)", table, id));
594
+ }
595
+
596
+ private void assertTable(String table) throws Exception
597
+ {
598
+ // datetime of UTC will be inserted by embulk.
599
+ // datetime of default timezone will be selected by JDBC.
600
+ TimeZone timeZone = TimeZone.getDefault();
601
+ List<List<Object>> rows = select(table);
602
+
603
+ /*
604
+ A001,ABCDE,abcde,,0,123.45,2015/03/05,2015/03/05 12:34:56
605
+ A002,AB,abcdef,-9999,-99999999.99,2015/03/06,2015/03/06 23:59:59
606
+ A003,,,,,,
607
+ */
608
+
609
+ assertEquals(3, rows.size());
610
+ Iterator<List<Object>> i1 = rows.iterator();
611
+ {
612
+ Iterator<Object> i2 = i1.next().iterator();
613
+ assertEquals("A001", i2.next());
614
+ assertEquals("ABCDE", i2.next());
615
+ assertEquals("abcde", i2.next());
616
+ assertEquals(new BigDecimal("0"), i2.next());
617
+ assertEquals(new BigDecimal("123.45"), i2.next());
618
+ assertEquals(toTimestamp("2015/03/05 00:00:00", timeZone), i2.next());
619
+ assertEquals(toOracleTimestamp("2015/03/05 12:34:56", timeZone), i2.next());
620
+ }
621
+ {
622
+ Iterator<Object> i2 = i1.next().iterator();
623
+ assertEquals("A002", i2.next());
624
+ assertEquals("AB", i2.next());
625
+ assertEquals("abcdef", i2.next());
626
+ assertEquals(new BigDecimal("-9999"), i2.next());
627
+ assertEquals(new BigDecimal("-99999999.99"), i2.next());
628
+ assertEquals(toTimestamp("2015/03/06 00:00:00", timeZone), i2.next());
629
+ assertEquals(toOracleTimestamp("2015/03/06 23:59:59", timeZone), i2.next());
630
+ }
631
+ {
632
+ Iterator<Object> i2 = i1.next().iterator();
633
+ assertEquals("A003", i2.next());
634
+ assertEquals(null, i2.next());
635
+ assertEquals(null, i2.next());
636
+ assertEquals(null, i2.next());
637
+ assertEquals(null, i2.next());
638
+ assertEquals(null, i2.next());
639
+ assertEquals(null, i2.next());
640
+ }
641
+ }
642
+
643
+ private void assertTableEmpty(String table) throws Exception
644
+ {
645
+ List<List<Object>> rows = select(table);
646
+ assertEquals(0, rows.size());
647
+ }
648
+
649
+ private void assertGeneratedTable1(String table) throws Exception
650
+ {
651
+ // datetime of UTC will be inserted by embulk.
652
+ // datetime of default timezone will be selected by JDBC.
653
+ TimeZone timeZone = TimeZone.getDefault();
654
+ List<List<Object>> rows = select(table);
655
+
656
+ /*
657
+ A001,ABCDE,abcde,0,123.45,2015/03/05,2015/03/05 12:34:56
658
+ A002,AB,abcdef,-9999,-99999999.99,2015/03/06,2015/03/06 23:59:59
659
+ A003,,,,,,
660
+ */
661
+
662
+ assertEquals(3, rows.size());
663
+ Iterator<List<Object>> i1 = rows.iterator();
664
+ {
665
+ Iterator<Object> i2 = i1.next().iterator();
666
+ assertEquals("A001", i2.next());
667
+ assertEquals("ABCDE", i2.next());
668
+ assertEquals("abcde", i2.next());
669
+ assertEquals(new BigDecimal("0"), i2.next());
670
+ assertEquals("123.45", i2.next());
671
+ assertEquals(toOracleTimestamp("2015/03/05 00:00:00", timeZone), i2.next());
672
+ assertEquals(toOracleTimestamp("2015/03/05 12:34:56", timeZone), i2.next());
673
+ }
674
+ {
675
+ Iterator<Object> i2 = i1.next().iterator();
676
+ assertEquals("A002", i2.next());
677
+ assertEquals("AB", i2.next());
678
+ assertEquals("abcdef", i2.next());
679
+ assertEquals(new BigDecimal("-9999"), i2.next());
680
+ assertEquals("-99999999.99", i2.next());
681
+ assertEquals(toOracleTimestamp("2015/03/06 00:00:00", timeZone), i2.next());
682
+ assertEquals(toOracleTimestamp("2015/03/06 23:59:59", timeZone), i2.next());
683
+ }
684
+ {
685
+ Iterator<Object> i2 = i1.next().iterator();
686
+ assertEquals("A003", i2.next());
687
+ assertEquals(null, i2.next());
688
+ assertEquals(null, i2.next());
689
+ assertEquals(null, i2.next());
690
+ assertEquals(null, i2.next());
691
+ assertEquals(null, i2.next());
692
+ assertEquals(null, i2.next());
693
+ }
694
+ }
695
+
696
+ private void assertGeneratedTable2(String table) throws Exception
697
+ {
698
+ // datetime of UTC will be inserted by embulk.
699
+ // datetime of default timezone will be selected by JDBC.
700
+ TimeZone timeZone = TimeZone.getDefault();
701
+ List<List<Object>> rows = select(table);
702
+
703
+ /*
704
+ A001,ABCDE,abcde,0,123.45,2015/03/05,2015/03/05 12:34:56
705
+ A002,AB,abcdef,-9999,-99999999.99,2015/03/06,2015/03/06 23:59:59
706
+ A003,,,,,,
707
+ */
708
+
709
+ assertEquals(3, rows.size());
710
+ Iterator<List<Object>> i1 = rows.iterator();
711
+ {
712
+ Iterator<Object> i2 = i1.next().iterator();
713
+ assertEquals("A001", i2.next());
714
+ assertEquals("ABCDE", i2.next());
715
+ assertEquals("abcde", i2.next());
716
+ assertEquals(new BigDecimal("0"), i2.next());
717
+ assertEquals(new BigDecimal("123.45"), i2.next());
718
+ assertEquals(toTimestamp("2015/03/05 00:00:00", timeZone), i2.next());
719
+ assertEquals(toOracleTimestamp("2015/03/05 12:34:56", timeZone), i2.next());
720
+ }
721
+ {
722
+ Iterator<Object> i2 = i1.next().iterator();
723
+ assertEquals("A002", i2.next());
724
+ assertEquals("AB", i2.next());
725
+ assertEquals("abcdef", i2.next());
726
+ assertEquals(new BigDecimal("-9999"), i2.next());
727
+ assertEquals(new BigDecimal("-99999999.99"), i2.next());
728
+ assertEquals(toTimestamp("2015/03/06 00:00:00", timeZone), i2.next());
729
+ assertEquals(toOracleTimestamp("2015/03/06 23:59:59", timeZone), i2.next());
730
+ }
731
+ {
732
+ Iterator<Object> i2 = i1.next().iterator();
733
+ assertEquals("A003", i2.next());
734
+ assertEquals(null, i2.next());
735
+ assertEquals(null, i2.next());
736
+ assertEquals(null, i2.next());
737
+ assertEquals(null, i2.next());
738
+ assertEquals(null, i2.next());
739
+ assertEquals(null, i2.next());
740
+ }
741
+ }
742
+
743
+ @Override
744
+ protected Object getValue(ResultSet resultSet, int index) throws SQLException
745
+ {
746
+ if (resultSet.getMetaData().getColumnTypeName(index).equals("CLOB")) {
747
+ return resultSet.getString(index);
748
+ }
749
+ return super.getValue(resultSet, index);
750
+ }
751
+
752
+
753
+ private Timestamp toTimestamp(String s, TimeZone timeZone)
754
+ {
755
+ for (String formatString : new String[]{"yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd"}) {
756
+ DateFormat dateFormat = new SimpleDateFormat(formatString);
757
+ dateFormat.setTimeZone(timeZone);
758
+ try {
759
+ Date date = dateFormat.parse(s);
760
+ return new Timestamp(date.getTime());
761
+ } catch (ParseException e) {
762
+ // NOP
763
+ }
764
+ }
765
+ throw new IllegalArgumentException(s);
766
+ }
767
+
768
+ private Object toOracleTimestamp(String s, TimeZone timeZone) throws Exception
769
+ {
770
+ Class<?> timestampClass = Class.forName("oracle.sql.TIMESTAMP");
771
+ Constructor<?> constructor = timestampClass.getConstructor(Timestamp.class);
772
+ return constructor.newInstance(toTimestamp(s, timeZone));
773
+ }
774
+
775
+ @Override
776
+ protected Connection connect() throws SQLException
777
+ {
778
+ return DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:TESTDB", "TEST_USER", "test_pw");
779
+ }
780
+
781
+ private void run(String ymlName) throws Exception
782
+ {
783
+ tester.run(convertYml(ymlName));
784
+ }
785
+
297
786
  }