1 | /* |
2 | |
3 | Derby - Class org.apache.derby.iapi.sql.dictionary.ViewDescriptor |
4 | |
5 | Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable. |
6 | |
7 | Licensed under the Apache License, Version 2.0 (the "License"); |
8 | you may not use this file except in compliance with the License. |
9 | You may obtain a copy of the License at |
10 | |
11 | http://www.apache.org/licenses/LICENSE-2.0 |
12 | |
13 | Unless required by applicable law or agreed to in writing, software |
14 | distributed under the License is distributed on an "AS IS" BASIS, |
15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16 | See the License for the specific language governing permissions and |
17 | limitations under the License. |
18 | |
19 | */ |
20 | |
21 | package org.apache.derby.iapi.sql.dictionary; |
22 | |
23 | import org.apache.derby.catalog.UUID; |
24 | |
25 | import org.apache.derby.iapi.sql.depend.Dependent; |
26 | import org.apache.derby.iapi.sql.depend.Provider; |
27 | import org.apache.derby.iapi.sql.dictionary.GenericDescriptorList; |
28 | import org.apache.derby.iapi.error.StandardException; |
29 | import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; |
30 | import org.apache.derby.iapi.store.access.TransactionController; |
31 | import org.apache.derby.iapi.sql.depend.DependencyManager; |
32 | |
33 | import org.apache.derby.iapi.services.context.ContextService; |
34 | |
35 | import org.apache.derby.iapi.reference.SQLState; |
36 | import org.apache.derby.iapi.services.sanity.SanityManager; |
37 | import org.apache.derby.iapi.sql.StatementType; |
38 | import org.apache.derby.catalog.DependableFinder; |
39 | import org.apache.derby.catalog.Dependable; |
40 | import org.apache.derby.iapi.services.io.StoredFormatIds; |
41 | |
42 | /** |
43 | * This is the implementation of ViewDescriptor. Users of View descriptors |
44 | * should only use the following methods: |
45 | * <ol> |
46 | * <li> getUUID |
47 | * <li> setUUID |
48 | * <li> getViewText |
49 | * <li> setViewName |
50 | * <li> getCheckOptionType |
51 | * <li> getCompSchemaId |
52 | * </ol> |
53 | * |
54 | * @version 0.1 |
55 | * @author Jeff Lichtman |
56 | */ |
57 | |
58 | public class ViewDescriptor extends TupleDescriptor |
59 | implements UniqueTupleDescriptor, Dependent, Provider |
60 | { |
61 | private int checkOption; |
62 | private String viewName; |
63 | private String viewText; |
64 | private UUID uuid; |
65 | private UUID compSchemaId; |
66 | |
67 | public static final int NO_CHECK_OPTION = 0; |
68 | |
69 | /** |
70 | * Constructor for a ViewDescriptor. |
71 | * |
72 | * @param dataDictionary The data dictionary that this descriptor lives in |
73 | * @param viewID The UUID for the view |
74 | * @param viewName The name of the view |
75 | * @param viewText The text of the query expression from the view definition. |
76 | * @param checkOption int check option type |
77 | * @param compSchemaId the schemaid to compile in |
78 | */ |
79 | |
80 | public ViewDescriptor(DataDictionary dataDictionary, UUID viewID, String viewName, String viewText, |
81 | int checkOption, UUID compSchemaId) |
82 | { |
83 | super( dataDictionary ); |
84 | |
85 | uuid = viewID; |
86 | this.viewText = viewText; |
87 | this.viewName = viewName; |
88 | |
89 | /* RESOLVE - No check options for now */ |
90 | if (SanityManager.DEBUG) |
91 | { |
92 | if (checkOption != ViewDescriptor.NO_CHECK_OPTION) |
93 | { |
94 | SanityManager.THROWASSERT("checkOption (" + checkOption + |
95 | ") expected to be " + ViewDescriptor.NO_CHECK_OPTION); |
96 | } |
97 | } |
98 | this.checkOption = checkOption; |
99 | this.compSchemaId = compSchemaId; |
100 | } |
101 | |
102 | // |
103 | // ViewDescriptor interface |
104 | // |
105 | |
106 | /** |
107 | * Gets the UUID of the view. |
108 | * |
109 | * @return The UUID of the view. |
110 | */ |
111 | public UUID getUUID() |
112 | { |
113 | return uuid; |
114 | } |
115 | |
116 | /** |
117 | * Sets the UUID of the view. |
118 | * |
119 | * @param uuid The UUID of the view. |
120 | */ |
121 | public void setUUID(UUID uuid) |
122 | { |
123 | this.uuid = uuid; |
124 | } |
125 | |
126 | /** |
127 | * Gets the text of the view definition. |
128 | * |
129 | * @return A String containing the text of the CREATE VIEW |
130 | * statement that created the view |
131 | */ |
132 | public String getViewText() |
133 | { |
134 | return viewText; |
135 | } |
136 | |
137 | /** |
138 | * Sets the name of the view. |
139 | * |
140 | * @param name The name of the view. |
141 | */ |
142 | public void setViewName(String name) |
143 | { |
144 | viewName = name; |
145 | } |
146 | |
147 | /** |
148 | * Gets an identifier telling what type of check option |
149 | * is on this view. |
150 | * |
151 | * @return An identifier telling what type of check option |
152 | * is on the view. |
153 | */ |
154 | public int getCheckOptionType() |
155 | { |
156 | return checkOption; |
157 | } |
158 | |
159 | /** |
160 | * Get the compilation type schema id when this view |
161 | * was first bound. |
162 | * |
163 | * @return the schema UUID |
164 | */ |
165 | public UUID getCompSchemaId() |
166 | { |
167 | return compSchemaId; |
168 | } |
169 | |
170 | |
171 | // |
172 | // Provider interface |
173 | // |
174 | |
175 | /** |
176 | @return the stored form of this provider |
177 | |
178 | @see Dependable#getDependableFinder |
179 | */ |
180 | public DependableFinder getDependableFinder() |
181 | { |
182 | return getDependableFinder(StoredFormatIds.VIEW_DESCRIPTOR_FINDER_V01_ID); |
183 | } |
184 | |
185 | /** |
186 | * Return the name of this Provider. (Useful for errors.) |
187 | * |
188 | * @return String The name of this provider. |
189 | */ |
190 | public String getObjectName() |
191 | { |
192 | return viewName; |
193 | } |
194 | |
195 | /** |
196 | * Get the provider's UUID |
197 | * |
198 | * @return String The provider's UUID |
199 | */ |
200 | public UUID getObjectID() |
201 | { |
202 | return uuid; |
203 | } |
204 | |
205 | /** |
206 | * Get the provider's type. |
207 | * |
208 | * @return String The provider's type. |
209 | */ |
210 | public String getClassType() |
211 | { |
212 | return Dependable.VIEW; |
213 | } |
214 | |
215 | // |
216 | // Dependent Inteface |
217 | // |
218 | /** |
219 | Check that all of the dependent's dependencies are valid. |
220 | |
221 | @return true if the dependent is currently valid |
222 | */ |
223 | public boolean isValid() |
224 | { |
225 | return true; |
226 | } |
227 | |
228 | /** |
229 | Prepare to mark the dependent as invalid (due to at least one of |
230 | its dependencies being invalid). |
231 | |
232 | @param action The action causing the invalidation |
233 | @param p the provider |
234 | |
235 | @exception StandardException thrown if unable to make it invalid |
236 | */ |
237 | public void prepareToInvalidate(Provider p, int action, |
238 | LanguageConnectionContext lcc) |
239 | throws StandardException |
240 | { |
241 | switch ( action ) |
242 | { |
243 | /* |
244 | * We don't care about creating or dropping indexes or |
245 | * alter table on an underlying table. |
246 | */ |
247 | case DependencyManager.CREATE_INDEX: |
248 | case DependencyManager.DROP_INDEX: |
249 | case DependencyManager.CREATE_CONSTRAINT: |
250 | case DependencyManager.ALTER_TABLE: |
251 | case DependencyManager.CREATE_TRIGGER: |
252 | case DependencyManager.DROP_TRIGGER: |
253 | |
254 | case DependencyManager.BULK_INSERT: |
255 | case DependencyManager.COMPRESS_TABLE: |
256 | case DependencyManager.RENAME_INDEX: |
257 | case DependencyManager.UPDATE_STATISTICS: |
258 | case DependencyManager.DROP_STATISTICS: |
259 | case DependencyManager.TRUNCATE_TABLE: |
260 | /* |
261 | ** Set constriants is a bit odd in that it |
262 | ** will send a SET_CONSTRAINTS on the table |
263 | ** when it enables a constraint, rather than |
264 | ** on the constraint. So since we depend on |
265 | ** the table, we have to deal with this action. |
266 | */ |
267 | case DependencyManager.SET_CONSTRAINTS_ENABLE: |
268 | case DependencyManager.SET_TRIGGERS_ENABLE: |
269 | break; |
270 | |
271 | default: |
272 | |
273 | DependencyManager dm; |
274 | |
275 | dm = getDataDictionary().getDependencyManager(); |
276 | throw StandardException.newException(SQLState.LANG_PROVIDER_HAS_DEPENDENT_VIEW, |
277 | dm.getActionString(action), |
278 | p.getObjectName(), viewName); |
279 | |
280 | } // end switch |
281 | } |
282 | |
283 | /** |
284 | Mark the dependent as invalid (due to at least one of |
285 | its dependencies being invalid). |
286 | |
287 | @param action The action causing the invalidation |
288 | |
289 | @exception StandardException thrown if unable to make it invalid |
290 | */ |
291 | public void makeInvalid(int action, LanguageConnectionContext lcc) |
292 | throws StandardException |
293 | { |
294 | switch ( action ) |
295 | { |
296 | /* creating or dropping another publication won't affect |
297 | * this view. so we allow these actions. |
298 | * We don't care about creating or dropping indexes or |
299 | * alter table on an underlying table. |
300 | */ |
301 | case DependencyManager.CREATE_INDEX: |
302 | case DependencyManager.DROP_INDEX: |
303 | case DependencyManager.ALTER_TABLE: |
304 | case DependencyManager.CREATE_CONSTRAINT: |
305 | case DependencyManager.BULK_INSERT: |
306 | case DependencyManager.COMPRESS_TABLE: |
307 | case DependencyManager.SET_CONSTRAINTS_ENABLE: |
308 | case DependencyManager.SET_TRIGGERS_ENABLE: |
309 | case DependencyManager.CREATE_TRIGGER: |
310 | case DependencyManager.DROP_TRIGGER: |
311 | case DependencyManager.RENAME_INDEX: |
312 | case DependencyManager.UPDATE_STATISTICS: |
313 | case DependencyManager.DROP_STATISTICS: |
314 | case DependencyManager.TRUNCATE_TABLE: |
315 | break; |
316 | |
317 | default: |
318 | |
319 | /* We should never get here, since we can't have dangling references */ |
320 | if (SanityManager.DEBUG) |
321 | { |
322 | SanityManager.THROWASSERT("did not expect to get called"); |
323 | } |
324 | break; |
325 | |
326 | } // end switch |
327 | |
328 | } |
329 | |
330 | /** |
331 | Attempt to revalidate the dependent. For prepared statements, |
332 | this could go through its dependencies and check that they |
333 | are up to date; if not, it would recompile the statement. |
334 | Any failure during this attempt should throw |
335 | StandardException.unableToRevalidate(). |
336 | |
337 | @exception StandardException thrown if unable to make it valid |
338 | */ |
339 | public void makeValid(LanguageConnectionContext lcc) |
340 | throws StandardException |
341 | { |
342 | } |
343 | |
344 | // |
345 | // class interface |
346 | // |
347 | |
348 | /** |
349 | * Prints the contents of the ViewDescriptor |
350 | * |
351 | * @return The contents as a String |
352 | */ |
353 | public String toString() |
354 | { |
355 | if (SanityManager.DEBUG) |
356 | { |
357 | return "uuid: " + uuid + " viewName: " + viewName + "\n" + |
358 | "viewText: " + viewText + "\n" + |
359 | "checkOption: " + checkOption + "\n" + |
360 | "compSchemaId: " + compSchemaId + "\n"; |
361 | } |
362 | else |
363 | { |
364 | return ""; |
365 | } |
366 | } |
367 | |
368 | public void dropViewWork(DataDictionary dd, DependencyManager dm, |
369 | LanguageConnectionContext lcc, TransactionController tc, |
370 | SchemaDescriptor sd, TableDescriptor td, boolean cascade) |
371 | throws StandardException |
372 | { |
373 | /* Drop the columns */ |
374 | dd.dropAllColumnDescriptors(td.getUUID(), tc); |
375 | |
376 | /* Prepare all dependents to invalidate. (This is there chance |
377 | * to say that they can't be invalidated. For example, an open |
378 | * cursor referencing a table/view that the user is attempting to |
379 | * drop.) If no one objects, then invalidate any dependent objects. |
380 | */ |
381 | dm.invalidateFor(td, DependencyManager.DROP_VIEW, lcc); |
382 | |
383 | /* Clear the dependencies for the view */ |
384 | dm.clearDependencies(lcc, this); |
385 | |
386 | /* Drop the view */ |
387 | dd.dropViewDescriptor(this, tc); |
388 | |
389 | /* Drop the table */ |
390 | dd.dropTableDescriptor(td, sd, tc); |
391 | } |
392 | |
393 | |
394 | } |