Search in sources :

Example 1 with Argument

use of org.jdbi.v3.core.argument.Argument in project jdbi by jdbi.

the class SqlStatement method bindBeanList.

/**
 * Bind a parameter for each value in the given list * number of property names,
 * and defines an attribute as the comma-separated list of parameter references (using colon prefix).
 *
 * Used to create query similar to:
 * select * from things where (id, foo) in ((1,'abc'),(2,'def'),(3,'ghi'))
 * <p>
 * Examples:
 * <pre>
 *
 * List&lt;ThingKey&gt; thingKeys = ...
 * List&lt;Thing&gt; things = handle.createQuery("select * from things where (id, foo) in (&lt;thingKeys&gt;)")
 *     .bindBeanList("thingKeys", thingKeys, Arrays.asList("id", "foo"))
 *     .mapTo(Contact.class)
 *     .list();
 * </pre>
 *
 * @param key    attribute name
 * @param values list of values that will be comma-spliced into the defined attribute value.
 * @param propertyNames list of properties that will be invoked on the values.
 * @return this
 * @throws IllegalArgumentException if the list of values or properties is empty.
 * @throws UnableToCreateStatementException If a property can't be found on an value or we can't find a Argument for it.
 */
public final This bindBeanList(String key, List<?> values, List<String> propertyNames) throws UnableToCreateStatementException {
    if (values.isEmpty()) {
        throw new IllegalArgumentException(getClass().getSimpleName() + ".bindBeanList was called with no values.");
    }
    if (propertyNames.isEmpty()) {
        throw new IllegalArgumentException(getClass().getSimpleName() + ".bindBeanList was called with no properties.");
    }
    StringBuilder names = new StringBuilder();
    StatementContext ctx = getContext();
    for (int valueIndex = 0; valueIndex < values.size(); valueIndex++) {
        if (valueIndex > 0) {
            names.append(',');
        }
        Object bean = values.get(valueIndex);
        BeanPropertyArguments beanProperties = new BeanPropertyArguments(null, bean);
        names.append("(");
        for (int propertyIndex = 0; propertyIndex < propertyNames.size(); propertyIndex++) {
            if (propertyIndex > 0) {
                names.append(",");
            }
            String propertyName = propertyNames.get(propertyIndex);
            String name = "__" + key + "_" + valueIndex + "_" + propertyName;
            names.append(':').append(name);
            Argument argument = beanProperties.find(propertyName, ctx).orElseThrow(() -> new UnableToCreateStatementException("Unable to get " + propertyName + " argument for " + bean, ctx));
            bind(name, argument);
        }
        names.append(")");
    }
    return define(key, names.toString());
}
Also used : InputStreamArgument(org.jdbi.v3.core.argument.InputStreamArgument) NullArgument(org.jdbi.v3.core.argument.NullArgument) ObjectArgument(org.jdbi.v3.core.argument.ObjectArgument) Argument(org.jdbi.v3.core.argument.Argument) CharacterStreamArgument(org.jdbi.v3.core.argument.CharacterStreamArgument) BeanPropertyArguments(org.jdbi.v3.core.argument.BeanPropertyArguments)

Example 2 with Argument

use of org.jdbi.v3.core.argument.Argument in project jdbi by jdbi.

the class BindBeanListFactory method createForParameter.

@Override
public SqlStatementParameterCustomizer createForParameter(Annotation annotation, Class<?> sqlObjectType, Method method, Parameter param, int index, Type type) {
    final BindBeanList bindBeanList = (BindBeanList) annotation;
    final String name = ParameterUtil.findParameterName(bindBeanList.value(), param).orElseThrow(() -> new UnsupportedOperationException("A @BindBeanList parameter was not given a name, " + "and parameter name data is not present in the class file, for: " + param.getDeclaringExecutable() + "::" + param));
    return (stmt, arg) -> {
        if (arg == null) {
            throw new IllegalArgumentException("argument is null; null was explicitly forbidden on BindBeanList");
        }
        stmt.bindBeanList(name, IterableLike.toList(arg), Arrays.asList(bindBeanList.propertyNames()));
    };
}
Also used : Arrays(java.util.Arrays) ParameterUtil(org.jdbi.v3.sqlobject.internal.ParameterUtil) Type(java.lang.reflect.Type) Parameter(java.lang.reflect.Parameter) SqlStatementCustomizerFactory(org.jdbi.v3.sqlobject.customizer.SqlStatementCustomizerFactory) Annotation(java.lang.annotation.Annotation) BindBeanList(org.jdbi.v3.sqlobject.customizer.BindBeanList) SqlStatementParameterCustomizer(org.jdbi.v3.sqlobject.customizer.SqlStatementParameterCustomizer) IterableLike(org.jdbi.v3.core.internal.IterableLike) Method(java.lang.reflect.Method) BindBeanList(org.jdbi.v3.sqlobject.customizer.BindBeanList)

Example 3 with Argument

use of org.jdbi.v3.core.argument.Argument in project jdbi by jdbi.

the class BuiltInArgumentFactory method build.

@Override
@SuppressWarnings("unchecked")
public Optional<Argument> build(Type expectedType, Object value, ConfigRegistry config) {
    Class<?> expectedClass = getErasedType(expectedType);
    if (value != null && expectedClass == Object.class) {
        expectedClass = value.getClass();
    }
    @SuppressWarnings("rawtypes") ArgBuilder v = BUILDERS.get(expectedClass);
    if (v != null) {
        return Optional.of(v.build(value));
    }
    // Enums must be bound as VARCHAR.
    if (value instanceof Enum) {
        Enum<?> enumValue = (Enum<?>) value;
        return Optional.of(STR_BUILDER.build(enumValue.name()));
    }
    if (value instanceof Optional) {
        Object nestedValue = ((Optional<?>) value).orElse(null);
        Type nestedType = findOptionalType(expectedType, nestedValue);
        return config.get(Arguments.class).findFor(nestedType, nestedValue);
    }
    return value == null ? Optional.of(config.get(Arguments.class).getUntypedNullArgument()) : Optional.empty();
}
Also used : GenericTypes.getErasedType(org.jdbi.v3.core.generic.GenericTypes.getErasedType) Type(java.lang.reflect.Type) Optional(java.util.Optional)

Example 4 with Argument

use of org.jdbi.v3.core.argument.Argument in project jdbi by jdbi.

the class SqlArrayArgumentFactory method build.

@Override
public Optional<Argument> build(Type type, Object value, ConfigRegistry config) {
    Class<?> erasedType = GenericTypes.getErasedType(type);
    if (!(erasedType.isArray() || Collection.class.isAssignableFrom(erasedType))) {
        return Optional.empty();
    }
    if (value == null) {
        return Optional.of(new NullArgument(Types.ARRAY));
    }
    Function<Type, Optional<SqlArrayType<?>>> lookup = eT -> config.get(SqlArrayTypes.class).findFor(eT);
    if (erasedType.isArray()) {
        Class<?> elementType = erasedType.getComponentType();
        return lookup.apply(elementType).map(arrayType -> new SqlArrayArgument<>(arrayType, value));
    }
    return GenericTypes.findGenericParameter(type, Collection.class).flatMap(lookup).map(arrayType -> new SqlArrayArgument<>(arrayType, value));
}
Also used : Type(java.lang.reflect.Type) Collection(java.util.Collection) Argument(org.jdbi.v3.core.argument.Argument) ArgumentFactory(org.jdbi.v3.core.argument.ArgumentFactory) NullArgument(org.jdbi.v3.core.argument.NullArgument) Optional(java.util.Optional) GenericTypes(org.jdbi.v3.core.generic.GenericTypes) Function(java.util.function.Function) ConfigRegistry(org.jdbi.v3.core.config.ConfigRegistry) Types(java.sql.Types) Type(java.lang.reflect.Type) Optional(java.util.Optional) Collection(java.util.Collection) NullArgument(org.jdbi.v3.core.argument.NullArgument)

Example 5 with Argument

use of org.jdbi.v3.core.argument.Argument in project jdbi by jdbi.

the class TestBindBean method testNoArgumentFactoryRegisteredForProperty.

@Test
public void testNoArgumentFactoryRegisteredForProperty() {
    handle.execute("create table beans (id integer, value_type varchar)");
    assertThatThrownBy(() -> handle.attach(BeanDao.class).insert(new Bean(1, ValueType.valueOf("foo")))).hasMessageContaining("No argument factory registered");
}
Also used : BindBean(org.jdbi.v3.sqlobject.customizer.BindBean) Test(org.junit.Test)

Aggregations

Type (java.lang.reflect.Type)4 Argument (org.jdbi.v3.core.argument.Argument)4 NullArgument (org.jdbi.v3.core.argument.NullArgument)3 Annotation (java.lang.annotation.Annotation)2 Method (java.lang.reflect.Method)2 Parameter (java.lang.reflect.Parameter)2 Types (java.sql.Types)2 Optional (java.util.Optional)2 ConfigRegistry (org.jdbi.v3.core.config.ConfigRegistry)2 IterableLike (org.jdbi.v3.core.internal.IterableLike)2 SqlStatementCustomizerFactory (org.jdbi.v3.sqlobject.customizer.SqlStatementCustomizerFactory)2 SqlStatementParameterCustomizer (org.jdbi.v3.sqlobject.customizer.SqlStatementParameterCustomizer)2 ParameterUtil (org.jdbi.v3.sqlobject.internal.ParameterUtil)2 Duration (java.time.Duration)1 Arrays (java.util.Arrays)1 Collection (java.util.Collection)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 Function (java.util.function.Function)1 Nonnull (javax.annotation.Nonnull)1