Thank you very much for sharing your thoughts, Thomas. 2017-02-27 10:57 GMT+01:00 Thomas GILLET <[email protected]>:
> Hello all, > > Happily using jOOQ for a while now, I'm starting to use it for a little > more than just SQL generation and I'm struggling a little when working with > keys (primary, unique, foreign). > > First, the Key interface doesn't have any generic information about the > key type: the only generic parameter represents the type of the owner table. > So for example, although both ends of a foreign key should have the same > type, there is no type-safety to guarantee that. And more generally, it's > problematic to write methods expecting a key with a certain type. > > I tried other types to add genericity to my keys, like Row and its > numbered friends, or jOOL tuples, but in the end it seems RecordType is > more appropriate. > Its parameter being a single Record type rather than several data types, > it's easier to work with. For example when extracting values of a key > implementing RecordType<K>, I return a record of type K ; this can't be > done with a Row, short of writing all 22 overloads. > > But then sometimes I need to work with key values only, rather than key > fields or a key record (for example when comparing values from both ends of > a foreign key, I cannot compare full records since key columns may not have > the same name). > Technically I could use RecordType again (since anyway all field > containers are implemented on top of a Fields object), but judging from > the name of the interface, its documentation, and the fact that > DSL.recordType only take Field arguments, it doesn't feel like this type > is meant to contain values. > No, indeed. RecordType is a type descriptor, not an actual value / tuple. Here's the distinction: - Row: an actual QueryPart that can generate a row constructor in SQL. It can contain column references as well as values - RecordType: A type descriptor for records and rows - Record: A map of column references / values pairs > So, to hold key fields: > - Use Key, adding a type parameter? > - Use RecordType? (but RecordType only contains Fields and not TableFields > as do Key) > - Make Key extend RecordType ? > > To hold key values: > - Create some new "RecordValue<R>" type, symmetrical to RecordType<R> ? > > Or, giving up the difference between key fields and key values, use a > single "RecordTuple<R>" type to hold anything? > Row could even extend this type (with each RowX<...> extending > RecordTuple<RecordX<...>>). > Clearly, you won't be getting what you're looking for out of the existing type systems too soon, as it was not designed for this use-case, yet. There are some unfortunate inconsistencies in jOOQ's API which are due to the late decision (version 3.0 only) to have those 22-arity "overloads" for a variety of types (but not for others). For some types, these 22-overloads make a lot of sense, mostly because you get immediate value in your SQL construction. For other types, they would have made sense, but were much too hard to implement correctly because of the limitations of the Java type systems, or because of backwards compatibility with jOOQ 2.0. For other types, they made no sense. Yes, a Key should really be a "more compatible" type with RecordType. In fact, UpdatableRecord.key() returns a Record, which is covariantly overridden by concrete generated tables to return a Record1<T1>, or Record2<T1, T2>, etc. so this concept certainly exists in jOOQ. Just not for Key. We might be able to redesign these API types in a way that improves the current situation. Certainly not in a backwards-compatible way, though. This means we would have two parallel APIs that do the same thing for the "rest" of version 3.x (or we fix this only in version 4.0). Now, before we proceed, I'd really love to have some more concrete examples of use-cases where constraint meta data needs to be queried in client code. I know you're trying to implement that tree persistence on top of jOOQ (see other discussion), but let's not go to the bigger picture, let's focus on concrete operations that you're trying to do and where the lack of type information is bothering you. Do you have some minimal examples you could share? Lukas -- You received this message because you are subscribed to the Google Groups "jOOQ User Group" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
