KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hsqldb > View


1 /* Copyright (c) 2001-2005, The HSQL Development Group
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of the HSQL Development Group nor the names of its
15  * contributors may be used to endorse or promote products derived from this
16  * software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
22  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */

30
31
32 package org.hsqldb;
33
34 import org.hsqldb.HsqlNameManager.HsqlName;
35 import org.hsqldb.lib.HsqlArrayList;
36 import org.hsqldb.lib.Iterator;
37
38 // fredt@users 20020420 - patch523880 by leptipre@users - VIEW support - modified
39
// fredt@users 20031227 - remimplementated as compiled query
40

41 /**
42  * Represents an SQL VIEW based on a SELECT statement.
43  *
44  * @author leptipre@users
45  * @author fredt@users
46  * @version 1.8.0
47  * @since 1.7.0
48  */

49 class View extends Table {
50
51     Select viewSelect;
52     SubQuery viewSubQuery;
53     private String JavaDoc statement;
54     private HsqlName[] colList;
55
56     /** schema at the time of compilation */
57     HsqlName compileTimeSchema;
58
59     /**
60      * List of subqueries in this view in order of materialization. Last
61      * element is the view itself.
62      */

63     SubQuery[] viewSubqueries;
64
65     /**
66      * Constructor.
67      * @param Session
68      * @param db database
69      * @param name HsqlName of the view
70      * @param definition SELECT statement of the view
71      * @param columns array of HsqlName column names
72      * @throws HsqlException
73      */

74     View(Session session, Database db, HsqlName name, String JavaDoc definition,
75             HsqlName[] columns) throws HsqlException {
76
77         super(db, name, VIEW);
78
79         isReadOnly = true;
80         colList = columns;
81         statement = trimStatement(definition);
82         compileTimeSchema = session.getSchemaHsqlName(null);
83
84         compile(session);
85
86         HsqlName[] schemas = getSchemas();
87
88         for (int i = 0; i < schemas.length; i++) {
89             if (db.schemaManager.isSystemSchema(schemas[i])) {
90                 continue;
91             }
92
93             if (!schemas[i].equals(name.schema)) {
94                 throw Trace.error(Trace.INVALID_SCHEMA_NAME_NO_SUBCLASS);
95             }
96         }
97     }
98
99     /**
100      * Returns the SELECT statement trimmed of any terminating SQL
101      * whitespace, separators or SQL comments.
102      */

103     static String JavaDoc trimStatement(String JavaDoc s) throws HsqlException {
104
105         int position;
106         String JavaDoc str;
107         Tokenizer tokenizer = new Tokenizer(s);
108
109         // fredt@users - this establishes the end of the actual statement
110
// to get rid of any end semicolon or comment line after the end
111
// of statement
112
do {
113             position = tokenizer.getPosition();
114             str = tokenizer.getString();
115         } while (str.length() != 0 || tokenizer.wasValue());
116
117         return s.substring(0, position).trim();
118     }
119
120     /**
121      * Compiles the SELECT statement and sets up the columns.
122      */

123     void compile(Session session) throws HsqlException {
124
125         // create the working table
126
Parser p = new Parser(session, this.database,
127                               new Tokenizer(statement));
128         int brackets = p.parseOpenBracketsSelect();
129
130         viewSubQuery = p.parseSubquery(brackets, colList, true,
131                                        Expression.VIEW);
132
133         p.setAsView(this);
134
135         viewSubqueries = p.getSortedSubqueries();
136         viewSelect = viewSubQuery.select;
137
138         viewSelect.prepareResult(session);
139
140         Result.ResultMetaData metadata = viewSelect.resultMetaData;
141         int columns = viewSelect.iResultLen;
142
143         if (super.columnCount == 0) {
144
145             // do not add columns at recompile time
146
super.addColumns(metadata, columns);
147         }
148     }
149
150     /**
151      * Returns the SELECT statement for the view.
152      */

153     String JavaDoc getStatement() {
154         return statement;
155     }
156
157     /**
158      * Overridden to disable SET TABLE READONLY DDL for View objects.
159      */

160     void setDataReadOnly(boolean value) throws HsqlException {
161         throw Trace.error(Trace.NOT_A_TABLE);
162     }
163
164     /**
165      * Returns list of schemas
166      */

167     HsqlName[] getSchemas() {
168
169         HsqlArrayList list = new HsqlArrayList();
170
171         for (int i = 0; i < viewSubqueries.length; i++) {
172             Select select = viewSubqueries[i].select;
173
174             for (; select != null; select = select.unionSelect) {
175                 TableFilter[] tfilter = select.tFilter;
176
177                 for (int j = 0; j < tfilter.length; j++) {
178                     list.add(tfilter[j].filterTable.tableName.schema);
179                 }
180             }
181         }
182
183         return (HsqlName[]) list.toArray(new HsqlName[list.size()]);
184     }
185
186     boolean hasView(View view) {
187
188         if (view == this) {
189             return false;
190         }
191
192         for (int i = 0; i < viewSubqueries.length; i++) {
193             if (viewSubqueries[i].view == view) {
194                 return true;
195             }
196         }
197
198         return false;
199     }
200
201     /**
202      * Returns true if the view references any column of the named table.
203      */

204     boolean hasTable(Table table) {
205
206         for (int i = 0; i < viewSubqueries.length; i++) {
207             Select select = viewSubqueries[i].select;
208
209             for (; select != null; select = select.unionSelect) {
210                 TableFilter[] tfilter = select.tFilter;
211
212                 for (int j = 0; j < tfilter.length; j++) {
213                     if (table.equals(tfilter[j].filterTable.tableName)) {
214                         return true;
215                     }
216                 }
217             }
218         }
219
220         return false;
221     }
222
223     /**
224      * Returns true if the view references the named column of the named table,
225      * otherwise false.
226      */

227     boolean hasColumn(Table table, String JavaDoc colname) {
228
229         if (hasTable(table)) {
230             Expression.Collector coll = new Expression.Collector();
231
232             coll.addAll(viewSubqueries[viewSubqueries.length - 1].select,
233                         Expression.COLUMN);
234
235             Iterator it = coll.iterator();
236
237             for (; it.hasNext(); ) {
238                 Expression e = (Expression) it.next();
239
240                 if (colname.equals(e.getBaseColumnName())
241                         && table.equals(e.getTableHsqlName())) {
242                     return true;
243                 }
244             }
245         }
246
247         return false;
248     }
249
250     /**
251      * Returns true if the view references the named SEQUENCE,
252      * otherwise false.
253      */

254     boolean hasSequence(NumberSequence sequence) {
255
256         Expression.Collector coll = new Expression.Collector();
257
258         coll.addAll(viewSubqueries[viewSubqueries.length - 1].select,
259                     Expression.SEQUENCE);
260
261         Iterator it = coll.iterator();
262
263         for (; it.hasNext(); ) {
264             Expression e = (Expression) it.next();
265
266             if (e.valueData == sequence) {
267                 return true;
268             }
269         }
270
271         return false;
272     }
273 }
274
Popular Tags