| 1 package com.quadcap.sql; 2 3 40 41 import java.io.ByteArrayOutputStream ; 42 import java.io.Externalizable ; 43 import java.io.IOException ; 44 import java.io.ObjectInput ; 45 import java.io.ObjectOutput ; 46 47 import java.util.Vector ; 48 49 import java.sql.ResultSet ; 50 import java.sql.SQLException ; 51 52 import com.quadcap.sql.index.Btree; 53 import com.quadcap.sql.index.BCursor; 54 55 import com.quadcap.util.Debug; 56 import com.quadcap.util.Util; 57 58 64 public class ExportedKeyConstraint extends ForeignKeyConstraint 65 implements Externalizable  66 { 67 transient ImportedKeyConstraint iConstraint; 68 transient String iConstraintName; 69 70 String uConstraintName; 71 72 73 76 public ExportedKeyConstraint() {} 77 78 81 public ExportedKeyConstraint(String name, Vector colNames, 82 String fTableName, Vector fColNames, 83 ImportedKeyConstraint iConstraint, 84 UniqueConstraint uConstraint) 85 throws SQLException  86 { 87 super(name, colNames, fTableName, fColNames); 88 this.iConstraint = iConstraint; 89 this.iConstraintName = iConstraint.getName(); 90 this.uConstraintName = uConstraint.getName(); 91 uConstraint.addExportConstraint(this); 92 if (this.colNames == null) { 93 this.colNames = uConstraint.getColumnNames(); 94 } 95 } 96 97 public void delete(Session session) throws SQLException , IOException { 98 UniqueConstraint uc = 99 (UniqueConstraint)table.getConstraint(uConstraintName); 100 if (uc != null) { 101 uc.removeExportConstraint(name); 102 } 103 } 104 105 void setForeignKeyCols(int[] fCols) { 106 this.fCols = fCols; 107 } 108 109 public void checkUpdate(Session session, byte[] oldKey, Row row, 110 Row oldRow, long rowId, Constraint activeIndex) 111 throws SQLException , IOException  112 { 113 getComparator(); 114 Database db = session.getDatabase(); 115 byte[] newKey = makeKey(session, row); 116 if (activeIndex != this) oldKey = makeKey(session, oldRow); 117 if (compare.compare(newKey, oldKey) != 0) { 118 ExportedKeys ek = getExportedKeys(session); 119 if (isSelfReferencing(db)) { 120 byte[] oldfKey = makeFKey(session, oldRow); 121 byte[] newfKey = makeFKey(session, row); 122 ek.addSelfRefEntry(oldKey, newKey, oldfKey, newfKey); 123 } else { 124 ek.addEntry(oldKey, newKey); 125 } 126 } 127 } 128 129 public void checkDelete(Session session, Row row, long rowId) 130 throws SQLException , IOException  131 { 132 byte[] fkey = getImportedKeyConstraint(session.getDatabase()).makeFKey(session, row); 133 if (isSelfReferencing(session.getDatabase())) { 134 ExportedKeys ek = getExportedKeys(session); 135 byte[] key = makeKey(session, row); 136 ek.addDeleteSelfRef(key, fkey); 137 } else { 138 checkKeyRemoval(session, fkey); 139 } 140 } 141 142 public void checkKeyRemoval(Session session, byte[] oldkey) 143 throws SQLException , IOException  144 { 145 getComparator(); 146 Database db = session.getDatabase(); 147 Btree fTree = getForeignIndex(db); 148 int count = 0; 149 boolean match = false; 150 BCursor cursor = fTree.getCursor(false); 151 try { 152 boolean kvalid = cursor.seek(oldkey); 153 while (!match && (kvalid || cursor.next())) { 154 byte[] key = cursor.getKey(); 155 int cmp = compare.compare(key, oldkey); 156 match = cmp == 0; 157 kvalid = false; 158 } 159 } finally { 160 cursor.release(); 161 } 162 if (match) { 163 int refSpec = iConstraint.getRefAction(DELETE); 164 switch (refSpec) { 165 case NOACTION: 166 throw new SQLException ( 167 "Foreign key constraint violation: children exist", 168 "23000"); 169 170 case CASCADE: 171 ExportedKeys ek = getExportedKeys(session); 172 ek.removeKey(refSpec, oldkey); 173 break; 174 case SETNULL: 175 case SETDEFAULT: 176 throw new SQLException ( 178 "Foreign key constraint violation and SET " + 179 "{NULL|DEFAULT} not implemented", "23000"); 180 } 181 } 182 } 183 184 189 ExportedKeys getExportedKeys(Session session) throws IOException { 190 ExportedKeys ek = 191 (ExportedKeys)session.getContext(this, isDeferred()); 192 if (ek == null) { 193 ek = new ExportedKeys(session, this); 194 session.putContext(this, isDeferred(), ek); 195 } 196 return ek; 197 } 198 199 ImportedKeyConstraint getImportedKeyConstraint(Database db) 200 throws SQLException , IOException  201 { 202 if (iConstraint == null) { 203 getFTable(db); 204 iConstraint = 205 (ImportedKeyConstraint)fTable.getConstraint(iConstraintName); 206 } 207 return iConstraint; 208 } 209 210 Btree getForeignIndex(Database db) throws SQLException , IOException { 211 return getImportedKeyConstraint(db).getIndex(db); 212 } 213 214 public void readExternal(ObjectInput in) 215 throws IOException , ClassNotFoundException  216 { 217 super.readExternal(in); 218 iConstraintName = (String )in.readObject(); 219 uConstraintName = (String )in.readObject(); 220 } 221 222 public void writeExternal(ObjectOutput out) throws IOException { 223 super.writeExternal(out); 224 out.writeObject(iConstraintName); 225 out.writeObject(uConstraintName); 226 } 227 } 228 | Popular Tags |