All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sap.cds.impl.sql.UpdateStatementBuilder Maven / Gradle / Ivy

There is a newer version: 3.4.0
Show newest version
/************************************************************************
 * © 2019-2023 SAP SE or an SAP affiliate company. All rights reserved. *
 ************************************************************************/
package com.sap.cds.impl.sql;

import static com.sap.cds.impl.builder.model.ElementRefImpl.parse;
import static com.sap.cds.impl.sql.SQLHelper.param;
import static com.sap.cds.impl.sql.SQLStatementBuilder.aliasResolver;
import static com.sap.cds.impl.sql.SpaceSeparatedCollector.joining;
import static com.sap.cds.util.CdsModelUtils.element;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.Stream.Builder;

import com.sap.cds.impl.Context;
import com.sap.cds.impl.PreparedCqnStmt.Parameter;
import com.sap.cds.jdbc.spi.SqlMapping;
import com.sap.cds.ql.cqn.CqnElementRef;
import com.sap.cds.ql.cqn.CqnUpdate;
import com.sap.cds.ql.cqn.CqnValue;
import com.sap.cds.reflect.CdsElement;
import com.sap.cds.reflect.CdsEntity;

public class UpdateStatementBuilder implements SQLStatementBuilder {

	private final CqnUpdate update;
	private final SqlMapping sqlMapping;
	private final String tableName;
	private final TokenToSQLTransformer toSQL;
	private final List params = new ArrayList<>();
	private final CdsEntity entity;

	public UpdateStatementBuilder(Context context, CqnUpdate update) {
		this.update = update;
		entity = context.getCdsModel().getEntity(update.ref().firstSegment());
		sqlMapping = context.getDbContext().getSqlMapping(entity);
		tableName = sqlMapping.tableName();
		Function aliasResolver = aliasResolver(context, entity);
		toSQL = TokenToSQLTransformer.notCollating(context, aliasResolver, entity, tableName, params);
	}

	@Override
	public SQLStatement build() {
		Builder builder = Stream.builder();
		builder.add("UPDATE");
		builder.add(tableName);
		builder.add("SET");
		Stream elements = update.elements().map(e -> {
			CqnElementRef ref = parse(e);
			CdsElement cdsEl = element(entity, ref);
			params.add(param(e, cdsEl));
			return sqlMapping.columnName(ref) + " = ?";
		});
		Stream setters = update.setters().entrySet().stream().map(setter -> {
			CqnElementRef ref = parse(setter.getKey());
			return expression(ref, setter.getValue());
		});
		builder.add(commaSeparated(Stream.concat(elements, setters)));

		update.where().map(w -> toSQL.toSQL(entity, w)).ifPresent(s -> {
			builder.add("WHERE");
			builder.add(s);
		});

		String sql = builder.build().collect(joining());

		return new SQLStatement(sql, params);
	}

	private String expression(CqnElementRef ref, CqnValue value) {
		return sqlMapping.columnName(ref) + " = " + toSQL.apply(value);
	}

	public static String commaSeparated(Stream stream) {
		return stream.collect(Collectors.joining(", ", "", ""));
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy