⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mscursorresultset.java

📁 jtds的源码 是你学习java的好东西
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
        synchronized (tds) {
            // With meta data (we're not expecting any ResultSets), no timeout
            // (because we're not sending the request yet), don't alter max
            // rows, don't alter max field size, don't send yet
            tds.executeSQL(null, "sp_cursor", param, false, 0, -1, -1, false);

            if (param.length != 4) {
                param = new ParamInfo[4];
                param[0] = PARAM_CURSOR_HANDLE;
            }

            // Setup fetchtype param
            PARAM_FETCHTYPE.value = FETCH_INFO;
            param[1] = PARAM_FETCHTYPE;

            // Setup rownum
            PARAM_ROWNUM_OUT.clearOutValue();
            param[2] = PARAM_ROWNUM_OUT;
            // Setup numRows parameter
            PARAM_NUMROWS_OUT.clearOutValue();
            param[3] = PARAM_NUMROWS_OUT;

            // No meta data (no ResultSets expected), use statement timeout,
            // don't alter max rows, don't alter max field size, send now
            tds.executeSQL(null, "sp_cursorfetch", param, true,
                    statement.getQueryTimeout(), -1, -1, true);
        }

        // Consume the sp_cursor response
        tds.consumeOneResponse();
        statement.getMessages().checkErrors();
        Integer retVal = tds.getReturnStatus();
        if (retVal.intValue() != 0) {
            throw new SQLException(Messages.get("error.resultset.cursorfail"),
                    "24000");
        }

        //
        // Allow row values to be garbage collected
        //
        if (row != null) {
            for (int i = 0; i < row.length; i++) {
                if (row[i] != null) {
                    row[i].clearInValue();
                }
            }
        }

        // Consume the sp_cursorfetch response
        tds.clearResponseQueue();
        statement.getMessages().checkErrors();
        cursorPos = ((Integer) PARAM_ROWNUM_OUT.getOutValue()).intValue();
        rowsInResult = ((Integer) PARAM_NUMROWS_OUT.getOutValue()).intValue();

        // Update row status
        if (opType == CURSOR_OP_DELETE || opType == CURSOR_OP_UPDATE) {
            Object[] currentRow = getCurrentRow();
            if (currentRow == null) {
                throw new SQLException(
                        Messages.get("error.resultset.updatefail"), "24000");
            }
            // No need to re-fetch the row, just mark it as deleted or dirty
            currentRow[columns.length - 1] =
                    (opType == CURSOR_OP_DELETE) ? SQL_ROW_DELETED : SQL_ROW_DIRTY;
        }
    }

    /**
     * Close a server side cursor.
     *
     * @throws SQLException
     */
    private void cursorClose() throws SQLException {
        TdsCore tds = statement.getTds();

        statement.clearWarnings();

        // Consume rest of output and remember any exceptions
        tds.clearResponseQueue();
        SQLException ex = statement.getMessages().exceptions;

        ParamInfo param[] = new ParamInfo[1];

        // Setup cursor handle param
        param[0] = PARAM_CURSOR_HANDLE;

        tds.executeSQL(null, "sp_cursorclose", param, false,
                statement.getQueryTimeout(), -1, -1, true);
        tds.clearResponseQueue();
        
        if (ex != null) {
            ex.setNextException(statement.getMessages().exceptions);
            throw ex;
        } else {
            statement.getMessages().checkErrors();
        }
    }

    /**
     * Processes the output of a cursor open or fetch operation. Fetches a
     * batch of rows from the <code>TdsCore</code>, loading them into the row
     * cache and optionally sets the column meta data (if called on cursor
     * open). Consumes all the response and checks for server returned errors.
     *
     * @param tds     the <code>TdsCore</code> instance
     * @param setMeta whether column meta data needs to be loaded (cursor open)
     * @throws SQLException if an error occurs or an error message is returned
     *                      by the server
     */
    private void processOutput(TdsCore tds, boolean setMeta) throws SQLException {
        while (!tds.getMoreResults() && !tds.isEndOfResponse());

        int i = 0;
        if (tds.isResultSet()) {
            // Set column meta data if necessary
            if (setMeta) {
                this.columns = copyInfo(tds.getColumns());
                this.columnCount = getColumnCount(columns);
            }
            // With TDS 7 the data row (if any) is sent without any
            // preceding resultset header.
            // With TDS 8 there is a dummy result set header first
            // then the data. This case also used if meta data not supressed.
            if (tds.isRowData() || tds.getNextRow()) {
                do {
                    rowCache[i++] = copyRow(tds.getRowData());
                } while (tds.getNextRow());
            }
        } else if (setMeta) {
            statement.getMessages().addException(new SQLException(
                    Messages.get("error.statement.noresult"), "24000"));
        }

        // Set the rest of the rows to null
        for (; i < rowCache.length; ++i) {
            rowCache[i] = null;
        }

        tds.clearResponseQueue();
        statement.messages.checkErrors();
    }

//
// -------------------- java.sql.ResultSet methods -------------------
//

    public void afterLast() throws SQLException {
        checkOpen();
        checkScrollable();

        if (pos != POS_AFTER_LAST) {
            // SAfe Just fetch a very large absolute value
            cursorFetch(FETCH_ABSOLUTE, Integer.MAX_VALUE);
        }
    }

    public void beforeFirst() throws SQLException {
        checkOpen();
        checkScrollable();

        if (pos != POS_BEFORE_FIRST) {
            cursorFetch(FETCH_ABSOLUTE, 0);
        }
    }

    public void cancelRowUpdates() throws SQLException {
        checkOpen();
        checkUpdateable();

        if (onInsertRow) {
            throw new SQLException(Messages.get("error.resultset.insrow"), "24000");
        }

        for (int i = 0; updateRow != null && i < updateRow.length; i++) {
            if (updateRow[i] != null) {
                updateRow[i].clearInValue();
            }
        }
    }

    public void close() throws SQLException {
        if (!closed) {
            try {
                if (!statement.getConnection().isClosed()) {
                    cursorClose();
                }
            } finally {
                closed    = true;
                statement = null;
            }
        }
    }

    public void deleteRow() throws SQLException {
        checkOpen();
        checkUpdateable();

        if (getCurrentRow() == null) {
            throw new SQLException(Messages.get("error.resultset.norow"), "24000");
        }

        if (onInsertRow) {
            throw new SQLException(Messages.get("error.resultset.insrow"), "24000");
        }

        cursor(CURSOR_OP_DELETE, null);
    }

    public void insertRow() throws SQLException {
        checkOpen();
        checkUpdateable();

        if (!onInsertRow) {
            throw new SQLException(Messages.get("error.resultset.notinsrow"), "24000");
        }

        cursor(CURSOR_OP_INSERT, insertRow);
    }

    public void moveToCurrentRow() throws SQLException {
        checkOpen();
        checkUpdateable();

        onInsertRow = false;
    }

    public void moveToInsertRow() throws SQLException {
        checkOpen();
        checkUpdateable();
        if (insertRow == null) {
            insertRow = new ParamInfo[columnCount];
        }
        onInsertRow = true;
    }

    public void refreshRow() throws SQLException {
        checkOpen();

        if (onInsertRow) {
            throw new SQLException(Messages.get("error.resultset.insrow"), "24000");
        }

        cursorFetch(FETCH_REPEAT, 0);
    }

    public void updateRow() throws SQLException {
        checkOpen();
        checkUpdateable();

        if (getCurrentRow() == null) {
            throw new SQLException(Messages.get("error.resultset.norow"), "24000");
        }

        if (onInsertRow) {
            throw new SQLException(Messages.get("error.resultset.insrow"), "24000");
        }

        if (updateRow != null) {
            cursor(CURSOR_OP_UPDATE, updateRow);
        }
    }

    public boolean first() throws SQLException {
        checkOpen();
        checkScrollable();

        pos = 1;
        if (getCurrentRow() == null) {
            return cursorFetch(FETCH_FIRST, 0);
        } else {
            return true;
        }
    }

    // FIXME Make the isXXX() methods work with forward-only cursors (rowsInResult == -1)
    public boolean isLast() throws SQLException {
        checkOpen();

        return(pos == rowsInResult) && (rowsInResult != 0);
    }

    public boolean last() throws SQLException {
        checkOpen();
        checkScrollable();

        pos = rowsInResult;
        if (asyncCursor || getCurrentRow() == null) {
            if (cursorFetch(FETCH_LAST, 0)) {
                // Set pos to the last row, as the number of rows can change
                pos = rowsInResult;
                return true;
            } else {
                return false;
            }
        } else {
            return true;
        }
    }

    public boolean next() throws SQLException {
        checkOpen();

        ++pos;
        if (getCurrentRow() == null) {
            return cursorFetch(FETCH_NEXT, 0);
        } else {
            return true;
        }
    }

    public boolean previous() throws SQLException {
        checkOpen();
        checkScrollable();

        // Don't bother if we're already before the first row
        if (pos == POS_BEFORE_FIRST) {
            return false;
        }

        // Save current ResultSet position
        int initPos = pos;
        // Decrement current position
        --pos;
        if (initPos == POS_AFTER_LAST || getCurrentRow() == null) {
            boolean res = cursorFetch(FETCH_PREVIOUS, 0);
            pos = (initPos == POS_AFTER_LAST) ? rowsInResult : (initPos - 1);
            return res;
        } else {
            return true;
        }
    }

    public boolean rowDeleted() throws SQLException {
        checkOpen();

        Object[] currentRow = getCurrentRow();

        // If there is no current row, return false (the row was not deleted)
        if (currentRow == null) {
            return false;
        }

        // Reload if dirty
        if (SQL_ROW_DIRTY.equals(currentRow[columns.length - 1])) {
            cursorFetch(FETCH_REPEAT, 0);
            currentRow = getCurrentRow();
        }

        return SQL_ROW_DELETED.equals(currentRow[columns.length - 1]);
    }

    public boolean rowInserted() throws SQLException {
        checkOpen();
        // No way to find out
        return false;
    }

    public boolean rowUpdated() throws SQLException {
        checkOpen();
        // No way to find out
        return false;
    }

    public boolean absolute(int row) throws SQLException {
        checkOpen();
        checkScrollable();

        pos = (row >= 0) ? row : (rowsInResult - row + 1);
        if (getCurrentRow() == null) {
            boolean result = cursorFetch(FETCH_ABSOLUTE, row);
            if (cursorPos == 1 && row + rowsInResult < 0) {
                pos = 0;
                result = false;
            }
            return result;
        } else {
            return true;
        }
    }

    public boolean relative(int row) throws SQLException {
        checkOpen();
        checkScrollable();

        pos = (pos == POS_AFTER_LAST) ? (rowsInResult + 1 + row) : (pos + row);
        if (getCurrentRow() == null) {
            if (pos < cursorPos) {
                // If fetching backwards fetch the row and the rows before it,
                // then restore pos
                int savePos = pos;
                boolean result = cursorFetch(FETCH_RELATIVE,
                        pos - cursorPos - fetchSize + 1);
                if (result) {
                    pos = savePos;
                } else {
                    pos = POS_BEFORE_FIRST;
                }
                return result;
            } else {
                return cursorFetch(FETCH_RELATIVE, pos - cursorPos);
            }
        } else {
            return true;
        }
    }

    protected Object[] getCurrentRow() {
        if (pos < cursorPos || pos >= cursorPos + rowCache.length) {
            return null;
        }

        return rowCache[pos - cursorPos];
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -