embulk-output-postgresql 0.4.0 → 0.4.1

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.
@@ -1,245 +1,245 @@
1
- package org.embulk.output.postgresql;
2
-
3
- import java.util.Calendar;
4
- import java.util.Locale;
5
- import java.io.File;
6
- import java.io.FileOutputStream;
7
- import java.io.Writer;
8
- import java.io.BufferedWriter;
9
- import java.io.OutputStreamWriter;
10
- import java.io.IOException;
11
- import java.nio.charset.Charset;
12
- import java.math.BigDecimal;
13
- import java.sql.Date;
14
- import java.sql.Time;
15
- import java.sql.SQLException;
16
- import org.embulk.spi.time.Timestamp;
17
- import org.embulk.output.jdbc.BatchInsert;
18
-
19
- public abstract class AbstractPostgreSQLCopyBatchInsert
20
- implements BatchInsert
21
- {
22
- protected static final Charset FILE_CHARSET = Charset.forName("UTF-8");
23
-
24
- protected static final String nullString = "\\N";
25
- protected static final String newLineString = "\n";
26
- protected static final String delimiterString = "\t";
27
-
28
- protected File currentFile;
29
- protected BufferedWriter writer;
30
- protected int index;
31
- protected int batchRows;
32
-
33
- protected AbstractPostgreSQLCopyBatchInsert() throws IOException
34
- {
35
- this.index = 0;
36
- openNewFile();
37
- }
38
-
39
- private File createTempFile() throws IOException
40
- {
41
- return File.createTempFile("embulk-output-postgres-copy-", ".tsv.tmp"); // TODO configurable temporary file path
42
- }
43
-
44
- protected File openNewFile() throws IOException
45
- {
46
- File newFile = createTempFile();
47
- File oldFile = closeCurrentFile();
48
- this.writer = openWriter(newFile);
49
- currentFile = newFile;
50
- return oldFile;
51
- }
52
-
53
- protected File closeCurrentFile() throws IOException
54
- {
55
- if(writer != null) {
56
- writer.close();
57
- writer = null;
58
- }
59
- return currentFile;
60
- }
61
-
62
- protected BufferedWriter openWriter(File newFile) throws IOException
63
- {
64
- return new BufferedWriter(new OutputStreamWriter(new FileOutputStream(newFile), FILE_CHARSET));
65
- }
66
-
67
- public int getBatchWeight()
68
- {
69
- long fsize = currentFile.length();
70
- if (fsize > Integer.MAX_VALUE) {
71
- return Integer.MAX_VALUE;
72
- } else {
73
- return (int) fsize;
74
- }
75
- }
76
-
77
- public void finish() throws IOException, SQLException
78
- {
79
- closeCurrentFile(); // this is necessary to make getBatchWeight() work
80
- if (getBatchWeight() != 0) {
81
- flush();
82
- }
83
- }
84
-
85
- public void add() throws IOException
86
- {
87
- writer.write(newLineString);
88
- batchRows++;
89
- index = 0;
90
- }
91
-
92
- private void appendDelimiter() throws IOException
93
- {
94
- if(index != 0) {
95
- writer.write(delimiterString);
96
- }
97
- index++;
98
- }
99
-
100
- public void setNull(int sqlType) throws IOException
101
- {
102
- appendDelimiter();
103
- writer.write(nullString);
104
- }
105
-
106
- public void setBoolean(boolean v) throws IOException
107
- {
108
- appendDelimiter();
109
- writer.write(String.valueOf(v));
110
- }
111
-
112
- public void setByte(byte v) throws IOException
113
- {
114
- appendDelimiter();
115
- setEscapedString(String.valueOf(v));
116
- }
117
-
118
- public void setShort(short v) throws IOException
119
- {
120
- appendDelimiter();
121
- writer.write(String.valueOf(v));
122
- }
123
-
124
- public void setInt(int v) throws IOException
125
- {
126
- appendDelimiter();
127
- writer.write(String.valueOf(v));
128
- }
129
-
130
- public void setLong(long v) throws IOException
131
- {
132
- appendDelimiter();
133
- writer.write(String.valueOf(v));
134
- }
135
-
136
- public void setFloat(float v) throws IOException
137
- {
138
- appendDelimiter();
139
- writer.write(String.valueOf(v));
140
- }
141
-
142
- public void setDouble(double v) throws IOException
143
- {
144
- appendDelimiter();
145
- writer.write(String.valueOf(v));
146
- }
147
-
148
- public void setBigDecimal(BigDecimal v) throws IOException
149
- {
150
- appendDelimiter();
151
- writer.write(String.valueOf(v));
152
- }
153
-
154
- public void setString(String v) throws IOException
155
- {
156
- appendDelimiter();
157
- setEscapedString(v);
158
- }
159
-
160
- public void setNString(String v) throws IOException
161
- {
162
- appendDelimiter();
163
- setEscapedString(v);
164
- }
165
-
166
- public void setBytes(byte[] v) throws IOException
167
- {
168
- appendDelimiter();
169
- setEscapedString(String.valueOf(v));
170
- }
171
-
172
- public void setSqlDate(Timestamp v, Calendar cal) throws IOException
173
- {
174
- appendDelimiter();
175
- cal.setTimeInMillis(v.getEpochSecond() * 1000);
176
- String f = String.format(Locale.ENGLISH, "%02d-%02d-%02d",
177
- cal.get(Calendar.YEAR),
178
- cal.get(Calendar.MONTH) + 1,
179
- cal.get(Calendar.DAY_OF_MONTH));
180
- writer.write(f);
181
- }
182
-
183
- public void setSqlTime(Timestamp v, Calendar cal) throws IOException
184
- {
185
- appendDelimiter();
186
- cal.setTimeInMillis(v.getEpochSecond() * 1000);
187
- String f = String.format(Locale.ENGLISH, "%02d:%02d:%02d.%06d",
188
- cal.get(Calendar.HOUR_OF_DAY),
189
- cal.get(Calendar.MINUTE),
190
- cal.get(Calendar.SECOND),
191
- v.getNano() / 1000);
192
- writer.write(f);
193
- }
194
-
195
- public void setSqlTimestamp(Timestamp v, Calendar cal) throws IOException
196
- {
197
- appendDelimiter();
198
- cal.setTimeInMillis(v.getEpochSecond() * 1000);
199
- int zoneOffset = cal.get(Calendar.ZONE_OFFSET) / 1000 / 60; // zone offset considering DST in minute
200
- String offset;
201
- if (zoneOffset >= 0) {
202
- offset = String.format(Locale.ENGLISH, "+%02d%02d", zoneOffset / 60, zoneOffset % 60);
203
- } else {
204
- offset = String.format(Locale.ENGLISH, "-%02d%02d", -zoneOffset / 60, -zoneOffset % 60);
205
- }
206
- String f = String.format(Locale.ENGLISH, "%d-%02d-%02d %02d:%02d:%02d.%06d%s",
207
- cal.get(Calendar.YEAR),
208
- cal.get(Calendar.MONTH) + 1,
209
- cal.get(Calendar.DAY_OF_MONTH),
210
- cal.get(Calendar.HOUR_OF_DAY),
211
- cal.get(Calendar.MINUTE),
212
- cal.get(Calendar.SECOND),
213
- v.getNano() / 1000,
214
- offset);
215
- writer.write(f);
216
- }
217
-
218
- // Escape \, \n, \t, \r
219
- // Remove \0
220
- private void setEscapedString(String v) throws IOException{
221
- for (char c : v.toCharArray()) {
222
- String s;
223
- switch (c) {
224
- case '\\':
225
- s = "\\\\";
226
- break;
227
- case '\n':
228
- s = "\\n";
229
- break;
230
- case '\t':
231
- s = "\\t";
232
- break;
233
- case '\r':
234
- s = "\\r";
235
- break;
236
- case 0:
237
- s = "";
238
- break;
239
- default:
240
- s = String.valueOf(c);
241
- }
242
- writer.write(s);
243
- }
244
- }
245
- }
1
+ package org.embulk.output.postgresql;
2
+
3
+ import java.util.Calendar;
4
+ import java.util.Locale;
5
+ import java.io.File;
6
+ import java.io.FileOutputStream;
7
+ import java.io.Writer;
8
+ import java.io.BufferedWriter;
9
+ import java.io.OutputStreamWriter;
10
+ import java.io.IOException;
11
+ import java.nio.charset.Charset;
12
+ import java.math.BigDecimal;
13
+ import java.sql.Date;
14
+ import java.sql.Time;
15
+ import java.sql.SQLException;
16
+ import org.embulk.spi.time.Timestamp;
17
+ import org.embulk.output.jdbc.BatchInsert;
18
+
19
+ public abstract class AbstractPostgreSQLCopyBatchInsert
20
+ implements BatchInsert
21
+ {
22
+ protected static final Charset FILE_CHARSET = Charset.forName("UTF-8");
23
+
24
+ protected static final String nullString = "\\N";
25
+ protected static final String newLineString = "\n";
26
+ protected static final String delimiterString = "\t";
27
+
28
+ protected File currentFile;
29
+ protected BufferedWriter writer;
30
+ protected int index;
31
+ protected int batchRows;
32
+
33
+ protected AbstractPostgreSQLCopyBatchInsert() throws IOException
34
+ {
35
+ this.index = 0;
36
+ openNewFile();
37
+ }
38
+
39
+ private File createTempFile() throws IOException
40
+ {
41
+ return File.createTempFile("embulk-output-postgres-copy-", ".tsv.tmp"); // TODO configurable temporary file path
42
+ }
43
+
44
+ protected File openNewFile() throws IOException
45
+ {
46
+ File newFile = createTempFile();
47
+ File oldFile = closeCurrentFile();
48
+ this.writer = openWriter(newFile);
49
+ currentFile = newFile;
50
+ return oldFile;
51
+ }
52
+
53
+ protected File closeCurrentFile() throws IOException
54
+ {
55
+ if(writer != null) {
56
+ writer.close();
57
+ writer = null;
58
+ }
59
+ return currentFile;
60
+ }
61
+
62
+ protected BufferedWriter openWriter(File newFile) throws IOException
63
+ {
64
+ return new BufferedWriter(new OutputStreamWriter(new FileOutputStream(newFile), FILE_CHARSET));
65
+ }
66
+
67
+ public int getBatchWeight()
68
+ {
69
+ long fsize = currentFile.length();
70
+ if (fsize > Integer.MAX_VALUE) {
71
+ return Integer.MAX_VALUE;
72
+ } else {
73
+ return (int) fsize;
74
+ }
75
+ }
76
+
77
+ public void finish() throws IOException, SQLException
78
+ {
79
+ closeCurrentFile(); // this is necessary to make getBatchWeight() work
80
+ if (getBatchWeight() != 0) {
81
+ flush();
82
+ }
83
+ }
84
+
85
+ public void add() throws IOException
86
+ {
87
+ writer.write(newLineString);
88
+ batchRows++;
89
+ index = 0;
90
+ }
91
+
92
+ private void appendDelimiter() throws IOException
93
+ {
94
+ if(index != 0) {
95
+ writer.write(delimiterString);
96
+ }
97
+ index++;
98
+ }
99
+
100
+ public void setNull(int sqlType) throws IOException
101
+ {
102
+ appendDelimiter();
103
+ writer.write(nullString);
104
+ }
105
+
106
+ public void setBoolean(boolean v) throws IOException
107
+ {
108
+ appendDelimiter();
109
+ writer.write(String.valueOf(v));
110
+ }
111
+
112
+ public void setByte(byte v) throws IOException
113
+ {
114
+ appendDelimiter();
115
+ setEscapedString(String.valueOf(v));
116
+ }
117
+
118
+ public void setShort(short v) throws IOException
119
+ {
120
+ appendDelimiter();
121
+ writer.write(String.valueOf(v));
122
+ }
123
+
124
+ public void setInt(int v) throws IOException
125
+ {
126
+ appendDelimiter();
127
+ writer.write(String.valueOf(v));
128
+ }
129
+
130
+ public void setLong(long v) throws IOException
131
+ {
132
+ appendDelimiter();
133
+ writer.write(String.valueOf(v));
134
+ }
135
+
136
+ public void setFloat(float v) throws IOException
137
+ {
138
+ appendDelimiter();
139
+ writer.write(String.valueOf(v));
140
+ }
141
+
142
+ public void setDouble(double v) throws IOException
143
+ {
144
+ appendDelimiter();
145
+ writer.write(String.valueOf(v));
146
+ }
147
+
148
+ public void setBigDecimal(BigDecimal v) throws IOException
149
+ {
150
+ appendDelimiter();
151
+ writer.write(String.valueOf(v));
152
+ }
153
+
154
+ public void setString(String v) throws IOException
155
+ {
156
+ appendDelimiter();
157
+ setEscapedString(v);
158
+ }
159
+
160
+ public void setNString(String v) throws IOException
161
+ {
162
+ appendDelimiter();
163
+ setEscapedString(v);
164
+ }
165
+
166
+ public void setBytes(byte[] v) throws IOException
167
+ {
168
+ appendDelimiter();
169
+ setEscapedString(String.valueOf(v));
170
+ }
171
+
172
+ public void setSqlDate(Timestamp v, Calendar cal) throws IOException
173
+ {
174
+ appendDelimiter();
175
+ cal.setTimeInMillis(v.getEpochSecond() * 1000);
176
+ String f = String.format(Locale.ENGLISH, "%02d-%02d-%02d",
177
+ cal.get(Calendar.YEAR),
178
+ cal.get(Calendar.MONTH) + 1,
179
+ cal.get(Calendar.DAY_OF_MONTH));
180
+ writer.write(f);
181
+ }
182
+
183
+ public void setSqlTime(Timestamp v, Calendar cal) throws IOException
184
+ {
185
+ appendDelimiter();
186
+ cal.setTimeInMillis(v.getEpochSecond() * 1000);
187
+ String f = String.format(Locale.ENGLISH, "%02d:%02d:%02d.%06d",
188
+ cal.get(Calendar.HOUR_OF_DAY),
189
+ cal.get(Calendar.MINUTE),
190
+ cal.get(Calendar.SECOND),
191
+ v.getNano() / 1000);
192
+ writer.write(f);
193
+ }
194
+
195
+ public void setSqlTimestamp(Timestamp v, Calendar cal) throws IOException
196
+ {
197
+ appendDelimiter();
198
+ cal.setTimeInMillis(v.getEpochSecond() * 1000);
199
+ int zoneOffset = cal.get(Calendar.ZONE_OFFSET) / 1000 / 60; // zone offset considering DST in minute
200
+ String offset;
201
+ if (zoneOffset >= 0) {
202
+ offset = String.format(Locale.ENGLISH, "+%02d%02d", zoneOffset / 60, zoneOffset % 60);
203
+ } else {
204
+ offset = String.format(Locale.ENGLISH, "-%02d%02d", -zoneOffset / 60, -zoneOffset % 60);
205
+ }
206
+ String f = String.format(Locale.ENGLISH, "%d-%02d-%02d %02d:%02d:%02d.%06d%s",
207
+ cal.get(Calendar.YEAR),
208
+ cal.get(Calendar.MONTH) + 1,
209
+ cal.get(Calendar.DAY_OF_MONTH),
210
+ cal.get(Calendar.HOUR_OF_DAY),
211
+ cal.get(Calendar.MINUTE),
212
+ cal.get(Calendar.SECOND),
213
+ v.getNano() / 1000,
214
+ offset);
215
+ writer.write(f);
216
+ }
217
+
218
+ // Escape \, \n, \t, \r
219
+ // Remove \0
220
+ private void setEscapedString(String v) throws IOException{
221
+ for (char c : v.toCharArray()) {
222
+ String s;
223
+ switch (c) {
224
+ case '\\':
225
+ s = "\\\\";
226
+ break;
227
+ case '\n':
228
+ s = "\\n";
229
+ break;
230
+ case '\t':
231
+ s = "\\t";
232
+ break;
233
+ case '\r':
234
+ s = "\\r";
235
+ break;
236
+ case 0:
237
+ s = "";
238
+ break;
239
+ default:
240
+ s = String.valueOf(c);
241
+ }
242
+ writer.write(s);
243
+ }
244
+ }
245
+ }
@@ -1,73 +1,73 @@
1
- package org.embulk.output.postgresql;
2
-
3
- import java.io.File;
4
- import java.io.IOException;
5
- import java.io.FileInputStream;
6
- import java.sql.Connection;
7
- import java.sql.SQLException;
8
- import org.slf4j.Logger;
9
- import org.postgresql.copy.CopyManager;
10
- import org.postgresql.core.BaseConnection;
11
- import org.embulk.spi.Exec;
12
- import org.embulk.output.jdbc.JdbcSchema;
13
-
14
- public class PostgreSQLCopyBatchInsert
15
- extends AbstractPostgreSQLCopyBatchInsert
16
- {
17
- private final Logger logger = Exec.getLogger(PostgreSQLCopyBatchInsert.class);
18
- private final PostgreSQLOutputConnector connector;
19
-
20
- private PostgreSQLOutputConnection connection = null;
21
- private CopyManager copyManager = null;
22
- private String copySql = null;
23
- private long totalRows;
24
-
25
- public PostgreSQLCopyBatchInsert(PostgreSQLOutputConnector connector) throws IOException, SQLException
26
- {
27
- super();
28
- this.connector = connector;
29
- }
30
-
31
- @Override
32
- public void prepare(String loadTable, JdbcSchema insertSchema) throws SQLException
33
- {
34
- this.connection = connector.connect(true);
35
- this.copySql = connection.buildCopySql(loadTable, insertSchema);
36
- this.copyManager = connection.newCopyManager();
37
- logger.info("Copy SQL: "+copySql);
38
- }
39
-
40
- @Override
41
- public void flush() throws IOException, SQLException
42
- {
43
- File file = closeCurrentFile(); // flush buffered data in writer
44
-
45
- logger.info(String.format("Loading %,d rows (%,d bytes)", batchRows, file.length()));
46
- long startTime = System.currentTimeMillis();
47
- FileInputStream in = new FileInputStream(file);
48
- try {
49
- // TODO check age of connection and call isValid if it's old and reconnect if it's invalid
50
- copyManager.copyIn(copySql, in);
51
- } finally {
52
- in.close();
53
- }
54
- double seconds = (System.currentTimeMillis() - startTime) / 1000.0;
55
-
56
- totalRows += batchRows;
57
- batchRows = 0;
58
- logger.info(String.format("> %.2f seconds (loaded %,d rows in total)", seconds, totalRows));
59
-
60
- openNewFile();
61
- file.delete();
62
- }
63
-
64
- @Override
65
- public void close() throws IOException, SQLException
66
- {
67
- closeCurrentFile().delete();
68
- if (connection != null) {
69
- connection.close();
70
- connection = null;
71
- }
72
- }
73
- }
1
+ package org.embulk.output.postgresql;
2
+
3
+ import java.io.File;
4
+ import java.io.IOException;
5
+ import java.io.FileInputStream;
6
+ import java.sql.Connection;
7
+ import java.sql.SQLException;
8
+ import org.slf4j.Logger;
9
+ import org.postgresql.copy.CopyManager;
10
+ import org.postgresql.core.BaseConnection;
11
+ import org.embulk.spi.Exec;
12
+ import org.embulk.output.jdbc.JdbcSchema;
13
+
14
+ public class PostgreSQLCopyBatchInsert
15
+ extends AbstractPostgreSQLCopyBatchInsert
16
+ {
17
+ private final Logger logger = Exec.getLogger(PostgreSQLCopyBatchInsert.class);
18
+ private final PostgreSQLOutputConnector connector;
19
+
20
+ private PostgreSQLOutputConnection connection = null;
21
+ private CopyManager copyManager = null;
22
+ private String copySql = null;
23
+ private long totalRows;
24
+
25
+ public PostgreSQLCopyBatchInsert(PostgreSQLOutputConnector connector) throws IOException, SQLException
26
+ {
27
+ super();
28
+ this.connector = connector;
29
+ }
30
+
31
+ @Override
32
+ public void prepare(String loadTable, JdbcSchema insertSchema) throws SQLException
33
+ {
34
+ this.connection = connector.connect(true);
35
+ this.copySql = connection.buildCopySql(loadTable, insertSchema);
36
+ this.copyManager = connection.newCopyManager();
37
+ logger.info("Copy SQL: "+copySql);
38
+ }
39
+
40
+ @Override
41
+ public void flush() throws IOException, SQLException
42
+ {
43
+ File file = closeCurrentFile(); // flush buffered data in writer
44
+
45
+ logger.info(String.format("Loading %,d rows (%,d bytes)", batchRows, file.length()));
46
+ long startTime = System.currentTimeMillis();
47
+ FileInputStream in = new FileInputStream(file);
48
+ try {
49
+ // TODO check age of connection and call isValid if it's old and reconnect if it's invalid
50
+ copyManager.copyIn(copySql, in);
51
+ } finally {
52
+ in.close();
53
+ }
54
+ double seconds = (System.currentTimeMillis() - startTime) / 1000.0;
55
+
56
+ totalRows += batchRows;
57
+ batchRows = 0;
58
+ logger.info(String.format("> %.2f seconds (loaded %,d rows in total)", seconds, totalRows));
59
+
60
+ openNewFile();
61
+ file.delete();
62
+ }
63
+
64
+ @Override
65
+ public void close() throws IOException, SQLException
66
+ {
67
+ closeCurrentFile().delete();
68
+ if (connection != null) {
69
+ connection.close();
70
+ connection = null;
71
+ }
72
+ }
73
+ }