📄 updatableresultset.java
字号:
return; } this.isUpdatable = true; this.notUpdatableReason = null; return; } /** * 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. * @throws SQLException * if the ResultSet is not updatable or some other error occurs */ public synchronized void deleteRow() throws SQLException { checkClosed(); if (!this.isUpdatable) { throw new NotUpdatable(this.notUpdatableReason); } if (this.onInsertRow) { throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.1")); //$NON-NLS-1$ } else if (this.rowData.size() == 0) { throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.2")); //$NON-NLS-1$ } else if (isBeforeFirst()) { throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.3")); //$NON-NLS-1$ } else if (isAfterLast()) { throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.4")); //$NON-NLS-1$ } if (this.deleter == null) { if (this.deleteSQL == null) { generateStatements(); } this.deleter = this.connection .clientPrepareStatement(this.deleteSQL); } this.deleter.clearParameters(); String characterEncoding = null; if (this.connection.getUseUnicode()) { characterEncoding = this.connection.getEncoding(); } // // FIXME: Use internal routines where possible for character // conversion! try { int numKeys = this.primaryKeyIndicies.size(); if (numKeys == 1) { int index = ((Integer) this.primaryKeyIndicies.get(0)) .intValue(); String currentVal = ((characterEncoding == null) ? new String( (byte[]) this.thisRow[index]) : new String( (byte[]) this.thisRow[index], characterEncoding)); this.deleter.setString(1, currentVal); } else { for (int i = 0; i < numKeys; i++) { int index = ((Integer) this.primaryKeyIndicies.get(i)) .intValue(); String currentVal = ((characterEncoding == null) ? new String( (byte[]) this.thisRow[index]) : new String((byte[]) this.thisRow[index], characterEncoding)); this.deleter.setString(i + 1, currentVal); } } this.deleter.executeUpdate(); this.rowData.removeRow(this.rowData.getCurrentRowNumber()); } catch (java.io.UnsupportedEncodingException encodingEx) { throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.39", //$NON-NLS-1$ new Object[] { this.charEncoding }) //$NON-NLS-1$ , SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ //$NON-NLS-2$ } } private synchronized void extractDefaultValues() throws SQLException { java.sql.DatabaseMetaData dbmd = this.connection.getMetaData(); java.sql.ResultSet columnsResultSet = null; try { columnsResultSet = dbmd.getColumns(this.catalog, null, this.tableOnlyName, "%"); //$NON-NLS-1$ HashMap columnNameToDefaultValueMap = new HashMap( this.fields.length /* at least this big... */); while (columnsResultSet.next()) { String columnName = columnsResultSet.getString("COLUMN_NAME"); //$NON-NLS-1$ byte[] defaultValue = columnsResultSet.getBytes("COLUMN_DEF"); //$NON-NLS-1$ columnNameToDefaultValueMap.put(columnName, defaultValue); } int numFields = this.fields.length; this.defaultColumnValue = new byte[numFields][]; for (int i = 0; i < numFields; i++) { String defValTableName = this.fields[i].getOriginalName(); if ((defValTableName == null) || (defValTableName.length() == 0)) { defValTableName = this.fields[i].getName(); } if (defValTableName != null) { byte[] defaultVal = (byte[]) columnNameToDefaultValueMap .get(defValTableName); this.defaultColumnValue[i] = defaultVal; } } } finally { if (columnsResultSet != null) { columnsResultSet.close(); columnsResultSet = null; } } } /** * JDBC 2.0 * * <p> * Moves to the first 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 first() throws SQLException { return super.first(); } /** * Figure out whether or not this ResultSet is updateable, and if so, * generate the PreparedStatements to support updates. * * @throws SQLException * DOCUMENT ME! * @throws NotUpdatable * DOCUMENT ME! */ protected synchronized void generateStatements() throws SQLException { if (!this.isUpdatable) { this.doingUpdates = false; this.onInsertRow = false; throw new NotUpdatable(this.notUpdatableReason); } String quotedId = getQuotedIdChar(); if (this.fields[0].getOriginalTableName() != null) { StringBuffer tableNameBuffer = new StringBuffer(); String databaseName = this.fields[0].getDatabaseName(); if ((databaseName != null) && (databaseName.length() > 0)) { tableNameBuffer.append(quotedId); tableNameBuffer.append(databaseName); tableNameBuffer.append(quotedId); tableNameBuffer.append('.'); } this.tableOnlyName = this.fields[0].getOriginalTableName(); tableNameBuffer.append(quotedId); tableNameBuffer.append(this.tableOnlyName); tableNameBuffer.append(quotedId); this.qualifiedAndQuotedTableName = tableNameBuffer.toString(); } else { StringBuffer tableNameBuffer = new StringBuffer(); this.tableOnlyName = this.fields[0].getTableName(); tableNameBuffer.append(quotedId); tableNameBuffer.append(this.tableOnlyName); tableNameBuffer.append(quotedId); this.qualifiedAndQuotedTableName = tableNameBuffer.toString(); } this.primaryKeyIndicies = new ArrayList(); StringBuffer fieldValues = new StringBuffer(); StringBuffer keyValues = new StringBuffer(); StringBuffer columnNames = new StringBuffer(); StringBuffer insertPlaceHolders = new StringBuffer(); boolean firstTime = true; boolean keysFirstTime = true; String equalsStr = this.connection.versionMeetsMinimum(3, 23, 0) ? "<=>" : "="; for (int i = 0; i < this.fields.length; i++) { String originalColumnName = this.fields[i].getOriginalName(); String columnName = null; if (this.connection.getIO().hasLongColumnInfo() && (originalColumnName != null) && (originalColumnName.length() > 0)) { columnName = originalColumnName; } else { columnName = this.fields[i].getName(); } if (this.fields[i].isPrimaryKey()) { this.primaryKeyIndicies.add(new Integer(i)); if (!keysFirstTime) { keyValues.append(" AND "); //$NON-NLS-1$ } else { keysFirstTime = false; } keyValues.append(quotedId); keyValues.append(columnName); keyValues.append(quotedId); keyValues.append(equalsStr); keyValues.append("?"); //$NON-NLS-1$ } if (firstTime) { firstTime = false; fieldValues.append("SET "); //$NON-NLS-1$ } else { fieldValues.append(","); //$NON-NLS-1$ columnNames.append(","); //$NON-NLS-1$ insertPlaceHolders.append(","); //$NON-NLS-1$ } insertPlaceHolders.append("?"); //$NON-NLS-1$ columnNames.append(quotedId); columnNames.append(columnName); columnNames.append(quotedId); fieldValues.append(quotedId); fieldValues.append(columnName); fieldValues.append(quotedId); fieldValues.append("=?"); //$NON-NLS-1$ } this.updateSQL = "UPDATE " + this.qualifiedAndQuotedTableName + " " //$NON-NLS-1$ //$NON-NLS-2$ + fieldValues.toString() //$NON-NLS-1$ //$NON-NLS-2$ + " WHERE " + keyValues.toString(); //$NON-NLS-1$ this.insertSQL = "INSERT INTO " + this.qualifiedAndQuotedTableName //$NON-NLS-1$ + " (" + columnNames.toString() //$NON-NLS-1$ //$NON-NLS-2$ + ") VALUES (" + insertPlaceHolders.toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ this.refreshSQL = "SELECT " + columnNames.toString() + " FROM " //$NON-NLS-1$ //$NON-NLS-2$ + this.qualifiedAndQuotedTableName //$NON-NLS-1$ //$NON-NLS-2$ + " WHERE " + keyValues.toString(); //$NON-NLS-1$ this.deleteSQL = "DELETE FROM " + this.qualifiedAndQuotedTableName //$NON-NLS-1$ + " WHERE " //$NON-NLS-1$ //$NON-NLS-2$ + keyValues.toString(); } private synchronized SingleByteCharsetConverter getCharConverter() throws SQLException { if (!this.initializedCharConverter) { this.initializedCharConverter = true; if (this.connection.getUseUnicode()) { this.charEncoding = connection.getEncoding(); this.charConverter = this.connection .getCharsetConverter(this.charEncoding); } } return this.charConverter; } /** * JDBC 2.0 Return the concurrency of this result set. The concurrency used * is determined by the statement that created the result set. * * @return the concurrency type, CONCUR_READ_ONLY, etc. * * @exception SQLException * if a database-access error occurs */ public int getConcurrency() throws SQLException { return (this.isUpdatable ? CONCUR_UPDATABLE : CONCUR_READ_ONLY); } private synchronized String getQuotedIdChar() throws SQLException { if (this.quotedIdChar == null) { boolean useQuotedIdentifiers = this.connection .supportsQuotedIdentifiers(); if (useQuotedIdentifiers) { java.sql.DatabaseMetaData dbmd = this.connection.getMetaData(); this.quotedIdChar = dbmd.getIdentifierQuoteString(); } else { this.quotedIdChar = ""; //$NON-NLS-1$ } } return this.quotedIdChar; } /** * JDBC 2.0 Insert the contents of the insert row into the result set and * the database. Must be on the insert row when this method is called. * * @exception SQLException * if a database-access error occurs, if called when not on * the insert row, or if all non-nullable columns in the * insert row have not been given a value */ public synchronized void insertRow() throws SQLException { checkClosed(); if (!this.onInsertRow) { throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.7")); //$NON-NLS-1$ } this.inserter.executeUpdate(); long autoIncrementId = this.inserter.getLastInsertID(); int numFields = this.fields.length; byte[][] newRow = new byte[numFields][]; for (int i = 0; i < numFields; i++) { if (this.inserter.isNull(i)) { newRow[i] = null; } else { newRow[i] = this.inserter.getBytesRepresentation(i); } // // WARN: This non-variant only holds if MySQL never allows more // than one auto-increment key (which is the way it is _today_) // if (this.fields[i].isAutoIncrement() && autoIncrementId > 0) { newRow[i] = String.valueOf(autoIncrementId).getBytes(); this.inserter.setBytesNoEscapeNoQuotes(i + 1, newRow[i]); } } refreshRow(this.inserter, newRow); this.rowData.addRow(newRow); resetInserter(); } /** * JDBC 2.0 * * <p> * Determine if the cursor is after the last row in the result set. * </p> * * @return true if after the last row, false otherwise. Returns false when * the result set contains no rows. * * @exception SQLException * if a database-access error occurs. */ public synchronized boolean isAfterLast() throws SQLException { return super.isAfterLast(); } /** * JDBC 2.0 * * <p> * Determine if the cursor is before the first row in the result set. * </p> * * @return true if before the first row, false otherwise. Returns false when * the result set contains no rows. * * @exception SQLException * if a database-access error occurs. */ public synchronized boolean isBeforeFirst() throws SQLException { return super.isBeforeFirst(); } /** * JDBC 2.0 * * <p> * Determine if the cursor is on the first row of the result set. * </p> * * @return true if on the first row, false otherwise. * * @exception SQLException * if a database-access error occurs. */ public synchronized boolean isFirst() throws SQLException { return super.isFirst(); } /** * JDBC 2.0 * * <p> * Determine if the cursor is on the last row of the result set. Note: * Calling isLast() may be expensive since the JDBC driver might need to * fetch ahead one row in order to determine whether the current row is the * last row in the result set. * </p> * * @return true if on the last row, false otherwise. * * @exception SQLException * if a database-access error occurs. */ public synchronized boolean isLast() throws SQLException { return super.isLast(); } boolean isUpdatable() { return this.isUpdatable; } /** * JDBC 2.0 *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -