📄 updatableresultset.java
字号:
* <p> * Moves to the last row in the result set. * </p> * * @return true if on a valid row, false if no rows in the result set. * * @exception SQLException * if a database-access error occurs, or result set type is * TYPE_FORWARD_ONLY. */ public synchronized boolean last() throws SQLException { return super.last(); } /** * JDBC 2.0 Move the cursor to the remembered cursor position, usually the * current row. Has no effect unless the cursor is on the insert row. * * @exception SQLException * if a database-access error occurs, or the result set is * not updatable * @throws SQLException * if the ResultSet is not updatable or some other error occurs */ public synchronized void moveToCurrentRow() throws SQLException { checkClosed(); if (!this.isUpdatable) { throw new NotUpdatable(this.notUpdatableReason); } if (this.onInsertRow) { this.onInsertRow = false; this.thisRow = this.savedCurrentRow; } } /** * JDBC 2.0 Move to the insert row. The current cursor position is * remembered while the cursor is positioned on the insert row. The insert * row is a special row associated with an updatable result set. It is * essentially a buffer where a new row may be constructed by calling the * updateXXX() methods prior to inserting the row into the result set. Only * the updateXXX(), getXXX(), and insertRow() methods may be called when the * cursor is on the insert row. All of the columns in a result set must be * given a value each time this method is called before calling insertRow(). * UpdateXXX()must be called before getXXX() on a column. * * @exception SQLException * if a database-access error occurs, or the result set is * not updatable * @throws NotUpdatable * DOCUMENT ME! */ public synchronized void moveToInsertRow() throws SQLException { checkClosed(); if (!this.isUpdatable) { throw new NotUpdatable(this.notUpdatableReason); } if (this.inserter == null) { if (this.insertSQL == null) { generateStatements(); } this.inserter = this.connection .clientPrepareStatement(this.insertSQL); if (this.populateInserterWithDefaultValues) { extractDefaultValues(); } resetInserter(); } else { resetInserter(); } int numFields = this.fields.length; this.onInsertRow = true; this.doingUpdates = false; this.savedCurrentRow = this.thisRow; this.thisRow = new byte[numFields][]; for (int i = 0; i < numFields; i++) { if (!this.populateInserterWithDefaultValues) { this.inserter.setBytesNoEscapeNoQuotes(i + 1, "DEFAULT".getBytes()); this.thisRow[i] = null; } else { if (this.defaultColumnValue[i] != null) { Field f = this.fields[i]; switch (f.getMysqlType()) { case MysqlDefs.FIELD_TYPE_DATE: case MysqlDefs.FIELD_TYPE_DATETIME: case MysqlDefs.FIELD_TYPE_NEWDATE: case MysqlDefs.FIELD_TYPE_TIME: case MysqlDefs.FIELD_TYPE_TIMESTAMP: if (this.defaultColumnValue[i].length > 7 && this.defaultColumnValue[i][0] == (byte) 'C' && this.defaultColumnValue[i][1] == (byte) 'U' && this.defaultColumnValue[i][2] == (byte) 'R' && this.defaultColumnValue[i][3] == (byte) 'R' && this.defaultColumnValue[i][4] == (byte) 'E' && this.defaultColumnValue[i][5] == (byte) 'N' && this.defaultColumnValue[i][6] == (byte) 'T' && this.defaultColumnValue[i][7] == (byte) '_') { this.inserter.setBytesNoEscapeNoQuotes(i + 1, this.defaultColumnValue[i]); break; } default: this.inserter.setBytes(i + 1, this.defaultColumnValue[i], false, false); } // This value _could_ be changed from a getBytes(), so we // need a copy.... byte[] defaultValueCopy = new byte[this.defaultColumnValue[i].length]; System.arraycopy(defaultColumnValue[i], 0, defaultValueCopy, 0, defaultValueCopy.length); this.thisRow[i] = defaultValueCopy; } else { this.inserter.setNull(i + 1, java.sql.Types.NULL); this.thisRow[i] = null; } } } } /** * A ResultSet is initially positioned before its first row, the first call * to next makes the first row the current row; the second call makes the * second row the current row, etc. * * <p> * If an input stream from the previous row is open, it is implicitly * closed. The ResultSet's warning chain is cleared when a new row is read * </p> * * @return true if the new current is valid; false if there are no more rows * * @exception SQLException * if a database access error occurs */ public synchronized boolean next() throws SQLException { return super.next(); } /** * The prev method is not part of JDBC, but because of the architecture of * this driver it is possible to move both forward and backward within the * result set. * * <p> * If an input stream from the previous row is open, it is implicitly * closed. The ResultSet's warning chain is cleared when a new row is read * </p> * * @return true if the new current is valid; false if there are no more rows * * @exception SQLException * if a database access error occurs */ public synchronized boolean prev() throws SQLException { return super.prev(); } /** * JDBC 2.0 * * <p> * Moves to the previous row in the result set. * </p> * * <p> * Note: previous() is not the same as relative(-1) since it makes sense to * call previous() when there is no current row. * </p> * * @return true if on a valid row, false if off the result set. * * @exception SQLException * if a database-access error occurs, or result set type is * TYPE_FORWAR_DONLY. */ public synchronized boolean previous() throws SQLException { return super.previous(); } /** * Closes this ResultSet, releasing all resources. * * @param calledExplicitly * was this called from close()? * * @throws SQLException * if an error occurs. */ protected void realClose(boolean calledExplicitly) throws SQLException { if (this.isClosed) { return; } SQLException sqlEx = null; if (this.useUsageAdvisor) { if ((this.deleter == null) && (this.inserter == null) && (this.refresher == null) && (this.updater == null)) { this.eventSink = ProfileEventSink.getInstance(this.connection); String message = Messages.getString("UpdatableResultSet.34"); //$NON-NLS-1$ this.eventSink.consumeEvent(new ProfilerEvent( ProfilerEvent.TYPE_WARN, "", //$NON-NLS-1$ (this.owningStatement == null) ? "N/A" //$NON-NLS-1$ : this.owningStatement.currentCatalog, //$NON-NLS-1$ this.connectionId, (this.owningStatement == null) ? (-1) : this.owningStatement.getId(), this.resultId, System.currentTimeMillis(), 0, Constants.MILLIS_I18N, null, this.pointOfOrigin, message)); } } try { if (this.deleter != null) { this.deleter.close(); } } catch (SQLException ex) { sqlEx = ex; } try { if (this.inserter != null) { this.inserter.close(); } } catch (SQLException ex) { sqlEx = ex; } try { if (this.refresher != null) { this.refresher.close(); } } catch (SQLException ex) { sqlEx = ex; } try { if (this.updater != null) { this.updater.close(); } } catch (SQLException ex) { sqlEx = ex; } super.realClose(calledExplicitly); if (sqlEx != null) { throw sqlEx; } } /** * JDBC 2.0 Refresh the value of the current row with its current value in * the database. Cannot be called when on the insert row. The refreshRow() * method provides a way for an application to explicitly tell the JDBC * driver to refetch a row(s) from the database. An application may want to * call refreshRow() when caching or prefetching is being done by the JDBC * driver to fetch the latest value of a row from the database. The JDBC * driver may actually refresh multiple rows at once if the fetch size is * greater than one. All values are refetched subject to the transaction * isolation level and cursor sensitivity. If refreshRow() is called after * calling updateXXX(), but before calling updateRow() then the updates made * to the row are lost. Calling refreshRow() frequently will likely slow * performance. * * @exception SQLException * if a database-access error occurs, or if called when on * the insert row. * @throws NotUpdatable * DOCUMENT ME! */ public synchronized void refreshRow() throws SQLException { checkClosed(); if (!this.isUpdatable) { throw new NotUpdatable(); } if (this.onInsertRow) { throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.8")); //$NON-NLS-1$ } else if (this.rowData.size() == 0) { throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.9")); //$NON-NLS-1$ } else if (isBeforeFirst()) { throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.10")); //$NON-NLS-1$ } else if (isAfterLast()) { throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.11")); //$NON-NLS-1$ } refreshRow(this.updater, this.thisRow); } private synchronized void refreshRow(PreparedStatement updateInsertStmt, Object[] rowToRefresh) throws SQLException { if (this.refresher == null) { if (this.refreshSQL == null) { generateStatements(); } this.refresher = this.connection .clientPrepareStatement(this.refreshSQL); } this.refresher.clearParameters(); int numKeys = this.primaryKeyIndicies.size(); if (numKeys == 1) { byte[] dataFrom = null; int index = ((Integer) this.primaryKeyIndicies.get(0)).intValue(); if (!this.doingUpdates && !this.onInsertRow) { dataFrom = (byte[]) rowToRefresh[index]; } else { dataFrom = updateInsertStmt.getBytesRepresentation(index); // Primary keys not set? if (updateInsertStmt.isNull(index) || (dataFrom.length == 0)) { dataFrom = (byte[]) rowToRefresh[index]; } else { dataFrom = stripBinaryPrefix(dataFrom); } } this.refresher.setBytesNoEscape(1, dataFrom); } else { for (int i = 0; i < numKeys; i++) { byte[] dataFrom = null; int index = ((Integer) this.primaryKeyIndicies.get(i)) .intValue(); if (!this.doingUpdates && !this.onInsertRow) { dataFrom = (byte[]) rowToRefresh[index]; } else { dataFrom = updateInsertStmt.getBytesRepresentation(index); // Primary keys not set? if (updateInsertStmt.isNull(index) || (dataFrom.length == 0)) { dataFrom = (byte[]) this.thisRow[index]; } else { dataFrom = stripBinaryPrefix(dataFrom); } } this.refresher.setBytesNoEscape(i + 1, dataFrom); } } java.sql.ResultSet rs = null; try { rs = this.refresher.executeQuery(); int numCols = rs.getMetaData().getColumnCount(); if (rs.next()) { for (int i = 0; i < numCols; i++) { byte[] val = rs.getBytes(i + 1); if ((val == null) || rs.wasNull()) { rowToRefresh[i] = null; } else { rowToRefresh[i] = rs.getBytes(i + 1); } } } else { throw SQLError.createSQLException(Messages .getString("UpdatableResultSet.12"), //$NON-NLS-1$ SQLError.SQL_STATE_GENERAL_ERROR); //$NON-NLS-1$ } } finally { if (rs != null) { try { rs.close(); } catch (SQLException ex) { ; // ignore } } } } /** * JDBC 2.0 * * <p> * Moves a relative number of rows, either positive or negative. Attempting * to move beyond the first/last row in the result set positions the cursor * before/after the the first/last row. Calling relative(0) is valid, but * does not change the cursor position. * </p> * * <p> * Note: Calling relative(1) is different than calling next() since is makes * sense to call next() when there is no current row, for example, when the * cursor is positioned before the first row or after the last row of the * result set. * </p> * * @param rows * DOCUMENT ME! * * @return true if on a row, false otherwise. * * @exception SQLException * if a database-access error occurs, or there is no current * row, or result set type is TYPE_FORWARD_ONLY. */ public synchronized boolean relative(int rows) throws SQLException { return super.relative(rows); } private void resetInserter() throws SQLException { this.inserter.clearParameters(); for (int i = 0; i < this.fields.length; i++) { this.inserter.setNull(i + 1, 0); } } /** * JDBC 2.0 Determine if this row has been deleted. A deleted row may leave * a visible "hole" in a result set. This method can be used to detect holes * in a result set. The value returned depends on whether or not the result * set can detect deletions. * * @return true if deleted and deletes are detected
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -