Search in sources :

Example 6 with FBField

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

the class AbstractPreparedStatement method addBatch.

/**
 * Adds a set of parameters to this <code>PreparedStatement</code>
 * object's batch of commands.
 *
 * @exception SQLException
 *                if a database access error occurs
 * @see Statement#addBatch
 * @since 1.2
 * @see <a href="package-summary.html#2.0 API">What Is in the JDBC 2.0 API
 *      </a>
 */
public void addBatch() throws SQLException {
    checkValidity();
    boolean allParamsSet = true;
    // TODO Replace with check of FieldValue#isInitialized
    for (boolean anIsParamSet : isParamSet) {
        allParamsSet &= anIsParamSet;
    }
    if (!allParamsSet)
        throw new FBSQLException("Not all parameters set.");
    final RowValue batchedValues = fieldValues.deepCopy();
    for (int i = 0; i < batchedValues.getCount(); i++) {
        FBField field = getField(i + 1);
        if (field instanceof FBFlushableField)
            batchedValues.getFieldValue(i).setCachedObject(((FBFlushableField) field).getCachedObject());
    }
    batchList.add(batchedValues);
}
Also used : FBField(org.firebirdsql.jdbc.field.FBField) FBFlushableField(org.firebirdsql.jdbc.field.FBFlushableField) RowValue(org.firebirdsql.gds.ng.fields.RowValue)

Example 7 with FBField

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

the class AbstractPreparedStatement method setStringForced.

/**
 * Sets the designated parameter to the given String value. This is a
 * workaround for the ambiguous "operation was cancelled" response from the
 * server for when an oversized string is set for a limited-size field. This
 * method sets the string parameter without checking size constraints.
 *
 * @param parameterIndex
 *            the first parameter is 1, the second is 2, ...
 * @param x
 *            The String value to be set
 * @throws SQLException
 *             if a database access occurs
 */
public void setStringForced(int parameterIndex, String x) throws SQLException {
    FBField field = getField(parameterIndex);
    if (field instanceof FBWorkaroundStringField)
        ((FBWorkaroundStringField) field).setStringForced(x);
    else
        field.setString(x);
    isParamSet[parameterIndex - 1] = true;
}
Also used : FBField(org.firebirdsql.jdbc.field.FBField) FBWorkaroundStringField(org.firebirdsql.jdbc.field.FBWorkaroundStringField)

Example 8 with FBField

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

the class AbstractPreparedStatement method flushFields.

/**
 * Flush fields that might have cached data.
 *
 * @throws SQLException if something went wrong.
 */
private void flushFields() throws SQLException {
    // flush any cached data that can be hanging
    for (int i = 0; i < isParamSet.length; i++) {
        FBField field = getField(i + 1);
        if (!(field instanceof FBFlushableField))
            continue;
        ((FBFlushableField) field).flushCachedData();
    }
}
Also used : FBField(org.firebirdsql.jdbc.field.FBField) FBFlushableField(org.firebirdsql.jdbc.field.FBFlushableField)

Example 9 with FBField

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

the class FBManagedConnection method recover.

/**
 * Obtain a list of prepared transaction branches from a resource manager.
 * The transaction manager calls this method during recovery to obtain the
 * list of transaction branches that are currently in prepared or
 * heuristically completed states.
 *
 * @param flags
 *            One of TMSTARTRSCAN, TMENDRSCAN, TMNOFLAGS. TMNOFLAGS must be
 *            used when no other flags are set in flags.
 * @return The resource manager returns zero or more XIDs for the
 *         transaction branches that are currently in a prepared or
 *         heuristically completed state. If an error occurs during the
 *         operation, the resource manager should throw the appropriate
 *         XAException.
 * @throws XAException
 *             An error has occurred. Possible values are XAER_RMERR,
 *             XAER_RMFAIL, XAER_INVAL, and XAER_PROTO.
 */
public Xid[] recover(int flags) throws javax.transaction.xa.XAException {
    if (flags != XAResource.TMSTARTRSCAN && flags != XAResource.TMENDRSCAN && flags != XAResource.TMNOFLAGS && flags != (XAResource.TMSTARTRSCAN | XAResource.TMENDRSCAN))
        throw new FBXAException("flag not allowed in this context: " + flags + ", valid flags are TMSTARTRSCAN, TMENDRSCAN, TMNOFLAGS, TMSTARTRSCAN|TMENDRSCAN", XAException.XAER_PROTO);
    try {
        // if (!((flags & XAResource.TMSTARTRSCAN) == 0))
        // if ((flags & XAResource.TMENDRSCAN) == 0 && (flags & XAResource.TMNOFLAGS) == 0)
        // return new Xid[0];
        List<FBXid> xids = new ArrayList<>();
        FbTransaction trHandle2 = database.startTransaction(tpb.getTransactionParameterBuffer());
        FbStatement stmtHandle2 = database.createStatement(trHandle2);
        GDSHelper gdsHelper2 = new GDSHelper(database);
        gdsHelper2.setCurrentTransaction(trHandle2);
        stmtHandle2.prepare(RECOVERY_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);
                xids.add(xid);
            } catch (FBIncorrectXidException ex) {
                log.warn("ignoring XID stored with invalid format in RDB$TRANSACTIONS for RDB$TRANSACTION_ID=" + inLimboTxId);
            }
            row++;
        }
        stmtHandle2.close();
        trHandle2.commit();
        return xids.toArray(new FBXid[0]);
    } 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) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) GDSHelper(org.firebirdsql.gds.impl.GDSHelper) FieldDataProvider(org.firebirdsql.jdbc.field.FieldDataProvider) ByteArrayInputStream(java.io.ByteArrayInputStream) ResourceException(javax.resource.ResourceException)

Example 10 with FBField

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

the class TestReconnectTransaction method testReconnectTransaction.

@Test
public void testReconnectTransaction() throws Exception {
    FbConnectionProperties connectionInfo = new FbConnectionProperties();
    connectionInfo.setServerName(FBTestProperties.DB_SERVER_URL);
    connectionInfo.setPortNumber(FBTestProperties.DB_SERVER_PORT);
    connectionInfo.setUser(DB_USER);
    connectionInfo.setPassword(DB_PASSWORD);
    connectionInfo.setDatabaseName(FBTestProperties.getDatabasePath());
    connectionInfo.setEncoding("NONE");
    FbDatabaseFactory databaseFactory = FBTestProperties.getFbDatabaseFactory();
    try (FbDatabase dbHandle1 = databaseFactory.connect(connectionInfo)) {
        dbHandle1.attach();
        FbTransaction trHandle1 = dbHandle1.startTransaction(tpb.getTransactionParameterBuffer());
        trHandle1.prepare(message);
    // No commit! We leave trHandle1 in Limbo.
    }
    try (FbDatabase dbHandle2 = databaseFactory.connect(connectionInfo)) {
        dbHandle2.attach();
        GDSHelper gdsHelper2 = new GDSHelper(dbHandle2);
        FbTransaction trHandle2 = dbHandle2.startTransaction(tpb.getTransactionParameterBuffer());
        gdsHelper2.setCurrentTransaction(trHandle2);
        FbStatement stmtHandle2 = dbHandle2.createStatement(trHandle2);
        stmtHandle2.prepare(RECOVERY_QUERY);
        final List<RowValue> rows = new ArrayList<>();
        StatementListener stmtListener = new DefaultStatementListener() {

            @Override
            public void receivedRow(FbStatement sender, RowValue rowValues) {
                rows.add(rowValues);
            }
        };
        stmtHandle2.addStatementListener(stmtListener);
        stmtHandle2.execute(RowValue.EMPTY_ROW_VALUE);
        stmtHandle2.fetchRows(10);
        DataProvider dataProvider0 = new DataProvider(rows, 0);
        DataProvider dataProvider1 = new DataProvider(rows, 1);
        FBField field0 = FBField.createField(stmtHandle2.getFieldDescriptor().getFieldDescriptor(0), dataProvider0, gdsHelper2, false);
        FBField field1 = FBField.createField(stmtHandle2.getFieldDescriptor().getFieldDescriptor(1), dataProvider1, gdsHelper2, false);
        boolean foundInLimboTx = false;
        int row = 0;
        while (row < rows.size()) {
            dataProvider0.setRow(row);
            dataProvider1.setRow(row);
            long inLimboTxId = field0.getLong();
            byte[] inLimboMessage = field1.getBytes();
            if (Arrays.equals(message, inLimboMessage)) {
                foundInLimboTx = true;
                FbTransaction inLimboTrHandle = dbHandle2.reconnectTransaction(inLimboTxId);
                assertEquals(inLimboTxId, inLimboTrHandle.getTransactionId());
                inLimboTrHandle.rollback();
                break;
            }
            row++;
        }
        stmtHandle2.close();
        trHandle2.commit();
        assertTrue("Should find in-limbo tx.", foundInLimboTx);
    }
}
Also used : FBField(org.firebirdsql.jdbc.field.FBField) DefaultStatementListener(org.firebirdsql.gds.ng.listeners.DefaultStatementListener) StatementListener(org.firebirdsql.gds.ng.listeners.StatementListener) ArrayList(java.util.ArrayList) GDSHelper(org.firebirdsql.gds.impl.GDSHelper) FieldDataProvider(org.firebirdsql.jdbc.field.FieldDataProvider) DefaultStatementListener(org.firebirdsql.gds.ng.listeners.DefaultStatementListener) RowValue(org.firebirdsql.gds.ng.fields.RowValue) Test(org.junit.Test)

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