View Javadoc

1   // 
2   //Copyright (c) 2003, Caltha - Gajda, Krzewski, Mach, Potempski Sp.J. 
3   //All rights reserved. 
4   //   
5   //Redistribution and use in source and binary forms, with or without modification,  
6   //are permitted provided that the following conditions are met: 
7   //   
8   //* Redistributions of source code must retain the above copyright notice,  
9   //this list of conditions and the following disclaimer. 
10  //* Redistributions in binary form must reproduce the above copyright notice,  
11  //this list of conditions and the following disclaimer in the documentation  
12  //and/or other materials provided with the distribution. 
13  //* Neither the name of the Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.  
14  //nor the names of its contributors may be used to endorse or promote products  
15  //derived from this software without specific prior written permission. 
16  // 
17  //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"  
18  //AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED  
19  //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
20  //IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,  
21  //INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  
22  //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
23  //OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
24  //WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)  
25  //ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  
26  //POSSIBILITY OF SUCH DAMAGE. 
27  //
28  
29  package org.objectledge.database.persistence;
30  
31  import java.math.BigDecimal;
32  import java.net.URL;
33  import java.sql.Array;
34  import java.sql.Blob;
35  import java.sql.Clob;
36  import java.sql.Connection;
37  import java.sql.PreparedStatement;
38  import java.sql.Ref;
39  import java.sql.ResultSet;
40  import java.sql.SQLException;
41  import java.util.Date;
42  
43  import org.objectledge.database.DatabaseUtils;
44  
45  /**
46   * An implementation of {@link DefaultInputRecord} that wraps a
47   * <code>java.sql.ResultSet</code>.
48   */
49  public class DefaultInputRecord implements InputRecord
50  {
51      // Member objects ////////////////////////////////////////////////////////
52  
53      /*** The wrapped result set. */
54      private ResultSet rs;
55  
56      // Initialization ////////////////////////////////////////////////////////
57  
58      /***
59       * Constructs an <code>InputRecordImpl</code>.
60       *
61       * @param rs the <code>ResultSet</code>.
62       */
63      public DefaultInputRecord(ResultSet rs)
64      {
65          this.rs = rs;
66      }
67  
68      // DefaultInputRecord interface /////////////////////////////////////////////////
69  
70      /***
71       * Returns a <code>boolean</code> field value.
72       *
73       * @param field the name of the field.
74       * @return the field value as boolean.
75       * @throws PersistenceException if the field is missing or otherwise unaccessible.
76       */
77      public boolean getBoolean(String field)
78          throws PersistenceException
79      {
80          try
81          {
82              return rs.getBoolean(field);
83          }
84          catch(SQLException e)
85          {
86              throw new PersistenceException("Failed to read field "+field, e);
87          }
88      }        
89  
90      /***
91       * Returns a <code>byte</code> field value.
92       *
93       * @param field the name of the field.
94       * @return the field value as byte.
95       * @throws PersistenceException if the field is missing or otherwise unaccessible.
96       */
97      public byte getByte(String field)
98          throws PersistenceException        
99      {
100         try
101         {
102             return rs.getByte(field);
103         }
104         catch(SQLException e)
105         {
106             throw new PersistenceException("Failed to read field "+field, e);
107         }
108     }
109 
110     /***
111      * Returns a <code>short</code> field value.
112      *
113      * @param field the name of the field.
114      * @return the field value as short.     
115      * @throws PersistenceException if the field is missing or otherwise unaccessible.
116      */
117     public short getShort(String field)
118         throws PersistenceException        
119     {
120         try
121         {
122             return rs.getShort(field);
123         }
124         catch(SQLException e)
125         {
126             throw new PersistenceException("Failed to read field "+field, e);
127         }
128     }
129 
130     /***
131      * Returns an <code>int</code> field value.
132      *
133      * @param field the name of the field.
134      * @return the field value as integer.
135      * @throws PersistenceException if the field is missing or otherwise unaccessible.
136      */
137     public int getInteger(String field)
138         throws PersistenceException        
139     {
140         try
141         {
142             return rs.getInt(field);
143         }
144         catch(SQLException e)
145         {
146             throw new PersistenceException("Failed to read field "+field, e);
147         }
148     }
149 
150     /***
151      * Returns a <code>long</code> field value.
152      *
153      * @param field the name of the field.
154      * @return the field value as long.
155      * @throws PersistenceException if the field is missing or otherwise unaccessible.
156      */
157     public long getLong(String field)
158         throws PersistenceException        
159     {
160         try
161         {
162             return rs.getLong(field);
163         }
164         catch(SQLException e)
165         {
166             throw new PersistenceException("Failed to read field "+field, e);
167         }
168     }
169 
170     /***
171      * Returns a <code>BigDecimal</code> field value.
172      *
173      * @param field the name of the field.
174      * @return the field value as big decimal.
175      * @throws PersistenceException if the field is missing or otherwise unaccessible.
176      */
177     public BigDecimal getBigDecimal(String field)
178         throws PersistenceException        
179     {
180         try
181         {
182             return rs.getBigDecimal(field);
183         }
184         catch(SQLException e)
185         {
186             throw new PersistenceException("Failed to read field "+field, e);
187         }
188     }
189 
190     /***
191      * Returns a <code>float</code> field value.
192      *
193      * @param field the name of the field.
194      * @return the field value as float.
195      * @throws PersistenceException if the field is missing or otherwise unaccessible.
196      */
197     public float getFloat(String field)
198         throws PersistenceException        
199     {
200         try
201         {
202             return rs.getFloat(field);
203         }
204         catch(SQLException e)
205         {
206             throw new PersistenceException("Failed to read field "+field, e);
207         }
208     }
209 
210     /***
211      * Returns a <code>double</code> field value.
212      *
213      * @param field the name of the field.
214      * @return the field value as double.
215      * @throws PersistenceException if the field is missing or otherwise unaccessible.
216      */
217     public double getDouble(String field)
218         throws PersistenceException        
219     {
220         try
221         {
222             return rs.getDouble(field);
223         }
224         catch(SQLException e)
225         {
226             throw new PersistenceException("Failed to read field "+field, e);
227         }
228     }
229 
230     /***
231      * Returns a <code>String</code> field value.
232      *
233      * @param field the name of the field.
234      * @return the field value as string.
235      * @throws PersistenceException if the field is missing or otherwise unaccessible.
236      */
237     public String getString(String field)
238         throws PersistenceException        
239     {
240         try
241         {
242             return DatabaseUtils.unescapeSqlString(rs.getString(field));
243         }
244         catch(SQLException e)
245         {
246             throw new PersistenceException("Failed to read field "+field, e);
247         }
248     }
249 
250     /***
251      * Returns a <code>byte</code> array field value.
252      *
253      * <p>String value read from the database will be BASE64 decoded to obtain
254      * byte array.</p>
255      *
256      * @param field the name of the field.
257      * @return the field value as array of byte.
258      * @throws PersistenceException if the field is missing or otherwise unaccessible.
259      */
260     public byte[] getBytes(String field)
261         throws PersistenceException        
262     {
263         try
264         {
265             String encoded = rs.getString(field);
266             sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
267             return decoder.decodeBuffer(encoded);
268         }
269         catch(Exception e)
270         {
271             throw new PersistenceException("Failed to read field "+field, e);
272         }
273     }
274 
275     /***
276      * Returns a <code>Date</code> field value.
277      *
278      * @param field the name of the field.
279      * @return the field value as date.
280      * @throws PersistenceException if the field is missing or otherwise
281      *         unaccessible. 
282      */
283     public Date getDate(String field)
284         throws PersistenceException        
285     {
286         try
287         {
288             java.sql.Timestamp ts = rs.getTimestamp(field);
289             return ts == null ? null : new Date(ts.getTime());
290         }
291         catch(SQLException e)
292         {
293             throw new PersistenceException("Failed to read field "+field, e);
294         }
295     }
296 
297     /***
298      * gets a <code>Array</code> field value.
299      * 
300      * @param field the name of the field.
301      * @return value the value of the filed.
302      * @throws PersistenceException if the field could not be get to the
303      *         specified value. 
304      */
305     public Array getArray(String field)
306         throws PersistenceException
307     {
308         try
309         {
310             return rs.getArray(field);
311         }
312         catch(SQLException e)
313         {
314             throw new PersistenceException("Failed to read field "+field, e);
315         }
316     }
317 
318     /***
319      * Returns a <code>Blob</code> field value.
320      * 
321      * @param field the name of the field.
322      * @return value the value of the filed.
323      * @throws PersistenceException if the field could not be get to the
324      *         specified value. 
325      */
326     public Blob getBlob(String field)
327         throws PersistenceException
328     {
329         try
330         {
331             return rs.getBlob(field);
332         }
333         catch(SQLException e)
334         {
335             throw new PersistenceException("Failed to read field "+field, e);
336         }
337     }
338 
339     /***
340      * Returns a <code>Clob</code> field value.
341      * 
342      * @param field the name of the field.
343      * @return value the value of the filed.
344      * @throws PersistenceException if the field could not be get to the
345      *         specified value. 
346      */
347     public Clob getClob(String field)
348         throws PersistenceException
349     {
350         try
351         {
352             return rs.getClob(field);
353         }
354         catch(SQLException e)
355         {
356             throw new PersistenceException("Failed to read field "+field, e);
357         }
358     }
359 
360     /***
361      * Returns a <code>Ref</code> field value.
362      * 
363      * @param field the name of the field.
364      * @return value the value of the filed.
365      * @throws PersistenceException if the field could not be get to the
366      *         specified value. 
367      */
368     public Ref getRef(String field)
369         throws PersistenceException
370     {
371         try
372         {
373             return rs.getRef(field);
374         }
375         catch(SQLException e)
376         {
377             throw new PersistenceException("Failed to read field "+field, e);
378         }
379     }
380 
381     /***
382      * Returns a <code>URL</code> field value.
383      * 
384      * @param field the name of the field.
385      * @return value the value of the filed.
386      * @throws PersistenceException if the field could not be get to the
387      *         specified value. 
388      */
389     public URL getURL(String field)
390         throws PersistenceException
391     {
392         try
393         {
394             return rs.getURL(field);
395         }
396         catch(SQLException e)
397         {
398             throw new PersistenceException("Failed to read field "+field, e);
399         }
400     }
401 
402     /***
403      * Returns a <code>Object</code> field value.
404      * 
405      * @param field the name of the field.
406      * @return value the value of the filed.
407      * @throws PersistenceException if the field could not be get to the
408      *         specified value. 
409      */
410     public Object getObject(String field)
411         throws PersistenceException
412     {
413         try
414         {
415             return rs.getObject(field);
416         }
417         catch(SQLException e)
418         {
419             throw new PersistenceException("Failed to read field "+field, e);
420         }
421     }
422 
423     /***
424      * Returns <code>true</code> if the field has <code>SQL NULL</code>
425      * value. 
426      *
427      * @param field the name of the field.
428      * @return <code>true</code> if null.
429      * @throws PersistenceException if the field is missing or otherwise
430      *         unaccessible. 
431      */
432     public boolean isNull(String field)
433         throws PersistenceException
434     {
435         try
436         {
437             rs.getString(field);
438             return rs.wasNull();
439         }
440         catch(SQLException e)
441         {
442             throw new PersistenceException("Failed to read field "+field, e);
443         }
444     }
445     
446     // statements ///////////////////////////////////////////////////////////////////////////////
447     
448     /***
449      * Creates a select statement for fetching an object from the database.
450      * 
451      * @param object Persistent object.
452      * @param conn the connection to use.
453      * @return a prepared statement.
454      * @throws PersistenceException if there is a problem retrieving key values from the object.
455      * @throws SQLException if there is a problem creating the statement.
456      */
457     public static PreparedStatement getSelectStatements(Persistent object, Connection conn)
458         throws PersistenceException, SQLException
459     {
460         DefaultOutputRecord out = new DefaultOutputRecord(object);
461         object.getData(out);
462         PreparedStatement stmt = conn.prepareStatement("SELECT * FROM " + object.getTable() + 
463             " WHERE " + out.getWhereClause());
464         out.setValues(stmt, true, false);
465         return stmt;
466     }
467     
468     /***
469      * Creates a select statement for fetching an object from the database.
470      * 
471      * @param key the key value.
472      * @param object Persistent object.
473      * @param conn the connection to use.
474      * @return a prepared statement.
475      * @throws SQLException if there is a problem creating the statement.
476      */
477     public static PreparedStatement getSelectStatement(long key, Persistent object, Connection conn)
478         throws SQLException
479     {
480         return conn.prepareStatement("SELECT * FROM " + object.getTable() + " WHERE " +
481             object.getKeyColumns()[0] + " = " + key);
482     }
483     
484     /***
485      * Creates a select statement for fetching an object from the database.
486      * 
487      * @param where where clause, or <code>null</code> to fetch all objects.
488      * @param object Persistent object.
489      * @param conn the connection to use.
490      * @return a prepared statement.
491      * @throws SQLException if there is a problem creating the statement.
492      */
493     public static PreparedStatement getSelectStatement(String where, Persistent object, 
494         Connection conn)
495         throws SQLException
496     {
497         if (where != null)
498         {
499             return conn.prepareStatement("SELECT * FROM " + object.getTable() + " WHERE " + where);
500         }
501         else
502         {
503             return conn.prepareStatement("SELECT * FROM " + object.getTable());
504         }
505     }
506 }