org.firebirdsql.jdbc.FBTxPreparedStatement Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jaybird Show documentation
Show all versions of jaybird Show documentation
JDBC Driver for the Firebird RDBMS
The newest version!
/*
* Firebird Open Source JDBC Driver
*
* Distributable under LGPL license.
* You may obtain a copy of the License at http://www.gnu.org/copyleft/lgpl.html
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* LGPL License for more details.
*
* This file was created by members of the firebird development team.
* All individual contributions remain the Copyright (C) of those
* individuals. Contributors to this file are either listed here or
* can be obtained from a source control history command.
*
* All rights reserved.
*/
package org.firebirdsql.jdbc;
import org.firebirdsql.gds.JaybirdErrorCodes;
import org.firebirdsql.gds.ng.FbExceptionBuilder;
import org.firebirdsql.gds.ng.FbStatement;
import org.firebirdsql.jaybird.parser.LocalStatementClass;
import org.firebirdsql.jaybird.parser.LocalStatementType;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.*;
import java.util.Calendar;
import java.util.List;
import static org.firebirdsql.jdbc.FBPreparedStatement.METHOD_NOT_SUPPORTED;
import static org.firebirdsql.jdbc.SQLStateConstants.SQL_STATE_GENERAL_ERROR;
/**
* Specialized implementation of {@link FirebirdPreparedStatement}/{@link java.sql.PreparedStatement} for executing
* transaction management statements.
*
* Contrary to normal statement implementations, this doesn't notify a {@link FBObjectListener.StatementListener} about
* execution starts and completion, as those would start transactions when needed, which will interfere with the goal
* of this statement type (that is commit, rollback, or start a new transaction). Instead, this implementation will
* call on {@link FBConnection#handleHardCommitStatement()}, {@link FBConnection#handleHardRollbackStatement()}, or
* {@link FBConnection#handleSetTransactionStatement(String)}.
*
*
* @author Mark Rotteveel
* @since 6
*/
@SuppressWarnings("java:S1192")
@NullMarked
final class FBTxPreparedStatement extends AbstractStatement implements FirebirdPreparedStatement {
private final LocalStatementType statementType;
private final String sql;
FBTxPreparedStatement(FBConnection connection, LocalStatementType statementType, String sql,
ResultSetBehavior rsBehavior) throws SQLException {
super(connection, rsBehavior);
if (statementType.statementClass() != LocalStatementClass.TRANSACTION_BOUNDARY) {
throw new IllegalArgumentException("Unsupported value for statementType (implementation bug): "
+ statementType);
}
this.statementType = statementType;
this.sql = sql;
setPoolable(true);
}
@Override
protected FbStatement getStatementHandle() throws SQLException {
throw new SQLFeatureNotSupportedException("This statement implementation does not use a statement handle");
}
@Override
public @Nullable String getExecutionPlan() throws SQLException {
checkValidity();
throw new FBDriverNotCapableException(
"Cannot provide an execution plan for a transaction management statement");
}
@Override
public @Nullable String getExplainedExecutionPlan() throws SQLException {
checkValidity();
throw new FBDriverNotCapableException(
"Cannot provide an explained execution plan for a transaction management statement");
}
@Override
public int getStatementType() {
return switch (statementType) {
case HARD_COMMIT -> FirebirdPreparedStatement.TYPE_COMMIT;
case HARD_ROLLBACK -> FirebirdPreparedStatement.TYPE_ROLLBACK;
case SET_TRANSACTION -> FirebirdPreparedStatement.TYPE_START_TRANS;
// Should already be handled by constructor
default -> throw new AssertionError(
"Unsupported value for statementType (implementation bug): " + statementType);
};
}
@Override
public void close() throws SQLException {
if (isClosed()) return;
try (var ignored = withLock()) {
super.close();
connection.notifyStatementClosed(this);
}
}
@Override
public void completeStatement(CompletionReason reason) throws SQLException {
if (reason == CompletionReason.CONNECTION_ABORT) {
super.close();
}
}
@Override
public ResultSet executeQuery() throws SQLException {
checkValidity();
throw FbExceptionBuilder.forNonTransientException(JaybirdErrorCodes.jb_executeQueryWithTxStmt).toSQLException();
}
@Override
public int executeUpdate() throws SQLException {
execute0();
return 0;
}
@Override
public long executeLargeUpdate() throws SQLException {
execute0();
return 0L;
}
@Override
public boolean execute() throws SQLException {
execute0();
return false;
}
private void execute0() throws SQLException {
try (var ignored = withLock()) {
checkValidity();
switch (statementType) {
case HARD_COMMIT -> connection.handleHardCommitStatement();
case HARD_ROLLBACK -> connection.handleHardRollbackStatement();
case SET_TRANSACTION -> connection.handleSetTransactionStatement(sql);
// Should already be handled by constructor
default -> throw new AssertionError(
"Unsupported value for statementType (implementation bug): " + statementType);
}
performCloseOnCompletion();
}
}
@Override
public void addBatch() throws SQLException {
checkValidity();
throw FbExceptionBuilder.forException(JaybirdErrorCodes.jb_addBatchWithTxStmt).toSQLException();
}
@Override
public void addBatch(String sql) throws SQLException {
methodNotSupported();
}
@Override
public void clearBatch() throws SQLException {
checkValidity();
// silently ignored
}
@Override
public int[] executeBatch() throws SQLException {
checkValidity();
// There never is a batch, so always return an empty array
return new int[0];
}
@Override
public long[] executeLargeBatch() throws SQLException {
checkValidity();
// There never is a batch, so always return an empty array
return new long[0];
}
@SuppressWarnings("java:S4144")
@Override
public @Nullable ResultSetMetaData getMetaData() throws SQLException {
checkValidity();
// There is never a result set, so no metadata
return null;
}
@Override
public ParameterMetaData getParameterMetaData() throws SQLException {
checkValidity();
// Zero parameters, so empty parameter metadata
return new FBParameterMetaData(connection.getFbDatabase().emptyRowDescriptor(), connection);
}
@Override
public ResultSet executeQuery(String sql) throws SQLException {
return methodNotSupported();
}
private static T methodNotSupported() throws SQLException {
throw new SQLNonTransientException(METHOD_NOT_SUPPORTED, SQL_STATE_GENERAL_ERROR);
}
@Override
public int executeUpdate(String sql) throws SQLException {
return methodNotSupported();
}
@Override
public long executeLargeUpdate(String sql) throws SQLException {
return methodNotSupported();
}
@Override
public boolean execute(String sql) throws SQLException {
return methodNotSupported();
}
@Override
public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
return methodNotSupported();
}
@Override
public long executeLargeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
return methodNotSupported();
}
@Override
public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
return methodNotSupported();
}
@Override
public long executeLargeUpdate(String sql, int[] columnIndexes) throws SQLException {
return methodNotSupported();
}
@Override
public int executeUpdate(String sql, String[] columnNames) throws SQLException {
return methodNotSupported();
}
@Override
public long executeLargeUpdate(String sql, String[] columnNames) throws SQLException {
return methodNotSupported();
}
@Override
public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
return methodNotSupported();
}
@Override
public boolean execute(String sql, int[] columnIndexes) throws SQLException {
return methodNotSupported();
}
@Override
public boolean execute(String sql, String[] columnNames) throws SQLException {
return methodNotSupported();
}
@Override
public void setNull(int parameterIndex, int sqlType) throws SQLException {
noParameters(parameterIndex);
}
private void noParameters(int parameterIndex) throws SQLException {
checkValidity();
throw new SQLException("Invalid column index: " + parameterIndex,
SQLStateConstants.SQL_STATE_INVALID_DESC_FIELD_ID);
}
@Override
public void setBoolean(int parameterIndex, boolean x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setByte(int parameterIndex, byte x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setShort(int parameterIndex, short x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setInt(int parameterIndex, int x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setLong(int parameterIndex, long x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setFloat(int parameterIndex, float x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setDouble(int parameterIndex, double x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setBigDecimal(int parameterIndex, @Nullable BigDecimal x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setString(int parameterIndex, @Nullable String x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setBytes(int parameterIndex, byte @Nullable [] x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setDate(int parameterIndex, @Nullable Date x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setTime(int parameterIndex, @Nullable Time x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setTimestamp(int parameterIndex, @Nullable Timestamp x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setAsciiStream(int parameterIndex, @Nullable InputStream x, int length) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setUnicodeStream(int parameterIndex, @Nullable InputStream x, int length) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setBinaryStream(int parameterIndex, @Nullable InputStream x, int length) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void clearParameters() throws SQLException {
checkValidity();
// silently ignored
}
@Override
public void setObject(int parameterIndex, @Nullable Object x, int targetSqlType) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setObject(int parameterIndex, @Nullable Object x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setCharacterStream(int parameterIndex, @Nullable Reader reader, int length) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setRef(int parameterIndex, @Nullable Ref x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setBlob(int parameterIndex, @Nullable Blob x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setClob(int parameterIndex, @Nullable Clob x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setArray(int parameterIndex, @Nullable Array x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setDate(int parameterIndex, @Nullable Date x, @Nullable Calendar cal) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setTime(int parameterIndex, @Nullable Time x, @Nullable Calendar cal) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setTimestamp(int parameterIndex, @Nullable Timestamp x, @Nullable Calendar cal) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setURL(int parameterIndex, @Nullable URL x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setRowId(int parameterIndex, @Nullable RowId x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setNString(int parameterIndex, @Nullable String value) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setNCharacterStream(int parameterIndex, @Nullable Reader value, long length) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setNClob(int parameterIndex, @Nullable NClob value) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setClob(int parameterIndex, @Nullable Reader reader, long length) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setBlob(int parameterIndex, @Nullable InputStream inputStream, long length) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setNClob(int parameterIndex, @Nullable Reader reader, long length) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setSQLXML(int parameterIndex, @Nullable SQLXML xmlObject) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setObject(int parameterIndex, @Nullable Object x, int targetSqlType, int scaleOrLength)
throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setAsciiStream(int parameterIndex, @Nullable InputStream x, long length) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setBinaryStream(int parameterIndex, @Nullable InputStream x, long length) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setCharacterStream(int parameterIndex, @Nullable Reader reader, long length) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setAsciiStream(int parameterIndex, @Nullable InputStream x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setBinaryStream(int parameterIndex, @Nullable InputStream x) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setCharacterStream(int parameterIndex, @Nullable Reader reader) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setNCharacterStream(int parameterIndex, @Nullable Reader value) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setClob(int parameterIndex, @Nullable Reader reader) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setBlob(int parameterIndex, @Nullable InputStream inputStream) throws SQLException {
noParameters(parameterIndex);
}
@Override
public void setNClob(int parameterIndex, @Nullable Reader reader) throws SQLException {
noParameters(parameterIndex);
}
@Override
public int getInsertedRowsCount() {
return -1;
}
@Override
public int getUpdatedRowsCount() {
return -1;
}
@Override
public int getDeletedRowsCount() {
return -1;
}
@Override
public boolean hasOpenResultSet() {
return false;
}
/**
* {@inheritDoc}
*
* @deprecated Use {@link #getResultSet()} instead, will be removed in Jaybird 7
*/
@SuppressWarnings("removal")
@Deprecated(since = "6", forRemoval = true)
@Override
public @Nullable ResultSet getCurrentResultSet() throws SQLException {
return getResultSet();
}
@SuppressWarnings("java:S4144")
@Override
public int getMaxFieldSize() throws SQLException {
checkValidity();
return 0;
}
@Override
public void setMaxFieldSize(int max) throws SQLException {
checkValidity();
// silently ignored
}
@Override
public void setEscapeProcessing(boolean enable) throws SQLException {
checkValidity();
// silently ignored
}
@SuppressWarnings("java:S4144")
@Override
public int getQueryTimeout() throws SQLException {
checkValidity();
return 0;
}
@Override
public void setQueryTimeout(int seconds) throws SQLException {
checkValidity();
// silently ignored
}
@Override
public void cancel() throws SQLException {
checkValidity();
throw new FBDriverNotCapableException("Cannot cancel transaction management statement execution");
}
@SuppressWarnings("java:S4144")
@Override
public @Nullable ResultSet getResultSet() throws SQLException {
checkValidity();
return null;
}
@SuppressWarnings("java:S4144")
@Override
public int getUpdateCount() throws SQLException {
checkValidity();
return -1;
}
@SuppressWarnings("java:S4144")
@Override
public long getLargeUpdateCount() throws SQLException {
checkValidity();
return -1;
}
@Override
public boolean getMoreResults() throws SQLException {
checkValidity();
return false;
}
@Override
public boolean getMoreResults(int current) throws SQLException {
checkValidity();
return false;
}
@Override
public ResultSet getGeneratedKeys() throws SQLException {
checkValidity();
return new FBResultSet(connection.getFbDatabase().emptyRowDescriptor(), List.of());
}
@SuppressWarnings("ConstantValue")
@Override
public T unwrap(Class iface) throws SQLException {
if (!isWrapperFor(iface)) {
throw new SQLException("Unable to unwrap to class " + (iface != null ? iface.getName() : "(null)"));
}
return iface.cast(this);
}
@SuppressWarnings("ConstantValue")
@Override
public boolean isWrapperFor(Class> iface) {
return iface != null && iface.isAssignableFrom(getClass());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy