diff options
author | Eike Stepper | 2013-05-19 14:46:25 +0000 |
---|---|---|
committer | Eike Stepper | 2013-05-19 14:46:25 +0000 |
commit | 24770a2a8333d5e18df024f1bbc851430b0e9734 (patch) | |
tree | 463f2a706e9804aafeef6ce8bd8d6435eae92be6 | |
parent | 3d9da56810c62e5fe04dd7d9ee6f00cce68065fe (diff) | |
download | cdo-24770a2a8333d5e18df024f1bbc851430b0e9734.tar.gz cdo-24770a2a8333d5e18df024f1bbc851430b0e9734.tar.xz cdo-24770a2a8333d5e18df024f1bbc851430b0e9734.zip |
[323006] [DB] Various PostgreSQL test failures
https://bugs.eclipse.org/bugs/show_bug.cgi?id=323006
14 files changed, 397 insertions, 331 deletions
diff --git a/plugins/org.eclipse.emf.cdo.examples.installer/examples/org.eclipse.emf.cdo.examples.master/config/cdo-server.xml b/plugins/org.eclipse.emf.cdo.examples.installer/examples/org.eclipse.emf.cdo.examples.master/config/cdo-server.xml index 5f6e00524e..c76d89e9f1 100644 --- a/plugins/org.eclipse.emf.cdo.examples.installer/examples/org.eclipse.emf.cdo.examples.master/config/cdo-server.xml +++ b/plugins/org.eclipse.emf.cdo.examples.installer/examples/org.eclipse.emf.cdo.examples.master/config/cdo-server.xml @@ -96,8 +96,8 @@ serverName="localhost" portNumber="5432" databaseName="repo1" - user="cdo" - password="cdo"/> + user="postgres" + password="postgres"/> --> <!-- Example: diff --git a/plugins/org.eclipse.emf.cdo.examples.master/config/cdo-server.xml b/plugins/org.eclipse.emf.cdo.examples.master/config/cdo-server.xml index 5f6e00524e..c76d89e9f1 100644 --- a/plugins/org.eclipse.emf.cdo.examples.master/config/cdo-server.xml +++ b/plugins/org.eclipse.emf.cdo.examples.master/config/cdo-server.xml @@ -96,8 +96,8 @@ serverName="localhost" portNumber="5432" databaseName="repo1" - user="cdo" - password="cdo"/> + user="postgres" + password="postgres"/> --> <!-- Example: diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java index d1bbe8ddec..9dc67a301a 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java @@ -92,8 +92,6 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; -import java.sql.Blob; -import java.sql.Clob; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -396,17 +394,15 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor, resultSet.next(); long size = resultSet.getLong(1); - Blob blob = resultSet.getBlob(2); + InputStream inputStream = resultSet.getBinaryStream(2); if (resultSet.wasNull()) { - Clob clob = resultSet.getClob(3); - Reader in = clob.getCharacterStream(); - IOUtil.copyCharacter(in, new OutputStreamWriter(out), size); + Reader reader = resultSet.getCharacterStream(3); + IOUtil.copyCharacter(reader, new OutputStreamWriter(out), size); } else { - InputStream in = blob.getBinaryStream(); - IOUtil.copyBinary(in, out, size); + IOUtil.copyBinary(inputStream, out, size); } } catch (SQLException ex) @@ -432,17 +428,16 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor, { byte[] id = HexUtil.hexToBytes(resultSet.getString(1)); long size = resultSet.getLong(2); - Blob blob = resultSet.getBlob(3); + InputStream inputStream = resultSet.getBinaryStream(3); if (resultSet.wasNull()) { - Clob clob = resultSet.getClob(4); - Reader in = clob.getCharacterStream(); + Reader reader = resultSet.getCharacterStream(4); Writer out = handler.handleClob(id, size); if (out != null) { try { - IOUtil.copyCharacter(in, out, size); + IOUtil.copyCharacter(reader, out, size); } finally { @@ -452,13 +447,12 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor, } else { - InputStream in = blob.getBinaryStream(); OutputStream out = handler.handleBlob(id, size); if (out != null) { try { - IOUtil.copyBinary(in, out, size); + IOUtil.copyBinary(inputStream, out, size); } finally { diff --git a/plugins/org.eclipse.emf.cdo.server.product/config/cdo-server.xml b/plugins/org.eclipse.emf.cdo.server.product/config/cdo-server.xml index 1ce1bdabb8..652ae84cbe 100644 --- a/plugins/org.eclipse.emf.cdo.server.product/config/cdo-server.xml +++ b/plugins/org.eclipse.emf.cdo.server.product/config/cdo-server.xml @@ -96,8 +96,8 @@ serverName="localhost" portNumber="5432" databaseName="repo1" - user="cdo" - password="cdo"/> + user="postgres" + password="postgres"/> --> <!-- Example: diff --git a/plugins/org.eclipse.emf.cdo.tests.db/CDO AllTests (PostgreSQL non-audit).launch b/plugins/org.eclipse.emf.cdo.tests.db/CDO AllTests (PostgreSQL ALL).launch index d624f94450..d624f94450 100644 --- a/plugins/org.eclipse.emf.cdo.tests.db/CDO AllTests (PostgreSQL non-audit).launch +++ b/plugins/org.eclipse.emf.cdo.tests.db/CDO AllTests (PostgreSQL ALL).launch diff --git a/plugins/org.eclipse.emf.cdo.tests.db/build.properties b/plugins/org.eclipse.emf.cdo.tests.db/build.properties index d017d59937..41e5bee44e 100644 --- a/plugins/org.eclipse.emf.cdo.tests.db/build.properties +++ b/plugins/org.eclipse.emf.cdo.tests.db/build.properties @@ -27,7 +27,7 @@ src.includes = about.html,\ CDO AllTests (Hsqldb audit).launch,\ CDO AllTests (Hsqldb non-audit).launch,\ CDO AllTests (Mysql).launch,\ - CDO AllTests (PostgreSQL non-audit).launch,\ + CDO AllTests (PostgreSQL ALL).launch,\ CDO AllTests (DBStore).launch,\ CDO AllTests (H2 ALL).launch,\ CDO AllTests (H2 UUIDs).launch,\ diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBPsql.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBPsql.java index 0caf84da70..00abaf36b5 100644 --- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBPsql.java +++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/AllTestsDBPsql.java @@ -38,5 +38,7 @@ public class AllTestsDBPsql extends DBConfigs protected void initConfigSuites(TestSuite parent) { addScenario(parent, COMBINED, new PostgresqlConfig(false, false, IDGenerationLocation.STORE), JVM, NATIVE); + addScenario(parent, COMBINED, new PostgresqlConfig(true, false, IDGenerationLocation.STORE), JVM, NATIVE); + addScenario(parent, COMBINED, new PostgresqlConfig(true, true, IDGenerationLocation.STORE), JVM, NATIVE); } } diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/Net4jDBTest.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/Net4jDBTest.java index 1fa09f86ef..cdc06bbc14 100644 --- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/Net4jDBTest.java +++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/Net4jDBTest.java @@ -21,6 +21,7 @@ import org.eclipse.net4j.db.ddl.IDBTable; import org.eclipse.net4j.util.collection.Pair; import org.eclipse.net4j.util.io.ExtendedDataInputStream; import org.eclipse.net4j.util.io.ExtendedDataOutputStream; +import org.eclipse.net4j.util.io.ExtendedIOUtil; import org.eclipse.net4j.util.io.IOUtil; import java.io.ByteArrayInputStream; @@ -46,19 +47,12 @@ public class Net4jDBTest extends AbstractCDOTest { private static final String FIELD_NAME = "testField"; - private ArrayList<Pair<DBType, Object>> columns = new ArrayList<Pair<DBType, Object>>(); - - private DBStore store; - - private Connection connection; + private transient ArrayList<Pair<DBType, Object>> columns = new ArrayList<Pair<DBType, Object>>(); @Override protected void doTearDown() throws Exception { columns.clear(); - columns = null; - store = null; - connection = null; super.doTearDown(); } @@ -158,7 +152,7 @@ public class Net4jDBTest extends AbstractCDOTest { registerColumn(DBType.CLOB, "Test"); - StringBuffer b = new StringBuffer(); + StringBuilder b = new StringBuilder(); for (int i = 0; i < 1000000; i++) { b.append("x"); @@ -336,13 +330,31 @@ public class Net4jDBTest extends AbstractCDOTest doTest(getName()); } - private void registerColumn(DBType type, Object value) + private void registerColumn(DBType type, Object value) throws IOException { + testIOSymmetry(type, value); + Pair<DBType, Object> column = Pair.create(type, value); columns.add(column); } - private void prepareTable(final String tableName) + private void testIOSymmetry(DBType type, Object value) throws IOException + { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + ExtendedDataOutputStream outs = new ExtendedDataOutputStream(output); + writeTypeValue(outs, type, value); + outs.close(); + output.flush(); + byte[] buffer = output.toByteArray(); + output.close(); + + ByteArrayInputStream input = new ByteArrayInputStream(buffer); + ExtendedDataInputStream ins = new ExtendedDataInputStream(input); + Object actualValue = readTypeValue(ins, type); + assertEquals(value, actualValue, type, -1); + } + + private void prepareTable(DBStore store, final String tableName) { IDBDatabase database = store.getDatabase(); database.updateSchema(new IDBDatabase.RunnableWithSchema() @@ -371,7 +383,7 @@ public class Net4jDBTest extends AbstractCDOTest }); } - private void writeValues(String tableName) throws Exception + private void writeValues(Connection connection, String tableName) throws Exception { ByteArrayOutputStream output = new ByteArrayOutputStream(); ExtendedDataOutputStream outs = new ExtendedDataOutputStream(output); @@ -418,7 +430,7 @@ public class Net4jDBTest extends AbstractCDOTest input.close(); } - private void checkValues(String tableName) throws Exception + private void checkValues(Connection connection, String tableName) throws Exception { Statement stmt = connection.createStatement(); ResultSet resultSet = stmt.executeQuery("SELECT * FROM " + tableName); @@ -430,7 +442,8 @@ public class Net4jDBTest extends AbstractCDOTest int c = 1; for (Pair<DBType, Object> column : columns) { - column.getElement1().writeValue(outs, resultSet, c++, false); + DBType dbType = column.getElement1(); + dbType.writeValue(outs, resultSet, c++, false); } resultSet.close(); @@ -451,50 +464,53 @@ public class Net4jDBTest extends AbstractCDOTest Object expected = column.getElement2(); Object actual = readTypeValue(ins, dbType); - Class<? extends Object> type = expected.getClass(); - if (type.isArray()) + assertEquals(expected, actual, dbType, c++); + } + } + + private void assertEquals(Object expected, Object actual, DBType dbType, int c) + { + Class<? extends Object> type = expected.getClass(); + if (type.isArray()) + { + Class<?> componentType = type.getComponentType(); + if (componentType == byte.class) { - Class<?> componentType = type.getComponentType(); - if (componentType == byte.class) - { - assertEquals("Error in column " + c + " of type " + dbType, true, - Arrays.equals((byte[])expected, (byte[])actual)); - } - else if (componentType == char.class) - { - assertEquals("Error in column " + c + " with type " + dbType, true, - Arrays.equals((char[])expected, (char[])actual)); - } - else - { - throw new IllegalStateException("Unexpected component type: " + componentType); - } + assertEquals("Error in column " + c + " of type " + dbType, true, + Arrays.equals((byte[])expected, (byte[])actual)); + } + else if (componentType == char.class) + { + assertEquals("Error in column " + c + " with type " + dbType, true, + Arrays.equals((char[])expected, (char[])actual)); } else { - if (dbType == DBType.TIME) - { - actual = (Long)actual % 86400000L; - expected = (Long)expected % 86400000L; - } - - assertEquals("Error in column " + c + " with type " + dbType, expected, actual); + throw new IllegalStateException("Unexpected component type: " + componentType); + } + } + else + { + if (dbType == DBType.TIME) + { + actual = (Long)actual % 86400000L; + expected = (Long)expected % 86400000L; } - ++c; + assertEquals("Error in column " + c + " with type " + dbType, expected, actual); } } private void doTest(String tableName) throws Exception { - store = (DBStore)getRepository().getStore(); - connection = store.getConnection(); + DBStore store = (DBStore)getRepository().getStore(); + Connection connection = store.getConnection(); try { - prepareTable(tableName); - writeValues(tableName); - checkValues(tableName); + prepareTable(store, tableName); + writeValues(connection, tableName); + checkValues(connection, tableName); } finally { @@ -563,25 +579,8 @@ public class Net4jDBTest extends AbstractCDOTest return; case CLOB: - { - long length = ((String)value).length(); - StringReader source = new StringReader((String)value); - try - { - outs.writeLong(length); - while (length-- > 0) - { - int c = source.read(); - outs.writeChar(c); - } - } - finally - { - IOUtil.close(source); - } - + ExtendedIOUtil.writeCharacterStream(outs, new StringReader((String)value)); return; - } case BIGINT: case DATE: @@ -597,25 +596,8 @@ public class Net4jDBTest extends AbstractCDOTest return; case BLOB: - { - long length = ((byte[])value).length; - ByteArrayInputStream source = new ByteArrayInputStream((byte[])value); - try - { - outs.writeLong(length); - while (length-- > 0) - { - int b = source.read(); - outs.writeByte(b + Byte.MIN_VALUE); - } - } - finally - { - IOUtil.close(source); - } - + ExtendedIOUtil.writeBinaryStream(outs, new ByteArrayInputStream((byte[])value)); return; - } default: throw new UnsupportedOperationException("not implemented"); @@ -670,19 +652,16 @@ public class Net4jDBTest extends AbstractCDOTest case CLOB: { StringWriter result = new StringWriter(); + try { - long length = ins.readLong(); - while (length-- > 0) - { - char c = ins.readChar(); - result.append(c); - } + ExtendedIOUtil.readCharacterStream(ins, result); } finally { IOUtil.close(result); } + return result.toString(); } @@ -703,12 +682,7 @@ public class Net4jDBTest extends AbstractCDOTest try { - long length = ins.readLong(); - while (length-- > 0) - { - int b = ins.readByte(); - result.write(b - Byte.MIN_VALUE); - } + ExtendedIOUtil.readBinaryStream(ins, result); } finally { diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/PostgresqlConfig.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/PostgresqlConfig.java index 21fcffd167..c35c708403 100644 --- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/PostgresqlConfig.java +++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/PostgresqlConfig.java @@ -37,9 +37,9 @@ public class PostgresqlConfig extends DBConfig private transient PGSimpleDataSource dataSource; - private transient PGSimpleDataSource setupDataSource; + // private transient PGSimpleDataSource setupDataSource; - private String currentRepositoryName = "cdodb1"; + // private transient String currentRepositoryName; public PostgresqlConfig(boolean supportingAudits, boolean supportingBranches, IDGenerationLocation idGenerationLocation) @@ -62,13 +62,7 @@ public class PostgresqlConfig extends DBConfig @Override protected DataSource createDataSource(String repoName) { - currentRepositoryName = repoName; - - dataSource = new PGSimpleDataSource(); - dataSource.setServerName("localhost"); - dataSource.setDatabaseName(currentRepositoryName); - dataSource.setUser("sa"); - dataSource.setPassword("sa"); + dataSource = internalCreateDataSource(repoName); try { @@ -88,9 +82,8 @@ public class PostgresqlConfig extends DBConfig protected void deactivateRepositories() { super.deactivateRepositories(); - dataSource = null; - setupDataSource = null; dropDatabase(); + dataSource = null; } private void dropDatabase() @@ -99,12 +92,14 @@ public class PostgresqlConfig extends DBConfig try { - connection = getSetupDataSource().getConnection(); - DBUtil.dropAllTables(connection, currentRepositoryName); + connection = dataSource.getConnection(); + String databaseName = dataSource.getDatabaseName(); + + DBUtil.dropAllTables(connection, databaseName); } - catch (SQLException ignore) + catch (SQLException ex) { - IOUtil.ERR().println(ignore); + IOUtil.ERR().println(ex); } finally { @@ -112,17 +107,13 @@ public class PostgresqlConfig extends DBConfig } } - private DataSource getSetupDataSource() + private PGSimpleDataSource internalCreateDataSource(String databaseName) { - if (setupDataSource == null) - { - setupDataSource = new PGSimpleDataSource(); - setupDataSource.setServerName("localhost"); - setupDataSource.setDatabaseName(currentRepositoryName); - setupDataSource.setUser("sa"); - setupDataSource.setPassword("sa"); - } - - return setupDataSource; + PGSimpleDataSource dataSource = new PGSimpleDataSource(); + dataSource.setServerName("localhost"); + dataSource.setDatabaseName(databaseName); + dataSource.setUser("postgres"); + dataSource.setPassword("postgres"); + return dataSource; } } diff --git a/plugins/org.eclipse.net4j.db.postgresql/src/org/eclipse/net4j/db/postgresql/PostgreSQLAdapter.java b/plugins/org.eclipse.net4j.db.postgresql/src/org/eclipse/net4j/db/postgresql/PostgreSQLAdapter.java index fc24422542..3eaedac099 100644 --- a/plugins/org.eclipse.net4j.db.postgresql/src/org/eclipse/net4j/db/postgresql/PostgreSQLAdapter.java +++ b/plugins/org.eclipse.net4j.db.postgresql/src/org/eclipse/net4j/db/postgresql/PostgreSQLAdapter.java @@ -61,7 +61,7 @@ public class PostgreSQLAdapter extends DBAdapter @Override public int getMaxTableNameLength() { - // http://www.postgresql.org/docs/9.0/static/sql-syntax-lexical.html + // http://www.postgresql.org/docs/9.2/static/sql-syntax-lexical.html return 63; } @@ -71,23 +71,34 @@ public class PostgreSQLAdapter extends DBAdapter @Override public int getMaxFieldNameLength() { - // http://www.postgresql.org/docs/8.2/static/sql-syntax-lexical.html + // http://www.postgresql.org/docs/9.2/static/sql-syntax-lexical.html return 63; } @Override protected String getTypeName(IDBField field) { + // http://www.postgresql.org/docs/9.2/static/datatype.html DBType type = field.getType(); switch (type) { - case LONGVARCHAR: + case BIT: + return "boolean"; //$NON-NLS-1$ + + case TINYINT: + return DBType.SMALLINT.toString(); + case VARCHAR: + case LONGVARCHAR: case CLOB: return "text"; //$NON-NLS-1$ + + case BINARY: case VARBINARY: + case LONGVARBINARY: case BLOB: return "bytea"; //$NON-NLS-1$ + case DOUBLE: return "double precision"; //$NON-NLS-1$ } @@ -130,19 +141,6 @@ public class PostgreSQLAdapter extends DBAdapter return "42703".equals(ex.getSQLState()); } - @Override - public DBType adaptType(DBType type) - { - switch (type) - { - // Due to Bug 289194: [DB] BLOB not correctly handled by PostgreSQL DBAdapter - case BLOB: - return DBType.VARBINARY; - } - - return super.adaptType(type); - } - /** * @since 4.1 */ diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBType.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBType.java index 88e68feb5b..52cefc6b95 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBType.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/db/DBType.java @@ -13,21 +13,19 @@ package org.eclipse.net4j.db; import org.eclipse.net4j.util.io.ExtendedDataInput; import org.eclipse.net4j.util.io.ExtendedDataOutput; +import org.eclipse.net4j.util.io.ExtendedIOUtil; import org.eclipse.net4j.util.io.IOUtil; import org.eclipse.net4j.util.io.TMPUtil; -import java.io.ByteArrayInputStream; -import java.io.EOFException; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.Reader; -import java.sql.Blob; -import java.sql.Clob; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -470,36 +468,28 @@ public enum DBType public Object writeValueWithResult(ExtendedDataOutput out, ResultSet resultSet, int column, boolean canBeNull) throws SQLException, IOException { - Clob value = resultSet.getClob(column); - if (canBeNull) - { - if (resultSet.wasNull()) - { - out.writeBoolean(false); - return null; - } - - out.writeBoolean(true); - } - - long length = value.length(); - Reader reader = value.getCharacterStream(); + Reader value = null; try { - out.writeLong(length); - while (length-- > 0) + value = resultSet.getCharacterStream(column); + if (canBeNull) { - int c = reader.read(); - out.writeChar(c); + if (resultSet.wasNull()) + { + out.writeBoolean(false); + return null; + } + + out.writeBoolean(true); } + + return ExtendedIOUtil.writeCharacterStream(out, value); } finally { - IOUtil.close(reader); + IOUtil.close(value); } - - return null; } @Override @@ -512,92 +502,11 @@ public enum DBType return null; } - Reader reader; - - long length = in.readLong(); - if (length > 0) - { - reader = createFileReader(in, length); - } - else - { - reader = new Reader() - { - @Override - public int read(char[] cbuf, int off, int len) throws IOException - { - return -1; - } - - @Override - public void close() throws IOException - { - // Do nothing - } - }; - } + ReaderWithLength value = ReaderWithLength.create(in); + long length = value.getLength(); - statement.setCharacterStream(column, reader, (int)length); - // reader.close(); - return null; - } - - private FileReader createFileReader(final ExtendedDataInput in, long length) throws IOException - { - FileWriter fw = null; - - try - { - final File tempFile = TMPUtil.createTempFile("clob_", ".tmp"); - tempFile.deleteOnExit(); - - fw = new FileWriter(tempFile); - - Reader reader = new Reader() - { - @Override - public int read(char[] cbuf, int off, int len) throws IOException - { - int read = 0; - - try - { - while (read < len) - { - cbuf[off++] = in.readChar(); - read++; - } - } - catch (EOFException ex) - { - read = -1; - } - - return read; - } - - @Override - public void close() throws IOException - { - } - }; - - IOUtil.copyCharacter(reader, fw, length); - - return new FileReader(tempFile) - { - @Override - public void close() throws IOException - { - super.close(); - tempFile.delete(); - } - }; - } - finally - { - IOUtil.close(fw); - } + statement.setCharacterStream(column, value, (int)length); + return length; } }, @@ -844,32 +753,28 @@ public enum DBType public Object writeValueWithResult(ExtendedDataOutput out, ResultSet resultSet, int column, boolean canBeNull) throws SQLException, IOException { - Blob value = resultSet.getBlob(column); - if (canBeNull) + InputStream value = null; + + try { - if (resultSet.wasNull()) + value = resultSet.getBinaryStream(column); + if (canBeNull) { - out.writeBoolean(false); - return null; - } - - out.writeBoolean(true); - } + if (resultSet.wasNull()) + { + out.writeBoolean(false); + return null; + } - long length = value.length(); - InputStream stream = value.getBinaryStream(); + out.writeBoolean(true); + } - try - { - out.writeLong(length); - IOUtil.copyBinary(stream, new ExtendedDataOutput.Stream(out), length); + return ExtendedIOUtil.writeBinaryStream(out, value); } finally { - IOUtil.close(stream); + IOUtil.close(value); } - - return null; } @Override @@ -882,53 +787,11 @@ public enum DBType return null; } - long length = in.readLong(); - InputStream value = null; - - if (length > 0) - { - value = createFileInputStream(in, length); - } - else - { - value = new ByteArrayInputStream(new byte[0]); - } + InputStreamWithLength value = InputStreamWithLength.create(in); + long length = value.getLength(); statement.setBinaryStream(column, value, (int)length); - - // XXX cannot close the input stream here, because - // it is still used in executeBatch() later. - // so maybe we could return it here and let the caller - // collect and close the streams. - return null; - } - - private FileInputStream createFileInputStream(final ExtendedDataInput in, long length) throws IOException - { - FileOutputStream fos = null; - - try - { - final File tempFile = TMPUtil.createTempFile("blob_", ".tmp"); - tempFile.deleteOnExit(); - - fos = new FileOutputStream(tempFile); - IOUtil.copyBinary(new ExtendedDataInput.Stream(in), fos, length); - - return new FileInputStream(tempFile) - { - @Override - public void close() throws IOException - { - super.close(); - tempFile.delete(); - } - }; - } - finally - { - IOUtil.close(fos); - } + return length; } }; @@ -1084,4 +947,130 @@ public enum DBType return null; } + + /** + * @author Eike Stepper + */ + private static final class InputStreamWithLength extends FileInputStream + { + private final File file; + + private final long length; + + private InputStreamWithLength(File file, long length) throws FileNotFoundException + { + super(file); + this.file = file; + this.length = length; + } + + public long getLength() + { + return length; + } + + @Override + public void close() throws IOException + { + super.close(); + file.delete(); + } + + public static InputStreamWithLength create(final ExtendedDataInput in) throws IOException + { + // new Reader() + // { + // @Override + // public int read(char[] cbuf, int off, int len) throws IOException + // { + // return IOUtil.EOF; + // } + // + // @Override + // public void close() throws IOException + // { + // // Do nothing + // } + // }; + + FileOutputStream fileOutputStream = null; + + try + { + File tempFile = TMPUtil.createTempFile("lob_", ".tmp"); + fileOutputStream = new FileOutputStream(tempFile); + + long length = ExtendedIOUtil.readBinaryStream(in, fileOutputStream); + + return new InputStreamWithLength(tempFile, length); + } + finally + { + IOUtil.close(fileOutputStream); + } + } + } + + /** + * @author Eike Stepper + */ + private static final class ReaderWithLength extends FileReader + { + private final File file; + + private final long length; + + private ReaderWithLength(File file, long length) throws FileNotFoundException + { + super(file); + this.file = file; + this.length = length; + } + + public long getLength() + { + return length; + } + + @Override + public void close() throws IOException + { + super.close(); + file.delete(); + } + + public static ReaderWithLength create(final ExtendedDataInput in) throws IOException + { + // new Reader() + // { + // @Override + // public int read(char[] cbuf, int off, int len) throws IOException + // { + // return IOUtil.EOF; + // } + // + // @Override + // public void close() throws IOException + // { + // // Do nothing + // } + // }; + + FileWriter fileWriter = null; + + try + { + File tempFile = TMPUtil.createTempFile("lob_", ".tmp"); + fileWriter = new FileWriter(tempFile); + + long length = ExtendedIOUtil.readCharacterStream(in, fileWriter); + + return new ReaderWithLength(tempFile, length); + } + finally + { + IOUtil.close(fileWriter); + } + } + } } diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBConnection.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBConnection.java index bea0778966..01a30be35e 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBConnection.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBConnection.java @@ -214,12 +214,18 @@ public final class DBConnection implements IDBConnection public void commit() throws SQLException { - delegate.commit(); + if (!delegate.getAutoCommit()) + { + delegate.commit(); + } } public void rollback() throws SQLException { - delegate.rollback(); + if (!delegate.getAutoCommit()) + { + delegate.rollback(); + } } public DatabaseMetaData getMetaData() throws SQLException diff --git a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBDatabase.java b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBDatabase.java index bced23975f..d0a4662e18 100644 --- a/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBDatabase.java +++ b/plugins/org.eclipse.net4j.db/src/org/eclipse/net4j/internal/db/DBDatabase.java @@ -53,7 +53,7 @@ public final class DBDatabase extends SetContainer<IDBConnection> implements IDB this.adapter = adapter; this.connectionProvider = connectionProvider; - schema = DBUtil.execute(connectionProvider, new RunnableWithConnection<IDBSchema>() + schema = DBUtil.execute(DBDatabase.this, new RunnableWithConnection<IDBSchema>() { public IDBSchema run(Connection connection) throws SQLException { diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedIOUtil.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedIOUtil.java index 43a6ee9d83..6eed2d34dc 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedIOUtil.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/ExtendedIOUtil.java @@ -24,6 +24,8 @@ import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.io.ObjectStreamClass; import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; /** * @author Eike Stepper @@ -44,6 +46,10 @@ public final class ExtendedIOUtil private static final byte NO_ENUM_LITERAL = Byte.MIN_VALUE; + private static final int BYTE_BUFFER_SIZE = 8192; + + private static final int CHARACTER_BUFFER_SIZE = 4096; + private ExtendedIOUtil() { } @@ -208,6 +214,112 @@ public final class ExtendedIOUtil } /** + * @since 3.3 + */ + public static long writeBinaryStream(DataOutput out, InputStream inputStream) throws IOException + { + long length = 0; + byte[] buffer = new byte[BYTE_BUFFER_SIZE]; + + for (;;) + { + int n = inputStream.read(buffer); + if (n == IOUtil.EOF) + { + out.writeShort(0); + break; + } + + out.writeShort(n); + out.write(buffer, 0, n); + length += n; + } + + return length; + } + + /** + * @since 3.3 + */ + public static long readBinaryStream(DataInput in, OutputStream outputStream) throws IOException + { + long length = 0; + byte[] buffer = new byte[BYTE_BUFFER_SIZE]; + + for (;;) + { + int n = in.readShort(); + if (n == 0) + { + break; + } + + in.readFully(buffer, 0, n); + outputStream.write(buffer, 0, n); + length += n; + } + + return length; + } + + /** + * @since 3.3 + */ + public static long writeCharacterStream(DataOutput out, Reader reader) throws IOException + { + long length = 0; + char[] buffer = new char[CHARACTER_BUFFER_SIZE]; + + for (;;) + { + int n = reader.read(buffer); + if (n == IOUtil.EOF) + { + out.writeShort(0); + break; + } + + out.writeShort(n); + for (int i = 0; i < n; i++) + { + out.writeChar(buffer[i]); + } + + length += n; + } + + return length; + } + + /** + * @since 3.3 + */ + public static long readCharacterStream(DataInput in, Writer writer) throws IOException + { + long length = 0; + char[] buffer = new char[CHARACTER_BUFFER_SIZE]; + + for (;;) + { + int n = in.readShort(); + if (n == 0) + { + break; + } + + for (int i = 0; i < n; i++) + { + buffer[i] = in.readChar(); + } + + writer.write(buffer, 0, n); + length += n; + } + + return length; + } + + /** * @since 3.0 */ public static void writeEnum(DataOutput out, Enum<?> literal) throws IOException |