in mapper-processor/src/main/java/com/datastax/oss/driver/internal/mapper/processor/dao/DaoIncrementMethodGenerator.java [228:315]
private void generatePrepareRequest(
MethodSpec.Builder methodBuilder,
String requestName,
EntityDefinition entityDefinition,
String helperFieldName,
List<? extends VariableElement> incrementParameters) {
if (incrementParameters.isEmpty()) {
context
.getMessager()
.error(
methodElement,
"%s method must take at least one parameter representing an increment to a "
+ "counter column",
Increment.class.getSimpleName());
return;
}
methodBuilder
.addStatement("$L.throwIfKeyspaceMissing()", helperFieldName)
.addCode(
"$[$1T $2L = (($3L.getKeyspaceId() == null)\n"
+ "? $4T.update($3L.getTableId())\n"
+ ": $4T.update($3L.getKeyspaceId(), $3L.getTableId()))",
SimpleStatement.class,
requestName,
helperFieldName,
QueryBuilder.class);
// Add an increment clause for every non-PK parameter. Example: for a parameter `long oneStar`
// => `.append("one_star", QueryBuilder.bindMarker("oneStar"))`
for (VariableElement parameter : incrementParameters) {
CodeBlock cqlName = null;
CqlName annotation = parameter.getAnnotation(CqlName.class);
if (annotation != null) {
// If a CQL name is provided, use that
cqlName = CodeBlock.of("$S", annotation.value());
} else {
// Otherwise, try to match the parameter to an entity property based on the names, for
// example parameter `oneStar` matches `ProductRating.getOneStar()`.
for (PropertyDefinition property : entityDefinition.getRegularColumns()) {
if (property.getJavaName().equals(parameter.getSimpleName().toString())) {
cqlName = property.getCqlName();
break;
}
}
if (cqlName == null) {
List<String> javaNames =
StreamSupport.stream(entityDefinition.getRegularColumns().spliterator(), false)
.map(PropertyDefinition::getJavaName)
.collect(Collectors.toList());
context
.getMessager()
.error(
parameter,
"Could not match '%s' with any counter column in %s (expected one of: %s). "
+ "You can also specify a CQL name directly with @%s.",
parameter.getSimpleName(),
entityDefinition.getClassName().simpleName(),
javaNames,
CqlName.class.getSimpleName());
// Don't return abruptly, execute the rest of the method to finish the Java statement
// cleanly (otherwise JavaPoet throws an error). The generated statement will be
// incorrect, but that doesn't matter since we've already thrown a compile error.
break;
}
}
// Always use the parameter name. This is what the binding code will expect (see
// GeneratedCodePatterns.bindParameters call in generate())
String bindMarkerName = parameter.getSimpleName().toString();
// We use `append` to generate "c=c+?". QueryBuilder also has `increment` that produces
// "c+=?", but that doesn't work with Cassandra 2.1.
methodBuilder.addCode(
"\n.append($1L, $2T.bindMarker($3S))", cqlName, QueryBuilder.class, bindMarkerName);
}
for (PropertyDefinition property : entityDefinition.getPrimaryKey()) {
methodBuilder.addCode(
"\n.where($1T.column($2L).isEqualTo($3T.bindMarker($2L)))",
Relation.class,
property.getCqlName(),
QueryBuilder.class);
}
methodBuilder.addCode("\n.build()$];\n");
}