If only Java didn't make it so damned hard to create a simple named class with
two or more values in it. Naming is generally a good thing, especially when the
alternative is Tuple2<SQLExpression<?>,SQLExpression<?>>.
It was a constant source of annoyance that part of the Depot implementation
lived in samskivert.jdbc. Now it all lives in Depot and samskivert can go back
to being a long obsolete library of utility methods.
Depot clients will have to make three renaming changes:
1. ConnectionProvider &c are now in com.samskivert.depot.
2. ByteEnum is now in com.samskivert.util.
3. Methods that returned index information used to return samskivert Tuple if
you wanted an expression and an order. Now they must return Depot Tuple2. This
should fail at app startup if you miss a spot, so this should not result in any
ticking timebombs.
NB: the next commit is probably going to change Tuple2 into a proper named
class because using a Tuple2 for this situation turns out to suck.
NB2: I moved DropTableMigration out of impl and put the impl details into
DepotMetaData. I should have done that separately, but it was already in
progress when I undertook to revamp.
Strings were always being shoved into a Comparable array.
Does the array type matter? Apparently not. We should just
rip out these tests and always store in a Comparable[].
We've had JDBC array support in Postgres for 5 years now, so I think we're
probably safe to assume it's working everywhere. Ha ha, I'm such an optimist.
It's not clear what the right thing to do is if the database connection fails
during the middle of a transaction. In general, one can't talk to the database
after that, so I'm assuming the transaction is aborted (or eventually aborted)
and rolled back, and everything has to be retried.
I'm not currently tracking state inside a Transaction, which means that I don't
freak out if you call commit() then call rollback(), I just ignore the latter
call, and it's also possible to do something stupid like:
Transaction tx = Transaction.start(ctx);
try {
_somRepo.doOp(..);
} catch (DatabaseException de) {
// no problem!, keep on keepin' on
}
_someRepo.doAnotherOp(...);
tx.commit();
If the first repo op fails due to a database connection failure, the
transaction will get a new database connection for the second op and do the
last half of the op in a new connection.
I guess I'll have to do some state tracking, because stupid as the above code
is, I'm sure some circumstance will arise where it seems like a reasonable
thing to do, and hilarity will ensue. Blah.
The _marshallers table must be guarded as computed marshallers can be created
at any time, and marshaller initialization itself must be guarded for the same
reason.
Thanks to Ray for pointing this out.
This causes the elements of the list to match the original order they were
added to the cons list (which stores elements "backwards").
This order matters for joins, as Ray discovered.