KickJava   Java API By Example, From Geeks To Geeks.

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


1 /**
2  * com.mckoi.database.interpret.UpdateTable 14 Sep 2001
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 java.util.*;
28 import com.mckoi.database.*;
29
30 /**
31  * The instance class that stores all the information about an update
32  * statement for processing.
33  *
34  * @author Tobias Downer
35  */

36
37 public class UpdateTable extends Statement {
38
39   /**
40    * The name the table that we are to update.
41    */

42   String JavaDoc table_name;
43
44   /**
45    * An array of Assignment objects which represent what we are changing.
46    */

47   ArrayList column_sets;
48
49   /**
50    * If the update statement has a 'where' clause, then this is set here. If
51    * it has no 'where' clause then we apply to the entire table.
52    */

53   SearchExpression where_condition;
54
55   /**
56    * The limit of the number of rows that are updated by this statement. A
57    * limit of -1 means there is no limit.
58    */

59   int limit = -1;
60
61   /**
62    * Tables that are relationally linked to the table being inserted into, set
63    * after 'prepare'. This is used to determine the tables we need to read
64    * lock because we need to validate relational constraints on the tables.
65    */

66   private ArrayList relationally_linked_tables;
67
68
69   // -----
70

71   /**
72    * The DataTable we are updating.
73    */

74   private DataTable update_table;
75
76   /**
77    * The TableName object set during 'prepare'.
78    */

79   private TableName tname;
80
81   /**
82    * The plan for the set of records we are updating in this query.
83    */

84   private QueryPlanNode plan;
85
86   // ---------- Implemented from Statement ----------
87

88   public void prepare() throws DatabaseException {
89
90     table_name = (String JavaDoc) cmd.getObject("table_name");
91     column_sets = (ArrayList) cmd.getObject("assignments");
92     where_condition = (SearchExpression) cmd.getObject("where_clause");
93     limit = cmd.getInt("limit");
94
95     // ---
96

97     // Resolve the TableName object.
98
tname = resolveTableName(table_name, database);
99     // Does the table exist?
100
if (!database.tableExists(tname)) {
101       throw new DatabaseException("Table '" + tname + "' does not exist.");
102     }
103     // Get the table we are updating
104
update_table = database.getTable(tname);
105
106     // Form a TableSelectExpression that represents the select on the table
107
TableSelectExpression select_expression = new TableSelectExpression();
108     // Create the FROM clause
109
select_expression.from_clause.addTable(table_name);
110     // Set the WHERE clause
111
select_expression.where_clause = where_condition;
112
113     // Generate the TableExpressionFromSet hierarchy for the expression,
114
TableExpressionFromSet from_set =
115                        Planner.generateFromSet(select_expression, database);
116     // Form the plan
117
plan = Planner.formQueryPlan(database, select_expression, from_set, null);
118
119     // Resolve the variables in the assignments.
120
for (int i = 0; i < column_sets.size(); ++i) {
121       Assignment assignment = (Assignment) column_sets.get(i);
122       Variable orig_var = assignment.getVariable();
123       Variable new_var = from_set.resolveReference(orig_var);
124       if (new_var == null) {
125         throw new StatementException("Reference not found: " + orig_var);
126       }
127       orig_var.set(new_var);
128       assignment.prepareExpressions(from_set.expressionQualifier());
129     }
130
131     // Resolve all tables linked to this
132
TableName[] linked_tables =
133                              database.queryTablesRelationallyLinkedTo(tname);
134     relationally_linked_tables = new ArrayList(linked_tables.length);
135     for (int i = 0; i < linked_tables.length; ++i) {
136       relationally_linked_tables.add(database.getTable(linked_tables[i]));
137     }
138
139   }
140
141   public Table evaluate() throws DatabaseException {
142
143     DatabaseQueryContext context = new DatabaseQueryContext(database);
144
145     // Generate a list of Variable objects that represent the list of columns
146
// being changed.
147
Variable[] col_var_list = new Variable[column_sets.size()];
148     for (int i = 0; i < col_var_list.length; ++i) {
149       Assignment assign = (Assignment) column_sets.get(i);
150       col_var_list[i] = assign.getVariable();
151     }
152
153     // Check that this user has privs to update the table.
154
if (!database.getDatabase().canUserUpdateTableObject(context,
155                                                   user, tname, col_var_list)) {
156       throw new UserAccessException(
157                           "User not permitted to update table: " + table_name);
158     }
159
160     // Check the user has select permissions on the tables in the plan.
161
Select.checkUserSelectPermissions(context, user, plan);
162     
163     // Evaluate the plan to find the update set.
164
Table update_set = plan.evaluate(context);
165
166     // Make an array of assignments
167
Assignment[] assign_list = new Assignment[column_sets.size()];
168     assign_list = (Assignment[]) column_sets.toArray(assign_list);
169     // Update the data table.
170
int update_count = update_table.update(context,
171                                            update_set, assign_list, limit);
172
173     // Notify TriggerManager that we've just done an update.
174
if (update_count > 0) {
175       database.notifyTriggerEvent(new TriggerEvent(
176                         TriggerEvent.UPDATE, tname.toString(), update_count));
177     }
178
179     // Return the number of rows we updated.
180
return FunctionTable.resultTable(context, update_count);
181
182   }
183
184
185 }
186
Popular Tags