Changeset 5876


Ignore:
Timestamp:
Nov 15, 2011, 2:45:50 PM (10 years ago)
Author:
Nicklas Nordborg
Message:

References #1616: Clone reporter information to per-experiment tables in the dynamic database

Added ReporterCloneTemplate as a main item type in BASE. The template can hold a list of reporter properties (ClonedProperty) which defines the properties that should be cloned. The id, version and externalId are mandatory.

When a template is used to to clone reporter information into an experiment, a locked copy of the template is created. This is needed to avoid problems if the template is changed.

There is no gui for defining templates, and the cloned reporter information can't be used in queries or table listings yet.

Location:
trunk/src
Files:
6 added
20 edited

Legend:

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

    r5828 r5876  
    33613361    </description>
    33623362  </query>
     3363 
     3364  <query id="GET_VIRTUALDBS_FOR_REPORTERCLONETEMPLATE" type="HQL">
     3365    <sql>
     3366      SELECT {1}
     3367      FROM VirtualDbData vdb
     3368      WHERE vdb.reporterCloneTemplate = :reporterCloneTemplate
     3369    </sql>
     3370    <description>
     3371      A Hibernate query that get virtual databases
     3372      that are using a given reporter clone template.
     3373    </description>
     3374  </query>
    33633375
    33643376 
  • trunk/src/core/net/sf/basedb/core/DynamicPositionQuery.java

    r5711 r5876  
    7676  }
    7777 
     78  DynamicPositionQuery(Experiment experiment)
     79  {
     80    super(experiment.getVirtualDb(), VirtualTable.POSITION);
     81    this.bioAssaySet = null;
     82    joinedItems = new HashSet<Object>();
     83    setAutoJoinType(JoinType.LEFT);
     84  }
     85 
    7886  /*
    7987    From the AbstractSqlQuery class
  • trunk/src/core/net/sf/basedb/core/DynamicQuery.java

    r5319 r5876  
    7575  }
    7676 
     77  /**
     78    Create a new non-restricted dynamic query.
     79    @param vdb The virtual database to use
     80    @param rootTable The root table of the query
     81    @since 3.1
     82   */
     83  DynamicQuery(VirtualDb vdb, VirtualTable rootTable)
     84  {
     85    super(rootTable.getQualifiedTableName(vdb));
     86    this.cube = null;
     87    this.virtualDb = vdb;
     88    this.rootTable = rootTable;
     89    this.transform = null;
     90  }
     91 
    7792  /*
    7893    From the Query interface
  • trunk/src/core/net/sf/basedb/core/Experiment.java

    r5345 r5876  
    2525
    2626import net.sf.basedb.core.data.ExperimentData;
     27import net.sf.basedb.core.data.ReporterCloneTemplateData;
    2728import net.sf.basedb.core.hibernate.TypeWrapper;
    2829import net.sf.basedb.core.query.Restrictions;
     
    170171  private long addedBytes = 0;
    171172  private long updatedBytes = 0;
     173  private String oldReporterCloneTable;
     174  private String newReporterCloneTable;
    172175 
    173176  /**
     
    278281 
    279282  /**
     283    Remove old reporter clone table after a successful commit.
     284  */
     285  @Override
     286  void onAfterCommit(Action action)
     287  {
     288    super.onAfterCommit(action);
     289    if (newReporterCloneTable != null && oldReporterCloneTable != null)
     290    {
     291      // If a new reporter clone table has been created and an old one
     292      // existed, the old should be removed
     293      try
     294      {
     295        HibernateUtil.dropDynamicTable(oldReporterCloneTable);
     296      }
     297      catch (RuntimeException ex)
     298      {
     299        Application.getLogger().warn("Could not remove old reporter clone table: " + oldReporterCloneTable, ex);
     300      }
     301    }
     302    oldReporterCloneTable = null;
     303    newReporterCloneTable = null;
     304  }
     305
     306  /**
     307    Remove new reporter clone table after a rollback.
     308  */
     309  @Override
     310  void onRollback(Action action)
     311  {
     312    super.onRollback(action);
     313    if (newReporterCloneTable != null)
     314    {
     315      // If a new reporter clone table has been created it should be removed
     316      try
     317      {
     318        HibernateUtil.dropDynamicTable(newReporterCloneTable);
     319      }
     320      catch (RuntimeException ex)
     321      {
     322        Application.getLogger().warn("Could not rollback reporter clone table creation: " + oldReporterCloneTable, ex);
     323      }
     324    }
     325    oldReporterCloneTable = null;
     326    newReporterCloneTable = null;
     327  }
     328
     329  /**
    280330    @since 2.5
    281331   */
     
    752802    return query;
    753803  }
     804 
     805  /**
     806    Create a reporter clone table in the dynamic database for this
     807    experiment and populate it with the current reporter annotations
     808    for all reporters that are part of the experiment. This method will
     809    create an immutable copy of the template so that we can always know
     810    which fields that have been cloned, even if the template is modified.
     811   
     812    @param dc A DbControl to use for database access
     813    @param template The template that decides which fieds that
     814      are cloned
     815    @param progress An optional progress reporter
     816    @return The number of reporters that was cloned
     817    @since 3.1
     818  */
     819  public int cloneReporters(DbControl dc, ReporterCloneTemplate template, ProgressReporter progress)
     820  {
     821    VirtualDb db = VirtualDb.getById(dc, getData().getVirtualDb().getId());
     822   
     823    if (db.hasClonedReporters())
     824    {
     825      // Remove existing clone table
     826      oldReporterCloneTable = VirtualTable.CLONED_REPORTERS.getTableName(db);
     827      ReporterCloneTemplateData oldClone = db.getData().getReporterCloneTemplate();
     828      HibernateUtil.deleteData(dc.getHibernateSession(), oldClone);
     829      this.addBytes(-oldClone.getBytes());
     830    }
     831   
     832    if (progress != null) progress.display(0, "Creating clone table...");
     833    // Create a copy of the template
     834    ReporterCloneTemplateData copy = template.createLockedCopy();
     835    db.getData().setReporterCloneTemplate(copy);
     836    HibernateUtil.saveData(dc.getHibernateSession(), copy);
     837   
     838    // Create a new clone table
     839    newReporterCloneTable = HibernateUtil.createVirtualTable(db, VirtualTable.CLONED_REPORTERS);
     840   
     841    // Clone reporter information
     842    return new ReporterCloneBatcher(dc, this).cloneReporters(progress);
     843  }
     844 
    754845 
    755846  /**
  • trunk/src/core/net/sf/basedb/core/FilterBatcher.java

    r5689 r5876  
    143143    super();
    144144    this.bioAssaySet = bioAssaySet;
    145     this.bytesPerRow = VirtualTable.FILTER.getBytesPerRow(bioAssaySet.getRawDataType());
     145    this.bytesPerRow = VirtualTable.FILTER.getBytesPerRow(bioAssaySet.getVirtualDb());
    146146    setDbControl(dc);
    147147  }
     
    351351    throws SQLException, BaseException
    352352  {
    353     RawDataType rdt = bioAssaySet.getRawDataType();
    354353    VirtualDb vdb = bioAssaySet.getVirtualDb();
    355354    if (!vdb.hasTable(VirtualTable.FILTER))
     
    362361      vdb,
    363362      VirtualTable.FILTER,
    364       VirtualTable.FILTER.getColumns(rdt),
     363      VirtualTable.FILTER.getColumns(vdb),
    365364      new Object[] {cube, filter}
    366365    );
     
    377376    throws BaseException
    378377  {
    379     RawDataType rdt = bioAssaySet.getRawDataType();
    380378    VirtualDb vdb = bioAssaySet.getVirtualDb();
    381379    if (!vdb.hasTable(VirtualTable.FILTER))
     
    383381      vdb.createTables(VirtualTable.FILTER);
    384382    }
    385     String sql = BatchUtil.buildInsertSelectSql(vdb, VirtualTable.FILTER, VirtualTable.FILTER.getColumns(rdt), selectSql);
     383    String sql = BatchUtil.buildInsertSelectSql(vdb, VirtualTable.FILTER, VirtualTable.FILTER.getColumns(vdb), selectSql);
    386384    return sql;
    387385  }
  • trunk/src/core/net/sf/basedb/core/HibernateUtil.java

    r5857 r5876  
    722722    @param db The virtual db item
    723723    @param table Information about the table to create
     724    @return The name of the created table
    724725    @see #dropVirtualTable(VirtualDb, VirtualTable)
    725726    @see #virtualTableExists(VirtualDb, VirtualTable)
    726727  */
    727   static synchronized void createVirtualTable(VirtualDb db, VirtualTable table)
     728  static synchronized String createVirtualTable(VirtualDb db, VirtualTable table)
    728729    throws BaseException
    729730  {
     
    738739      if (!tableExists(tableName, session))
    739740      {
    740         Table hibernateTable = newDynamicMapping(db, table);
     741        Table hibernateTable = newDynamicMapping(db, table, true);
    741742        Dialect dialect = getDialect();
    742743        String dynamicCatalog = Application.getDynamicCatalog();
     
    763764      }
    764765      HibernateUtil.commit(tx);
     766      return tableName;
    765767    }
    766768    catch (BaseException ex)
     
    802804    throws BaseException
    803805  {
     806    dropDynamicTable(table.getTableName(db));
     807  }
     808 
     809  static synchronized void dropDynamicTable(String tableName)
     810  {
    804811    Session session = null;
    805812    Transaction tx = null;
     
    809816      tx = HibernateUtil.newTransaction(session);
    810817
    811       if (tableExists(table.getTableName(db), session))
     818      if (tableExists(tableName, session))
    812819      {
    813         Table hibernateTable = newDynamicMapping(db, table);
     820        Table hibernateTable = new Table("`" + tableName + "`");
    814821        Dialect dialect = getDialect();
    815822        String dynamicCatalog = quote(Application.getDynamicCatalog());
     
    821828      HibernateUtil.commit(tx);
    822829    }
    823     catch (BaseException ex)
     830    catch (SQLException ex)
    824831    {
    825832      if (tx != null) HibernateUtil.rollback(tx);
    826       log.error("Exception while dropping virtual table: " + table, ex);
     833      log.error("Exception while dropping dynamic table: " + tableName, ex);
     834      throw new BaseException(ex);
     835    }
     836    catch (RuntimeException ex)
     837    {
     838      if (tx != null) HibernateUtil.rollback(tx);
     839      log.error("Exception while dropping dynamic table: " + tableName, ex);
    827840      throw ex;
    828     }
    829     catch (SQLException ex)
    830     {
    831       if (tx != null) HibernateUtil.rollback(tx);
    832       log.error("Exception while dropping virtual table: " + table, ex);
    833       throw new BaseException(ex);
    834841    }
    835842    finally
     
    903910    @param table Information about the table to generate the mapping for
    904911  */
    905   private static Table newDynamicMapping(VirtualDb db, VirtualTable table)
     912  private static Table newDynamicMapping(VirtualDb db, VirtualTable table, boolean withColumns)
    906913  {
    907914    String tableName = table.getTableName(db);
    908915    Table hibernateTable = new Table("`"+tableName+"`");
    909     hibernateTable.setPrimaryKey(new PrimaryKey());
    910     for (VirtualColumn column : table.getColumns(db.getRawDataType()))
    911     {
    912       addColumn(mappings, hibernateTable, column);
     916    if (withColumns)
     917    {
     918      hibernateTable.setPrimaryKey(new PrimaryKey());
     919      for (VirtualColumn column : table.getColumns(db))
     920      {
     921        addColumn(mappings, hibernateTable, column);
     922      }
    913923    }
    914924    return hibernateTable;
     
    917927  /**
    918928    Add a column to a table. This method is used by
    919     {@link #newDynamicMapping(VirtualDb, VirtualTable)} to build the mapping
     929    {@link #newDynamicMapping(VirtualDb, VirtualTable, boolean)} to build the mapping
    920930    information Hibernate requires to generate the SQL to create the table.
    921931    @param hibernateTable The <code>org.hibernate.mapping.Table</code> object
     
    939949    hibernateTable.addColumn(hibernateColumn);
    940950   
    941     // Add column to primary key
    942951    if (column.isPrimaryKey())
    943952    {
     953      // Add column to primary key
    944954      hibernateTable.getPrimaryKey().addColumn(hibernateColumn);
    945955    }
    946    
    947     // Create index for column
    948     if (column.isIndexed())
    949     {
     956    else if (column.isUnique())
     957    {
     958      // Set unique constraint for column
     959      hibernateColumn.setUnique(column.isUnique());
     960    }
     961    else if (column.isIndexed())
     962    {
     963      // Create index on this column
    950964      Index hibernateIndex = new Index();
    951965      hibernateIndex.addColumn(hibernateColumn);
  • trunk/src/core/net/sf/basedb/core/Install.java

    r5864 r5876  
    118118    method.
    119119  */
    120   public static final int NEW_SCHEMA_VERSION = Integer.valueOf(102).intValue();
     120  public static final int NEW_SCHEMA_VERSION = Integer.valueOf(103).intValue();
    121121 
    122122  public static synchronized int createTables(SchemaGenerator.Mode mode, ProgressReporter progress,
     
    362362      createRoleKey(Item.REPORTER, "Reporters", "Gives access to reporter", guests_use_administrators_all);
    363363      createRoleKey(Item.REPORTERLIST, "Reporter lists", "Gives access to reporter lists", users_create);
     364      createRoleKey(Item.REPORTERCLONETEMPLATE, "Reporter clone template", "Gives access to reporter clone templates", guests_use_power_users_all);
    364365 
    365366      // Array LIMS - plates
  • trunk/src/core/net/sf/basedb/core/Item.java

    r5730 r5876  
    257257  REPORTERSCORE(164, "Reporter score", "rps", null, null, null,
    258258    820),
     259  /**
     260    The item is a {@link ReporterCloneTemplate}.
     261    @since 3.1
     262  */
     263  REPORTERCLONETEMPLATE(165, "Reporter clone template", "rct", ReporterCloneTemplate.class, ReporterCloneTemplateData.class, DefinedPermissions.ownable,
     264    800),
    259265
    260266  /**
  • trunk/src/core/net/sf/basedb/core/MappingBatcher.java

    r4997 r5876  
    106106    this.dataCube = dataCube;
    107107    this.noRawMapping = dataCube.isInDatabase();
    108     this.bytesPerRow = VirtualTable.RAWPARENTS.getBytesPerRow(dataCube.getRawDataType());
     108    this.bytesPerRow = VirtualTable.RAWPARENTS.getBytesPerRow(dataCube.getVirtualDb());
    109109    setDbControl(dc);
    110110  }
     
    291291    throws SQLException, BaseException
    292292  {
    293     RawDataType rdt = dataCube.getRawDataType();
    294293    VirtualDb vdb = dataCube.getVirtualDb();
    295294    if (!vdb.hasTable(VirtualTable.RAWPARENTS))
     
    300299    rawMappingSqlStatement = BatchUtil.buildInsertSql(vdb,
    301300      VirtualTable.RAWPARENTS,
    302       VirtualTable.RAWPARENTS.getColumns(rdt),
     301      VirtualTable.RAWPARENTS.getColumns(vdb),
    303302      new Object[] {cube}
    304303    );
     
    315314    throws BaseException
    316315  {
    317     RawDataType rdt = dataCube.getRawDataType();
    318316    VirtualDb vdb = dataCube.getVirtualDb();
    319317    if (!vdb.hasTable(VirtualTable.RAWPARENTS))
     
    321319      vdb.createTables(VirtualTable.RAWPARENTS);
    322320    }
    323     String sql = BatchUtil.buildInsertSelectSql(vdb, VirtualTable.RAWPARENTS, VirtualTable.RAWPARENTS.getColumns(rdt), selectSql);
     321    String sql = BatchUtil.buildInsertSelectSql(vdb, VirtualTable.RAWPARENTS, VirtualTable.RAWPARENTS.getColumns(vdb), selectSql);
    324322    return sql;
    325323  }
  • trunk/src/core/net/sf/basedb/core/PositionBatcher.java

    r4889 r5876  
    107107    super();
    108108    this.dataCube = dataCube;
    109     this.bytesPerRow = VirtualTable.POSITION.getBytesPerRow(dataCube.getRawDataType());
     109    this.bytesPerRow = VirtualTable.POSITION.getBytesPerRow(dataCube.getVirtualDb());
    110110    setDbControl(dc);
    111111  }
     
    280280    throws SQLException, BaseException
    281281  {
    282     RawDataType rdt = dataCube.getRawDataType();
    283282    VirtualDb vdb = dataCube.getVirtualDb();
    284283    if (!vdb.hasTable(VirtualTable.POSITION))
     
    289288    positionSqlStatement = BatchUtil.buildInsertSql(vdb,
    290289      VirtualTable.POSITION,
    291       VirtualTable.POSITION.getColumns(rdt),
     290      VirtualTable.POSITION.getColumns(vdb),
    292291      new Object[] {cube}
    293292    );
     
    304303    throws BaseException
    305304  {
    306     RawDataType rdt = dataCube.getRawDataType();
    307305    VirtualDb vdb = dataCube.getVirtualDb();
    308306    if (!vdb.hasTable(VirtualTable.POSITION))
     
    310308      vdb.createTables(VirtualTable.POSITION);
    311309    }
    312     String sql = BatchUtil.buildInsertSelectSql(vdb, VirtualTable.POSITION, VirtualTable.POSITION.getColumns(rdt), selectSql);
     310    String sql = BatchUtil.buildInsertSelectSql(vdb, VirtualTable.POSITION, VirtualTable.POSITION.getColumns(vdb), selectSql);
    313311    return sql;
    314312  }
  • trunk/src/core/net/sf/basedb/core/PositionExtraValueBatcher.java

    r5218 r5876  
    155155    super();
    156156    this.extraValue = extraValue;
    157     this.bytesPerRow = extraValue.getVirtualTable().getBytesPerRow(extraValue.getRawDataType());
     157    this.bytesPerRow = extraValue.getVirtualTable().getBytesPerRow(extraValue.getVirtualDb());
    158158    this.valueType = extraValue.getExtraValueType().getValueType();
    159159    this.sqlType = valueType.getSQLType();
     
    385385    throws SQLException, BaseException
    386386  {
    387     RawDataType rdt = extraValue.getRawDataType();
    388387    VirtualDb vdb = extraValue.getVirtualDb();
    389388    VirtualTable vt = extraValue.getVirtualTable();
     
    397396      vdb,
    398397      vt,
    399       vt.getColumns(rdt),
     398      vt.getColumns(vdb),
    400399      new Object[] {cube, extra}
    401400    );
     
    412411    throws BaseException
    413412  {
    414     RawDataType rdt = extraValue.getRawDataType();
    415413    VirtualDb vdb = extraValue.getVirtualDb();
    416414    VirtualTable vt = extraValue.getVirtualTable();
     
    419417      vdb.createTables(vt);
    420418    }
    421     String sql = BatchUtil.buildInsertSelectSql(vdb, vt, vt.getColumns(rdt), selectSql);
     419    String sql = BatchUtil.buildInsertSelectSql(vdb, vt, vt.getColumns(vdb), selectSql);
    422420    return sql;
    423421  }
  • trunk/src/core/net/sf/basedb/core/SpotBatcher.java

    r4992 r5876  
    143143    this.bioAssaySet = bioAssaySet;
    144144    this.numChannels = bioAssaySet.getRawDataType().getChannels();
    145     this.bytesPerRow = VirtualTable.SPOT.getBytesPerRow(bioAssaySet.getRawDataType());
     145    this.bytesPerRow = VirtualTable.SPOT.getBytesPerRow(bioAssaySet.getVirtualDb());
    146146    setDbControl(dc);
    147147  }
     
    367367    throws SQLException, BaseException
    368368  {
    369     RawDataType rdt = bioAssaySet.getRawDataType();
    370369    VirtualDb vdb = bioAssaySet.getVirtualDb();
    371370    if (!vdb.hasTable(VirtualTable.SPOT))
     
    378377      vdb,
    379378      VirtualTable.SPOT,
    380       VirtualTable.SPOT.getColumns(rdt),
     379      VirtualTable.SPOT.getColumns(vdb),
    381380      new Object[] {cube, layer}
    382381    );
     
    393392    throws BaseException
    394393  {
    395     RawDataType rdt = bioAssaySet.getRawDataType();
    396394    VirtualDb vdb = bioAssaySet.getVirtualDb();
    397395    if (!vdb.hasTable(VirtualTable.SPOT))
     
    399397      vdb.createTables(VirtualTable.SPOT);
    400398    }
    401     String sql = BatchUtil.buildInsertSelectSql(vdb, VirtualTable.SPOT, VirtualTable.SPOT.getColumns(rdt), selectSql);
     399    String sql = BatchUtil.buildInsertSelectSql(vdb, VirtualTable.SPOT, VirtualTable.SPOT.getColumns(vdb), selectSql);
    402400    return sql;
    403401  }
  • trunk/src/core/net/sf/basedb/core/SpotExtraValueBatcher.java

    r5218 r5876  
    146146    super();
    147147    this.extraValue = extraValue;
    148     this.bytesPerRow = extraValue.getVirtualTable().getBytesPerRow(extraValue.getRawDataType());
     148    this.bytesPerRow = extraValue.getVirtualTable().getBytesPerRow(extraValue.getVirtualDb());
    149149    this.valueType = extraValue.getExtraValueType().getValueType();
    150150    this.sqlType = valueType.getSQLType();
     
    382382    throws SQLException, BaseException
    383383  {
    384     RawDataType rdt = extraValue.getRawDataType();
    385384    VirtualDb vdb = extraValue.getVirtualDb();
    386385    VirtualTable vt = extraValue.getVirtualTable();
     
    394393      vdb,
    395394      vt,
    396       vt.getColumns(rdt),
     395      vt.getColumns(vdb),
    397396      new Object[] {cube, extra}
    398397    );
     
    409408    throws BaseException
    410409  {
    411     RawDataType rdt = extraValue.getRawDataType();
    412410    VirtualDb vdb = extraValue.getVirtualDb();
    413411    VirtualTable vt = extraValue.getVirtualTable();
     
    416414      vdb.createTables(vt);
    417415    }
    418     String sql = BatchUtil.buildInsertSelectSql(vdb, vt, vt.getColumns(rdt), selectSql);
     416    String sql = BatchUtil.buildInsertSelectSql(vdb, vt, vt.getColumns(vdb), selectSql);
    419417    return sql;
    420418  }
  • trunk/src/core/net/sf/basedb/core/Update.java

    r5864 r5876  
    6161import net.sf.basedb.core.data.PropertyFilterData;
    6262import net.sf.basedb.core.data.ProtocolData;
     63import net.sf.basedb.core.data.ReporterCloneTemplateData;
    6364import net.sf.basedb.core.data.RoleKeyData;
    6465import net.sf.basedb.core.data.SchemaVersionData;
     
    103104    </td>
    104105  </tr>
     106  <tr>
     107    <td>103</td>
     108    <td>
     109      Added {@link ReporterCloneTemplateData} and related classes. No
     110      special update is required.
     111    </td>
     112  </tr>
    105113
    106114  </table>
     
    162170        if (progress != null) progress.display((int)(progress_current), "--Updating schema version: " + schemaVersion + " -> 102...");
    163171        schemaVersion = setSchemaVersionInTransaction(session, 102);
    164         progress_current += 2 * progress_step;
     172        progress_current += progress_step;
    165173      }
    166174
     
    177185        if (progress != null) progress.display((int)(progress_current), "--Updating schema version: " + schemaVersion + " -> 102...");
    178186        schemaVersion = updateToSchemaVersion102(session);
     187        progress_current += progress_step;
     188      }
     189     
     190      if (schemaVersion < 103)
     191      {
     192        if (progress != null) progress.display((int)(progress_current), "--Updating schema version: " + schemaVersion + " -> 103...");
     193        schemaVersion = setSchemaVersionInTransaction(session, 103);
    179194        progress_current += progress_step;
    180195      }
  • trunk/src/core/net/sf/basedb/core/VirtualColumn.java

    r5590 r5876  
    2424package net.sf.basedb.core;
    2525
     26import net.sf.basedb.core.data.ReporterData;
    2627import net.sf.basedb.core.hibernate.TypeWrapper;
    2728
     
    5152 
    5253  /**
     54    Used in constructor to tell that the column must contain only
     55    unique values.
     56    @since 3.1
     57  */
     58  public static final boolean UNIQUE = true;
     59 
     60  /**
    5361    Used in constructor to tell that the column should be nullable.
    5462  */
     
    6674  public static final VirtualColumn CUBE =
    6775    new VirtualColumn("cube", "cube", TypeWrapper.SHORT, 0,
    68       !INDEXED, !NULLABLE, PRIMARY_KEY, false);
     76      !INDEXED, !UNIQUE, !NULLABLE, PRIMARY_KEY, false);
    6977   
    7078  /**
     
    7482  public static final VirtualColumn LAYER =
    7583    new VirtualColumn("layer", "layer", TypeWrapper.SHORT, 0,
    76       !INDEXED, !NULLABLE, PRIMARY_KEY, false);
     84      !INDEXED, !UNIQUE, !NULLABLE, PRIMARY_KEY, false);
    7785
    7886  /**
     
    8290  public static final VirtualColumn COLUMN =
    8391    new VirtualColumn("column", "column", TypeWrapper.SHORT, 0,
    84       !INDEXED, !NULLABLE, PRIMARY_KEY, false);
     92      !INDEXED, !UNIQUE, !NULLABLE, PRIMARY_KEY, false);
    8593 
    8694  /**
     
    8997  public static final VirtualColumn POSITION =
    9098    new VirtualColumn("position", "position", TypeWrapper.INTEGER, 0,
    91       !INDEXED, !NULLABLE, PRIMARY_KEY, false);
     99      !INDEXED, !UNIQUE, !NULLABLE, PRIMARY_KEY, false);
    92100
    93101  /**
     
    97105  public static final VirtualColumn FILTER =
    98106    new VirtualColumn("filter", "filter", TypeWrapper.SHORT, 0,
    99       !INDEXED, !NULLABLE, PRIMARY_KEY, false);
     107      !INDEXED, !UNIQUE, !NULLABLE, PRIMARY_KEY, false);
    100108
    101109  /**
     
    105113  public static final VirtualColumn EXTRA =
    106114    new VirtualColumn("extra", "extra", TypeWrapper.SHORT, 0,
    107       !INDEXED, !NULLABLE, PRIMARY_KEY, false);
     115      !INDEXED, !UNIQUE, !NULLABLE, PRIMARY_KEY, false);
    108116
    109117  /**
     
    114122  public static final VirtualColumn REPORTER_ID =
    115123    new VirtualColumn("reporterId", "reporter_id", TypeWrapper.INTEGER, 0,
    116       !INDEXED, NULLABLE, !PRIMARY_KEY, false);
    117 
     124      !INDEXED, !UNIQUE, NULLABLE, !PRIMARY_KEY, false);
     125
     126  /**
     127    Column for storing the id of a reporter when it is part of the
     128    primary key. For perfomance reasons it is not linked with a
     129    foreign key to the <code>Reporters</code> table.
     130    @since 3.1
     131  */
     132  public static final VirtualColumn REPORTER_ID_PK =
     133    new VirtualColumn("reporterId", "id", TypeWrapper.INTEGER, 0,
     134      !INDEXED, UNIQUE, !NULLABLE, PRIMARY_KEY, false);
     135 
     136  /**
     137    Column for storing the original version of a reporter that
     138    is cloned to a virtual table.
     139    @since 3.1
     140  */
     141  public static final VirtualColumn REPORTER_VERSION =
     142    new VirtualColumn("version", "version", TypeWrapper.INTEGER, 0,
     143      !INDEXED, !UNIQUE, !NULLABLE, !PRIMARY_KEY, false);
     144 
     145  /**
     146    Column for storing the external reporter id.
     147    @since 3.1
     148  */
     149  public static final VirtualColumn REPORTER_EXTERNAL_ID =
     150    new VirtualColumn("externalId", "external_id", TypeWrapper.STRING, ReporterData.MAX_EXTERNAL_ID_LENGTH,
     151      INDEXED, UNIQUE, !NULLABLE, !PRIMARY_KEY, false);
     152 
    118153  /**
    119154    This column stores the id of a raw date object. For perfomance reasons it is
     
    123158  public static final VirtualColumn RAWDATA_ID =
    124159    new VirtualColumn("rawDataId", "rawdata_id", TypeWrapper.INTEGER, 0,
    125       !INDEXED, !NULLABLE, PRIMARY_KEY, false);
     160      !INDEXED, !UNIQUE, !NULLABLE, PRIMARY_KEY, false);
    126161 
    127162  /**
     
    132167  public static final VirtualColumn RAWBIOASSAY_ID =
    133168    new VirtualColumn("rawBioAssayId", "rawbioassay_id", TypeWrapper.INTEGER, 0,
    134       !INDEXED, !NULLABLE, PRIMARY_KEY, false);
     169      !INDEXED, !UNIQUE, !NULLABLE, PRIMARY_KEY, false);
    135170
    136171  /**
     
    139174  public static final VirtualColumn EXTRA_INT =
    140175    new VirtualColumn("extraInt", "value", TypeWrapper.INTEGER, 0,
    141       !INDEXED, NULLABLE, !PRIMARY_KEY, false);
     176      !INDEXED, !UNIQUE, NULLABLE, !PRIMARY_KEY, false);
    142177
    143178  /**
     
    146181  public static final VirtualColumn EXTRA_FLOAT =
    147182    new VirtualColumn("extraFloat", "value", TypeWrapper.FLOAT, 0,
    148       !INDEXED, NULLABLE, !PRIMARY_KEY, false);
     183      !INDEXED, !UNIQUE, NULLABLE, !PRIMARY_KEY, false);
    149184
    150185  /**
     
    153188  public static final VirtualColumn EXTRA_STRING =
    154189    new VirtualColumn("extraString", "value", TypeWrapper.STRING, 255,
    155       !INDEXED, NULLABLE, !PRIMARY_KEY, false);
     190      !INDEXED, !UNIQUE, NULLABLE, !PRIMARY_KEY, false);
    156191
    157192  /**
     
    182217  {
    183218    return new VirtualColumn("rch"+channel, "ch"+channel, TypeWrapper.FLOAT, 0,
    184           !INDEXED, NULLABLE, !PRIMARY_KEY, false);
     219          !INDEXED, !UNIQUE, NULLABLE, !PRIMARY_KEY, false);
    185220  }
    186221 
     
    198233  {
    199234    return new VirtualColumn("ch"+channel, "ch"+channel, TypeWrapper.FLOAT, 0,
    200           !INDEXED, NULLABLE, !PRIMARY_KEY, true);
     235          !INDEXED, !UNIQUE, NULLABLE, !PRIMARY_KEY, true);
    201236  }
    202237 
     
    215250
    216251  /**
     252    Get a virutal column view of a cloned reporter property.
     253    @param property The cloned reporter property
     254    @return A virtual column representation of the cloned property
     255    @since 3.1
     256  */
     257  public static VirtualColumn clonedProperty(ClonedProperty property)
     258  {
     259    return new VirtualColumn(property.getName(), property.getColumn(), property.getType().getTypeWrapper(),
     260      property.getLength(), !INDEXED, !UNIQUE, property.isNullable(), !PRIMARY_KEY, false);
     261  }
     262 
     263  /**
    217264    The name of the column.
    218265  */
     
    238285  */
    239286  private final boolean indexed;
     287
     288  /**
     289    If the column must contain unique values or not.
     290  */
     291  private final boolean unique;
     292
    240293 
    241294  /**
     
    255308  */
    256309  private VirtualColumn(String name, String column, TypeWrapper type, int size,
    257     boolean indexed, boolean nullable, boolean primaryKey, boolean untransformIntensities)
     310    boolean indexed, boolean unique, boolean nullable, boolean primaryKey,
     311    boolean untransformIntensities)
    258312  {
    259313    this.name = name;
     
    262316    this.size = size;
    263317    this.indexed = indexed;
     318    this.unique = unique;
    264319    this.nullable = nullable;
    265320    this.primaryKey = primaryKey;
     
    333388
    334389  /**
     390    If the column must contain unique values or not.
     391    @return TRUE if unique, FALSE otherwise.
     392  */
     393  public boolean isUnique()
     394  {
     395    return unique;
     396  }
     397
     398  /**
    335399    If null values are allowed in the column or not.
    336400    @return TRUE if null is allowed, FALSE otherwise
  • trunk/src/core/net/sf/basedb/core/VirtualDb.java

    r5689 r5876  
    180180  {
    181181    return getDbControl().getItem(Experiment.class, getData().getExperiment());
     182  }
     183 
     184  /**
     185    Get the reporter clone template that is active in the current virtual database.
     186    If no cloned reporter information exists, this method return null.
     187    @return A <code>ReporterCloneTemplate</code> (locked) or null
     188    @since 3.1
     189  */
     190  public ReporterCloneTemplate getReporterCloneTemplate()
     191  {
     192    return getDbControl().getItem(ReporterCloneTemplate.class, getData().getReporterCloneTemplate());
     193  }
     194 
     195  /**
     196    Check if this virtual db is storing cloned reporter information or not.
     197    @since 3.1
     198  */
     199  public boolean hasClonedReporters()
     200  {
     201    return getData().getReporterCloneTemplate() != null;
    182202  }
    183203 
  • trunk/src/core/net/sf/basedb/core/VirtualTable.java

    r5854 r5876  
    2424
    2525import java.util.Arrays;
    26 
    27 import net.sf.basedb.core.hibernate.TypeWrapper;
     26import java.util.List;
     27
     28import net.sf.basedb.core.data.ReporterCloneTemplateData;
    2829
    2930import org.hibernate.dialect.Dialect;
     
    6768      the raw data type.
    6869    */
     70    @Override
     71    public VirtualColumn[] getColumns(VirtualDb vdb)
     72    {
     73      VirtualColumn[] columns = super.getColumns(vdb);
     74      RawDataType rdt = vdb.getRawDataType();
     75      VirtualColumn[] allColumns = new VirtualColumn[columns.length + rdt.getChannels()];
     76      System.arraycopy(columns, 0, allColumns, 0, columns.length);
     77      for (int i = 0; i < rdt.getChannels(); ++i)
     78      {
     79        allColumns[i+columns.length] = VirtualColumn.channelRaw(i+1);
     80      }
     81      return allColumns;
     82    }
     83   
     84    @Override
     85    @Deprecated
    6986    public VirtualColumn[] getColumns(RawDataType rdt)
    7087    {
     
    224241    VirtualColumn.COLUMN,
    225242    VirtualColumn.POSITION
    226   );
     243  ),
     244 
     245  /**
     246    Table that holds cloned reporter information for an experiment. The
     247    reporter id, version and external id are mandatory columns.
     248    Additional columns will be added according to what is defined
     249    by the {@link ReporterCloneTemplate} attached to an experiment.
     250    @since 3.1
     251  */
     252  CLONED_REPORTERS("D#Reporters", "crp",
     253    VirtualColumn.REPORTER_ID_PK,
     254    VirtualColumn.REPORTER_VERSION,
     255    VirtualColumn.REPORTER_EXTERNAL_ID)
     256  {
     257    /**
     258      Return default columns plus cloned columns as specified by template.
     259      If the virtual database doesn't have a template, an empty array is returned.
     260    */
     261    @Override
     262    public VirtualColumn[] getColumns(VirtualDb vdb)
     263    {
     264      if (!vdb.hasClonedReporters()) return new VirtualColumn[0];
     265     
     266      VirtualColumn[] defaultColumns = super.getColumns(vdb);
     267      ReporterCloneTemplate cloneTemplate = vdb.getReporterCloneTemplate();
     268      List<ClonedProperty> properties = cloneTemplate.getClonedProperties();
     269      VirtualColumn[] allColumns = new VirtualColumn[defaultColumns.length + properties.size()];
     270      System.arraycopy(defaultColumns, 0, allColumns, 0, defaultColumns.length);
     271     
     272      int index = defaultColumns.length;
     273      for (ClonedProperty cp : properties)
     274      {
     275        allColumns[index] = VirtualColumn.clonedProperty(cp);
     276        index++;
     277      }
     278      return allColumns;
     279    }
     280   
     281    /**
     282      @throws UnsupportedOperationException Must use the non-deprecated methods
     283    */
     284    @Override
     285    @Deprecated
     286    public VirtualColumn[] getColumns(RawDataType rdt)
     287    {
     288      throw new UnsupportedOperationException("getColumns(RawDataType)");
     289    }
     290
     291    /**
     292      Get the real table name of this table in the database.
     293      @param vdb The virtual database
     294    */
     295    @Override
     296    public String getTableName(VirtualDb vdb)
     297    {
     298      ReporterCloneTemplateData clone = vdb.getData().getReporterCloneTemplate();
     299      int suffix = clone == null ? 0 : clone.getId();
     300      return super.getTableName(vdb) + suffix;
     301    }
     302
     303  }
     304
     305  ;
    227306 
    228307  /**
     
    294373    Get all columns in this table.
    295374    @param rdt The raw data type of the experiment
    296   */
     375    @deprecated In 3.1, use {@link #getColumns(VirtualDb)} or
     376      {@link #getColumns(Experiment)} instead
     377  */
     378  @Deprecated
    297379  public VirtualColumn[] getColumns(RawDataType rdt)
    298380  {
    299381    return Arrays.copyOf(columns, columns.length);
     382  }
     383 
     384  /**
     385    Get all columns in this table.
     386    @param vdb The virtual database this table belongs to
     387    @since 3.1
     388  */
     389  public VirtualColumn[] getColumns(VirtualDb vdb)
     390  {
     391    return Arrays.copyOf(columns, columns.length);
     392  }
     393 
     394  /**
     395    Get all columns in this table.
     396    @param exp The experiment this table belongs to
     397    @since 3.1
     398  */
     399  public final VirtualColumn[] getColumns(Experiment exp)
     400  {
     401    return getColumns(exp.getVirtualDb());
    300402  }
    301403 
     
    324426    returned from this method.
    325427    @param rdt The raw data type of the experiment
    326   */
     428    @deprecated In 3.1, use {@link #getBytesPerRow(Experiment)}
     429      or {@link #getBytesPerRow(VirtualDb)} instead
     430  */
     431  @Deprecated
    327432  public long getBytesPerRow(RawDataType rdt)
    328433  {
     
    330435    for (VirtualColumn vc : getColumns(rdt))
    331436    {
    332       TypeWrapper type = vc.getTypeWrapper();
    333       if (type == TypeWrapper.SHORT)
    334       {
    335         bytesPerRow += 2;
    336       }
    337       else if (type == TypeWrapper.INTEGER)
    338       {
    339         bytesPerRow += 4;
    340       }
    341       else if (type == TypeWrapper.FLOAT)
    342       {
    343         bytesPerRow += 4;
    344       }
    345       else if (type == TypeWrapper.STRING)
    346       {
    347         bytesPerRow += 0; // Actual string length is added by the batcher
    348       }
    349       else
    350       {
    351         throw new AssertionError("No bytes per row specified for type: "+type);
    352       }
     437      bytesPerRow += vc.getTypeWrapper().getApproximateSize();
    353438    }
    354439    return bytesPerRow;
    355440  }
     441 
     442  /**
     443    @see #getBytesPerRow(VirtualDb)
     444    @since 3.1
     445  */
     446  public final long getBytesPerRow(Experiment experiment)
     447  {
     448    return getBytesPerRow(experiment.getVirtualDb());
     449  }
     450 
     451  /**
     452    Get the number of bytes a single row in the database occupies.
     453    The number doesn't include any variable length columns, ie. string
     454    columns. The caller should add the string length to the value
     455    returned from this method.
     456    @param vdb The virtual database where the table is stored
     457    @since 3.1
     458  */
     459  public long getBytesPerRow(VirtualDb vdb)
     460  {
     461    long bytesPerRow = 0;
     462    for (VirtualColumn vc : getColumns(vdb))
     463    {
     464      bytesPerRow += vc.getTypeWrapper().getApproximateSize();
     465    }
     466    return bytesPerRow;
     467  }
     468 
    356469}
  • trunk/src/core/net/sf/basedb/core/data/VirtualDbData.java

    r5818 r5876  
    5757  }
    5858
     59  private ReporterCloneTemplateData reporterCloneTemplate;
     60  /**
     61    Get the template used for creating the cloned reporter table
     62    in this virtual database, or null if there is no cloned
     63    reporter information.
     64    @hibernate.many-to-one column="`clone_template_id`" not-null="false"
     65      outer-join="false" unique="true" cascade="delete"
     66    @since 3.1
     67  */
     68  public ReporterCloneTemplateData getReporterCloneTemplate()
     69  {
     70    return reporterCloneTemplate;
     71  }
     72  public void setReporterCloneTemplate(ReporterCloneTemplateData reporterCloneTemplate)
     73  {
     74    this.reporterCloneTemplate = reporterCloneTemplate;
     75  }
     76
    5977  private short cubes;
    6078  /**
  • trunk/src/core/net/sf/basedb/core/hibernate/TypeWrapper.java

    r5475 r5876  
    4646 
    4747  public static final TypeWrapper<ShortType> SHORT =
    48     new TypeWrapper<ShortType>(ShortType.INSTANCE);
     48    new TypeWrapper<ShortType>(ShortType.INSTANCE, 2);
    4949
    5050  public static final TypeWrapper<IntegerType> INTEGER =
    51     new TypeWrapper<IntegerType>(IntegerType.INSTANCE);
     51    new TypeWrapper<IntegerType>(IntegerType.INSTANCE, 4);
    5252
    5353  public static final TypeWrapper<LongType> LONG =
    54     new TypeWrapper<LongType>(LongType.INSTANCE);
     54    new TypeWrapper<LongType>(LongType.INSTANCE, 8);
    5555
    5656  public static final TypeWrapper<FloatType> FLOAT =
    57     new TypeWrapper<FloatType>(FloatType.INSTANCE);
     57    new TypeWrapper<FloatType>(FloatType.INSTANCE, 4);
    5858
    5959  public static final TypeWrapper<DoubleType> DOUBLE =
    60     new TypeWrapper<DoubleType>(DoubleType.INSTANCE);
     60    new TypeWrapper<DoubleType>(DoubleType.INSTANCE, 8);
    6161
    6262  public static final TypeWrapper<StringType> STRING =
    63     new TypeWrapper<StringType>(StringType.INSTANCE);
     63    new TypeWrapper<StringType>(StringType.INSTANCE, 0);
    6464
    6565  public static final TypeWrapper<TextType> TEXT =
    66     new TypeWrapper<TextType>(TextType.INSTANCE);
     66    new TypeWrapper<TextType>(TextType.INSTANCE, 0);
    6767
    6868  public static final TypeWrapper<BooleanType> BOOLEAN =
    69     new TypeWrapper<BooleanType>(BooleanType.INSTANCE);
     69    new TypeWrapper<BooleanType>(BooleanType.INSTANCE, 1);
    7070 
    7171  public static final TypeWrapper<DateType> DATE =
    72     new TypeWrapper<DateType>(DateType.INSTANCE);
     72    new TypeWrapper<DateType>(DateType.INSTANCE, 4);
    7373
    7474  public static final TypeWrapper<TimestampType> TIMESTAMP =
    75     new TypeWrapper<TimestampType>(TimestampType.INSTANCE);
     75    new TypeWrapper<TimestampType>(TimestampType.INSTANCE, 4);
    7676
    7777
    7878  private final T hibernateType;
    7979  private final int sqlType;
     80  private final int size;
    8081 
    81   protected TypeWrapper(T hibernateType)
     82  protected TypeWrapper(T hibernateType, int size)
    8283  {
    8384    this.hibernateType = hibernateType;
    8485    this.sqlType = hibernateType instanceof org.hibernate.type.SingleColumnType ?
    8586      ((org.hibernate.type.SingleColumnType)hibernateType).sqlType() : 0;
     87    this.size = size;
    8688  }
    8789 
     
    104106  }
    105107 
     108  /**
     109    Get the number of bytes a single value for this type occupies
     110    in a database (approximately). If the type represents a
     111    variable-length property, 0 is returned.
     112   
     113    @return The number of bytes required in the database
     114      or 0 if not known
     115    @since 3.1
     116  */
     117  public int getApproximateSize()
     118  {
     119    return size;
     120  }
     121 
    106122
    107123}
  • trunk/src/test/TestAll.java

    r5764 r5876  
    167167    TestAnalyzeUtil.setupExperiment();
    168168    results.put("TestBasicAnalysis", TestBasicAnalysis.test_all());
     169//    results.put("TestReporterCloneTemplate", TestReporterCloneTemplate.test_all());
    169170    results.put("TestIntensityCalculatorPlugin", TestIntensityCalculatorPlugin.test_all());
    170171    results.put("TestLowessNormalization", TestLowessNormalization.test_all());
Note: See TracChangeset for help on using the changeset viewer.