Changeset 5858


Ignore:
Timestamp:
Nov 9, 2011, 3:01:29 PM (10 years ago)
Author:
Nicklas Nordborg
Message:

Fixes #1648: Upgrading from BASE 2 to BASE 3 may create duplicate file set members

This seems to be working now. I'll do some final tests tomorrow and then release 3.0.1.

Location:
branches/3.0-stable/src/core/net/sf/basedb/core
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/3.0-stable/src/core/net/sf/basedb/core/Install.java

    r5833 r5858  
    117117    method.
    118118  */
    119   public static final int NEW_SCHEMA_VERSION = Integer.valueOf(100).intValue();
     119  public static final int NEW_SCHEMA_VERSION = Integer.valueOf(102).intValue();
    120120 
    121121  public static synchronized int createTables(boolean update, ProgressReporter progress,
  • branches/3.0-stable/src/core/net/sf/basedb/core/Update.java

    r5837 r5858  
    9595    </td>
    9696  </tr>
    97  
     97  <tr>
     98    <td>101 and 102</td>
     99    <td>
     100      Fixes an issue with duplicate {@link FileSetMemberData} entries
     101      due to a bug in the upgrade program. Make sure that the unique
     102      constraint that should prevent duplicates exists.
     103    </td>
     104  </tr>
     105
    98106  </table>
    99107
     
    122130    throws BaseException
    123131  {
    124     final int total_progress_steps = Install.NEW_SCHEMA_VERSION;
    125     final float progress_factor = 100F / total_progress_steps;
    126132    if (progress != null) progress.display(0, "Updating database...");
    127133    org.hibernate.Session session = null;
     
    141147      session = HibernateUtil.newSession();
    142148      int schemaVersion = getSchemaVersion(session);
     149      final int total_progress_steps = 1 + Install.NEW_SCHEMA_VERSION - schemaVersion;
     150      final float progress_step = 100F / total_progress_steps;
     151      float progress_current = progress_step;
    143152     
    144153      if (schemaVersion == 99)
    145154      {
    146155        // Final update to BASE 3
    147         if (progress != null) progress.display((int)(1*progress_factor), "--Updating schema version: " + schemaVersion + " -> 100...");
     156        if (progress != null) progress.display((int)(progress_current), "--Updating schema version: " + schemaVersion + " -> 100...");
    148157        schemaVersion = updateToSchemaVersion100(session);
    149 
     158        progress_current += progress_step;
     159       
     160        // Skipping directly to 102 since the updateToBase3()
     161        // has already fixed those issues
     162        if (progress != null) progress.display((int)(progress_current), "--Updating schema version: " + schemaVersion + " -> 102...");
     163        schemaVersion = setSchemaVersionInTransaction(session, 102);
     164        progress_current += 2 * progress_step;
     165      }
     166
     167      // The 101 and 102 updates are only needed when updating from a BASE 3.0.0 installation
     168      if (schemaVersion < 101)
     169      {
     170        if (progress != null) progress.display((int)(progress_current), "--Updating schema version: " + schemaVersion + " -> 101...");
     171        schemaVersion = updateToSchemaVersion101(session);
     172        progress_current += progress_step;
     173      }
     174     
     175      if (schemaVersion < 102)
     176      {
     177        if (progress != null) progress.display((int)(progress_current), "--Updating schema version: " + schemaVersion + " -> 102...");
     178        schemaVersion = updateToSchemaVersion102(session);
     179        progress_current += progress_step;
    150180      }
    151181     
     
    435465  }
    436466
     467  /**
     468    Remove duplicate file set members.
     469   
     470    @return The new schema version (=101)
     471  */
     472  private static int updateToSchemaVersion101(org.hibernate.Session session)
     473    throws BaseException
     474  {
     475    final int schemaVersion = 101;
     476    org.hibernate.Transaction tx = null;
     477    try
     478    {
     479      tx = HibernateUtil.newTransaction(session);
     480
     481      org.hibernate.Query query = HibernateUtil.createQuery(session,
     482        "SELECT fsm FROM FileSetMemberData fsm");
     483      List<FileSetMemberData> members = HibernateUtil.loadList(FileSetMemberData.class, query, null);
     484      Set<String> allMembers = new HashSet<String>();
     485      for (FileSetMemberData member : members)
     486      {
     487        int fileSetId = member.getFileSet().getId();
     488        int fileTypeId = member.getDataFileType().getId();
     489        int fileId = member.getFile().getId();
     490        String unique = fileSetId + "." + fileTypeId + "." + fileId;
     491        if (!allMembers.add(unique))
     492        {
     493          // This combination has been seen before
     494          session.delete(member);
     495        }
     496      }
     497     
     498      // Update the schema version number
     499      setSchemaVersion(session, schemaVersion);
     500 
     501      // Commit the changes
     502      HibernateUtil.commit(tx);
     503      log.info("updateToSchemaVersion101: OK");
     504    }
     505    catch (BaseException ex)
     506    {
     507      if (tx != null) HibernateUtil.rollback(tx);
     508      log.error("updateToSchemaVersion101: FAILED", ex);
     509      throw ex;
     510    }
     511    return schemaVersion;
     512  }
     513
     514  /**
     515    Add unique index on FileSetMembers(fileset_id,datafiletype_id,file_id)
     516   
     517    @return The new schema version (=102)
     518  */
     519  private static int updateToSchemaVersion102(org.hibernate.Session session)
     520    throws BaseException
     521  {
     522    final int schemaVersion = 102;
     523    try
     524    {
     525 
     526      // Try to drop just to make sure that we don't create duplicated indexes
     527      dropIndex(session, true, "FileSetMembers", "fileset_id", "datafiletype_id", "file_id");
     528      // Create the index
     529      createIndex(session, true, "FileSetMembers_uniquefile", "FileSetMembers", "fileset_id", "datafiletype_id", "file_id");
     530     
     531      // Update the schema version number
     532      setSchemaVersionInTransaction(session, schemaVersion);
     533 
     534      log.info("updateToSchemaVersion102: OK");
     535    }
     536    catch (SQLException ex)
     537    {
     538      log.error("updateToSchemaVersion102: FAILED", ex);
     539      throw new BaseException(ex);
     540    }
     541    catch (BaseException ex)
     542    {
     543      log.error("updateToSchemaVersion102: FAILED", ex);
     544      throw ex;
     545    }
     546    return schemaVersion;
     547  }
     548 
    437549  // Item type codes for item types that was removed since BASE 2
    438550  private static final int LABELEDEXTRACT = 204;
     
    456568    {
    457569      progress.display(0, "Updating to BASE 3.0...");
     570      //if (true) throw new RuntimeException("foo");
    458571      Config.setProperty("extensions.disabled", "true");
    459572      Application.start(false, false, false);
     
    491604      progress.display(15, "--Removing unique constraint on FileSetMembers");
    492605      dropIndex(session, true, "FileSetMembers", "fileset_id", "datafiletype_id");
     606      createIndex(session, true, "FileSetMembers_uniquefile", "FileSetMembers", "fileset_id", "datafiletype_id", "file_id");
    493607      fixPlatformFileTypes(session);
    494608     
     
    11661280        FileSetData fileSet = null;
    11671281       
     1282        // Keep track of duplicate files (since more than one image may reference the same fileId)
     1283        Set<Integer> files = new HashSet<Integer>();
     1284       
    11681285        while (it2.hasNext())
    11691286        {
    11701287          Object[] imgRow = (Object[])it2.next();
    11711288          Integer fileId = (Integer)imgRow[2];
    1172           if (fileId != null)
     1289          if (fileId != null && files.add(fileId))
    11731290          {
    11741291            if (fileSet == null)
Note: See TracChangeset for help on using the changeset viewer.