@Override
  protected Number executeCountQuery(
      Table table, List<FilterItem> whereItems, boolean functionApproximationAllowed) {
    final String query;

    try {
      final StringBuilder sb = new StringBuilder();
      sb.append("SELECT COUNT() FROM ");
      sb.append(table.getName());

      boolean firstWhere = true;
      for (FilterItem filterItem : whereItems) {
        if (firstWhere) {
          sb.append(" WHERE ");
          firstWhere = false;
        } else {
          sb.append(" AND ");
        }
        rewriteFilterItem(sb, filterItem);
      }
      query = sb.toString();
    } catch (UnsupportedOperationException e) {
      logger.debug("Failed to rewrite count query, falling back to client side counting", e);

      // unable to rewrite to SOQL, counting will be done client side.
      return null;
    }

    final QueryResult queryResult = executeSoqlQuery(query);

    assert queryResult.isDone();

    return queryResult.getSize();
  }
  @Test
  public void testQuery() throws Exception {
    SalesforceConnector connector = new SalesforceConnector();
    final SObject sObject1 = Mockito.mock(SObject.class);
    final SObject sObject2 = Mockito.mock(SObject.class);
    final SObject sObject3 = Mockito.mock(SObject.class);
    when(sObject1.getId()).thenReturn("1");
    when(sObject2.getId()).thenReturn("2");
    when(sObject3.getId()).thenReturn("3");
    QueryResult queryResult = Mockito.mock(QueryResult.class);
    when(queryResult.getRecords())
        .thenAnswer(
            new Answer<Object>() {
              int counter = 0;

              @Override
              public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
                SObject[] result = null;
                switch (counter) {
                  case 0:
                    result = new SObject[] {sObject1};
                    break;
                  case 1:
                    result = new SObject[] {sObject2, sObject3};
                    break;
                  case 2:
                    result = new SObject[] {};
                    break;
                }
                counter++;
                return result;
              }
            });
    when(queryResult.isDone()).thenReturn(false).thenReturn(true);
    when(queryResult.getQueryLocator()).thenReturn("001").thenReturn(null);

    PartnerConnection partnerConnection = Mockito.mock(PartnerConnection.class);
    BulkConnection bulkConnection = Mockito.mock(BulkConnection.class);
    connector.setBulkConnection(bulkConnection);
    connector.setConnection(partnerConnection);

    when(partnerConnection.query(eq(MOCK_QUERY))).thenReturn(queryResult);
    when(partnerConnection.queryMore("001")).thenReturn(queryResult);

    PagingDelegate<Map<String, Object>> delegate =
        connector.query(MOCK_QUERY, new PagingConfiguration(1));
    List<Map<String, Object>> result = delegate.getPage();
    assertEquals(1, result.size());

    result = delegate.getPage();
    assertEquals(2, result.size());

    assertNull(delegate.getPage());
  }
  @Test
  public void testSearch() throws Exception {
    String input =
        "exec native('search;SELECT Account.Id, Account.Type, Account.Name FROM Account')";

    TranslationUtility util = FakeTranslationFactory.getInstance().getExampleTranslationUtility();
    Command command = util.parseCommand(input);
    ExecutionContext ec = Mockito.mock(ExecutionContext.class);
    RuntimeMetadata rm = Mockito.mock(RuntimeMetadata.class);
    SalesforceConnection connection = Mockito.mock(SalesforceConnection.class);

    QueryResult qr = Mockito.mock(QueryResult.class);
    Mockito.stub(qr.isDone()).toReturn(true);

    ArrayList<SObject> results = new ArrayList<SObject>();
    ArrayList<Object> values = new ArrayList<Object>();

    SObject s = Mockito.mock(SObject.class);
    // Mockito.stub(s.getId()).toReturn("theID");
    Mockito.stub(s.getType()).toReturn("Account");
    results.add(s);

    Element e1 = Mockito.mock(Element.class);
    Mockito.stub(e1.getTextContent()).toReturn("The ID");
    values.add(e1);

    Element e2 = Mockito.mock(Element.class);
    Mockito.stub(e2.getTextContent()).toReturn("The Type");
    values.add(e2);

    Element e3 = Mockito.mock(Element.class);
    Mockito.stub(e3.getTextContent()).toReturn("The Name");
    values.add(e3);

    Mockito.stub(s.getAny()).toReturn(values);
    Mockito.stub(qr.getRecords()).toReturn(results);
    Mockito.stub(
            connection.query(
                "SELECT Account.Id, Account.Type, Account.Name FROM Account", 0, false))
        .toReturn(qr);

    DirectQueryExecution execution =
        (DirectQueryExecution) TRANSLATOR.createExecution(command, ec, rm, connection);
    execution.execute();

    Mockito.verify(connection, Mockito.times(1))
        .query("SELECT Account.Id, Account.Type, Account.Name FROM Account", 0, false);

    assertArrayEquals(
        new Object[] {"The ID", "The Type", "The Name"}, (Object[]) execution.next().get(0));
  }
  public void querySample() {
    try {
      // Set query batch size
      partnerConnection.setQueryOptions(250);

      // SOQL query to use
      String soqlQuery = "SELECT FirstName, LastName FROM Contact";
      // Make the query call and get the query results
      QueryResult qr = partnerConnection.query(soqlQuery);

      boolean done = false;
      int loopCount = 0;
      // Loop through the batches of returned results
      while (!done) {
        System.out.println("Records in results set " + loopCount++ + " - ");
        SObject[] records = qr.getRecords();
        // Process the query results
        for (int i = 0; i < records.length; i++) {
          SObject contact = records[i];
          Object firstName = contact.getField("FirstName");
          Object lastName = contact.getField("LastName");
          if (firstName == null) {
            System.out.println("Contact " + (i + 1) + ": " + lastName);
          } else {
            System.out.println("Contact " + (i + 1) + ": " + firstName + " " + lastName);
          }
        }
        if (qr.isDone()) {
          done = true;
        } else {
          qr = partnerConnection.queryMore(qr.getQueryLocator());
        }
      }
    } catch (ConnectionException ce) {
      ce.printStackTrace();
    }
    System.out.println("\nQuery execution completed.");
  }