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

com.sap.cds.jdbc.hana.hierarchies.HierarchySubsetBuilder Maven / Gradle / Ivy

There is a newer version: 3.4.0
Show newest version
/*******************************************************************
 * © 2024 SAP SE or an SAP affiliate company. All rights reserved. *
 *******************************************************************/
package com.sap.cds.jdbc.hana.hierarchies;

import static com.sap.cds.reflect.impl.CdsElementBuilder.element;

import java.util.Optional;

import com.sap.cds.impl.parser.token.CqnBoolLiteral;
import com.sap.cds.impl.parser.token.Jsonizer;
import com.sap.cds.ql.Source;
import com.sap.cds.ql.StructuredType;
import com.sap.cds.ql.TableFunction;
import com.sap.cds.ql.cqn.CqnPredicate;
import com.sap.cds.ql.cqn.CqnSource;
import com.sap.cds.ql.cqn.CqnVisitor;
import com.sap.cds.ql.hana.HierarchySubset;
import com.sap.cds.reflect.CdsBaseType;
import com.sap.cds.reflect.CdsElementDefinition;
import com.sap.cds.reflect.CdsStructuredType;
import com.sap.cds.reflect.CdsType;
import com.sap.cds.reflect.impl.CdsSimpleTypeBuilder;
import com.sap.cds.util.CqnStatementUtils;

public class HierarchySubsetBuilder implements HierarchySubset {
	private static final CdsType INTEGER = CdsSimpleTypeBuilder.simpleType(CdsBaseType.INT32);
	private static final CdsElementDefinition DISTANCE = element("hierarchy_distance").type(INTEGER).isNotNull(true)
			.build();

	private final boolean isAncestors;
	protected final Source source;
	protected CqnPredicate startWhere;
	// distance
	private int from = 0;
	private int to = 0;

	private HierarchySubsetBuilder(Source source, boolean isAncestors) {
		this.source = source;
		this.isAncestors = isAncestors;
		if (isAncestors) {
			this.from = Integer.MIN_VALUE;
		} else {
			this.to = Integer.MAX_VALUE;
		}
	}

	public static HierarchySubsetBuilder ancestors(Source source) {
		return new HierarchySubsetBuilder(source, true);
	}

	public static HierarchySubsetBuilder descendants(Source source) {
		return new HierarchySubsetBuilder(source, false);
	}

	@Override
	public TableFunction copy(Source source) {
		HierarchySubsetBuilder impl = new HierarchySubsetBuilder(source, isAncestors);
		impl.startWhere = startWhere;
		impl.from = from; 
		impl.to = to;
		return impl;
	}

	@Override
	public HierarchySubsetBuilder startWhere(CqnPredicate startWhere) {
		this.startWhere = startWhere == CqnBoolLiteral.TRUE ? null : startWhere;
		return this;
	}

	@Override
	public Optional startWhere() {
		return Optional.ofNullable(startWhere);
	}

	@Override
	public int from() {
		return from;
	}

	@Override
	public int to() {
		return to;
	}

	@Override
	public HierarchySubsetBuilder from(int from) {
		this.from = from;
		return this;
	}

	@Override
	public HierarchySubsetBuilder to(int to) {
		this.to = to;
		return this;
	}

	@Override
	public HierarchySubsetBuilder distance(int from, int to) {
		this.from = from;
		this.to = to;
		return this;
	}

	@Override
	public HierarchySubsetBuilder distance(int distanceFromStart, boolean keepStart) {
		if (isAncestors) {
			return distance(distanceFromStart < 0 ? Integer.MIN_VALUE : -distanceFromStart, keepStart ? 0 : -1);
		}
		return distance(keepStart ? 0 : 1, distanceFromStart < 0 ? Integer.MAX_VALUE : distanceFromStart);
	}

	@Override
	public CqnSource source() {
		return source;
	}

	@Override
	public StructuredType getType() {
		return source.getType();
	}

	@Override
	public void accept(CqnVisitor visitor) {
	}

	@Override
	public String toJson() {
		Jsonizer cqn = Jsonizer.object("source", source);
		if (startWhere != null) {
			cqn.put("startWhere", startWhere);
		}
		if (from > Integer.MIN_VALUE && from < Integer.MAX_VALUE) {
			cqn.put("from", from);
		}
		if (to > Integer.MIN_VALUE && to < Integer.MAX_VALUE) {
			cqn.put("to", to);
		}

		String subset = isAncestors ? "ancestors" : "descendants";
		return Jsonizer.object(subset, cqn).toJson();
	}

	@Override
	public boolean isAncestors() {
		return isAncestors;
	}

	@Override
	public boolean isDescendants() {
		return !isAncestors;
	}
	
	@Override
	public CdsStructuredType rowType(CdsStructuredType sourceRowType) {
		return CqnStatementUtils.addElementsTo(sourceRowType, DISTANCE);
	}

	@Override
	public String name() {
		return isAncestors ? "HIERARCHY_ANCESTORS" : "HIERARCHY_DESCENDANTS";
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy