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.ByteArrayOutputStream;
00042
import java.io.Externalizable;
00043
import java.io.IOException;
00044
import java.io.ObjectInput;
00045
import java.io.ObjectOutput;
00046
00047
import java.util.Vector;
00048
00049
import java.sql.ResultSet;
00050
import java.sql.SQLException;
00051
00052
import com.quadcap.sql.io.ObjectInputStream;
00053
import com.quadcap.sql.io.ObjectOutputStream;
00054
00055
import com.quadcap.sql.index.Btree;
00056
import com.quadcap.sql.index.Comparator;
00057
00058
00059
00060
00061
00062
00063 public abstract class ForeignKeyConstraint
00064
extends Constraint
00065 implements
Externalizable
00066 {
00067 String
fTableName;
00068 Vector
fColNames;
00069 Table fTable;
00070 UniqueConstraint fConstraint;
00071 int[]
fCols;
00072 transient Comparator
compare;
00073
00074
00075
00076
00077 public ForeignKeyConstraint() {}
00078
00079 public ForeignKeyConstraint(String name, String fTableName) {
00080 super(name);
00081
this.fTableName = fTableName;
00082 }
00083
00084 public ForeignKeyConstraint(String name, Vector colNames,
00085 String fTableName, Vector fColNames) {
00086 super(name, colNames);
00087
this.fTableName = fTableName;
00088
this.fColNames = fColNames;
00089 }
00090
00091
00092
00093
00094 public void resetColumns() throws SQLException {
00095 super.resetColumns();
00096
fCols = null;
00097 }
00098
00099 public void checkInsert(
Session session,
Row row)
00100
throws SQLException, IOException
00101 {
00102 }
00103
00104 public void applyInsert(
Session session,
Row row,
long rowId,
00105
Constraint activeIndex)
00106
throws SQLException, IOException
00107 {
00108 }
00109
00110 public void checkUpdate(
Session session,
Row row,
long rowId)
00111
throws SQLException, IOException
00112 {
00113 }
00114
00115 public void applyUpdate(
Session session, byte[] oldKey,
Row row,
00116
Row oldRow,
long rowId,
Constraint activeIndex)
00117
throws SQLException, IOException
00118 {
00119 }
00120
00121 public void checkDelete(
Session session,
Row row,
long rowId)
00122
throws SQLException, IOException
00123 {
00124 }
00125
00126 public void applyDelete(
Session session,
Row row,
long rowId,
00127
Constraint activeIndex)
00128
throws SQLException, IOException
00129 {
00130 }
00131
00132
00133
00134
00135 public final boolean isDeferred() {
00136
return (spec & INIT_DEFERRED) != 0;
00137 }
00138
00139 final Comparator
getComparator() throws SQLException {
00140
if (
compare == null)
compare =
new Key(
getColumns().length);
00141
return compare;
00142 }
00143
00144
00145
00146
00147 public byte[]
makeKey(
Session session,
Row row)
00148
throws SQLException
00149 {
00150
return makeKey(row,
getColumns());
00151 }
00152
00153
00154
00155
00156 public byte[]
makeFKey(
Session session,
Row row)
00157
throws IOException, SQLException
00158 {
00159
return makeKey(row,
getFCols(session.getDatabase()));
00160 }
00161
00162 private final byte[] makeKey(
Row row,
int[] k)
throws SQLException {
00163
return Key.makeKey(null, row, k, 0,
false);
00164 }
00165
00166 public void setForeignColumn(String name) {
00167
fColNames =
new Vector();
00168
fColNames.addElement(name);
00169 }
00170
00171 public void readExternal(ObjectInput in)
00172
throws IOException, ClassNotFoundException
00173 {
00174 super.readExternal(in);
00175
fTableName = (String)in.readObject();
00176
fColNames = (Vector)in.readObject();
00177 }
00178
00179 public void writeExternal(ObjectOutput out)
throws IOException {
00180 super.writeExternal(out);
00181 out.writeObject(
fTableName);
00182 out.writeObject(
fColNames);
00183 }
00184
00185 public String
getFTableName() {
00186
return fTableName;
00187 }
00188
00189 public void setFTableName(String s) {
00190
fTableName = s;
00191 }
00192
00193 public Table getFTable(
Database db)
throws SQLException, IOException {
00194
if (
fTable == null) {
00195
Relation t = db.getRelation(
fTableName);
00196
if (t == null) {
00197
throw new SQLException(
"No such table: " +
fTableName,
00198
"42000");
00199 }
00200
try {
00201
fTable = (
Table)t;
00202 }
catch (ClassCastException e) {
00203
throw new SQLException(
"Not a base table: " +
fTableName,
00204
"42000");
00205 }
00206 }
00207
return fTable;
00208 }
00209
00210
00211
00212
00213 public void add(
Session session)
throws SQLException, IOException {}
00214
00215
abstract public void delete(
Session session)
00216
throws SQLException, IOException
00217 ;
00218
00219
00220
00221
00222 public int[]
getFCols(
Database db)
throws SQLException, IOException {
00223
if (
fCols == null) {
00224
if (
fColNames == null) {
00225
UniqueConstraint pk = getFTable(db).
getPrimaryKey();
00226
if (pk == null) {
00227
throw new SQLException(
"No primary key for table " +
00228
fTable.
getName());
00229 }
00230
fConstraint = pk;
00231
fCols = pk.getColumns();
00232 }
else {
00233
fCols = getFTable(db).
mapColumns(
fColNames);
00234
fConstraint =
fTable.
getIndexForColumns(
fCols);
00235 }
00236 }
00237
return fCols;
00238 }
00239
00240 boolean isSelfReferencing(
Database db)
throws IOException, SQLException {
00241
boolean ret = table == getFTable(db);
00242
return ret;
00243 }
00244
00245 public String
toString() {
00246 StringBuffer sb =
new StringBuffer(super.toString());
00247 sb.append(
" references " +
fTableName +
"(");
00248
if (
fColNames != null) {
00249
for (
int i = 0; i <
fColNames.size(); i++) {
00250
if (i > 0) sb.append(
",");
00251 sb.append(
fColNames.elementAt(i).toString());
00252 }
00253 }
00254 sb.append(
')');
00255
return sb.toString();
00256 }
00257 }