/** Read all PeMS data in the given time range at the given VDS. */
  public PeMSProfile read(Interval interval, Long vdsId) throws DatabaseException {
    PeMSProfile profile;
    String pemsIdStr = "pems.{vds_id=" + vdsId + ", interval=" + interval + "}";

    long timeBegin = System.nanoTime();

    try {
      dbr.transactionBegin();
      Monitor.debug("PeMS reader transaction beginning on " + pemsIdStr);

      profile = readProfile(interval, vdsId);

      dbr.transactionCommit();
      Monitor.debug("PeMS reader transaction committing on " + pemsIdStr);
    } catch (DatabaseException dbExc) {
      Monitor.err(dbExc);
      throw dbExc;
    } finally {
      try {
        dbr.transactionRollback();
        Monitor.debug("PeMS reader transaction rollback on " + pemsIdStr);
      } catch (Exception Exc) {
        // Do nothing.
      }
    }

    long timeCommit = System.nanoTime();
    if (profile != null) {
      Monitor.duration("Read " + pemsIdStr, timeCommit - timeBegin);
    }

    return profile;
  }
  /**
   * Read one node with the given ID from the database.
   *
   * @param nodeID ID of the node in the database
   * @param networkID ID of the network
   * @return Node
   */
  public Node read(long nodeID, long networkID) throws DatabaseException {
    Node node;
    String nodeIdStr = "node.{id=" + nodeID + ", network_id=" + networkID + "}";

    long timeBegin = System.nanoTime();

    try {
      dbr.transactionBegin();
      Monitor.debug("Node reader transaction beginning on " + nodeIdStr);

      node = readWithAssociates(nodeID, networkID);

      dbr.transactionCommit();
      Monitor.debug("Node reader transaction committing on " + nodeIdStr);
    } catch (DatabaseException dbExc) {
      Monitor.err(dbExc);
      throw dbExc;
    } finally {
      try {
        dbr.transactionRollback();
        Monitor.debug("Node reader transaction rollback on " + nodeIdStr);
      } catch (Exception Exc) {
        // Do nothing.
      }
    }

    long timeCommit = System.nanoTime();
    if (node != null) {
      Monitor.duration("Read " + nodeIdStr, timeCommit - timeBegin);
    }

    return node;
  }
  /**
   * Read all PeMS aggregate data in the given time range, having a VDS ID in the given list, and at
   * the given aggregation level. List is sorted by time.
   */
  public List<PeMSStationAggregate> read(
      Interval interval, List<Long> vdsIds, PeMSAggregate.AggregationLevel level)
      throws DatabaseException {

    List<PeMSStationAggregate> list;

    String pemsIdStr =
        "pems.{vds_id=["
            + vdsIds.get(0)
            + ","
            + vdsIds.get(1)
            + ",...], interval="
            + interval
            + ", level="
            + level
            + "}";

    long timeBegin = System.nanoTime();

    try {
      dbr.transactionBegin();
      Monitor.debug("PeMS aggregate reader transaction beginning on " + pemsIdStr);

      list = readList(interval, vdsIds, level);

      dbr.transactionCommit();
      Monitor.debug("PeMS aggregate reader transaction committing on " + pemsIdStr);
    } catch (DatabaseException dbExc) {
      Monitor.err(dbExc);
      throw dbExc;
    } finally {
      try {
        dbr.transactionRollback();
        Monitor.debug("PeMS aggregate reader transaction rollback on " + pemsIdStr);
      } catch (Exception Exc) {
        // Do nothing.
      }
    }

    long timeCommit = System.nanoTime();
    if (list != null) {
      Monitor.duration("Read " + pemsIdStr, timeCommit - timeBegin);
    }

    return list;
  }
  /** Read all PeMS data in the given time range and having a VDS ID in the given list. */
  public PeMSSet read(Interval interval, List<Long> vdsIds) throws DatabaseException {
    PeMSSet set = null;

    String pemsIdStr =
        "pems.{vds_id=["
            + vdsIds.get(0)
            + ","
            + vdsIds.get(1)
            + ",...], interval="
            + interval
            + "}";

    long timeBegin = System.nanoTime();

    try {
      dbr.transactionBegin();
      Monitor.debug("PeMS reader transaction beginning on " + pemsIdStr);

      set = readSet(interval, vdsIds);

      dbr.transactionCommit();
      Monitor.debug("PeMS reader transaction committing on " + pemsIdStr);
    } catch (DatabaseException dbExc) {
      Monitor.err(dbExc);
      throw dbExc;
    } finally {
      try {
        dbr.transactionRollback();
        Monitor.debug("PeMS reader transaction rollback on " + pemsIdStr);
      } catch (Exception Exc) {
        // Do nothing.
      }
    }

    long timeCommit = System.nanoTime();
    if (set != null) {
      Monitor.duration("Read " + pemsIdStr, timeCommit - timeBegin);
    }

    return set;
  }