@Override
 public List<String> getTestNames() {
   try {
     return db.withConnection(
         new ConnectionAction<List<String>>() {
           public List<String> execute(Connection connection) throws Exception {
             List<String> testNames = new ArrayList<String>();
             ResultSet testExecutions =
                 connection
                     .createStatement()
                     .executeQuery("select distinct testId from testExecution order by testId");
             while (testExecutions.next()) {
               testNames.add(testExecutions.getString(1));
             }
             return testNames;
           }
         });
   } catch (Exception e) {
     throw new RuntimeException(
         String.format("Could not load test history from datastore '%s'.", dbFile), e);
   }
 }
 public void report(final CrossVersionPerformanceResults results) {
   try {
     db.withConnection(
         new ConnectionAction<Void>() {
           public Void execute(Connection connection) throws Exception {
             long testId;
             PreparedStatement statement =
                 connection.prepareStatement(
                     "insert into testExecution(testId, executionTime, targetVersion, testProject, tasks, args, gradleOpts, daemon, operatingSystem, jvm, vcsBranch, vcsCommit) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
             try {
               statement.setString(1, results.getTestId());
               statement.setTimestamp(2, new Timestamp(results.getTestTime()));
               statement.setString(3, results.getVersionUnderTest());
               statement.setString(4, results.getTestProject());
               statement.setObject(5, toArray(results.getTasks()));
               statement.setObject(6, toArray(results.getArgs()));
               statement.setObject(7, toArray(results.getGradleOpts()));
               statement.setObject(8, results.getDaemon());
               statement.setString(9, results.getOperatingSystem());
               statement.setString(10, results.getJvm());
               statement.setString(11, results.getVcsBranch());
               String vcs =
                   results.getVcsCommits() == null
                       ? null
                       : Joiner.on(",").join(results.getVcsCommits());
               statement.setString(12, vcs);
               statement.execute();
               ResultSet keys = statement.getGeneratedKeys();
               keys.next();
               testId = keys.getLong(1);
             } finally {
               statement.close();
             }
             statement =
                 connection.prepareStatement(
                     "insert into testOperation(testExecution, version, totalTime, configurationTime, executionTime, heapUsageBytes, totalHeapUsageBytes, maxHeapUsageBytes, maxUncollectedHeapBytes, maxCommittedHeapBytes) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
             try {
               addOperations(statement, testId, null, results.getCurrent());
               for (BaselineVersion baselineVersion : results.getBaselineVersions()) {
                 addOperations(
                     statement,
                     testId,
                     baselineVersion.getVersion(),
                     baselineVersion.getResults());
               }
             } finally {
               statement.close();
             }
             for (String previousId : results.getPreviousTestIds()) {
               statement =
                   connection.prepareStatement(
                       "update testExecution set testId = ? where testId = ?");
               try {
                 statement.setString(1, results.getTestId());
                 statement.setString(2, previousId);
                 statement.execute();
               } finally {
                 statement.close();
               }
             }
             return null;
           }
         });
   } catch (Exception e) {
     throw new RuntimeException(
         String.format("Could not open results datastore '%s'.", dbFile), e);
   }
 }
  @Override
  public CrossVersionPerformanceTestHistory getTestResults(
      final String testName, final int mostRecentN) {
    try {
      return db.withConnection(
          new ConnectionAction<CrossVersionPerformanceTestHistory>() {
            public CrossVersionPerformanceTestHistory execute(Connection connection)
                throws Exception {
              List<CrossVersionPerformanceResults> results =
                  new ArrayList<CrossVersionPerformanceResults>();
              Set<String> allVersions =
                  new TreeSet<String>(
                      new Comparator<String>() {
                        public int compare(String o1, String o2) {
                          return GradleVersion.version(o1).compareTo(GradleVersion.version(o2));
                        }
                      });
              Set<String> allBranches = new TreeSet<String>();
              PreparedStatement executionsForName =
                  connection.prepareStatement(
                      "select top ? id, executionTime, targetVersion, testProject, tasks, args, gradleOpts, daemon, operatingSystem, jvm, vcsBranch, vcsCommit from testExecution where testId = ? order by executionTime desc");
              PreparedStatement operationsForExecution =
                  connection.prepareStatement(
                      "select version, totalTime, configurationTime, executionTime, heapUsageBytes, totalHeapUsageBytes, maxHeapUsageBytes, maxUncollectedHeapBytes, maxCommittedHeapBytes from testOperation where testExecution = ?");
              executionsForName.setInt(1, mostRecentN);
              executionsForName.setString(2, testName);
              ResultSet testExecutions = executionsForName.executeQuery();
              while (testExecutions.next()) {
                long id = testExecutions.getLong(1);
                CrossVersionPerformanceResults performanceResults =
                    new CrossVersionPerformanceResults();
                performanceResults.setTestId(testName);
                performanceResults.setTestTime(testExecutions.getTimestamp(2).getTime());
                performanceResults.setVersionUnderTest(testExecutions.getString(3));
                performanceResults.setTestProject(testExecutions.getString(4));
                performanceResults.setTasks(toList(testExecutions.getObject(5)));
                performanceResults.setArgs(toList(testExecutions.getObject(6)));
                performanceResults.setGradleOpts(toList(testExecutions.getObject(7)));
                performanceResults.setDaemon((Boolean) testExecutions.getObject(8));
                performanceResults.setOperatingSystem(testExecutions.getString(9));
                performanceResults.setJvm(testExecutions.getString(10));
                performanceResults.setVcsBranch(testExecutions.getString(11).trim());
                performanceResults.setVcsCommits(splitVcsCommits(testExecutions.getString(12)));

                results.add(performanceResults);
                allBranches.add(performanceResults.getVcsBranch());

                operationsForExecution.setLong(1, id);
                ResultSet builds = operationsForExecution.executeQuery();
                while (builds.next()) {
                  String version = builds.getString(1);
                  if ("1.7".equals(version)
                      && performanceResults.getTestTime() <= ignoreV17Before) {
                    // Ignore some broken samples
                    continue;
                  }
                  MeasuredOperation operation = new MeasuredOperation();
                  operation.setTotalTime(Duration.millis(builds.getBigDecimal(2)));
                  operation.setConfigurationTime(Duration.millis(builds.getBigDecimal(3)));
                  operation.setExecutionTime(Duration.millis(builds.getBigDecimal(4)));
                  operation.setTotalMemoryUsed(DataAmount.bytes(builds.getBigDecimal(5)));
                  operation.setTotalHeapUsage(DataAmount.bytes(builds.getBigDecimal(6)));
                  operation.setMaxHeapUsage(DataAmount.bytes(builds.getBigDecimal(7)));
                  operation.setMaxUncollectedHeap(DataAmount.bytes(builds.getBigDecimal(8)));
                  operation.setMaxCommittedHeap(DataAmount.bytes(builds.getBigDecimal(9)));

                  if (version == null) {
                    performanceResults.getCurrent().add(operation);
                  } else {
                    BaselineVersion baselineVersion = performanceResults.baseline(version);
                    baselineVersion.getResults().add(operation);
                    allVersions.add(version);
                  }
                }
              }
              testExecutions.close();
              operationsForExecution.close();
              executionsForName.close();

              return new CrossVersionPerformanceTestHistory(
                  testName,
                  new ArrayList<String>(allVersions),
                  new ArrayList<String>(allBranches),
                  results);
            }
          });
    } catch (Exception e) {
      throw new RuntimeException(
          String.format("Could not load results from datastore '%s'.", dbFile), e);
    }
  }