Quadcap Embeddable Database

com/quadcap/sql/StmtRenameTable.java

Go to the documentation of this file.
00001 package com.quadcap.sql; 00002 00003 /* Copyright 1999 - 2003 Quadcap Software. All rights reserved. 00004 * 00005 * This software is distributed under the Quadcap Free Software License. 00006 * This software may be used or modified for any purpose, personal or 00007 * commercial. Open Source redistributions are permitted. Commercial 00008 * redistribution of larger works derived from, or works which bundle 00009 * this software requires a "Commercial Redistribution License"; see 00010 * http://www.quadcap.com/purchase. 00011 * 00012 * Redistributions qualify as "Open Source" under one of the following terms: 00013 * 00014 * Redistributions are made at no charge beyond the reasonable cost of 00015 * materials and delivery. 00016 * 00017 * Redistributions are accompanied by a copy of the Source Code or by an 00018 * irrevocable offer to provide a copy of the Source Code for up to three 00019 * years at the cost of materials and delivery. Such redistributions 00020 * must allow further use, modification, and redistribution of the Source 00021 * Code under substantially the same terms as this license. 00022 * 00023 * Redistributions of source code must retain the copyright notices as they 00024 * appear in each source code file, these license terms, and the 00025 * disclaimer/limitation of liability set forth as paragraph 6 below. 00026 * 00027 * Redistributions in binary form must reproduce this Copyright Notice, 00028 * these license terms, and the disclaimer/limitation of liability set 00029 * forth as paragraph 6 below, in the documentation and/or other materials 00030 * provided with the distribution. 00031 * 00032 * The Software is provided on an "AS IS" basis. No warranty is 00033 * provided that the Software is free of defects, or fit for a 00034 * particular purpose. 00035 * 00036 * Limitation of Liability. Quadcap Software shall not be liable 00037 * for any damages suffered by the Licensee or any third party resulting 00038 * from use of the Software. 00039 */ 00040 00041 import java.io.Externalizable; 00042 import java.io.IOException; 00043 import java.io.ObjectInput; 00044 import java.io.ObjectOutput; 00045 00046 import java.util.ArrayList; 00047 import java.util.Enumeration; 00048 import java.util.HashMap; 00049 import java.util.Iterator; 00050 import java.util.Map; 00051 00052 import java.sql.SQLException; 00053 00054 import com.quadcap.sql.file.BlockFile; 00055 import com.quadcap.sql.file.ByteUtil; 00056 00057 import com.quadcap.sql.index.Btree; 00058 import com.quadcap.sql.index.BCursor; 00059 00060 import com.quadcap.sql.io.Extern; 00061 00062 import com.quadcap.util.Debug; 00063 00064 /** 00065 * Implementation of the SQL <b>ALTER TABLE RENAME TO</b> statement. 00066 * 00067 * @author Stan Bailes 00068 */ 00069 00070 public class StmtRenameTable extends LogStep implements Stmt, Externalizable { 00071 String oldName; 00072 String newName; 00073 Relation r; 00074 00075 public StmtRenameTable() {} 00076 00077 public StmtRenameTable(String oldName, String newName) { 00078 this.oldName = oldName; 00079 this.newName = newName; 00080 } 00081 00082 public void execute(Session session) throws IOException, SQLException { 00083 session.getTableWriteLock("#Schema"); 00084 session.getTableWriteLock(oldName); 00085 session.getTableWriteLock(newName); 00086 session.doStep(this); 00087 } 00088 00089 public void redo(Session session) throws IOException, SQLException { 00090 rename(session, oldName, newName); 00091 } 00092 00093 public void undo(Session session) throws IOException, SQLException { 00094 rename(session, newName, oldName); 00095 } 00096 00097 public void rename(Session session, String oldN, String newN) 00098 throws IOException, SQLException 00099 { 00100 Database db = session.getDatabase(); 00101 Relation oldR = db.getRelation(oldN); 00102 if (oldR == null) { 00103 throw new SQLException("no such table: " + oldN, "42000"); 00104 } 00105 db.renameRelation(oldR, newN); 00106 Relation newR = db.getRelation(newN); 00107 if (newR == null) { 00108 throw new SQLException("rename failed!: " + newN); 00109 } 00110 00111 Enumeration views = db.getViews(newN); 00112 while (views.hasMoreElements()) { 00113 String view1 = views.nextElement().toString(); 00114 renameView(session, view1, oldN, newN); 00115 } 00116 00117 if (newR instanceof Table) { 00118 Map referencingTables = new HashMap(); 00119 Table t = (Table)newR; 00120 int num = t.getNumConstraints(); 00121 for (int i = 0; i < num; i++) { 00122 Constraint c = t.getConstraint(i); 00123 if (c instanceof ForeignKeyConstraint) { 00124 ForeignKeyConstraint fc = (ForeignKeyConstraint)c; 00125 String fTable = fc.getFTableName(); 00126 referencingTables.put(fTable, ""); 00127 } 00128 } 00129 if (referencingTables.size() > 0) { 00130 Iterator iter = referencingTables.keySet().iterator(); 00131 while (iter.hasNext()) { 00132 renameForeignKeys(session, iter.next().toString(), oldN, newN); 00133 } 00134 db.updateRelation(newR); 00135 } 00136 } 00137 } 00138 00139 void renameForeignKeys(Session session, String tableName, String oldN, 00140 String newN) 00141 throws IOException, SQLException 00142 { 00143 session.getTableReadLock(tableName); 00144 Database db = session.getDatabase(); 00145 Table t = (Table)db.getRelation(tableName); 00146 int num = t.getNumConstraints(); 00147 for (int i = 0; i < num; i++) { 00148 Constraint c = t.getConstraint(i); 00149 if (c instanceof ForeignKeyConstraint) { 00150 ForeignKeyConstraint fc = (ForeignKeyConstraint)c; 00151 String fTable = fc.getFTableName(); 00152 if (fTable.equals(oldN)) { 00153 fc.setFTableName(newN); 00154 fc.resetColumns(); 00155 } 00156 } 00157 } 00158 db.updateRelation(t); 00159 } 00160 00161 class RenameTableVisitor implements ExpressionVisitor { 00162 String oldN; 00163 String newN; 00164 RenameTableVisitor(String oldN, String newN) { 00165 this.oldN = oldN; 00166 this.newN = newN; 00167 } 00168 public void visit(Expression ex) { 00169 if (ex instanceof SelectFromTable) { 00170 SelectFromTable sf = (SelectFromTable)ex; 00171 String tableName = sf.getTableName(); 00172 if (tableName.equals(oldN)) { 00173 sf.setTableName(newN); 00174 } 00175 } else if (ex instanceof SelectExpression) { 00176 Iterator iter = ((SelectExpression)ex).getFrom().iterator(); 00177 while (iter.hasNext()) { 00178 visit((Expression)iter.next()); 00179 } 00180 } 00181 ex.visitSubExpressions(this); 00182 } 00183 } 00184 00185 void renameView(Session session, String viewName, String oldN, 00186 String newN) 00187 throws IOException, SQLException 00188 { 00189 00190 session.getTableReadLock(viewName); 00191 00192 Database db = session.getDatabase(); 00193 View v = (View)db.getRelation(viewName); 00194 Expression viewEx = v.getViewExpression(); 00195 RenameTableVisitor visitor = new RenameTableVisitor(oldN, newN); 00196 visitor.visit(viewEx); 00197 db.updateRelation(v); 00198 } 00199 00200 public void prepare(Session session) throws IOException, SQLException { 00201 } 00202 00203 public void readExternal(ObjectInput in) 00204 throws IOException, ClassNotFoundException 00205 { 00206 oldName = (String)in.readObject(); 00207 newName = (String)in.readObject(); 00208 } 00209 00210 public void writeExternal(ObjectOutput out) throws IOException { 00211 out.writeObject(oldName); 00212 out.writeObject(newName); 00213 } 00214 00215 //#ifdef DEBUG 00216 /** 00217 * Return a displayable representation for debugging 00218 */ 00219 public String toString() { 00220 StringBuffer sb = new StringBuffer(super.toString()); 00221 sb.append(" RenameTable("); 00222 sb.append(oldName); 00223 sb.append(" to "); 00224 sb.append(newName); 00225 sb.append(')'); 00226 return sb.toString(); 00227 } 00228 //#endif 00229 00230 static Extern extern; 00231 public void setExtern(Extern extern) { StmtRenameTable.extern = extern; } 00232 public Extern getExtern() { return extern; } 00233 }