Esempio n. 1
0
  protected static void rewriteFilterItem(StringBuilder sb, FilterItem filterItem)
      throws UnsupportedOperationException {
    if (filterItem.isCompoundFilter()) {
      FilterItem[] childrend = filterItem.getChildItems();
      boolean firstChild = true;
      sb.append('(');
      for (FilterItem child : childrend) {
        if (firstChild) {
          firstChild = false;
        } else {
          sb.append(' ');
          sb.append(filterItem.getLogicalOperator().toString());
          sb.append(' ');
        }
        rewriteFilterItem(sb, child);
      }
      sb.append(')');
      return;
    }

    final SelectItem selectItem = filterItem.getSelectItem();
    validateSoqlSupportedSelectItem(selectItem);

    final Column column = selectItem.getColumn();
    sb.append(column.getName());
    sb.append(' ');

    final OperatorType operator = filterItem.getOperator();
    if (OperatorType.IN.equals(operator)) {
      throw new UnsupportedOperationException("IN operator not supported: " + filterItem);
    }
    sb.append(operator.toSql());
    sb.append(' ');

    final Object operand = filterItem.getOperand();
    if (operand == null) {
      sb.append("null");
    } else if (operand instanceof String) {
      sb.append('\'');

      String str = operand.toString();
      str = str.replaceAll("\'", "\\\\'");
      str = str.replaceAll("\"", "\\\\\"");
      str = str.replaceAll("\r", "\\\\r");
      str = str.replaceAll("\n", "\\\\n");
      str = str.replaceAll("\t", "\\\\t");

      sb.append(str);
      sb.append('\'');
    } else if (operand instanceof Number) {
      sb.append(operand);
    } else if (operand instanceof Date) {
      final SimpleDateFormat dateFormat;
      ColumnType expectedColumnType = selectItem.getExpectedColumnType();
      if (expectedColumnType == ColumnType.DATE) {
        // note: we don't apply the timezone for DATE fields, since they
        // don't contain time-of-day information.
        dateFormat = new SimpleDateFormat(SOQL_DATE_FORMAT_OUT);
      } else if (expectedColumnType == ColumnType.TIME) {
        dateFormat = new SimpleDateFormat(SOQL_TIME_FORMAT_OUT, Locale.ENGLISH);
        dateFormat.setTimeZone(SOQL_TIMEZONE);
      } else {
        dateFormat = new SimpleDateFormat(SOQL_DATE_TIME_FORMAT_OUT, Locale.ENGLISH);
        dateFormat.setTimeZone(SOQL_TIMEZONE);
      }

      String str = dateFormat.format((Date) operand);
      logger.debug("Date '{}' formatted as: {}", operand, str);
      sb.append(str);
    } else if (operand instanceof Column) {
      sb.append(((Column) operand).getName());
    } else if (operand instanceof SelectItem) {
      SelectItem operandSelectItem = (SelectItem) operand;
      validateSoqlSupportedSelectItem(operandSelectItem);
      sb.append(operandSelectItem.getColumn().getName());
    } else {
      throw new UnsupportedOperationException("Unsupported operand: " + operand);
    }
  }
Esempio n. 2
0
  @Override
  public DataSet executeQuery(Query query) {
    final List<FromItem> fromItems = query.getFromClause().getItems();
    if (fromItems.size() != 1) {
      // not a simple SELECT ... FROM [table] ... query, we need to use
      // query post processing.
      return super.executeQuery(query);
    }

    final Table table = fromItems.get(0).getTable();
    if (table == null) {
      return super.executeQuery(query);
    }

    if (!query.getGroupByClause().isEmpty()) {
      return super.executeQuery(query);
    }

    if (!query.getHavingClause().isEmpty()) {
      return super.executeQuery(query);
    }

    final List<SelectItem> selectItems = query.getSelectClause().getItems();
    final StringBuilder sb = new StringBuilder();

    try {
      sb.append("SELECT ");
      int i = 0;
      final Column[] columns = new Column[selectItems.size()];
      for (SelectItem selectItem : selectItems) {
        validateSoqlSupportedSelectItem(selectItem);
        columns[i] = selectItem.getColumn();
        if (i != 0) {
          sb.append(", ");
        }
        sb.append(columns[i].getName());
        i++;
      }

      sb.append(" FROM ");
      sb.append(table.getName());

      boolean firstWhere = true;
      for (FilterItem filterItem : query.getWhereClause().getItems()) {
        if (firstWhere) {
          sb.append(" WHERE ");
          firstWhere = false;
        } else {
          sb.append(" AND ");
        }
        rewriteFilterItem(sb, filterItem);
      }

      i = 0;
      final List<OrderByItem> items = query.getOrderByClause().getItems();
      for (OrderByItem orderByItem : items) {
        if (i == 0) {
          sb.append(" ORDER BY ");
        } else {
          sb.append(", ");
        }

        final SelectItem selectItem = orderByItem.getSelectItem();
        validateSoqlSupportedSelectItem(selectItem);

        final Column column = selectItem.getColumn();
        sb.append(column.getName());
        sb.append(' ');
        sb.append(orderByItem.getDirection());

        i++;
      }

      final Integer firstRow = query.getFirstRow();
      final Integer maxRows = query.getMaxRows();
      if (maxRows != null && maxRows > 0) {
        if (firstRow != null) {
          // add first row / offset to avoid missing some records.
          sb.append(" LIMIT " + (maxRows + firstRow - 1));
        } else {
          sb.append(" LIMIT " + maxRows);
        }
      }

      final QueryResult result = executeSoqlQuery(sb.toString());

      DataSet dataSet = new SalesforceDataSet(columns, result, _connection);

      if (firstRow != null) {
        // OFFSET is still only a developer preview feature of SFDC. See
        // http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_calls_soql_select_offset.htm
        dataSet = new FirstRowDataSet(dataSet, firstRow.intValue());
      }

      return dataSet;

    } catch (UnsupportedOperationException e) {
      logger.debug(
          "Failed to rewrite query to SOQL, falling back to regular query post-processing", e);
      return super.executeQuery(query);
    }
  }