Hi Tom,
As it turns out I did something very similar to this yesterday to
create a soundex qualifier. In my case, I used the Wonder qualifiers
as a guide on how to do it as, like you, I didn't find much in the way
of documentation by Apple.
The first thing you'll want to do is subclass ERXKeyValueQualifier
(Wonder) or EOKeyValueQualifier (non-Wonder) as you'll want to see if
this key contains that string.
You'll want to override the 'evaluatesWithObject' method, which
essentially returns true if a certain object qualifies against this
qualifier. Since you'll want the key's value on the object, use
something like this:
public boolean evaluateWithObject(Object object) {
Object result =
NSKeyValueCodingAdditions.Utility.valueForKeyPath(object, key());
if (result == null)
return false;
return value().toString().contains(result.toString());
}
checking for null values where appropriate, of course.
You can test this out now in unit tests / elsewhere in the application
that uses in-memory filtering and it'll do exactly as you'd expect.
The problem is when you try to use your qualifier in a fetch
specification - when it actually hits the database - you'll get
nothing back because EOF isn't sure how to express your query in SQL,
so you have to tell it how.
So, you'll want to create a subclass of
EOQualifierSQLGeneration._KeyValueQualifierSupport and override this
method:
public String sqlStringForSQLExpression(EOQualifier rawQualifier,
EOSQLExpression sqlExpression)
rawQualifier is your contains qualifier, so feel free to cast it to
that if you need it (you'll need the key() and value() methods!) and
sqlExpression contains some goodies that you'll need a bit later.
What you want this method to return is a qualifying string in SQL -
that is, if your SELECT statement looks like this:
select FIRST_NAME, LAST_NAME from PERSON where PERSON_ID = 1 and AGE
>= 19
you're looking to return the PERSON_ID = 1 or AGE >= 19 bits. At this
point, EOF has already been awesome and figured out what the table/
field name bit of this is - it'll look like t0.PERSON_ID or
t1.LOCATION_ID or something, so you can get this like this:
NSArray<?> attributePath =
ERXEOAccessUtilities.attributePathForKeyPath(e.entity(),
yourQualifier.key());
EOAttribute attribute = (EOAttribute) attributePath.lastObject();
String sqlName;
if (attributePath.count() > 1)
sqlName = e.sqlStringForAttributePath(attributePath);
else
sqlName = e.sqlStringForAttribute(attribute);
I stole this from Wonder, and I'm not sure if there's a shorter way to
do it, but now you have sqlName and, by using yourQualifier.value(),
you should be able to make your qualifying string without too much
difficulty. I'm not sure how to do this *without*
ERXEOAccessUtilities. Be careful at this level, though, because you
could be vulnerable to SQL injection.
The final little bit you want to do is tell EOF to use your special
SQL generator when using this qualifier. At the top of your
qualifier, add this lovely little bit of code:
static {
EOQualifierSQLGeneration.Support.setSupportForClass(new
YourQualifierSQLGenerationSupport(), YourQualifier.class);
}
Hope this helps.
Bill
Hi Chuck,
Thanks for the info. I will look into Wonder for an example. It
seemed to me that an Oracle Plugin inner class was handling the SQL
generation. As you mentioned, the documentation on how to create a
EOQualifier subclass is weak.
thanks,
tom
--
Bill Gallop
Software Developer
Strata Health Solutions Inc.
Phone: +1 403 261 0855 x2103
Fax: +1 403 265 0650
http://www.stratahealth.com
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com
This email sent to [email protected]