TablesDependencyHelper.java

  1. /*
  2.  *
  3.  * The DbUnit Database Testing Framework
  4.  * Copyright (C)2005, DbUnit.org
  5.  *
  6.  * This library is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Lesser General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2.1 of the License, or (at your option) any later version.
  10.  *
  11.  * This library is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Lesser General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public
  17.  * License along with this library; if not, write to the Free Software
  18.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  *
  20.  */
  21. package org.dbunit.database.search;

  22. import java.sql.SQLException;
  23. import java.util.Set;

  24. import org.dbunit.database.IDatabaseConnection;
  25. import org.dbunit.database.PrimaryKeyFilter.PkTableMap;
  26. import org.dbunit.dataset.DataSetException;
  27. import org.dbunit.dataset.FilteredDataSet;
  28. import org.dbunit.dataset.IDataSet;
  29. import org.dbunit.dataset.filter.ITableFilter;
  30. import org.dbunit.util.CollectionsHelper;
  31. import org.dbunit.util.search.DepthFirstSearch;
  32. import org.dbunit.util.search.SearchException;
  33. import org.slf4j.Logger;
  34. import org.slf4j.LoggerFactory;


  35. /**
  36.  * Helper for the graph-search based classes used to calculate dependency
  37.  * among tables.  
  38.  *
  39.  * @author Felipe Leme (dbunit@felipeal.net)
  40.  * @author Last changed by: $Author$
  41.  * @version $Revision$ $Date$
  42.  * @since Aug 26, 2005
  43.  */
  44. public class TablesDependencyHelper {

  45.     /**
  46.      * Logger for this class
  47.      */
  48.     private static final Logger logger = LoggerFactory.getLogger(TablesDependencyHelper.class);

  49.     // this is a "static" class
  50.     private TablesDependencyHelper() {
  51.     }

  52.     /**
  53.      * Get the name of all tables that depend on the root tables (i.e, all tables that have FKs
  54.      * pointing to the PK of the root table).
  55.      * @param connection database connection
  56.      * @param rootTable root table described above
  57.      * @return name of all tables that depend on the root table (including the root table),
  58.      * in the right order for insertions
  59.      * @throws SearchException if an exception occurred while calculating the order
  60.      */
  61.     public static String[] getDependentTables( IDatabaseConnection connection, String rootTable )
  62.     throws SearchException
  63.     {
  64.         logger.debug("getDependentTables(connection={}, rootTable={}) - start", connection, rootTable);
  65.         return getDependentTables( connection, new String[] { rootTable } );    
  66.     }

  67.     /**
  68.      * Get the name of all tables that depend on the root tables (i.e, all tables that have FKs
  69.      * pointing to the PK of one of the root tables).
  70.      * @param connection database connection
  71.      * @param rootTables array of root tables described above
  72.      * @return name of all tables that depend on the root tables (including the root tables),
  73.      * in the right order for insertions
  74.      * @throws SearchException if an exception occurred while calculating the order
  75.      */
  76.     public static String[] getDependentTables( IDatabaseConnection connection, String[] rootTables )
  77.     throws SearchException
  78.     {
  79.         logger.debug("getDependentTables(connection={}, rootTables={}) - start", connection, rootTables);

  80.         ImportedKeysSearchCallback callback = new ImportedKeysSearchCallback(connection);
  81.         DepthFirstSearch search = new DepthFirstSearch();
  82.         Set tables = search.search( rootTables, callback );
  83.         return CollectionsHelper.setToStrings( tables );
  84.     }

  85.     /**
  86.      * Get the name of all tables that the given rootTable depends on (i.e, all tables whose PK is a FK for the root table).
  87.      * @param connection database connection
  88.      * @param rootTable root table described above
  89.      * @return name of all tables that the rootTable depends on (including the rootTable itself),
  90.      * in the right order for insertions
  91.      * @throws SearchException if an exception occurred while calculating the order
  92.      * @since 2.4
  93.      */
  94.     public static String[] getDependsOnTables( IDatabaseConnection connection, String rootTable )
  95.     throws SearchException
  96.     {
  97.         logger.debug("getDependsOnTables(connection={}, rootTable={}) - start", connection, rootTable);

  98.         ExportedKeysSearchCallback callback = new ExportedKeysSearchCallback(connection);
  99.         DepthFirstSearch search = new DepthFirstSearch();
  100.         Set tables = search.search( new String[]{rootTable}, callback );
  101.         return CollectionsHelper.setToStrings( tables );
  102.     }

  103.     /**
  104.      * Get the name of all tables that depend on a root table ( i.e, all tables whose PK
  105.      * is a FK for the root table) and also the tables the root table depends on
  106.      * (i.e., all tables which have a FK for the root table's PK).
  107.      * @param connection database connection
  108.      * @param rootTable root table described above
  109.      * @return name of all tables that depend on the root table (including the root table),
  110.      * in the right order for insertions
  111.      * @throws SearchException if an exception occurred while calculating the order
  112.      */
  113.     public static String[] getAllDependentTables( IDatabaseConnection connection, String rootTable )
  114.     throws SearchException
  115.     {
  116.         logger.debug("getAllDependentTables(connection={}, rootTable={}) - start", connection, rootTable);
  117.         return getAllDependentTables( connection, new String[] { rootTable } );
  118.     }

  119.     /**
  120.      * Get the name of all tables that depend on the root tables ( i.e, all tables whose PK
  121.      * is a FK for any of the root tables) and also the tables the root tables depends on
  122.      * (i.e., all tables which have a FK for any of the root table's PK).
  123.      * @param connection database connection
  124.      * @param rootTables root tables described above
  125.      * @return name of all tables that depend on the root tables (including the root tables),
  126.      * in the right order for insertions
  127.      * @throws SearchException if an exception occurred while calculating the order
  128.      */
  129.     public static String[] getAllDependentTables(IDatabaseConnection connection, String[] rootTables)
  130.     throws SearchException
  131.     {
  132.         logger.debug("getAllDependentTables(connection={}, rootTables={}) - start",connection, rootTables);

  133.         ImportedAndExportedKeysSearchCallback callback = new ImportedAndExportedKeysSearchCallback(connection);
  134.         DepthFirstSearch search = new DepthFirstSearch();
  135.         Set tables = search.search(rootTables, callback);
  136.         return CollectionsHelper.setToStrings(tables);
  137.     }

  138.     // TODO: javadoc (and unit tests) from down here...

  139.     public static IDataSet getDataset(IDatabaseConnection connection,String rootTable, Set allowedIds)
  140.     throws SearchException, SQLException, DataSetException
  141.     {
  142.         if (logger.isDebugEnabled())
  143.         {
  144.             logger.debug("getDataset(connection={}, rootTable={}, allowedIds={}) - start",
  145.                     new Object[] { connection, rootTable, allowedIds });
  146.         }

  147.         PkTableMap map = new PkTableMap();
  148.         map.addAll(rootTable, allowedIds);
  149.         return getDataset(connection, map);
  150.     }

  151.     public static IDataSet getDataset( IDatabaseConnection connection, PkTableMap rootTables )
  152.     throws SearchException, SQLException, DataSetException
  153.     {
  154.         logger.debug("getDataset(connection={}, rootTables={}) - start", connection, rootTables);

  155.         ImportedKeysSearchCallbackFilteredByPKs callback = new ImportedKeysSearchCallbackFilteredByPKs(connection, rootTables);
  156.         ITableFilter filter = callback.getFilter();
  157.         DepthFirstSearch search = new DepthFirstSearch();
  158.         String[] tableNames = rootTables.getTableNames();
  159.         Set tmpTables = search.search( tableNames, callback );
  160.         String[] dependentTables  = CollectionsHelper.setToStrings( tmpTables );
  161.         IDataSet tmpDataset = connection.createDataSet( dependentTables );
  162.         FilteredDataSet dataset = new FilteredDataSet(filter, tmpDataset);
  163.         return dataset;
  164.     }

  165.     public static IDataSet getAllDataset( IDatabaseConnection connection, String rootTable, Set allowedPKs )
  166.     throws SearchException, SQLException, DataSetException
  167.     {
  168.         if (logger.isDebugEnabled())
  169.         {
  170.             logger.debug("getAllDataset(connection={}, rootTable={}, allowedPKs={}) - start",
  171.                     new Object[]{ connection, rootTable, allowedPKs });
  172.         }

  173.         PkTableMap map = new PkTableMap();
  174.         map.addAll( rootTable, allowedPKs );
  175.         return getAllDataset( connection, map );
  176.     }

  177.     public static IDataSet getAllDataset( IDatabaseConnection connection, PkTableMap rootTables )
  178.     throws SearchException, SQLException, DataSetException
  179.     {
  180.         logger.debug("getAllDataset(connection={}, rootTables={}) - start", connection, rootTables);

  181.         ImportedAndExportedKeysSearchCallbackFilteredByPKs callback = new ImportedAndExportedKeysSearchCallbackFilteredByPKs(connection, rootTables);    
  182.         ITableFilter filter = callback.getFilter();
  183.         DepthFirstSearch search = new DepthFirstSearch();
  184.         String[] tableNames = rootTables.getTableNames();
  185.         Set tmpTables = search.search( tableNames, callback );
  186.         String[] dependentTables  = CollectionsHelper.setToStrings( tmpTables );
  187.         IDataSet tmpDataset = connection.createDataSet( dependentTables );
  188.         FilteredDataSet dataset = new FilteredDataSet(filter, tmpDataset);
  189.         return dataset;
  190.     }

  191.     /**
  192.      * Returns a set of tables on which the given table directly depends on.
  193.      * @param connection The connection to be used for the database lookup.
  194.      * @param tableName
  195.      * @return a set of tables on which the given table directly depends on.
  196.      * @throws SearchException
  197.      * @since 2.4
  198.      */
  199.     public static Set getDirectDependsOnTables(IDatabaseConnection connection,
  200.             String tableName) throws SearchException
  201.     {
  202.         logger.debug("getDirectDependsOnTables(connection={}, tableName={}) - start",
  203.                     connection, tableName);
  204.        
  205.         ExportedKeysSearchCallback callback = new ExportedKeysSearchCallback(connection);
  206.         // Do a depthFirstSearch with a recursion depth of 1
  207.         DepthFirstSearch search = new DepthFirstSearch(1);
  208.         Set tables = search.search( new String[]{tableName}, callback );
  209.         return tables;
  210.     }

  211.     /**
  212.      * Returns a set of tables which directly depend on the given table.
  213.      * @param connection The connection to be used for the database lookup.
  214.      * @param tableName
  215.      * @return a set of tables on which the given table directly depends on.
  216.      * @throws SearchException
  217.      * @since 2.4
  218.      */
  219.     public static Set getDirectDependentTables(IDatabaseConnection connection,
  220.             String tableName) throws SearchException
  221.     {
  222.         logger.debug("getDirectDependentTables(connection={}, tableName={}) - start",
  223.                     connection, tableName);

  224.         ImportedKeysSearchCallback callback = new ImportedKeysSearchCallback(connection);
  225.         // Do a depthFirstSearch with a recursion depth of 1
  226.         DepthFirstSearch search = new DepthFirstSearch(1);
  227.         Set tables = search.search( new String[]{tableName}, callback );
  228.         return tables;
  229.     }

  230. }