Clover coverage report - Ledge Components - SNAPSHOT
Coverage timestamp: Fri Nov 17 2006 05:13:20 CET
file stats: LOC: 392   Methods: 10
NCLOC: 265   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
DefaultPersistence.java 81.8% 90.4% 100% 89.8%
coverage coverage
 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.sql.Connection;
 32    import java.sql.PreparedStatement;
 33    import java.sql.ResultSet;
 34    import java.sql.Statement;
 35    import java.util.ArrayList;
 36    import java.util.List;
 37   
 38    import org.jcontainer.dna.Logger;
 39    import org.objectledge.database.Database;
 40    import org.objectledge.database.DatabaseUtils;
 41   
 42    /**
 43    * Provides Object-Relational DB mapping.
 44    *
 45    * @author <a href="mailto:rafal@caltha.pl">Rafal Krzewski</a>
 46    * @author <a href="mailto:pablo@caltha.pl">Pawel Potempski</a>
 47    * @version $Id: DefaultPersistence.java,v 1.5 2005/05/05 11:13:02 rafal Exp $
 48    */
 49    public class DefaultPersistence implements Persistence
 50    {
 51    /** The Database. */
 52    private Database database;
 53   
 54    /** The logger */
 55    private Logger logger;
 56   
 57    /**
 58    * Component constructor.
 59    *
 60    * @param database the database.
 61    * @param logger the logger.
 62    */
 63  4508 public DefaultPersistence(Database database, Logger logger)
 64    {
 65  4508 this.logger = logger;
 66  4508 this.database = database;
 67    }
 68   
 69    // PersistenceSystem interface //////////////////////////////////////////
 70   
 71    /**
 72    * Loads an object from the database.
 73    *
 74    * @param id the identifier of the object.
 75    * @param factory the object instance factory.
 76    * @return the presistent object.
 77    * @throws PersistenceException if any exception occured.
 78    */
 79  138 public Persistent load(long id, PersistentFactory factory) throws PersistenceException
 80    {
 81  138 Connection conn = null;
 82  138 try
 83    {
 84  138 conn = database.getConnection();
 85  138 Persistent obj = factory.newInstance();
 86  138 PreparedStatement statement = DefaultInputRecord.getSelectStatement(id, obj, conn);
 87  138 ResultSet rs = statement.executeQuery();
 88  138 if (!rs.next())
 89    {
 90  92 return null;
 91    }
 92  46 InputRecord record = new DefaultInputRecord(rs);
 93  46 obj.setData(record);
 94  46 obj.setSaved(record.getLong(obj.getKeyColumns()[0]));
 95  46 return obj;
 96    }
 97    catch (Exception e)
 98    {
 99  0 throw new PersistenceException("Failed to retrieve object", e);
 100    }
 101    finally
 102    {
 103  138 DatabaseUtils.close(conn);
 104    }
 105    }
 106   
 107    /**
 108    * Loads objects from the database.
 109    *
 110    * <p>Note that joins are not supported. This package provides a means of
 111    * converting objects to rows in a table and vice versa. If you want more,
 112    * you need some different tool.</p>
 113    *
 114    * @param where the where clause to be used in the query
 115    * @param factory the object instance factory.
 116    * @return the list of presistent objects.
 117    * @throws PersistenceException if any exception occured.
 118    */
 119  5520 public List load(String where, PersistentFactory factory) throws PersistenceException
 120    {
 121  5520 Connection conn = null;
 122  5520 try
 123    {
 124  5520 conn = database.getConnection();
 125  5520 Persistent obj = factory.newInstance();
 126  5520 PreparedStatement statement = DefaultInputRecord.getSelectStatement(where, obj, conn);
 127  5520 ResultSet rs = statement.executeQuery();
 128  5520 InputRecord record = new DefaultInputRecord(rs);
 129  5520 ArrayList list = new ArrayList();
 130  5520 while (rs.next())
 131    {
 132  8004 obj.setData(record);
 133  8004 obj.setSaved(record.getLong(obj.getKeyColumns()[0]));
 134  8004 list.add(obj);
 135  8004 obj = factory.newInstance();
 136    }
 137  5520 return list;
 138    }
 139    catch (Exception e)
 140    {
 141  0 throw new PersistenceException("Failed to retrieve object", e);
 142    }
 143    finally
 144    {
 145  5520 DatabaseUtils.close(conn);
 146    }
 147    }
 148   
 149    /**
 150    * Saves an object in the database.
 151    *
 152    * @param object the object to be saved.
 153    * @throws PersistenceException if any exception occured.
 154    */
 155  4002 public void save(Persistent object) throws PersistenceException
 156    {
 157  4002 synchronized (object)
 158    {
 159  4002 OutputRecord record = new DefaultOutputRecord(object);
 160  4002 String table = object.getTable();
 161  4002 String[] keys = object.getKeyColumns();
 162  4002 object.getData(record);
 163  4002 Connection conn = null;
 164   
 165  4002 try
 166    {
 167  4002 conn = database.getConnection();
 168  4002 PreparedStatement statement;
 169  4002 if (object.getSaved())
 170    {
 171  230 statement = record.getUpdateStatement(conn);
 172  230 statement.execute();
 173    }
 174    else
 175    {
 176  3772 long id;
 177  3772 if (keys.length == 1)
 178    {
 179  644 id = database.getNextId(table);
 180  644 record.setLong(keys[0], id);
 181    }
 182    else
 183    {
 184  3128 id = -1;
 185    }
 186  3772 statement = record.getInsertStatement(conn);
 187  3772 statement.execute();
 188  3772 object.setSaved(id);
 189    }
 190    }
 191    catch (Exception e)
 192    {
 193  0 throw new PersistenceException("Failed to save object", e);
 194    }
 195    finally
 196    {
 197  4002 DatabaseUtils.close(conn);
 198    }
 199    }
 200    }
 201   
 202    /**
 203    * Reverts the object to the saved state.
 204    *
 205    * @param object the object to have it's state restored.
 206    * @throws PersistenceException if any exception occured.
 207    * @throws IllegalStateException if no state has been saved yet for the
 208    * object in question.
 209    */
 210  138 public void revert(Persistent object) throws PersistenceException, IllegalStateException
 211    {
 212  138 synchronized (object)
 213    {
 214  138 if (!object.getSaved())
 215    {
 216  46 throw new IllegalStateException("no state has been saved yet");
 217    }
 218  92 Connection conn = null;
 219  92 try
 220    {
 221  92 conn = database.getConnection();
 222  92 PreparedStatement statement = DefaultInputRecord.getSelectStatements(object, conn);
 223  92 ResultSet rs = statement.executeQuery();
 224  92 if (!rs.next())
 225    {
 226  46 throw new PersistenceException("saved state was lost");
 227    }
 228  46 InputRecord irecord = new DefaultInputRecord(rs);
 229  46 object.setData(irecord);
 230    }
 231    catch (Exception e)
 232    {
 233  46 throw new PersistenceException("failed to revert object's state", e);
 234    }
 235    finally
 236    {
 237  92 DatabaseUtils.close(conn);
 238    }
 239    }
 240    }
 241   
 242    /**
 243    * Removes an object from the database.
 244    *
 245    * @param object the object to be removed.
 246    * @throws PersistenceException if any exception occured.
 247    */
 248  322 public void delete(Persistent object) throws PersistenceException
 249    {
 250  322 synchronized (object)
 251    {
 252  322 Connection conn = null;
 253  322 try
 254    {
 255  322 conn = database.getConnection();
 256  322 OutputRecord record = new DefaultOutputRecord(object);
 257  322 object.getData(record);
 258  322 PreparedStatement statement = record.getDeleteStatement(conn);
 259  322 statement.execute();
 260  322 if(statement.getUpdateCount() != 1)
 261    {
 262  0 throw new PersistenceException("unsuccessful DELETE statement");
 263    }
 264    }
 265    catch (Exception e)
 266    {
 267  0 if(e instanceof PersistenceException)
 268    {
 269  0 throw (PersistenceException)e;
 270    }
 271  0 throw new PersistenceException("Failed to delete object", e);
 272    }
 273    finally
 274    {
 275  322 DatabaseUtils.close(conn);
 276    }
 277    }
 278    }
 279   
 280    /**
 281    * Removes the objects from the database.
 282    *
 283    * @param where the where clause to be used in the query
 284    * @param factory the object instance factory.
 285    * @throws PersistenceException if any exception occured.
 286    */
 287  1196 public void delete(String where, PersistentFactory factory) throws PersistenceException
 288    {
 289  1196 Connection conn = null;
 290  1196 try
 291    {
 292  1196 conn = database.getConnection();
 293  1196 Persistent obj = factory.newInstance();
 294  1196 PreparedStatement statement = conn.prepareStatement("DELETE FROM " + obj.getTable() +
 295    " WHERE " + where);
 296  1196 statement.executeUpdate();
 297    }
 298    catch (Exception e)
 299    {
 300  0 throw new PersistenceException("Failed to retrieve object", e);
 301    }
 302    finally
 303    {
 304  1196 DatabaseUtils.close(conn);
 305    }
 306    }
 307   
 308    /**
 309    * An utility method for checking for existence of rows.
 310    *
 311    * @param table the table to be checked.
 312    * @param where the condition.
 313    * @return <code>true</code> if the <code>condition</code> is true for one
 314    * or more rows in the <code>table</code>.
 315    * @throws PersistenceException if any exception occured.
 316    */
 317  184 public boolean exists(String table, String where) throws PersistenceException
 318    {
 319  184 Connection conn = null;
 320  184 try
 321    {
 322  184 conn = database.getConnection();
 323  184 Statement statement = conn.createStatement();
 324  184 ResultSet rs;
 325  184 if (where != null)
 326    {
 327  92 rs = statement.executeQuery("SELECT DISTINCT 1 FROM " + table + " WHERE " + where);
 328    }
 329    else
 330    {
 331  92 rs = statement.executeQuery("SELECT DISTINCT 1 FROM " + table);
 332    }
 333  184 return (rs.next());
 334    }
 335    catch (Exception e)
 336    {
 337  0 throw new PersistenceException("Failed to execute query", e);
 338    }
 339    finally
 340    {
 341  184 DatabaseUtils.close(conn);
 342    }
 343    }
 344   
 345    /**
 346    * An utility method for checking the number of matching rows.
 347    *
 348    * @param table the table to be chcked.
 349    * @param where the condition.
 350    * @return the number of <code>table</code> matching the condition.
 351    * @throws PersistenceException if any exception occured.
 352    */
 353  138 public int count(String table, String where) throws PersistenceException
 354    {
 355  138 Connection conn = null;
 356  138 try
 357    {
 358  138 conn = database.getConnection();
 359  138 Statement statement = conn.createStatement();
 360  138 ResultSet rs;
 361  138 if (where != null)
 362    {
 363  46 rs = statement.executeQuery("SELECT COUNT(*) FROM " + table + " WHERE " + where);
 364    }
 365    else
 366    {
 367  92 rs = statement.executeQuery("SELECT COUNT(*) FROM " + table);
 368    }
 369  138 if (!rs.next())
 370    {
 371  0 throw new PersistenceException("internal error - no data???");
 372    }
 373  138 return (rs.getInt(1));
 374    }
 375    catch (Exception e)
 376    {
 377  0 throw new PersistenceException("Failed to execute query", e);
 378    }
 379    finally
 380    {
 381  138 DatabaseUtils.close(conn);
 382    }
 383    }
 384   
 385    /**
 386    * {@inheritDoc}
 387    */
 388  4508 public Database getDatabase()
 389    {
 390  4508 return database;
 391    }
 392    }