thsi opportunity to move a whole heap of stuff into impl that doesn't really
need to be visible to external parties. We're changing the return value of all
expression creating factory classes to SQLExpression or FluentExp because those
expose all the functionality one might need on the returned values and there's
otherwise no value to be had getting an And() or a LiteralExp() and a downside
of preventing us from replacing the implementation of those expressions without
breaking binary compatibility.
I hemmed a bit about everything in depot.operator. In theory everything there
is available via a combination of Exps and FluentExp but in practice Whirled
uses a ton of those classes directly (whre a ton is defined as 64 imports of
classes in depot.operator). Perhaps I'll go on a cleanup jihad there and then
move all that to impl as well.
The rabbit holes, they always go deep.
reminder why it can be useful not to return the most specific type possible
from a method, but rather a more general supertype that allows us to change the
internals of the method without losing binary compatibility.
computed field in a computed record, Depot freaks out because it doesn't know
what table the computed field comes from when it doesn't come from any table.
So clearly this is what we want to achieve that functionality, but what I'm not
100% sure about is what ass biting we're opening ourselves up to here by not
freaking out in this case. We may be taking a step backwards in terms of useful
error reporting if someone does something stupid with computed fields. But
we'll just have to see what those errors are when they crop up. If the database
can't figure out what we're talking about with the unqualified field name, it
too will freak out.
system classes (not 100% done, if you use a ByteEnum in a key right now it
doesn't do the right thing). Also moved SimpleCacheKey into impl because it's
an implementation detail, not meant to be used by external parties.
us so that if we use multiple PersistenceContexts in the same VM they don't all
point to the same cache buckets which causes badness. At some point we'll
probably have to make it easier to customize these configurations, but this
should work for now.
indicative to the caller that they're not just getting another array list back
but rather a magical lazily converted list but is more useful than Iterable.
memory so that if we turn around and recreate a PersistenceContext with a brand
new classloader and start loading things from the cache, we don't have
freakoutery because there's a record in memory that was resolved with the old
classloader. Plus it allows those old classloaders to get collected.
all of our fromByte() methods already do which is iterate over the Enum and
find the one with the right byte. If we care about performance (which we don't
because this is trivial since all of these enums are small), we could even
cache a mapping from byte to enum in the field marshaller. No need to foist
this reponsibility on the ByteEnum implementor.
that return a collection return an XList which extends List and adds the
method:
public <R> Iterable<R> map (Function<T, R> mapper);
which allows you to do things the following:
return findAll(CategoryRecord.class,
new Where(CategoryRecord.PARENT_ID.eq(parentId))).
map(CategoryRecord.TO_CATEGORY);
which is sufficiently awesome that I think it merits taking these liberties.
Plus it opens the door to adding other transformations that one might want to
do with a collection just loaded from the database.
java.sql.Date and java.util.Date and we support custom getters and setters to
do fancier aggregate conversion (multiple persistent fields into a single
runtime field and/or creation of partially initialized runtime objects from the
available persistent data).