use of org.jdbi.v3.core.qualifier.QualifiedType in project jdbi by jdbi.
the class BindFactory method createForParameter.
@Override
public SqlStatementParameterCustomizer createForParameter(Annotation annotation, Class<?> sqlObjectType, Method method, Parameter param, int index, Type type) {
Bind b = (Bind) annotation;
String nameFromAnnotation = b == null ? Bind.NO_VALUE : b.value();
Optional<String> name = ParameterUtil.findParameterName(nameFromAnnotation, param);
return new SqlStatementParameterCustomizer() {
@Override
public void apply(SqlStatement<?> stmt, Object arg) throws SQLException {
QualifiedType<?> qualifiedType = qualifiedType(stmt.getConfig());
stmt.bindByType(index, arg, qualifiedType);
name.ifPresent(n -> stmt.bindByType(n, arg, qualifiedType));
}
@Override
public void warm(ConfigRegistry config) {
config.get(Mappers.class).findFor(qualifiedType(config));
}
private QualifiedType<?> qualifiedType(ConfigRegistry config) {
return QualifiedType.of(type).withAnnotations(config.get(Qualifiers.class).findFor(param));
}
};
}
use of org.jdbi.v3.core.qualifier.QualifiedType in project jdbi by jdbi.
the class TestCodecFactoryH2 method testCodecFactory.
@Test
public void testCodecFactory() throws Exception {
QualifiedType<TestValue> testType = QualifiedType.of(TestValue.class);
Jdbi jdbi = h2Extension.getJdbi();
jdbi.registerCodecFactory(CodecFactory.forSingleCodec(testType, new TestValueCodec()));
jdbi.useHandle(h -> {
h.execute("CREATE TABLE test (test VARCHAR PRIMARY KEY)");
});
TestValue value = new TestValue(12345);
int result = jdbi.withHandle(h -> h.createUpdate("INSERT INTO test (test) VALUES (:test)").bindByType("test", value, testType).execute());
assertEquals(1, result);
TestValue response = jdbi.withHandle(h -> h.createQuery("SELECT * from test").mapTo(testType).first());
assertEquals(value, response);
}
use of org.jdbi.v3.core.qualifier.QualifiedType in project jdbi by jdbi.
the class ConstructorMapper method specialize0.
private Optional<RowMapper<T>> specialize0(StatementContext ctx, List<String> columnNames, List<ColumnNameMatcher> columnNameMatchers, List<String> unmatchedColumns) {
final int count = factory.getParameterCount();
final Parameter[] parameters = factory.getParameters();
boolean matchedColumns = false;
final List<String> unmatchedParameters = new ArrayList<>();
final List<ParameterData> paramData = new ArrayList<>();
for (int i = 0; i < count; i++) {
final Parameter parameter = parameters[i];
boolean nullable = isNullable(parameter);
Nested anno = parameter.getAnnotation(Nested.class);
if (anno == null) {
final String paramName = prefix + paramName(parameters, i, constructorProperties);
final OptionalInt columnIndex = findColumnIndex(paramName, columnNames, columnNameMatchers, () -> debugName(parameter));
if (columnIndex.isPresent()) {
int colIndex = columnIndex.getAsInt();
final QualifiedType<?> type = QualifiedType.of(parameter.getParameterizedType()).withAnnotations(ctx.getConfig(Qualifiers.class).findFor(parameter));
paramData.add(new ParameterData(i, parameter, ctx.findColumnMapperFor(type).map(mapper -> new SingleColumnMapper<>(mapper, colIndex + 1)).orElseThrow(() -> new IllegalArgumentException(format("Could not find column mapper for type '%s' of parameter '%s' for instance factory '%s'", type, paramName, factory)))));
matchedColumns = true;
unmatchedColumns.remove(columnNames.get(colIndex));
} else if (nullable) {
paramData.add(new ParameterData(i, parameter, (r, c) -> null));
} else {
unmatchedParameters.add(paramName);
}
} else {
final String nestedPrefix = prefix + anno.value();
final Optional<? extends RowMapper<?>> nestedMapper = nestedMappers.computeIfAbsent(parameter, p -> new ConstructorMapper<>(findFactoryFor(p.getType()), nestedPrefix)).specialize0(ctx, columnNames, columnNameMatchers, unmatchedColumns);
if (nestedMapper.isPresent()) {
paramData.add(new ParameterData(i, parameter, nestedMapper.get()));
matchedColumns = true;
} else if (nullable) {
paramData.add(new ParameterData(i, parameter, (r, c) -> null));
} else {
unmatchedParameters.add(paramName(parameters, i, constructorProperties));
}
}
}
if (!matchedColumns) {
return Optional.empty();
}
paramData.sort(Comparator.comparing(p -> p.propagateNull ? 1 : 0));
if (!unmatchedParameters.isEmpty()) {
throw new IllegalArgumentException(format(UNMATCHED_CONSTRUCTOR_PARAMETER, factory, unmatchedParameters));
}
final Optional<String> nullMarkerColumn = Optional.ofNullable(factory.getAnnotationIncludingType(PropagateNull.class)).map(PropagateNull::value);
return Optional.of((r, c) -> {
if (PojoMapper.propagateNull(r, nullMarkerColumn)) {
return null;
}
final Object[] params = new Object[count];
for (ParameterData p : paramData) {
params[p.index] = p.mapper.map(r, c);
if (p.propagateNull && (params[p.index] == null || (p.isPrimitive && r.wasNull()))) {
return null;
}
}
return factory.newInstance(params);
});
}
use of org.jdbi.v3.core.qualifier.QualifiedType in project jdbi by jdbi.
the class FieldMapper method specialize0.
private Optional<RowMapper<T>> specialize0(StatementContext ctx, List<String> columnNames, List<ColumnNameMatcher> columnNameMatchers, List<String> unmatchedColumns) {
final List<FieldData> fields = new ArrayList<>();
for (Class<?> aType = type; aType != null; aType = aType.getSuperclass()) {
for (Field field : aType.getDeclaredFields()) {
Nested anno = field.getAnnotation(Nested.class);
if (anno == null) {
String paramName = prefix + paramName(field);
findColumnIndex(paramName, columnNames, columnNameMatchers, () -> debugName(field)).ifPresent(index -> {
QualifiedType<?> fieldType = QualifiedType.of(field.getGenericType()).withAnnotations(ctx.getConfig(Qualifiers.class).findFor(field));
@SuppressWarnings("unchecked") ColumnMapper<?> mapper = ctx.findColumnMapperFor(fieldType).orElse((ColumnMapper) (r, n, c) -> r.getObject(n));
fields.add(new FieldData(field, new SingleColumnMapper<>(mapper, index + 1)));
unmatchedColumns.remove(columnNames.get(index));
});
} else {
String nestedPrefix = prefix + anno.value().toLowerCase();
if (anyColumnsStartWithPrefix(columnNames, nestedPrefix, columnNameMatchers)) {
nestedMappers.computeIfAbsent(field, f -> new FieldMapper<>(field.getType(), nestedPrefix)).specialize0(ctx, columnNames, columnNameMatchers, unmatchedColumns).ifPresent(mapper -> fields.add(new FieldData(field, mapper)));
}
}
}
}
if (fields.isEmpty() && !columnNames.isEmpty()) {
return Optional.empty();
}
Collections.sort(fields, Comparator.comparing(f -> f.propagateNull ? 1 : 0));
final Optional<String> nullMarkerColumn = Optional.ofNullable(type.getAnnotation(PropagateNull.class)).map(PropagateNull::value);
return Optional.of((r, c) -> {
if (PojoMapper.propagateNull(r, nullMarkerColumn)) {
return null;
}
T obj = construct();
for (FieldData f : fields) {
Object value = f.mapper.map(r, ctx);
if (f.propagateNull && (value == null || (f.isPrimitive && r.wasNull()))) {
return null;
}
writeField(obj, f.field, value);
}
return obj;
});
}
use of org.jdbi.v3.core.qualifier.QualifiedType in project jdbi by jdbi.
the class ArgumentBinder method argumentFactoryForType.
Function<Object, Argument> argumentFactoryForType(QualifiedType<?> type) {
return argumentFactoryByType.computeIfAbsent(type, qt -> {
Arguments args = ctx.getConfig(Arguments.class);
Function<Object, Argument> factory = args.prepareFor(type).orElse(v -> args.findFor(type, v).orElseThrow(() -> factoryNotFound(type, v)));
return value -> DescribedArgument.wrap(ctx, factory.apply(value), value);
});
}
Aggregations