use of org.apache.derby.iapi.sql.ResultSet in project derby by apache.
the class EmbedResultSet method updateRow.
/**
* JDBC 2.0
*
* Update the underlying database with the new contents of the
* current row. Cannot be called when on the insert row.
*
* @exception SQLException if a database-access error occurs, or
* if called when on the insert row
*/
public void updateRow() throws SQLException {
synchronized (getConnectionSynchronization()) {
checksBeforeUpdateOrDelete("updateRow", -1);
// Check that the cursor is not positioned on insertRow
checkNotOnInsertRow();
setupContextStack();
LanguageConnectionContext lcc = getLanguageConnectionContext(getEmbedConnection());
StatementContext statementContext = null;
try {
if (// nothing got updated on this row
currentRowHasBeenUpdated == false)
// nothing to do since no updates were made to this row
return;
// now construct the update where current of sql
boolean foundOneColumnAlready = false;
StringBuffer updateWhereCurrentOfSQL = new StringBuffer("UPDATE ");
CursorActivation activation = lcc.lookupCursorActivation(getCursorName());
ExecCursorTableReference targetTable = activation.getPreparedStatement().getTargetTable();
// got the underlying (schema.)table name
updateWhereCurrentOfSQL.append(getFullBaseTableName(targetTable));
updateWhereCurrentOfSQL.append(" SET ");
ResultDescription rd = theResults.getResultDescription();
for (int i = 1; i <= rd.getColumnCount(); i++) {
// in this for loop we are constructing columnname=?,... part of the update sql
if (columnGotUpdated[i - 1]) {
// if the column got updated, do following
if (foundOneColumnAlready)
updateWhereCurrentOfSQL.append(",");
// using quotes around the column name to preserve case sensitivity
updateWhereCurrentOfSQL.append(IdUtil.normalToDelimited(rd.getColumnDescriptor(i).getName()) + "=?");
foundOneColumnAlready = true;
}
}
// using quotes around the cursor name to preserve case sensitivity
updateWhereCurrentOfSQL.append(" WHERE CURRENT OF " + IdUtil.normalToDelimited(getCursorName()));
StatementContext currSC = lcc.getStatementContext();
Activation parentAct = null;
if (currSC != null) {
parentAct = currSC.getActivation();
}
// Context used for preparing, don't set any timeout (use 0)
statementContext = lcc.pushStatementContext(isAtomic, false, updateWhereCurrentOfSQL.toString(), null, false, 0L);
// A priori, the new statement context inherits the activation of
// the existing statementContext, so that that activation ends up
// as parent of the new activation 'act' created below, which will
// be the activation of the pushed statement context.
statementContext.setActivation(parentAct);
org.apache.derby.iapi.sql.PreparedStatement ps = lcc.prepareInternalStatement(updateWhereCurrentOfSQL.toString());
Activation act = ps.getActivation(lcc, false);
statementContext.setActivation(act);
// in this for loop we are assigning values for parameters in sql constructed earlier with columnname=?,...
for (int i = 1, paramPosition = 0; i <= rd.getColumnCount(); i++) {
if (// if the column got updated, do following
columnGotUpdated[i - 1])
act.getParameterValueSet().getParameterForSet(paramPosition++).setValue(updateRow.getColumn(i));
}
// Don't set any timeout when updating rows (use 0)
// Execute the update where current of sql.
org.apache.derby.iapi.sql.ResultSet rs = ps.executeSubStatement(activation, act, true, 0L);
SQLWarning w = act.getWarnings();
if (w != null) {
addWarning(w);
}
act.close();
// For forward only resultsets, after a update, the ResultSet will be positioned right before the next row.
if (getType() == TYPE_FORWARD_ONLY) {
currentRow = null;
} else {
movePosition(RELATIVE, 0, "relative");
}
lcc.popStatementContext(statementContext, null);
InterruptStatus.restoreIntrFlagIfSeen(lcc);
} catch (Throwable t) {
throw closeOnTransactionError(t);
} finally {
if (statementContext != null)
lcc.popStatementContext(statementContext, null);
restoreContextStack();
initializeUpdateRowModifiers();
}
}
}
use of org.apache.derby.iapi.sql.ResultSet in project derby by apache.
the class EmbedResultSet method deleteRow.
/**
* JDBC 2.0
*
* Delete the current row from the result set and the underlying
* database. Cannot be called when on the insert row.
*
* @exception SQLException if a database-access error occurs, or if
* called when on the insert row.
*/
public void deleteRow() throws SQLException {
synchronized (getConnectionSynchronization()) {
checksBeforeUpdateOrDelete("deleteRow", -1);
// Check that the cursor is not positioned on insertRow
checkNotOnInsertRow();
setupContextStack();
LanguageConnectionContext lcc = getLanguageConnectionContext(getEmbedConnection());
StatementContext statementContext = null;
// now construct the delete where current of sql
try {
StringBuffer deleteWhereCurrentOfSQL = new StringBuffer("DELETE FROM ");
CursorActivation activation = lcc.lookupCursorActivation(getCursorName());
// get the underlying (schema.)table name
deleteWhereCurrentOfSQL.append(getFullBaseTableName(activation.getPreparedStatement().getTargetTable()));
// using quotes around the cursor name to preserve case sensitivity
deleteWhereCurrentOfSQL.append(" WHERE CURRENT OF " + IdUtil.normalToDelimited(getCursorName()));
StatementContext currSC = lcc.getStatementContext();
Activation parentAct = null;
if (currSC != null) {
parentAct = currSC.getActivation();
}
// Context used for preparing, don't set any timeout (use 0)
statementContext = lcc.pushStatementContext(isAtomic, false, deleteWhereCurrentOfSQL.toString(), null, false, 0L);
// A priori, the new statement context inherits the activation
// of the existing statementContext, so that that activation
// ends up as parent of the new activation 'act' created below,
// which will be the activation of the pushed statement
// context.
statementContext.setActivation(parentAct);
org.apache.derby.iapi.sql.PreparedStatement ps = lcc.prepareInternalStatement(deleteWhereCurrentOfSQL.toString());
// Get activation, so that we can get the warning from it
Activation act = ps.getActivation(lcc, false);
statementContext.setActivation(act);
// Don't set any timeout when deleting rows (use 0)
// execute delete where current of sql
org.apache.derby.iapi.sql.ResultSet rs = ps.executeSubStatement(activation, act, true, 0L);
SQLWarning w = act.getWarnings();
if (w != null) {
addWarning(w);
}
act.close();
// After a delete, the ResultSet will be positioned right before
// the next row.
currentRow = null;
lcc.popStatementContext(statementContext, null);
InterruptStatus.restoreIntrFlagIfSeen(lcc);
} catch (Throwable t) {
throw closeOnTransactionError(t);
} finally {
if (statementContext != null)
lcc.popStatementContext(statementContext, null);
restoreContextStack();
initializeUpdateRowModifiers();
}
}
}
use of org.apache.derby.iapi.sql.ResultSet in project derby by apache.
the class GenericLanguageConnectionContext method endTransactionActivationHandling.
//
// class implementation
//
/**
* If we are called as part of rollback code path, then we will reset all
* the activations that have resultset returning rows associated with
* them. DERBY-3304 Resultsets that do not return rows should be left
* alone when the rollback is through the JDBC Connection object. If the
* rollback is caused by an exception, then at that time, all kinds of
* resultsets should be closed.
*
* If we are called as part of commit code path, then we will do one of
* the following if the activation has resultset assoicated with it. Also,
* we will clear the conglomerate used while scanning for update/delete
* 1)Close result sets that return rows and are not held across commit.
* 2)Clear the current row of the resultsets that return rows and are
* held across commit.
* 3)Leave the result sets untouched if they do not return rows
*
* Additionally, clean up (close()) activations that have been
* marked as unused during statement finalization.
*
* @exception StandardException thrown on failure
*/
private void endTransactionActivationHandling(boolean forRollback) throws StandardException {
// itself from the list, thus invalidating the Enumeration
for (int i = acts.size() - 1; i >= 0; i--) {
// the end of the array
if (i >= acts.size())
continue;
Activation a = acts.get(i);
/*
** Look for stale activations. Activations are
** marked as unused during statement finalization.
** Here, we sweep and remove this inactive ones.
*/
if (!a.isInUse()) {
a.close();
continue;
}
// Determine if the activation has a resultset and if that resultset
// returns rows. For such an activation, we need to take special
// actions during commit and rollback as explained in the comments
// below.
ResultSet activationResultSet = a.getResultSet();
boolean resultsetReturnsRows = activationResultSet != null && activationResultSet.returnsRows();
if (forRollback) {
if (resultsetReturnsRows)
// Since we are dealing with rollback, we need to reset
// the activation no matter what the holdability might
// be provided that resultset returns rows. An example
// where we do not want to close a resultset that does
// not return rows would be a java procedure which has
// user invoked rollback inside of it. That rollback
// should not reset the activation associated with
// the call to java procedure because that activation
// is still being used.
a.reset();
// Only invalidate statements if we performed DDL.
if (dataDictionaryInWriteMode()) {
ExecPreparedStatement ps = a.getPreparedStatement();
if (ps != null) {
ps.makeInvalid(DependencyManager.ROLLBACK, this);
}
}
} else {
// We are dealing with commit here.
if (resultsetReturnsRows) {
if (a.getResultSetHoldability() == false)
// Close result sets that return rows and are not held
// across commit. This is to implement closing JDBC
// result sets that are CLOSE_CURSOR_ON_COMMIT at commit
// time.
activationResultSet.close();
else
// Clear the current row of the result sets that return
// rows and are held across commit. This is to implement
// keeping JDBC result sets open that are
// HOLD_CURSORS_OVER_COMMIT at commit time and marking
// the resultset to be not on a valid row position. The
// user will need to reposition within the resultset
// before doing any row operations.
activationResultSet.clearCurrentRow();
}
a.clearHeapConglomerateController();
}
}
}
use of org.apache.derby.iapi.sql.ResultSet in project derby by apache.
the class GenericLanguageConnectionContext method lookupCursorActivation.
/**
* See if a given cursor is available for use.
* if so return its activation. Returns null if not found.
* For use in execution.
*
* @return the activation for the given cursor, null
* if none was found.
*/
public CursorActivation lookupCursorActivation(String cursorName) {
int size = acts.size();
if (size > 0) {
int cursorHash = cursorName.hashCode();
for (int i = 0; i < size; i++) {
Activation a = acts.get(i);
if (!a.isInUse()) {
continue;
}
String executingCursorName = a.getCursorName();
// two names actually are equal.
if (executingCursorName == null || executingCursorName.hashCode() != cursorHash) {
continue;
}
if (cursorName.equals(executingCursorName)) {
ResultSet rs = a.getResultSet();
if (rs == null)
continue;
// if the result set is closed, the the cursor doesn't exist
if (rs.isClosed()) {
continue;
}
return (CursorActivation) a;
}
}
}
return null;
}
use of org.apache.derby.iapi.sql.ResultSet in project derby by apache.
the class GenericLanguageConnectionContext method verifyAllHeldResultSetsAreClosed.
/**
* Verify that there are no activations with open held result sets.
*
* @return boolean Found no open (held) resultsets.
*
* @exception StandardException thrown on failure
*/
/* This gets used in case of hold cursors. If there are any hold cursors open
* then user can't change the isolation level without closing them. At the
* execution time, set transaction isolation level calls this method before
* changing the isolation level.
*/
public boolean verifyAllHeldResultSetsAreClosed() throws StandardException {
boolean seenOpenResultSets = false;
/* For every activation */
for (int i = acts.size() - 1; i >= 0; i--) {
Activation a = acts.get(i);
if (SanityManager.DEBUG) {
SanityManager.ASSERT(a instanceof CursorActivation, "a is not a CursorActivation");
}
if (!a.isInUse()) {
continue;
}
if (!a.getResultSetHoldability()) {
continue;
}
ResultSet rs = ((CursorActivation) a).getResultSet();
/* is there an open result set? */
if ((rs != null) && !rs.isClosed() && rs.returnsRows()) {
seenOpenResultSets = true;
break;
}
}
if (!seenOpenResultSets)
return (true);
// There may be open ResultSet's that are yet to be garbage collected
// let's try and force these out rather than throw an error
System.gc();
System.runFinalization();
/* For every activation */
for (int i = acts.size() - 1; i >= 0; i--) {
Activation a = acts.get(i);
if (SanityManager.DEBUG) {
SanityManager.ASSERT(a instanceof CursorActivation, "a is not a CursorActivation");
}
if (!a.isInUse()) {
continue;
}
if (!a.getResultSetHoldability()) {
continue;
}
ResultSet rs = ((CursorActivation) a).getResultSet();
/* is there an open held result set? */
if ((rs != null) && !rs.isClosed() && rs.returnsRows()) {
return (false);
}
}
return (true);
}
Aggregations