Clover coverage report -
Coverage timestamp: Thu Jul 5 2007 20:02:32 EDT
file stats: LOC: 330   Methods: 8
NCLOC: 215   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
JDBCCacheLoaderOld.java 25% 32.2% 50% 30.8%
coverage coverage
 1    /*
 2    * JBoss, the OpenSource J2EE webOS
 3    *
 4    * Distributable under LGPL license.
 5    * See terms of license at gnu.org.
 6    */
 7    package org.jboss.cache.loader;
 8   
 9    import org.apache.commons.logging.Log;
 10    import org.apache.commons.logging.LogFactory;
 11    import org.jboss.cache.Fqn;
 12    import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
 13   
 14    import java.sql.Connection;
 15    import java.sql.PreparedStatement;
 16    import java.sql.ResultSet;
 17    import java.sql.SQLException;
 18    import java.util.ArrayList;
 19    import java.util.HashMap;
 20    import java.util.List;
 21    import java.util.Map;
 22   
 23    /**
 24    * JDBC CacheLoader implementation.
 25    * <p/>
 26    * This implementation uses one table. The table consists of three columns:
 27    * <ul>
 28    * <li>text column for fqn (which is also a primary key)</li>
 29    * <li>blob column for attributes (can contain null)</li>
 30    * <li>text column for parent fqn (can contain null)</li>
 31    * </ul>
 32    * <p/>
 33    * The configuration options are:
 34    * <p/>
 35    * <b>Table configuration</b>
 36    * <ul>
 37    * <li><b>cache.jdbc.table.name</b> - the table name (default is <i>jbosscache</i>)</li>
 38    * <li><b>cache.jdbc.table.create</b> - should be true or false, indicates whether to create the table at start phase</li>
 39    * <li><b>cache.jdbc.table.drop</b> - should be true or false, indicates whether to drop the table at stop phase</li>
 40    * <li><b>cache.jdbc.table.primarykey</b> - the name for the table primary key (default is <i>jbosscache_pk</i>)</li>
 41    * <li><b>cache.jdbc.fqn.column</b> - the name for the fqn column (default is <i>fqn</i>)</li>
 42    * <li><b>cache.jdbc.fqn.type</b> - the type for the fqn column (default is <i>varchar(255)</i>)</li>
 43    * <li><b>cache.jdbc.node.column</b> - the name for the node's contents column (default is <i>node</i>)</li>
 44    * <li><b>cache.jdbc.node.type</b> - the type for the node's contents column (default is <i>blob</i>)</li>
 45    * <li><b>cache.jdbc.parent.column</b> - the name for the parent fqn column (default is <i>parent</i>)</li>
 46    * </ul>
 47    * <p/>
 48    * <b>DataSource configuration</b>
 49    * <ul>
 50    * <li><b>cache.jdbc.datasource</b> - the JNDI name of the datasource</li>
 51    * </ul>
 52    * <p/>
 53    * <b>JDBC driver configuration (used when DataSource is not configured)</b>
 54    * <ul>
 55    * <li><b>cache.jdbc.driver</b> - fully qualified JDBC driver name</li>
 56    * <li><b>cache.jdbc.url</b> - URL to connect to the database</li>
 57    * <li><b>cache.jdbc.user</b> - the username to use to connect to the database</li>
 58    * <li><b>cache.jdbc.password</b> - the password to use to connect to the database</li>
 59    * </ul>
 60    *
 61    * @author <a href="mailto:alex@jboss.org">Alexey Loubyansky</a>
 62    * @author <a href="mailto:hmesha@novell.com">Hany Mesha </a>
 63    * @author <a href="mailto:galder.zamarreno@jboss.com">Galder Zamarreno</a>
 64    * @version <tt>$Revision: 1.6 $</tt>
 65    * @deprecated please use the {@link org.jboss.cache.loader.JDBCCacheLoader}.
 66    */
 67    @Deprecated
 68    public class JDBCCacheLoaderOld extends AdjListJDBCCacheLoader
 69    {
 70    private static final Log log = LogFactory.getLog(JDBCCacheLoaderOld.class);
 71   
 72    private JDBCCacheLoaderOldConfig config;
 73   
 74   
 75  6 public AdjListJDBCCacheLoaderConfig processConfig(IndividualCacheLoaderConfig base)
 76    {
 77  6 if (config instanceof JDBCCacheLoaderOldConfig)
 78    {
 79  0 config = (JDBCCacheLoaderOldConfig) base;
 80    }
 81    else
 82    {
 83  6 config = new JDBCCacheLoaderOldConfig(base);
 84    }
 85  6 return config;
 86    }
 87   
 88  0 public IndividualCacheLoaderConfig getConfig()
 89    {
 90  0 return config;
 91    }
 92   
 93   
 94    /**
 95    * Adds/overrides a value in a node for a key.
 96    * If the node does not exist yet, the node will be created.
 97    * If parent nodes do not exist for the node, empty parent nodes will be created.
 98    *
 99    * @param name node's fqn
 100    * @param key attribute's key
 101    * @param value attribute's value
 102    * @return old value associated with the attribute's key or null if there was no value previously
 103    * associated with the attribute's key
 104    * @throws Exception
 105    */
 106  24 public Object put(Fqn name, Object key, Object value) throws Exception
 107    {
 108  24 Map oldNode = loadNode(name);
 109  24 Object oldValue;
 110  24 Map node;
 111   
 112  24 if (oldNode == null || oldNode == NULL_NODE_IN_ROW)
 113    {
 114  24 node = new HashMap();
 115    }
 116    else
 117    {
 118  0 node = oldNode;
 119    }
 120  24 oldValue = node.put(key, value);
 121   
 122  24 if (oldNode != null)
 123    {
 124  0 updateNode(name, node);
 125    }
 126    else
 127    {
 128  24 if (name.size() > 1)
 129    {
 130  21 for (int i = 1; i < name.size(); ++i)
 131    {
 132  42 final Fqn parent = name.getAncestor(i);
 133  42 if (!exists(parent))
 134    {
 135  16 insertNode(parent, null);
 136    }
 137    }
 138    }
 139  24 insertNode(name, node);
 140    }
 141   
 142  24 return oldValue;
 143    }
 144   
 145    /**
 146    * Adds attributes from the passed in map to the existing node.
 147    * If there is no node for the fqn, a new node will be created.
 148    *
 149    * @param name node's fqn
 150    * @param attributes attributes
 151    * @throws Exception
 152    */
 153  0 public void put(Fqn name, Map attributes) throws Exception
 154    {
 155  0 put(name, attributes, false);
 156    }
 157   
 158    /**
 159    * Removes a node and all its children.
 160    * Uses the same connection for all the db work.
 161    *
 162    * @param name node's fqn
 163    * @throws Exception
 164    */
 165  12 public void remove(Fqn name) throws Exception
 166    {
 167  12 Connection con = null;
 168  12 PreparedStatement ps = null;
 169  12 try
 170    {
 171  12 if (name.size() == 0)
 172    {
 173  12 if (log.isDebugEnabled())
 174    {
 175  0 log.debug("executing sql: " + config.getDeleteAllSql());
 176    }
 177   
 178  12 con = cf.getConnection();
 179  12 ps = con.prepareStatement(config.getDeleteAllSql());
 180  12 int deletedRows = ps.executeUpdate();
 181   
 182  12 if (log.isDebugEnabled())
 183    {
 184  0 log.debug("total rows deleted: " + deletedRows);
 185    }
 186    }
 187    else
 188    {
 189  0 StringBuffer sql = new StringBuffer(300);
 190  0 sql.append("delete from ").append(config.getTable()).append(" where fqn in (");
 191    //sql2.append("delete from " + table + " where fqn=? or parent in (");
 192  0 List fqns = new ArrayList();
 193   
 194  0 addChildrenToDeleteSql(name.toString(), sql, fqns);
 195   
 196  0 sql.append(')');
 197   
 198  0 if (fqns.size() == 1)
 199    {
 200  0 if (log.isDebugEnabled())
 201    {
 202  0 log.debug("executing sql: " + config.getDeleteNodeSql() + "(" + name + ")");
 203    }
 204   
 205  0 con = cf.getConnection();
 206  0 ps = con.prepareStatement(config.getDeleteNodeSql());
 207  0 ps.setString(1, name.toString());
 208    }
 209    else
 210    {
 211  0 if (log.isDebugEnabled())
 212    {
 213  0 log.debug("executing sql: " + sql + " " + fqns);
 214    }
 215   
 216  0 con = cf.getConnection();
 217  0 ps = con.prepareStatement(sql.toString());
 218  0 for (int i = 0; i < fqns.size(); ++i)
 219    {
 220  0 ps.setString(i + 1, (String) fqns.get(i));
 221    }
 222    }
 223   
 224  0 int deletedRows = ps.executeUpdate();
 225   
 226  0 if (log.isDebugEnabled())
 227    {
 228  0 log.debug("total rows deleted: " + deletedRows);
 229    }
 230    }
 231    }
 232    catch (SQLException e)
 233    {
 234  0 reportAndRethrowError("Failed to remove node " + name, e);
 235    }
 236    finally
 237    {
 238  12 safeClose(ps);
 239  12 cf.close(con);
 240    }
 241    }
 242   
 243    // Private
 244   
 245  0 private void addChildrenToDeleteSql(String name, StringBuffer sql, List fqns)
 246    throws SQLException
 247    {
 248    // for now have to use connection per method, i.e. can't pass the same connection to recursive
 249    // invocations because buggy PointBase driver invalidates result sets.
 250  0 Connection con = null;
 251  0 PreparedStatement selChildrenPs = null;
 252  0 ResultSet rs = null;
 253  0 try
 254    {
 255  0 if (log.isDebugEnabled())
 256    {
 257  0 log.debug("executing sql: " + config.getSelectChildFqnsSql() + "(" + name + ")");
 258    }
 259   
 260  0 con = cf.getConnection();
 261  0 selChildrenPs = con.prepareStatement(config.getSelectChildFqnsSql());
 262  0 selChildrenPs.setString(1, name);
 263  0 rs = selChildrenPs.executeQuery();
 264   
 265  0 if (rs.next())
 266    {
 267  0 do
 268    {
 269  0 String childStr = rs.getString(1);
 270  0 addChildrenToDeleteSql(childStr, sql, fqns);
 271    }
 272  0 while (rs.next());
 273    }
 274   
 275  0 if (fqns.size() == 0)
 276    {
 277  0 sql.append("?");
 278    }
 279    else
 280    {
 281  0 sql.append(", ?");
 282    }
 283  0 fqns.add(name);
 284    }
 285    finally
 286    {
 287  0 safeClose(rs);
 288  0 safeClose(selChildrenPs);
 289  0 cf.close(con);
 290    }
 291    }
 292   
 293  0 public void put(Fqn name, Map attributes, boolean override) throws Exception
 294    {
 295    // JBCACHE-769 -- make a defensive copy
 296  0 Map attrs = (attributes == null ? null : new HashMap(attributes));
 297   
 298  0 Map oldNode = loadNode(name);
 299  0 if (oldNode != null)
 300    {
 301  0 if (!override && oldNode != NULL_NODE_IN_ROW && attrs != null)
 302    {
 303  0 attrs.putAll(oldNode);
 304    }
 305  0 updateNode(name, attrs);
 306    }
 307    else
 308    {
 309  0 if (name.size() > 1)
 310    {
 311  0 for (int i = 1; i < name.size(); ++i)
 312    {
 313  0 final Fqn parent = name.getAncestor(i);
 314  0 if (!exists(parent))
 315    {
 316  0 insertNode(parent, null);
 317    }
 318    }
 319    }
 320  0 insertNode(name, attrs);
 321    }
 322    }
 323   
 324   
 325  147 protected Log getLogger()
 326    {
 327  147 return log;
 328    }
 329   
 330    }