1 package com.quadcap.sql; 2 3 40 41 import java.io.Externalizable ; 42 import java.io.IOException ; 43 import java.io.ObjectInput ; 44 import java.io.ObjectOutput ; 45 46 import java.util.ArrayList ; 47 import java.util.Enumeration ; 48 import java.util.HashMap ; 49 import java.util.Iterator ; 50 import java.util.Map ; 51 52 import java.sql.SQLException ; 53 54 import com.quadcap.sql.file.BlockFile; 55 import com.quadcap.sql.file.ByteUtil; 56 57 import com.quadcap.sql.index.Btree; 58 import com.quadcap.sql.index.BCursor; 59 60 import com.quadcap.sql.io.Extern; 61 62 import com.quadcap.util.Debug; 63 64 69 70 public class StmtRenameTable extends LogStep implements Stmt, Externalizable { 71 String oldName; 72 String newName; 73 Relation r; 74 75 public StmtRenameTable() {} 76 77 public StmtRenameTable(String oldName, String newName) { 78 this.oldName = oldName; 79 this.newName = newName; 80 } 81 82 public void execute(Session session) throws IOException , SQLException { 83 session.getTableWriteLock("#Schema"); 84 session.getTableWriteLock(oldName); 85 session.getTableWriteLock(newName); 86 session.doStep(this); 87 } 88 89 public void redo(Session session) throws IOException , SQLException { 90 rename(session, oldName, newName); 91 } 92 93 public void undo(Session session) throws IOException , SQLException { 94 rename(session, newName, oldName); 95 } 96 97 public void rename(Session session, String oldN, String newN) 98 throws IOException , SQLException 99 { 100 Database db = session.getDatabase(); 101 Relation oldR = db.getRelation(oldN); 102 if (oldR == null) { 103 throw new SQLException ("no such table: " + oldN, "42000"); 104 } 105 db.renameRelation(oldR, newN); 106 Relation newR = db.getRelation(newN); 107 if (newR == null) { 108 throw new SQLException ("rename failed!: " + newN); 109 } 110 111 Enumeration views = db.getViews(newN); 112 while (views.hasMoreElements()) { 113 String view1 = views.nextElement().toString(); 114 renameView(session, view1, oldN, newN); 115 } 116 117 if (newR instanceof Table) { 118 Map referencingTables = new HashMap (); 119 Table t = (Table)newR; 120 int num = t.getNumConstraints(); 121 for (int i = 0; i < num; i++) { 122 Constraint c = t.getConstraint(i); 123 if (c instanceof ForeignKeyConstraint) { 124 ForeignKeyConstraint fc = (ForeignKeyConstraint)c; 125 String fTable = fc.getFTableName(); 126 referencingTables.put(fTable, ""); 127 } 128 } 129 if (referencingTables.size() > 0) { 130 Iterator iter = referencingTables.keySet().iterator(); 131 while (iter.hasNext()) { 132 renameForeignKeys(session, iter.next().toString(), oldN, newN); 133 } 134 db.updateRelation(newR); 135 } 136 } 137 } 138 139 void renameForeignKeys(Session session, String tableName, String oldN, 140 String newN) 141 throws IOException , SQLException 142 { 143 session.getTableReadLock(tableName); 144 Database db = session.getDatabase(); 145 Table t = (Table)db.getRelation(tableName); 146 int num = t.getNumConstraints(); 147 for (int i = 0; i < num; i++) { 148 Constraint c = t.getConstraint(i); 149 if (c instanceof ForeignKeyConstraint) { 150 ForeignKeyConstraint fc = (ForeignKeyConstraint)c; 151 String fTable = fc.getFTableName(); 152 if (fTable.equals(oldN)) { 153 fc.setFTableName(newN); 154 fc.resetColumns(); 155 } 156 } 157 } 158 db.updateRelation(t); 159 } 160 161 class RenameTableVisitor implements ExpressionVisitor { 162 String oldN; 163 String newN; 164 RenameTableVisitor(String oldN, String newN) { 165 this.oldN = oldN; 166 this.newN = newN; 167 } 168 public void visit(Expression ex) { 169 if (ex instanceof SelectFromTable) { 170 SelectFromTable sf = (SelectFromTable)ex; 171 String tableName = sf.getTableName(); 172 if (tableName.equals(oldN)) { 173 sf.setTableName(newN); 174 } 175 } else if (ex instanceof SelectExpression) { 176 Iterator iter = ((SelectExpression)ex).getFrom().iterator(); 177 while (iter.hasNext()) { 178 visit((Expression)iter.next()); 179 } 180 } 181 ex.visitSubExpressions(this); 182 } 183 } 184 185 void renameView(Session session, String viewName, String oldN, 186 String newN) 187 throws IOException , SQLException 188 { 189 190 session.getTableReadLock(viewName); 191 192 Database db = session.getDatabase(); 193 View v = (View)db.getRelation(viewName); 194 Expression viewEx = v.getViewExpression(); 195 RenameTableVisitor visitor = new RenameTableVisitor(oldN, newN); 196 visitor.visit(viewEx); 197 db.updateRelation(v); 198 } 199 200 public void prepare(Session session) throws IOException , SQLException { 201 } 202 203 public void readExternal(ObjectInput in) 204 throws IOException , ClassNotFoundException 205 { 206 oldName = (String )in.readObject(); 207 newName = (String )in.readObject(); 208 } 209 210 public void writeExternal(ObjectOutput out) throws IOException { 211 out.writeObject(oldName); 212 out.writeObject(newName); 213 } 214 215 219 public String toString() { 220 StringBuffer sb = new StringBuffer (super.toString()); 221 sb.append(" RenameTable("); 222 sb.append(oldName); 223 sb.append(" to "); 224 sb.append(newName); 225 sb.append(')'); 226 return sb.toString(); 227 } 228 230 static Extern extern; 231 public void setExtern(Extern extern) { StmtRenameTable.extern = extern; } 232 public Extern getExtern() { return extern; } 233 } 234 | Popular Tags |