001: /*
002: * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
003: *
004: * Licensed under the Aduna BSD-style license.
005: */
006: package org.openrdf.sail.rdbms.mysql.alt;
007:
008: import java.io.BufferedOutputStream;
009: import java.io.File;
010: import java.io.FileOutputStream;
011: import java.io.IOException;
012: import java.io.OutputStream;
013: import java.io.OutputStreamWriter;
014: import java.nio.charset.Charset;
015: import java.sql.PreparedStatement;
016: import java.sql.SQLException;
017: import java.util.regex.Matcher;
018: import java.util.regex.Pattern;
019:
020: import org.apache.commons.dbcp.DelegatingConnection;
021: import org.apache.commons.dbcp.DelegatingPreparedStatement;
022: import org.apache.commons.dbcp.SQLNestedException;
023:
024: /**
025: *
026: * @author James Leigh
027: */
028: public class BatchInsertStatement extends DelegatingPreparedStatement {
029:
030: private static final int BUF_SIZE = 512 * 1024;
031:
032: public static String prepareSql(String table, String... columns) {
033: StringBuilder sb = new StringBuilder();
034: sb.append("LOAD DATA LOCAL INFILE ?");
035: sb.append("\nINTO TABLE ").append(table);
036: sb.append("\nCHARACTER SET utf8");
037: sb
038: .append("\nFIELDS TERMINATED BY ? ENCLOSED BY ? ESCAPED BY ?");
039: sb.append("\nLINES TERMINATED BY ? STARTING BY ?");
040: sb.append("\n(");
041: for (String column : columns) {
042: sb.append(column).append(',');
043: }
044: sb.setCharAt(sb.length() - 1, ')');
045: return sb.toString();
046: }
047:
048: private OutputStreamWriter writer;
049:
050: private Object[] record;
051:
052: private File file;
053:
054: private Pattern escape = Pattern.compile("([\\t\\n\\\\])");
055:
056: public BatchInsertStatement(PreparedStatement stmt, String table,
057: String... columns) throws SQLException {
058: super (new DelegatingConnection(stmt.getConnection()), stmt);
059: record = new Object[columns.length];
060: try {
061: file = File.createTempFile(table, ".mysql");
062: super .setString(1, file.getAbsolutePath());
063: super .setString(2, "\t");
064: super .setString(3, "");
065: super .setString(4, "\\");
066: super .setString(5, "\n");
067: super .setString(6, "");
068: OutputStream out = new BufferedOutputStream(
069: new FileOutputStream(file), BUF_SIZE);
070: writer = new OutputStreamWriter(out, Charset
071: .forName("UTF-8"));
072: } catch (IOException e) {
073: throw new SQLNestedException(e.toString(), e);
074: }
075: }
076:
077: @Override
078: public boolean isClosed() {
079: return super .isClosed();
080: }
081:
082: @Override
083: public void setObject(int idx, Object obj) throws SQLException {
084: record[idx - 1] = obj;
085: }
086:
087: @Override
088: public void addBatch() throws SQLException {
089: try {
090: for (int i = 0; i < record.length; i++) {
091: if (i > 0) {
092: writer.write('\t');
093: }
094: if (record[i] instanceof Number) {
095: writer.write(record[i].toString());
096: } else {
097: Matcher matcher = escape.matcher(record[i]
098: .toString());
099: writer.write(matcher.replaceAll("\\$1"));
100: }
101: }
102: writer.write('\n');
103: } catch (IOException e) {
104: throw new SQLNestedException(e.toString(), e);
105: }
106: }
107:
108: @Override
109: public int[] executeBatch() throws SQLException {
110: try {
111: writer.flush();
112: writer.close();
113: writer = null;
114: return new int[] { super .executeUpdate() };
115: } catch (IOException e) {
116: throw new SQLNestedException(e.toString(), e);
117: } finally {
118: file.delete();
119: file = null;
120: }
121: }
122:
123: @Override
124: protected void finalize() throws Throwable {
125: if (writer != null) {
126: writer.close();
127: }
128: if (file != null) {
129: file.delete();
130: }
131: }
132:
133: }
|