Author: [log in to unmask]
Date: Fri Jun 5 17:09:45 2015
New Revision: 3102
Log:
Updates and cleanup to EVIO file crawler in preparation for running at JLAB; improved the time stamp arguments to allow a date to be supplied for cut off; reorganized the database update classes.
Added:
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunSummaryUpdater.java
Modified:
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/DateFileFilter.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EpicsLog.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EventTypeLog.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileCrawler.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileFilter.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileList.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileSequenceComparator.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileUtilities.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileVisitor.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/JCacheManager.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunFilter.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunLog.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunLogUpdater.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunProcessor.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunSummary.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/package-info.java
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/DateFileFilter.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/DateFileFilter.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/DateFileFilter.java Fri Jun 5 17:09:45 2015
@@ -12,7 +12,7 @@
* <p>
* Files with a creation date after the time stamp will be rejected.
*
- * @author Jeremy McCormick
+ * @author Jeremy McCormick, SLAC
*/
final class DateFileFilter implements FileFilter {
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EpicsLog.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EpicsLog.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EpicsLog.java Fri Jun 5 17:09:45 2015
@@ -11,7 +11,7 @@
/**
* Create a summary log of EPICS information found in EVIO events.
*
- * @author Jeremy McCormick
+ * @author Jeremy McCormick, SLAC
*/
final class EpicsLog extends EvioEventProcessor {
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EventTypeLog.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EventTypeLog.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EventTypeLog.java Fri Jun 5 17:09:45 2015
@@ -11,7 +11,7 @@
/**
* This class makes a log of the number of different event types found in a run by their tag value.
*
- * @author Jeremy McCormick
+ * @author Jeremy McCormick, SLAC
*/
final class EventTypeLog extends EvioEventProcessor {
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileCrawler.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileCrawler.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileCrawler.java Fri Jun 5 17:09:45 2015
@@ -5,6 +5,7 @@
import java.nio.file.FileVisitOption;
import java.nio.file.Files;
import java.nio.file.attribute.BasicFileAttributes;
+import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashSet;
@@ -24,11 +25,14 @@
* Crawls EVIO files in a directory tree, groups the files that are found by run, and optionally performs various tasks based on the run summary
* information that is accumulated, including printing a summary, caching the files from JLAB MSS, and updating a run database.
*
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
*/
-// TODO: write out Auger XML (and don't actually execute job)
-// TODO: write summary EVIO file with control/EPICS events (maybe?)
-// TODO: flag to allow overwriting existing information in run table
+// TODO: need options for...
+// -database connections prop file
+// -writing Auger XML for crawl job (and don't actually execute job)
+// -writing out a summary EVIO file containing control events only (PRESTART, EPICS, scalars?, END)
+// -allow overwriting existing information in run table rather than inserting
+// -get supplementary information from run spreadsheet (including whether run was "JUNK" or not)
public final class EvioFileCrawler {
/**
@@ -45,23 +49,27 @@
* Command line options for the crawler.
*/
private static final Options OPTIONS = new Options();
+
+ private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/**
* Statically define the command options.
*/
static {
+ OPTIONS.addOption("a", "accept-runs", true, "list of run numbers to accept (others will be excluded)");
+ OPTIONS.addOption("b", "begin-date", true, "min date for files (example 2015-03-26 11:28:59)");
+ OPTIONS.addOption("c", "cache-files", false, "automatically cache files from MSS (JLAB only)");
+ OPTIONS.addOption("d", "directory", true, "root directory to start crawling (default is current dir)");
+ OPTIONS.addOption("e", "epics", false, "process EPICS data found in EVIO files");
OPTIONS.addOption("h", "help", false, "print help and exit");
- OPTIONS.addOption("t", "timestamp-file", true, "timestamp file for date filtering; modified time will be set at end of job");
- OPTIONS.addOption("d", "directory", true, "starting directory");
- OPTIONS.addOption("r", "runs", true, "list of runs to accept (others will be excluded)");
- OPTIONS.addOption("s", "summary", false, "print run summary at end of job");
- OPTIONS.addOption("L", "log-level", true, "set log level (INFO, FINE, etc.)");
- OPTIONS.addOption("u", "update", false, "update the run database");
- OPTIONS.addOption("e", "epics", false, "process EPICS data");
- OPTIONS.addOption("c", "cache", false, "automatically cache all files from MSS");
- OPTIONS.addOption("w", "wait", true, "total time in seconds to allow for file caching");
- OPTIONS.addOption("m", "max-files", true, "maximum number of files to accept per run (for debugging)");
- OPTIONS.addOption("p", "print", true, "set event printing interval when running EVIO processors");
+ OPTIONS.addOption("m", "max-files", true, "max number of files to process per run (only for debugging)");
+ OPTIONS.addOption("p", "print", true, "set event print interval during EVIO processing");
+ OPTIONS.addOption("r", "insert-run-log", false, "update the run database (not done by default)");
+ OPTIONS.addOption("t", "timestamp-file", true, "existing or new timestamp file name for date cut off");
+ OPTIONS.addOption("s", "print-summary", false, "print run summary at the end of the job");
+ OPTIONS.addOption("w", "max-cache-wait", true, "total seconds to allow for file caching");
+ OPTIONS.addOption("L", "log-level", true, "set the log level (INFO, FINE, etc.)");
+ OPTIONS.addOption("u", "update-run-log", false, "allow overriding existing data in the run db (not allowed by default)");
}
/**
@@ -83,7 +91,7 @@
private final Set<Integer> acceptRuns = new HashSet<Integer>();
/**
- * The class for managing the file caching using the jcache command.
+ * The class for managing the file caching using the 'jcache' command.
*/
private final JCacheManager cacheManager = new JCacheManager();
@@ -135,7 +143,7 @@
/**
* Flag indicating if the run database should be updated from results of the job.
*/
- private boolean update = false;
+ private boolean updateRunLog = false;
/**
* Flag indicating if the file cache should be used (e.g. jcache automatically executed to move files to the cache disk from tape).
@@ -146,6 +154,8 @@
* The maximum wait time in milliseconds to allow for file caching operations.
*/
private Long waitTime;
+
+ private boolean allowUpdates = false;
/**
* Create the processor for a single run.
@@ -202,18 +212,26 @@
if (cl.hasOption("t")) {
this.timestampFile = new File(cl.getOptionValue("t"));
if (!this.timestampFile.exists()) {
- throw new IllegalArgumentException("The timestamp file does not exist: " + this.timestampFile.getPath());
- }
- try {
- this.timestamp = new Date(Files.readAttributes(this.timestampFile.toPath(), BasicFileAttributes.class).lastModifiedTime()
- .toMillis());
- } catch (final IOException e) {
- throw new RuntimeException("Error getting attributes of timestamp file.", e);
- }
- }
-
- if (cl.hasOption("r")) {
- for (final String runString : cl.getOptionValues("r")) {
+ try {
+ // Create new time stamp file.
+ LOGGER.info("creating new timestamp file " + this.timestampFile.getPath());
+ this.timestampFile.createNewFile();
+ } catch (IOException e) {
+ throw new IllegalArgumentException("Error creating timestamp file " + this.timestampFile.getPath());
+ }
+ } else {
+ try {
+ // Get cut-off date for files from existing time stamp file.
+ this.timestamp = new Date(Files.readAttributes(this.timestampFile.toPath(), BasicFileAttributes.class).lastModifiedTime().toMillis());
+ LOGGER.info("got timestamp " + this.timestamp + " from existing file " + this.timestampFile.getPath());
+ } catch (final IOException e) {
+ throw new RuntimeException("Error getting attributes of timestamp file.", e);
+ }
+ }
+ }
+
+ if (cl.hasOption("a")) {
+ for (final String runString : cl.getOptionValues("a")) {
final Integer acceptRun = Integer.parseInt(runString);
this.acceptRuns.add(acceptRun);
LOGGER.config("added accept run " + acceptRun);
@@ -224,8 +242,8 @@
this.printSummary = true;
}
- if (cl.hasOption("u")) {
- this.update = true;
+ if (cl.hasOption("r")) {
+ this.updateRunLog = true;
}
if (cl.hasOption("e")) {
@@ -250,7 +268,26 @@
if (cl.hasOption("p")) {
this.eventPrintInterval = Integer.parseInt(cl.getOptionValue("p"));
}
-
+
+ if (cl.hasOption("u")) {
+ this.allowUpdates = true;
+ if (!this.updateRunLog) {
+ LOGGER.info("the -u option is ignored because run_log is not being updated");
+ }
+ }
+
+ if (cl.hasOption("b")) {
+ try {
+ if (this.timestamp != null) {
+ LOGGER.warning("existing timestamp from file " + this.timestamp + " will be overridden by date from -b argument");
+ }
+ this.timestamp = DATE_FORMAT.parse(cl.getOptionValue("b"));
+ LOGGER.info("set timestamp to " + DATE_FORMAT.format(this.timestamp));
+ } catch (java.text.ParseException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
} catch (final ParseException e) {
throw new RuntimeException("Error parsing options.", e);
}
@@ -343,9 +380,9 @@
}
// Insert run information into the database.
- if (this.update) {
+ if (this.updateRunLog) {
// Update run log.
- new RunLogUpdater(runs).insert();
+ new RunLogUpdater(runs, allowUpdates).insert();
}
// Update the timestamp file which can be used to tell which files have been processed.
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileFilter.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileFilter.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileFilter.java Fri Jun 5 17:09:45 2015
@@ -7,7 +7,7 @@
* This is a simple file filter that will accept EVIO files with a certain convention to their naming which looks like <i>FILENAME.evio.SEQUENCE</i>.
* This matches the convention used by the CODA DAQ software.
*
- * @author Jeremy McCormick
+ * @author Jeremy McCormick, SLAC
*/
final class EvioFileFilter implements FileFilter {
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileList.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileList.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileList.java Fri Jun 5 17:09:45 2015
@@ -14,7 +14,7 @@
* This is a list of <code>File</code> objects that are assumed to be EVIO files. There are some added utilities for getting the total number of
* events in all the files.
*
- * @author Jeremy McCormick
+ * @author Jeremy McCormick, SLAC
*/
final class EvioFileList extends ArrayList<File> {
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileSequenceComparator.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileSequenceComparator.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileSequenceComparator.java Fri Jun 5 17:09:45 2015
@@ -6,7 +6,7 @@
/**
* Compare two EVIO files by their sequence numbers.
*
- * @author Jeremy McCormick
+ * @author Jeremy McCormick, SLAC
*/
final class EvioFileSequenceComparator implements Comparator<File> {
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileUtilities.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileUtilities.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileUtilities.java Fri Jun 5 17:09:45 2015
@@ -16,7 +16,7 @@
/**
* A miscellaneous collection of EVIO file utility methods used by classes in the crawler package.
*
- * @author Jeremy McCormick
+ * @author Jeremy McCormick, SLAC
*/
final class EvioFileUtilities {
@@ -31,10 +31,10 @@
private static final long MILLISECONDS = 1000L;
/**
- * Get a cached file path assuming that the input file is on the JLAB MSS.
+ * Get a cached file path, assuming that the input file path is on the JLAB MSS e.g. it starts with "/mss".
*
* @param file the MSS file path
- * @return the cached file path
+ * @return the cached file path (prepends "/cache" to the path)
* @throws IllegalArgumentException if the file is not on the MSS (e.g. path does not start with "/mss")
*/
static File getCachedFile(final File file) {
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileVisitor.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileVisitor.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileVisitor.java Fri Jun 5 17:09:45 2015
@@ -16,9 +16,11 @@
import org.lcsim.util.log.LogUtil;
/**
- * A file visitor that crawls directories looking for EVIO files.
+ * A file visitor that crawls directories for EVIO files.
+ * <p>
+ * It updates a run log to keep track of which files are associated with which run numbers.
*
- * @author Jeremy McCormick
+ * @author Jeremy McCormick, SLAC
*/
final class EvioFileVisitor extends SimpleFileVisitor<Path> {
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/JCacheManager.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/JCacheManager.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/JCacheManager.java Fri Jun 5 17:09:45 2015
@@ -22,29 +22,27 @@
/**
* Utility class for using the <i>jcache</i> command at JLAB.
*
- * @author Jeremy McCormick
+ * @author Jeremy McCormick, SLAC
*/
final class JCacheManager {
/**
* Keeps track of cache status for a single file.
- *
- * @author Jeremy McCormick
*/
static class CacheStatus {
/**
- * Flag indicating if file is cached yet.
+ * Flag indicating if the file is cached yet.
*/
private boolean cached = false;
/**
- * Path to the file on the MSS (not the cached path).
+ * Path to the file on the MSS.
*/
private File file = null;
/**
- * The request ID from the 'jcache submit' command.
+ * The request ID from executing the 'jcache submit' command.
*/
private Integer requestId = null;
@@ -301,7 +299,7 @@
/**
* Submit cache request for every file in a list.
*
- * @param files
+ * @param files the list of files
*/
void cache(final List<File> files) {
for (final File file : files) {
@@ -354,7 +352,7 @@
}
/**
- * Clear all cache statuses.
+ * Clear all cache statuses, which means files are no longer tracked by this manager.
*/
void clear() {
this.cacheStatuses.clear();
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunFilter.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunFilter.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunFilter.java Fri Jun 5 17:09:45 2015
@@ -7,7 +7,7 @@
/**
* A filter which rejects files that have a run number not in the accept list.
*
- * @author Jeremy McCormick
+ * @author Jeremy McCormick, SLAC
*/
final class RunFilter implements FileFilter {
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunLog.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunLog.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunLog.java Fri Jun 5 17:09:45 2015
@@ -16,7 +16,7 @@
* <p>
* This class is able to update the run database using the <code>insert</code> methods.
*
- * @author Jeremy McCormick
+ * @author Jeremy McCormick, SLAC
*/
final class RunLog {
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunLogUpdater.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunLogUpdater.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunLogUpdater.java Fri Jun 5 17:09:45 2015
@@ -1,11 +1,7 @@
package org.hps.record.evio.crawler;
-import java.io.File;
import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
import java.sql.SQLException;
-import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -15,7 +11,7 @@
/**
* Updates the run database with run log information from crawler job.
*
- * @author Jeremy McCormick
+ * @author Jeremy McCormick, SLAC
*/
public class RunLogUpdater {
@@ -24,11 +20,13 @@
*/
private static final Logger LOGGER = LogUtil.create(RunLogUpdater.class);
- RunLog runLog;
+ private RunLog runLog;
- final Connection connection;
+ private final Connection connection;
+
+ private boolean allowUpdates = false;
- RunLogUpdater(RunLog runLog) {
+ RunLogUpdater(RunLog runLog, boolean allowUpdates) {
this.runLog = runLog;
// Create database connection to use in this session.
@@ -43,36 +41,66 @@
e.printStackTrace();
}
}
-
- boolean hasRun(int run) {
- boolean hasRun = false;
- PreparedStatement statement = null;
- try {
- statement = connection.prepareStatement("SELECT run from run_log where run = ?");
- statement.setInt(1, run);
- ResultSet rs = statement.executeQuery();
- if (rs.next()) hasRun = true;
- } catch (final SQLException e) {
- throw new RuntimeException(e);
- }
- return hasRun;
- }
/**
- * Insert all the information from the run log into the run database.
+ * Insert the run summary information into the database.
+ *
+ * @param connection the database connection
+ * @throws SQLException if there is an error querying the database
*/
- void insert() {
-
+ void insert() throws SQLException {
+
LOGGER.info("inserting runs into run_log ...");
try {
connection.setAutoCommit(false);
- this.insertRunLog(connection);
+ // Update or insert a row for every run found.
+ for (final Integer run : runLog.getSortedRunNumbers()) {
+
+ RunSummary runSummary = runLog.getRunSummary(run);
+
+ LOGGER.info("updating " + runSummary);
+
+ RunSummaryUpdater updater = new RunSummaryUpdater(connection, runSummary);
+
+ // Does a row already exist for run?
+ if (updater.runLogExists()) {
+ LOGGER.info("record for " + run + " exists already");
+ // Are updates allowed?
+ if (allowUpdates) {
+ LOGGER.info("updating existing row in run_log for " + run);
+ // Update existing row.
+ updater.updateRunLog();
+ } else {
+ // Row exists and updates not allowed which is an error.
+ throw new RuntimeException("Row already exists for run " + run + " and allowUpdates is false");
+ }
+ } else {
+
+ LOGGER.info("inserting new row in run_log for " + run);
+
+ // Insert new record into run_log.
+ updater.insertRunLog();
+ }
- this.insertFiles(connection);
-
- connection.commit();
-
+ boolean fileLogExists = updater.fileLogExists();
+
+ // Are updates disallowed and file log exists?
+ if (!allowUpdates && fileLogExists) {
+ // File records exist but updates not allowed so this is an error.
+ throw new RuntimeException("Cannot delete existing file records because allowUpdates is false");
+ }
+
+ // Delete existing file log.
+ if (fileLogExists) {
+ // Delete the file log.
+ updater.deleteFileLog();
+ }
+
+ // Insert the file log.
+ updater.insertFileLog();
+ }
+
} catch (final SQLException e) {
LOGGER.log(Level.SEVERE, "rolling back transaction", e);
try {
@@ -83,69 +111,10 @@
} finally {
try {
connection.setAutoCommit(true);
+ connection.close();
} catch (final SQLException e) {
throw new RuntimeException(e);
- }
+ }
}
- }
-
- /**
- * Insert the file lists into the run database.
- *
- * @param connection the database connection
- * @throws SQLException if there is an error executing the SQL query
- */
- private void insertFiles(final Connection connection) throws SQLException {
- for (final int run : runLog.getSortedRunNumbers()) {
- insertFiles(connection, run, runLog.getRunSummary(run).getEvioFileList());
- }
- }
-
- /**
- * Insert the run summary information into the database.
- *
- * @param connection the database connection
- * @throws SQLException if there is an error querying the database
- */
- private void insertRunLog(final Connection connection) throws SQLException {
- PreparedStatement runLogStatement = null;
- runLogStatement = connection
- .prepareStatement("INSERT INTO run_log (run, start_date, end_date, nevents, nfiles, end_ok, last_updated) VALUES(?, ?, ?, ?, ?, ?, NOW())");
- for (final Integer run : runLog.getSortedRunNumbers()) {
- LOGGER.info("preparing to insert run " + run + " into database ..");
- final RunSummary runSummary = runLog.getRunSummary(run);
- runLogStatement.setInt(1, run);
- runLogStatement.setTimestamp(2, new java.sql.Timestamp(runSummary.getStartDate().getTime()));
- runLogStatement.setTimestamp(3, new java.sql.Timestamp(runSummary.getEndDate().getTime()));
- runLogStatement.setInt(4, runSummary.getTotalEvents());
- runLogStatement.setInt(5, runSummary.getEvioFileList().size());
- runLogStatement.setBoolean(6, runSummary.isEndOkay());
- runLogStatement.executeUpdate();
- LOGGER.info("committed run " + run + " to run_log");
- }
- LOGGER.info("run_log was updated!");
- }
-
- /**
- * Insert the file names into the run database.
- *
- * @param connection the database connection
- * @param run the run number
- * @throws SQLException if there is a problem executing one of the database queries
- */
- void insertFiles(final Connection connection, final int run, List<File> files) throws SQLException {
- LOGGER.info("updating file list ...");
- PreparedStatement filesStatement = null;
- filesStatement = connection.prepareStatement("INSERT INTO run_log_files (run, directory, name) VALUES(?, ?, ?)");
- LOGGER.info("inserting files from run " + run + " into database");
- for (final File file : files) {
- LOGGER.info("creating update statement for " + file.getPath());
- filesStatement.setInt(1, run);
- filesStatement.setString(2, file.getParentFile().getPath());
- filesStatement.setString(3, file.getName());
- LOGGER.info("executing statement: " + filesStatement);
- filesStatement.executeUpdate();
- }
- LOGGER.info("run_log_files was updated!");
- }
+ }
}
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunProcessor.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunProcessor.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunProcessor.java Fri Jun 5 17:09:45 2015
@@ -24,7 +24,7 @@
* <p>
* There is also a list of processors which is run on all events from the run, if the processor list is not empty.
*
- * @author Jeremy McCormick
+ * @author Jeremy McCormick, SLAC
*/
final class RunProcessor {
@@ -120,7 +120,8 @@
List<File> files = this.runSummary.getEvioFileList();
if (this.maxFiles != -1) {
LOGGER.info("limiting processing to first " + this.maxFiles + " files from max files setting");
- files = files.subList(0, this.maxFiles - 1);
+ files = files.subList(0, this.maxFiles);
+ LOGGER.info("using file list with size " + files.size());
}
return files;
}
@@ -195,7 +196,6 @@
* @throws IOException if there is some kind of IO error
* @throws Exception if there is a generic error thrown by event processing
*/
- // FIXME: I think this method is terribly inefficient right now.
private void process(final File file) throws EvioException, IOException, Exception {
LOGGER.fine("processing " + file.getPath() + " ...");
@@ -240,7 +240,6 @@
// Check if END event is present if this is the last file in the run.
if (file.equals(this.runSummary.getEvioFileList().last())) {
- LOGGER.info("checking end okay ...");
final boolean endOkay = this.isEndOkay(reader);
this.runSummary.setEndOkay(endOkay);
LOGGER.info("endOkay set to " + endOkay);
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunSummary.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunSummary.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunSummary.java Fri Jun 5 17:09:45 2015
@@ -10,7 +10,8 @@
import org.lcsim.util.log.LogUtil;
/**
- * This class models the run summary information which is persisted as one record in the <i>run_log</i> table.
+ * This class models the run summary information which is persisted as a row in the <i>run_log</i> table
+ * of the run database.
* <p>
* This information includes:
* <ul>
@@ -20,9 +21,10 @@
* <li>total number of events across all files in the run</li>
* <li>number of files found belonging to the run</li>
* <li>whether the EVIO END event was found</li>
+ * <li>whether the run is considered good</li>
* </ul>
*
- * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ * @author Jeremy McCormick, SLAC
*/
final class RunSummary {
@@ -245,4 +247,9 @@
void sortFiles() {
this.files.sort();
}
+
+ public String toString() {
+ return "RunSummary { run: " + this.run + ", started: " + this.getStartDate() + ", ended: " + this.getEndDate() + ", events: "
+ + this.getTotalEvents() + ", endOkay: " + endOkay + " }";
+ }
}
Added: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunSummaryUpdater.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunSummaryUpdater.java (added)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunSummaryUpdater.java Fri Jun 5 17:09:45 2015
@@ -0,0 +1,181 @@
+package org.hps.record.evio.crawler;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.lcsim.util.log.LogUtil;
+
+/**
+ * Utilities for updating or insert a run summary row into the run_log table.
+ *
+ * @author Jeremy McCormick, SLAC
+ */
+public class RunSummaryUpdater {
+
+ /**
+ * Setup logging.
+ */
+ private static final Logger LOGGER = LogUtil.create(RunSummaryUpdater.class);
+
+ /**
+ * The run summary to update or insert.
+ */
+ private RunSummary runSummary;
+
+ /**
+ * The database connection.
+ */
+ private Connection connection;
+
+ /**
+ * The run number (read from the summary in the constructor for convenience).
+ */
+ private int run = -1;
+
+ /**
+ * Create a <code>RunSummaryUpdater</code> for the given <code>RunSummary</code>.
+ *
+ * @param connection the database connection
+ * @param runSummary the run summary to update or insert
+ */
+ RunSummaryUpdater(Connection connection, RunSummary runSummary) {
+
+ if (connection == null) {
+ throw new IllegalArgumentException("connection is null");
+ }
+ this.connection = connection;
+
+ if (runSummary == null) {
+ throw new IllegalArgumentException("runSummary is null");
+ }
+ this.runSummary = runSummary;
+
+ this.run = this.runSummary.getRun();
+ }
+
+ /**
+ * Execute a SQL update to modify an existing row in the database.
+ *
+ * @throws SQLException if there is an error executing the SQL statement
+ */
+ void updateRunLog() throws SQLException {
+
+ PreparedStatement runLogStatement = null;
+ runLogStatement =
+ connection.prepareStatement("UPDATE run_log SET start_date = ?, end_date = ?, nevents = ?, nfiles = ?, end_ok = ? where run = ?");
+ LOGGER.info("preparing to update run " + run + " in run_log ..");
+ runLogStatement.setTimestamp(1, new java.sql.Timestamp(runSummary.getStartDate().getTime()));
+ runLogStatement.setTimestamp(2, new java.sql.Timestamp(runSummary.getEndDate().getTime()));
+ runLogStatement.setInt(3, runSummary.getTotalEvents());
+ runLogStatement.setInt(4, runSummary.getEvioFileList().size());
+ runLogStatement.setBoolean(5, runSummary.isEndOkay());
+ runLogStatement.setInt(6, run);
+ runLogStatement.executeUpdate();
+ connection.commit();
+ LOGGER.info("run " + run + " was updated in run_log");
+ }
+
+ /**
+ * Insert a new row in the run_log table.
+ *
+ * @param connection the database connection
+ * @throws SQLException if there is an error querying the database
+ */
+ void insertRunLog() throws SQLException {
+ PreparedStatement statement =
+ connection.prepareStatement("INSERT INTO run_log (run, start_date, end_date, nevents, nfiles, end_ok) VALUES(?, ?, ?, ?, ?, ?)");
+ LOGGER.info("preparing to insert run " + run + " into run_log ..");
+ statement.setInt(1, run);
+ statement.setTimestamp(2, new java.sql.Timestamp(runSummary.getStartDate().getTime()));
+ statement.setTimestamp(3, new java.sql.Timestamp(runSummary.getEndDate().getTime()));
+ statement.setInt(4, runSummary.getTotalEvents());
+ statement.setInt(5, runSummary.getEvioFileList().size());
+ statement.setBoolean(6, runSummary.isEndOkay());
+ statement.executeUpdate();
+ connection.commit();
+ LOGGER.info("insert run " + run + " to run_log");
+ }
+
+ /**
+ * Return <code>true</code> if there is an existing row for this run summary.
+ *
+ * @return <code>true</code> if there is an existing row for this run summary.
+ * @throws SQLException if there is an error executing the SQL query
+ */
+ boolean runLogExists() throws SQLException {
+ PreparedStatement s = connection.prepareStatement("SELECT run from run_log where run = ?");
+ s.setInt(1, run);
+ ResultSet rs = s.executeQuery();
+ return rs.first();
+ }
+
+ /**
+ * Insert the file names into the run database.
+ *
+ * @param connection the database connection
+ * @param run the run number
+ * @throws SQLException if there is a problem executing one of the database queries
+ */
+ void insertFileLog() throws SQLException {
+ LOGGER.info("updating file list ...");
+ PreparedStatement filesStatement = null;
+ filesStatement = connection.prepareStatement("INSERT INTO run_log_files (run, directory, name) VALUES(?, ?, ?)");
+ LOGGER.info("inserting files from run " + run + " into database");
+ for (final File file : runSummary.getEvioFileList()) {
+ LOGGER.info("creating update statement for " + file.getPath());
+ filesStatement.setInt(1, run);
+ filesStatement.setString(2, file.getParentFile().getPath());
+ filesStatement.setString(3, file.getName());
+ LOGGER.info("executing statement: " + filesStatement);
+ filesStatement.executeUpdate();
+ }
+ connection.commit();
+ LOGGER.info("run_log_files was updated!");
+ }
+
+ /**
+ * Delete the records of the files associated to this run.
+ *
+ * @param files the list of files
+ * @throws SQLException if there is an error executing the SQL query
+ */
+ void deleteFileLog() throws SQLException {
+ LOGGER.info("deleting run_log_files for " + run + " ...");
+ PreparedStatement s = connection.prepareStatement("DELETE FROM run_log_files where run = ?");
+ s.setInt(1, run);
+ s.executeUpdate();
+ connection.commit();
+ LOGGER.info("done deleting run_log_files for " + run);
+ }
+
+ /**
+ * Delete the row for this run from the run_log table.
+ *
+ * @throws SQLException if there is an error executing the SQL query
+ */
+ void deleteRunLog() throws SQLException {
+ LOGGER.info("deleting run_log for " + run + " ...");
+ PreparedStatement s = connection.prepareStatement("DELETE FROM run_log where run = ?");
+ s.setInt(1, run);
+ s.executeUpdate();
+ connection.commit();
+ LOGGER.info("done deleting run_log_files for " + run);
+ }
+
+ /**
+ * Return <code>true</code> if there is a row for at least one file for the run.
+ * @return <code>true</code> if there are file rows for this run
+ * @throws SQLException if there is an error executing the SQL query
+ */
+ boolean fileLogExists() throws SQLException {
+ PreparedStatement s = connection.prepareStatement("SELECT run FROM run_log_files where run = ?");
+ s.setInt(1, run);
+ ResultSet rs = s.executeQuery();
+ return rs.first();
+ }
+}
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/package-info.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/package-info.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/package-info.java Fri Jun 5 17:09:45 2015
@@ -1,6 +1,6 @@
/**
* Implements an EVIO file crawler for extracting run and configuration information, including run start and end dates, event counts, etc.
*
- * @author Jeremy McCormick
+ * @author Jeremy McCormick, SLAC
*/
package org.hps.record.evio.crawler;
|