Changeset 5021


Ignore:
Timestamp:
Jun 26, 2009, 2:07:15 PM (13 years ago)
Author:
Nicklas Nordborg
Message:

References #1340: Implement AnyToAny?.deleteStrayLinks()

The method has been implemented. It is still not called during cleanup.

Location:
trunk/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/core/common-queries.xml

    r4910 r5021  
    34613461    </description>
    34623462  </query>
    3463   <query id="SET_INTENSITYTRANSFORM_ON_BIOASSAYSETS" type="HQL">
    3464     <sql>
    3465       UPDATE BioAssaySetData bas
    3466       SET bas.intensityTransform = :transform
    3467       WHERE bas.intensityTransform IS NULL
    3468     </sql>
    3469     <description>
    3470       An update query that sets the intensityTransform on all
    3471       bioassay sets that doesn't have a value.
     3463  <query id="FIND_USED_TYPES_IN_ANYTOANY" type="SQL">
     3464    <sql>
     3465      SELECT [a].[from_type] FROM [AnyToAny] [a]
     3466      UNION
     3467      SELECT [a].[to_type] FROM [AnyToAny] [a]
     3468    </sql>
     3469    <description>
     3470      An SQL query that selects all used item types in any-to-any
     3471      links. It must select both the the 'from' and 'to' item type.
     3472    </description>
     3473  </query>
     3474  <query id="SELECT_STRAY_ANYTOANY" type="SQL">
     3475    <sql>
     3476      SELECT [a].[id]
     3477      FROM [AnyToAny] [a]
     3478      LEFT JOIN [{1}] [t]
     3479        ON ([t].[id] = [a].[from_id] AND [a].[from_type] = :type)
     3480        OR ([t].[id] = [a].[to_id] AND [a].[to_type] = :type)
     3481      WHERE [t].[id] IS NULL
     3482      AND ([a].[from_type] = :type OR [a].[to_type] = :type)
     3483    </sql>
     3484    <description>
     3485      An SQL query that selects the ID of all any-to-any links were
     3486      either the 'from' or 'to' item is missing. A single query
     3487      is used to delete all items of a specific type (both
     3488      'from' and 'to).
     3489    </description>
     3490  </query>
     3491  <query id="DELETE_STRAY_ANYTOANY" type="HQL">
     3492    <sql>
     3493      DELETE FROM AnyToAnyData
     3494      WHERE id IN (:ids)
     3495    </sql>
     3496    <description>
     3497      A HQL query that deletes all any-to-any links with the
     3498      id's given in the list.
    34723499    </description>
    34733500  </query>
  • trunk/src/core/net/sf/basedb/core/AnyToAny.java

    r4996 r5021  
    2222*/
    2323package net.sf.basedb.core;
     24
     25import java.util.List;
     26
     27import org.hibernate.Hibernate;
     28import org.hibernate.mapping.PersistentClass;
     29import org.hibernate.mapping.Table;
    2430
    2531import net.sf.basedb.core.Transactional.Action;
     
    2834import net.sf.basedb.core.query.Hql;
    2935import net.sf.basedb.core.query.Restrictions;
     36import net.sf.basedb.core.signal.ThreadSignalHandler;
    3037
    3138/**
     
    335342 
    336343  /**
    337     Delete all links that are linking to non-existing applications. This method
     344    @deprecated Use {@link #deleteStrayLinks(ProgressReporter)} instead.
     345  */
     346  public static synchronized void deleteStrayLinks()
     347  {
     348    deleteStrayLinks(null);
     349  }
     350
     351  /**
     352    Delete all links that are linking to non-existing items. This method
    338353    is intended to be executed at regular intervals by a cleanup application.
    339354    Although the {@link BasicItem#onBeforeCommit(Transactional.Action)} method
    340355    tries to delete as many links as it can, it will not not delete links
    341356    leading to items that have been deleted by Hibernate cascade.
    342   */
    343   public static synchronized void deleteStrayLinks()
    344   {
    345    
    346    
    347   }
    348  
     357    @param progress An optional progress reporter
     358    @since 2.13
     359  */
     360  public static synchronized int deleteStrayLinks(ProgressReporter progress)
     361  {
     362    org.hibernate.Session session = null;
     363    org.hibernate.Transaction tx = null;
     364    int numDeleted = 0;
     365
     366    try
     367    {
     368      session = HibernateUtil.newSession();
     369      tx = HibernateUtil.newTransaction(session);
     370     
     371      // Find the used items types in any-to-any links
     372      if (progress != null)
     373      {
     374        progress.display(5, "Finding item types used by any-to-any links...");
     375      }
     376      org.hibernate.Query query = HibernateUtil.getPredefinedSQLQuery(session,
     377          "FIND_USED_TYPES_IN_ANYTOANY");
     378      /*
     379        -- NOTE! UNION produces a distinct result by default (which is what we want)
     380        SELECT [a].[from_type] FROM [AnyToAny] [a]
     381        UNION
     382        SELECT [a].[to_type] FROM [AnyToAny] [a]
     383      */
     384      List<Integer> itemTypes = HibernateUtil.loadList(Integer.class, query, null);
     385     
     386      // For each item type; find and delete non-existing items
     387      int index = 0;
     388      int numItemTypes = itemTypes.size();
     389      org.hibernate.Query deleteQuery =
     390        HibernateUtil.getPredefinedQuery(session, "DELETE_STRAY_ANYTOANY");
     391      for (int itemType : itemTypes)
     392      {
     393        ThreadSignalHandler.checkInterrupted();
     394        Item item = Item.fromValue(itemType);
     395        if (progress != null)
     396        {
     397          int percent = 10 + (90 * index) / numItemTypes;
     398          progress.display(percent, "Deleting any-to-any links referencing non-existing item: " + item);
     399        }
     400        PersistentClass pClass = HibernateUtil.getClassMapping(item.getDataClass().getName());
     401        Table table = pClass.getTable();
     402     
     403        query = HibernateUtil.getPredefinedSQLQuery(session, "SELECT_STRAY_ANYTOANY",
     404            table.getName());
     405        /*
     406          SELECT [a].[id]
     407          FROM [AnyToAny] [a]
     408          LEFT JOIN [{1}] [t]
     409            ON ([t].[id] = [a].[from_id] and [a].[from_type] = :type)
     410            OR ([t].[id] = [a].[to_id] and [a].[to_type] = :type)
     411          WHERE [t].[id] is null AND ([a].[from_type = :type OR [a].[to_type] = :type)
     412        */
     413        query.setInteger("type", itemType);
     414        List<Integer> stray = HibernateUtil.loadList(Integer.class, query, null);
     415        if (stray.size() > 0)
     416        {
     417          deleteQuery.setParameterList("ids", stray, Hibernate.INTEGER);
     418          numDeleted += HibernateUtil.executeUpdate(deleteQuery);
     419        }
     420        index++;
     421      }
     422      HibernateUtil.commit(tx);
     423    }
     424    catch (RuntimeException ex)
     425    {
     426      if (tx != null) HibernateUtil.rollback(tx);
     427      throw ex;
     428    }
     429    finally
     430    {
     431      if (session != null) HibernateUtil.close(session);
     432    }
     433    return numDeleted;
     434  }
    349435 
    350436  private BasicItem from;
  • trunk/src/test/TestAnyToAny.java

    r4514 r5021  
    2424import net.sf.basedb.core.AnyToAny;
    2525import net.sf.basedb.core.BaseException;
     26import net.sf.basedb.core.BasicItem;
    2627import net.sf.basedb.core.DbControl;
    2728import net.sf.basedb.core.File;
     29import net.sf.basedb.core.Item;
    2830import net.sf.basedb.core.ItemResultList;
     31import net.sf.basedb.core.ProgressReporter;
    2932import net.sf.basedb.core.Sample;
     33import net.sf.basedb.util.ConsoleProgressReporter;
    3034
    3135public class TestAnyToAny
     
    4953    int fileId1 = TestFile.test_create("Linked file #1", false, true);
    5054    int fileId2 = TestFile.test_create("Linked file #2", false, true);
    51     int id = test_create(sampleId, fileId1, "first");
    52     int id2 = test_create(sampleId, fileId2, "second");
     55    int id = test_create(sampleId, Item.FILE, fileId1, "first", true);
     56    int id2 = test_create(sampleId, Item.FILE, fileId2, "second", true);
     57    // Set up test for stray links
     58    int clientId = TestClient.test_create("test-stray-links", false);
     59    int helpId = TestHelp.test_create(clientId, "stray-link-test", true);
     60    test_create(sampleId, Item.HELP, helpId, "help", false);
    5361    test_load(id);
    54     test_list_from(sampleId, 2);
     62    test_list_from(sampleId, 3);
    5563    test_list_to(fileId1, 1);
    5664    test_exists(sampleId, "first", true);
    5765    test_exists(sampleId, "third", false);
     66
     67    // Standard test: Delete
     68    if (TestUtil.waitBeforeDelete()) TestUtil.waitForEnter();
     69    TestClient.test_delete(clientId); // Cascade deletes the help item
     70    if (TestUtil.waitBeforeDelete()) TestUtil.waitForEnter();
    5871   
    59 
    60     // Extra tests:
    61     if (TestUtil.waitBeforeDelete()) TestUtil.waitForEnter();
    62 
    63     // Standard test: Delete
     72    test_delete_stray(1);
     73    test_list_from(sampleId, 2);
    6474    test_delete(id);
    6575    test_delete_all(sampleId, 1);
     
    7282  }
    7383
    74   static int test_create(int sampleId, int fileId, String name)
    75   {
    76     if (sampleId == 0 || fileId == 0) return 0;
     84  static int test_create(int sampleId, Item itemType, int itemId, String name, boolean usingTo)
     85  {
     86    if (sampleId == 0 || itemId == 0) return 0;
    7787    int id = 0;
    7888    DbControl dc = null;
     
    8191      dc = TestUtil.getDbControl();
    8292      Sample s = Sample.getById(dc, sampleId);
    83       File f = File.getById(dc, fileId);
    84       AnyToAny a = AnyToAny.getNew(dc, s, f, name, true);
     93      BasicItem item = itemType.getById(dc, itemId);
     94      AnyToAny a = AnyToAny.getNew(dc, s, item, name, usingTo);
    8595      a.setDescription("Added at "+new Date());
    8696      dc.saveItem(a);
     
    261271  }
    262272 
     273  static void test_delete_stray(int expectedResults)
     274  {
     275    try
     276    {
     277      ProgressReporter progress = TestUtil.getSilent() ? null : new ConsoleProgressReporter();
     278      int deletedLinks = AnyToAny.deleteStrayLinks(progress);
     279      if (expectedResults >= 0 && expectedResults != deletedLinks)
     280      {
     281        throw new BaseException("Expected "+expectedResults+" deletions, not "+deletedLinks);
     282      }
     283      if (progress != null) progress.append("\n");
     284      write("--Delete stray any-to-any links OK ("+deletedLinks+")");
     285    }
     286    catch (Throwable ex)
     287    {
     288      write("--Delete stray any-to-any links FAILED");
     289      ex.printStackTrace();
     290      ok = false;
     291    }
     292    finally
     293    {}
     294  }
     295
     296 
    263297  static void test_exists(int sampleId, String name, boolean expected)
    264298  {
Note: See TracChangeset for help on using the changeset viewer.