예제 #1
0
  /** WARNING: side-effecty */
  private String renderScalarSelect() {

    boolean isSubselect = superQuery != null;

    StringBuilder buf = new StringBuilder(20);

    if (scalarTypes.size() == 0) {
      // ie. no select clause
      int size = returnedTypes.size();
      for (int k = 0; k < size; k++) {

        scalarTypes.add(
            getFactory()
                .getTypeResolver()
                .getTypeFactory()
                .manyToOne(persisters[k].getEntityName(), shallowQuery));

        String[] idColumnNames = persisters[k].getIdentifierColumnNames();
        for (int i = 0; i < idColumnNames.length; i++) {
          buf.append(returnedTypes.get(k)).append('.').append(idColumnNames[i]);
          if (!isSubselect) buf.append(" as ").append(NameGenerator.scalarName(k, i));
          if (i != idColumnNames.length - 1 || k != size - 1) buf.append(", ");
        }
      }

    } else {
      // there _was_ a select clause
      Iterator iter = scalarSelectTokens.iterator();
      int c = 0;
      boolean nolast = false; // real hacky...
      int parenCount = 0; // used to count the nesting of parentheses
      while (iter.hasNext()) {
        Object next = iter.next();
        if (next instanceof String) {
          String token = (String) next;

          if ("(".equals(token)) {
            parenCount++;
          } else if (")".equals(token)) {
            parenCount--;
          }

          String lc = token.toLowerCase();
          if (lc.equals(", ")) {
            if (nolast) {
              nolast = false;
            } else {
              if (!isSubselect && parenCount == 0) {
                int x = c++;
                buf.append(" as ").append(NameGenerator.scalarName(x, 0));
              }
            }
          }
          buf.append(token);
          if (lc.equals("distinct") || lc.equals("all")) {
            buf.append(' ');
          }
        } else {
          nolast = true;
          String[] tokens = (String[]) next;
          for (int i = 0; i < tokens.length; i++) {
            buf.append(tokens[i]);
            if (!isSubselect) {
              buf.append(" as ").append(NameGenerator.scalarName(c, i));
            }
            if (i != tokens.length - 1) buf.append(", ");
          }
          c++;
        }
      }
      if (!isSubselect && !nolast) {
        int x = c++;
        buf.append(" as ").append(NameGenerator.scalarName(x, 0));
      }
    }

    return buf.toString();
  }
예제 #2
0
  private void renderSQL() throws QueryException, MappingException {

    final int rtsize;
    if (returnedTypes.size() == 0 && scalarTypes.size() == 0) {
      // ie no select clause in HQL
      returnedTypes = fromTypes;
      rtsize = returnedTypes.size();
    } else {
      rtsize = returnedTypes.size();
      Iterator iter = entitiesToFetch.iterator();
      while (iter.hasNext()) {
        returnedTypes.add(iter.next());
      }
    }
    int size = returnedTypes.size();
    persisters = new Queryable[size];
    names = new String[size];
    owners = new int[size];
    ownerAssociationTypes = new EntityType[size];
    suffixes = new String[size];
    includeInSelect = new boolean[size];
    for (int i = 0; i < size; i++) {
      String name = (String) returnedTypes.get(i);
      // if ( !isName(name) ) throw new QueryException("unknown type: " + name);
      persisters[i] = getEntityPersisterForName(name);
      // TODO: cannot use generateSuffixes() - it handles the initial suffix differently.
      suffixes[i] = (size == 1) ? "" : Integer.toString(i) + '_';
      names[i] = name;
      includeInSelect[i] = !entitiesToFetch.contains(name);
      if (includeInSelect[i]) selectLength++;
      if (name.equals(collectionOwnerName)) collectionOwnerColumn = i;
      String oneToOneOwner = (String) oneToOneOwnerNames.get(name);
      owners[i] = (oneToOneOwner == null) ? -1 : returnedTypes.indexOf(oneToOneOwner);
      ownerAssociationTypes[i] = (EntityType) uniqueKeyOwnerReferences.get(name);
    }

    if (ArrayHelper.isAllNegative(owners)) owners = null;

    String scalarSelect = renderScalarSelect(); // Must be done here because of side-effect! yuck...

    int scalarSize = scalarTypes.size();
    hasScalars = scalarTypes.size() != rtsize;

    returnTypes = new Type[scalarSize];
    for (int i = 0; i < scalarSize; i++) {
      returnTypes[i] = (Type) scalarTypes.get(i);
    }

    QuerySelect sql = new QuerySelect(getFactory().getDialect());
    sql.setDistinct(distinct);

    if (!shallowQuery) {
      renderIdentifierSelect(sql);
      renderPropertiesSelect(sql);
    }

    if (collectionPersister != null) {
      sql.addSelectFragmentString(collectionPersister.selectFragment(fetchName, "__"));
    }

    if (hasScalars || shallowQuery) sql.addSelectFragmentString(scalarSelect);

    // TODO: for some dialects it would be appropriate to add the renderOrderByPropertiesSelect() to
    // other select strings
    mergeJoins(sql.getJoinFragment());

    sql.setWhereTokens(whereTokens.iterator());

    sql.setGroupByTokens(groupByTokens.iterator());
    sql.setHavingTokens(havingTokens.iterator());
    sql.setOrderByTokens(orderByTokens.iterator());

    if (collectionPersister != null && collectionPersister.hasOrdering()) {
      sql.addOrderBy(collectionPersister.getSQLOrderByString(fetchName));
    }

    scalarColumnNames = NameGenerator.generateColumnNames(returnTypes, getFactory());

    // initialize the Set of queried identifier spaces (ie. tables)
    Iterator iter = collections.values().iterator();
    while (iter.hasNext()) {
      CollectionPersister p = getCollectionPersister((String) iter.next());
      addQuerySpaces(p.getCollectionSpaces());
    }
    iter = typeMap.keySet().iterator();
    while (iter.hasNext()) {
      Queryable p = getEntityPersisterForName((String) iter.next());
      addQuerySpaces(p.getQuerySpaces());
    }

    sqlString = sql.toQueryString();

    if (holderClass != null)
      holderConstructor = ReflectHelper.getConstructor(holderClass, returnTypes);

    if (hasScalars) {
      actualReturnTypes = returnTypes;
    } else {
      actualReturnTypes = new Type[selectLength];
      int j = 0;
      for (int i = 0; i < persisters.length; i++) {
        if (includeInSelect[i]) {
          actualReturnTypes[j++] =
              getFactory()
                  .getTypeResolver()
                  .getTypeFactory()
                  .manyToOne(persisters[i].getEntityName(), shallowQuery);
        }
      }
    }
  }