Why does the Java dependency management world have to suck so badly? Is it not
crazy to want projects to be able to publish their own releases and to make it
easy for other projects to depend on those published releases? Why do I have to
reconfigure the standard configuration to add new repository sources? Why
doesn't the IvyRep resolver work and do something sophisticated?
Why can't I just fucking put in my ivy.xml:
<dependency org="com.samskivert" name="samskivert" rev="1.0" conf="runtime"
source="http://samskivert.googlecode.com/svn/releases"/>
and have Ivy do something smart like assume that there will be a standard
directory structure at the specified root and that it will contain the ivy.xml
and module.jar file that it needs, and just download them?
Instead I have to write a ton of fucking boilerplate and wire it all in via a
separate ivysettings.xml file, and then helpfully instruct anyone who uses my
fucking library that they too can have the pleasure of doing the same.
columns in the results to match the FieldMarshaller column names, so we have
to use those rather than the field names. Also, shadowed fields need to use
the column names of the fields that they're shadowing.
date from date(). We should probably just modify DateFuncs.date to
return a date in both cases (perhaps with a separate DateFun.DateCast
class), but for now it's easier to have MySQL return a timestamp as
well.
the terminator (we encode the terminator as a different character).
This is somewhat nicer when inspecting an encoded String, and allows
for a future in which the decoder easily counts the number of terminator
characters and pre-allocates the storage, if we so desired.
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.