001: /*
002:
003: Derby - Class org.apache.derby.vti.DeferModification
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to You under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.vti;
023:
024: import java.sql.SQLException;
025:
026: /**
027: * This interface is implemented by a read/write VTI class that wants to control when
028: * modifications to the VTI are deferred, or to be notified that a it is to be modified.
029: * Consider the following statement:<br>
030: * UPDATE NEW myVTI(...)
031: * SET cost = cost + 10
032: * WHERE cost < 15
033: *<p>
034: * Updating a column that is used in the WHERE clause might or might not give the VTI implementation trouble;
035: * the update might cause the same row to be selected more than once. This problem can be solved by building the
036: * complete list of rows to be updated and the new column values before updating any rows. The updates are applied
037: * after the list is built. This process is called "deferred update".
038: *<p>
039: * By default, updates on a VTI are deferred when the VTI ResultSet
040: * is scrollable (ResultSet.TYPE_SCROLL_SENSITIVE or TYPE_SCROLL_INSENSITIVE), and one or more of the following is true.
041: *<ol>
042: *<li>One or more of the columns in the SET clause is also used in the WHERE
043: * clause and the VTI ResultSet is sensitive. We do not defer updates
044: * when the ResultSet is TYPE_SCROLL_INSENSITIVE because it is not necessary.
045: *<li>The where clause contains a subselect on a VTI from the same class as the
046: * target VTI. We do not look at the VTI parameters, just the VTI class name.
047: *</ol>
048: *<p>
049: * By default, deletes on a VTI are deferred in a similar situation: when the VTI ResultSet
050: * is scrollable (ResultSet.TYPE_SCROLL_SENSITIVE or TYPE_SCROLL_INSENSITIVE), and
051: * the where clause contains a subselect on a VTI from the same class as the
052: * target VTI. We do not look at the VTI parameters, just the VTI class name.
053: *<p>
054: * By default, inserts into a VTI are deferred when the same VTI class is used as both
055: * the source and target. It does not depend on the scrollability of the
056: * VTI ResultSet because inserts can be deferred without scrolling the ResultSet.
057: *<p>
058: * If these defaults are not appropriate then the class implementing the VTI should also implement
059: * this interface (org.apache.derby.vti.DeferModification).
060: *<p>
061: * (A read/write VTI is implemented by a class that implements the java.sql.PreparedStatement interface,
062: * often by extending the UpdatableVTITemplate interface. @see UpdatableVTITemplate).
063: *<p>
064: * Update and delete statement deferral is implemented by scrolling the VTI's ResultSet. Therefore,
065: * updates and deletes on a VTI are never deferred unless the VTI's ResultSets are scrollable, even
066: * if the DeferModification interface methods return <b>true</b>.
067: * Therefore for an update or delete to be deferred the VTI getResultSetType() method must return
068: * ResultSet.TYPE_SCROLL_SENSITIVE or TYPE_SCROLL_INSENSITIVE and the VTI must produce scrollable
069: * java.sql.ResultSets that implement the getRow() and absolute() methods. If your VTI is implemented as
070: * an extension to UpdatableVTITemplate then you must override the getResultSetMethod:
071: * UpdatableVTITemplate.getResultSetType()
072: * throws an exception. If your VTI's ResultSets are implemented as extensions to VTITemplate then you must
073: * override the getRow() and absolute() methods: VTITemplate.getRow() and absolute() throw exceptions.
074: *<p>
075: * This interface is not used when the VTI is referenced only in a subselect; it is only used when a
076: * VTI appears as the target of an INSERT, UPDATE, or DELETE statement.
077: */
078: public interface DeferModification {
079:
080: public static final int INSERT_STATEMENT = 1;
081: public static final int UPDATE_STATEMENT = 2;
082: public static final int DELETE_STATEMENT = 3;
083:
084: /**
085: * This method is called during preparation of an insert, update, or delete statement with this VTI
086: * as the target. It indicates whether the statement should be deferred irregardless of the other clauses
087: * in the statement. If alwaysDefer returns <b>true</b> then the other methods in this interface
088: * are not called. (At least not for this statement type).
089: *
090: * @param statementType One of INSERT_STATEMENT, UPDATE_STATEMENT, DELETE_STATEMENT.
091: *
092: * @return <b>true</b> if the statement type should always be deferred on this VTI,
093: * <b>false</b> other criteria (see below) should be examined to determine
094: * whether to defer the modification.
095: *
096: * @exception SQLException on an unexpected condition.
097: */
098: public boolean alwaysDefer(int statementType) throws SQLException;
099:
100: /**
101: * This method is called during preparation of an update or delete statement on the virtual
102: * table if getResultSetType() returns ResultSet.TYPE_SCROLL_SENSITIVE or TYPE_SCROLL_SENSITIVE and
103: * alwaysDefer( statementType) returns <b>false</b>.
104: * ColumnRequiresDefer is called once for each column that is being updated,
105: * or each column in a DELETE where clause until
106: * it returns <b>true</b> or until all the columns have been exhausted.
107: *
108: * @param statementType UPDATE_STATEMENT or DELETE_STATEMENT.
109: * @param columnName the name of one of the columns being updated
110: * @param inWhereClause indicates whether the column also appears in the where clause
111: *
112: * @return <b>true</b> if the update must be deferred
113: * <b>false</b> if this column does not require a deferred update
114: *
115: * @exception SQLException a parameter is invalid or there is another unexpected failure.
116: */
117: public boolean columnRequiresDefer(int statementType,
118: String columnName, boolean inWhereClause)
119: throws SQLException;
120:
121: /**
122: * This method is called during preparation of an insert, update, or delete statement that has this virtual
123: * table as its target and that has a sub-select. It is invoked once for each regular table in a sub-select,
124: * if it has not already been determined that the statement should be deferred or that the VTI does not support
125: * deferral.
126: *
127: * @param statementType the statement type: INSERT_STATEMENT, UPDATE_STATEMENT, or DELETE_STATEMENT.
128: * @param schemaName the schema of the table in the sub-select.
129: * @param tableName the name of the table in the sub-select.
130: *
131: * @return <b>true</b> if the modification must be deferred
132: * <b>false</b> if this source table does not necessitate a deferred modification
133: *
134: * @exception SQLException a parameter is invalid or there is another unexpected failure.
135: */
136: public boolean subselectRequiresDefer(int statementType,
137: String schemaName, String tableName) throws SQLException;
138:
139: /**
140: * This method is called during preparation of an insert, update, or delete statement that has this virtual
141: * table as its target and that has a sub-select. It is invoked once for each virtual table in the sub-select,
142: * if it has not already been determined that the statement should be deferred or that the VTI does not support
143: * deferral.
144: *
145: * @param statementType the statement type: INSERT_STATEMENT, UPDATE_STATEMENT, or DELETE_STATEMENT.
146: * @param VTIClassName the name of the class implementing the VTI in the sub-select.
147: *
148: * @return <b>true</b> if the modification must be deferred
149: * <b>false</b> if this source table does not necessitate a deferred modification
150: *
151: * @exception SQLException a parameter is invalid or there is another unexpected failure.
152: */
153: public boolean subselectRequiresDefer(int statementType,
154: String VTIClassName) throws SQLException;
155:
156: /**
157: * This VTI method is called by Cloudscape when a VTI modification (insert, update, or delete)
158: * is executed. It is called after the VTI has been instantiated but before any rows are read,
159: * inserted, updated, or deleted.
160: *
161: * @param statementType one of INSERT_STATEMENT, UPDATE_STATEMENT, or DELETE_STATEMENT
162: * @param deferred <b>true</b> if the modification will be deferred, <b>false</b> if not.
163: *
164: * @exception SQLException thrown on an unexpected failure
165: */
166: public void modificationNotify(int statementType, boolean deferred)
167: throws SQLException;
168: }
|