001 package org.apache.ojb.broker.util.sequence;
002
003 /* Copyright 2003-2005 The Apache Software Foundation
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 import org.apache.commons.lang.SystemUtils;
019 import org.apache.ojb.broker.PersistenceBroker;
020 import org.apache.ojb.broker.PersistenceBrokerException;
021 import org.apache.ojb.broker.metadata.JdbcTypesHelper;
022 import org.apache.ojb.broker.util.logging.LoggerFactory;
023 import org.apache.ojb.broker.accesslayer.ResultSetAndStatement;
024 import org.apache.ojb.broker.metadata.FieldDescriptor;
025 import org.apache.ojb.broker.metadata.JdbcType;
026 import org.apache.ojb.broker.query.Query;
027
028 import java.sql.SQLException;
029
030
031 /**
032 * An Implementation Class that will retrieve a valid new value
033 * for a PK field that is of type 'uniqueidentifier'. Since values
034 * for these types are generated through a 'newid()' call to
035 * MSSQL Server, this class is only valid for MSSQL Server 7.0 and up.
036 * <br/>
037 * This SequenceManager can be used for any classes that have their PK
038 * defined as a 'uniqueidetifier'
039 *
040 * @author <a href="mailto:aclute825@hotmail.com">Andrew Clute</a>
041 * @version $Id: SequenceManagerMSSQLGuidImpl.java,v 1.1 2007-08-24 22:17:29 ewestfal Exp $
042 */
043 public class SequenceManagerMSSQLGuidImpl extends AbstractSequenceManager
044 {
045 private static final JdbcType JDBC_TYPE_VARCHAR = JdbcTypesHelper.getJdbcTypeByName("varchar");
046 /**
047 * Constructor used by
048 * {@link org.apache.ojb.broker.util.sequence.SequenceManagerFactory}
049 *
050 * @param broker PB instance to perform the
051 * id generation.
052 */
053 public SequenceManagerMSSQLGuidImpl(PersistenceBroker broker)
054 {
055 super(broker);
056 }
057
058 public Object getUniqueValue(FieldDescriptor field) throws SequenceManagerException
059 {
060 // only works for VARCHAR fields
061 if(!field.getJdbcType().equals(JDBC_TYPE_VARCHAR))
062 {
063 throw new SequenceManagerException("This implementation only works with fields defined" +
064 " as VARCHAR, but given field was " + (field != null ? field.getJdbcType() : null));
065 }
066 Object result = getUniqueString(field);
067 // perform a sql to java conversion here, so that clients do
068 // not see any db specific values
069 result = field.getFieldConversion().sqlToJava(result);
070 return result;
071 }
072
073 /**
074 * returns a unique String for given field.
075 * the returned uid is unique accross all tables.
076 */
077 protected String getUniqueString(FieldDescriptor field) throws SequenceManagerException
078 {
079 ResultSetAndStatement rsStmt = null;
080 String returnValue = null;
081 try
082 {
083 rsStmt = getBrokerForClass().serviceJdbcAccess().executeSQL(
084 "select newid()", field.getClassDescriptor(), Query.NOT_SCROLLABLE);
085 if (rsStmt.m_rs.next())
086 {
087 returnValue = rsStmt.m_rs.getString(1);
088 }
089 else
090 {
091 LoggerFactory.getDefaultLogger().error(this.getClass()
092 + ": Can't lookup new oid for field " + field);
093 }
094 }
095 catch (PersistenceBrokerException e)
096 {
097 throw new SequenceManagerException(e);
098 }
099 catch (SQLException e)
100 {
101 throw new SequenceManagerException(e);
102 }
103
104 finally
105 {
106 // close the used resources
107 if (rsStmt != null) rsStmt.close();
108 }
109 return returnValue;
110 }
111
112 /**
113 * Returns a new unique int for the given Class and fieldname.
114 */
115 protected int getUniqueId(FieldDescriptor field) throws SequenceManagerException
116 {
117 throw new SequenceManagerException(
118 SystemUtils.LINE_SEPARATOR +
119 "Failure attempting to retrieve a Guid for a field that is an int -- field should be returned as a VARCHAR");
120 }
121
122 /**
123 * Returns a new unique int for the given Class and fieldname.
124 */
125 protected long getUniqueLong(FieldDescriptor field) throws SequenceManagerException
126 {
127 throw new SequenceManagerException(
128 SystemUtils.LINE_SEPARATOR +
129 "Failure attempting to retrieve a Guid for a field that is a long -- field should be returned as a VARCHAR");
130 }
131
132 // TODO: never used? remove?
133 // /**
134 // * returns a unique Object for class clazz and field fieldName.
135 // * the returned Object is unique accross all tables in the extent of clazz.
136 // */
137 // protected Object getUniqueObject(FieldDescriptor field) throws SequenceManagerException
138 // {
139 // return getUniqueString(field);
140 // }
141 }
142