use of org.jdbi.v3.core.internal.lexer.DefineStatementLexer.DEFINE in project jdbi by jdbi.
the class DefinedAttributeTemplateEngine method render.
@Override
public String render(String template, StatementContext ctx) {
StringBuilder b = new StringBuilder();
DefineStatementLexer lexer = new DefineStatementLexer(new ANTLRStringStream(template));
try {
Token t = lexer.nextToken();
while (t.getType() != EOF) {
switch(t.getType()) {
case COMMENT:
case LITERAL:
case QUOTED_TEXT:
case DOUBLE_QUOTED_TEXT:
b.append(t.getText());
break;
case DEFINE:
String text = t.getText();
String key = text.substring(1, text.length() - 1);
Object value = ctx.getAttribute(key);
if (value == null) {
throw new UnableToCreateStatementException("Undefined attribute for token '" + text + "'", ctx);
}
b.append(value);
break;
case ESCAPED_TEXT:
b.append(t.getText().substring(1));
break;
default:
break;
}
t = lexer.nextToken();
}
return b.toString();
} catch (RuntimeException e) {
throw new UnableToCreateStatementException("Error rendering SQL template: '" + template + "'", e, ctx);
}
}
use of org.jdbi.v3.core.internal.lexer.DefineStatementLexer.DEFINE in project jdbi by jdbi.
the class JdbiFactoryBean method getObject.
/**
* See {@link org.springframework.beans.factory.FactoryBean#getObject}
*/
@Override
public Jdbi getObject() throws Exception {
final Jdbi jdbi = Jdbi.create(() -> DataSourceUtils.getConnection(dataSource));
if (autoInstallPlugins) {
jdbi.installPlugins();
}
plugins.forEach(jdbi::installPlugin);
globalDefines.forEach(jdbi::define);
return jdbi;
}
use of org.jdbi.v3.core.internal.lexer.DefineStatementLexer.DEFINE 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<ThingKey> thingKeys = ...
* List<Thing> things = handle.createQuery("select * from things where (id, foo) in (<thingKeys>)")
* .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) {
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, getConfig());
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());
}
use of org.jdbi.v3.core.internal.lexer.DefineStatementLexer.DEFINE in project jdbi by jdbi.
the class DefineListFactory method createForParameter.
@Override
public SqlStatementParameterCustomizer createForParameter(Annotation annotation, Class<?> sqlObjectType, Method method, Parameter param, int index, Type type) {
final DefineList d = (DefineList) annotation;
final String name = ParameterUtil.findParameterName(d.value(), param).orElseThrow(() -> new UnsupportedOperationException("A @DefineList parameter was not given a name, " + "and parameter name data is not present in the class file, for: " + param.getDeclaringExecutable() + "::" + param));
return (stmt, arg) -> {
List<?> argsList;
if (arg instanceof List) {
argsList = (List<?>) arg;
} else if (arg instanceof Object[]) {
argsList = Arrays.asList((Object[]) arg);
} else if (arg == null) {
throw new IllegalArgumentException("A null object was passed as a @DefineList parameter. " + "@DefineList is only supported on List and array arguments");
} else {
throw new IllegalArgumentException("A " + arg.getClass() + " object was passed as a @DefineList " + "parameter. @DefineList is only supported on List and array arguments");
}
if (argsList.isEmpty()) {
throw new IllegalArgumentException("An empty list was passed as a @DefineList parameter. Can't define " + "an empty attribute.");
}
// Uses stream match, cause the Java 9 ImmutableList implementation throws an NPE if asked `contains(null)`
if (argsList.stream().anyMatch(Objects::isNull)) {
throw new IllegalArgumentException("A @DefineList parameter was passed a list with null values in it.");
}
stmt.defineList(name, argsList);
};
}
use of org.jdbi.v3.core.internal.lexer.DefineStatementLexer.DEFINE in project jdbi by jdbi.
the class DefineFactory method createForParameter.
@Override
public SqlStatementParameterCustomizer createForParameter(Annotation annotation, Class<?> sqlObjectType, Method method, Parameter param, int index, Type type) {
Define define = (Define) annotation;
final String name = ParameterUtil.findParameterName(define.value(), param).orElseThrow(() -> new UnsupportedOperationException("A @Define parameter was not given a name, " + "and parameter name data is not present in the class file, for: " + param.getDeclaringExecutable() + "::" + param));
return (stmt, arg) -> stmt.define(name, arg);
}
Aggregations