KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > quadcap > sql > IndexConstraint


1 package com.quadcap.sql;
2
3 /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
4  *
5  * This software is distributed under the Quadcap Free Software License.
6  * This software may be used or modified for any purpose, personal or
7  * commercial. Open Source redistributions are permitted. Commercial
8  * redistribution of larger works derived from, or works which bundle
9  * this software requires a "Commercial Redistribution License"; see
10  * http://www.quadcap.com/purchase.
11  *
12  * Redistributions qualify as "Open Source" under one of the following terms:
13  *
14  * Redistributions are made at no charge beyond the reasonable cost of
15  * materials and delivery.
16  *
17  * Redistributions are accompanied by a copy of the Source Code or by an
18  * irrevocable offer to provide a copy of the Source Code for up to three
19  * years at the cost of materials and delivery. Such redistributions
20  * must allow further use, modification, and redistribution of the Source
21  * Code under substantially the same terms as this license.
22  *
23  * Redistributions of source code must retain the copyright notices as they
24  * appear in each source code file, these license terms, and the
25  * disclaimer/limitation of liability set forth as paragraph 6 below.
26  *
27  * Redistributions in binary form must reproduce this Copyright Notice,
28  * these license terms, and the disclaimer/limitation of liability set
29  * forth as paragraph 6 below, in the documentation and/or other materials
30  * provided with the distribution.
31  *
32  * The Software is provided on an "AS IS" basis. No warranty is
33  * provided that the Software is free of defects, or fit for a
34  * particular purpose.
35  *
36  * Limitation of Liability. Quadcap Software shall not be liable
37  * for any damages suffered by the Licensee or any third party resulting
38  * from use of the Software.
39  */

40
41 import java.io.ByteArrayOutputStream JavaDoc;
42 import java.io.Externalizable JavaDoc;
43 import java.io.IOException JavaDoc;
44 import java.io.ObjectInput JavaDoc;
45 import java.io.ObjectOutput JavaDoc;
46
47 import java.util.Vector JavaDoc;
48
49 import java.sql.ResultSet JavaDoc;
50 import java.sql.SQLException JavaDoc;
51
52 import com.quadcap.sql.file.ByteUtil;
53
54 import com.quadcap.sql.index.Btree;
55 import com.quadcap.sql.index.Comparator;
56
57 import com.quadcap.sql.file.BlockFile;
58
59 import com.quadcap.util.Debug;
60 import com.quadcap.util.Util;
61
62 /**
63  * Base class for all index constraints.
64  *
65  * @author Stan Bailes
66  */

67 abstract public class IndexConstraint extends Constraint
68                                       implements Externalizable JavaDoc {
69     Btree index = null;
70     long indexRoot = -1;
71     protected boolean useComparator = true;
72
73     /**
74      * Default constructor (required for Externalizable)
75      */

76     public IndexConstraint() {}
77
78     /**
79      * Explicit constructor for named index
80      */

81     public IndexConstraint(String JavaDoc name) {
82     super(name);
83     }
84
85     public IndexConstraint(String JavaDoc name, Vector JavaDoc names) {
86     super(name, names);
87     }
88
89     //------------------------------------------------------------------
90
// Abstract interface: implementation required
91
/**
92      * Make a serialized key appropriate to the constraint type, based on
93      * the row and row id information
94      */

95     abstract public byte[] makeKey(Session session, Row row, long rowId)
96     throws SQLException JavaDoc
97     ;
98
99     /**
100      * Derived classes must implement this function, which returns the
101      * constraint type as a human readable string.
102      */

103     abstract public String JavaDoc constraintType();
104
105     /**
106      * Constraint.add(): We need to build an index!
107      */

108     public void add(Session session) throws SQLException JavaDoc, IOException JavaDoc {
109     index = null;
110     indexRoot = -1;
111         resetColumns();
112     getIndex(session.getDatabase());
113
114         getColumns();
115     IndexCursor c = table.getCursor(session, this);
116         if (c != null) {
117             try {
118                 while (c.next()) {
119                     Row row = c.getRow();
120                     long rowId = c.getRowId();
121                     byte[] key = makeKey(session, row, rowId);
122                     if (index.get(key) != null) {
123                         throw new SQLException JavaDoc(constraintType() +
124                                                " constraint violated");
125                     }
126                     if (session.getConnection().inRecovery()) {
127                         rowId = session.getLog().getRowMap(rowId);
128                     }
129                     index.set(key, key.length, session.getBuf8(rowId), 0, 8);
130                 }
131             } finally {
132                 c.close();
133             }
134     }
135         
136     }
137
138     /**
139      * Constraint.delete(): We destroy our index
140      */

141     public void delete(Session session) throws IOException JavaDoc {
142         if (indexRoot > 0) {
143             Database db = session.getDatabase();
144             getIndex(db);
145             if (index != null) {
146                 index.free();
147             }
148         }
149     }
150
151     /**
152      * Externalizable.readExternal(): Read me from a stream
153      */

154     public void readExternal(ObjectInput JavaDoc in)
155     throws IOException JavaDoc, ClassNotFoundException JavaDoc
156     {
157     super.readExternal(in);
158     indexRoot = in.readLong();
159     useComparator = in.read() == 1;
160     }
161
162     /**
163      * Externalizable.writeExternal(): Write me to a stream
164      */

165     public void writeExternal(ObjectOutput JavaDoc out) throws IOException JavaDoc {
166     super.writeExternal(out);
167     out.writeLong(indexRoot);
168     out.write(useComparator ? 1 : 0);
169     }
170
171     //---------------------------------
172
// Constraint.checkNNN() functions
173

174     /**
175      * Constraint.checkInsert(): We could check for dups
176      */

177     public void checkInsert(Session session, Row row)
178     throws SQLException JavaDoc, IOException JavaDoc
179     {
180     }
181
182     public void checkUpdate(Session session, byte[] oldKey, Row row,
183                             Row oldRow, long rowId, Constraint activeIndex)
184     throws SQLException JavaDoc, IOException JavaDoc
185     {
186     }
187     
188     public void checkDelete(Session session, Row row, long rowId)
189         throws SQLException JavaDoc, IOException JavaDoc
190     {
191     }
192
193     //---------------------------------
194
// Constraint.applyXXX() functions
195

196     /**
197      * Constraint.applyInsert(): Add an index entry
198      */

199     public void applyInsert(Session session, Row row, long rowId,
200                 Constraint activeIndex)
201     throws SQLException JavaDoc, IOException JavaDoc
202     {
203     
204     Database db = session.getDatabase();
205     byte[] key = makeKey(session, row, rowId);
206     AddIndexEntry add = new AddIndexEntry(session, this, key, rowId);
207     if (activeIndex == this) {
208         session.addPendingAction(add);
209     } else {
210         session.doStep(add);
211     }
212     }
213
214     // careful, 'oldKey' only applies to the 'activeIndex', which may not
215
// be this constraint.
216
public void applyUpdate(Session session, byte[] oldKey, Row row,
217                 Row oldRow, long rowId, Constraint activeIndex)
218     throws SQLException JavaDoc, IOException JavaDoc
219     {
220         byte[] key = makeKey(session, row, rowId);
221         if (activeIndex != this) {
222             oldKey = makeKey(session, oldRow, rowId);
223         }
224         if (Util.compareBytes(key, oldKey) != 0) {
225             UpdateIndex ui =
226                 (UpdateIndex)session.getContext(this, isDeferred());
227             if (ui == null) {
228                 ui = new UpdateIndex(session, this);
229                 session.putContext(this, isDeferred(), ui);
230             }
231             ui.addEntry(key, oldKey, rowId);
232         } else {
233         }
234     }
235
236     public void applyDelete(Session session, Row row, long rowId,
237                 Constraint activeIndex)
238     throws SQLException JavaDoc, IOException JavaDoc
239     {
240     Database db = session.getDatabase();
241     byte[] key = makeKey(session, row, rowId);
242         
243     if (index == null) getIndex(db);
244     DeleteIndexEntry del = new DeleteIndexEntry(session, this, key);
245     if (activeIndex == this) {
246         session.addPendingAction(del);
247     } else {
248         session.doStep(del);
249     }
250     }
251
252     /**
253      * Does this constraint have enough information to uniquely identify
254      * each row?
255      */

256     public boolean isUnique() { return true; }
257
258     /**
259      * Return the number of columns in the index implementing this constraint
260      */

261     public int getIndexColumnCount() {
262     return getColumnCount();
263     }
264
265     /**
266      * Lazy getter for underlying Index object (a Btree, in this case)
267      */

268     public Btree getIndex(Database db) throws IOException JavaDoc {
269     if (index == null) {
270         BlockFile file = db.getFile();
271         boolean create = false;
272         if (indexRoot == -1) {
273         indexRoot = file.newPage();
274         db.updateRelation(table);
275         create = true;
276             }
277         if (useComparator) {
278         Comparator compare = new Key(getIndexColumnCount());
279         index = new Btree(file, compare, indexRoot, create);
280         } else {
281         index = new Btree(file, indexRoot, create);
282         }
283     }
284     return index;
285     }
286
287    /**
288     * Return a string representation of the constraint
289     */

290     public String JavaDoc toString() {
291         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
292         sb.append(getName());
293     if (table != null) {
294         sb.append("(");
295         try {
296         Vector JavaDoc v = getColumnNames();
297         for (int i = 0; i < v.size(); i++) {
298             if (i > 0) sb.append(',');
299             sb.append(v.elementAt(i).toString());
300         }
301         sb.append(")");
302         } catch (SQLException JavaDoc e) {
303         sb.append("Exception: " + e.toString());
304         }
305     }
306     return sb.toString();
307     }
308 }
309
Popular Tags