001 package org.apache.ojb.broker.platforms;
002
003 /* Copyright 2002-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 java.sql.PreparedStatement;
019 import java.sql.SQLException;
020 import java.sql.Types;
021 import java.util.Properties;
022
023 import org.apache.ojb.broker.query.LikeCriteria;
024 import org.apache.ojb.broker.util.sequence.SequenceManagerHelper;
025
026 /**
027 * This class extends <code>PlatformDefaultImpl</code> and defines specific
028 * behavior for the PostgreSQL platform.
029 *
030 * <p/>
031 * Many of the database sequence specific properties can be specified using
032 * <em>custom attributes</em> within the <em>sequence-manager</em> element.
033 * <br/>
034 * The database sequence specific properties are generally speaking, see database user guide
035 * for detailed description.
036 *
037 * <p>
038 * Implementation configuration properties:
039 * </p>
040 *
041 * <table cellspacing="2" cellpadding="2" border="3" frame="box">
042 * <tr>
043 * <td><strong>Property Key</strong></td>
044 * <td><strong>Property Values</strong></td>
045 * </tr>
046 * <tr>
047 * <td>sequenceStart</td>
048 * <td>
049 * DEPRECATED. Database sequence specific property.<br/>
050 * Specifies the first sequence number to be
051 * generated. Allowed: <em>1</em> or greater.
052 * </td>
053 * </tr>
054 * <tr>
055 * <td>seq.start</td>
056 * <td>
057 * Database sequence specific property.<br/>
058 * Specifies the first sequence number to be
059 * generated. Allowed: <em>1</em> or greater.
060 * </td>
061 * </tr>
062 * <tr>
063 * <td>seq.incrementBy</td>
064 * <td>
065 * Database sequence specific property.<br/>
066 * Specifies the interval between sequence numbers.
067 * This value can be any positive or negative
068 * integer, but it cannot be 0.
069 * </td>
070 * </tr>
071 * <tr>
072 * <td>seq.maxValue</td>
073 * <td>
074 * Database sequence specific property.<br/>
075 * Set max value for sequence numbers.
076 * </td>
077 * </tr>
078 * <tr>
079 * <td>seq.minValue</td>
080 * <td>
081 * Database sequence specific property.<br/>
082 * Set min value for sequence numbers.
083 * </td>
084 * </tr>
085 * <tr>
086 * <td>seq.cycle</td>
087 * <td>
088 * Database sequence specific property.<br/>
089 * If <em>true</em>, specifies that the sequence continues to generate
090 * values after reaching either its maximum or minimum value.
091 * <br/>
092 * If <em>false</em>, specifies that the sequence cannot generate more values after
093 * reaching its maximum or minimum value.
094 * </td>
095 * </tr>
096 * <tr>
097 * <td>seq.cache</td>
098 * <td>
099 * Database sequence specific property.<br/>
100 * Specifies how many values of the sequence Oracle
101 * preallocates and keeps in memory for faster access.
102 * Allowed values: <em>2</em> or greater. If set <em>0</em>,
103 * an explicite <em>nocache</em> expression will be set.
104 * </td>
105 * </tr>
106 * <tr>
107 * <td>seq.order</td>
108 * <td>
109 * Database sequence specific property.<br/>
110 * If set <em>true</em>, guarantees that sequence numbers
111 * are generated in order of request.
112 * <br/>
113 * If <em>false</em>, a <em>no order</em> expression will be set.
114 * </td>
115 * </tr>
116 * </table>
117 *
118 * @author <a href="mailto:thma@apache.org">Thomas Mahler<a>
119 * @version $Id: PlatformPostgreSQLImpl.java,v 1.1 2007-08-24 22:17:35 ewestfal Exp $
120 */
121
122 public class PlatformPostgreSQLImpl extends PlatformDefaultImpl
123 {
124 public void setObjectForStatement(PreparedStatement ps, int index, Object value, int sqlType) throws SQLException
125 {
126 if ((value instanceof byte[]) && (sqlType == Types.LONGVARBINARY))
127 {
128 ps.setBytes(index, (byte[]) value);
129 }
130 else
131 {
132 super.setObjectForStatement(ps, index, value, sqlType);
133 }
134 }
135
136 public String createSequenceQuery(String sequenceName)
137 {
138 return "create sequence " + sequenceName;
139 }
140
141 public String createSequenceQuery(String sequenceName, Properties prop)
142 {
143 /*
144 CREATE [ TEMPORARY | TEMP ] SEQUENCE seqname [ INCREMENT increment ]
145 [ MINVALUE minvalue ] [ MAXVALUE maxvalue ]
146 [ START start ] [ CACHE cache ] [ CYCLE ]
147 */
148 StringBuffer query = new StringBuffer(createSequenceQuery(sequenceName));
149 if(prop != null)
150 {
151 Boolean b;
152 Long value;
153
154 value = SequenceManagerHelper.getSeqIncrementBy(prop);
155 if(value != null)
156 {
157 query.append(" INCREMENT ").append(value.longValue());
158 }
159
160 value = SequenceManagerHelper.getSeqMinValue(prop);
161 if(value != null)
162 {
163 query.append(" MINVALUE ").append(value.longValue());
164 }
165
166 value = SequenceManagerHelper.getSeqMaxValue(prop);
167 if(value != null)
168 {
169 query.append(" MAXVALUE ").append(value.longValue());
170 }
171
172 value = SequenceManagerHelper.getSeqStart(prop);
173 if(value != null)
174 {
175 query.append(" START ").append(value.longValue());
176 }
177
178 value = SequenceManagerHelper.getSeqCacheValue(prop);
179 if(value != null)
180 {
181 query.append(" CACHE ").append(value.longValue());
182 }
183
184 b = SequenceManagerHelper.getSeqCycleValue(prop);
185 if(b != null)
186 {
187 if(b.booleanValue()) query.append(" CYCLE");
188 }
189 }
190 return query.toString();
191 }
192
193 public String nextSequenceQuery(String sequenceName)
194 {
195 return "select nextval('" + sequenceName + "')";
196 }
197
198 public String dropSequenceQuery(String sequenceName)
199 {
200 return "drop sequence " + sequenceName;
201 }
202
203 /* (non-Javadoc)
204 * @see org.apache.ojb.broker.platforms.Platform#addPagingSql(java.lang.StringBuffer)
205 */
206 public void addPagingSql(StringBuffer anSqlString)
207 {
208 anSqlString.append(" LIMIT ? OFFSET ?");
209 }
210
211 /* (non-Javadoc)
212 * @see org.apache.ojb.broker.platforms.Platform#supportsPaging()
213 */
214 public boolean supportsPaging()
215 {
216 return true;
217 }
218
219 /* (non-Javadoc)
220 * @see org.apache.ojb.broker.platforms.Platform#bindPagingParameters(java.sql.PreparedStatement, int, int, int)
221 */
222 public int bindPagingParameters(PreparedStatement ps, int index, int startAt, int endAt) throws SQLException
223 {
224 ps.setInt(index, endAt - (startAt - 1)); // number of rows to fetch
225 index++;
226 ps.setInt(index, startAt - 1); // zero based start
227 index++;
228 return index;
229 }
230
231 /**
232 * @see org.apache.ojb.broker.platforms.Platform#getEscapeClause(org.apache.ojb.broker.query.LikeCriteria)
233 */
234 public String getEscapeClause(LikeCriteria aCriteria)
235 {
236 if (LikeCriteria.getEscapeCharacter() != LikeCriteria.DEFAULT_ESCPAPE_CHARACTER)
237 {
238 // the default escape character is \, so there's no need for an escape clause
239 return super.getEscapeClause(aCriteria);
240 }
241 else
242 {
243 return "";
244 }
245 }
246 }