embulk-output-sqlserver 0.6.3 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/build.gradle +4 -2
- data/classpath/{embulk-output-jdbc-0.6.3.jar → embulk-output-jdbc-0.6.4.jar} +0 -0
- data/classpath/{embulk-output-sqlserver-0.6.3.jar → embulk-output-sqlserver-0.6.4.jar} +0 -0
- data/classpath/jtds-1.3.1.jar +0 -0
- data/src/main/java/org/embulk/output/SQLServerOutputPlugin.java +114 -20
- data/src/main/java/org/embulk/output/sqlserver/SQLServerOutputConnector.java +2 -7
- data/src/test/java/org/embulk/output/sqlserver/SQLServerOutputPluginTest.java +157 -10
- data/src/test/resources/sqlserver/yml/test-jtds.yml +43 -0
- metadata +9 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e4e793c760c471271fa0388e2313a9d2d329eb6f
|
4
|
+
data.tar.gz: 54633fc992bbe7f01faf4873ce22cb22bf738497
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 963f63991e65b0b49899fd4c2c951374198191e6aaddd56bc8d33693f446de37468af7edd6b91d4c9c7d64d3688765c35ac0f6e3f5f3457de5142f2c28a4bf8d
|
7
|
+
data.tar.gz: 92ee454069669fb5378b6d43bd564e931cc3e73885e2bdc4c39b01c11d4576a3b6ae44fb3dce9024fcc010d7b1c1e4f1b94facf76443aa87191a6fd8333025c0
|
data/README.md
CHANGED
@@ -10,7 +10,7 @@ SQL Server output plugins for Embulk loads records to SQL Server.
|
|
10
10
|
|
11
11
|
## Configuration
|
12
12
|
|
13
|
-
- **driver_path**: path to the jar file of
|
13
|
+
- **driver_path**: path to the jar file of Microsoft SQL Server JDBC driver. If not set, open-source driver (jTDS driver) is used (string)
|
14
14
|
- **host**: database host name (string, required)
|
15
15
|
- **port**: database port number (integer, default: 1433)
|
16
16
|
- **integratedSecutiry**: whether to use integrated authentication or not. The `sqljdbc_auth.dll` must be located on Java library path if using integrated authentication. : (boolean, default: false)
|
data/build.gradle
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
[compileTestJava]*.options*.encoding = 'UTF-8'
|
2
|
-
|
3
1
|
dependencies {
|
4
2
|
compile project(':embulk-output-jdbc')
|
3
|
+
compile 'net.sourceforge.jtds:jtds:1.3.1'
|
4
|
+
|
5
|
+
testCompile 'org.embulk:embulk-standards:0.8.8'
|
5
6
|
testCompile files('../embulk-output-jdbc/build/classes/test/')
|
7
|
+
testCompile files('driver/sqljdbc41.jar')
|
6
8
|
}
|
Binary file
|
Binary file
|
Binary file
|
@@ -1,12 +1,10 @@
|
|
1
1
|
package org.embulk.output;
|
2
2
|
|
3
|
-
import
|
4
|
-
import
|
5
|
-
import java.util.List;
|
6
|
-
import java.util.Properties;
|
7
|
-
|
3
|
+
import com.google.common.base.Optional;
|
4
|
+
import com.google.common.collect.ImmutableSet;
|
8
5
|
import org.embulk.config.Config;
|
9
6
|
import org.embulk.config.ConfigDefault;
|
7
|
+
import org.embulk.config.ConfigException;
|
10
8
|
import org.embulk.output.jdbc.AbstractJdbcOutputPlugin;
|
11
9
|
import org.embulk.output.jdbc.BatchInsert;
|
12
10
|
import org.embulk.output.jdbc.MergeConfig;
|
@@ -18,12 +16,17 @@ import org.embulk.output.sqlserver.SQLServerOutputConnector;
|
|
18
16
|
import org.embulk.output.sqlserver.setter.SQLServerColumnSetterFactory;
|
19
17
|
import org.joda.time.DateTimeZone;
|
20
18
|
|
21
|
-
import
|
22
|
-
import
|
19
|
+
import java.io.IOException;
|
20
|
+
import java.sql.SQLException;
|
21
|
+
import java.util.Properties;
|
22
|
+
|
23
|
+
import static java.util.Locale.ENGLISH;
|
23
24
|
|
24
25
|
public class SQLServerOutputPlugin
|
25
26
|
extends AbstractJdbcOutputPlugin
|
26
27
|
{
|
28
|
+
private static int DEFAULT_PORT = 1433;
|
29
|
+
|
27
30
|
public interface SQLServerPluginTask
|
28
31
|
extends PluginTask
|
29
32
|
{
|
@@ -68,6 +71,27 @@ public class SQLServerOutputPlugin
|
|
68
71
|
public InsertMethod getInsertMethod();
|
69
72
|
}
|
70
73
|
|
74
|
+
private static class UrlAndProperties {
|
75
|
+
private final String url;
|
76
|
+
private final Properties props;
|
77
|
+
|
78
|
+
public UrlAndProperties(String url, Properties props)
|
79
|
+
{
|
80
|
+
this.url = url;
|
81
|
+
this.props = props;
|
82
|
+
}
|
83
|
+
|
84
|
+
public String getUrl()
|
85
|
+
{
|
86
|
+
return this.url;
|
87
|
+
}
|
88
|
+
|
89
|
+
public Properties getProps()
|
90
|
+
{
|
91
|
+
return this.props;
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
71
95
|
@Override
|
72
96
|
protected Class<? extends PluginTask> getTaskClass()
|
73
97
|
{
|
@@ -87,12 +111,49 @@ public class SQLServerOutputPlugin
|
|
87
111
|
protected SQLServerOutputConnector getConnector(PluginTask task, boolean retryableMetadataOperation)
|
88
112
|
{
|
89
113
|
SQLServerPluginTask sqlServerTask = (SQLServerPluginTask) task;
|
114
|
+
boolean useJtdsDriver = false;
|
90
115
|
|
91
116
|
if (sqlServerTask.getDriverPath().isPresent()) {
|
92
117
|
loadDriverJar(sqlServerTask.getDriverPath().get());
|
118
|
+
try {
|
119
|
+
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
|
120
|
+
} catch(Exception e) {
|
121
|
+
throw new ConfigException("Driver set at field 'driver_path' doesn't include Microsoft SQLServerDriver", e);
|
122
|
+
}
|
123
|
+
} else {
|
124
|
+
// prefer Microsoft SQLServerDriver if it is in classpath
|
125
|
+
try {
|
126
|
+
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
|
127
|
+
} catch(Exception e) {
|
128
|
+
logger.info("Using jTDS Driver");
|
129
|
+
try {
|
130
|
+
Class.forName("net.sourceforge.jtds.jdbc.Driver");
|
131
|
+
} catch(Exception e2) {
|
132
|
+
throw new ConfigException("'driver_path' doesn't set and can't found jTDS driver", e2);
|
133
|
+
|
134
|
+
}
|
135
|
+
useJtdsDriver = true;
|
136
|
+
}
|
93
137
|
}
|
94
138
|
|
139
|
+
UrlAndProperties urlProps = getUrlAndProperties(sqlServerTask, useJtdsDriver);
|
140
|
+
logger.info("Connecting to {} options {}", urlProps.getUrl(), getPropsWithMaskedSecret(urlProps));
|
141
|
+
return new SQLServerOutputConnector(urlProps.getUrl(), urlProps.getProps(), null);
|
142
|
+
}
|
143
|
+
|
144
|
+
private UrlAndProperties getUrlAndProperties(SQLServerPluginTask sqlServerTask, boolean useJtdsDriver)
|
145
|
+
{
|
146
|
+
Properties props = new Properties();
|
95
147
|
String url;
|
148
|
+
|
149
|
+
props.putAll(sqlServerTask.getOptions());
|
150
|
+
if (sqlServerTask.getUser().isPresent()) {
|
151
|
+
props.setProperty("user", sqlServerTask.getUser().get());
|
152
|
+
}
|
153
|
+
if (sqlServerTask.getPassword().isPresent()) {
|
154
|
+
props.setProperty("password", sqlServerTask.getPassword().get());
|
155
|
+
}
|
156
|
+
|
96
157
|
if (sqlServerTask.getUrl().isPresent()) {
|
97
158
|
if (sqlServerTask.getInsertMethod() == InsertMethod.NATIVE) {
|
98
159
|
throw new IllegalArgumentException("Cannot set 'url' when 'insert_method' is 'native'.");
|
@@ -112,6 +173,36 @@ public class SQLServerOutputPlugin
|
|
112
173
|
if (!sqlServerTask.getDatabase().isPresent()) {
|
113
174
|
throw new IllegalArgumentException("Field 'database' is not set.");
|
114
175
|
}
|
176
|
+
}
|
177
|
+
|
178
|
+
if(useJtdsDriver) {
|
179
|
+
// jTDS URL: host:port[/database] or host[/database][;instance=]
|
180
|
+
// host:port;instance= is allowed but port will be ignored? in this case.
|
181
|
+
if (sqlServerTask.getInstance().isPresent()) {
|
182
|
+
if (sqlServerTask.getPort() != DEFAULT_PORT) {
|
183
|
+
logger.warn("'port: {}' option is ignored because instance option is set", sqlServerTask.getPort());
|
184
|
+
}
|
185
|
+
url = String.format(ENGLISH, "jdbc:jtds:sqlserver://%s", sqlServerTask.getHost().get());
|
186
|
+
props.setProperty("instance", sqlServerTask.getInstance().get());
|
187
|
+
}
|
188
|
+
else {
|
189
|
+
url = String.format(ENGLISH, "jdbc:jtds:sqlserver://%s:%d", sqlServerTask.getHost().get(), sqlServerTask.getPort());
|
190
|
+
}
|
191
|
+
|
192
|
+
// /database
|
193
|
+
if (sqlServerTask.getDatabase().isPresent()) {
|
194
|
+
url += "/" + sqlServerTask.getDatabase().get();
|
195
|
+
}
|
196
|
+
|
197
|
+
// integratedSecutiry is not supported, user + password is required
|
198
|
+
if (sqlServerTask.getIntegratedSecurity().isPresent()) {
|
199
|
+
throw new ConfigException("'integratedSecutiry' option is not supported with jTDS driver. Set 'driver_path: /path/to/sqljdbc.jar' option if you want to use Microsoft SQLServerDriver.");
|
200
|
+
}
|
201
|
+
|
202
|
+
if (!sqlServerTask.getUser().isPresent()) {
|
203
|
+
throw new ConfigException("'user' option is required but not set.");
|
204
|
+
}
|
205
|
+
}else {
|
115
206
|
StringBuilder urlBuilder = new StringBuilder();
|
116
207
|
if (sqlServerTask.getInstance().isPresent()) {
|
117
208
|
urlBuilder.append(String.format("jdbc:sqlserver://%s\\%s",
|
@@ -136,21 +227,10 @@ public class SQLServerOutputPlugin
|
|
136
227
|
url = urlBuilder.toString();
|
137
228
|
}
|
138
229
|
|
139
|
-
|
140
|
-
Properties props = new Properties();
|
141
|
-
props.putAll(sqlServerTask.getOptions());
|
142
|
-
|
143
|
-
if (sqlServerTask.getUser().isPresent()) {
|
144
|
-
props.setProperty("user", sqlServerTask.getUser().get());
|
145
|
-
}
|
146
|
-
logger.info("Connecting to {} options {}", url, props);
|
147
|
-
if (sqlServerTask.getPassword().isPresent()) {
|
148
|
-
props.setProperty("password", sqlServerTask.getPassword().get());
|
149
|
-
}
|
150
|
-
|
151
|
-
return new SQLServerOutputConnector(url, props, null);
|
230
|
+
return new UrlAndProperties(url, props);
|
152
231
|
}
|
153
232
|
|
233
|
+
|
154
234
|
@Override
|
155
235
|
protected BatchInsert newBatchInsert(PluginTask task, Optional<MergeConfig> mergeConfig) throws IOException, SQLException
|
156
236
|
{
|
@@ -167,4 +247,18 @@ public class SQLServerOutputPlugin
|
|
167
247
|
{
|
168
248
|
return new SQLServerColumnSetterFactory(batch, defaultTimeZone);
|
169
249
|
}
|
250
|
+
|
251
|
+
private Properties getPropsWithMaskedSecret(UrlAndProperties urlAndProperties)
|
252
|
+
{
|
253
|
+
Properties safeProps = new Properties();
|
254
|
+
Properties originalProps = urlAndProperties.getProps();
|
255
|
+
for(String key : originalProps.stringPropertyNames()) {
|
256
|
+
if (key.equals("password")) {
|
257
|
+
safeProps.setProperty(key, "***");
|
258
|
+
} else {
|
259
|
+
safeProps.setProperty(key, originalProps.getProperty(key));
|
260
|
+
}
|
261
|
+
}
|
262
|
+
return safeProps;
|
263
|
+
}
|
170
264
|
}
|
@@ -1,12 +1,12 @@
|
|
1
1
|
package org.embulk.output.sqlserver;
|
2
2
|
|
3
|
+
import org.embulk.output.jdbc.JdbcOutputConnector;
|
4
|
+
|
3
5
|
import java.sql.Connection;
|
4
6
|
import java.sql.DriverManager;
|
5
7
|
import java.sql.SQLException;
|
6
8
|
import java.util.Properties;
|
7
9
|
|
8
|
-
import org.embulk.output.jdbc.JdbcOutputConnector;
|
9
|
-
|
10
10
|
public class SQLServerOutputConnector
|
11
11
|
implements JdbcOutputConnector
|
12
12
|
{
|
@@ -16,11 +16,6 @@ public class SQLServerOutputConnector
|
|
16
16
|
|
17
17
|
public SQLServerOutputConnector(String url, Properties properties, String schemaName)
|
18
18
|
{
|
19
|
-
try {
|
20
|
-
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
|
21
|
-
} catch (Exception ex) {
|
22
|
-
throw new RuntimeException(ex);
|
23
|
-
}
|
24
19
|
this.url = url;
|
25
20
|
this.properties = properties;
|
26
21
|
this.schemaName = schemaName;
|
@@ -1,6 +1,11 @@
|
|
1
1
|
package org.embulk.output.sqlserver;
|
2
2
|
|
3
|
-
import
|
3
|
+
import org.embulk.output.AbstractJdbcOutputPluginTest;
|
4
|
+
import org.embulk.output.SQLServerOutputPlugin;
|
5
|
+
import org.embulk.output.tester.EmbulkPluginTester;
|
6
|
+
import org.embulk.spi.OutputPlugin;
|
7
|
+
import org.junit.BeforeClass;
|
8
|
+
import org.junit.Test;
|
4
9
|
|
5
10
|
import java.math.BigDecimal;
|
6
11
|
import java.sql.Connection;
|
@@ -15,16 +20,12 @@ import java.util.Date;
|
|
15
20
|
import java.util.Iterator;
|
16
21
|
import java.util.List;
|
17
22
|
|
18
|
-
import org.
|
19
|
-
import org.embulk.output.SQLServerOutputPlugin;
|
20
|
-
import org.embulk.output.tester.EmbulkPluginTester;
|
21
|
-
import org.embulk.spi.OutputPlugin;
|
22
|
-
import org.junit.BeforeClass;
|
23
|
-
import org.junit.Test;
|
23
|
+
import static org.junit.Assert.assertEquals;
|
24
24
|
|
25
25
|
|
26
26
|
public class SQLServerOutputPluginTest extends AbstractJdbcOutputPluginTest
|
27
27
|
{
|
28
|
+
private static boolean useJtdsDriver = false;
|
28
29
|
private static boolean canTest;
|
29
30
|
private static EmbulkPluginTester tester = new EmbulkPluginTester();
|
30
31
|
static {
|
@@ -34,6 +35,13 @@ public class SQLServerOutputPluginTest extends AbstractJdbcOutputPluginTest
|
|
34
35
|
@BeforeClass
|
35
36
|
public static void beforeClass()
|
36
37
|
{
|
38
|
+
try {
|
39
|
+
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
|
40
|
+
} catch (ClassNotFoundException e) {
|
41
|
+
System.err.println("Warning: you should put 'sqljdbc41.jar' in 'embulk-input-sqlserver/driver' directory in order to test.");
|
42
|
+
return;
|
43
|
+
}
|
44
|
+
|
37
45
|
try {
|
38
46
|
new SQLServerOutputPluginTest().connect();
|
39
47
|
canTest = true;
|
@@ -41,8 +49,7 @@ public class SQLServerOutputPluginTest extends AbstractJdbcOutputPluginTest
|
|
41
49
|
System.out.println(t);
|
42
50
|
} finally {
|
43
51
|
if (!canTest) {
|
44
|
-
System.out.println("Warning: you should
|
45
|
-
System.out.println("(server = localhost, port = 1433, instance = SQLEXPRESS, database = TESTDB, user = TEST_USER, password = TEST_PW)");
|
52
|
+
System.out.println("Warning: you should prepare database in order to test (server = localhost, port = 1433, instance = SQLEXPRESS, database = TESTDB, user = TEST_USER, password = TEST_PW).");
|
46
53
|
}
|
47
54
|
}
|
48
55
|
}
|
@@ -368,11 +375,147 @@ public class SQLServerOutputPluginTest extends AbstractJdbcOutputPluginTest
|
|
368
375
|
assertTable(1, table);
|
369
376
|
}
|
370
377
|
|
378
|
+
@Test
|
379
|
+
public void testJtds() throws Exception
|
380
|
+
{
|
381
|
+
boolean canTestJtds = false;
|
382
|
+
useJtdsDriver = true;
|
383
|
+
try {
|
384
|
+
new SQLServerOutputPluginTest().connect();
|
385
|
+
canTestJtds = true;
|
386
|
+
} catch (Throwable t) {
|
387
|
+
System.out.println(t);
|
388
|
+
} finally {
|
389
|
+
if (!canTestJtds) {
|
390
|
+
System.out.println("Warning: jTDS driver can't connect to database.");
|
391
|
+
System.out.println("(server = localhost, port = 1433, instance = SQLEXPRESS, database = TESTDB, user = TEST_USER, password = TEST_PW)");
|
392
|
+
return;
|
393
|
+
}
|
394
|
+
}
|
395
|
+
|
396
|
+
try {
|
397
|
+
String table = "TEST1";
|
398
|
+
dropTable(table);
|
399
|
+
createTable(table);
|
400
|
+
insertRecord(table);
|
401
|
+
tester.run(convertYml("/sqlserver/yml/test-jtds.yml"));
|
402
|
+
assertTableJtds(1, table);
|
403
|
+
} finally {
|
404
|
+
useJtdsDriver = false;
|
405
|
+
}
|
406
|
+
}
|
407
|
+
|
408
|
+
|
371
409
|
private void assertTable(int skip, String table) throws Exception
|
372
410
|
{
|
373
411
|
assertTable(skip, table, false);
|
374
412
|
}
|
375
413
|
|
414
|
+
private void assertTableJtds(int skip, String table) throws Exception
|
415
|
+
{
|
416
|
+
List<List<Object>> rows = select(table);
|
417
|
+
assertEquals(skip + 3, rows.size());
|
418
|
+
rows = rows.subList(skip, skip + 3);
|
419
|
+
|
420
|
+
Iterator<List<Object>> i1 = rows.iterator();
|
421
|
+
{
|
422
|
+
Iterator<Object> i2 = i1.next().iterator();
|
423
|
+
assertEquals("A001", i2.next());
|
424
|
+
assertEquals(0, i2.next());
|
425
|
+
assertEquals(1234, i2.next());
|
426
|
+
assertEquals(123456, i2.next());
|
427
|
+
assertEquals(12345678901L, i2.next());
|
428
|
+
assertEquals(false, i2.next());
|
429
|
+
assertEquals(new BigDecimal("1.23"), i2.next());
|
430
|
+
assertEquals(new BigDecimal("3.456"), i2.next());
|
431
|
+
assertEquals(new BigDecimal("12.3400"), i2.next());
|
432
|
+
assertEquals(new BigDecimal("123.4567"), i2.next());
|
433
|
+
assertEquals(Float.valueOf(0.1234567F), i2.next());
|
434
|
+
assertEquals(Double.valueOf(0.12345678901234D), i2.next());
|
435
|
+
assertEquals("a ", i2.next());
|
436
|
+
assertEquals("b", i2.next());
|
437
|
+
assertEquals("c", i2.next());
|
438
|
+
assertEquals("A ", i2.next());
|
439
|
+
assertEquals("B", i2.next());
|
440
|
+
assertEquals("C", i2.next());
|
441
|
+
assertEquals("2016-01-01", i2.next());
|
442
|
+
assertEquals(createTimestamp("2017/01/01 01:02:03", 123000000), i2.next());
|
443
|
+
// Embulk timestamp doesn't support values under microseconds.
|
444
|
+
assertEquals("2018-01-01 01:02:03.1234560", i2.next().toString());
|
445
|
+
|
446
|
+
assertEquals(createTimestamp("2019/01/01 01:02:03", 120000000).toString(), i2.next());
|
447
|
+
assertEquals(createTimestamp("2020/01/01 01:02:00", 0), i2.next());
|
448
|
+
|
449
|
+
// Embulk timestamp doesn't support values under microseconds.
|
450
|
+
assertEquals("03:04:05.1234560", i2.next().toString());
|
451
|
+
assertEquals("06:07:08.12", i2.next().toString());
|
452
|
+
}
|
453
|
+
{
|
454
|
+
Iterator<Object> i2 = i1.next().iterator();
|
455
|
+
assertEquals("A002", i2.next());
|
456
|
+
assertEquals(255, i2.next());
|
457
|
+
assertEquals(-32768, i2.next());
|
458
|
+
assertEquals(-2147483648, i2.next());
|
459
|
+
assertEquals(-9223372036854775808L, i2.next());
|
460
|
+
assertEquals(true, i2.next());
|
461
|
+
assertEquals(new BigDecimal("-9999999999.99"), i2.next());
|
462
|
+
assertEquals(new BigDecimal("-99.999"), i2.next());
|
463
|
+
assertEquals(new BigDecimal("-214748.3648"), i2.next());
|
464
|
+
assertEquals(new BigDecimal("-922337203685477.5808"), i2.next());
|
465
|
+
assertEquals(Float.valueOf(-9999000000F), i2.next());
|
466
|
+
assertEquals(Double.valueOf(-999999999999000000D), i2.next());
|
467
|
+
// char, varchar, text don't be capable on Unicode chars
|
468
|
+
//assertEquals("あい", i2.next());
|
469
|
+
i2.next();
|
470
|
+
//assertEquals("あいうえ", i2.next());
|
471
|
+
i2.next();
|
472
|
+
//assertEquals("あいうえお", i2.next());
|
473
|
+
i2.next();
|
474
|
+
|
475
|
+
// nchar, nvarcar, ntext
|
476
|
+
assertEquals("かき ", i2.next());
|
477
|
+
assertEquals("かきくけ", i2.next());
|
478
|
+
assertEquals("かきくけこ", i2.next());
|
479
|
+
|
480
|
+
assertEquals("2016-12-31", i2.next());
|
481
|
+
assertEquals(createTimestamp("2017/12/31 23:59:59", 997000000), i2.next());
|
482
|
+
// Embulk timestamp doesn't support values under microseconds.
|
483
|
+
assertEquals("2018-12-31 23:59:59.9999990", i2.next().toString());
|
484
|
+
assertEquals(createTimestamp("2019/12/31 23:59:59", 990000000).toString(), i2.next());
|
485
|
+
assertEquals(createTimestamp("2021/01/01 00:00:00", 0), i2.next());
|
486
|
+
// Embulk timestamp doesn't support values under microseconds.
|
487
|
+
assertEquals("23:59:59.9999990", i2.next().toString());
|
488
|
+
assertEquals("23:59:59.99", i2.next().toString());
|
489
|
+
}
|
490
|
+
{
|
491
|
+
Iterator<Object> i2 = i1.next().iterator();
|
492
|
+
assertEquals("A003", i2.next());
|
493
|
+
assertEquals(null, i2.next());
|
494
|
+
assertEquals(null, i2.next());
|
495
|
+
assertEquals(null, i2.next());
|
496
|
+
assertEquals(null, i2.next());
|
497
|
+
assertEquals(null, i2.next());
|
498
|
+
assertEquals(null, i2.next());
|
499
|
+
assertEquals(null, i2.next());
|
500
|
+
assertEquals(null, i2.next());
|
501
|
+
assertEquals(null, i2.next());
|
502
|
+
assertEquals(null, i2.next());
|
503
|
+
assertEquals(null, i2.next());
|
504
|
+
assertEquals(null, i2.next());
|
505
|
+
assertEquals(null, i2.next());
|
506
|
+
assertEquals(null, i2.next());
|
507
|
+
assertEquals(null, i2.next());
|
508
|
+
assertEquals(null, i2.next());
|
509
|
+
assertEquals(null, i2.next());
|
510
|
+
assertEquals(null, i2.next());
|
511
|
+
assertEquals(null, i2.next());
|
512
|
+
assertEquals(null, i2.next());
|
513
|
+
assertEquals(null, i2.next());
|
514
|
+
assertEquals(null, i2.next());
|
515
|
+
assertEquals(null, i2.next());
|
516
|
+
}
|
517
|
+
}
|
518
|
+
|
376
519
|
private void assertTable(int skip, String table, boolean precise) throws Exception
|
377
520
|
{
|
378
521
|
List<List<Object>> rows = select(table);
|
@@ -668,7 +811,11 @@ public class SQLServerOutputPluginTest extends AbstractJdbcOutputPluginTest
|
|
668
811
|
@Override
|
669
812
|
protected Connection connect() throws SQLException
|
670
813
|
{
|
671
|
-
|
814
|
+
if(useJtdsDriver) {
|
815
|
+
return DriverManager.getConnection("jdbc:jtds:sqlserver://localhost:1433/TESTDB;instance=SQLEXPRESS;useLOBs=false", "TEST_USER", "test_pw");
|
816
|
+
} else {
|
817
|
+
return DriverManager.getConnection("jdbc:sqlserver://localhost\\SQLEXPRESS:1433;databasename=TESTDB", "TEST_USER", "test_pw");
|
818
|
+
}
|
672
819
|
}
|
673
820
|
|
674
821
|
}
|
@@ -0,0 +1,43 @@
|
|
1
|
+
in:
|
2
|
+
type: file
|
3
|
+
path_prefix: '/sqlserver/data/test1/test1.csv'
|
4
|
+
parser:
|
5
|
+
charset: UTF-8
|
6
|
+
newline: CRLF
|
7
|
+
type: csv
|
8
|
+
delimiter: ','
|
9
|
+
quote: ''
|
10
|
+
columns:
|
11
|
+
- {name: ID, type: string}
|
12
|
+
- {name: TINYINT_ITEM, type: long}
|
13
|
+
- {name: SMALLINT_ITEM, type: long}
|
14
|
+
- {name: INT_ITEM, type: long}
|
15
|
+
- {name: BIGINT_ITEM, type: long}
|
16
|
+
- {name: BIT_ITEM, type: boolean}
|
17
|
+
- {name: DECIMAL_ITEM, type: string}
|
18
|
+
- {name: NUMERIC_ITEM, type: string}
|
19
|
+
- {name: SMALLMONEY_ITEM, type: string}
|
20
|
+
- {name: MONEY_ITEM, type: string}
|
21
|
+
- {name: REAL_ITEM, type: double}
|
22
|
+
- {name: FLOAT_ITEM, type: double}
|
23
|
+
- {name: CHAR_ITEM, type: string}
|
24
|
+
- {name: VARCHAR_ITEM, type: string}
|
25
|
+
- {name: TEXT_ITEM, type: string}
|
26
|
+
- {name: NCHAR_ITEM, type: string}
|
27
|
+
- {name: NVARCHAR_ITEM, type: string}
|
28
|
+
- {name: NTEXT_ITEM, type: string}
|
29
|
+
- {name: DATE_ITEM, type: timestamp, format: '%Y/%m/%d'}
|
30
|
+
- {name: DATETIME_ITEM, type: timestamp, format: '%Y/%m/%d %H:%M:%S.%N'}
|
31
|
+
- {name: DATETIME2_ITEM, type: timestamp, format: '%Y/%m/%d %H:%M:%S.%N'}
|
32
|
+
- {name: DATETIME2_2_ITEM, type: timestamp, format: '%Y/%m/%d %H:%M:%S.%N'}
|
33
|
+
- {name: SMALLDATETIME_ITEM, type: timestamp, format: '%Y/%m/%d %H:%M:%S'}
|
34
|
+
- {name: TIME_ITEM, type: timestamp, format: '%H:%M:%S.%N'}
|
35
|
+
- {name: TIME_2_ITEM, type: timestamp, format: '%H:%M:%S.%N'}
|
36
|
+
out:
|
37
|
+
type: sqlserver
|
38
|
+
host: localhost
|
39
|
+
database: TESTDB
|
40
|
+
user: TEST_USER
|
41
|
+
password: test_pw
|
42
|
+
table: TEST1
|
43
|
+
mode: insert_direct
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: embulk-output-sqlserver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-09-30 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Inserts or updates records to a table.
|
14
14
|
email:
|
@@ -19,6 +19,9 @@ extra_rdoc_files: []
|
|
19
19
|
files:
|
20
20
|
- README.md
|
21
21
|
- build.gradle
|
22
|
+
- classpath/embulk-output-jdbc-0.6.4.jar
|
23
|
+
- classpath/embulk-output-sqlserver-0.6.4.jar
|
24
|
+
- classpath/jtds-1.3.1.jar
|
22
25
|
- lib/embulk/output/sqlserver.rb
|
23
26
|
- src/main/java/org/embulk/output/SQLServerOutputPlugin.java
|
24
27
|
- src/main/java/org/embulk/output/sqlserver/InsertMethod.java
|
@@ -41,6 +44,7 @@ files:
|
|
41
44
|
- src/test/resources/sqlserver/data/test5/test5.csv
|
42
45
|
- src/test/resources/sqlserver/yml/test-insert-direct.yml
|
43
46
|
- src/test/resources/sqlserver/yml/test-insert.yml
|
47
|
+
- src/test/resources/sqlserver/yml/test-jtds.yml
|
44
48
|
- src/test/resources/sqlserver/yml/test-native-date.yml
|
45
49
|
- src/test/resources/sqlserver/yml/test-native-decimal.yml
|
46
50
|
- src/test/resources/sqlserver/yml/test-native-integer.yml
|
@@ -50,8 +54,6 @@ files:
|
|
50
54
|
- src/test/resources/sqlserver/yml/test-replace.yml
|
51
55
|
- src/test/resources/sqlserver/yml/test-string-timestamp.yml
|
52
56
|
- src/test/resources/sqlserver/yml/test-truncate-insert.yml
|
53
|
-
- classpath/embulk-output-jdbc-0.6.3.jar
|
54
|
-
- classpath/embulk-output-sqlserver-0.6.3.jar
|
55
57
|
homepage: https://github.com/embulk/embulk-output-jdbc
|
56
58
|
licenses:
|
57
59
|
- Apache 2.0
|
@@ -62,17 +64,17 @@ require_paths:
|
|
62
64
|
- lib
|
63
65
|
required_ruby_version: !ruby/object:Gem::Requirement
|
64
66
|
requirements:
|
65
|
-
- -
|
67
|
+
- - ">="
|
66
68
|
- !ruby/object:Gem::Version
|
67
69
|
version: '0'
|
68
70
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
71
|
requirements:
|
70
|
-
- -
|
72
|
+
- - ">="
|
71
73
|
- !ruby/object:Gem::Version
|
72
74
|
version: '0'
|
73
75
|
requirements: []
|
74
76
|
rubyforge_project:
|
75
|
-
rubygems_version: 2.
|
77
|
+
rubygems_version: 2.4.8
|
76
78
|
signing_key:
|
77
79
|
specification_version: 4
|
78
80
|
summary: JDBC output plugin for Embulk
|