KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > quadcap > sql > StmtAddColumn


1 package com.quadcap.sql;
2
3 /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
4  *
5  * This software is distributed under the Quadcap Free Software License.
6  * This software may be used or modified for any purpose, personal or
7  * commercial. Open Source redistributions are permitted. Commercial
8  * redistribution of larger works derived from, or works which bundle
9  * this software requires a "Commercial Redistribution License"; see
10  * http://www.quadcap.com/purchase.
11  *
12  * Redistributions qualify as "Open Source" under one of the following terms:
13  *
14  * Redistributions are made at no charge beyond the reasonable cost of
15  * materials and delivery.
16  *
17  * Redistributions are accompanied by a copy of the Source Code or by an
18  * irrevocable offer to provide a copy of the Source Code for up to three
19  * years at the cost of materials and delivery. Such redistributions
20  * must allow further use, modification, and redistribution of the Source
21  * Code under substantially the same terms as this license.
22  *
23  * Redistributions of source code must retain the copyright notices as they
24  * appear in each source code file, these license terms, and the
25  * disclaimer/limitation of liability set forth as paragraph 6 below.
26  *
27  * Redistributions in binary form must reproduce this Copyright Notice,
28  * these license terms, and the disclaimer/limitation of liability set
29  * forth as paragraph 6 below, in the documentation and/or other materials
30  * provided with the distribution.
31  *
32  * The Software is provided on an "AS IS" basis. No warranty is
33  * provided that the Software is free of defects, or fit for a
34  * particular purpose.
35  *
36  * Limitation of Liability. Quadcap Software shall not be liable
37  * for any damages suffered by the Licensee or any third party resulting
38  * from use of the Software.
39  */

40
41 import java.io.IOException JavaDoc;
42
43 import java.util.Vector JavaDoc;
44
45 import java.sql.SQLException JavaDoc;
46
47 import com.quadcap.sql.file.BlockFile;
48 import com.quadcap.sql.file.ByteUtil;
49
50 import com.quadcap.sql.index.Btree;
51 import com.quadcap.sql.index.BCursor;
52
53 import com.quadcap.sql.types.Value;
54 import com.quadcap.sql.types.ValueLong;
55 import com.quadcap.sql.types.ValueNull;
56
57 import com.quadcap.util.Debug;
58
59 /**
60  * Implementation of SQL <b>ADD COLUMN</b> statement.
61  *
62  * @author Stan Bailes
63  */

64 public class StmtAddColumn implements Stmt {
65     String JavaDoc tableName;
66     Column column;
67     String JavaDoc aname;
68
69     /**
70      * Explicit constructor from table name and Column
71      */

72     public StmtAddColumn(String JavaDoc tableName, Column column, String JavaDoc aname) {
73     this.tableName = tableName;
74     this.column = column;
75         this.aname = aname;
76     }
77
78     /**
79      * Stmt.execute()
80      *
81      * For ADD COLUMN, we need to update the table definition, of course.
82      * But then, we need to update *all* of the rows!
83      */

84     public void execute(Session session) throws IOException JavaDoc, SQLException JavaDoc {
85         // First, acquire the schema and table locks
86
Database db = session.getDatabase();
87         session.getTableWriteLock("#Schema");
88     session.getTableWriteLock(tableName);
89
90         // Make a cursor from the original schema
91
Table table = (Table)db.getRelation(tableName);
92         if (table == null) {
93             throw new SQLException JavaDoc("Table not found: " + tableName);
94         }
95
96         if (table.getColumnIndex(column.getName()) >= 1) {
97             throw new SQLException JavaDoc("Add Column: a column named '" +
98                                    column.getName() +
99                                    "' already exists int table '" +
100                                    tableName + "'");
101         }
102
103         int newpos = table.getColumnCount() + 1;
104         if (aname != null) {
105             if (aname.equals("")) {
106                 newpos = 1;
107             } else {
108                 newpos = table.getColumnIndex(aname) + 1;
109                 if (newpos <= 0) {
110                     throw new SQLException JavaDoc("Bad column name: " + aname);
111                 }
112             }
113         }
114         column.setColumn(newpos);
115
116         // Update every row in the table with the new column value
117
BCursor bc = null;
118         try {
119             long id = 0;
120             BlockFile file = db.getFile();
121             Expression defaultExpr = column.getDefault();
122             Value columnDefault =
123                 defaultExpr == null ? ValueNull.valueNull
124                 : defaultExpr.getValue(session, null);
125             
126             IndexConstraint ic = table.getAnyIndex(session);
127             Btree index = ic.getIndex(db);
128             bc = index.getCursor(false);
129             LazyRow row1 = new LazyRow(table.getColumnCount());
130             Row row2 = new Row(table.getColumnCount() + 1);
131             while (bc.next()) {
132                 long rowId = bc.getValAsLong();
133                 db.getRow(rowId, row1, false);
134                 int offset = 0;
135                 for (int i = 1; i <= row2.size(); i++) {
136                     if (i == newpos) {
137                         if (column.isAutoIncrement()) {
138                             columnDefault = new ValueLong(++id);
139                         }
140                         row2.set(i, columnDefault);
141                         offset = 1;
142                     } else {
143                         row2.set(i, row1.item(i - offset));
144                     }
145                 }
146                 UpdateRow update = null;
147                 if (db.inMemory()) {
148                     update = new UpdateRow(session, rowId, row1, row2);
149                     row2 = new Row(table.getColumnCount() + 1);
150                     row1 = new LazyRow(table.getColumnCount());
151                 } else {
152                     byte[] oldRowBytes = row1.getBytes();
153                     byte[] rowBytes = LazyRow.writeRow(session, null, row2);
154                     update = new UpdateRow(session, table, rowId,
155                                            oldRowBytes, rowBytes);
156                 }
157                 session.doStep(update);
158             }
159             if (column.isAutoIncrement()) {
160                 session.doStep(new AutoNumberStep(session, table, id+1));
161             }
162     } finally {
163             if (bc != null) bc.release();
164         }
165
166         // This changes the table schema
167
session.doStep(new AddColumn(session, table, column, newpos));
168
169         Vector JavaDoc cv = column.getConstraints();
170         if (cv != null) for (int i = 0; i < cv.size(); i++) {
171             Constraint constraint = (Constraint)cv.elementAt(i);
172             session.doStep(new AddConstraint(session, table, constraint));
173         }
174
175         table.resetColumnConstraints();
176     }
177 }
178
Popular Tags