Re: Custom array column types in EO model
Re: Custom array column types in EO model
- Subject: Re: Custom array column types in EO model
- From: Paul Hoadley via Webobjects-dev <email@hidden>
- Date: Fri, 4 Nov 2022 20:53:22 +1030
- Feedback-id: i671c40f3:Fastmail
Hi Ramsey,
On 3 Nov 2022, at 16:42, Ramsey Gurley <email@hidden> wrote:
> I think I see where I did the magic now.
>
> If you look at the main commit where it appeared,
>
> https://github.com/wocommunity/wonder/commit/28ab710470fbff0c82449e6f0be3cf6127f273d6
>
> <https://github.com/wocommunity/wonder/commit/28ab710470fbff0c82449e6f0be3cf6127f273d6>
>
> You can see there's properties to set the jdbc adaptor and column class. You
> possibly need to implement your own custom column to handle a sql array type
> in addition to dates.
Thanks for that—it was enough to get me heading in the right direction.
After a day of trial and error, and re-kindling my friendship with the Eclipse
debugger, I actually got the job done: I have an attribute that returns an
NSArray<String>, backed by a PostgreSQL 'text[]' column, using a java.sql.Array
to and from the JDBC adapter. I can report that this is possible without
modifying Wonder's EOAttribute clone, though it's a little hairy:
1. I created a sub-class of ERXEnhancedJDBCColumn (which basically supersedes
the now-deprecated DateJDBCColumn). Unfortunately, that needs to live in the
com.webobjects.jdbcadaptor because JDBCColumn is package-private (and it needs
access to some package-private fields in that class), but I can live with that.
2. Overriding takeInputValue(), I call super.takeInputValue() and catch the
IllegalArgumentException thrown on the way out of
adaptorValueByConvertingAttributeValue() (which you identified in a previous
post). My preference was to check whether I have an "attribute of interest"
(see below), and immediately just call _statement.setArray(this._column,
convertedValue) (where convertedValue is the java.sql.Array I've created), but
that didn't work—I've forgotten the details, but I presume there's something
going on in the call to super.takeInputValue() that's important. I might still
investigate this further to reduce the ugly exception-catching idiom here.
3. _fetchValue() needs to be overridden as well, similar to what Henrique did
for numeric types in 62717132. I've added a new Value Type "AS" for the model,
which stands for "array of strings". If I've got an EOAttribute with this Value
Type, I can just return NSArray.of((String[])
_rs.getArray(_column).getArray())—I don't need a factory method, because a
java.sql.Array knows how to turn itself into a primitive array.
4. Finally, and I can't believe I'm going to admit this, there's some mild
model swizzling required: EOAttribute.adaptorValueType() basically defaults to
AdaptorBytesType if you don't set a Factory Method (_valueFactoryMethodName) or
an Init Argument (_argumentType) in the model, and that seemed to prevent
creating the java.sql.Array coming out. I could have faked it—setting the
method name to "dummy" and argument to String in the model gets us
AdaptorCharactersType, but that felt dirtier than calling this on the attribute
of interest: FieldUtils.writeField(attribute, "_adaptorValueType",
EOAttribute.AdaptorCharactersType, true).
Anyway, (a) this works (well, in very limited testing so far), which is great,
but (b) it could probably be better achieved by modifying (Wonder's)
EOAttribute. I stopped short of doing that only because it should probably be
implemented in a general and well-designed way. I think this should be
database-agnostic, but adding new symbolic Value Types for models is probably
something we should discuss here first. If anyone is interested in this, I'd be
happy to collaborate on bringing it into Wonder.
--
Paul Hoadley
https://logicsquad.net/
https://www.linkedin.com/company/logic-squad/
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden