KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > broker > platforms > PlatformDefaultImpl


1 package org.apache.ojb.broker.platforms;
2
3 /* Copyright 2002-2005 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 import java.io.StringReader JavaDoc;
19 import java.sql.CallableStatement JavaDoc;
20 import java.sql.Connection JavaDoc;
21 import java.sql.DatabaseMetaData JavaDoc;
22 import java.sql.PreparedStatement JavaDoc;
23 import java.sql.ResultSet JavaDoc;
24 import java.sql.SQLException JavaDoc;
25 import java.sql.Statement JavaDoc;
26 import java.sql.Types JavaDoc;
27 import java.util.Properties JavaDoc;
28
29 import org.apache.ojb.broker.PersistenceBrokerException;
30 import org.apache.ojb.broker.accesslayer.JoinSyntaxTypes;
31 import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
32 import org.apache.ojb.broker.query.LikeCriteria;
33 import org.apache.ojb.broker.util.logging.Logger;
34 import org.apache.ojb.broker.util.logging.LoggerFactory;
35
36 /**
37  * This class is a concrete implementation of <code>Platform</code>. Provides default implementations for all
38  * methods declared in <code>Platform</code>.
39  * It is intended as a vanilla implementation and as baseclass for
40  * platform specific implementations.
41  *
42  * @version $Id: PlatformDefaultImpl.java,v 1.27.2.7 2005/12/18 16:43:19 tomdz Exp $
43  * @author Thomas Mahler
44  */

45 public class PlatformDefaultImpl implements Platform, JoinSyntaxTypes
46 {
47     protected Logger log = LoggerFactory.getLogger(PlatformDefaultImpl.class);
48     private static final String JavaDoc INITIALIZATION_CHECK_AUTOCOMMIT = "initializationCheck";
49     private static final String JavaDoc FALSE_STR = "false";
50
51     protected boolean m_batchUpdatesChecked = false;
52     protected boolean m_supportsBatchUpdates = false;
53
54     public boolean supportsBatchOperations()
55     {
56         return m_supportsBatchUpdates;
57     }
58
59     /**
60      * Sets platform information for if the jdbc driver/db combo support
61      * batch operations. Will only be checked once, then have same batch
62      * support setting for the entire session.
63      *
64      * @param conn
65      */

66     protected void checkForBatchSupport(Connection JavaDoc conn)
67     {
68         if (!m_batchUpdatesChecked)
69         {
70             DatabaseMetaData JavaDoc meta;
71             try
72             {
73                 meta = conn.getMetaData();
74                 m_supportsBatchUpdates = meta.supportsBatchUpdates();
75             }
76             catch (Throwable JavaDoc th)
77             {
78                 log.info("Batch support check failed", th);
79                 m_supportsBatchUpdates = false;
80             }
81             finally
82             {
83                 m_batchUpdatesChecked = true;
84             }
85         }
86     }
87
88     public void afterStatementCreate(Statement JavaDoc stmt) throws PlatformException
89     {
90         //noop
91
}
92
93     public void beforeStatementClose(Statement JavaDoc stmt, ResultSet JavaDoc rs) throws PlatformException
94     {
95         if (rs != null)
96         {
97             try
98             {
99                 rs.close();
100             }
101             catch (SQLException JavaDoc e)
102             {
103                 throw new PlatformException("Resultset closing failed", e);
104             }
105         }
106     }
107
108     public void afterStatementClose(Statement JavaDoc stmt, ResultSet JavaDoc rs) throws PlatformException
109     {
110         //nothing
111
}
112
113     public void beforeBatch(PreparedStatement JavaDoc stmt) throws PlatformException
114     {
115         // nothing
116
}
117
118     public void addBatch(PreparedStatement JavaDoc stmt) throws PlatformException
119     {
120         try
121         {
122             stmt.addBatch();
123         }
124         catch (SQLException JavaDoc e)
125         {
126             throw new PlatformException("Failure while calling 'addBatch' on given Statement object", e);
127         }
128     }
129
130     public int[] executeBatch(PreparedStatement JavaDoc stmt) throws PlatformException
131     {
132         try
133         {
134             return stmt.executeBatch();
135         }
136         catch (SQLException JavaDoc e)
137         {
138             throw new PlatformException("Failure while calling 'executeBatch' on given Statement object", e);
139         }
140     }
141
142
143     /**
144      * @see Platform#initializeJdbcConnection
145      */

146     public void initializeJdbcConnection(JdbcConnectionDescriptor jcd, Connection JavaDoc conn) throws PlatformException
147     {
148         if (jcd.getBatchMode()) checkForBatchSupport(conn);
149
150         switch (jcd.getUseAutoCommit())
151         {
152             case JdbcConnectionDescriptor.AUTO_COMMIT_IGNORE_STATE:
153                 // nothing to do
154
break;
155             case JdbcConnectionDescriptor.AUTO_COMMIT_SET_TRUE_AND_TEMPORARY_FALSE:
156                 try
157                 {
158                     /*
159                     arminw:
160                     workaround to be backward compatible. In future releases we shouldn't change the autocommit
161                     state of a connection at initializing by the ConnectionFactory. The autocommit state should
162                     only be changed by the ConnectionManager. We have to separate this stuff.
163                     */

164                     if (!jcd.getAttribute(INITIALIZATION_CHECK_AUTOCOMMIT, FALSE_STR).equalsIgnoreCase(FALSE_STR)
165                             && !conn.getAutoCommit())
166                     {
167                         conn.setAutoCommit(true);
168                     }
169                 }
170                 catch (SQLException JavaDoc e)
171                 {
172                     if (!jcd.isIgnoreAutoCommitExceptions())
173                     {
174                         throw new PlatformException("Connection initializing: setAutoCommit(true) failed", e);
175                     }
176                     else
177                     {
178                         log.info("Connection initializing: setAutoCommit jdbc-driver problems. " + e.getMessage());
179                     }
180                 }
181                 break;
182             case JdbcConnectionDescriptor.AUTO_COMMIT_SET_FALSE:
183                 try
184                 {
185                     if (conn.getAutoCommit()) conn.setAutoCommit(false);
186                 }
187                 catch (SQLException JavaDoc e)
188                 {
189                     if (!jcd.isIgnoreAutoCommitExceptions())
190                     {
191                         throw new PlatformException("Connection initializing: setAutoCommit(false) failed", e);
192                     }
193                     else
194                     {
195                         log.info("Connection initializing: setAutoCommit jdbc-driver problems. " + e.getMessage());
196                     }
197                 }
198                 break;
199         }
200     }
201
202     public void changeAutoCommitState(JdbcConnectionDescriptor jcd, Connection JavaDoc con, boolean newState)
203     {
204         if (con == null)
205         {
206             log.error("Given m_connection was null, cannot prepare autoCommit state");
207             return;
208         }
209         if (JdbcConnectionDescriptor.AUTO_COMMIT_SET_TRUE_AND_TEMPORARY_FALSE == jcd.getUseAutoCommit())
210         {
211             try
212             {
213                 con.setAutoCommit(newState);
214             }
215             catch (SQLException JavaDoc e)
216             {
217                 if (jcd.isIgnoreAutoCommitExceptions())
218                 {
219                     log.info("Set autoCommit(" + newState + ") failed: " + e.getMessage());
220                 }
221                 else
222                 {
223                     log.error("Set autoCommit(" + newState + ") failed", e);
224                     throw new PersistenceBrokerException("Set autoCommit(false) failed", e);
225                 }
226             }
227         }
228     }
229
230     /*
231      * @see Platform#setObject(PreparedStatement, int, Object, int)
232      */

233     public void setObjectForStatement(PreparedStatement JavaDoc ps, int index, Object JavaDoc value, int sqlType)
234             throws SQLException JavaDoc
235     {
236         if ((sqlType == Types.LONGVARCHAR) && (value instanceof String JavaDoc))
237         {
238             String JavaDoc s = (String JavaDoc) value;
239             ps.setCharacterStream(index, new StringReader JavaDoc(s), s.length());
240         }
241         /*
242         PATCH for BigDecimal truncation problem. Seems that several databases (e.g. DB2, Sybase)
243         has problem with BigDecimal fields if the sql-type was set. The problem was discussed here
244         http://nagoya.apache.org/eyebrowse/ReadMsg?listName=ojb-user@db.apache.org&msgNo=14113
245         A better option will be
246         <snip>
247         else if ((value instanceof BigDecimal) && (sqlType == Types.DECIMAL
248                  || sqlType == Types.NUMERIC))
249          {
250              ps.setObject(index, value, sqlType,
251                      ((BigDecimal) value).scale());
252          }
253          </snip>
254         But this way maxDB/sapDB does not work correct, so we use the most flexible solution
255         and let the jdbc-driver handle BigDecimal objects by itself.
256         */

257         else if(sqlType == Types.DECIMAL || sqlType == Types.NUMERIC)
258         {
259             ps.setObject(index, value);
260         }
261         else
262         {
263 // arminw: this method call is done very, very often, so we can improve performance
264
// by comment out this section
265
// if (log.isDebugEnabled()) {
266
// log.debug("Default setObjectForStatement, sqlType=" + sqlType +
267
// ", value class=" + (value == null ? "NULL!" : value.getClass().getName())
268
// + ", value=" + value);
269
// }
270
ps.setObject(index, value, sqlType);
271         }
272     }
273
274     /*
275      * @see Platform#setNullForStatement(PreparedStatement, int, int)
276      */

277     public void setNullForStatement(PreparedStatement JavaDoc ps, int index, int sqlType) throws SQLException JavaDoc
278     {
279         ps.setNull(index, sqlType);
280     }
281
282     /**
283      * Get join syntax type for this RDBMS - one on of the constants from JoinSyntaxType interface
284      *
285      * @see Platform#getJoinSyntaxType
286      */

287     public byte getJoinSyntaxType()
288     {
289         return SQL92_JOIN_SYNTAX;
290     }
291
292     /**
293      * Override default ResultSet size determination (rs.last();rs.getRow())
294      * with select count(*) operation
295      *
296      * @see Platform#useCountForResultsetSize()
297      */

298     public boolean useCountForResultsetSize()
299     {
300         return false;
301     }
302
303     public String JavaDoc createSequenceQuery(String JavaDoc sequenceName, Properties JavaDoc prop)
304     {
305         return createSequenceQuery(sequenceName);
306     }
307
308     /**
309      * Override this method to enable database based sequence generation
310      */

311     public String JavaDoc createSequenceQuery(String JavaDoc sequenceName)
312     {
313         /*default implementation does not support this*/
314         throw new UnsupportedOperationException JavaDoc("This feature is not supported by this implementation");
315     }
316
317     /**
318      * Override this method to enable database based sequence generation
319      */

320     public String JavaDoc nextSequenceQuery(String JavaDoc sequenceName)
321     {
322         /*default implementation does not support this*/
323         throw new UnsupportedOperationException JavaDoc("This feature is not supported by this implementation");
324     }
325
326     /**
327      * Override this method to enable database based sequence generation
328      */

329     public String JavaDoc dropSequenceQuery(String JavaDoc sequenceName)
330     {
331         /*default implementation does not support this*/
332         throw new UnsupportedOperationException JavaDoc("This feature is not supported by this implementation");
333     }
334
335     public CallableStatement JavaDoc prepareNextValProcedureStatement(Connection JavaDoc con, String JavaDoc procedureName,
336                                                               String JavaDoc sequenceName) throws PlatformException
337     {
338         /*@todo implementation*/
339         throw new UnsupportedOperationException JavaDoc("Not supported by this implementation");
340     }
341
342     public String JavaDoc getLastInsertIdentityQuery(String JavaDoc tableName)
343     {
344         /*@todo implementation*/
345         throw new UnsupportedOperationException JavaDoc("This feature is not supported by this implementation");
346     }
347
348     /**
349      * @see org.apache.ojb.broker.platforms.Platform#addPagingSql(java.lang.StringBuffer)
350      */

351     public void addPagingSql(StringBuffer JavaDoc anSqlString)
352     {
353         // do nothing
354
}
355
356     /**
357      * @see org.apache.ojb.broker.platforms.Platform#bindPagingParametersFirst()
358      */

359     public boolean bindPagingParametersFirst()
360     {
361         return false;
362     }
363
364     /**
365      * @see org.apache.ojb.broker.platforms.Platform#supportsPaging()
366      */

367     public boolean supportsPaging()
368     {
369         return false;
370     }
371
372     /**
373      * @see org.apache.ojb.broker.platforms.Platform#bindPagingParameters(java.sql.PreparedStatement, int, int, int)
374      */

375     public int bindPagingParameters(PreparedStatement JavaDoc ps, int index, int startAt, int endAt) throws SQLException JavaDoc
376     {
377         ps.setInt(index, startAt - 1); // zero based start
378
index++;
379         ps.setInt(index, endAt - (startAt - 1)); // number of rows to fetch
380
index++;
381         return index;
382     }
383
384     /**
385      * Answer the Character for Concatenation
386      */

387     protected String JavaDoc getConcatenationCharacter()
388     {
389         return "||";
390     }
391
392     /**
393      * {@inheritDoc}
394      */

395     public boolean supportsMultiColumnCountDistinct()
396     {
397         return true;
398     }
399
400     /**
401      * @see org.apache.ojb.broker.platforms.Platform#concatenate(java.lang.String[])
402      */

403     public String JavaDoc concatenate(String JavaDoc[] theColumns)
404     {
405         if (theColumns.length == 1)
406         {
407             return theColumns[0];
408         }
409
410         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
411         String JavaDoc concatChar = getConcatenationCharacter();
412
413         for (int i = 0; i < theColumns.length; i++)
414         {
415             if (i > 0)
416             {
417                 buf.append(" ").append(concatChar).append(" ");
418             }
419             buf.append(theColumns[i]);
420         }
421
422         return buf.toString();
423     }
424
425     /**
426      * @see org.apache.ojb.broker.platforms.Platform#getEscapeClause(org.apache.ojb.broker.query.LikeCriteria)
427      */

428     public String JavaDoc getEscapeClause(LikeCriteria aCriteria)
429     {
430         String JavaDoc value = (String JavaDoc) aCriteria.getValue();
431         char escapeChar = LikeCriteria.getEscapeCharacter();
432
433         if (value.indexOf(escapeChar) >= 0)
434         {
435             return " ESCAPE '" + escapeChar + "'";
436         }
437         else
438         {
439             return "";
440         }
441     }
442
443     /**
444      * @see org.apache.ojb.broker.platforms.Platform#registerOutResultSet(java.sql.CallableStatement, int)
445      */

446     public void registerOutResultSet(CallableStatement JavaDoc stmt, int position)
447             throws SQLException JavaDoc
448     {
449         stmt.registerOutParameter(position, Types.OTHER);
450     }
451 }
452
Popular Tags