Right now, converters are used when setting a property in java on the way out of sql. I think they should go both directions, because for any custom converters, the reverse logic is usually needed to convert a java property into the appropriate format for inserting into sql.
For example, if I had a field on a POJO of type java.time.Year
(I use java 8), and a corresponding INT
column in the database, I would add the following converter right now (ignoring exceptions for simplicity):
public class YearConverter implements Converter<Year>
{
@Override
public Year convert(Object val) throws ConverterException
{
return Year.of((int) val);
}
}
However I would also need to add some custom code before calling Query#addParameter()
:
if (Year.class.equals(value.getClass()))
{
int actualValueToPutInDatabase = ((Year)value).getValue();
// now addParameter
}
I think this logic should live in the converter. Here are two possibilities for how that could work:
- to/from database methods, make sql2o do addParameter work:
public class YearConverter implements Converter<Year>
{
@Override
public Year fromDatabase(Object val) throws ConverterException
{
// equivalent of current "convert"
}
@Override
public Object toDatabase(Year val)
{
return val.getValue();
}
}
For this to work, sql2o would have to check for a registered converter when Query#addParameter()
is called, then call #toDatabase()
, then call #addParameter()
with the result.
- let uses do addParameter directly:
public class YearConverter implements Converter<Year>
{
@Override
public Year convert(Object val) throws ConverterException
{
// equivalent of current "convert"
}
@Override
public void addParameter(NamedParameterStatement stmt, String name, Year val) throws SQLException
{
stmt.setInt(name, val.getValue());
}
}
For this to work, sql2o would have to check for a registered converter when Query#addParameter()
is called, then call the converter's #addParameter()
.
From a users perspective, I think the first approach is much cleaner and clearer, because the job of the converter is to go to/from the database. However it would be easier to implement the second approach, and it would give users more control over functionality.