private void initFromDatabase() throws SQLException, BlockStoreException {
    Statement s = conn.get().createStatement();
    ResultSet rs;

    rs = s.executeQuery("SELECT value FROM settings WHERE name = '" + CHAIN_HEAD_SETTING + "'");
    if (!rs.next()) {
      throw new BlockStoreException("corrupt Postgres block store - no chain head pointer");
    }
    Sha256Hash hash = new Sha256Hash(rs.getBytes(1));
    rs.close();
    this.chainHeadBlock = get(hash);
    this.chainHeadHash = hash;
    if (this.chainHeadBlock == null) {
      throw new BlockStoreException("corrupt Postgres block store - head block not found");
    }

    rs =
        s.executeQuery(
            "SELECT value FROM settings WHERE name = '" + VERIFIED_CHAIN_HEAD_SETTING + "'");
    if (!rs.next()) {
      throw new BlockStoreException(
          "corrupt Postgres block store - no verified chain head pointer");
    }
    hash = new Sha256Hash(rs.getBytes(1));
    rs.close();
    s.close();
    this.verifiedChainHeadBlock = get(hash);
    this.verifiedChainHeadHash = hash;
    if (this.verifiedChainHeadBlock == null) {
      throw new BlockStoreException("corrupt Postgres block store - verified head block not found");
    }
  }
 private boolean tableExists(String table) throws SQLException {
   Statement s = conn.get().createStatement();
   try {
     ResultSet results = s.executeQuery("SELECT * FROM " + table + " WHERE 1 = 2");
     results.close();
     return true;
   } catch (SQLException ex) {
     return false;
   } finally {
     s.close();
   }
 }
  /**
   * Dumps information about the size of actual data in the database to standard output The only
   * truly useless data counted is printed in the form "N in id indexes" This does not take database
   * indexes into account
   */
  public void dumpSizes() throws SQLException, BlockStoreException {
    maybeConnect();
    Statement s = conn.get().createStatement();
    long size = 0;
    long totalSize = 0;
    int count = 0;
    ResultSet rs = s.executeQuery("SELECT name, value FROM settings");
    while (rs.next()) {
      size += rs.getString(1).length();
      size += rs.getBytes(2).length;
      count++;
    }
    rs.close();
    System.out.printf(
        "Settings size: %d, count: %d, average size: %f%n", size, count, (double) size / count);

    totalSize += size;
    size = 0;
    count = 0;
    rs = s.executeQuery("SELECT chainWork, header FROM headers");
    while (rs.next()) {
      size += 28; // hash
      size += rs.getBytes(1).length;
      size += 4; // height
      size += rs.getBytes(2).length;
      count++;
    }
    rs.close();
    System.out.printf(
        "Headers size: %d, count: %d, average size: %f%n", size, count, (double) size / count);

    totalSize += size;
    size = 0;
    count = 0;
    rs = s.executeQuery("SELECT txOutChanges, transactions FROM undoableBlocks");
    while (rs.next()) {
      size += 28; // hash
      size += 4; // height
      byte[] txOutChanges = rs.getBytes(1);
      byte[] transactions = rs.getBytes(2);
      if (txOutChanges == null) size += transactions.length;
      else size += txOutChanges.length;
      // size += the space to represent NULL
      count++;
    }
    rs.close();
    System.out.printf(
        "Undoable Blocks size: %d, count: %d, average size: %f%n",
        size, count, (double) size / count);

    totalSize += size;
    size = 0;
    count = 0;
    long scriptSize = 0;
    rs = s.executeQuery("SELECT value, scriptBytes FROM openOutputs");
    while (rs.next()) {
      size += 32; // hash
      size += 4; // index
      size += 4; // height
      size += rs.getBytes(1).length;
      size += rs.getBytes(2).length;
      scriptSize += rs.getBytes(2).length;
      count++;
    }
    rs.close();
    System.out.printf(
        "Open Outputs size: %d, count: %d, average size: %f, average script size: %f (%d in id indexes)%n",
        size, count, (double) size / count, (double) scriptSize / count, count * 8);

    totalSize += size;
    System.out.println("Total Size: " + totalSize);

    s.close();
  }