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);
}
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;
}
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();
}
}
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);
}
}
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);
}
}
Aggregations