use of com.datastax.oss.driver.api.mapper.annotations.Delete in project java-driver by datastax.
the class DaoDeleteMethodGenerator method generate.
@Override
public Optional<MethodSpec> generate() {
Delete annotation = methodElement.getAnnotation(Delete.class);
assert annotation != null;
if (annotation.ifExists() && !annotation.customIfClause().isEmpty()) {
context.getMessager().error(methodElement, "Invalid annotation parameters: %s cannot have both ifExists and customIfClause", Delete.class.getSimpleName());
return Optional.empty();
}
// Validate the arguments: either an entity instance, or the PK components (in the latter case,
// the entity class has to be provided via the annotation).
// In either case, a Function<BoundStatementBuilder, BoundStatementBuilder> can be added in last
// position.
List<? extends VariableElement> parameters = methodElement.getParameters();
VariableElement boundStatementFunction = findBoundStatementFunction(methodElement);
if (boundStatementFunction != null) {
parameters = parameters.subList(0, parameters.size() - 1);
}
TypeElement entityElement;
EntityDefinition entityDefinition;
boolean hasEntityParameter;
if (parameters.isEmpty()) {
context.getMessager().error(methodElement, "Wrong number of parameters: %s methods with no custom clause " + "must take either an entity instance, or the primary key components", Delete.class.getSimpleName());
return Optional.empty();
}
String customWhereClause = annotation.customWhereClause();
String customIfClause = annotation.customIfClause();
VariableElement firstParameter = parameters.get(0);
entityElement = EntityUtils.asEntityElement(firstParameter, typeParameters);
hasEntityParameter = (entityElement != null);
// the number of primary key parameters provided, if -1 this implies a custom
// where clause where number of parameters that are primary key are irrelevant.
final int primaryKeyParameterCount;
if (hasEntityParameter) {
if (!customWhereClause.isEmpty()) {
context.getMessager().error(methodElement, "Invalid parameter list: %s methods that have a custom where clause " + "must not take an Entity (%s) as a parameter", Delete.class.getSimpleName(), entityElement.getSimpleName());
}
entityDefinition = context.getEntityFactory().getDefinition(entityElement);
primaryKeyParameterCount = entityDefinition.getPrimaryKey().size();
} else {
entityElement = getEntityClassFromAnnotation(Delete.class);
if (entityElement == null) {
context.getMessager().error(methodElement, "Missing entity class: %s methods that do not operate on an entity " + "instance must have an 'entityClass' argument", Delete.class.getSimpleName());
return Optional.empty();
} else {
entityDefinition = context.getEntityFactory().getDefinition(entityElement);
}
if (customWhereClause.isEmpty()) {
/* if a custom if clause is provided, the whole primary key must also be provided.
* we only do this check if there is no custom where clause as the order of
* keys may differ in that case.*/
List<? extends VariableElement> primaryKeyParameters = parameters;
if (!customIfClause.isEmpty()) {
if (primaryKeyParameters.size() < entityDefinition.getPrimaryKey().size()) {
List<TypeName> primaryKeyTypes = entityDefinition.getPrimaryKey().stream().map(d -> d.getType().asTypeName()).collect(Collectors.toList());
context.getMessager().error(methodElement, "Invalid parameter list: %s methods that have a custom if clause" + "must specify the entire primary key (expected primary keys of %s: %s)", Delete.class.getSimpleName(), entityElement.getSimpleName(), primaryKeyTypes);
return Optional.empty();
} else {
// restrict parameters to primary key length.
primaryKeyParameters = primaryKeyParameters.subList(0, entityDefinition.getPrimaryKey().size());
}
}
primaryKeyParameterCount = primaryKeyParameters.size();
if (!EntityUtils.areParametersValid(entityElement, entityDefinition, primaryKeyParameters, Delete.class, context, methodElement, processedType, "do not operate on an entity instance and lack a custom where clause")) {
return Optional.empty();
}
} else {
primaryKeyParameterCount = -1;
}
}
// Validate the return type:
DaoReturnType returnType = parseAndValidateReturnType(getSupportedReturnTypes(), Delete.class.getSimpleName());
if (returnType == null) {
return Optional.empty();
}
// Generate the method
String helperFieldName = enclosingClass.addEntityHelperField(ClassName.get(entityElement));
String statementName = enclosingClass.addPreparedStatement(methodElement, (methodBuilder, requestName) -> generatePrepareRequest(methodBuilder, requestName, helperFieldName, primaryKeyParameterCount));
CodeBlock.Builder createStatementBlock = CodeBlock.builder();
createStatementBlock.addStatement("$T boundStatementBuilder = $L.boundStatementBuilder()", BoundStatementBuilder.class, statementName);
populateBuilderWithStatementAttributes(createStatementBlock, methodElement);
populateBuilderWithFunction(createStatementBlock, boundStatementFunction);
int nextParameterIndex = 0;
if (hasEntityParameter) {
warnIfCqlNamePresent(Collections.singletonList(firstParameter));
// Bind entity's PK properties
for (PropertyDefinition property : entityDefinition.getPrimaryKey()) {
GeneratedCodePatterns.setValue(property.getCqlName(), property.getType(), CodeBlock.of("$L.$L()", firstParameter.getSimpleName(), property.getGetterName()), "boundStatementBuilder", createStatementBlock, enclosingClass);
}
nextParameterIndex = 1;
} else if (customWhereClause.isEmpty()) {
// The PK components are passed as arguments to the method (we've already checked that the
// types match).
List<CodeBlock> primaryKeyNames = entityDefinition.getPrimaryKey().stream().map(PropertyDefinition::getCqlName).collect(Collectors.toList()).subList(0, primaryKeyParameterCount);
List<? extends VariableElement> bindMarkers = parameters.subList(0, primaryKeyParameterCount);
warnIfCqlNamePresent(bindMarkers);
GeneratedCodePatterns.bindParameters(bindMarkers, primaryKeyNames, createStatementBlock, enclosingClass, context, false);
nextParameterIndex = primaryKeyNames.size();
}
// Bind any remaining parameters, assuming they are values for a custom WHERE or IF clause
if (nextParameterIndex < parameters.size()) {
if (customIfClause.isEmpty() && customWhereClause.isEmpty()) {
context.getMessager().error(methodElement, "Wrong number of parameters: %s methods can only have additional " + "parameters if they specify a custom WHERE or IF clause", Delete.class.getSimpleName());
}
List<? extends VariableElement> bindMarkers = parameters.subList(nextParameterIndex, parameters.size());
if (validateCqlNamesPresent(bindMarkers)) {
GeneratedCodePatterns.bindParameters(bindMarkers, createStatementBlock, enclosingClass, context, false);
} else {
return Optional.empty();
}
}
createStatementBlock.addStatement("$T boundStatement = boundStatementBuilder.build()", BoundStatement.class);
return crudMethod(createStatementBlock, returnType, helperFieldName);
}
use of com.datastax.oss.driver.api.mapper.annotations.Delete in project java-driver by datastax.
the class DaoDeleteMethodGenerator method generatePrepareRequest.
private void generatePrepareRequest(MethodSpec.Builder methodBuilder, String requestName, String helperFieldName, int parameterSize) {
Delete delete = methodElement.getAnnotation(Delete.class);
boolean ifExists = delete.ifExists();
String customWhereClause = delete.customWhereClause();
String customIfClause = delete.customIfClause();
methodBuilder.addCode("$[$T $L = $L", SimpleStatement.class, requestName, helperFieldName);
if (!customWhereClause.isEmpty()) {
methodBuilder.addCode(".deleteStart().whereRaw($S)", customWhereClause);
} else {
methodBuilder.addCode(".deleteByPrimaryKeyParts($L)", parameterSize);
}
if (ifExists) {
methodBuilder.addCode(".ifExists()");
} else if (!customIfClause.isEmpty()) {
methodBuilder.addCode(".ifRaw($S)", customIfClause);
}
methodBuilder.addCode(".build();$]\n");
}
use of com.datastax.oss.driver.api.mapper.annotations.Delete in project java-driver by datastax.
the class DaoImplementationGeneratorTest method should_generate_delete_method_returning_ReactiveResultSet.
@Test
public void should_generate_delete_method_returning_ReactiveResultSet() {
Compilation compilation = compileWithMapperProcessor("test", Collections.emptyList(), ENTITY_SPEC, TypeSpec.interfaceBuilder(ClassName.get("test", "ProductDao")).addModifiers(Modifier.PUBLIC).addAnnotation(Dao.class).addMethod(MethodSpec.methodBuilder("delete").addAnnotation(Delete.class).addParameter(ParameterSpec.builder(ENTITY_CLASS_NAME, "product").build()).returns(REACTIVE_RESULT_CLASS_NAME).addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT).build()).build());
assertThat(compilation).succeededWithoutWarnings();
assertGeneratedFileContains(compilation, "public ReactiveResultSet delete(Product product)");
assertGeneratedFileContains(compilation, "return executeReactive(boundStatement);");
}
Aggregations