KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > h2 > command > dml > Update


1 /*
2  * Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
3  * Initial Developer: H2 Group
4  */

5 package org.h2.command.dml;
6
7 import java.sql.SQLException JavaDoc;
8
9 import org.h2.command.Prepared;
10 import org.h2.engine.Right;
11 import org.h2.engine.Session;
12 import org.h2.expression.Expression;
13 import org.h2.message.Message;
14 import org.h2.result.Row;
15 import org.h2.store.UndoLogRecord;
16 import org.h2.table.Column;
17 import org.h2.table.PlanItem;
18 import org.h2.table.Table;
19 import org.h2.table.TableFilter;
20 import org.h2.util.ObjectArray;
21 import org.h2.util.StringUtils;
22 import org.h2.value.Value;
23
24 /**
25  * @author Thomas
26  */

27 public class Update extends Prepared {
28
29     private Expression condition;
30     private TableFilter tableFilter;
31     private Expression[] expressions;
32
33     public Update(Session session) {
34         super(session);
35     }
36
37     public void setTableFilter(TableFilter tableFilter) {
38         this.tableFilter = tableFilter;
39         Table table = tableFilter.getTable();
40         expressions = new Expression[table.getColumns().length];
41     }
42
43     public void setCondition(Expression condition) {
44         this.condition = condition;
45     }
46
47     public void setAssignment(Column column, Expression expression)
48             throws SQLException JavaDoc {
49         int id = column.getColumnId();
50         if (expressions[id] != null) {
51             throw Message.getSQLException(Message.DUPLICATE_COLUMN_NAME_1, column
52                     .getName());
53         }
54         expressions[id] = expression;
55     }
56
57     public int update() throws SQLException JavaDoc {
58         tableFilter.startQuery();
59         tableFilter.reset();
60         // TODO optimization: update old / new list: maybe use a linked list (to avoid array allocation)
61
ObjectArray oldRows = new ObjectArray();
62         ObjectArray newRows = new ObjectArray();
63         Table table = tableFilter.getTable();
64         session.getUser().checkRight(table, Right.UPDATE);
65         table.fireBefore(session);
66         table.lock(session, true);
67         int columnCount = table.getColumns().length;
68         // get the old rows, compute the new rows
69
setCurrentRowNumber(0);
70         while (tableFilter.next()) {
71             checkCancelled();
72             setCurrentRowNumber(oldRows.size()+1);
73             if (condition == null || Boolean.TRUE.equals(condition.getBooleanValue(session))) {
74                 Row oldRow = tableFilter.get();
75                 oldRows.add(oldRow);
76                 Row newRow = table.getTemplateRow();
77                 for (int i = 0; i < columnCount; i++) {
78                     Expression newExpr = expressions[i];
79                     Value newValue;
80                     if (newExpr == null) {
81                         newValue = oldRow.getValue(i);
82                     } else {
83                         Column column = table.getColumn(i);
84                         newValue = newExpr.getValue(session).convertTo(column.getType());
85                     }
86                     newRow.setValue(i, newValue);
87                 }
88                 table.validateConvertUpdateSequence(session, newRow);
89                 newRows.add(newRow);
90             }
91         }
92         // TODO performance: loop only if required
93
// TODO self referencing referential integrity constraints don't work if update is multi-row and 'inversed' the condition! probably need multi-row triggers with 'deleted' and 'inserted' at the same time. anyway good for sql compatibility
94
// TODO update in-place (but if the position changes, we need to update all indexes)
95
// before row triggers
96
if(table.fireRow()) {
97             for (int i = 0; i < oldRows.size(); i++) {
98                 checkCancelled();
99                 Row o = (Row) oldRows.get(i);
100                 Row n = (Row) newRows.get(i);
101                 table.fireBeforeRow(session, o, n);
102             }
103         }
104         // remove the old rows
105
for (int i = 0; i < oldRows.size(); i++) {
106             checkCancelled();
107             Row o = (Row) oldRows.get(i);
108             table.removeRow(session, o);
109             session.log(new UndoLogRecord(table, UndoLogRecord.DELETE, o));
110         }
111         // add the new rows
112
for (int i=0; i < newRows.size(); i++) {
113             checkCancelled();
114             Row n = (Row) newRows.get(i);
115             table.addRow(session, n);
116             session.log(new UndoLogRecord(table, UndoLogRecord.INSERT, n));
117         }
118         if(table.fireRow()) {
119             for (int i=0; i < newRows.size(); i++) {
120                 checkCancelled();
121                 Row n = (Row) newRows.get(i);
122                 Row o = (Row) oldRows.get(i);
123                 table.fireAfterRow(session, o, n);
124             }
125         }
126         table.fireAfter(session);
127         return newRows.size();
128     }
129
130     public String JavaDoc getPlan() {
131         StringBuffer JavaDoc buff = new StringBuffer JavaDoc();
132         buff.append("UPDATE ");
133         buff.append(tableFilter.getPlanSQL(false));
134         buff.append("\nSET ");
135         Table table = tableFilter.getTable();
136         int columnCount = table.getColumns().length;
137         for (int i = 0, j = 0; i < columnCount; i++) {
138             Expression newExpr = expressions[i];
139             if (newExpr != null) {
140                 if(j>0) {
141                     buff.append(",\n");
142                 }
143                 j++;
144                 Column column = table.getColumn(i);
145                 buff.append(column.getName());
146                 buff.append(" = ");
147                 buff.append(StringUtils.unEnclose(newExpr.getSQL()));
148             }
149         }
150         if(condition != null) {
151             buff.append("\nWHERE " + StringUtils.unEnclose(condition.getSQL()));
152         }
153         return buff.toString();
154     }
155
156     public void prepare() throws SQLException JavaDoc {
157         if (condition != null) {
158             condition.mapColumns(tableFilter, 0);
159             condition = condition.optimize(session);
160             condition.createIndexConditions(tableFilter);
161         }
162         for (int i = 0; i < expressions.length; i++) {
163             Expression expr = expressions[i];
164             if (expr != null) {
165                 expr.mapColumns(tableFilter, 0);
166                 expressions[i] = expr.optimize(session);
167             }
168         }
169         PlanItem item = tableFilter.getBestPlanItem(session);
170         tableFilter.setPlanItem(item);
171         tableFilter.prepare();
172     }
173
174     public boolean isTransactional() {
175         return true;
176     }
177
178 }
179
Popular Tags