embulk-input-sqlserver 0.10.0 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -4
- data/build.gradle +1 -0
- data/classpath/{embulk-input-jdbc-0.10.0.jar → embulk-input-jdbc-0.10.1.jar} +0 -0
- data/classpath/embulk-input-sqlserver-0.10.1.jar +0 -0
- data/classpath/mssql-jdbc-7.2.2.jre8.jar +0 -0
- data/src/main/java/org/embulk/input/SQLServerInputPlugin.java +36 -26
- data/src/main/java/org/embulk/input/sqlserver/getter/SQLServerColumnGetterFactory.java +15 -5
- data/src/test/java/org/embulk/input/sqlserver/BasicTest.java +9 -0
- data/src/test/java/org/embulk/input/sqlserver/IncrementalTest.java +149 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/basic/jtds_config.yml +3 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/char/config_1.yml +3 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/char/config_2.yml +4 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/char/expected_1.csv +4 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/char/expected_1.diff +3 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/char/expected_2.csv +2 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/char/expected_2.diff +3 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/char/insert_more.sql +6 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/char/setup.sql +11 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/datetime2/config_1.yml +4 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/datetime2/config_2.yml +4 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/datetime2/expected_1.csv +7 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/datetime2/expected_1.diff +3 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/datetime2/expected_2.csv +3 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/datetime2/expected_2.diff +3 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/datetime2/insert_more.sql +8 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/datetime2/setup.sql +14 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/int/config_1.yml +3 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/int/config_2.yml +4 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/int/expected_1.csv +4 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/int/expected_1.diff +3 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/int/expected_2.csv +2 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/int/expected_2.diff +3 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/int/insert_more.sql +6 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/int/setup.sql +11 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/config_1.yml +14 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/config_2.yml +14 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/expected_1.csv +4 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/expected_1.diff +3 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/expected_2.csv +2 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/expected_2.diff +3 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/insert_more.sql +5 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/multi_columns_config_1.yml +16 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/multi_columns_config_2.yml +17 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/multi_columns_expected_1.csv +4 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/multi_columns_expected_1.diff +3 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/multi_columns_expected_2.csv +2 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/multi_columns_expected_2.diff +3 -0
- data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/setup.sql +11 -0
- metadata +45 -4
- data/classpath/embulk-input-sqlserver-0.10.0.jar +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 04e9c70944217bbd26e88379fd303c5671420aa56a6dd514c690f0edd948ee14
|
4
|
+
data.tar.gz: d718ebd86e88a4d45d4982c744738aacb6296cfef8e3da45f42ef60261e42085
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dfc3d01c225d6b3a8658d0d7622883e5d0b417b5f44f681a442441808c247f253cd200795354aab7e3a02c984acbd12351ecb072947b64e4864411c360a80280
|
7
|
+
data.tar.gz: 5fdce20cab127d48be9fbb005ff913dc177d804aaf15632c2a0a14dd33df634962aa6a4163d274ba09e2da21f397761ba5aa619647f53453d35e733579a850e3
|
data/README.md
CHANGED
@@ -9,7 +9,8 @@ SQL Server input plugin for Embulk loads records from SQL Server.
|
|
9
9
|
|
10
10
|
## Configuration
|
11
11
|
|
12
|
-
- **driver_path**: path to the jar file of Microsoft SQL Server JDBC driver. If not set,
|
12
|
+
- **driver_path**: path to the jar file of Microsoft SQL Server JDBC driver. If not set, the bundled JDBC driver (Microsoft SQL Server JDBC driver 7.2.2) will be used. (string)
|
13
|
+
- **driver_type**: the current version of embulk-input-sqlserver will use Microsoft SQL Server JDBC driver in default, but version 0.10.0 or older will use jTDS driver in default. You can still use jTDS driver by setting this option to "jtds". (string, default: "mssql-jdbc")
|
13
14
|
- **host**: database host name (string, required if url is not set)
|
14
15
|
- **port**: database port number (integer, default: 1433)
|
15
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)
|
@@ -38,13 +39,14 @@ embulk "-J-Djava.library.path=C:\drivers" run input-sqlserver.yml
|
|
38
39
|
- **socket_timeout**: timeout for executing the query. 0 means no timeout. (integer (seconds), default: 1800)
|
39
40
|
- **options**: extra JDBC properties (hash, default: {})
|
40
41
|
- **incremental**: if true, enables incremental loading. See next section for details (boolean, default: false)
|
41
|
-
- **incremental_columns**: column names for incremental loading (array of strings, default: use primary keys)
|
42
|
+
- **incremental_columns**: column names for incremental loading (array of strings, default: use primary keys). Columns of integer types, string types and `datetime2` are supported.
|
42
43
|
- **last_record**: values of the last record for incremental loading (array of objects, default: load all records)
|
43
44
|
- **default_timezone**: If the sql type of a column is `date`/`time`/`datetime` and the embulk type is `string`, column values are formatted int this default_timezone. You can overwrite timezone for each columns using column_options option. (string, default: `UTC`)
|
44
45
|
- **default_column_options**: advanced: column_options for each JDBC type as default. key-value pairs where key is a JDBC type (e.g. 'DATE', 'BIGINT') and value is same as column_options's value.
|
45
46
|
- **column_options**: advanced: key-value pairs where key is a column name and value is options for the column.
|
46
47
|
- **value_type**: embulk get values from database as this value_type. Typically, the value_type determines `getXXX` method of `java.sql.PreparedStatement`.
|
47
48
|
(string, default: depends on the sql type of the column. Available values options are: `long`, `double`, `float`, `decimal`, `boolean`, `string`, `json`, `date`, `time`, `timestamp`)
|
49
|
+
NOTE: the default value_type for DATE, TIME and DATETIME2 is `string`, because jTDS driver, default JDBC driver for older embulk-input-sqlserver, returns Types.VARCHAR as JDBC type for these types.
|
48
50
|
- **type**: Column values are converted to this embulk type.
|
49
51
|
Available values options are: `boolean`, `long`, `double`, `string`, `json`, `timestamp`).
|
50
52
|
By default, the embulk type is determined according to the sql type of the column (or value_type if specified).
|
@@ -71,13 +73,13 @@ ORDER BY updated_at, id
|
|
71
73
|
|
72
74
|
When bulk data loading finishes successfully, it outputs `last_record: ` paramater as config-diff so that next execution uses it.
|
73
75
|
|
74
|
-
At the next execution, when `last_record: ` is also set, this plugin generates additional WHERE conditions to load records larger than the last record. For example, if `last_record: ["2017-01-01 00:32:12", 5291]` is set,
|
76
|
+
At the next execution, when `last_record: ` is also set, this plugin generates additional WHERE conditions to load records larger than the last record. For example, if `last_record: ["2017-01-01 00:32:12.4876590", 5291]` is set,
|
75
77
|
|
76
78
|
```
|
77
79
|
SELECT * FROM (
|
78
80
|
...original query is here...
|
79
81
|
)
|
80
|
-
WHERE updated_at > '2017-01-01 00:32:12' OR (updated_at = '2017-01-01 00:32:12' AND id > 5291)
|
82
|
+
WHERE updated_at > '2017-01-01 00:32:12.4876590' OR (updated_at = '2017-01-01 00:32:12.4876590' AND id > 5291)
|
81
83
|
ORDER BY updated_at, id
|
82
84
|
```
|
83
85
|
|
data/build.gradle
CHANGED
Binary file
|
Binary file
|
Binary file
|
@@ -33,6 +33,10 @@ public class SQLServerInputPlugin
|
|
33
33
|
@ConfigDefault("null")
|
34
34
|
public Optional<String> getDriverPath();
|
35
35
|
|
36
|
+
@Config("driver_type")
|
37
|
+
@ConfigDefault("\"mssql-jdbc\"")
|
38
|
+
public String getDriverType();
|
39
|
+
|
36
40
|
@Config("host")
|
37
41
|
@ConfigDefault("null")
|
38
42
|
public Optional<String> getHost();
|
@@ -113,26 +117,29 @@ public class SQLServerInputPlugin
|
|
113
117
|
SQLServerPluginTask sqlServerTask = (SQLServerPluginTask) task;
|
114
118
|
|
115
119
|
Driver driver;
|
116
|
-
boolean useJtdsDriver = false;
|
117
120
|
if (sqlServerTask.getDriverPath().isPresent()) {
|
118
121
|
addDriverJarToClasspath(sqlServerTask.getDriverPath().get());
|
122
|
+
}
|
123
|
+
|
124
|
+
boolean useJtdsDriver;
|
125
|
+
if (sqlServerTask.getDriverType().equalsIgnoreCase("mssql-jdbc")) {
|
126
|
+
useJtdsDriver = false;
|
119
127
|
try {
|
120
128
|
driver = (Driver) Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
|
121
129
|
}
|
122
130
|
catch (Exception e) {
|
123
|
-
throw new ConfigException("
|
131
|
+
throw new ConfigException("Can't load Microsoft SQLServerDriver from classpath", e);
|
124
132
|
}
|
125
|
-
}
|
126
|
-
|
127
|
-
// prefer Microsoft SQLServerDriver if it is in classpath
|
133
|
+
} else if (sqlServerTask.getDriverType().equalsIgnoreCase("jtds")) {
|
134
|
+
useJtdsDriver = true;
|
128
135
|
try {
|
129
|
-
driver = (Driver) Class.forName("
|
136
|
+
driver = (Driver) Class.forName("net.sourceforge.jtds.jdbc.Driver").newInstance();
|
130
137
|
}
|
131
|
-
catch (Exception
|
132
|
-
|
133
|
-
driver = new net.sourceforge.jtds.jdbc.Driver();
|
134
|
-
useJtdsDriver = true;
|
138
|
+
catch (Exception e) {
|
139
|
+
throw new ConfigException("Can't load jTDS Driver from classpath", e);
|
135
140
|
}
|
141
|
+
} else {
|
142
|
+
throw new ConfigException("Unknown driver_type : " + sqlServerTask.getDriverType());
|
136
143
|
}
|
137
144
|
|
138
145
|
UrlAndProperties urlAndProps = buildUrlAndProperties(sqlServerTask, useJtdsDriver);
|
@@ -141,18 +148,21 @@ public class SQLServerInputPlugin
|
|
141
148
|
props.putAll(sqlServerTask.getOptions());
|
142
149
|
logConnectionProperties(urlAndProps.getUrl(), props);
|
143
150
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
con
|
151
|
+
if (driver != null) {
|
152
|
+
Connection con = driver.connect(urlAndProps.getUrl(), props);
|
153
|
+
try {
|
154
|
+
SQLServerInputConnection c = new SQLServerInputConnection(con, sqlServerTask.getSchema().orNull(),
|
155
|
+
sqlServerTask.getTransactionIsolationLevel().orNull());
|
156
|
+
con = null;
|
157
|
+
return c;
|
158
|
+
}
|
159
|
+
finally {
|
160
|
+
if (con != null) {
|
161
|
+
con.close();
|
162
|
+
}
|
154
163
|
}
|
155
164
|
}
|
165
|
+
throw new ConfigException("Fail to create new connection");
|
156
166
|
}
|
157
167
|
|
158
168
|
@Override
|
@@ -166,7 +176,6 @@ public class SQLServerInputPlugin
|
|
166
176
|
Properties props = new Properties();
|
167
177
|
|
168
178
|
// common properties
|
169
|
-
|
170
179
|
if (sqlServerTask.getUser().isPresent()) {
|
171
180
|
props.setProperty("user", sqlServerTask.getUser().get());
|
172
181
|
}
|
@@ -185,6 +194,7 @@ public class SQLServerInputPlugin
|
|
185
194
|
else {
|
186
195
|
// SQLServerDriver properties
|
187
196
|
props.setProperty("loginTimeout", String.valueOf(sqlServerTask.getConnectTimeout())); // seconds
|
197
|
+
props.setProperty("socketTimeout", String.valueOf(sqlServerTask.getSocketTimeout() * 1000L)); // milliseconds
|
188
198
|
|
189
199
|
props.setProperty("applicationName", sqlServerTask.getApplicationName());
|
190
200
|
|
@@ -196,9 +206,8 @@ public class SQLServerInputPlugin
|
|
196
206
|
if (sqlServerTask.getUrl().isPresent()) {
|
197
207
|
if (sqlServerTask.getHost().isPresent()
|
198
208
|
|| sqlServerTask.getInstance().isPresent()
|
199
|
-
|| sqlServerTask.getDatabase().isPresent()
|
200
|
-
|
201
|
-
throw new ConfigException("'host', 'port', 'instance', 'database' and 'integratedSecurity' options are invalid if 'url' option is set.");
|
209
|
+
|| sqlServerTask.getDatabase().isPresent()) {
|
210
|
+
throw new ConfigException("'host', 'instance' and 'database' options are invalid if 'url' option is set.");
|
202
211
|
}
|
203
212
|
|
204
213
|
return new UrlAndProperties(sqlServerTask.getUrl().get(), props);
|
@@ -240,7 +249,7 @@ public class SQLServerInputPlugin
|
|
240
249
|
}
|
241
250
|
}
|
242
251
|
else {
|
243
|
-
// SQLServerDriver URL: host:port[;databaseName=] or host\instance[;databaseName=]
|
252
|
+
// SQLServerDriver URL: host:port[;databaseName=database] or host\instance[;databaseName=database]
|
244
253
|
// host\instance:port[;databaseName] is allowed but \instance will be ignored in this case.
|
245
254
|
if (sqlServerTask.getInstance().isPresent()) {
|
246
255
|
if (sqlServerTask.getPort() != DEFAULT_PORT) {
|
@@ -252,7 +261,7 @@ public class SQLServerInputPlugin
|
|
252
261
|
url = String.format(ENGLISH, "jdbc:sqlserver://%s:%d", sqlServerTask.getHost().get(), sqlServerTask.getPort());
|
253
262
|
}
|
254
263
|
|
255
|
-
// ;databaseName=
|
264
|
+
// ;databaseName=database
|
256
265
|
if (sqlServerTask.getDatabase().isPresent()) {
|
257
266
|
props.setProperty("databaseName", sqlServerTask.getDatabase().get());
|
258
267
|
}
|
@@ -263,6 +272,7 @@ public class SQLServerInputPlugin
|
|
263
272
|
throw new ConfigException("'user' options are invalid if 'integratedSecutiry' option is set.");
|
264
273
|
}
|
265
274
|
props.setProperty("integratedSecurity", "true");
|
275
|
+
props.setProperty("authenticationScheme", "JavaKerberos");
|
266
276
|
}
|
267
277
|
else {
|
268
278
|
if (!sqlServerTask.getUser().isPresent()) {
|
@@ -18,12 +18,22 @@ public class SQLServerColumnGetterFactory extends ColumnGetterFactory {
|
|
18
18
|
@Override
|
19
19
|
public ColumnGetter newColumnGetter(JdbcInputConnection con, AbstractJdbcInputPlugin.PluginTask task, JdbcColumn column, JdbcColumnOption option)
|
20
20
|
{
|
21
|
-
ColumnGetter getter = super.newColumnGetter(con, task, column, option);
|
22
21
|
switch (column.getTypeName()) {
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
case "date":
|
23
|
+
case "datetime2":
|
24
|
+
case "time":
|
25
|
+
case "sql_variant":
|
26
|
+
// DateTimeOffset is available only in MSSQL
|
27
|
+
case "datetimeoffset":
|
28
|
+
// because jTDS driver, default JDBC driver for older embulk-input-sqlserver, returns Types.VARCHAR as JDBC type for these types.
|
29
|
+
return new StringColumnGetter(to, getToType(option));
|
30
|
+
|
31
|
+
case "datetime":
|
32
|
+
ColumnGetter getter = super.newColumnGetter(con, task, column, option);
|
33
|
+
return new TimestampWithoutTimeZoneIncrementalHandler(getter);
|
34
|
+
|
35
|
+
default:
|
36
|
+
return super.newColumnGetter(con, task, column, option);
|
27
37
|
}
|
28
38
|
}
|
29
39
|
|
@@ -53,4 +53,13 @@ public class BasicTest
|
|
53
53
|
assertThat(readSortedFile(out1), is(readResource("test_expected.csv")));
|
54
54
|
assertThat(result1.getConfigDiff(), is((ConfigDiff) loadYamlResource(embulk, "test_expected.diff")));
|
55
55
|
}
|
56
|
+
|
57
|
+
@Test
|
58
|
+
public void testJTDS() throws Exception
|
59
|
+
{
|
60
|
+
Path out1 = embulk.createTempFile("csv");
|
61
|
+
TestingEmbulk.RunResult result1 = embulk.runInput(baseConfig.merge(loadYamlResource(embulk, "jtds_config.yml")), out1);
|
62
|
+
assertThat(readSortedFile(out1), is(readResource("test_expected.csv")));
|
63
|
+
assertThat(result1.getConfigDiff(), is((ConfigDiff) loadYamlResource(embulk, "test_expected.diff")));
|
64
|
+
}
|
56
65
|
}
|
@@ -0,0 +1,149 @@
|
|
1
|
+
package org.embulk.input.sqlserver;
|
2
|
+
|
3
|
+
import org.embulk.config.ConfigDiff;
|
4
|
+
import org.embulk.config.ConfigSource;
|
5
|
+
import org.embulk.input.SQLServerInputPlugin;
|
6
|
+
import org.embulk.spi.InputPlugin;
|
7
|
+
import org.embulk.test.EmbulkTests;
|
8
|
+
import org.embulk.test.TestingEmbulk;
|
9
|
+
import org.embulk.test.TestingEmbulk.RunResult;
|
10
|
+
import org.junit.Before;
|
11
|
+
import org.junit.Rule;
|
12
|
+
import org.junit.Test;
|
13
|
+
|
14
|
+
import java.nio.file.Path;
|
15
|
+
|
16
|
+
import static org.embulk.input.sqlserver.SQLServerTests.execute;
|
17
|
+
import static org.embulk.test.EmbulkTests.readSortedFile;
|
18
|
+
import static org.hamcrest.Matchers.is;
|
19
|
+
import static org.junit.Assert.assertThat;
|
20
|
+
|
21
|
+
public class IncrementalTest
|
22
|
+
{
|
23
|
+
private static final String BASIC_RESOURCE_PATH = "org/embulk/input/sqlserver/test/expect/incremental/";
|
24
|
+
|
25
|
+
private static ConfigSource loadYamlResource(TestingEmbulk embulk, String fileName)
|
26
|
+
{
|
27
|
+
return embulk.loadYamlResource(BASIC_RESOURCE_PATH + fileName);
|
28
|
+
}
|
29
|
+
|
30
|
+
private static String readResource(String fileName)
|
31
|
+
{
|
32
|
+
return EmbulkTests.readResource(BASIC_RESOURCE_PATH + fileName);
|
33
|
+
}
|
34
|
+
|
35
|
+
@Rule
|
36
|
+
public TestingEmbulk embulk = TestingEmbulk.builder()
|
37
|
+
.registerPlugin(InputPlugin.class, "sqlserver", SQLServerInputPlugin.class)
|
38
|
+
.build();
|
39
|
+
|
40
|
+
private ConfigSource baseConfig;
|
41
|
+
|
42
|
+
@Before
|
43
|
+
public void setup()
|
44
|
+
{
|
45
|
+
baseConfig = SQLServerTests.baseConfig();
|
46
|
+
}
|
47
|
+
|
48
|
+
@Test
|
49
|
+
public void testInt() throws Exception
|
50
|
+
{
|
51
|
+
// setup first rows
|
52
|
+
execute(readResource("int/setup.sql"));
|
53
|
+
|
54
|
+
Path out1 = embulk.createTempFile("csv");
|
55
|
+
RunResult result1 = embulk.runInput(baseConfig.merge(loadYamlResource(embulk, "int/config_1.yml")), out1);
|
56
|
+
assertThat(readSortedFile(out1), is(readResource("int/expected_1.csv")));
|
57
|
+
assertThat(result1.getConfigDiff(), is((ConfigDiff) loadYamlResource(embulk, "int/expected_1.diff")));
|
58
|
+
|
59
|
+
// insert more rows
|
60
|
+
execute(readResource("int/insert_more.sql"));
|
61
|
+
|
62
|
+
Path out2 = embulk.createTempFile("csv");
|
63
|
+
RunResult result2 = embulk.runInput(baseConfig.merge(loadYamlResource(embulk, "int/config_2.yml")), out2);
|
64
|
+
assertThat(readSortedFile(out2), is(readResource("int/expected_2.csv")));
|
65
|
+
assertThat(result2.getConfigDiff(), is((ConfigDiff) loadYamlResource(embulk, "int/expected_2.diff")));
|
66
|
+
}
|
67
|
+
|
68
|
+
@Test
|
69
|
+
public void testChar() throws Exception
|
70
|
+
{
|
71
|
+
// setup first rows
|
72
|
+
execute(readResource("char/setup.sql"));
|
73
|
+
|
74
|
+
Path out1 = embulk.createTempFile("csv");
|
75
|
+
RunResult result1 = embulk.runInput(baseConfig.merge(loadYamlResource(embulk, "char/config_1.yml")), out1);
|
76
|
+
assertThat(readSortedFile(out1), is(readResource("char/expected_1.csv")));
|
77
|
+
assertThat(result1.getConfigDiff(), is((ConfigDiff) loadYamlResource(embulk, "char/expected_1.diff")));
|
78
|
+
|
79
|
+
// insert more rows
|
80
|
+
execute(readResource("char/insert_more.sql"));
|
81
|
+
|
82
|
+
Path out2 = embulk.createTempFile("csv");
|
83
|
+
RunResult result2 = embulk.runInput(baseConfig.merge(loadYamlResource(embulk, "char/config_2.yml")), out2);
|
84
|
+
assertThat(readSortedFile(out2), is(readResource("char/expected_2.csv")));
|
85
|
+
assertThat(result2.getConfigDiff(), is((ConfigDiff) loadYamlResource(embulk, "char/expected_2.diff")));
|
86
|
+
}
|
87
|
+
|
88
|
+
@Test
|
89
|
+
public void testDateTime2() throws Exception
|
90
|
+
{
|
91
|
+
// setup first rows
|
92
|
+
execute(readResource("datetime2/setup.sql"));
|
93
|
+
|
94
|
+
Path out1 = embulk.createTempFile("csv");
|
95
|
+
RunResult result1 = embulk.runInput(baseConfig.merge(loadYamlResource(embulk, "datetime2/config_1.yml")), out1);
|
96
|
+
assertThat(readSortedFile(out1), is(readResource("datetime2/expected_1.csv")));
|
97
|
+
// SQL Server datetime2 type is mapped to StringColumnGetter, not to TimestampWithoutTimeZoneIncrementalHandler, for compatibility.
|
98
|
+
// So a timestamp value in JSON will be like 'yyyy-MM-dd HH:mm:ss.SSSSSSS', not like 'yyyy-MM-ddTHH:mm:ss.SSSSSS'.
|
99
|
+
assertThat(result1.getConfigDiff(), is((ConfigDiff) loadYamlResource(embulk, "datetime2/expected_1.diff")));
|
100
|
+
|
101
|
+
// insert more rows
|
102
|
+
execute(readResource("datetime2/insert_more.sql"));
|
103
|
+
|
104
|
+
Path out2 = embulk.createTempFile("csv");
|
105
|
+
RunResult result2 = embulk.runInput(baseConfig.merge(loadYamlResource(embulk, "datetime2/config_2.yml")), out2);
|
106
|
+
assertThat(readSortedFile(out2), is(readResource("datetime2/expected_2.csv")));
|
107
|
+
assertThat(result2.getConfigDiff(), is((ConfigDiff) loadYamlResource(embulk, "datetime2/expected_2.diff")));
|
108
|
+
}
|
109
|
+
|
110
|
+
@Test
|
111
|
+
public void testQueryWithPlaceholder() throws Exception
|
112
|
+
{
|
113
|
+
// setup first rows
|
114
|
+
execute(readResource("query/setup.sql"));
|
115
|
+
|
116
|
+
Path out1 = embulk.createTempFile("csv");
|
117
|
+
RunResult result1 = embulk.runInput(baseConfig.merge(loadYamlResource(embulk, "query/config_1.yml")), out1);
|
118
|
+
assertThat(readSortedFile(out1), is(readResource("query/expected_1.csv")));
|
119
|
+
assertThat(result1.getConfigDiff(), is((ConfigDiff) loadYamlResource(embulk, "query/expected_1.diff")));
|
120
|
+
|
121
|
+
// insert more rows
|
122
|
+
execute(readResource("query/insert_more.sql"));
|
123
|
+
|
124
|
+
Path out2 = embulk.createTempFile("csv");
|
125
|
+
RunResult result2 = embulk.runInput(baseConfig.merge(loadYamlResource(embulk, "query/config_2.yml")), out2);
|
126
|
+
assertThat(readSortedFile(out2), is(readResource("query/expected_2.csv")));
|
127
|
+
assertThat(result2.getConfigDiff(), is((ConfigDiff) loadYamlResource(embulk, "query/expected_2.diff")));
|
128
|
+
}
|
129
|
+
|
130
|
+
@Test
|
131
|
+
public void testQueryWithPlaceholderAndMultiColumns() throws Exception
|
132
|
+
{
|
133
|
+
// setup first rows
|
134
|
+
execute(readResource("query/setup.sql"));
|
135
|
+
|
136
|
+
Path out1 = embulk.createTempFile("csv");
|
137
|
+
RunResult result1 = embulk.runInput(baseConfig.merge(loadYamlResource(embulk, "query/multi_columns_config_1.yml")), out1);
|
138
|
+
assertThat(readSortedFile(out1), is(readResource("query/multi_columns_expected_1.csv")));
|
139
|
+
assertThat(result1.getConfigDiff(), is((ConfigDiff) loadYamlResource(embulk, "query/multi_columns_expected_1.diff")));
|
140
|
+
|
141
|
+
// insert more rows
|
142
|
+
execute(readResource("query/insert_more.sql"));
|
143
|
+
|
144
|
+
Path out2 = embulk.createTempFile("csv");
|
145
|
+
RunResult result2 = embulk.runInput(baseConfig.merge(loadYamlResource(embulk, "query/multi_columns_config_2.yml")), out2);
|
146
|
+
assertThat(readSortedFile(out2), is(readResource("query/multi_columns_expected_2.csv")));
|
147
|
+
assertThat(result2.getConfigDiff(), is((ConfigDiff) loadYamlResource(embulk, "query/multi_columns_expected_2.diff")));
|
148
|
+
}
|
149
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
DROP TABLE CHAR_LOAD
|
2
|
+
CREATE TABLE CHAR_LOAD (
|
3
|
+
NAME CHAR(2) NOT NULL,
|
4
|
+
NOTE TEXT
|
5
|
+
);
|
6
|
+
|
7
|
+
INSERT INTO CHAR_LOAD (NAME, NOTE) VALUES ('A3', 'first');
|
8
|
+
INSERT INTO CHAR_LOAD (NAME, NOTE) VALUES ('A4', 'first');
|
9
|
+
INSERT INTO CHAR_LOAD (NAME, NOTE) VALUES ('A2', 'first');
|
10
|
+
INSERT INTO CHAR_LOAD (NAME, NOTE) VALUES ('A1', 'first');
|
11
|
+
|
data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/datetime2/insert_more.sql
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
|
2
|
+
INSERT INTO DT_LOAD (TIME, NOTE) VALUES ('2016-11-02 04:00:00', 'more_skip');
|
3
|
+
INSERT INTO DT_LOAD (TIME, NOTE) VALUES ('2016-11-02 04:00:05.333000', 'more_skip');
|
4
|
+
INSERT INTO DT_LOAD (TIME, NOTE) VALUES ('2016-11-02 04:00:05.333003', 'more_skip');
|
5
|
+
INSERT INTO DT_LOAD (TIME, NOTE) VALUES ('2016-11-02 04:00:05.333004', 'more_load');
|
6
|
+
INSERT INTO DT_LOAD (TIME, NOTE) VALUES ('2016-11-02 04:00:06', 'more_load');
|
7
|
+
INSERT INTO DT_LOAD (TIME, NOTE) VALUES ('2016-11-02 04:00:06', 'more_load');
|
8
|
+
|
data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/datetime2/setup.sql
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
DROP TABLE DT_LOAD
|
2
|
+
CREATE TABLE DT_LOAD (
|
3
|
+
TIME DATETIME2 NOT NULL,
|
4
|
+
NOTE TEXT
|
5
|
+
);
|
6
|
+
|
7
|
+
INSERT INTO DT_LOAD (TIME, NOTE) VALUES ('2016-11-02 01:00:01', 'first');
|
8
|
+
INSERT INTO DT_LOAD (TIME, NOTE) VALUES ('2016-11-02 02:00:02', 'first');
|
9
|
+
INSERT INTO DT_LOAD (TIME, NOTE) VALUES ('2016-11-02 03:00:03', 'first');
|
10
|
+
INSERT INTO DT_LOAD (TIME, NOTE) VALUES ('2016-11-02 04:00:04', 'first');
|
11
|
+
INSERT INTO DT_LOAD (TIME, NOTE) VALUES ('2016-11-02 04:00:05.111001', 'first');
|
12
|
+
INSERT INTO DT_LOAD (TIME, NOTE) VALUES ('2016-11-02 04:00:05.222002', 'first');
|
13
|
+
INSERT INTO DT_LOAD (TIME, NOTE) VALUES ('2016-11-02 04:00:05.333003', 'first');
|
14
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
DROP TABLE INT_LOAD
|
2
|
+
CREATE TABLE INT_LOAD (
|
3
|
+
NUM INT NOT NULL,
|
4
|
+
NOTE TEXT
|
5
|
+
);
|
6
|
+
|
7
|
+
INSERT INTO INT_LOAD (NUM, NOTE) VALUES (3, 'first');
|
8
|
+
INSERT INTO INT_LOAD (NUM, NOTE) VALUES (4, 'first');
|
9
|
+
INSERT INTO INT_LOAD (NUM, NOTE) VALUES (2, 'first');
|
10
|
+
INSERT INTO INT_LOAD (NUM, NOTE) VALUES (1, 'first');
|
11
|
+
|
data/src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/insert_more.sql
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
|
2
|
+
INSERT INTO QUERY_LOAD (NUM, NUM2, NOTE) VALUES (0, 100, 'more_skip');
|
3
|
+
INSERT INTO QUERY_LOAD (NUM, NUM2, NOTE) VALUES (4, 104, 'more_skip');
|
4
|
+
INSERT INTO QUERY_LOAD (NUM, NUM2, NOTE) VALUES (9, 109, 'more_load');
|
5
|
+
INSERT INTO QUERY_LOAD (NUM, NUM2, NOTE) VALUES (5, 105, 'more_load');
|
@@ -0,0 +1,16 @@
|
|
1
|
+
last_record: [0,0]
|
2
|
+
incremental: true
|
3
|
+
incremental_columns: [NUM,NUM2]
|
4
|
+
use_raw_query_with_incremental: true
|
5
|
+
query: |
|
6
|
+
SELECT
|
7
|
+
*
|
8
|
+
FROM
|
9
|
+
QUERY_LOAD
|
10
|
+
WHERE
|
11
|
+
NUM IS NOT NULL
|
12
|
+
AND NUM > :NUM
|
13
|
+
OR (NUM = :NUM AND NUM2 > :NUM2)
|
14
|
+
ORDER BY
|
15
|
+
NUM ASC,
|
16
|
+
NUM2 ASC
|
@@ -0,0 +1,17 @@
|
|
1
|
+
last_record: [4,104]
|
2
|
+
incremental: true
|
3
|
+
incremental_columns: [NUM,NUM2]
|
4
|
+
use_raw_query_with_incremental: true
|
5
|
+
query: |
|
6
|
+
SELECT
|
7
|
+
*
|
8
|
+
FROM
|
9
|
+
QUERY_LOAD
|
10
|
+
WHERE
|
11
|
+
NUM IS NOT NULL
|
12
|
+
AND NUM > :NUM
|
13
|
+
AND NUM2 IS NOT NULL
|
14
|
+
OR (NUM = :NUM AND NUM2 > :NUM2)
|
15
|
+
ORDER BY
|
16
|
+
NUM ASC,
|
17
|
+
NUM2 ASC
|
@@ -0,0 +1,11 @@
|
|
1
|
+
DROP TABLE QUERY_LOAD
|
2
|
+
CREATE TABLE QUERY_LOAD (
|
3
|
+
NUM INT NOT NULL,
|
4
|
+
NUM2 INT NOT NULL,
|
5
|
+
NOTE TEXT
|
6
|
+
);
|
7
|
+
|
8
|
+
INSERT INTO QUERY_LOAD (NUM, NUM2, NOTE) VALUES (3, 103, 'first');
|
9
|
+
INSERT INTO QUERY_LOAD (NUM, NUM2, NOTE) VALUES (4, 104, 'first');
|
10
|
+
INSERT INTO QUERY_LOAD (NUM, NUM2, NOTE) VALUES (2, 102, 'first');
|
11
|
+
INSERT INTO QUERY_LOAD (NUM, NUM2, NOTE) VALUES (1, 101, 'first');
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: embulk-input-sqlserver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-09-06 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Selects records from a table.
|
14
14
|
email:
|
@@ -19,19 +19,60 @@ extra_rdoc_files: []
|
|
19
19
|
files:
|
20
20
|
- README.md
|
21
21
|
- build.gradle
|
22
|
-
- classpath/embulk-input-jdbc-0.10.
|
23
|
-
- classpath/embulk-input-sqlserver-0.10.
|
22
|
+
- classpath/embulk-input-jdbc-0.10.1.jar
|
23
|
+
- classpath/embulk-input-sqlserver-0.10.1.jar
|
24
24
|
- classpath/jtds-1.3.1.jar
|
25
|
+
- classpath/mssql-jdbc-7.2.2.jre8.jar
|
25
26
|
- lib/embulk/input/sqlserver.rb
|
26
27
|
- src/main/java/org/embulk/input/SQLServerInputPlugin.java
|
27
28
|
- src/main/java/org/embulk/input/sqlserver/SQLServerInputConnection.java
|
28
29
|
- src/main/java/org/embulk/input/sqlserver/getter/SQLServerColumnGetterFactory.java
|
29
30
|
- src/test/java/org/embulk/input/sqlserver/BasicTest.java
|
31
|
+
- src/test/java/org/embulk/input/sqlserver/IncrementalTest.java
|
30
32
|
- src/test/java/org/embulk/input/sqlserver/SQLServerTests.java
|
33
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/basic/jtds_config.yml
|
31
34
|
- src/test/resources/org/embulk/input/sqlserver/test/expect/basic/setup.sql
|
32
35
|
- src/test/resources/org/embulk/input/sqlserver/test/expect/basic/test_config.yml
|
33
36
|
- src/test/resources/org/embulk/input/sqlserver/test/expect/basic/test_expected.csv
|
34
37
|
- src/test/resources/org/embulk/input/sqlserver/test/expect/basic/test_expected.diff
|
38
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/char/config_1.yml
|
39
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/char/config_2.yml
|
40
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/char/expected_1.csv
|
41
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/char/expected_1.diff
|
42
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/char/expected_2.csv
|
43
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/char/expected_2.diff
|
44
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/char/insert_more.sql
|
45
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/char/setup.sql
|
46
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/datetime2/config_1.yml
|
47
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/datetime2/config_2.yml
|
48
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/datetime2/expected_1.csv
|
49
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/datetime2/expected_1.diff
|
50
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/datetime2/expected_2.csv
|
51
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/datetime2/expected_2.diff
|
52
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/datetime2/insert_more.sql
|
53
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/datetime2/setup.sql
|
54
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/int/config_1.yml
|
55
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/int/config_2.yml
|
56
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/int/expected_1.csv
|
57
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/int/expected_1.diff
|
58
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/int/expected_2.csv
|
59
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/int/expected_2.diff
|
60
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/int/insert_more.sql
|
61
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/int/setup.sql
|
62
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/config_1.yml
|
63
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/config_2.yml
|
64
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/expected_1.csv
|
65
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/expected_1.diff
|
66
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/expected_2.csv
|
67
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/expected_2.diff
|
68
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/insert_more.sql
|
69
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/multi_columns_config_1.yml
|
70
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/multi_columns_config_2.yml
|
71
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/multi_columns_expected_1.csv
|
72
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/multi_columns_expected_1.diff
|
73
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/multi_columns_expected_2.csv
|
74
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/multi_columns_expected_2.diff
|
75
|
+
- src/test/resources/org/embulk/input/sqlserver/test/expect/incremental/query/setup.sql
|
35
76
|
homepage: https://github.com/embulk/embulk-input-jdbc
|
36
77
|
licenses:
|
37
78
|
- Apache 2.0
|
Binary file
|