KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > mckoi > database > interpret > ViewManager


1 /**
2  * com.mckoi.database.interpret.ViewManager 24 Aug 2002
3  *
4  * Mckoi SQL Database ( http://www.mckoi.com/database )
5  * Copyright (C) 2000, 2001, 2002 Diehl and Associates, Inc.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * Version 2 as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License Version 2 for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * Version 2 along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  *
20  * Change Log:
21  *
22  *
23  */

24
25 package com.mckoi.database.interpret;
26
27 import com.mckoi.database.*;
28 import java.util.ArrayList JavaDoc;
29 import java.util.List JavaDoc;
30
31 /**
32  * Handler for creating and dropping views in the database.
33  *
34  * @author Tobias Downer
35  */

36
37 public class ViewManager extends Statement {
38
39   /**
40    * The type of command we are running through this ViewManager.
41    */

42   private String JavaDoc type;
43   
44   /**
45    * The view name to create/drop.
46    */

47   private String JavaDoc view_name;
48   
49   /**
50    * The view name as a TableName object.
51    */

52   private TableName vname;
53   
54   /**
55    * If this is a create command, the TableSelectExpression that forms the view.
56    */

57   private TableSelectExpression select_expression;
58
59   /**
60    * If this is a create command, the QueryPlanNode that represents the view
61    * plan.
62    */

63   private QueryPlanNode plan;
64   
65   
66   // ---------- Implemented from Statement ----------
67

68   public void prepare() throws DatabaseException {
69     type = (String JavaDoc) cmd.getObject("type");
70     view_name = (String JavaDoc) cmd.getObject("view_name");
71     
72     String JavaDoc schema_name = database.getCurrentSchema();
73     vname = TableName.resolve(schema_name, view_name);
74     vname = database.tryResolveCase(vname);
75     
76     if (type.equals("create")) {
77       // Get the select expression
78
select_expression =
79                    (TableSelectExpression) cmd.getObject("select_expression");
80       // Get the column name list
81
ArrayList JavaDoc col_list = (ArrayList JavaDoc) cmd.getObject("column_list");
82
83       // Generate the TableExpressionFromSet hierarchy for the expression,
84
TableExpressionFromSet from_set =
85                          Planner.generateFromSet(select_expression, database);
86       // Form the plan
87
plan = Planner.formQueryPlan(database, select_expression, from_set,
88                                    new ArrayList JavaDoc());
89
90       // Wrap the result around a SubsetNode to alias the columns in the
91
// table correctly for this view.
92
int sz = (col_list == null) ? 0 : col_list.size();
93       Variable[] original_vars = from_set.generateResolvedVariableList();
94       Variable[] new_column_vars = new Variable[original_vars.length];
95
96       if (sz > 0) {
97         if (sz != original_vars.length) {
98           throw new StatementException(
99                  "Column list is not the same size as the columns selected.");
100         }
101         for (int i = 0; i < sz; ++i) {
102           String JavaDoc col_name = (String JavaDoc) col_list.get(i);
103           new_column_vars[i] = new Variable(vname, col_name);
104         }
105       }
106       else {
107         sz = original_vars.length;
108         for (int i = 0; i < sz; ++i) {
109           new_column_vars[i] = new Variable(vname, original_vars[i].getName());
110         }
111       }
112
113       // Check there are no repeat column names in the table.
114
for (int i = 0; i < sz; ++i) {
115         Variable cur_v = new_column_vars[i];
116         for (int n = i + 1; n < sz; ++n) {
117           if (new_column_vars[n].equals(cur_v)) {
118             throw new DatabaseException(
119                 "Duplicate column name '" + cur_v + "' in view. " +
120                 "A view may not contain duplicate column names.");
121           }
122         }
123       }
124       
125       // Wrap the plan around a SubsetNode plan
126
plan = new QueryPlan.SubsetNode(plan, original_vars, new_column_vars);
127
128     }
129
130   }
131
132   public Table evaluate() throws DatabaseException {
133
134     DatabaseQueryContext context = new DatabaseQueryContext(database);
135
136     if (type.equals("create")) {
137       // Does the user have privs to create this tables?
138
if (!database.getDatabase().canUserCreateTableObject(context,
139                                                            user, vname)) {
140         throw new UserAccessException(
141                           "User not permitted to create view: " + view_name);
142       }
143
144       // Does the schema exist?
145
boolean ignore_case = database.isInCaseInsensitiveMode();
146       SchemaDef schema =
147               database.resolveSchemaCase(vname.getSchema(), ignore_case);
148       if (schema == null) {
149         throw new DatabaseException("Schema '" + vname.getSchema() +
150                                     "' doesn't exist.");
151       }
152       else {
153         vname = new TableName(schema.getName(), vname.getName());
154       }
155     
156       // Check the permissions for this user to select from the tables in the
157
// given plan.
158
Select.checkUserSelectPermissions(context, user, plan);
159
160       // Does the table already exist?
161
if (database.tableExists(vname)) {
162         throw new DatabaseException("View or table with name '" + vname +
163                                     "' already exists.");
164       }
165
166       // Before evaluation, make a clone of the plan,
167
QueryPlanNode plan_copy;
168       try {
169         plan_copy = (QueryPlanNode) plan.clone();
170       }
171       catch (CloneNotSupportedException JavaDoc e) {
172         Debug().writeException(e);
173         throw new DatabaseException("Clone error: " + e.getMessage());
174       }
175       
176       // We have to execute the plan to get the DataTableDef that represents the
177
// result of the view execution.
178
Table t = plan.evaluate(context);
179       DataTableDef data_table_def = new DataTableDef(t.getDataTableDef());
180       data_table_def.setTableName(vname);
181       
182       // Create a ViewDef object,
183
ViewDef view_def = new ViewDef(data_table_def, plan_copy);
184   
185       // And create the view object,
186
database.createView(query, view_def);
187
188       // The initial grants for a view is to give the user who created it
189
// full access.
190
database.getGrantManager().addGrant(
191            Privileges.TABLE_ALL_PRIVS, GrantManager.TABLE, vname.toString(),
192            user.getUserName(), true, Database.INTERNAL_SECURE_USERNAME);
193       
194     }
195     else if (type.equals("drop")) {
196
197       // Does the user have privs to drop this tables?
198
if (!database.getDatabase().canUserDropTableObject(context,
199                                                          user, vname)) {
200         throw new UserAccessException(
201                           "User not permitted to drop view: " + view_name);
202       }
203
204       // Drop the view object
205
database.dropView(vname);
206       
207       // Drop the grants for this object
208
database.getGrantManager().revokeAllGrantsOnObject(
209                                       GrantManager.TABLE, vname.toString());
210       
211     }
212     else {
213       throw new Error JavaDoc("Unknown view command type: " + type);
214     }
215
216     return FunctionTable.resultTable(context, 0);
217   }
218
219
220 }
221
222
Popular Tags