Search in sources :

Example 1 with ResultSet

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();
        }
    }
}
Also used : SQLWarning(java.sql.SQLWarning) CursorActivation(org.apache.derby.iapi.sql.execute.CursorActivation) Activation(org.apache.derby.iapi.sql.Activation) CursorActivation(org.apache.derby.iapi.sql.execute.CursorActivation) StatementContext(org.apache.derby.iapi.sql.conn.StatementContext) ExecCursorTableReference(org.apache.derby.iapi.sql.execute.ExecCursorTableReference) LanguageConnectionContext(org.apache.derby.iapi.sql.conn.LanguageConnectionContext) ResultDescription(org.apache.derby.iapi.sql.ResultDescription) ResultSet(org.apache.derby.iapi.sql.ResultSet)

Example 2 with ResultSet

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();
        }
    }
}
Also used : SQLWarning(java.sql.SQLWarning) CursorActivation(org.apache.derby.iapi.sql.execute.CursorActivation) LanguageConnectionContext(org.apache.derby.iapi.sql.conn.LanguageConnectionContext) Activation(org.apache.derby.iapi.sql.Activation) CursorActivation(org.apache.derby.iapi.sql.execute.CursorActivation) ResultSet(org.apache.derby.iapi.sql.ResultSet) StatementContext(org.apache.derby.iapi.sql.conn.StatementContext)

Example 3 with ResultSet

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();
        }
    }
}
Also used : ExecPreparedStatement(org.apache.derby.iapi.sql.execute.ExecPreparedStatement) ResultSet(org.apache.derby.iapi.sql.ResultSet) Activation(org.apache.derby.iapi.sql.Activation) CursorActivation(org.apache.derby.iapi.sql.execute.CursorActivation)

Example 4 with ResultSet

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;
}
Also used : CursorActivation(org.apache.derby.iapi.sql.execute.CursorActivation) ResultSet(org.apache.derby.iapi.sql.ResultSet) Activation(org.apache.derby.iapi.sql.Activation) CursorActivation(org.apache.derby.iapi.sql.execute.CursorActivation)

Example 5 with ResultSet

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);
}
Also used : CursorActivation(org.apache.derby.iapi.sql.execute.CursorActivation) ResultSet(org.apache.derby.iapi.sql.ResultSet) Activation(org.apache.derby.iapi.sql.Activation) CursorActivation(org.apache.derby.iapi.sql.execute.CursorActivation)

Aggregations

ResultSet (org.apache.derby.iapi.sql.ResultSet)13 Activation (org.apache.derby.iapi.sql.Activation)7 CursorActivation (org.apache.derby.iapi.sql.execute.CursorActivation)6 PreparedStatement (org.apache.derby.iapi.sql.PreparedStatement)4 StatementContext (org.apache.derby.iapi.sql.conn.StatementContext)3 Field (java.lang.reflect.Field)2 SQLWarning (java.sql.SQLWarning)2 ArrayList (java.util.ArrayList)2 LanguageConnectionContext (org.apache.derby.iapi.sql.conn.LanguageConnectionContext)2 ExecPreparedStatement (org.apache.derby.iapi.sql.execute.ExecPreparedStatement)2 ExecRow (org.apache.derby.iapi.sql.execute.ExecRow)2 NoPutResultSet (org.apache.derby.iapi.sql.execute.NoPutResultSet)2 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)2 UUID (org.apache.derby.catalog.UUID)1 ResultDescription (org.apache.derby.iapi.sql.ResultDescription)1 DependencyManager (org.apache.derby.iapi.sql.depend.DependencyManager)1 CursorResultSet (org.apache.derby.iapi.sql.execute.CursorResultSet)1 ExecCursorTableReference (org.apache.derby.iapi.sql.execute.ExecCursorTableReference)1 NumberDataValue (org.apache.derby.iapi.types.NumberDataValue)1 SQLBoolean (org.apache.derby.iapi.types.SQLBoolean)1