Changeset 5422


Ignore:
Timestamp:
Sep 22, 2010, 10:01:44 AM (12 years ago)
Author:
Nicklas Nordborg
Message:

References #1512: Add support for datetime annotation types

Adds a new data class/table for storing datetime parameters (=timestamp in the SQL world). The schema update changes the existing DateValues? table to only store dates.

Added Type.TIMESTAMP to the Type enumeration.

This is basically 1) and 2) in the ticket description.

Location:
trunk
Files:
1 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/config/dist/mysql-queries.xml

    r4888 r5422  
    163163  </query>
    164164
     165  <query id="CHANGE_DATEVALUES_VALUE_COLUMN" type="SQL">
     166    <sql>
     167      ALTER TABLE [DateValues]
     168      MODIFY COLUMN [value] date NOT NULL
     169    </sql>
     170    <description>
     171      An SQL query that changes the 'DateValues.value'
     172      column to a date-only column type.
     173    </description>
     174  </query>
    165175
    166176</predefined-queries>
  • trunk/config/dist/postgres-queries.xml

    r4888 r5422  
    2828-->
    2929<predefined-queries>
     30  <query id="CHANGE_DATEVALUES_VALUE_COLUMN" type="SQL">
     31    <sql>
     32      ALTER TABLE [DateValues]
     33      ALTER COLUMN [value] TYPE date
     34    </sql>
     35    <description>
     36      An SQL query that changes the 'DateValues.value'
     37      column to a date-only column type.
     38    </description>
     39  </query>
    3040
    3141</predefined-queries>
  • trunk/src/core/net/sf/basedb/core/DateUtil.java

    r4889 r5422  
    2424
    2525import java.text.SimpleDateFormat;
     26import java.util.Calendar;
    2627import java.util.Date;
    2728
     
    7475    return value == null ? null : (Date)value.clone();
    7576  }
    76 
     77 
     78  /**
     79    Truncate the given date so that only the date part
     80    remains. The time part is set to 00:00:00.0
     81    @param value The date to truncate, can be null
     82    @return A new date with time part set to 0 or null
     83    @since 2.16
     84  */
     85  public static Date truncate(Date value)
     86  {
     87    if (value == null) return null;
     88    Calendar cal = Calendar.getInstance();
     89    cal.setTime(value);
     90    cal.set(Calendar.HOUR, 0);
     91    cal.set(Calendar.MINUTE, 0);
     92    cal.set(Calendar.SECOND, 0);
     93    cal.set(Calendar.MILLISECOND, 0);
     94    return cal.getTime();
     95  }
     96 
    7797  private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
    7898 
    7999  /**
    80       Parses a string to create a <code>Date</code>. This method supports
     100      Parses a string to create a <code>Date</code> without time. This method supports
    81101      date in yyyy-MM-dd format or as long timevalues.
    82102       
     
    121141  }
    122142 
     143
     144  private static final SimpleDateFormat TIMESTAMP_FORMAT = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
     145
     146  /**
     147      Parses a string to create a <code>Date</code> including time. This method
     148      supports date in yyyy-MM-dd hh:mm:ss format or as long timevalues.
     149       
     150      @param value the <code>String</code> to be parsed
     151      @return a <code>Date</code> object
     152      @throws InvalidDataException if <code>value</code> isn't a valid date.
     153      @since 2.16
     154  */
     155  public static Date parseTimestamp(String value)
     156    throws InvalidDataException
     157  {
     158    Date result = null;
     159    if (value != null)
     160    {
     161      try
     162      {
     163        result = TIMESTAMP_FORMAT.parse(value);
     164      }
     165      catch (Exception ex)
     166      {
     167        try
     168        {
     169          result = new Date(new Long(value));
     170        }
     171        catch (Exception ex2)
     172        {
     173          throw new InvalidDataException("The value "+value+" is not a valid date.");
     174        }
     175      }
     176    }
     177    return result;
     178  }
     179
     180  /**
     181    Formats a timestamp in yyyy-MM-dd hh:mm:ss format.
     182    @param d The date to format.
     183    @return Formated date as a String
     184    @since 2.16
     185  */
     186  public static String formatTimestamp(Date d)
     187  {
     188    return TIMESTAMP_FORMAT.format(d);
     189  }
     190
     191 
    123192}
  • trunk/src/core/net/sf/basedb/core/Install.java

    r5406 r5422  
    115115    method.
    116116  */
    117   public static final int NEW_SCHEMA_VERSION = Integer.valueOf(84).intValue();
     117  public static final int NEW_SCHEMA_VERSION = Integer.valueOf(85).intValue();
    118118 
    119119  public static synchronized void createTables(boolean update, final ProgressReporter progress)
  • trunk/src/core/net/sf/basedb/core/Type.java

    r5384 r5422  
    3333import net.sf.basedb.core.data.StringParameterValueData;
    3434import net.sf.basedb.core.data.BooleanParameterValueData;
     35import net.sf.basedb.core.data.TimestampParameterValueData;
    3536import net.sf.basedb.core.hibernate.TypeWrapper;
    3637
     
    5455    Integer type.
    5556  */
    56   INT(TypeWrapper.INTEGER, 1, Integer.class, "int", "Integer", "IntegerValues", true, true)
     57  INT(TypeWrapper.INTEGER, 1, Integer.class, "int", "Integer", "IntegerValues", true, true, false)
    5758  {
    5859    ParameterValueData<Integer> newParameterValueData()
     
    7980    Long integer type.
    8081  */
    81   LONG(TypeWrapper.LONG, 2, Long.class, "long", "Long", "LongValues", true, true)
     82  LONG(TypeWrapper.LONG, 2, Long.class, "long", "Long", "LongValues", true, true, false)
    8283  {
    8384    ParameterValueData<Long> newParameterValueData()
     
    104105    Float type.
    105106  */
    106   FLOAT(TypeWrapper.FLOAT, 3, Float.class, "float", "Float", "FloatValues", true, true)
     107  FLOAT(TypeWrapper.FLOAT, 3, Float.class, "float", "Float", "FloatValues", true, true, false)
    107108  {
    108109    ParameterValueData<Float> newParameterValueData()
     
    131132    Double type.
    132133  */
    133   DOUBLE(TypeWrapper.DOUBLE, 4, Double.class, "double", "Double", "DoubleValues", true, true)
     134  DOUBLE(TypeWrapper.DOUBLE, 4, Double.class, "double", "Double", "DoubleValues", true, true, false)
    134135  {
    135136    ParameterValueData<Double> newParameterValueData()
     
    159160    @see #TEXT
    160161  */
    161   STRING(TypeWrapper.STRING, 5, String.class, "string", "String", "StringValues", true, false)
     162  STRING(TypeWrapper.STRING, 5, String.class, "string", "String", "StringValues", true, false, false)
    162163  {
    163164    ParameterValueData<String> newParameterValueData()
     
    181182    @see #STRING
    182183  */
    183   TEXT(TypeWrapper.TEXT, 6, String.class, "text", "Text", "TextValues", false, false)
     184  TEXT(TypeWrapper.TEXT, 6, String.class, "text", "Text", "TextValues", false, false, false)
    184185  {
    185186    ParameterValueData<String> newParameterValueData()
     
    202203    Boolean type.
    203204  */
    204   BOOLEAN(TypeWrapper.BOOLEAN, 7, Boolean.class, "boolean", "Boolean", "BooleanValues", false, false)
     205  BOOLEAN(TypeWrapper.BOOLEAN, 7, Boolean.class, "boolean", "Boolean", "BooleanValues", false, false, false)
    205206  {
    206207    ParameterValueData<Boolean> newParameterValueData()
     
    231232    The parameter is a date value.
    232233  */
    233   DATE(TypeWrapper.DATE, 8, Date.class, "date", "Date", "DateValues", true, false)
     234  DATE(TypeWrapper.DATE, 8, Date.class, "date", "Date", "DateValues", true, false, true)
    234235  {
    235236    ParameterValueData<Date> newParameterValueData()
     
    244245    public int sizeOf(Object value)
    245246    {
     247      return value == null ? 0 : 4;
     248    }
     249  },
     250
     251  /**
     252    The parameter is a date+time value.
     253    @since 2.16
     254  */
     255  TIMESTAMP(TypeWrapper.TIMESTAMP, 9, Date.class, "timestamp", "Timestamp", "TimestampValues", false, false, true)
     256  {
     257    ParameterValueData<Date> newParameterValueData()
     258    {
     259      return new TimestampParameterValueData();
     260    }
     261    public Object parseString(String value)
     262      throws InvalidDataException
     263    {
     264      return DateUtil.parseTimestamp(value);
     265    }
     266    public int sizeOf(Object value)
     267    {
    246268      return value == null ? 0 : 8;
    247269    }
    248270  };
    249271
     272 
    250273  private static final Map<Integer, Type> valueMapping = new HashMap<Integer, Type>();
    251274  private static final Map<String, Type> stringMapping = new HashMap<String, Type>();
     
    271294  private final boolean canEnumerate;
    272295  private final boolean isNumerical;
     296  private final boolean isTemporal;
    273297
    274298  private Type(TypeWrapper typeWrapper, int value, Class<?> valueClass,
    275     String stringValue, String displayValue, String tableName, boolean canEnumerate, boolean isNumerical)
     299    String stringValue, String displayValue, String tableName, boolean canEnumerate, boolean isNumerical, boolean isTemporal)
    276300  {
    277301    this.typeWrapper = typeWrapper;
     
    283307    this.canEnumerate = canEnumerate;
    284308    this.isNumerical = isNumerical;
     309    this.isTemporal = isTemporal;
    285310  }
    286311
     
    384409  }
    385410
     411  /**
     412    If the values of this type are date/time related.
     413    @return TRUE if the values are temporal, FALSE otherwise
     414    @since 2.16
     415  */
     416  public boolean isTemporal()
     417  {
     418    return isTemporal;
     419  }
     420
     421 
    386422  /**
    387423    Check if an object is a value of the correct type. Null is allowed.
  • trunk/src/core/net/sf/basedb/core/Update.java

    r5406 r5422  
    4545import net.sf.basedb.core.data.ChangeHistoryDetailData;
    4646import net.sf.basedb.core.data.DataCubeData;
     47import net.sf.basedb.core.data.DateParameterValueData;
    4748import net.sf.basedb.core.data.ExperimentData;
    4849import net.sf.basedb.core.data.FileData;
     
    6263import net.sf.basedb.core.data.RoleKeyData;
    6364import net.sf.basedb.core.data.SchemaVersionData;
     65import net.sf.basedb.core.data.TimestampParameterValueData;
    6466import net.sf.basedb.core.data.TransformationData;
    6567import net.sf.basedb.core.data.keyring.PluginKeys;
     
    914916      date to the creation date for all existing jobs that is in WAITING status
    915917      or higher.
     918    </td>
     919  </tr>
     920  <tr>
     921    <td>85</td>
     922    <td>
     923      Added {@link TimestampParameterValueData}. The update will change the
     924      {@link DateParameterValueData} to a date-only column type.
    916925    </td>
    917926  </tr>
     
    12521261            "--Updating schema version: " + schemaVersion + " -> 84...");
    12531262        schemaVersion = updateToSchemaVersion84(session);
     1263      }
     1264     
     1265      if (schemaVersion < 85)
     1266      {
     1267        if (progress != null) progress.display((int)(84*progress_factor),
     1268            "--Updating schema version: " + schemaVersion + " -> 85...");
     1269        schemaVersion = updateToSchemaVersion85(session);
    12541270      }
    12551271
     
    29222938  }
    29232939
    2924  
     2940  /**
     2941    Change the date type for the DateValues.values column,.
     2942  */
     2943  private static int updateToSchemaVersion85(org.hibernate.Session session)
     2944    throws BaseException
     2945  {
     2946    final int schemaVersion = 85;
     2947    org.hibernate.Transaction tx = null;
     2948    try
     2949    {
     2950      tx = HibernateUtil.newTransaction(session);
     2951     
     2952      // Load and execute the query
     2953      org.hibernate.Query query = HibernateUtil.getPredefinedSQLQuery(session, "CHANGE_DATEVALUES_VALUE_COLUMN");
     2954      /*
     2955        ALTER TABLE [DateValues]
     2956        MODIFY COLUMN [value] date NOT NULL
     2957      */
     2958      query.executeUpdate();
     2959     
     2960      // Update the schema version number
     2961      setSchemaVersion(session, schemaVersion);
     2962 
     2963      // Commit the changes
     2964      HibernateUtil.commit(tx);
     2965      log.info("updateToSchemaVersion85: OK");
     2966    }
     2967    catch (BaseException ex)
     2968    {
     2969      if (tx != null) HibernateUtil.rollback(tx);
     2970      log.error("updateToSchemaVersion85: FAILED", ex);
     2971      throw ex;
     2972    }
     2973    return schemaVersion;
     2974  }
    29252975 
    29262976  /**
  • trunk/src/core/net/sf/basedb/core/data/DateParameterValueData.java

    r4889 r5422  
    2727import java.util.Date;
    2828
     29import net.sf.basedb.core.DateUtil;
     30
    2931/**
    3032  Date parameter value.
     
    5153    @hibernate.bag table="`DateValues`" lazy="true" cascade="all"
    5254    @hibernate.collection-key column="`id`"
    53     @hibernate.collection-element column="`value`" type="timestamp" not-null="true"
     55    @hibernate.collection-element column="`value`" type="date" not-null="true"
    5456  */
    5557  public List<Date> getValues()
     
    6668  }
    6769
     70 
     71  /**
     72    Overrides the parent method since we want to get rid of the
     73    time part of the date.
     74  */
     75  @Override
     76  public void replaceValues(List<?> values)
     77  {
     78    List<Date> current = getValues();
     79    current.clear();
     80    if (values != null)
     81    {
     82      for (Object v : values)
     83      {
     84        current.add(DateUtil.truncate((Date)v));
     85      }
     86    }
     87  }
     88 
     89  /**
     90    Overrides the parent method since we want to get rid of the
     91    time part of the date.
     92  */
     93  @Override
     94  public void setSingleValue(Object value)
     95  {
     96    List<Date> current = getValues();
     97    current.clear();
     98    current.add(DateUtil.truncate((Date)value));
     99  }
     100 
    68101  public String toString()
    69102  {
  • trunk/src/core/net/sf/basedb/core/hibernate/TypeWrapper.java

    r5346 r5422  
    3131import org.hibernate.type.StringType;
    3232import org.hibernate.type.TextType;
     33import org.hibernate.type.TimestampType;
    3334
    3435/**
     
    7172    new TypeWrapper<DateType>(new DateType());
    7273
     74  public static final TypeWrapper<TimestampType> TIMESTAMP =
     75    new TypeWrapper<TimestampType>(new TimestampType());
     76
    7377
    7478  private final T hibernateType;
  • trunk/src/test/TestAnnotation.java

    r5060 r5422  
    6060    int doubleId = TestAnnotationType.test_create("Size", Type.DOUBLE, meterId, 8.13454646d, null, Item.ARRAYDESIGN, 1, null, true);
    6161    int dateId = TestAnnotationType.test_create(null, Type.DATE, 0, new Date(), null, Item.ARRAYDESIGN, 1, null, true);
     62    int timestampId = TestAnnotationType.test_create(null, Type.TIMESTAMP, 0, new Date(), null, Item.ARRAYDESIGN, 1, null, true);
    6263    int textId = TestAnnotationType.test_create(null, Type.TEXT, 0, "default value", null, Item.ARRAYDESIGN, 1, null, true);
    6364    int stringId = TestAnnotationType.test_create(null, Type.STRING, 0, "default value", null, Item.ARRAYDESIGN, 1, null, true);
     
    7576    int doubleAnnotationId2 = test_annotatate(Item.ARRAYDESIGN, arrayDesignId2, doubleId, millimeterId, 11.365789456857d);
    7677    int dateAnnotationId = test_annotatate(Item.ARRAYDESIGN, arrayDesignId, dateId, 0, new Date());
     78    int timestampAnnotationId = test_annotatate(Item.ARRAYDESIGN, arrayDesignId, timestampId, 0, new Date());
    7779    int textAnnotationId = test_annotatate(Item.ARRAYDESIGN, arrayDesignId, textId, 0, "a text annotation");
    7880    int stringAnnotationId = test_annotatate(Item.ARRAYDESIGN, arrayDesignId, stringId, 0, "a string annotation");
    7981    int booleanAnnotationId = test_annotatate(Item.ARRAYDESIGN, arrayDesignId, booleanId, 0, false);
    8082    int enumAnnotationId = test_annotatate(Item.ARRAYDESIGN, arrayDesignId, enumId, 0, 4);
    81     test_list_annotations(Item.ARRAYDESIGN, arrayDesignId, 9);
     83    test_list_annotations(Item.ARRAYDESIGN, arrayDesignId, 10);
    8284    test_list_annotations(Item.ARRAYDESIGN, arrayDesignId2, 2);
    8385
     
    9092    // Test: list inherited annotations and annotation sets
    9193    test_list_inherited_annotations(Item.RAWBIOASSAY, rawBioAssayId, 2);
    92     test_list_allinherited_annotations(Item.RAWBIOASSAY, rawBioAssayId, 9);
     94    test_list_allinherited_annotations(Item.RAWBIOASSAY, rawBioAssayId, 10);
    9395    test_list_inherited_annotationsets(Item.RAWBIOASSAY, rawBioAssayId, 1);
    9496    test_list_inheriting_annotationsets(Item.ARRAYDESIGN, arrayDesignId, 1);
     
    103105    test_remove_annotation(Item.ARRAYDESIGN, arrayDesignId, doubleId);
    104106    test_remove_annotation(Item.ARRAYDESIGN, arrayDesignId, dateId);
     107    test_remove_annotation(Item.ARRAYDESIGN, arrayDesignId, timestampId);
    105108    test_remove_annotation(Item.ARRAYDESIGN, arrayDesignId, textId);
    106109    test_remove_annotation(Item.ARRAYDESIGN, arrayDesignId, stringId);
     
    117120    TestAnnotationType.test_delete(doubleId);
    118121    TestAnnotationType.test_delete(dateId);
     122    TestAnnotationType.test_delete(timestampId);
    119123    TestAnnotationType.test_delete(textId);
    120124    TestAnnotationType.test_delete(stringId);
  • trunk/src/test/TestAnnotationType.java

    r5340 r5422  
    5555    int id_double = test_create("Size", Type.DOUBLE, meterId, 8.13459187745, null, Item.SAMPLE, 1, null, false);
    5656    int id_date = test_create(null, Type.DATE, 0, new Date(), null, Item.SAMPLE, 1, null, false);
     57    int id_timestamp = test_create(null, Type.TIMESTAMP, 0, new Date(), null, Item.SAMPLE, 1, null, false);
    5758    int id_text = test_create(null, Type.TEXT, 0, "default value", null, Item.SAMPLE, 1, null, false);
    5859    int id_string = test_create(null, Type.STRING, 0, "default value", null, Item.SAMPLE, 1, null, false);
     
    6566    test_load(id_double);
    6667    test_load(id_date);
     68    test_load(id_timestamp);
    6769    test_load(id_text);
    6870    test_load(id_string);
     
    9698    test_delete(id_double);
    9799    test_delete(id_date);
     100    test_delete(id_timestamp);
    98101    test_delete(id_text);
    99102    test_delete(id_string);
Note: See TracChangeset for help on using the changeset viewer.