00001
package com.quadcap.sql;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
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
00066
00067
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
00216
00217
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
00229
00230 static Extern
extern;
00231 public void setExtern(Extern
extern) {
StmtRenameTable.extern =
extern; }
00232 public Extern
getExtern() {
return extern; }
00233 }