Beispiel #1
0
    public void prepareUpdateExpressionWithRow(NSDictionary row, EOQualifier qualifier) {
      EOAttribute attribute;
      Object value;
      for (Enumeration enumeration = row.keyEnumerator();
          enumeration.hasMoreElements();
          addUpdateListAttribute(attribute, value)) {
        String attributeName = (String) enumeration.nextElement();
        attribute = this.entity().anyAttributeNamed(attributeName);
        if (attribute == null)
          throw new IllegalStateException(
              "prepareUpdateExpressionWithRow: row argument contains key '"
                  + attributeName
                  + "' which does not have corresponding attribute on entity '"
                  + this.entity().name()
                  + "'");
        value = row.objectForKey(attributeName);
      }

      _whereClauseString =
          EOQualifierSQLGeneration.Support._sqlStringForSQLExpression(qualifier, this);
      String tableList = tableListWithRootEntity(_rootEntityForExpression());
      _statement =
          assembleUpdateStatementWithRow(
              row, qualifier, tableList, new String(_listString), _whereClauseString);
    }
 // ENHANCEME: This should support restrictive qualifiers on the root entity
 @Override
 public EOQualifier schemaBasedQualifierWithRootEntity(
     EOQualifier eoqualifier, EOEntity eoentity) {
   EOQualifier result = null;
   EOKeyValueQualifier qualifier = (EOKeyValueQualifier) eoqualifier;
   String key = qualifier.key();
   if (qualifier.selector().name().equals(MatchesAllInArraySelectorName)) {
     EOQualifierSQLGeneration.Support support =
         EOQualifierSQLGeneration.Support.supportForClass(ERXToManyQualifier.class);
     NSArray array = (NSArray) qualifier.value();
     ERXToManyQualifier q = new ERXToManyQualifier(key, array, array.count());
     result = support.schemaBasedQualifierWithRootEntity(q, eoentity);
     return result;
   }
   return (EOQualifier) eoqualifier.clone();
 }
 @Override
 public EOQualifier qualifierMigratedFromEntityRelationshipPath(
     EOQualifier eoqualifier, EOEntity eoentity, String relationshipPath) {
   ERXToManyQualifier qualifier = (ERXToManyQualifier) eoqualifier;
   String newPath =
       EOQualifierSQLGeneration.Support._translateKeyAcrossRelationshipPath(
           qualifier.key(), relationshipPath, eoentity);
   return new ERXToManyQualifier(newPath, qualifier.elements(), qualifier.minCount());
 }
 /** Register SQL generation support for the qualifier. */
 static {
   EOQualifierSQLGeneration.Support.setSupportForClass(
       new ExistsQualifierSQLGenerationSupport(), ERXExistsQualifier.class);
 }
    /**
     * Generates the EXISTS SQL string for the given SQL expression. The bulk of the logic for
     * generating the sub-query is in this method.
     *
     * @param qualifier for which to generate the SQL
     * @param expression to use during SQL generation
     * @return SQL string for the current sub-query
     */
    public String sqlStringForSQLExpression(EOQualifier qualifier, EOSQLExpression expression) {
      if (null == qualifier || null == expression) {
        return null;
      }

      ERXExistsQualifier existsQualifier = (ERXExistsQualifier) qualifier;
      EOQualifier subqualifier = existsQualifier.subqualifier();
      String baseKeyPath = existsQualifier.baseKeyPath();

      EOEntity baseEntity = expression.entity();
      EORelationship relationship = null;

      // Walk the key path to the last entity.
      if (baseKeyPath != null) {
        for (Enumeration pathEnum =
                NSArray.componentsSeparatedByString(baseKeyPath, ".").objectEnumerator();
            pathEnum.hasMoreElements(); ) {
          String path = (String) pathEnum.nextElement();
          if (null == relationship) {
            relationship = baseEntity.anyRelationshipNamed(path);
          } else {
            relationship = relationship.destinationEntity().anyRelationshipNamed(path);
          }
        }
      }

      EOEntity srcEntity = relationship != null ? relationship.entity() : baseEntity;
      EOEntity destEntity = relationship != null ? relationship.destinationEntity() : baseEntity;

      // We need to do a bunch of hand-waiving to get the right table aliases for the table used in
      // the exists
      // subquery and for the join clause back to the source table.
      String sourceTableAlias =
          "t0"; // The alias for the the source table of the baseKeyPath from the main query.
      String destTableAlias; // The alias for the table used in the subquery.
      if (!srcEntity.equals(baseEntity)) { // The exists clause is applied to the different table.
        String sourceKeyPath = ERXStringUtilities.keyPathWithoutLastProperty(baseKeyPath);
        sqlStringForAttributeNamedInExpression(sourceKeyPath, expression);
        sqlStringForAttributeNamedInExpression(baseKeyPath, expression);
        sourceTableAlias =
            (String) expression.aliasesByRelationshipPath().valueForKey(sourceKeyPath);
        destTableAlias = (String) expression.aliasesByRelationshipPath().valueForKey(baseKeyPath);
        if (null == destTableAlias) {
          destTableAlias =
              "t" + (expression.aliasesByRelationshipPath().count()); // The first entry = "t0".
          expression.aliasesByRelationshipPath().takeValueForKey(destTableAlias, baseKeyPath);
        }
      } else { // The exists clause is applied to the base table.
        destTableAlias = "t" + expression.aliasesByRelationshipPath().count(); // Probably "t1"
      }

      EOAttribute sourceKeyAttribute = srcEntity.primaryKeyAttributes().lastObject();
      String sourceKey = expression.sqlStringForAttribute(sourceKeyAttribute);

      EOAttribute destKeyAttribute = relationship.destinationAttributes().lastObject();
      String destKey = expression.sqlStringForAttribute(destKeyAttribute);

      EOQualifier qual =
          EOQualifierSQLGeneration.Support._schemaBasedQualifierWithRootEntity(
              subqualifier, destEntity);
      EOFetchSpecification fetchSpecification =
          new EOFetchSpecification(destEntity.name(), qual, null, false, true, null);

      EODatabaseContext context =
          EODatabaseContext.registeredDatabaseContextForModel(
              destEntity.model(), EOObjectStoreCoordinator.defaultCoordinator());
      EOSQLExpressionFactory factory = context.database().adaptor().expressionFactory();

      EOSQLExpression subExpression = factory.expressionForEntity(destEntity);
      subExpression.aliasesByRelationshipPath().setObjectForKey(destTableAlias, "");
      subExpression.setUseAliases(true);
      subExpression.prepareSelectExpressionWithAttributes(
          destEntity.primaryKeyAttributes(), false, fetchSpecification);

      for (Enumeration bindEnumeration =
              subExpression.bindVariableDictionaries().objectEnumerator();
          bindEnumeration.hasMoreElements(); ) {
        expression.addBindVariableDictionary((NSDictionary) bindEnumeration.nextElement());
      }

      StringBuffer sb = new StringBuffer();
      sb.append(" EXISTS ( ");
      sb.append(
          ERXStringUtilities.replaceStringByStringInString(
              "t0.", destTableAlias + ".", subExpression.statement()));
      sb.append(" AND ");
      sb.append(
          ERXStringUtilities.replaceStringByStringInString("t0.", destTableAlias + ".", destKey));
      sb.append(" = ");
      sb.append(
          ERXStringUtilities.replaceStringByStringInString(
              "t0.", sourceTableAlias + ".", sourceKey));
      sb.append(" ) ");
      return sb.toString();
    }
  /**
   * Generates the sql string for the given sql expression. Bulk of the logic for generating the
   * sub-query is in this method.
   *
   * @param e a given sql expression
   * @return sql string for the current sub-query.
   */
  public String sqlStringForSQLExpression(EOSQLExpression e) {
    StringBuffer sb = new StringBuffer();
    if (attributeName != null) sb.append(e.sqlStringForAttributeNamed(attributeName));
    else {
      EOAttribute pk = (EOAttribute) e.entity().primaryKeyAttributes().lastObject();
      sb.append(e.sqlStringForAttribute(pk));
    }
    sb.append(" IN ( ");
    EOEntity entity =
        entityName == null ? e.entity() : e.entity().model().modelGroup().entityNamed(entityName);

    EOFetchSpecification fs =
        new EOFetchSpecification(entity.name(), qualifier, null, false, true, null);

    if (qualifier != null) {
      qualifier =
          EOQualifierSQLGeneration.Support._schemaBasedQualifierWithRootEntity(qualifier, entity);
    }
    if (qualifier != fs.qualifier()) {
      fs.setQualifier(qualifier);
    }

    // ASSUME: This makes a few assumptions, if anyone can figure out a fool
    // proof way that would be nice to get the model
    // Note you can't use:
    // EOAdaptor.adaptorWithModel(e.entity().model()).expressionFactory();
    // as this creates a
    //
    EODatabaseContext context =
        EODatabaseContext.registeredDatabaseContextForModel(
            entity.model(), EOObjectStoreCoordinator.defaultCoordinator());
    EOSQLExpressionFactory factory = context.database().adaptor().expressionFactory();

    NSArray subAttributes =
        destinationAttName != null
            ? new NSArray(entity.attributeNamed(destinationAttName))
            : entity.primaryKeyAttributes();

    EOSQLExpression subExpression = factory.expressionForEntity(entity);

    // Arroz: Having this table identifier replacement causes serious
    // problems if you have more than a table being processed in the subquery. Disabling
    // it will apparently not cause problems, because t0 inside the subquery is not
    // the same t0 outside it.
    // subExpression.aliasesByRelationshipPath().setObjectForKey("t1", "");

    subExpression.setUseAliases(true);
    subExpression.prepareSelectExpressionWithAttributes(subAttributes, false, fs);
    // EOSQLExpression
    // expression=factory.selectStatementForAttributes(entity.primaryKeyAttributes(),
    // false, fs,  entity);

    for (Enumeration bindEnumeration = subExpression.bindVariableDictionaries().objectEnumerator();
        bindEnumeration.hasMoreElements(); ) {
      e.addBindVariableDictionary((NSDictionary) bindEnumeration.nextElement());
    }

    // sb.append(ERXStringUtilities.replaceStringByStringInString("t0.",
    // "t1.", subExpression.statement()));
    sb.append(subExpression.statement());
    sb.append(" ) ");
    return sb.toString();
  }
 /** register SQL generation support for the qualifier */
 static {
   EOQualifierSQLGeneration.Support.setSupportForClass(
       new ToManyQualifierSQLGenerationSupport(), ERXToManyQualifier.class);
 }