Quadcap Embeddable Database

com/quadcap/sql/ForeignKeyConstraint.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.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 * Abstract base class for imported and exported key constraints. 00060 * 00061 * @author Stan Bailes 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 * Default constructor 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 * Reset any mapped columns (e.g. in case a column is added or deleted) 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 * Is this constraint 'deferred'? 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 * Create a candidate key for a row from this table 00146 */ 00147 public byte[] makeKey(Session session, Row row) 00148 throws SQLException 00149 { 00150 return makeKey(row, getColumns()); 00151 } 00152 00153 /** 00154 * Create a candidate key for a row from the foreign table 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 * If you care, remember to 'extend' and embrace. 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 }