Print

Print


Author: [log in to unmask]
Date: Thu Aug 27 18:42:21 2015
New Revision: 3428

Log:
Use factory so DAO impl classes can be protected; rework EPICS data API and database structure.  HPSJAVA-580, HPSJAVA-591

Added:
    java/trunk/record-util/src/main/java/org/hps/rundb/EpicsType.java
    java/trunk/record-util/src/main/java/org/hps/rundb/EpicsVariable.java
    java/trunk/record-util/src/main/java/org/hps/rundb/EpicsVariableDao.java
    java/trunk/record-util/src/main/java/org/hps/rundb/EpicsVariableDaoImpl.java
    java/trunk/record-util/src/main/java/org/hps/rundb/RunDatabaseDaoFactory.java
    java/trunk/record-util/src/main/java/org/hps/rundb/TriggerConfigDao.java
      - copied, changed from r3424, java/trunk/record-util/src/main/java/org/hps/rundb/TriggerConfigIntDao.java
    java/trunk/record-util/src/main/java/org/hps/rundb/TriggerConfigDaoImpl.java
      - copied, changed from r3424, java/trunk/record-util/src/main/java/org/hps/rundb/TriggerConfigIntDaoImpl.java
Removed:
    java/trunk/record-util/src/main/java/org/hps/rundb/TriggerConfigIntDao.java
    java/trunk/record-util/src/main/java/org/hps/rundb/TriggerConfigIntDaoImpl.java
Modified:
    java/trunk/record-util/src/main/java/org/hps/rundb/EpicsDataDao.java
    java/trunk/record-util/src/main/java/org/hps/rundb/EpicsDataDaoImpl.java
    java/trunk/record-util/src/main/java/org/hps/rundb/EvioFilesDao.java
    java/trunk/record-util/src/main/java/org/hps/rundb/EvioFilesDaoImpl.java
    java/trunk/record-util/src/main/java/org/hps/rundb/RunSummary.java
    java/trunk/record-util/src/main/java/org/hps/rundb/RunSummaryDao.java
    java/trunk/record-util/src/main/java/org/hps/rundb/RunSummaryDaoImpl.java
    java/trunk/record-util/src/main/java/org/hps/rundb/RunSummaryImpl.java
    java/trunk/record-util/src/main/java/org/hps/rundb/ScalerDataDaoImpl.java
    java/trunk/record-util/src/main/java/org/hps/rundb/package-info.java

Modified: java/trunk/record-util/src/main/java/org/hps/rundb/EpicsDataDao.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/rundb/EpicsDataDao.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/rundb/EpicsDataDao.java	Thu Aug 27 18:42:21 2015
@@ -12,40 +12,20 @@
 public interface EpicsDataDao {
 
     /**
-     * Delete EPICS data from the database.
-     *
-     * @param epicsData the EPICS data to delete
-     */
-    void deleteEpicsData(EpicsData epicsData);
-
-    /**
      * Delete all EPICS data for a run from the database.
      *
      * @param run the run number
      */
-    void deleteEpicsData(int run);
-
-    /**
-     * Get all the EPICS data in the database.
-     *
-     * @return the list of EPICS data
-     */
-    List<EpicsData> getAllEpicsData();
+    public void deleteEpicsData(EpicsType epicsType, final int run);
 
     /**
      * Get EPICS data by run.
      *
      * @param run the run number
+     * @param epicsType the type of EPICS data (1s or 10s)
      * @return the EPICS data
      */
-    List<EpicsData> getEpicsData(int run);
-
-    /**
-     * Get the list of unique variables names used in the database records.
-     *
-     * @return the list of unique variable names
-     */
-    List<String> getVariableNames();
+    List<EpicsData> getEpicsData(EpicsType epicsType, int run);
 
     /**
      * Insert a list of EPICS data into the database.
@@ -54,12 +34,5 @@
      *
      * @param epicsDataList the list of EPICS data
      */
-    void insertEpicsData(List<EpicsData> epicsDataList);
-
-    /**
-     * Updates EPICS data in the database.
-     *
-     * @param epicsData the EPICS data to update
-     */
-    void updateEpicsData(EpicsData epicsData);
+    void insertEpicsData(List<EpicsData> epicsDataList);   
 }

Modified: java/trunk/record-util/src/main/java/org/hps/rundb/EpicsDataDaoImpl.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/rundb/EpicsDataDaoImpl.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/rundb/EpicsDataDaoImpl.java	Thu Aug 27 18:42:21 2015
@@ -6,7 +6,9 @@
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.hps.record.epics.EpicsData;
 import org.hps.record.epics.EpicsHeader;
@@ -16,47 +18,17 @@
  *
  * @author Jeremy McCormick, SLAC
  */
-public class EpicsDataDaoImpl implements EpicsDataDao {
-
-    /**
-     * SQL data query strings.
-     */
-    private static class EpicsDataQuery {
-
-        /**
-         * Delete by run number.
-         */
-        private static final String DELETE_BY_RUN = "DELETE FROM run_epics WHERE run = ?";
-        /**
-         * Delete by run and sequence number.
-         */
-        private static final String DELETE_RUN_AND_SEQUENCE = "DELETE FROM run_epics WHERE run = ? and sequence = ?";
-        /**
-         * Insert a record.
-         */
-        private static final String INSERT = "INSERT INTO run_epics (run, sequence, timestamp, variable_name, value) VALUES (?, ?, ?, ?, ?)";
-        /**
-         * Select all records.
-         */
-        private static final String SELECT_ALL = "SELECT * FROM run_epics ORDER BY run, sequence";
-        /**
-         * Select by run number.
-         */
-        private static final String SELECT_RUN = "SELECT * FROM run_epics WHERE run = ? ORDER BY `sequence`";
-        /**
-         * Select unique variable names.
-         */
-        private static final String SELECT_VARIABLE_NAMES = "SELECT DISTINCT(variable_name) FROM run_epics ORDER BY variable_name";
-        /**
-         * Update a record.
-         */
-        private static final String UPDATE = "UPDATE run_epics SET run = ?, sequence = ?, timestamp = ?, variable_name = ?, value = ? WHERE run = ? and sequence = ? and variable_name = ?";
-    }
+final class EpicsDataDaoImpl implements EpicsDataDao {
 
     /**
      * The database connection.
      */
     private final Connection connection;
+
+    /**
+     * The database interface to get EPICS variable information.
+     */
+    private final EpicsVariableDao epicsVariableDao;
 
     /**
      * Create a new DAO implementation for EPICS data.
@@ -68,294 +40,217 @@
             throw new IllegalArgumentException("The connection is null.");
         }
         this.connection = connection;
-    }
-
-    /**
-     * Delete the record for this EPICS data object using its run and sequence number.
+        this.epicsVariableDao = new EpicsVariableDaoImpl(this.connection);
+    }
+
+    /**
+     * Create SQL insert string for the EPICS type.
+     *
+     * @param epicsType the EPICS type
+     * @return the SQL insert string for the type
+     */
+    private String createInsertSql(final EpicsType epicsType) {
+        final StringBuffer sb = new StringBuffer();
+        sb.append("INSERT INTO " + epicsType.getTableName() + " ( epics_header_id, ");
+        final List<EpicsVariable> variables = epicsVariableDao.getEpicsVariables(epicsType);
+        for (final EpicsVariable variable : variables) {
+            sb.append(variable.getColumnName() + ", ");
+        }
+        sb.setLength(sb.length() - 2);
+        sb.append(" ) VALUES ( ?, ");
+        for (int i = 0; i < variables.size(); i++) {
+            sb.append("?, ");
+        }
+        sb.setLength(sb.length() - 2);
+        sb.append(" )");
+        return sb.toString();
+    }
+
+    /**
+     * Delete all EPICS data for a run from the database.
      *
      * @param run the run number
-     * @throws IllegalArgumentException if the EPICS data is missing a header object
      */
     @Override
-    public void deleteEpicsData(final EpicsData epicsData) {
-        PreparedStatement preparedStatement = null;
+    public void deleteEpicsData(final EpicsType epicsType, final int run) {
+        PreparedStatement selectHeaderIds = null;
+        PreparedStatement deleteEpicsData = null;
+        PreparedStatement deleteHeader = null;
         try {
-            final EpicsHeader epicsHeader = epicsData.getEpicsHeader();
-            if (epicsHeader == null) {
-                throw new IllegalArgumentException("The EPICS data is missing header information.");
-            }
-            preparedStatement = connection.prepareStatement(EpicsDataQuery.DELETE_RUN_AND_SEQUENCE);
-            preparedStatement.setInt(1, epicsHeader.getRun());
-            preparedStatement.setInt(2, epicsHeader.getSequence());
-            preparedStatement.executeUpdate();
+            selectHeaderIds = connection.prepareStatement("SELECT id FROM epics_headers WHERE run = ?");
+            selectHeaderIds.setInt(1, run);
+            final ResultSet headerResultSet = selectHeaderIds.executeQuery();
+            deleteEpicsData = connection.prepareStatement("DELETE FROM " + epicsType.getTableName()
+                    + " WHERE epics_header_id = ?");
+            deleteHeader = connection.prepareStatement("DELETE FROM epics_headers WHERE id = ?");
+            final Set<Integer> headerIds = new HashSet<Integer>();
+            while (headerResultSet.next()) {
+                headerIds.add(headerResultSet.getInt("id"));
+            }
+            for (final Integer headerId : headerIds) {
+                deleteEpicsData.setInt(1, headerId);
+                int rowsAffected = deleteEpicsData.executeUpdate();
+                if (rowsAffected == 0) {
+                    throw new SQLException("Deletion of EPICS data failed; no rows affect.");
+                }
+                deleteHeader.setInt(1, headerId);
+                rowsAffected = deleteHeader.executeUpdate();
+                if (rowsAffected == 0) {
+                    throw new SQLException("Deletion of EPICS header failed; no rows affect.");
+                }
+            }
+
         } catch (final SQLException e) {
             throw new RuntimeException(e);
         } finally {
-            if (preparedStatement != null) {
-                try {
-                    preparedStatement.close();
-                } catch (final SQLException e) {
-                    e.printStackTrace();
-                }
-            }
-        }
-    }
-
-    /**
-     * Delete all EPICS data for a run from the database.
+            if (selectHeaderIds != null) {
+                try {
+                    selectHeaderIds.close();
+                } catch (final SQLException e) {
+                    e.printStackTrace();
+                }
+            }
+            if (deleteEpicsData != null) {
+                try {
+                    deleteEpicsData.close();
+                } catch (final SQLException e) {
+                    e.printStackTrace();
+                }
+            }
+            if (deleteHeader != null) {
+                try {
+                    deleteHeader.close();
+                } catch (final SQLException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    /**
+     * Get EPICS data by run.
      *
      * @param run the run number
+     * @param epicsType the type of EPICS data (1s or 10s)
+     * @return the EPICS data
      */
     @Override
-    public void deleteEpicsData(final int run) {
-        PreparedStatement preparedStatement = null;
+    public List<EpicsData> getEpicsData(final EpicsType epicsType, final int run) {
+        final List<EpicsData> epicsDataList = new ArrayList<EpicsData>();
+        PreparedStatement selectHeader = null;
+        PreparedStatement selectEpicsData = null;
         try {
-            preparedStatement = connection.prepareStatement(EpicsDataQuery.DELETE_BY_RUN);
-            preparedStatement.setInt(1, run);
-            preparedStatement.executeUpdate();
+            selectHeader = connection.prepareStatement("SELECT * FROM epics_headers WHERE run = ?");
+            selectHeader.setInt(1, run);
+            final ResultSet headerResultSet = selectHeader.executeQuery();
+            selectEpicsData = connection.prepareStatement("SELECT * FROM " + epicsType.getTableName()
+                    + " WHERE epics_header_id = ?");
+            final List<EpicsVariable> variables = epicsVariableDao.getEpicsVariables(epicsType);
+            while (headerResultSet.next()) {
+                final int headerId = headerResultSet.getInt("id");
+                final int headerRun = headerResultSet.getInt("run");
+                final int sequence = headerResultSet.getInt("sequence");
+                final int timestamp = headerResultSet.getInt("timestamp");
+                selectEpicsData.setInt(1, headerId);
+                final ResultSet epicsDataResult = selectEpicsData.executeQuery();
+                if (epicsDataResult.next()) {
+                    final EpicsHeader header = new EpicsHeader(new int[] {headerRun, sequence, timestamp});
+                    final EpicsData epicsData = new EpicsData();
+                    epicsData.setEpicsHeader(header);
+                    for (final EpicsVariable variable : variables) {
+                        final double value = epicsDataResult.getDouble(variable.getColumnName());
+                        epicsData.setValue(variable.getVariableName(), value);
+                    }
+                    epicsDataList.add(epicsData);
+                } else {
+                    throw new SQLException("Getting EPICS data failed; no data for header ID.");
+                }
+            }
         } catch (final SQLException e) {
             throw new RuntimeException(e);
         } finally {
-            if (preparedStatement != null) {
-                try {
-                    preparedStatement.close();
-                } catch (final SQLException e) {
-                    e.printStackTrace();
-                }
-            }
-        }
-    }
-
-    /**
-     * Get all the EPICS data in the database.
-     *
-     * @return the list of EPICS data
+            if (selectHeader != null) {
+                try {
+                    selectHeader.close();
+                } catch (final SQLException e) {
+                    e.printStackTrace();
+                }
+            }
+            if (selectEpicsData != null) {
+                try {
+                    selectEpicsData.close();
+                } catch (final SQLException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        return epicsDataList;
+    }
+
+    /**
+     * Insert a list of EPICS data into the database.
+     * <p>
+     * The run number comes from the header information.
+     *
+     * @param epicsDataList the list of EPICS data
      */
     @Override
-    public List<EpicsData> getAllEpicsData() {
-        PreparedStatement preparedStatement = null;
-        final List<EpicsData> epicsDataList = new ArrayList<EpicsData>();
+    public void insertEpicsData(final List<EpicsData> epicsDataList) {
+        if (epicsDataList.isEmpty()) {
+            throw new IllegalArgumentException("The EPICS data list is empty.");
+        }
+        System.out.println("inserting " + epicsDataList.size() + " EPICS records");
+        PreparedStatement insertHeaderStatement = null;
         try {
-            preparedStatement = connection.prepareStatement(EpicsDataQuery.SELECT_ALL);
-            final ResultSet resultSet = preparedStatement.executeQuery();
-            Integer currentRun = null;
-            Integer currentSequence = null;
-            EpicsData epicsData = new EpicsData();
-            while (resultSet.next()) {
-                if (currentRun == null) {
-                    currentRun = resultSet.getInt("run");
-                }
-                if (currentSequence == null) {
-                    currentSequence = resultSet.getInt("sequence");
-                }
-                final int run = resultSet.getInt("run");
-                final int sequence = resultSet.getInt("sequence");
-                final int timestamp = resultSet.getInt("timestamp");
-                final String variableName = resultSet.getString("variable_name");
-                final double value = resultSet.getDouble("value");
-                if (currentRun != run || currentSequence != sequence) {
-                    epicsDataList.add(epicsData);
-                    epicsData = new EpicsData();
-                    final EpicsHeader epicsHeader = new EpicsHeader(new int[] {run, sequence, timestamp});
-                    epicsData.setEpicsHeader(epicsHeader);
-                }
-                epicsData.setValue(variableName, value);
-            }
-            epicsDataList.add(epicsData);
+            insertHeaderStatement = connection.prepareStatement(
+                    "INSERT INTO epics_headers (run, sequence, timestamp) VALUES (?, ?, ?)",
+                    Statement.RETURN_GENERATED_KEYS);
+            for (final EpicsData epicsData : epicsDataList) {
+                final EpicsHeader epicsHeader = epicsData.getEpicsHeader();
+                if (epicsHeader == null) {
+                    throw new IllegalArgumentException("The EPICS data is missing a header.");
+                }
+                insertHeaderStatement.setInt(1, epicsHeader.getRun());
+                insertHeaderStatement.setInt(2, epicsHeader.getSequence());
+                insertHeaderStatement.setInt(3, epicsHeader.getTimestamp());
+                final int rowsCreated = insertHeaderStatement.executeUpdate();
+                if (rowsCreated == 0) {
+                    throw new SQLException("Creation of EPICS header record failed; no rows affected.");
+                }
+                int headerId = 0;
+                try (ResultSet generatedKeys = insertHeaderStatement.getGeneratedKeys()) {
+                    if (generatedKeys.next()) {
+                        headerId = generatedKeys.getInt(1);
+                    } else {
+                        throw new SQLException("Creation of EPICS header record failed; no ID obtained.");
+                    }
+                }
+                final EpicsType epicsType = EpicsType.getEpicsType(epicsData);
+                final String insertSql = this.createInsertSql(epicsType);
+                final List<EpicsVariable> variables = epicsVariableDao.getEpicsVariables(epicsType);
+                final PreparedStatement insertStatement = connection.prepareStatement(insertSql);
+                insertStatement.setInt(1, headerId);
+                int parameterIndex = 2;
+                for (final EpicsVariable variable : variables) {
+                    insertStatement.setDouble(parameterIndex, epicsData.getValue(variable.getVariableName()));
+                    ++parameterIndex;
+                }
+                final int dataRowsCreated = insertStatement.executeUpdate();
+                if (dataRowsCreated == 0) {
+                    throw new SQLException("Creation of EPICS data failed; no rows affected.");
+                }
+                insertStatement.close();
+            }
         } catch (final SQLException e) {
             throw new RuntimeException(e);
         } finally {
-            try {
-                preparedStatement.close();
-            } catch (final SQLException e) {
-                e.printStackTrace();
-            }
-        }
-        return epicsDataList;
-    }
-
-    /**
-     * Get EPICS data by run.
-     *
-     * @param run the run number
-     * @return the EPICS data
-     */
-    @Override
-    public List<EpicsData> getEpicsData(final int run) {
-        PreparedStatement preparedStatement = null;
-        final List<EpicsData> epicsDataList = new ArrayList<EpicsData>();
-        try {
-            preparedStatement = connection.prepareStatement(EpicsDataQuery.SELECT_RUN);
-            preparedStatement.setInt(1, run);
-            final ResultSet resultSet = preparedStatement.executeQuery();
-            Integer currentSequence = null;
-            EpicsData epicsData = new EpicsData();
-            EpicsHeader epicsHeader = null;
-            while (resultSet.next()) {
-
-                // Get record data.
-                final int sequence = resultSet.getInt("sequence");
-                final int timestamp = resultSet.getInt("timestamp");
-                final String variableName = resultSet.getString("variable_name");
-                final double value = resultSet.getDouble("value");
-
-                // Get sequence first time.
-                if (currentSequence == null) {
-                    currentSequence = resultSet.getInt("sequence");
-                }
-
-                // Create EPICS header.
-                epicsHeader = new EpicsHeader(new int[] {run, sequence, timestamp});
-
-                // First time need to set header here.
-                if (epicsData.getEpicsHeader() == null) {
-                    epicsData.setEpicsHeader(epicsHeader);
-                }
-
-                // New sequence number occurred.
-                if (currentSequence != sequence) {
-
-                    // Add the EPICS data to the list.
-                    epicsDataList.add(epicsData);
-
-                    // Use the new sequence number.
-                    currentSequence = sequence;
-
-                    // Create new EPICS data.
-                    epicsData = new EpicsData();
-
-                    // Set header from current record.
-                    epicsData.setEpicsHeader(epicsHeader);
-                }
-
-                // Set the value of the variable from the current record.
-                epicsData.setValue(variableName, value);
-            }
-
-            // Add the last object which will not happen inside the loop.
-            epicsDataList.add(epicsData);
-
-        } catch (final SQLException e) {
-            throw new RuntimeException(e);
-        } finally {
-            try {
-                preparedStatement.close();
-            } catch (final SQLException e) {
-                e.printStackTrace();
-            }
-        }
-        return epicsDataList;
-    }
-
-    /**
-     * Get the list of unique variables names used in the database records.
-     *
-     * @return the list of unique variable names
-     */
-    @Override
-    public List<String> getVariableNames() {
-        final List<String> variableNames = new ArrayList<String>();
-        Statement statement = null;
-        try {
-            statement = connection.createStatement();
-            final ResultSet resultSet = statement.executeQuery(EpicsDataQuery.SELECT_VARIABLE_NAMES);
-            while (resultSet.next()) {
-                variableNames.add(resultSet.getString(1));
-            }
-        } catch (final SQLException e) {
-            throw new RuntimeException(e);
-        } finally {
-            if (statement != null) {
-                try {
-                    statement.close();
-                } catch (final SQLException e) {
-                    e.printStackTrace();
-                }
-            }
-        }
-        return variableNames;
-    }
-
-    /**
-     * Insert a list of EPICS data into the database.
-     * <p>
-     * The run number comes from the header information.
-     *
-     * @param epicsDataList the list of EPICS data
-     */
-    @Override
-    public void insertEpicsData(final List<EpicsData> epicsDataList) {
-        if (epicsDataList.isEmpty()) {
-            throw new IllegalStateException("The EPICS data list is empty.");
-        }
-        PreparedStatement preparedStatement = null;
-        try {
-            preparedStatement = connection.prepareStatement(EpicsDataQuery.INSERT);
-            for (final EpicsData epicsData : epicsDataList) {
-                final EpicsHeader epicsHeader = epicsData.getEpicsHeader();
-                if (epicsHeader == null) {
-                    throw new IllegalArgumentException("The EPICS data is missing header information.");
-                }
-                for (final String variableName : epicsData.getKeys()) {
-                    preparedStatement.setInt(1, epicsData.getEpicsHeader().getRun());
-                    preparedStatement.setInt(2, epicsData.getEpicsHeader().getSequence());
-                    preparedStatement.setInt(3, epicsData.getEpicsHeader().getTimestamp());
-                    preparedStatement.setString(4, variableName);
-                    preparedStatement.setDouble(5, epicsData.getValue(variableName));
-                    preparedStatement.executeUpdate();
-                }
-            }
-        } catch (final SQLException e) {
-            throw new RuntimeException(e);
-        } finally {
-            if (preparedStatement != null) {
-                try {
-                    preparedStatement.close();
-                } catch (final SQLException e) {
-                    e.printStackTrace();
-                }
-            }
-        }
-    }
-
-    /**
-     * Updates EPICS data in the database.
-     *
-     * @param epicsData the EPICS data to update
-     */
-    @Override
-    public void updateEpicsData(final EpicsData epicsData) {
-        PreparedStatement preparedStatement = null;
-        try {
-            preparedStatement = connection.prepareStatement(EpicsDataQuery.UPDATE);
-            final int run = epicsData.getEpicsHeader().getRun();
-            final int sequence = epicsData.getEpicsHeader().getSequence();
-            final int timestamp = epicsData.getEpicsHeader().getTimestamp();
-            for (final String variableName : epicsData.getKeys()) {
-                preparedStatement.setInt(1, run);
-                preparedStatement.setInt(2, sequence);
-                preparedStatement.setInt(3, timestamp);
-                preparedStatement.setString(4, variableName);
-                preparedStatement.setDouble(5, epicsData.getValue(variableName));
-                preparedStatement.setInt(6, run);
-                preparedStatement.setInt(7, sequence);
-                preparedStatement.setString(8, variableName);
-                preparedStatement.executeUpdate();
-            }
-        } catch (final SQLException e) {
-            throw new RuntimeException(e);
-        } finally {
-            try {
-                if (preparedStatement != null) {
-                    preparedStatement.close();
-                }
-            } catch (final SQLException e) {
-                e.printStackTrace();
-            }
-            try {
-                connection.setAutoCommit(true);
-            } catch (final SQLException e) {
-                e.printStackTrace();
+            if (insertHeaderStatement != null) {
+                try {
+                    insertHeaderStatement.close();
+                } catch (final SQLException e) {
+                    e.printStackTrace();
+                }
             }
         }
     }

Added: java/trunk/record-util/src/main/java/org/hps/rundb/EpicsType.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/rundb/EpicsType.java	(added)
+++ java/trunk/record-util/src/main/java/org/hps/rundb/EpicsType.java	Thu Aug 27 18:42:21 2015
@@ -0,0 +1,84 @@
+package org.hps.rundb;
+
+import org.hps.record.epics.EpicsData;
+
+/**
+ * Enum for representing different types of EPICS data in the run database, of which there are currently two (1s and
+ * 10s).
+ *
+ * @author Jeremy McCormick, SLAC
+ */
+public enum EpicsType {
+
+    /**
+     * 10S EPICS data.
+     */
+    EPICS_10S(10),
+    /**
+     * 1S EPICS data.
+     */
+    EPICS_1S(1);
+
+    /**
+     * Get the type from an int.
+     *
+     * @param type the type from an int
+     * @return the type from an int
+     * @throws IllegalArgumentException if <code>type</code> is invalid (not 1 or 10)
+     */
+    public static EpicsType fromInt(final int type) {
+        if (type == EPICS_1S.type) {
+            return EPICS_1S;
+        } else if (type == EPICS_10S.type) {
+            return EPICS_10S;
+        } else {
+            throw new IllegalArgumentException("The type code is invalid (must be 1 or 10): " + type);
+        }
+    }
+
+    /**
+     * Return the type of the EPICS data (1s or 10s).
+     *
+     * @return the type of the EPICS data
+     */
+    public static EpicsType getEpicsType(final EpicsData epicsData) {
+        // FIXME: The type argument should be set on creation which would make this key check unnecessary.
+        if (epicsData.getKeys().contains("MBSY2C_energy")) {
+            return EpicsType.EPICS_1S;
+        } else {
+            return EpicsType.EPICS_10S;
+        }
+    }
+
+    /**
+     * The type encoding (1 or 10).
+     */
+    private int type;
+
+    /**
+     * Create an EPICS type.
+     *
+     * @param type the type encoding (1 or 10)
+     */
+    private EpicsType(final int type) {
+        this.type = type;
+    }
+
+    /**
+     * Get the table name for this type of data.
+     *
+     * @return the table name
+     */
+    public String getTableName() {
+        return this.name().toLowerCase();
+    }
+
+    /**
+     * Get the type encoding.
+     *
+     * @return the type encoding
+     */
+    public int getTypeCode() {
+        return this.type;
+    }
+}

Added: java/trunk/record-util/src/main/java/org/hps/rundb/EpicsVariable.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/rundb/EpicsVariable.java	(added)
+++ java/trunk/record-util/src/main/java/org/hps/rundb/EpicsVariable.java	Thu Aug 27 18:42:21 2015
@@ -0,0 +1,113 @@
+package org.hps.rundb;
+
+/**
+ * Information about an EPICS variable including its name in the EPICS database, column name for the run database,
+ * description of the variable, and type (either 1s or 10s).
+ * <p>
+ * This class is used to represent data from the <i>epics_variables</i> table in the run database.
+ *
+ * @see EpicsType
+ * @see org.hps.rundb.EpicsVariableDao
+ * @see org.hps.rundb.EpicsVariableDaoImpl
+ * @author Jeremy McCormick, SLAC
+ */
+public final class EpicsVariable {
+
+    /**
+     * The name of the variable in the run database.
+     */
+    private final String columnName;
+
+    /**
+     * A description of the variable.
+     */
+    private final String description;
+
+    /**
+     * The name of the variable in the EPICs system.
+     */
+    private final String variableName;
+
+    /**
+     * The type of the variable (1s or 10s).
+     */
+    private final EpicsType variableType;
+
+    /**
+     * Create an EPICs variable.
+     *
+     * @param variableName the name of the variable
+     * @param columnName the column name in the run db
+     * @param description the variable's description
+     * @param variableType the type of the variable
+     */
+    public EpicsVariable(final String variableName, final String columnName, final String description,
+            final EpicsType variableType) {
+        this.variableName = variableName;
+        this.columnName = columnName;
+        this.description = description;
+        this.variableType = variableType;
+    }
+
+    /**
+     * Create an EPICs variable.
+     *
+     * @param variableName the name of the variable
+     * @param columnName the column name in the run db
+     * @param description the variable's description
+     * @param variableType the type of the variable
+     */
+    public EpicsVariable(final String variableName, final String columnName, final String description, final int type) {
+        this.variableName = variableName;
+        this.columnName = columnName;
+        this.description = description;
+        this.variableType = EpicsType.fromInt(type);
+    }
+
+    /**
+     * Get the column name.
+     *
+     * @return the column name
+     */
+    public String getColumnName() {
+        return columnName;
+    }
+
+    /**
+     * Get the variable's description.
+     *
+     * @return the variable's description
+     */
+    public String getDescription() {
+        return description;
+    }
+
+    /**
+     * Get the variable name.
+     *
+     * @return the variable name
+     */
+    public String getVariableName() {
+        return variableName;
+    }
+
+    /**
+     * Get the variable's type.
+     *
+     * @return the variable's type
+     */
+    public EpicsType getVariableType() {
+        return variableType;
+    }
+
+    /**
+     * Return this object converted to a string.
+     *
+     * @return this object converted to a string
+     */
+    @Override
+    public String toString() {
+        return "EpicsVariable { variableName: " + variableName + ", columnName: " + columnName + ", description: "
+                + description + ", variableType: " + variableType.name() + " }";
+    }
+}

Added: java/trunk/record-util/src/main/java/org/hps/rundb/EpicsVariableDao.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/rundb/EpicsVariableDao.java	(added)
+++ java/trunk/record-util/src/main/java/org/hps/rundb/EpicsVariableDao.java	Thu Aug 27 18:42:21 2015
@@ -0,0 +1,26 @@
+package org.hps.rundb;
+
+import java.util.List;
+
+/**
+ * Database interface for EPICS variables.
+ * 
+ * @author Jeremy McCormick, SLAC
+ */
+public interface EpicsVariableDao {
+
+    /**
+     * Get the full list of EPICs variables.
+     * 
+     * @return the full list of EPICS variables
+     */
+    List<EpicsVariable> getEpicsVariables();
+    
+    /**
+     * Get a list of EPICs variables by type.
+     * 
+     * @param variableType the EPICS variable type
+     * @return the list of variables
+     */
+    List<EpicsVariable> getEpicsVariables(EpicsType variableType);
+}

Added: java/trunk/record-util/src/main/java/org/hps/rundb/EpicsVariableDaoImpl.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/rundb/EpicsVariableDaoImpl.java	(added)
+++ java/trunk/record-util/src/main/java/org/hps/rundb/EpicsVariableDaoImpl.java	Thu Aug 27 18:42:21 2015
@@ -0,0 +1,98 @@
+package org.hps.rundb;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Implementation of database interface for EPICS variable information in the run database.
+ *
+ * @author Jeremy McCormick, SLAC
+ */
+final class EpicsVariableDaoImpl implements EpicsVariableDao {
+
+    /**
+     * The database connection.
+     */
+    private final Connection connection;
+
+    /**
+     * Create the object for accessing the db.
+     *
+     * @param connection the database connection
+     */
+    public EpicsVariableDaoImpl(final Connection connection) {
+        this.connection = connection;
+    }
+
+    /**
+     * Get the full list of EPICs variables.
+     *
+     * @return the full list of EPICS variables
+     */
+    @Override
+    public List<EpicsVariable> getEpicsVariables() {
+        final List<EpicsVariable> epicsVariables = new ArrayList<EpicsVariable>();
+        Statement statement = null;
+        try {
+            statement = connection.createStatement();
+            final ResultSet resultSet = statement.executeQuery("SELECT * FROM epics_variables");
+            while (resultSet.next()) {
+                final EpicsVariable epicsVariable = new EpicsVariable(resultSet.getString("variable"),
+                        resultSet.getString("column_name"), resultSet.getString("description"),
+                        resultSet.getInt("epics_type"));
+                epicsVariables.add(epicsVariable);
+            }
+        } catch (final SQLException e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (statement != null) {
+                try {
+                    statement.close();
+                } catch (final SQLException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return epicsVariables;
+    }
+
+    /**
+     * Get a list of EPICs variables by type.
+     *
+     * @param variableType the EPICS variable type
+     * @return the list of variables
+     */
+    @Override
+    public List<EpicsVariable> getEpicsVariables(final EpicsType variableType) {
+        final List<EpicsVariable> epicsVariables = new ArrayList<EpicsVariable>();
+        PreparedStatement preparedStatement = null;
+        try {
+            preparedStatement = connection.prepareStatement("SELECT * FROM epics_variables WHERE epics_type = ?");
+            preparedStatement.setInt(1, variableType.getTypeCode());
+            final ResultSet resultSet = preparedStatement.executeQuery();
+            while (resultSet.next()) {
+                final EpicsVariable epicsVariable = new EpicsVariable(resultSet.getString("variable"),
+                        resultSet.getString("column_name"), resultSet.getString("description"),
+                        resultSet.getInt("epics_type"));
+                epicsVariables.add(epicsVariable);
+            }
+        } catch (final SQLException e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (preparedStatement != null) {
+                try {
+                    preparedStatement.close();
+                } catch (final SQLException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return epicsVariables;
+    }
+
+}

Modified: java/trunk/record-util/src/main/java/org/hps/rundb/EvioFilesDao.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/rundb/EvioFilesDao.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/rundb/EvioFilesDao.java	Thu Aug 27 18:42:21 2015
@@ -4,7 +4,7 @@
 import java.util.List;
 
 /**
- * Database Access Object (DAO) interface to EVIO files in the run database.
+ * Database interface to EVIO files in the run database.
  *
  * @author Jeremy McCormick, SLAC
  */

Modified: java/trunk/record-util/src/main/java/org/hps/rundb/EvioFilesDaoImpl.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/rundb/EvioFilesDaoImpl.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/rundb/EvioFilesDaoImpl.java	Thu Aug 27 18:42:21 2015
@@ -10,11 +10,11 @@
 import java.util.List;
 
 /**
- * Implementation of database operations for EVIO files in the run database.
+ * Implementation of database interface for EVIO files in the run database.
  *
  * @author Jeremy McCormick, SLAC
  */
-public class EvioFilesDaoImpl implements EvioFilesDao {
+final class EvioFilesDaoImpl implements EvioFilesDao {
 
     /**
      * SQL query strings.

Added: java/trunk/record-util/src/main/java/org/hps/rundb/RunDatabaseDaoFactory.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/rundb/RunDatabaseDaoFactory.java	(added)
+++ java/trunk/record-util/src/main/java/org/hps/rundb/RunDatabaseDaoFactory.java	Thu Aug 27 18:42:21 2015
@@ -0,0 +1,94 @@
+package org.hps.rundb;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ * Factory for creating database API objects for interacting with the run database.
+ * <p>
+ * This allows the implementation classes to be package protected as only public interfaces are returned by this class.
+ *
+ * @author Jeremy McCormick, SLAC
+ * @see EpicsDataDao
+ * @see EpicsVariableDao
+ */
+public final class RunDatabaseDaoFactory {
+
+    /**
+     * The database connection.
+     */
+    private final Connection connection;
+
+    /**
+     * Create a new factory.
+     *
+     * @param connection the database connection
+     */
+    public RunDatabaseDaoFactory(final Connection connection) {
+        if (connection == null) {
+            throw new IllegalArgumentException("The connection is null.");
+        }
+        try {
+            if (connection.isClosed()) {
+                throw new IllegalStateException("The connection is closed.");
+            }
+        } catch (final SQLException e) {
+            throw new IllegalStateException("Error when checking connection status.", e);
+        }
+        this.connection = connection;
+    }
+
+    /**
+     * Get the EPICS DAO.
+     *
+     * @return the EPICS DAO
+     */
+    public EpicsDataDao createEpicsDataDao() {
+        return new EpicsDataDaoImpl(connection);
+    }
+
+    /**
+     * Get the EPICS variable DAO.
+     *
+     * @return the EPICS variable DAO
+     */
+    public EpicsVariableDao createEpicsVariableDao() {
+        return new EpicsVariableDaoImpl(connection);
+    }
+
+    /**
+     * Get the EVIO files DAO.
+     *
+     * @return the EVIO files DAO
+     */
+    public EvioFilesDao createEvioFilesDao() {
+        return new EvioFilesDaoImpl(connection);
+    }
+
+    /**
+     * Get the run summary DAO.
+     *
+     * @return the run summary DAO
+     */
+    public RunSummaryDao createRunSummaryDao() {
+        return new RunSummaryDaoImpl(connection);
+    }
+
+    /**
+     * Get the scaler data DAO.
+     *
+     * @return the scaler data DAO
+     */
+    public ScalerDataDao createScalerDataDao() {
+        return new ScalerDataDaoImpl(connection);
+    }
+
+    /**
+     * Get the trigger config DAO.
+     *
+     * @return the trigger config DAO
+     */
+    public TriggerConfigDao createTriggerConfigDao() {
+        return new TriggerConfigDaoImpl(connection);
+    }
+}

Modified: java/trunk/record-util/src/main/java/org/hps/rundb/RunSummary.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/rundb/RunSummary.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/rundb/RunSummary.java	Thu Aug 27 18:42:21 2015
@@ -6,7 +6,7 @@
 
 import org.hps.record.epics.EpicsData;
 import org.hps.record.scalers.ScalerData;
-import org.hps.record.triggerbank.TriggerConfigInt;
+import org.hps.record.triggerbank.TriggerConfig;
 
 /**
  * This is an API for accessing run summary information which is persisted as a row in the <i>runs</i> table of the run
@@ -104,7 +104,7 @@
      *
      * @return the trigger config int values
      */
-    TriggerConfigInt getTriggerConfigInt();
+    TriggerConfig getTriggerConfigInt();
 
     /**
      * Get the start date.

Modified: java/trunk/record-util/src/main/java/org/hps/rundb/RunSummaryDao.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/rundb/RunSummaryDao.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/rundb/RunSummaryDao.java	Thu Aug 27 18:42:21 2015
@@ -3,7 +3,7 @@
 import java.util.List;
 
 /**
- * Data Access Object (DAO) API for managing run summary information in the run database.
+ * Database API for managing basic run summary information in the run database.
  *
  * @author Jeremy McCormick, SLAC
  */

Modified: java/trunk/record-util/src/main/java/org/hps/rundb/RunSummaryDaoImpl.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/rundb/RunSummaryDaoImpl.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/rundb/RunSummaryDaoImpl.java	Thu Aug 27 18:42:21 2015
@@ -12,6 +12,7 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import org.hps.record.epics.EpicsData;
 import org.lcsim.util.log.DefaultLogFormatter;
 import org.lcsim.util.log.LogUtil;
 
@@ -20,7 +21,7 @@
  *
  * @author Jeremy McCormick, SLAC
  */
-public class RunSummaryDaoImpl implements RunSummaryDao {
+final class RunSummaryDaoImpl implements RunSummaryDao {
 
     /**
      * SQL query strings.
@@ -78,11 +79,11 @@
      * The database API for scaler data.
      */
     private ScalerDataDao scalerDataDao = null;
-    
+
     /**
      * The database API for integer trigger config.
      */
-    private TriggerConfigIntDao triggerConfigIntDao = null;
+    private TriggerConfigDao triggerConfigIntDao = null;
 
     /**
      * Create a new DAO object for run summary information.
@@ -100,7 +101,7 @@
         epicsDataDao = new EpicsDataDaoImpl(this.connection);
         scalerDataDao = new ScalerDataDaoImpl(this.connection);
         evioFilesDao = new EvioFilesDaoImpl(this.connection);
-        triggerConfigIntDao = new TriggerConfigIntDaoImpl(this.connection);
+        triggerConfigIntDao = new TriggerConfigDaoImpl(this.connection);
     }
 
     /**
@@ -110,18 +111,19 @@
      */
     @Override
     public void deleteFullRunSummary(final RunSummary runSummary) {
-        
-        int run = runSummary.getRun();
-        
+
+        final int run = runSummary.getRun();
+
         // Delete EPICS log.
-        this.epicsDataDao.deleteEpicsData(run);
+        this.epicsDataDao.deleteEpicsData(EpicsType.EPICS_1S, run);
+        this.epicsDataDao.deleteEpicsData(EpicsType.EPICS_10S, run);
 
         // Delete scaler data.
         this.scalerDataDao.deleteScalerData(run);
 
         // Delete file list.
         this.evioFilesDao.deleteEvioFiles(run);
-        
+
         // Delete trigger config.
         this.triggerConfigIntDao.deleteTriggerConfigInt(run);
 
@@ -392,11 +394,11 @@
         // Insert scaler data.
         LOGGER.info("inserting " + runSummary.getScalerData().size() + " scaler data records");
         scalerDataDao.insertScalerData(runSummary.getScalerData(), runSummary.getRun());
-        
+
         // Insert trigger config.
         LOGGER.info("inserting " + runSummary.getTriggerConfigInt().size() + " trigger config variables");
-        triggerConfigIntDao.insertTriggerConfigInt(runSummary.getTriggerConfigInt(), runSummary.getRun());
-        
+        triggerConfigIntDao.insertTriggerConfig(runSummary.getTriggerConfigInt(), runSummary.getRun());
+
     }
 
     /**
@@ -442,16 +444,19 @@
         final RunSummaryImpl runSummary = (RunSummaryImpl) this.getRunSummary(run);
 
         // Read EPICS data and set on RunSummary.
-        runSummary.setEpicsData(epicsDataDao.getEpicsData(run));
+        final List<EpicsData> epicsDataList = new ArrayList<EpicsData>();
+        epicsDataList.addAll(epicsDataDao.getEpicsData(EpicsType.EPICS_1S, run));
+        epicsDataList.addAll(epicsDataDao.getEpicsData(EpicsType.EPICS_10S, run));
+        runSummary.setEpicsData(epicsDataList);
 
         // Read scaler data and set on RunSummary.
         runSummary.setScalerData(scalerDataDao.getScalerData(run));
 
         // Read EVIO file list and set on RunSummary.
         runSummary.setEvioFiles(evioFilesDao.getEvioFiles(run));
-        
+
         // Read trigger config.
-        runSummary.setTriggerConfigInt(triggerConfigIntDao.getTriggerConfigInt(run));
+        runSummary.setTriggerConfigInt(triggerConfigIntDao.getTriggerConfig(run));
 
         return runSummary;
     }

Modified: java/trunk/record-util/src/main/java/org/hps/rundb/RunSummaryImpl.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/rundb/RunSummaryImpl.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/rundb/RunSummaryImpl.java	Thu Aug 27 18:42:21 2015
@@ -11,7 +11,7 @@
 
 import org.hps.record.epics.EpicsData;
 import org.hps.record.scalers.ScalerData;
-import org.hps.record.triggerbank.TriggerConfigInt;
+import org.hps.record.triggerbank.TriggerConfig;
 
 /**
  * Implementation of {@link RunSummary} for retrieving information from the run database.
@@ -76,7 +76,7 @@
     /**
      * The trigger data for the run.
      */
-    private TriggerConfigInt triggerConfigInt;
+    private TriggerConfig triggerConfigInt;
 
     /**
      * Start date of run.
@@ -207,7 +207,7 @@
      *
      * @return the trigger config of this run
      */
-    public TriggerConfigInt getTriggerConfigInt() {
+    public TriggerConfig getTriggerConfigInt() {
         return triggerConfigInt;
     }
 
@@ -326,7 +326,7 @@
      *
      * @param triggerConfig the trigger config
      */
-    public void setTriggerConfigInt(final TriggerConfigInt triggerConfigInt) {
+    public void setTriggerConfigInt(final TriggerConfig triggerConfigInt) {
         this.triggerConfigInt = triggerConfigInt;
     }
 

Modified: java/trunk/record-util/src/main/java/org/hps/rundb/ScalerDataDaoImpl.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/rundb/ScalerDataDaoImpl.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/rundb/ScalerDataDaoImpl.java	Thu Aug 27 18:42:21 2015
@@ -14,7 +14,7 @@
  *
  * @author Jeremy McCormick, SLAC
  */
-public class ScalerDataDaoImpl implements ScalerDataDao {
+final class ScalerDataDaoImpl implements ScalerDataDao {
 
     /**
      * SQL query strings.

Copied: java/trunk/record-util/src/main/java/org/hps/rundb/TriggerConfigDao.java (from r3424, java/trunk/record-util/src/main/java/org/hps/rundb/TriggerConfigIntDao.java)
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/rundb/TriggerConfigIntDao.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/rundb/TriggerConfigDao.java	Thu Aug 27 18:42:21 2015
@@ -1,13 +1,13 @@
 package org.hps.rundb;
 
-import org.hps.record.triggerbank.TriggerConfigInt;
+import org.hps.record.triggerbank.TriggerConfig;
 
 /**
  * Database interface to trigger config.
  * 
  * @author Jeremy McCormick, SLAC
  */
-public interface TriggerConfigIntDao {
+public interface TriggerConfigDao {
    
     /**
      * Get the trigger config by run.
@@ -15,7 +15,7 @@
      * @param run the run number
      * @return the trigger config
      */
-    TriggerConfigInt getTriggerConfigInt(int run);
+    TriggerConfig getTriggerConfig(int run);
     
     /**
      * Insert a trigger config for a run.
@@ -23,7 +23,7 @@
      * @param run the run number
      * @param triggerConfig the trigger config
      */
-    void insertTriggerConfigInt(TriggerConfigInt triggerConfig, int run);
+    void insertTriggerConfig(TriggerConfig triggerConfig, int run);
    
     /**
      * Delete a trigger config by run number.

Copied: java/trunk/record-util/src/main/java/org/hps/rundb/TriggerConfigDaoImpl.java (from r3424, java/trunk/record-util/src/main/java/org/hps/rundb/TriggerConfigIntDaoImpl.java)
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/rundb/TriggerConfigIntDaoImpl.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/rundb/TriggerConfigDaoImpl.java	Thu Aug 27 18:42:21 2015
@@ -4,58 +4,73 @@
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.util.Map;
 
-import org.hps.record.triggerbank.TriggerConfigInt;
+import org.hps.record.triggerbank.TriggerConfig;
+import org.hps.record.triggerbank.TriggerConfigVariable;
 
 /**
  * Implementation of trigger config database interface.
- * 
+ *
  * @author Jeremy McCormick, SLAC
  */
-public class TriggerConfigIntDaoImpl implements TriggerConfigIntDao {
+final class TriggerConfigDaoImpl implements TriggerConfigDao {
 
     /**
      * The database connection.
      */
-    private Connection connection;
-    
-    /**
-     * SQL query strings.
-     */
-    static final class TriggerConfigQuery {
-        /**
-         * Select by run.
-         */
-        static final String SELECT_RUN = "SELECT * FROM run_trigger_config_int WHERE run = ?";
-        /**
-         * Insert by run.
-         */
-        static final String INSERT_VARIABLE = "INSERT INTO run_trigger_config_int (run, variable_name, value) VALUES (?, ?, ?)";
-        /**
-         * Delete by run.
-         */
-        static final String DELETE_RUN = "DELETE FROM run_trigger_config_int WHERE run = ?";
-    }
-    
+    private final Connection connection;
+
     /**
      * Create a new object.
-     * 
+     *
      * @param connection the database connection
      */
-    TriggerConfigIntDaoImpl(Connection connection) { 
+    TriggerConfigDaoImpl(final Connection connection) {
         this.connection = connection;
     }
 
+    /**
+     * Delete a trigger config by run number.
+     *
+     * @param run the run number
+     */
     @Override
-    public TriggerConfigInt getTriggerConfigInt(int run) {
+    public void deleteTriggerConfigInt(final int run) {
         PreparedStatement preparedStatement = null;
-        TriggerConfigInt triggerConfig = new TriggerConfigInt();
         try {
-            preparedStatement = connection.prepareStatement(TriggerConfigQuery.SELECT_RUN);
-            ResultSet resultSet = preparedStatement.executeQuery();
-            while (resultSet.next()) {
-                triggerConfig.put(resultSet.getString("variable_name"), resultSet.getLong("value"));
+            preparedStatement = connection.prepareStatement("DELETE FROM trigger_config WHERE run = ?");
+            preparedStatement.setInt(1, run);
+            preparedStatement.executeUpdate();
+        } catch (final SQLException e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (preparedStatement != null) {
+                try {
+                    preparedStatement.close();
+                } catch (final SQLException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+    }
+
+    /**
+     * Get the trigger config by run.
+     *
+     * @param run the run number
+     * @return the trigger config
+     */
+    @Override
+    public TriggerConfig getTriggerConfig(final int run) {
+        PreparedStatement preparedStatement = null;
+        final TriggerConfig triggerConfig = new TriggerConfig();
+        try {
+            preparedStatement = connection.prepareStatement("SELECT * FROM trigger_config WHERE run = ?");
+            final ResultSet resultSet = preparedStatement.executeQuery();
+            if (resultSet.next()) {
+                triggerConfig.put(TriggerConfigVariable.TI_TIME_OFFSET,
+                        resultSet.getLong(TriggerConfigVariable.TI_TIME_OFFSET.getColumnName()));
             }
         } catch (final SQLException e) {
             throw new RuntimeException(e);
@@ -69,17 +84,21 @@
         return triggerConfig;
     }
 
+    /**
+     * Insert a trigger config for a run.
+     *
+     * @param run the run number
+     * @param triggerConfig the trigger config
+     */
     @Override
-    public void insertTriggerConfigInt(TriggerConfigInt triggerConfig, int run) {
+    public void insertTriggerConfig(final TriggerConfig triggerConfig, final int run) {
+
         PreparedStatement preparedStatement = null;
         try {
-            preparedStatement = connection.prepareStatement(TriggerConfigQuery.INSERT_VARIABLE);
-            for (Map.Entry<String, Long> entry : triggerConfig.entrySet()) {
-                preparedStatement.setInt(1, run);
-                preparedStatement.setString(2, entry.getKey());
-                preparedStatement.setLong(3, entry.getValue());
-                preparedStatement.executeUpdate();
-            }
+            preparedStatement = connection.prepareStatement("INSERT INTO trigger_config ( "
+                    + TriggerConfigVariable.TI_TIME_OFFSET.getColumnName() + " ) VALUES (?)");
+            preparedStatement.setLong(1, triggerConfig.getTiTimeOffset());
+            preparedStatement.executeUpdate();
         } catch (final SQLException e) {
             throw new RuntimeException(e);
         } finally {
@@ -91,26 +110,6 @@
                 }
             }
         }
-        
+
     }
-
-    @Override
-    public void deleteTriggerConfigInt(int run) {
-        PreparedStatement preparedStatement = null;
-        try {
-            preparedStatement = connection.prepareStatement(TriggerConfigQuery.DELETE_RUN);
-            preparedStatement.setInt(1, run);
-            preparedStatement.executeUpdate();
-        } catch (final SQLException e) {
-            throw new RuntimeException(e);
-        } finally {
-            if (preparedStatement != null) {
-                try {
-                    preparedStatement.close();
-                } catch (final SQLException e) {
-                    e.printStackTrace();
-                }
-            }
-        }                
-    }   
 }

Modified: java/trunk/record-util/src/main/java/org/hps/rundb/package-info.java
 =============================================================================
--- java/trunk/record-util/src/main/java/org/hps/rundb/package-info.java	(original)
+++ java/trunk/record-util/src/main/java/org/hps/rundb/package-info.java	Thu Aug 27 18:42:21 2015
@@ -1,4 +1,4 @@
 /**
- * API for accessing the HPS run database with run summary information.
+ * API for accessing the HPS run database.
  */
 package org.hps.rundb;