001: /* ====================================================================
002: * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
003: *
004: * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * 1. Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * 3. The end-user documentation included with the redistribution,
019: * if any, must include the following acknowledgment:
020: * "This product includes software developed by Jcorporate Ltd.
021: * (http://www.jcorporate.com/)."
022: * Alternately, this acknowledgment may appear in the software itself,
023: * if and wherever such third-party acknowledgments normally appear.
024: *
025: * 4. "Jcorporate" and product names such as "Expresso" must
026: * not be used to endorse or promote products derived from this
027: * software without prior written permission. For written permission,
028: * please contact info@jcorporate.com.
029: *
030: * 5. Products derived from this software may not be called "Expresso",
031: * or other Jcorporate product names; nor may "Expresso" or other
032: * Jcorporate product names appear in their name, without prior
033: * written permission of Jcorporate Ltd.
034: *
035: * 6. No product derived from this software may compete in the same
036: * market space, i.e. framework, without prior written permission
037: * of Jcorporate Ltd. For written permission, please contact
038: * partners@jcorporate.com.
039: *
040: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
041: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
042: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
043: * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
044: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
045: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
046: * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
047: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
048: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
049: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
050: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
051: * SUCH DAMAGE.
052: * ====================================================================
053: *
054: * This software consists of voluntary contributions made by many
055: * individuals on behalf of the Jcorporate Ltd. Contributions back
056: * to the project(s) are encouraged when you make modifications.
057: * Please send them to support@jcorporate.com. For more information
058: * on Jcorporate Ltd. and its products, please see
059: * <http://www.jcorporate.com/>.
060: *
061: * Portions of this software are based upon other open source
062: * products and are subject to their respective licenses.
063: */
064:
065: package com.jcorporate.expresso.core.dbobj;
066:
067: /**
068: * DBSequence.java
069: *
070: * Written by Adam Rossi
071: * PlatinumSolutions, Inc.
072: * adam.rossi@platinumsolutions.com
073: *
074: * Copyright 2000, 2001 Jcorporate Ltd.
075: */
076:
077: import com.jcorporate.expresso.core.dataobjects.jdbc.JDBCObjectMetaData;
078: import com.jcorporate.expresso.core.db.DBConnection;
079: import com.jcorporate.expresso.core.db.DBException;
080:
081: import java.util.Iterator;
082: import java.util.Vector;
083:
084: /**
085: * DBSequence is a special DBObject that wraps a database sequence.
086: * Currently, this class only works with PostgreSQL sequences, but it
087: * should be easy to add support for Oracle or others (see createTable() and
088: * retrieve() methods specifically). If you attempt to use this with a database
089: * other than PostgreSQL, it will throw an exception.
090: * <p/>
091: * To make this compatible with the the schema autocreation of DBObjects magic,
092: * security scheme, etc., this class subclasses DBObject. But there are many
093: * methods that have been overriden, because they do not make sense for a sequence
094: * (ex: search, clear, etc). If these methods are called, an exception is thrown.
095: * <p/>
096: * To get the next value in the sequence, call getNext().
097: * <p/>
098: * make sure that you override the setupFields() method and supply the proper
099: * setup parameters.
100: * <p/>
101: * ex:
102: * <p/>
103: * super.setupFields() //Always!
104: * setTargetTable("SomeSequence");
105: * setDescription("Some example Database Sequence");
106: * this.setIncrement(new Integer(1)); // set the increment for the sequence
107: * this.setMinValue(new Integer(1)); // set the min value
108: * this.setMaxValue(new Integer(1000)); //set the max value (optional)
109: * this.setStart(new Integer(1)); //set the start value (optional)
110: *
111: * @author Adam Rossi
112: */
113: public abstract class DBSequence extends SecuredDBObject {
114:
115: private static final String THIS_CLASS = DBSequence.class.getName();
116:
117: private Integer increment = null;
118: private Integer minvalue = null;
119: private Integer maxvalue = null;
120: private Integer start = null;
121:
122: /**
123: * DBSequence constructor comment.
124: *
125: * @throws com.jcorporate.expresso.core.db.DBException
126: * The exception description.
127: */
128: public DBSequence()
129: throws com.jcorporate.expresso.core.db.DBException {
130: super ();
131: } /* DBSequence() */
132:
133: /**
134: * Creation date: (4/7/00 2:45:10 PM)
135: *
136: * @param theConnection com.jcorporate.expresso.core.db.DBConnection
137: */
138: public DBSequence(DBConnection theConnection) throws DBException {
139: super (theConnection);
140: } /* DBSequence(DBConnection) */
141:
142: public DBSequence(int uid) throws DBException {
143: super (uid);
144: }
145:
146: /**
147: * @throws DBException
148: */
149: public void add() throws DBException {
150: throw new DBException("You cannot add to a sequence");
151: } /* add() */
152:
153: /**
154: * @throws com.jcorporate.expresso.core.db.DBException
155: * The exception description.
156: */
157: public synchronized void clear() throws DBException {
158: throw new DBException("Cannot call clear() on a DBSequence");
159: } /* clear() */
160:
161: /**
162: * Create the sequence in the database. Assumes it is not there already.
163: */
164: public synchronized void createTable() throws DBException {
165: String myName = (THIS_CLASS + "createTable()");
166: String createStatement = ("CREATE SEQUENCE ");
167: DBConnection myConnection = null;
168:
169: try {
170: myConnection = this .getConnectionPool().getConnection(
171: myName);
172: createStatement = createStatement
173: + getJDBCMetaData().getTargetTable();
174:
175: /* If we're connection to PostgreSQL, this is how we make the */
176: /* sequence SQL: */
177: if (myConnection.getDBDriver().equals("postgresql.Driver")
178: || myConnection.getDBDriver().equals(
179: "org.postgresql.Driver")) {
180: if (increment != null) {
181: createStatement = createStatement + " increment = "
182: + increment.intValue();
183: }
184: if (minvalue != null) {
185: createStatement = createStatement + " minvalue = "
186: + minvalue.intValue();
187: }
188: if (maxvalue != null) {
189: createStatement = createStatement + " maxvalue = "
190: + maxvalue.intValue();
191: }
192: if (start != null) {
193: createStatement = createStatement + " start = "
194: + start.intValue();
195: }
196: } else {
197: throw new DBException(
198: "Only PostgreSQL currently supported");
199: }
200:
201: myConnection.executeUpdate(createStatement);
202: } catch (DBException de) {
203: throw de;
204: } finally {
205: myConnection.release();
206: }
207: } /* createTable() */
208:
209: /**
210: * @throws com.jcorporate.expresso.core.db.DBException
211: * The exception description.
212: */
213: public void delete()
214: throws com.jcorporate.expresso.core.db.DBException {
215: throw new DBException("Can't Delete from a sequence");
216: } /* delete() */
217:
218: /**
219: * @return boolean
220: * @throws com.jcorporate.expresso.core.db.DBException
221: * The exception description.
222: */
223: public boolean find()
224: throws com.jcorporate.expresso.core.db.DBException {
225: throw new DBException("Can't execute find on a DBSequence");
226: } /* find() */
227:
228: /**
229: * @return long
230: */
231: public long getNext() throws DBException {
232: this .retrieve();
233:
234: long returnValue;
235:
236: try {
237: returnValue = new Long(getField("nextval")).longValue();
238: } catch (NumberFormatException ne) {
239: throw new DBException(
240: "DBSequence.getNext: Could not convert \'"
241: + getField("nextval") + "\' to a number:"
242: + ne.getMessage());
243: } catch (Exception e) {
244: throw new DBException("DBSequence.getNext: " + e.toString());
245: }
246:
247: return returnValue;
248: } /* getNext() */
249:
250: /**
251: * NOTE: Subclass must override. This method should return a new object
252: * of the type of the subclass
253: *
254: * @return DBObject A newly allocated object of the subclass's class
255: */
256: public abstract DBObject getThisDBObj() throws DBException;
257:
258: /* getThisDBObj() */
259: /**
260: * @throws com.jcorporate.expresso.core.db.DBException
261: * The exception description.
262: */
263: public void retrieve()
264: throws com.jcorporate.expresso.core.db.DBException {
265: String myName = (THIS_CLASS + "retrieve()");
266: DBConnection myConnection = null;
267: JDBCObjectMetaData metadata = this .getJDBCMetaData();
268: try {
269: myConnection = this .getConnectionPool().getConnection(
270: myName);
271:
272: String myStatement = "SELECT ";
273:
274: /* If we're connection to PostgreSQL, this is how we get a */
275: /* sequence number: */
276: if (myConnection.getDBDriver().equals("postgresql.Driver")
277: || myConnection.getDBDriver().equals(
278: "org.postgresql.Driver")) {
279: myStatement = myStatement + "nextval('"
280: + metadata.getTargetTable() + "') as nextval";
281: } else {
282: throw new DBException(
283: "DBSequence only supported in PostgreSQL");
284: }
285: if (myConnection == null) {
286: throw new DBException(myName
287: + ":No connection - object not "
288: + " correctly initialized ("
289: + metadata.getName() + ") No such record");
290: }
291: try {
292: myConnection.execute(myStatement);
293:
294: String oneFieldName = ("");
295: String oneFieldValue = ("");
296:
297: if (myConnection.next()) {
298: int i = 1;
299:
300: for (Iterator e = metadata.getFieldListArray()
301: .iterator(); e.hasNext();) {
302: oneFieldName = (String) e.next();
303:
304: try {
305:
306: //we assume here that the result will be an int
307: int myint = myConnection.getInt(i);
308: oneFieldValue = "" + myint;
309: } catch (DBException de1) {
310: throw new DBException(myName + ": ("
311: + metadata.getName()
312: + ") Error retrieving field '"
313: + oneFieldName + "' index " + i
314: + ":" + de1.getMessage(), de1
315: .getDBMessage());
316: }
317:
318: i++;
319: setField(oneFieldName, oneFieldValue);
320: }
321: } else { /* for each field */
322: throw new DBException(myName + ": ("
323: + metadata.getName() + ") No such record");
324: }
325: } catch (DBException de) {
326: throw de;
327: } finally {
328: myConnection.release();
329: }
330: } catch (Exception e) {
331: throw new DBException("DBSequence retrieve error: "
332: + e.toString());
333: }
334: } /* retrieve() */
335:
336: /**
337: * @throws com.jcorporate.expresso.core.db.DBException
338: * The exception description.
339: */
340: public synchronized void search()
341: throws com.jcorporate.expresso.core.db.DBException {
342: throw new DBException("Can't search on a DBSequence");
343: } /* search() */
344:
345: /**
346: * @return java.util.Vector
347: * @throws com.jcorporate.expresso.core.db.DBException
348: * The exception description.
349: */
350: public synchronized Vector searchAndRetrieve()
351: throws com.jcorporate.expresso.core.db.DBException {
352: throw new DBException("Can't search on a DBSequence");
353: } /* searchAndRetrieve() */
354:
355: /**
356: * @param sortKeyString java.lang.String
357: * @return java.util.Vector
358: * @throws com.jcorporate.expresso.core.db.DBException
359: * The exception description.
360: */
361: public synchronized Vector searchAndRetrieve(String sortKeyString)
362: throws com.jcorporate.expresso.core.db.DBException {
363: throw new DBException("can't search on a DBSequence");
364: } /* searchAndRetrieve(String) */
365:
366: /**
367: * Size of the increment step (defaults to 1 usually in most DB's).
368: *
369: * @param I java.lang.Integer
370: */
371: public void setIncrement(Integer I) {
372: increment = I;
373: } /* setIncrement(Integer) */
374:
375: /**
376: * Maximum value for the sequence.
377: *
378: * @param I java.lang.Integer
379: */
380: public void setMaxValue(Integer I) {
381: maxvalue = I;
382: } /* setMaxValue(Integer) */
383:
384: /**
385: * Minumum value for the sequence when created
386: *
387: * @param I java.lang.Integer
388: */
389: public void setMinValue(Integer I) {
390: minvalue = I;
391: } /* setMinValue(Integer) */
392:
393: /**
394: * Where the sequence starts
395: *
396: * @param I java.lang.Integer
397: */
398: public void setStart(Integer I) {
399: start = I;
400: } /* setStart(Integer) */
401:
402: /**
403: * make sure that you override the setupFields() method and supply the
404: * proper setup parameters.
405: * <p/>
406: * ex:
407: * <p/>
408: * super.setupFields() //Always!
409: * setTargetTable("SomeSequence");
410: * setDescription("Some example Database Sequence");
411: * this.setIncrement(new Integer(1)); // set the increment for the sequence
412: * this.setMinValue(new Integer(1)); // set the min value
413: * this.setMaxValue(new Integer(1000)); //set the max value (optional)
414: * this.setStart(new Integer(1)); //set the start value (optional)
415: */
416: protected void setupFields()
417: throws com.jcorporate.expresso.core.db.DBException {
418: addField("nextval", "int", 0, false, "Next Number Value");
419: } /* setupFields() */
420:
421: /**
422: * Not allowed...
423: *
424: * @throws com.jcorporate.expresso.core.db.DBException
425: * The exception description.
426: */
427: public void update()
428: throws com.jcorporate.expresso.core.db.DBException {
429: throw new DBException("Can't call update on a DBSequence");
430: } /* update() */
431:
432: /**
433: * Does nothing...I am not sure what do to verify a sequence.
434: */
435: public void verify()
436: throws com.jcorporate.expresso.core.db.DBException {
437: } /* verify() */
438:
439: } /* DBSequence */
440:
441: /* DBSequence */
|