Search in sources :

Example 1 with FBField

use of org.firebirdsql.jdbc.field.FBField in project jaybird by FirebirdSQL.

the class FBManagedConnection method findSingleXid.

/**
 * Obtain a single prepared transaction branch from a resource manager, based on a Xid
 *
 * @param externalXid
 *            The Xid to find
 * @return The Xid if found, otherwise null.
 * @throws XAException
 *             An error has occurred. Possible values are XAER_RMERR,
 *             XAER_RMFAIL, XAER_INVAL, and XAER_PROTO.
 */
protected Xid findSingleXid(Xid externalXid) throws javax.transaction.xa.XAException {
    try {
        FbTransaction trHandle2 = database.startTransaction(tpb.getTransactionParameterBuffer());
        FbStatement stmtHandle2 = database.createStatement(trHandle2);
        GDSHelper gdsHelper2 = new GDSHelper(database);
        gdsHelper2.setCurrentTransaction(trHandle2);
        stmtHandle2.prepare(RECOVERY_QUERY_PARAMETRIZED);
        DataProvider dataProvider0 = new DataProvider(0);
        stmtHandle2.addStatementListener(dataProvider0);
        DataProvider dataProvider1 = new DataProvider(1);
        stmtHandle2.addStatementListener(dataProvider1);
        final RowValue parameters = stmtHandle2.getParameterDescriptor().createDefaultFieldValues();
        FBXid tempXid = new FBXid(externalXid);
        parameters.getFieldValue(0).setFieldData(tempXid.toBytes());
        stmtHandle2.execute(parameters);
        stmtHandle2.fetchRows(1);
        FBField field0 = FBField.createField(stmtHandle2.getFieldDescriptor().getFieldDescriptor(0), dataProvider0, gdsHelper2, false);
        FBField field1 = FBField.createField(stmtHandle2.getFieldDescriptor().getFieldDescriptor(1), dataProvider1, gdsHelper2, false);
        FBXid xid = null;
        if (dataProvider0.getRowCount() > 0) {
            dataProvider0.setRow(0);
            dataProvider1.setRow(0);
            long inLimboTxId = field0.getLong();
            byte[] inLimboMessage = field1.getBytes();
            try {
                xid = new FBXid(new ByteArrayInputStream(inLimboMessage), inLimboTxId);
            } catch (FBIncorrectXidException ex) {
                log.warn("ignoring XID stored with invalid format in RDB$TRANSACTIONS for RDB$TRANSACTION_ID=" + inLimboTxId);
            }
        }
        stmtHandle2.close();
        trHandle2.commit();
        return xid;
    } catch (SQLException | ResourceException e) {
        throw new FBXAException("can't perform query to fetch xids", XAException.XAER_RMFAIL, e);
    }
}
Also used : FBField(org.firebirdsql.jdbc.field.FBField) SQLException(java.sql.SQLException) GDSHelper(org.firebirdsql.gds.impl.GDSHelper) FieldDataProvider(org.firebirdsql.jdbc.field.FieldDataProvider) ByteArrayInputStream(java.io.ByteArrayInputStream) RowValue(org.firebirdsql.gds.ng.fields.RowValue) ResourceException(javax.resource.ResourceException)

Example 2 with FBField

use of org.firebirdsql.jdbc.field.FBField in project jaybird by FirebirdSQL.

the class FBManagedConnection method forget.

/**
 * Indicates that no further action will be taken on behalf of this
 * transaction (after a heuristic failure). It is assumed this will be
 * called after a failed commit or rollback.
 *
 * @throws XAException
 *             Occurs when the state was not correct (end never called), or
 *             the transaction ID is wrong.
 */
public void forget(Xid id) throws XAException {
    long inLimboId = -1;
    try {
        // find XID
        // TODO: Is there a reason why this piece of code can't use the JDBC Statement class?
        FbTransaction trHandle2 = database.startTransaction(tpb.getTransactionParameterBuffer());
        FbStatement stmtHandle2 = database.createStatement(trHandle2);
        GDSHelper gdsHelper2 = new GDSHelper(database);
        gdsHelper2.setCurrentTransaction(trHandle2);
        stmtHandle2.prepare(FORGET_FIND_QUERY);
        DataProvider dataProvider0 = new DataProvider(0);
        stmtHandle2.addStatementListener(dataProvider0);
        DataProvider dataProvider1 = new DataProvider(1);
        stmtHandle2.addStatementListener(dataProvider1);
        stmtHandle2.execute(RowValue.EMPTY_ROW_VALUE);
        stmtHandle2.fetchRows(10);
        FBField field0 = FBField.createField(stmtHandle2.getFieldDescriptor().getFieldDescriptor(0), dataProvider0, gdsHelper2, false);
        FBField field1 = FBField.createField(stmtHandle2.getFieldDescriptor().getFieldDescriptor(1), dataProvider1, gdsHelper2, false);
        int row = 0;
        while (row < dataProvider0.getRowCount()) {
            dataProvider0.setRow(row);
            dataProvider1.setRow(row);
            long inLimboTxId = field0.getLong();
            byte[] inLimboMessage = field1.getBytes();
            try {
                FBXid xid = new FBXid(new ByteArrayInputStream(inLimboMessage), inLimboTxId);
                boolean gtridEquals = Arrays.equals(xid.getGlobalTransactionId(), id.getGlobalTransactionId());
                boolean bqualEquals = Arrays.equals(xid.getBranchQualifier(), id.getBranchQualifier());
                if (gtridEquals && bqualEquals) {
                    inLimboId = inLimboTxId;
                    break;
                }
            } catch (FBIncorrectXidException ex) {
                log.warn("incorrect XID format in RDB$TRANSACTIONS where RDB$TRANSACTION_ID=" + inLimboTxId, ex);
            }
            row++;
        }
        stmtHandle2.close();
        trHandle2.commit();
    } catch (SQLException | ResourceException ex) {
        log.debug("can't perform query to fetch xids", ex);
        throw new FBXAException(XAException.XAER_RMFAIL, ex);
    }
    if (inLimboId == -1)
        // TODO: is XAER_NOTA the proper error code ?
        throw new FBXAException("XID not found", XAException.XAER_NOTA);
    try {
        // delete XID
        FbTransaction trHandle2 = database.startTransaction(tpb.getTransactionParameterBuffer());
        FbStatement stmtHandle2 = database.createStatement(trHandle2);
        GDSHelper gdsHelper2 = new GDSHelper(database);
        gdsHelper2.setCurrentTransaction(trHandle2);
        stmtHandle2.prepare(FORGET_DELETE_QUERY + inLimboId);
        stmtHandle2.execute(RowValue.EMPTY_ROW_VALUE);
        stmtHandle2.close();
        trHandle2.commit();
    } catch (SQLException ex) {
        throw new FBXAException("can't perform query to fetch xids", XAException.XAER_RMFAIL, ex);
    }
}
Also used : FBField(org.firebirdsql.jdbc.field.FBField) SQLException(java.sql.SQLException) GDSHelper(org.firebirdsql.gds.impl.GDSHelper) FieldDataProvider(org.firebirdsql.jdbc.field.FieldDataProvider) ByteArrayInputStream(java.io.ByteArrayInputStream) ResourceException(javax.resource.ResourceException)

Example 3 with FBField

use of org.firebirdsql.jdbc.field.FBField in project jaybird by FirebirdSQL.

the class AbstractCallableStatement method internalExecute.

/**
 * Execute statement internally. This method sets cached parameters. Rest of
 * the processing is done by superclass.
 */
protected boolean internalExecute(boolean sendOutParams) throws SQLException {
    currentRs = null;
    singletonRs = null;
    int counter = 0;
    for (FBProcedureParam param : procedureCall.getInputParams()) {
        if (param != null && param.isParam()) {
            counter++;
            Object value = param.getValue();
            FBField field = getField(counter);
            if (value == null) {
                field.setNull();
            } else if (value instanceof WrapperWithCalendar) {
                setField(field, (WrapperWithCalendar) value);
            } else if (value instanceof WrapperWithLong) {
                setField(field, (WrapperWithLong) value);
            } else {
                field.setObject(value);
            }
            isParamSet[counter - 1] = true;
        }
    }
    final boolean hasResultSet = super.internalExecute(sendOutParams);
    if (hasResultSet && isSingletonResult) {
        // Safeguarding first row so it will work even if the result set from getResultSet is manipulated
        singletonRs = new FBResultSet(fbStatement.getFieldDescriptor(), connection, new ArrayList<>(specialResult), true);
    }
    return hasResultSet;
}
Also used : FBField(org.firebirdsql.jdbc.field.FBField)

Example 4 with FBField

use of org.firebirdsql.jdbc.field.FBField in project jaybird by FirebirdSQL.

the class AbstractCallableStatement method setRequiredTypesInternal.

private void setRequiredTypesInternal(FBResultSet resultSet) throws SQLException {
    for (FBProcedureParam param : procedureCall.getOutputParams()) {
        if (param == null)
            continue;
        FBField field = resultSet.getField(procedureCall.mapOutParamIndexToPosition(param.getIndex()), false);
        field.setRequiredType(param.getType());
    }
}
Also used : FBField(org.firebirdsql.jdbc.field.FBField)

Example 5 with FBField

use of org.firebirdsql.jdbc.field.FBField in project jaybird by FirebirdSQL.

the class AbstractPreparedStatement method executeSingleForBatch.

private void executeSingleForBatch(RowValue data, List<Long> results) throws SQLException {
    for (int i = 0; i < fieldValues.getCount(); i++) {
        FieldValue fieldValue = fieldValues.getFieldValue(i);
        fieldValue.reset();
        FBField field = getField(i + 1);
        if (field instanceof FBFlushableField) {
            // Explicitly set to null to ensure initialized property set to true
            fieldValue.setFieldData(null);
            ((FBFlushableField) field).setCachedObject((CachedObject) data.getFieldValue(i).getCachedObject());
        } else {
            fieldValue.setFieldData(data.getFieldValue(i).getFieldData());
        }
        isParamSet[i] = true;
    }
    if (internalExecute(isExecuteProcedureStatement)) {
        throw jdbcVersionSupport.createBatchUpdateException("Statements executed as batch should not produce a result set", SQLStateConstants.SQL_STATE_INVALID_STMT_TYPE, 0, toLargeArray(results), null);
    }
    results.add(getLargeUpdateCount());
}
Also used : FBField(org.firebirdsql.jdbc.field.FBField) FBFlushableField(org.firebirdsql.jdbc.field.FBFlushableField) FieldValue(org.firebirdsql.gds.ng.fields.FieldValue)

Aggregations

FBField (org.firebirdsql.jdbc.field.FBField)10 GDSHelper (org.firebirdsql.gds.impl.GDSHelper)4 FieldDataProvider (org.firebirdsql.jdbc.field.FieldDataProvider)4 ByteArrayInputStream (java.io.ByteArrayInputStream)3 SQLException (java.sql.SQLException)3 ResourceException (javax.resource.ResourceException)3 RowValue (org.firebirdsql.gds.ng.fields.RowValue)3 FBFlushableField (org.firebirdsql.jdbc.field.FBFlushableField)3 ArrayList (java.util.ArrayList)1 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)1 FieldValue (org.firebirdsql.gds.ng.fields.FieldValue)1 DefaultStatementListener (org.firebirdsql.gds.ng.listeners.DefaultStatementListener)1 StatementListener (org.firebirdsql.gds.ng.listeners.StatementListener)1 FBWorkaroundStringField (org.firebirdsql.jdbc.field.FBWorkaroundStringField)1 Test (org.junit.Test)1