There are some optimizations that could probably be made, but
for now I defer to the new One Rule of Optimization:
"Do not optimize for performance unless it does not weird the code or
it Really Matters".
- continue to terminate Strings with a newline
- turn newlines inside a String into "\n"
- turn null elements into "\0".
This is one additional character when encoding nulls, but
I think it may improve readability..
contains generic type information which would allow a transformer to do the
right thing with a field of, say, type Set<Integer>.
If we had unit tests for StringIterable, I'd know that I didn't just break it.
I'd also know that it worked in the first place. :)
to the ternary operator are boolean constants, don't use the ternary operator.
a ? true : x == a || x
a ? x : true == !a || x
a ? false : x == !a && x
a ? x : false == a && x
case, seeing it fail, then adding the code to handle it was rather satisfying.
I'm not jumping on the TDD bandwagon or anything, but libraries like Depot are
clear cases where vigorous unit testing is a big win.
- Revamped column type determination to use a mechanism that supports
delegation and does not rely on a heap of instanceof calls (which results in
runtime failure rather than compile time failure when a new column type is
added)
- Discovered that HSQLDB (at least) does not handle Byte, Short and Float
correctly. It returns them as Integer, Integer and Double respectively, which
then causes failure when trying to write those values back to the fields. We
work around this by converting non-null results to the correct type after we
get them back from the JDBC driver.
This is an unimplemented proposal for handling non-basic types in Depot in an
extensible way, instead of continuing down the road of the ByteEnum-style
hackery that we've been doing to date. The basic design is as follows:
Annotate either a field or a class with @Transform and specify the classname of
a Transformer in that annotation. For example:
public class MyRecord extends PersistentRecord {
@Transform(Transformers.CommaSeparatedString.class)
public String[] cities;
}
will cause "cities" to be combined into a single string (comma separated)
before storing in the database, and split back into a string array from the
single string when read from the database.
Alternatively, one can annotate a type:
@Transform(ByteEnumTransformer.class)
public interface ByteEnum { ... }
If Depot sees a field of non-basic type, it will look for a @Transform
annotation on the field's type (and any interfaces implemented by that type or
its parent types, which is not auto-magic). If it finds one, it will use it.
Otherwise it will fall back to what it does now (which I think is to just foist
the object off to JDBC and hope for the best).
Comments and suggestions are invited.
verbose) mechanisms to accomodate his needs. We freak out as early as possible
to save the developer a time wasting debugging session in situations where they
update only one or the other of the persistent and runtime class, or make a
typo, or get the types wrong, etc.
A little bit back Mike added a fast-path for Key construction for keys with
one Comparable. Keys with multiple values would still validate the order
every time. This was necessary even when using the generated factory
because Class' getFields() does not guarantee any order. In practice,
the Sun JVM seems to return them in declared order, but apparently other
JVMs may not. The arguments to getKey() are determined when 'genrecord'
is run, but the field order used during runtime is computed at runtime.
This change generates code that stashes the key fields in an order
deteremined at the time 'genrecord' is run and that is guaranteed to
match the argument order to each PersistentRecord subclass' getKey().
Thus, getKey() can now directly construct a key with minimal overhead.
The field order is still computed at runtime as a fallback for
PersistentRecord classes that haven't yet been updated.
The ordering of getFields() is still being relied upon at 'genrecord'
time, but Mike may introduce a patch that will guarantee that ordering
matches declaration order. In the meantime, it's no worse than before
and if somehow someone does run 'genrecord' with an alternate JVM
they should immediately notice the discrepency in their diffs.
The Key constructor utilized is still public because it is used by
DepotUtil. A nice change would be to make it package-private.
However, I started making HSQL work a long time ago so that we could have real
unit tests that did real meaningful things, and Zell was kind enough to finish
making HSQL work, so we should be able to do some real end-to-end testing. I
just need to set up the necessary scaffolding. On the list!