
com.blazebit.persistence.impl.BaseUpdateCriteriaBuilderImpl Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2015 Blazebit.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.blazebit.persistence.impl;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import com.blazebit.persistence.BaseUpdateCriteriaBuilder;
import com.blazebit.persistence.MultipleSubqueryInitiator;
import com.blazebit.persistence.SubqueryInitiator;
import com.blazebit.persistence.impl.builder.expression.ExpressionBuilder;
import com.blazebit.persistence.impl.builder.expression.ExpressionBuilderEndedListener;
import com.blazebit.persistence.impl.expression.Expression;
import com.blazebit.persistence.impl.expression.SubqueryExpression;
import com.blazebit.persistence.impl.expression.VisitorAdapter;
import com.blazebit.persistence.spi.DbmsStatementType;
/**
*
* @param The query result type
* @author Christian Beikov
* @since 1.1.0
*/
public class BaseUpdateCriteriaBuilderImpl, Y> extends AbstractModificationCriteriaBuilder implements BaseUpdateCriteriaBuilder, SubqueryBuilderListener, ExpressionBuilderEndedListener {
private final VisitorAdapter parameterRegistrationVisitor;
private final Map setAttributes = new LinkedHashMap();
private SubqueryInternalBuilder currentSubqueryBuilder;
private String currentAttribute;
public BaseUpdateCriteriaBuilderImpl(MainQuery mainQuery, boolean isMainQuery, Class clazz, String alias, String cteName, Class> cteClass, Y result, CTEBuilderListener listener) {
super(mainQuery, isMainQuery, DbmsStatementType.UPDATE, clazz, alias, cteName, cteClass, result, listener);
this.parameterRegistrationVisitor = parameterManager.getParameterRegistrationVisitor();
}
@Override
@SuppressWarnings("unchecked")
public X set(String attributeName, Object value) {
verifyBuilderEnded();
checkAttribute(attributeName);
Expression attributeExpression = parameterManager.addParameterExpression(value);
setAttributes.put(attributeName, attributeExpression);
return (X) this;
}
@Override
@SuppressWarnings("unchecked")
public X setExpression(String attributeName, String expression) {
verifyBuilderEnded();
checkAttribute(attributeName);
Expression attributeExpression = expressionFactory.createScalarExpression(expression);
attributeExpression.accept(parameterRegistrationVisitor);
setAttributes.put(attributeName, attributeExpression);
return (X) this;
}
@SuppressWarnings("unchecked")
@Override
public SubqueryInitiator set(String attribute) {
verifySubqueryBuilderEnded();
checkAttribute(attribute);
this.currentAttribute = attribute;
return subqueryInitFactory.createSubqueryInitiator((X) this, this);
}
@SuppressWarnings("unchecked")
@Override
public MultipleSubqueryInitiator setSubqueries(String attribute, String expression) {
verifySubqueryBuilderEnded();
checkAttribute(attribute);
this.currentAttribute = attribute;
Expression expr = expressionFactory.createSimpleExpression(expression, true);
MultipleSubqueryInitiator initiator = new MultipleSubqueryInitiatorImpl((X) this, expr, this, subqueryInitFactory);
return initiator;
}
private void verifySubqueryBuilderEnded() {
if (currentAttribute != null) {
throw new BuilderChainingException("An initiator was not ended properly.");
}
if (currentSubqueryBuilder != null) {
throw new BuilderChainingException("An subquery builder was not ended properly.");
}
}
@Override
public void onBuilderEnded(ExpressionBuilder builder) {
if (currentAttribute == null) {
throw new BuilderChainingException("There was an attempt to end a builder that was not started or already closed.");
}
Expression attributeExpression = builder.getExpression();
attributeExpression.accept(parameterRegistrationVisitor);
setAttributes.put(currentAttribute, attributeExpression);
}
@Override
public void onBuilderEnded(SubqueryInternalBuilder builder) {
if (currentAttribute == null) {
throw new BuilderChainingException("There was an attempt to end a builder that was not started or already closed.");
}
if (currentSubqueryBuilder == null) {
throw new BuilderChainingException("There was an attempt to end a builder that was not started or already closed.");
}
Expression attributeExpression = new SubqueryExpression(builder);
attributeExpression.accept(parameterRegistrationVisitor);
setAttributes.put(currentAttribute, attributeExpression);
currentAttribute = null;
currentSubqueryBuilder = null;
}
@Override
public void onBuilderStarted(SubqueryInternalBuilder builder) {
if (currentAttribute == null) {
throw new BuilderChainingException("There was an attempt to start a builder without an originating initiator.");
}
if (currentSubqueryBuilder != null) {
throw new BuilderChainingException("There was an attempt to start a builder but a previous builder was not ended.");
}
currentSubqueryBuilder = builder;
}
@Override
public void onReplaceBuilder(SubqueryInternalBuilder oldBuilder, SubqueryInternalBuilder newBuilder) {
throw new IllegalArgumentException("Replace not valid!");
}
@Override
public void onInitiatorStarted(SubqueryInitiator> initiator) {
throw new IllegalArgumentException("Initiator started not valid!");
}
private void checkAttribute(String attributeName) {
// Just do that to assert the attribute exists
JpaUtils.getBasicAttributePath(getMetamodel(), entityType, attributeName);
Expression attributeExpression = setAttributes.get(attributeName);
if (attributeExpression != null) {
throw new IllegalArgumentException("The attribute [" + attributeName + "] has already been bound!");
}
}
@Override
protected void buildBaseQueryString(StringBuilder sbSelectFrom, boolean externalRepresentation) {
sbSelectFrom.append("UPDATE ");
sbSelectFrom.append(entityType.getName()).append(' ');
sbSelectFrom.append(entityAlias);
sbSelectFrom.append(" SET ");
queryGenerator.setQueryBuffer(sbSelectFrom);
SimpleQueryGenerator.BooleanLiteralRenderingContext oldBooleanLiteralRenderingContext = queryGenerator.setBooleanLiteralRenderingContext(SimpleQueryGenerator.BooleanLiteralRenderingContext.CASE_WHEN);
Iterator> setAttributeIter = setAttributes.entrySet().iterator();
if (setAttributeIter.hasNext()) {
Map.Entry attributeEntry = setAttributeIter.next();
sbSelectFrom.append(attributeEntry.getKey());
sbSelectFrom.append(" = ");
attributeEntry.getValue().accept(queryGenerator);
while (setAttributeIter.hasNext()) {
attributeEntry = setAttributeIter.next();
sbSelectFrom.append(',');
sbSelectFrom.append(attributeEntry.getKey());
sbSelectFrom.append(" = ");
attributeEntry.getValue().accept(queryGenerator);
}
}
queryGenerator.setBooleanLiteralRenderingContext(oldBooleanLiteralRenderingContext);
appendWhereClause(sbSelectFrom);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy