Skip to content

Commit

Permalink
ARTEMIS-1813 DB2 should avoid Blob to append data
Browse files Browse the repository at this point in the history
DB2 10.5 doesn't allow to append Blob data to an existing Blob,
producing unexpected errors: a custom DB2 sequential file
can perfom the append by using a customized UPDATE statement.
max-blob-size.db2 and create-file-table.db2 are changed to match the
2 GB max blob size limit allowed by DB2.
  • Loading branch information
franz1981 authored and clebertsuconic committed Apr 17, 2018
1 parent 9247eaa commit 998be38
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ public Connection getConnection() {
}

public final void setConnection(Connection connection) {
if (connection == null) {
if (this.connection == null) {
this.connection = connection;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.activemq.artemis.jdbc.store.file;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

import org.apache.activemq.artemis.jdbc.store.sql.SQLProvider;

@SuppressWarnings("SynchronizeOnNonFinalField")
public final class Db2SequentialFileDriver extends JDBCSequentialFileFactoryDriver {

public Db2SequentialFileDriver() {
super();
}

public Db2SequentialFileDriver(DataSource dataSource, SQLProvider provider) {
super(dataSource, provider);
}

public Db2SequentialFileDriver(Connection connection, SQLProvider provider) {
super(connection, provider);
}

@Override
protected void prepareStatements() throws SQLException {
this.deleteFile = connection.prepareStatement(sqlProvider.getDeleteFileSQL());
this.createFile = connection.prepareStatement(sqlProvider.getInsertFileSQL(), new String[]{"ID"});
this.selectFileByFileName = connection.prepareStatement(sqlProvider.getSelectFileByFileName());
this.copyFileRecord = connection.prepareStatement(sqlProvider.getCopyFileRecordByIdSQL());
this.renameFile = connection.prepareStatement(sqlProvider.getUpdateFileNameByIdSQL());
this.readLargeObject = connection.prepareStatement(sqlProvider.getReadLargeObjectSQL());
this.appendToLargeObject = connection.prepareStatement(sqlProvider.getAppendToLargeObjectSQL());
this.selectFileNamesByExtension = connection.prepareStatement(sqlProvider.getSelectFileNamesByExtensionSQL());
}

@Override
public int writeToFile(JDBCSequentialFile file, byte[] data) throws SQLException {
if (data == null || data.length == 0) {
return 0;
}
synchronized (connection) {
try {
connection.setAutoCommit(false);
int bytesWritten;
appendToLargeObject.setBytes(1, data);
appendToLargeObject.setLong(2, file.getId());
final int updatesFiles = appendToLargeObject.executeUpdate();
assert updatesFiles <= 1;
connection.commit();
if (updatesFiles == 0) {
bytesWritten = 0;
} else {
bytesWritten = data.length;
}
return bytesWritten;
} catch (SQLException e) {
connection.rollback();
throw e;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.apache.activemq.artemis.jdbc.store.sql.PropertySQLProvider;
import org.apache.activemq.artemis.jdbc.store.sql.SQLProvider;

import static org.apache.activemq.artemis.jdbc.store.sql.PropertySQLProvider.Factory.SQLDialect.DB2;
import static org.apache.activemq.artemis.jdbc.store.sql.PropertySQLProvider.Factory.SQLDialect.POSTGRESQL;

class JDBCFileUtils {
Expand All @@ -32,8 +33,11 @@ static JDBCSequentialFileFactoryDriver getDBFileDriver(String driverClass,
String jdbcConnectionUrl,
SQLProvider provider) throws SQLException {
final JDBCSequentialFileFactoryDriver dbDriver;
if (POSTGRESQL.equals(PropertySQLProvider.Factory.identifyDialect(driverClass))) {
final PropertySQLProvider.Factory.SQLDialect sqlDialect = PropertySQLProvider.Factory.identifyDialect(driverClass);
if (POSTGRESQL.equals(sqlDialect)) {
dbDriver = new PostgresSequentialSequentialFileDriver();
} else if (DB2.equals(sqlDialect)) {
dbDriver = new Db2SequentialFileDriver();
} else {
dbDriver = new JDBCSequentialFileFactoryDriver();
}
Expand All @@ -51,6 +55,8 @@ static JDBCSequentialFileFactoryDriver getDBFileDriver(DataSource dataSource, SQ
}
if (POSTGRESQL.equals(sqlDialect)) {
dbDriver = new PostgresSequentialSequentialFileDriver(dataSource, provider);
} else if (DB2.equals(sqlDialect)) {
dbDriver = new Db2SequentialFileDriver(dataSource, provider);
} else {
dbDriver = new JDBCSequentialFileFactoryDriver(dataSource, provider);
}
Expand All @@ -59,9 +65,12 @@ static JDBCSequentialFileFactoryDriver getDBFileDriver(DataSource dataSource, SQ

static JDBCSequentialFileFactoryDriver getDBFileDriver(Connection connection, SQLProvider provider) throws SQLException {
JDBCSequentialFileFactoryDriver dbDriver;
if (POSTGRESQL.equals(PropertySQLProvider.Factory.investigateDialect(connection))) {
final PropertySQLProvider.Factory.SQLDialect sqlDialect = PropertySQLProvider.Factory.investigateDialect(connection);
if (POSTGRESQL.equals(sqlDialect)) {
dbDriver = new PostgresSequentialSequentialFileDriver(connection, provider);
dbDriver.setConnection(connection);
} else if (DB2.equals(sqlDialect)) {
dbDriver = new Db2SequentialFileDriver(connection, provider);
} else {
dbDriver = new JDBCSequentialFileFactoryDriver(connection, provider);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ public static SQLDialect investigateDialect(Connection connection) {
if (dialect == null) {
logger.warnf("Unable to detect database dialect from connection metadata or JDBC driver name.");
} else {
logger.debugf("Detect database dialect as '%s'.");
logger.debugf("Detect database dialect as '%s'.", dialect);
}
} catch (Exception e) {
logger.debug("Unable to read JDBC metadata.", e);
Expand Down
4 changes: 3 additions & 1 deletion artemis-jdbc-store/src/main/resources/journal-sql.properties
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,6 @@ max-blob-size.oracle=4294967296
table-names-case.oracle=upper

# DB2 SQL statements
create-file-table.db2=CREATE TABLE %s (ID BIGINT GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1), FILENAME VARCHAR(255), EXTENSION VARCHAR(10), DATA BLOB, PRIMARY KEY(ID))
max-blob-size.db2=2147483647
create-file-table.db2=CREATE TABLE %s (ID BIGINT GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1), FILENAME VARCHAR(255), EXTENSION VARCHAR(10), DATA BLOB(2G), PRIMARY KEY(ID))
append-to-file.db2=UPDATE %s SET DATA = (DATA || ?) WHERE ID=?

0 comments on commit 998be38

Please sign in to comment.