KickJava   Java API By Example, From Geeks To Geeks.

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


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.Externalizable JavaDoc;
42 import java.io.IOException JavaDoc;
43 import java.io.ObjectInput JavaDoc;
44 import java.io.ObjectOutput JavaDoc;
45
46 import java.sql.SQLException JavaDoc;
47
48 import com.quadcap.sql.types.TypeBigInt;
49 import com.quadcap.sql.types.Value;
50 import com.quadcap.sql.types.ValueLong;
51
52 import com.quadcap.util.Debug;
53
54 /**
55  * Constraint class for SQL <b>AUTO_NUMBER</b> constraints.
56  *
57  * @author Stan Bailes
58  */

59 public class AutoNumberConstraint
60     extends Constraint implements Externalizable JavaDoc
61 {
62     transient AutoNumberStep step;
63     
64     long current = -1;
65
66     /**
67      * Default constructor
68      */

69     public AutoNumberConstraint() {}
70
71     /**
72      * Explicit name constructor
73      */

74     public AutoNumberConstraint(String JavaDoc name) {
75         super(name);
76     }
77
78     /**
79      * When added, I need to number all rows which already exist in the
80      * table
81      */

82     public void add(Session session) throws SQLException JavaDoc {
83     if (!table.isUnderConstruction()) {
84             try {
85                 Column col = getColumn();
86                 col.isAutoIncr = true;
87                 session.getDatabase().updateRelation(table);
88             } catch (IOException JavaDoc e) {
89                 throw DbException.wrapThrowable(e);
90             }
91         }
92     }
93
94     /**
95      * My column is no longer an auto-incrementer
96      */

97     public void delete(Session session) throws SQLException JavaDoc, IOException JavaDoc {
98         Column col = getColumn();
99         col.isAutoIncr = false;
100         session.getDatabase().updateRelation(table);
101     }
102
103     /**
104      * Our work is already done. (We gave out the number in checkInsert())
105      */

106     public void applyInsert(Session session, Row row, long rowId,
107                 Constraint activeIndex)
108     throws SQLException JavaDoc, IOException JavaDoc
109     {
110     }
111
112     /**
113      * We don't care about deletes.
114      */

115     public void checkDelete(Session session, Row row, long rowId)
116     throws SQLException JavaDoc, IOException JavaDoc
117     {
118     }
119     
120     /**
121      * We don't care about deletes.
122      */

123     public void applyDelete(Session session, Row row, long rowId,
124                 Constraint activeIndex)
125     throws SQLException JavaDoc, IOException JavaDoc
126     {
127     }
128
129     static Object JavaDoc stepLock = new Object JavaDoc();
130
131     /**
132      * If the 'with identity' field is null or not an integer
133      * we assign the number before the insert operation and increment
134      * our little counter.
135      */

136     public void checkInsert(Session session, Row row)
137     throws SQLException JavaDoc, IOException JavaDoc
138     {
139         Column c = getColumn();
140         int col = c.getColumn();
141         boolean incr = false;
142         Value v = row.item(col);
143         Database db = session.getDatabase();
144         
145         if (Value.isNull(v)) {
146             incr = true;
147         } else {
148             Value t = v.convert(TypeBigInt.typeBigInt);
149             if (!(t instanceof ValueLong)) {
150                 incr = true;
151             } else {
152                 ValueLong l = (ValueLong)t;
153                 current = db.getTableIdentity(table.getName());
154                 if (l.longValue() >= current) {
155                     current = l.longValue() + 1;
156                     synchronized (stepLock) {
157                         if (step == null) {
158                             step = new AutoNumberStep(session, table, current);
159                         } else {
160                             step.setCurrentId(current);
161                         }
162                         session.doStep(step); // go ahead and do it...
163
}
164                 }
165             }
166         }
167
168         if (incr) {
169             if (true || current < 0) {
170                 // XXX We can't optimize this away in all cases, because
171
// XXX the value of 'current' that's stored locally may
172
// XXX be wrong. This can happen if the table containing
173
// XXX this constraint isn't updated properly.
174
current = db.getTableIdentity(table.getName());
175             }
176             session.setLastInsertId(current);
177             row.set(col, new ValueLong(current++));
178             // we avoid an allocation per step by doing a static allocation,
179
// but then we need to protect the shared resource from contention
180
synchronized (stepLock) {
181                 if (step == null) {
182                     step = new AutoNumberStep(session, table, current);
183                 } else {
184                     step.setCurrentId(current);
185                 }
186                 session.doStep(step); // go ahead and do it...
187
}
188         }
189     }
190
191     /**
192      * We only operate during INSERT, basically.
193      */

194     public void checkUpdate(Session session, byte[] oldKey, Row row,
195                             Row oldRow, long rowId, Constraint activeIndex)
196     throws SQLException JavaDoc, IOException JavaDoc
197     {
198     }
199
200     /**
201      * 's cool.
202      */

203     public void applyUpdate(Session session, byte[] oldKey, Row row,
204                 Row oldRow, long rowId, Constraint activeIndex)
205     throws SQLException JavaDoc, IOException JavaDoc
206     {
207     }
208
209     /**
210      * Where did I leave off?
211      */

212     public void readExternal(ObjectInput JavaDoc in)
213     throws IOException JavaDoc, ClassNotFoundException JavaDoc
214     {
215     super.readExternal(in);
216     current = in.readLong();
217     }
218
219     /**
220      * Remember where we were.
221      */

222     public void writeExternal(ObjectOutput JavaDoc out) throws IOException JavaDoc {
223     super.writeExternal(out);
224     out.writeLong(current);
225     }
226
227     /**
228      * Do me first.
229      */

230     public int getPriority() { return 0; }
231 }
232
Popular Tags