Search in sources :

Example 6 with QualifiedType

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));
        }
    };
}
Also used : SqlStatement(org.jdbi.v3.core.statement.SqlStatement) ConfigRegistry(org.jdbi.v3.core.config.ConfigRegistry) Bind(org.jdbi.v3.sqlobject.customizer.Bind) Mappers(org.jdbi.v3.core.mapper.Mappers) SqlStatementParameterCustomizer(org.jdbi.v3.sqlobject.customizer.SqlStatementParameterCustomizer)

Example 7 with QualifiedType

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);
}
Also used : Jdbi(org.jdbi.v3.core.Jdbi) Test(org.junit.jupiter.api.Test)

Example 8 with QualifiedType

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);
    });
}
Also used : RowMapperFactory(org.jdbi.v3.core.mapper.RowMapperFactory) ConstructorProperties(java.beans.ConstructorProperties) PropagateNull(org.jdbi.v3.core.mapper.PropagateNull) PojoMapper(org.jdbi.v3.core.mapper.reflect.internal.PojoMapper) Nested(org.jdbi.v3.core.mapper.Nested) JdbiConstructors.findFactoryFor(org.jdbi.v3.core.mapper.reflect.JdbiConstructors.findFactoryFor) SingleColumnMapper(org.jdbi.v3.core.mapper.SingleColumnMapper) Constructor(java.lang.reflect.Constructor) OptionalInt(java.util.OptionalInt) ArrayList(java.util.ArrayList) SQLException(java.sql.SQLException) Parameter(java.lang.reflect.Parameter) ResultSet(java.sql.ResultSet) Map(java.util.Map) QualifiedType(org.jdbi.v3.core.qualifier.QualifiedType) RowMapper(org.jdbi.v3.core.mapper.RowMapper) ReflectionMapperUtil.getColumnNames(org.jdbi.v3.core.mapper.reflect.ReflectionMapperUtil.getColumnNames) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) String.format(java.lang.String.format) StatementContext(org.jdbi.v3.core.statement.StatementContext) List(java.util.List) Stream(java.util.stream.Stream) Annotation(java.lang.annotation.Annotation) ReflectionMapperUtil.findColumnIndex(org.jdbi.v3.core.mapper.reflect.ReflectionMapperUtil.findColumnIndex) Optional(java.util.Optional) Qualifiers(org.jdbi.v3.core.qualifier.Qualifiers) ReflectionMapperUtil.anyColumnsStartWithPrefix(org.jdbi.v3.core.mapper.reflect.ReflectionMapperUtil.anyColumnsStartWithPrefix) Comparator(java.util.Comparator) SingleColumnMapper(org.jdbi.v3.core.mapper.SingleColumnMapper) ArrayList(java.util.ArrayList) Nested(org.jdbi.v3.core.mapper.Nested) OptionalInt(java.util.OptionalInt) PropagateNull(org.jdbi.v3.core.mapper.PropagateNull) Parameter(java.lang.reflect.Parameter)

Example 9 with QualifiedType

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;
    });
}
Also used : RowMapperFactory(org.jdbi.v3.core.mapper.RowMapperFactory) ReflectionMapperUtil.getColumnNames(org.jdbi.v3.core.mapper.reflect.ReflectionMapperUtil.getColumnNames) PropagateNull(org.jdbi.v3.core.mapper.PropagateNull) PojoMapper(org.jdbi.v3.core.mapper.reflect.internal.PojoMapper) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Nested(org.jdbi.v3.core.mapper.Nested) Field(java.lang.reflect.Field) SingleColumnMapper(org.jdbi.v3.core.mapper.SingleColumnMapper) String.format(java.lang.String.format) ArrayList(java.util.ArrayList) StatementContext(org.jdbi.v3.core.statement.StatementContext) SQLException(java.sql.SQLException) List(java.util.List) ResultSet(java.sql.ResultSet) Map(java.util.Map) ColumnMapper(org.jdbi.v3.core.mapper.ColumnMapper) ReflectionMapperUtil.findColumnIndex(org.jdbi.v3.core.mapper.reflect.ReflectionMapperUtil.findColumnIndex) Optional(java.util.Optional) Qualifiers(org.jdbi.v3.core.qualifier.Qualifiers) QualifiedType(org.jdbi.v3.core.qualifier.QualifiedType) ReflectionMapperUtil.anyColumnsStartWithPrefix(org.jdbi.v3.core.mapper.reflect.ReflectionMapperUtil.anyColumnsStartWithPrefix) Comparator(java.util.Comparator) Collections(java.util.Collections) RowMapper(org.jdbi.v3.core.mapper.RowMapper) SingleColumnMapper(org.jdbi.v3.core.mapper.SingleColumnMapper) ArrayList(java.util.ArrayList) Nested(org.jdbi.v3.core.mapper.Nested) Field(java.lang.reflect.Field) PropagateNull(org.jdbi.v3.core.mapper.PropagateNull)

Example 10 with QualifiedType

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);
    });
}
Also used : Arrays(java.util.Arrays) CheckedConsumer(org.jdbi.v3.core.internal.exceptions.CheckedConsumer) NamedArgumentFinder(org.jdbi.v3.core.argument.NamedArgumentFinder) Sneaky(org.jdbi.v3.core.internal.exceptions.Sneaky) HashMap(java.util.HashMap) JdbiOptionals(org.jdbi.v3.core.internal.JdbiOptionals) Function(java.util.function.Function) ArrayList(java.util.ArrayList) PrepareKey(org.jdbi.v3.core.argument.internal.NamedArgumentFinderFactory.PrepareKey) SQLException(java.sql.SQLException) Map(java.util.Map) NonNull(edu.umd.cs.findbugs.annotations.NonNull) QualifiedType(org.jdbi.v3.core.qualifier.QualifiedType) TypedValue(org.jdbi.v3.core.argument.internal.TypedValue) TypeVariable(java.lang.reflect.TypeVariable) Argument(org.jdbi.v3.core.argument.Argument) Arguments(org.jdbi.v3.core.argument.Arguments) PreparedStatement(java.sql.PreparedStatement) PreparedBinding(org.jdbi.v3.core.statement.internal.PreparedBinding) String.format(java.lang.String.format) Consumer(java.util.function.Consumer) AbstractMap(java.util.AbstractMap) List(java.util.List) Type(java.lang.reflect.Type) Entry(java.util.Map.Entry) Nullable(edu.umd.cs.findbugs.annotations.Nullable) Optional(java.util.Optional) Qualifiers(org.jdbi.v3.core.qualifier.Qualifiers) CheckForNull(edu.umd.cs.findbugs.annotations.CheckForNull) Argument(org.jdbi.v3.core.argument.Argument) Arguments(org.jdbi.v3.core.argument.Arguments)

Aggregations

QualifiedType (org.jdbi.v3.core.qualifier.QualifiedType)8 StatementContext (org.jdbi.v3.core.statement.StatementContext)7 SQLException (java.sql.SQLException)6 Map (java.util.Map)6 Test (org.junit.jupiter.api.Test)6 ResultSet (java.sql.ResultSet)5 List (java.util.List)5 Qualifiers (org.jdbi.v3.core.qualifier.Qualifiers)5 ArrayList (java.util.ArrayList)4 Optional (java.util.Optional)4 Function (java.util.function.Function)4 ConfigRegistry (org.jdbi.v3.core.config.ConfigRegistry)4 ColumnMapper (org.jdbi.v3.core.mapper.ColumnMapper)4 String.format (java.lang.String.format)3 Set (java.util.Set)3 Jdbi (org.jdbi.v3.core.Jdbi)3 RowMapper (org.jdbi.v3.core.mapper.RowMapper)3 Injector (com.google.inject.Injector)2 Key (com.google.inject.Key)2 Module (com.google.inject.Module)2