001: /**
002: * Sequoia: Database clustering technology.
003: * Copyright (C) 2002-2004 French National Institute For Research In Computer
004: * Science And Control (INRIA).
005: * Copyright (C) 2005-2006 Continuent, Inc.
006: * Contact: sequoia@continuent.org
007: *
008: * Licensed under the Apache License, Version 2.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * 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: * Initial developer(s): Julie Marguerite.
021: * Contributor(s): Mathieu Peltier.
022: */package org.continuent.sequoia.controller.requests;
023:
024: import java.io.Serializable;
025: import java.sql.SQLException;
026: import java.util.SortedSet;
027: import java.util.TreeSet;
028:
029: import org.continuent.sequoia.common.i18n.Translate;
030: import org.continuent.sequoia.common.sql.schema.DatabaseSchema;
031: import org.continuent.sequoia.common.sql.schema.DatabaseTable;
032:
033: /**
034: * An <code>DropRequest</code> is an SQL request with the following syntax:
035: *
036: * <pre>
037: * DROP TABLE table-name
038: * </pre>
039: *
040: * @author <a href="mailto:Julie.Marguerite@inria.fr">Julie Marguerite </a>
041: * @author <a href="mailto:Mathieu.Peltier@inrialpes.fr">Mathieu Peltier </a>
042: * @version 1.0
043: */
044: public class DropRequest extends AbstractWriteRequest implements
045: Serializable {
046: private static final long serialVersionUID = 5702833689405251895L;
047:
048: // Be conservative, if we cannot parse the query, assumes it invalidates
049: // everything
050: protected boolean altersAggregateList = true;
051: protected boolean altersDatabaseCatalog = true;
052: protected boolean altersDatabaseSchema = true;
053: protected boolean altersMetadataCache = true;
054: protected boolean altersQueryResultCache = true;
055: protected boolean altersSomething = true;
056: protected boolean altersStoredProcedureList = true;
057: protected boolean altersUserDefinedTypes = true;
058: protected boolean altersUsers = true;
059:
060: /**
061: * Sorted list of table names that are being dropped. This will be used to
062: * remove these tables from the schema.
063: */
064: protected SortedSet tablesToDrop = null;
065:
066: /**
067: * Creates a new <code>DropRequest</code> instance. The caller must give an
068: * SQL request, without any leading or trailing spaces and beginning with
069: * 'create table ' (it will not be checked).
070: * <p>
071: * The request is not parsed but it can be done later by a call to
072: * {@link #parse(DatabaseSchema, int, boolean)}.
073: *
074: * @param sqlQuery the SQL request
075: * @param escapeProcessing should the driver to escape processing before
076: * sending to the database ?
077: * @param timeout an <code>int</code> value
078: * @param lineSeparator the line separator used in the query
079: * @see #parse
080: */
081: public DropRequest(String sqlQuery, boolean escapeProcessing,
082: int timeout, String lineSeparator) {
083: super (sqlQuery, escapeProcessing, timeout, lineSeparator,
084: RequestType.DROP);
085: setMacrosAreProcessed(true); // no macro processing needed
086: }
087:
088: /**
089: * @see org.continuent.sequoia.controller.requests.AbstractRequest#altersAggregateList()
090: */
091: public boolean altersAggregateList() {
092: return altersAggregateList;
093: }
094:
095: /**
096: * @see org.continuent.sequoia.controller.requests.AbstractRequest#altersDatabaseCatalog()
097: */
098: public boolean altersDatabaseCatalog() {
099: return altersDatabaseCatalog;
100: }
101:
102: /**
103: * @see org.continuent.sequoia.controller.requests.AbstractRequest#altersDatabaseSchema()
104: */
105: public boolean altersDatabaseSchema() {
106: return altersDatabaseSchema;
107: }
108:
109: /**
110: * @see org.continuent.sequoia.controller.requests.AbstractRequest#altersMetadataCache()
111: */
112: public boolean altersMetadataCache() {
113: return altersMetadataCache;
114: }
115:
116: /**
117: * @see org.continuent.sequoia.controller.requests.AbstractRequest#altersQueryResultCache()
118: */
119: public boolean altersQueryResultCache() {
120: return altersQueryResultCache;
121: }
122:
123: /**
124: * @see org.continuent.sequoia.controller.requests.AbstractRequest#altersSomething()
125: */
126: public boolean altersSomething() {
127: return altersSomething;
128: }
129:
130: /**
131: * @see org.continuent.sequoia.controller.requests.AbstractRequest#altersStoredProcedureList()
132: */
133: public boolean altersStoredProcedureList() {
134: return altersStoredProcedureList;
135: }
136:
137: /**
138: * @see org.continuent.sequoia.controller.requests.AbstractRequest#altersUserDefinedTypes()
139: */
140: public boolean altersUserDefinedTypes() {
141: return altersUserDefinedTypes;
142: }
143:
144: /**
145: * @see org.continuent.sequoia.controller.requests.AbstractRequest#altersUsers()
146: */
147: public boolean altersUsers() {
148: return altersUsers;
149: }
150:
151: /**
152: * @see AbstractRequest#cloneParsing(AbstractRequest)
153: */
154: public void cloneParsing(AbstractRequest request) {
155: if (!request.isParsed())
156: return;
157: cloneTableNameAndColumns((AbstractWriteRequest) request);
158: isParsed = true;
159: }
160:
161: /**
162: * @see org.continuent.sequoia.controller.requests.AbstractRequest#needsMacroProcessing()
163: */
164: public boolean needsMacroProcessing() {
165: return false;
166: }
167:
168: /**
169: * @see org.continuent.sequoia.controller.requests.AbstractRequest#parse(org.continuent.sequoia.common.sql.schema.DatabaseSchema,
170: * int, boolean)
171: */
172: public void parse(DatabaseSchema schema, int granularity,
173: boolean isCaseSensitive) throws SQLException {
174: if (granularity == ParsingGranularities.NO_PARSING) {
175: isParsed = true;
176: return;
177: }
178:
179: String originalSQL = this .trimCarriageReturnAndTabs();
180: String sql = originalSQL.toLowerCase();
181:
182: // Strip drop
183: sql = sql.substring("drop".length()).trim();
184: originalSQL = originalSQL.substring("drop".length()).trim();
185:
186: // Check what kind of create we are facing
187: if (sql.startsWith("database")) { // DROP DATABASE alters only the database catalog
188: altersDatabaseCatalog = true;
189: altersDatabaseSchema = false;
190: altersStoredProcedureList = false;
191: altersUserDefinedTypes = false;
192: altersUsers = false;
193: return;
194: }
195:
196: if (sql.startsWith("index") || sql.startsWith("role")
197: || sql.startsWith("sequence")) { // Does not alter anything :
198: // DROP INDEX
199: // DROP ROLE
200: // DROP SEQUENCE
201: altersSomething = false;
202: return;
203: }
204: if (sql.startsWith("function") || sql.startsWith("method")
205: || sql.startsWith("procedure")
206: || sql.startsWith("trigger") || sql.startsWith("type")) { // DROP FUNCTION, DROP METHOD, DROP PROCEDURE, DROP TRIGGER and
207: // DROP TYPE only alters definitions
208: altersDatabaseCatalog = false;
209: altersDatabaseSchema = false;
210: altersStoredProcedureList = true;
211: altersUserDefinedTypes = true;
212: altersUsers = false;
213: return;
214: }
215:
216: // From this point on, only the schema is affected
217: altersDatabaseCatalog = false;
218: altersDatabaseSchema = true;
219: altersStoredProcedureList = false;
220: altersUserDefinedTypes = false;
221: altersUsers = false;
222: if (sql.startsWith("schema") || sql.startsWith("view"))
223: // No parsing to do
224: return;
225:
226: // Strip 'drop (temporary) table '
227: int tableIdx = sql.indexOf("table");
228: if (tableIdx < 0)
229: throw new SQLException("Unsupported DROP statement: '"
230: + sqlQueryOrTemplate + "'");
231:
232: if (isCaseSensitive)
233: sql = originalSQL.substring(tableIdx + 5).trim();
234: else
235: sql = sql.substring(tableIdx + 5).trim();
236:
237: int endTableName = sql.indexOf(" ");
238:
239: if (endTableName >= 0)
240: sql = sql.substring(0, endTableName).trim();
241:
242: if (schema == null)
243: tableName = sql;
244: else {
245: // Get the table on which DROP occurs
246: DatabaseTable t = schema.getTable(sql, isCaseSensitive);
247: if (t == null)
248: throw new SQLException("Unknown table '" + sql
249: + "' in this DROP statement '"
250: + sqlQueryOrTemplate + "'", "42P01");
251: else
252: tableName = t.getName();
253: }
254: writeLockedTables = new TreeSet();
255: tablesToDrop = new TreeSet();
256: writeLockedTables.add(tableName);
257: tablesToDrop.add(tableName);
258: addDependingTables(schema, writeLockedTables);
259: isParsed = true;
260: }
261:
262: /**
263: * Does this request returns a ResultSet?
264: *
265: * @return false
266: */
267: public boolean returnsResultSet() {
268: return false;
269: }
270:
271: /**
272: * @see org.continuent.sequoia.controller.requests.AbstractRequest#getParsingResultsAsString()
273: */
274: public String getParsingResultsAsString() {
275: StringBuffer sb = new StringBuffer(super
276: .getParsingResultsAsString());
277: sb.append(Translate.get("request.alters", new String[] {
278: String.valueOf(altersAggregateList()),
279: String.valueOf(altersDatabaseCatalog()),
280: String.valueOf(altersDatabaseSchema()),
281: String.valueOf(altersMetadataCache()),
282: String.valueOf(altersQueryResultCache()),
283: String.valueOf(altersSomething()),
284: String.valueOf(altersStoredProcedureList()),
285: String.valueOf(altersUserDefinedTypes()),
286: String.valueOf(altersUsers()) }));
287: return sb.toString();
288: }
289:
290: /**
291: * Displays some debugging information about this request.
292: */
293: public void debug() {
294: super .debug();
295: if (tableName != null)
296: System.out.println("Dropped table '" + tableName + "'");
297: else
298: System.out.println("No information about dropped table");
299:
300: System.out.println();
301: }
302:
303: /**
304: * Return the set of tables that are dropped by current request. This set is
305: * different of writeLockedTables, as the latest also contains tables that
306: * need to be locked (because of foreign key constraints).
307: *
308: * @return set of tables that are being dropped by this request
309: */
310: public SortedSet getTablesToDrop() {
311: return tablesToDrop;
312: }
313: }
|