I have so much to say. I’ll probably break this into parts.
First, I was trying to add more type information to columns, because I wanted to implement something that did “select distinct”. I’m not even sure how this should work at an interface level, so it is all a big experiment. Not necessarily something that will go into mainline ever.
If you’re curious, the branch is here:
One of the tests fails, for interesting reasons.
But it made me think about a lot of things having to do with types, so some of what you said hit home.
I think the one principle should always be: “What does this buy for clients of the library?” Much more important than internal cleanliness concerns.
So, there are a few things on the table that could help clients.
- Support for non-Long primary keys.
- Support for distinct queries.
- Better type-checking for where clauses.
- Better type-checking/cleaner interface for running SQL functions.
Those are the big ones that I see out there right now.
The first is just a straight-up feature. If you want it, we should do it. It’s another type parameter or interface or something, because right now, it’s just always a long. And a lot of things will have to know about it to make it work right, but that’s fine. It’s a feature that makes hrorm better.
The second is a feature too, and it’s potentially a good one. But I am not sure how the interface even looks yet. There’s a lot of distinct style queries people might want, and maybe types have little to do with it in the end.
The next two are closely related: they have to do with columns being defined as just strings. I do not see any way around that at all, without radical changes to hrorm. And I mean really radical. A much bigger change than adding some kind of stream support. Like hrorm becomes a library that code generates DAO objects for you. That could be really nice, but, no, that’s just a different solution to the problem and if I wanted to do that I would just start from scratch and name it something different.
On the plus side, the way where clauses and sql functions work right now is a bit loose from the type system point-of-view, but that’s the worst you can say about it. I actually like how where clauses work. I think they have a pretty low weight and pack a lot of functionality into it.
So, really, the non-long primary key is the least speculative, highest reward.
That has nothing to do with Streams/laziness though, from a working on hrorm or a client’s usage point-of-view. (That I can see.) So I would like to talk about that separately.
From a types point of view, the term “column” is pretty overloaded. In hrorm, we already have several different notions of column. One is the interface Column
which really is something like DataElementInADaoDescriptor
. Maybe Column
is not the best word for that, and that can be changed.
Here are some of the concepts that we do have, one way or another. Not all of these map into hrorm classes, but they all exist somehow within hrorm.
- A SQL type (examples: INTEGER, VARCHAR, BOOLEAN)
- A Java SQL type (something that can be set onto a prepared statement or read from a result set) that supports a particular SQL type (examples Long, BigDecimal). This is very closely related to what hrorm now calls a
GenericColumn
, but they are subtly different, so it appears later.
- A Converter: something that translates between two types in both directions (generally between some arbitrary Java type and a Java SQL type) (examples, see hrorm
Converters
class)
- Java to SQL reader/writer. This is the
GenericColumn
. It sometimes mixes in a Converter.
- An Entity: an idealized model of something within a problem domain that can be persisted
- A Java model: A java class that represents an entity
- A table: A SQL structure that represents an entity
- A SQL column: a member of a SQL table that has a SQL type and a name
- A DAO Descriptor member: A SQL column combined with a Java type, and that Java type is either a Java SQL type, or has an associated Converter (this is what hrorm calls a
Column
right now for better or worse), so it always has a #4 in it, but also has a name, a prefix (or maybe that’s contextual or something), and getters and setters, which includes a specification of where to get and set things, so it includes an ENTITY class and a BUILDER class.
That could surely be refined further.
Your most fundamental point seems to be that concern number 9 is way down in the deepest bowels of hrorm, and that’s an annoyance, where’s it’s really trying to work on concepts 1-4 at the most. And relatedly, that some of the information that you really need at those lowest levels has been abstracted and lost.
My newest branch above simply adds some type information to column, but not enough, it turns out. And I agree that four type variables on a class is stretching it. Things like ChildDescriptor are hard to understand.
Well, this is already a wall of text, and I need to go put the laundry in the dryer.
If we want to support non-Long primary keys, let’s work on that. We can certainly start pulling apart the different types as we go down that road. I do think that will pay off for supporting other type-related things (like distinct selects).