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

com.sap.cds.ql.impl.UpdateBuilder Maven / Gradle / Ivy

There is a newer version: 3.8.0
Show newest version
/**************************************************************************
 * (C) 2019-2023 SAP SE or an SAP affiliate company. All rights reserved. *
 **************************************************************************/
package com.sap.cds.ql.impl;

import static com.sap.cds.impl.builder.model.StructuredTypeImpl.structuredType;
import static com.sap.cds.impl.builder.model.StructuredTypeRefImpl.typeRef;
import static com.sap.cds.util.DataUtils.deepMapKeys;
import static java.util.Collections.emptyMap;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Stream;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.sap.cds.impl.parser.token.Jsonizer;
import com.sap.cds.ql.StructuredType;
import com.sap.cds.ql.Update;
import com.sap.cds.ql.cqn.CqnStructuredTypeRef;
import com.sap.cds.ql.cqn.CqnUpdate;
import com.sap.cds.ql.cqn.Modifier;
import com.sap.cds.util.DataUtils;

public class UpdateBuilder> extends FilterableStatementBuilder>
		implements Update {

	private final T entity;
	private final List> entries = new ArrayList<>();

	private UpdateBuilder(T entity) {
		this.entity = entity;
		this.entries.add(emptyMap());
	}

	/**
	 * Creates an update statement to update entries from a specified entity set.
	 *
	 * @param     the type of the entity set
	 * @param entity the structured type representing the entity set
	 * @return the update statement
	 */
	public static > UpdateBuilder entity(T entity) {
		return new UpdateBuilder<>(entity);
	}

	public static UpdateBuilder> entity(String entityName) {
		return entity(typeRef(entityName));
	}

	/**
	 * Creates an update statement to update entries of a specified entity set.
	 *
	 * @param ref the ref to the entity
	 * @return the update statement
	 */
	public static UpdateBuilder> entity(CqnStructuredTypeRef ref) {
		return new UpdateBuilder<>(structuredType(ref));
	}

	/**
	 * Copies the given {@link CqnUpdate} into an {@link Update} builder.
	 *
	 * @param update the update statement to copy
	 * @return a copy of the given update statement
	 */
	public static UpdateBuilder> copy(CqnUpdate update) {
		return copy(update, ExpressionVisitor.COPY);
	}

	/**
	 * Copies the given {@link CqnUpdate} into an {@link Update} builder, applying
	 * the provided {@link Modifier}.
	 *
	 * @param update   the update statement to copy
	 * @param modifier the modifier to apply on the update statement
	 * @return the update statement
	 */
	public static UpdateBuilder> copy(CqnUpdate update, Modifier modifier) {
		CqnStructuredTypeRef ref = ExpressionVisitor.copy(update.ref(), modifier);
		UpdateBuilder> copy = entity(ref);
		copy.where = modifier.where(ExpressionVisitor.copy(update.where(), modifier));
		copy.hints(update.hints());

		return copy.entries(update.entries());
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static UpdateBuilder copyShallow(CqnUpdate statement) {
		UpdateBuilder> original = (UpdateBuilder>) statement;

		UpdateBuilder> copy = new UpdateBuilder<>(original.entity);
		copy.entries.clear();
		copy.entries.addAll(original.entries);
		copy.where = original.where;
		copy.hints.putAll(original.hints);
		return copy;
	}

	@Override
	public UpdateBuilder data(Map data) {
		this.entries.clear();
		addEntry(data);

		return this;
	}

	@Override
	public UpdateBuilder data(String key, Object value) {
		return data(Collections.singletonMap(key, value));
	}

	public UpdateBuilder entry(Map entry) {
		return data(entry);
	}

	@Override
	public UpdateBuilder entries(Iterable> entries) {
		this.entries.clear();
		entries.forEach(this::addEntry);
		if (this.entries.isEmpty()) {
			this.entries.add(emptyMap());
		}

		return this;
	}

	private void addEntry(Map entry) {
		entries.add(DataUtils.copyMap(entry));
	}

	@Override
	public CqnStructuredTypeRef ref() {
		return typeRef(entity);
	}

	@Override
	public String toJson() {
		Jsonizer cqn = Jsonizer.object("entity", ref());
		if (entries.size() == 1) {
			cqn.put("data", entries.get(0));
		} else {
			ArrayNode dta = cqn.array("entries");
			entries.forEach(dta::addPOJO);
		}
		where().ifPresent(w -> {
			ArrayNode whereArr = cqn.array("where");
			w.tokens().forEach(whereArr::addPOJO);
		});

		return Jsonizer.object("UPDATE", cqn).toJson();
	}

	@Override
	public String toString() {
		return toJson();
	}

	@Override
	public Map data() {
		return entries.get(0);
	}

	@Override
	public List> entries() {
		return entries; // NOSONAR
	}

	@Override
	public Stream elements() {
		Set all = new TreeSet<>();
		for (Map map : entries) {
			deepMapKeys(map).forEach(all::add);
		}

		return all.stream();
	}

	@Override
	@SuppressWarnings("unchecked")
	T getType() {
		return (T) entity.getType();
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy