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