Changeset 6578


Ignore:
Timestamp:
Oct 24, 2014, 2:15:15 PM (9 years ago)
Author:
Nicklas Nordborg
Message:

References #1873: Deleting child biomaterial doesn't return the used quantity to the parent

There is no a onetimefix script for fixing this. After updating BASE it should be executed (from the bin directory):

onetimefix.sh remaining_quantity -u <root login> -p <root pwd> 

where login and password is for the root user account in BASE.

Location:
branches/3.3-stable/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/3.3-stable/src/core/net/sf/basedb/core/Update.java

    r6510 r6578  
    4040import org.hibernate.mapping.PersistentClass;
    4141import org.hibernate.mapping.Table;
     42
    4243
    4344
     
    7475import net.sf.basedb.core.data.ItemSubtypeData;
    7576import net.sf.basedb.core.data.JobData;
     77import net.sf.basedb.core.data.MeasuredBioMaterialData;
    7678import net.sf.basedb.core.data.PhysicalBioAssayData;
    7779import net.sf.basedb.core.data.ProjectData;
     
    10671069 
    10681070 
     1071  /**
     1072    Vefify and update the remaining quantity of all biomaterials.
     1073    @return The number of biomaterial fixed
     1074  */
     1075  public static int recalculateRemainingQuantity(ProgressReporter progress)
     1076    throws BaseException
     1077  {
     1078    org.hibernate.Session session = null;
     1079    org.hibernate.Transaction tx = null;
     1080    int numUpdated = 0;
     1081    try
     1082    {
     1083      session = HibernateUtil.newSession();
     1084      tx = HibernateUtil.newTransaction(session);
     1085     
     1086      // For temporary storing the new remaining quantities
     1087      Map<Integer, Double> remaining = new HashMap<Integer, Double>();
     1088     
     1089      // Load used quantity for all events
     1090      org.hibernate.Query eventQuery = HibernateUtil.createQuery(session,
     1091        "SELECT evt.bioMaterial.id, evt.usedQuantity FROM BioMaterialEventData evt WHERE NOT evt.usedQuantity IS NULL");
     1092     
     1093      // Load used quantity for sources to all events
     1094      org.hibernate.Query sourcesQuery = HibernateUtil.createQuery(session,
     1095        "SELECT src.bioMaterial.id, src.usedQuantity FROM BioMaterialEventSourceData src WHERE NOT src.usedQuantity IS NULL");
     1096
     1097      progress.display(10, "Loading biomaterial items...\n");
     1098     
     1099      List<Object[]> events = HibernateUtil.loadList(Object[].class, eventQuery, null);
     1100      events.addAll(HibernateUtil.loadList(Object[].class, sourcesQuery, null));
     1101
     1102      // Calculate the remaining quantity for each biomaterial
     1103      // o[0] = biomaterial id, o[1] = used quantity     
     1104      for (Object[] o : events)
     1105      {
     1106        Integer id = (Integer)o[0];
     1107        Float usedQuantity = (Float)o[1];
     1108        Double currentRemaining = remaining.get(id);
     1109        if (currentRemaining == null) currentRemaining = 0.0;
     1110        currentRemaining = currentRemaining - usedQuantity.doubleValue();
     1111        remaining.put(id, currentRemaining);
     1112      }
     1113      progress.display(30, "Found "+ remaining.size() + " items. Checking remaining quantity...\n");
     1114     
     1115      // Update the remaining quantity
     1116      org.hibernate.Query updateQuery = HibernateUtil.createQuery(session,
     1117        "UPDATE MeasuredBioMaterialData mbm " +
     1118        "SET mbm.remainingQuantity = :remain "+
     1119        "WHERE mbm = :bioMaterial");
     1120      int numProcessed = 0;
     1121      for (Map.Entry<Integer, Double> entry : remaining.entrySet())
     1122      {
     1123        MeasuredBioMaterialData bioMaterial = HibernateUtil.loadData(session, MeasuredBioMaterialData.class, entry.getKey());
     1124        Double remainingQuantity = entry.getValue();
     1125        Float currentRemaining = bioMaterial.getRemainingQuantity();
     1126        if (currentRemaining == null || Math.abs(currentRemaining-remainingQuantity) > Math.abs(currentRemaining / 10000))
     1127        {
     1128          updateQuery.setEntity("bioMaterial", bioMaterial);
     1129          updateQuery.setFloat("remain", remainingQuantity.floatValue());
     1130          updateQuery.executeUpdate();
     1131          numUpdated++;
     1132        }
     1133        numProcessed++;
     1134        if (numProcessed % 100 == 0)
     1135        {
     1136          progress.display(30 + numProcessed * 60 / remaining.size(), "Processed " + numProcessed + " biomaterial items...                   ");
     1137        }
     1138      }
     1139      progress.append("\n");
     1140      if (numUpdated == 0)
     1141      {
     1142        progress.display(100, "Found " + numUpdated + " items to fix\n");
     1143      }
     1144      else
     1145      {
     1146        progress.display(95, "Found " + numUpdated + " items to fix. Comitting transaction...\n");
     1147        // Commit the changes
     1148        HibernateUtil.commit(tx);
     1149        progress.display(100, "Completeted update of " + numUpdated + " items\n");
     1150      }
     1151    }
     1152    catch (BaseException ex)
     1153    {
     1154      if (tx != null) HibernateUtil.rollback(tx);
     1155      throw ex;
     1156    }
     1157    return numUpdated;
     1158  }
     1159
     1160 
    10691161  // Item type codes for item types that was removed since BASE 2
    10701162  private static final int LABELEDEXTRACT = 204;
  • branches/3.3-stable/src/install/net/sf/basedb/install/OneTimeFix.java

    r5735 r6578  
    3131
    3232
     33
     34
     35
     36
    3337import net.sf.basedb.core.Application;
    3438import net.sf.basedb.core.Config;
    3539import net.sf.basedb.core.ProgressReporter;
     40import net.sf.basedb.core.SessionControl;
     41import net.sf.basedb.core.Update;
     42import net.sf.basedb.core.authentication.LoginRequest;
     43import net.sf.basedb.util.ConsoleProgressReporter;
    3644
    3745/**
     
    5563    try
    5664    {
    57       String cmd = args[0];   
    58       if ("foo".equals(cmd))
     65      String cmd = args[0];
     66      if ("remaining_quantity".equals(cmd))
    5967      {
    60         showUsage();
     68        String login = getOption(args, "-u", "root");
     69        String pwd = getOption(args, "-p", "root");
     70       
     71        String msg =
     72          "-------------------------------------------------------------------\n" +
     73          "This script re-calculates the remaining quantity of all biomaterial\n" +
     74          "items since it may have become incorrect due to a bug.\n" +
     75          "For more information see: http://base.thep.lu.se/ticket/1873\n\n" +
     76          "Press ENTER to continue or CTRL+C to abort\n" +
     77          "-------------------------------------------------------------------";
     78        System.out.println(msg);
     79        waitForEnter();
     80        showDbInfo(null);
     81        System.out.println("Starting BASE. Please wait...");
     82        Application.start(false);
     83        SessionControl sc = Application.newSessionControl(null, null, null);
     84        sc.login(new LoginRequest(login, pwd));
     85        int numModified = Update.recalculateRemainingQuantity(new ConsoleProgressReporter(false));
     86        sc.logout();
     87        sc.close();
     88        Application.stop();
    6189      }
    6290      else
Note: See TracChangeset for help on using the changeset viewer.