@Test
  public void testGroupByQuery() throws Exception {
    Table table = dataContext.getDefaultSchema().getTableByName(peopleIndexType);

    Query q = new Query();
    q.from(table);
    q.groupBy(table.getColumnByName("gender"));
    q.select(
        new SelectItem(table.getColumnByName("gender")),
        new SelectItem(FunctionType.MAX, table.getColumnByName("age")),
        new SelectItem(FunctionType.MIN, table.getColumnByName("age")),
        new SelectItem(FunctionType.COUNT, "*", "total"),
        new SelectItem(FunctionType.MIN, table.getColumnByName("id")).setAlias("firstId"));
    q.orderBy("gender");
    DataSet data = dataContext.executeQuery(q);
    assertEquals(
        "[peopletype.gender, MAX(peopletype.age), MIN(peopletype.age), COUNT(*) AS total, MIN(peopletype.id) AS firstId]",
        Arrays.toString(data.getSelectItems()));

    assertTrue(data.next());
    assertEquals("Row[values=[female, 20, 17, 5, 5]]", data.getRow().toString());
    assertTrue(data.next());
    assertEquals("Row[values=[male, 19, 17, 4, 1]]", data.getRow().toString());
    assertFalse(data.next());
  }
  public void testProductTable() throws Exception {
    Schema schema = dc.getDefaultSchema();
    assertEquals("developers.mdb", schema.getName());

    Table table = schema.getTableByName("product");
    assertEquals("[id, name, version, founder_developer]", Arrays.toString(table.getColumnNames()));

    Column idCol = table.getColumnByName("id");
    assertEquals(
        "Column[name=id,columnNumber=0,type=INTEGER,nullable=null,nativeType=LONG,columnSize=4]",
        idCol.toString());

    Column nameCol = table.getColumnByName("name");
    assertEquals(
        "Column[name=name,columnNumber=1,type=VARCHAR,nullable=null,nativeType=TEXT,columnSize=100]",
        nameCol.toString());

    Column versionCol = table.getColumnByName("version");
    assertEquals(
        "Column[name=version,columnNumber=2,type=INTEGER,nullable=null,nativeType=LONG,columnSize=4]",
        versionCol.toString());

    Column founderCol = table.getColumnByName("founder_developer");
    assertEquals(
        "Column[name=founder_developer,columnNumber=3,type=INTEGER,nullable=null,nativeType=LONG,columnSize=4]",
        founderCol.toString());

    DataSet ds;

    ds = dc.executeQuery(new Query().select(nameCol, versionCol, founderCol).from(table));
    assertTrue(ds.next());
    assertEquals("Anthons Algorithms", ds.getRow().getValue(nameCol).toString());
    assertEquals(11, ds.getRow().getValue(versionCol));
    assertEquals(1, ds.getRow().getValue(founderCol));
    assertTrue(ds.next());
    assertEquals("Barbaras Basic Bundle", ds.getRow().getValue(nameCol).toString());
    assertEquals(2, ds.getRow().getValue(versionCol));
    assertEquals(2, ds.getRow().getValue(founderCol));
    assertFalse(ds.next());
    ds.close();

    ds = dc.query().from(table).selectCount().execute();
    assertTrue(ds.next());
    assertEquals("Row[values=[2]]", ds.getRow().toString());
    assertFalse(ds.next());
    ds.close();
  }
  public void testDeveloperTable() throws Exception {
    Schema schema = dc.getDefaultSchema();
    assertEquals("developers.mdb", schema.getName());

    assertEquals("[developer, product]", Arrays.toString(schema.getTableNames()));

    Table table = schema.getTableByName("developer");
    assertEquals(
        "[id, name, email, male, developer_since]", Arrays.toString(table.getColumnNames()));

    Column[] primaryKeys = table.getPrimaryKeys();
    assertEquals(
        "[Column[name=id,columnNumber=0,type=INTEGER,nullable=null,nativeType=LONG,columnSize=4]]",
        Arrays.toString(primaryKeys));

    Column nameCol = table.getColumnByName("name");
    assertEquals(
        "Column[name=name,columnNumber=1,type=VARCHAR,nullable=null,nativeType=TEXT,columnSize=100]",
        nameCol.toString());

    Column maleCol = table.getColumnByName("male");
    assertEquals(
        "Column[name=male,columnNumber=3,type=BOOLEAN,nullable=null,nativeType=BOOLEAN,columnSize=1]",
        maleCol.toString());

    Column developerSinceCol = table.getColumnByName("developer_since");
    assertEquals(
        "Column[name=developer_since,columnNumber=4,type=TIMESTAMP,nullable=null,nativeType=SHORT_DATE_TIME,columnSize=8]",
        developerSinceCol.toString());

    DataSet ds =
        dc.executeQuery(new Query().select(nameCol, maleCol, developerSinceCol).from(table));
    while (ds.next()) {
      Row row = ds.getRow();
      assertEquals(3, row.getValues().length);
      Object value = row.getValue(0);
      assertEquals(String.class, value.getClass());
      value = row.getValue(1);
      assertEquals(Boolean.class, value.getClass());
      value = row.getValue(2);
      assertTrue(value instanceof Date);
    }
  }
  @Test
  public void testSimpleQuery() throws Exception {
    assertEquals(
        "[bulktype, peopletype, tweet1, tweet2]",
        Arrays.toString(dataContext.getDefaultSchema().getTableNames()));

    Table table = dataContext.getDefaultSchema().getTableByName("tweet1");

    assertEquals("[_id, message, postDate, user]", Arrays.toString(table.getColumnNames()));

    assertEquals(ColumnType.STRING, table.getColumnByName("user").getType());
    assertEquals(ColumnType.DATE, table.getColumnByName("postDate").getType());
    assertEquals(ColumnType.BIGINT, table.getColumnByName("message").getType());

    try (DataSet ds =
        dataContext.query().from(indexType1).select("user").and("message").execute()) {
      assertEquals(ElasticSearchDataSet.class, ds.getClass());

      assertTrue(ds.next());
      assertEquals("Row[values=[user1, 1]]", ds.getRow().toString());
    }
  }
  @Test
  public void testNumberIsHandledAsNumber() throws Exception {
    Table table = dataContext.getDefaultSchema().getTableByName(peopleIndexType);
    Column column = table.getColumnByName("age");
    ColumnType type = column.getType();
    assertEquals(ColumnType.BIGINT, type);

    DataSet dataSet = dataContext.query().from(table).select(column).execute();
    while (dataSet.next()) {
      Object value = dataSet.getRow().getValue(column);
      assertTrue(
          "Got class: " + value.getClass() + ", expected Number (or subclass)",
          value instanceof Number);
    }
  }
  @Test
  public void testDateIsHandledAsDate() throws Exception {
    Table table = dataContext.getDefaultSchema().getTableByName("tweet1");
    Column column = table.getColumnByName("postDate");
    ColumnType type = column.getType();
    assertEquals(ColumnType.DATE, type);

    DataSet dataSet = dataContext.query().from(table).select(column).execute();
    while (dataSet.next()) {
      Object value = dataSet.getRow().getValue(column);
      assertTrue(
          "Got class: " + value.getClass() + ", expected Date (or subclass)",
          value instanceof Date);
    }
  }
  @Test
  public void testCreateTableInsertQueryAndDrop() throws Exception {
    final Schema schema = dataContext.getDefaultSchema();
    final CreateTable createTable = new CreateTable(schema, "testCreateTable");
    createTable.withColumn("foo").ofType(ColumnType.STRING);
    createTable.withColumn("bar").ofType(ColumnType.NUMBER);
    dataContext.executeUpdate(createTable);

    final Table table = schema.getTableByName("testCreateTable");
    assertEquals(
        "[" + ElasticSearchDataContext.FIELD_ID + ", foo, bar]",
        Arrays.toString(table.getColumnNames()));

    final Column fooColumn = table.getColumnByName("foo");
    final Column idColumn = table.getPrimaryKeys()[0];
    assertEquals(
        "Column[name=_id,columnNumber=0,type=STRING,nullable=null,nativeType=null,columnSize=null]",
        idColumn.toString());

    dataContext.executeUpdate(
        new UpdateScript() {
          @Override
          public void run(UpdateCallback callback) {
            callback.insertInto(table).value("foo", "hello").value("bar", 42).execute();
            callback.insertInto(table).value("foo", "world").value("bar", 43).execute();
          }
        });

    dataContext.refreshSchemas();

    try (DataSet ds = dataContext.query().from(table).selectAll().orderBy("bar").execute()) {
      assertTrue(ds.next());
      assertEquals("hello", ds.getRow().getValue(fooColumn).toString());
      assertNotNull(ds.getRow().getValue(idColumn));
      assertTrue(ds.next());
      assertEquals("world", ds.getRow().getValue(fooColumn).toString());
      assertNotNull(ds.getRow().getValue(idColumn));
      assertFalse(ds.next());
    }

    dataContext.executeUpdate(new DropTable(table));

    dataContext.refreshSchemas();

    assertNull(dataContext.getTableByQualifiedLabel(table.getName()));
  }
  public void runScenario() {
    MultiThreadedTaskRunner taskRunner = TestEnvironment.getMultiThreadedTaskRunner();

    ThreadPoolExecutor executorService = (ThreadPoolExecutor) taskRunner.getExecutorService();
    assertEquals(TestEnvironment.THREAD_COUNT, executorService.getMaximumPoolSize());
    assertEquals(0, executorService.getActiveCount());

    DataCleanerConfiguration configuration =
        new DataCleanerConfigurationImpl()
            .withEnvironment(new DataCleanerEnvironmentImpl().withTaskRunner(taskRunner));

    AnalysisRunner runner = new AnalysisRunnerImpl(configuration);

    Datastore ds = TestHelper.createSampleDatabaseDatastore("foobar");
    try (DatastoreConnection con = ds.openConnection()) {

      AnalysisJob job;
      try (AnalysisJobBuilder analysisJobBuilder = new AnalysisJobBuilder(configuration)) {
        analysisJobBuilder.setDatastore(ds);

        Table table = con.getDataContext().getDefaultSchema().getTableByName("ORDERFACT");
        assertNotNull(table);

        Column statusColumn = table.getColumnByName("STATUS");
        Column commentsColumn = table.getColumnByName("COMMENTS");

        analysisJobBuilder.addSourceColumns(statusColumn, commentsColumn);
        analysisJobBuilder
            .addAnalyzer(AnalyzerMock.class)
            .addInputColumns(analysisJobBuilder.getSourceColumns());

        job = analysisJobBuilder.toAnalysisJob();
      }

      AnalysisResultFuture resultFuture = runner.run(job);

      try {
        Thread.sleep(550);
      } catch (InterruptedException e) {
        e.printStackTrace();
        fail("Interrupted! " + e.getMessage());
      }

      resultFuture.cancel();

      assertFalse(resultFuture.isSuccessful());
      assertTrue(resultFuture.isCancelled());
      assertTrue(resultFuture.isErrornous());

      try {
        Thread.sleep(400);
      } catch (InterruptedException e) {
        e.printStackTrace();
        fail("Interrupted! " + e.getMessage());
      }

      assertEquals(TestEnvironment.THREAD_COUNT, executorService.getMaximumPoolSize());

      long completedTaskCount = executorService.getCompletedTaskCount();
      assertTrue("completedTaskCount was: " + completedTaskCount, completedTaskCount > 3);

      int largestPoolSize = executorService.getLargestPoolSize();
      assertTrue("largestPoolSize was: " + largestPoolSize, largestPoolSize > 5);
      assertEquals(0, executorService.getActiveCount());
    }

    taskRunner.shutdown();
  }