/** * Ensures we don't have references to EOs before using this in the background thread. * * @param fs * @return a clone of the fetchSpecification with the EOQualifier converted to a schema-based * qualifier or the same {@link EOFetchSpecification} if there is no qualifier. */ private EOFetchSpecification schemaBasedFetchSpecification( EOFetchSpecification fetchSpecification) { EOQualifier q = fetchSpecification.qualifier(); if (q != null) { // Clone the fetchSpec fetchSpecification = (EOFetchSpecification) fetchSpecification.clone(); EOEditingContext ec = ERXEC.newEditingContext(); ec.lock(); try { EOEntity entity = ERXEOAccessUtilities.entityMatchingString(ec, fetchSpecification.entityName()); // Convert the qualifier to a schema-based qualifier q = entity.schemaBasedQualifier(q); fetchSpecification.setQualifier(q); } finally { ec.unlock(); } } // ~ if (q != null) return fetchSpecification; }
/** * 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(); }