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

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

The 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.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

import com.sap.cds.impl.parser.token.Jsonizer;
import com.sap.cds.ql.CQL;
import com.sap.cds.ql.Source;
import com.sap.cds.ql.StructuredType;
import com.sap.cds.ql.cqn.CqnPredicate;
import com.sap.cds.ql.cqn.CqnSelect;
import com.sap.cds.ql.cqn.CqnSortSpecification;
import com.sap.cds.ql.cqn.CqnSource;
import com.sap.cds.ql.cqn.CqnVisitor;
import com.sap.cds.ql.hana.CqnHierarchyGenerator;
import com.sap.cds.ql.hana.Hierarchy;
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 HierarchyGeneratorBuilder implements CqnHierarchyGenerator, Hierarchy {

	private static final CdsType BIGINT = CdsSimpleTypeBuilder.simpleType(CdsBaseType.INT64);
	private static final CdsType INTEGER = CdsSimpleTypeBuilder.simpleType(CdsBaseType.INT32);
	private static final CdsElementDefinition RANK = element("hierarchy_rank").type(BIGINT).isNotNull(true).build();
	private static final CdsElementDefinition LEVEL = element("hierarchy_level").type(INTEGER).isNotNull(true).build();
	private static final CdsElementDefinition TREE_SIZE = element("hierarchy_tree_size").type(BIGINT).isNotNull(true)
			.build();

	private final List siblingOrderBy;
	private final Source source;
	private Integer depth;
	private CqnPredicate startWhere;

	private HierarchyGeneratorBuilder(Source source) {
		this.source = source;
		this.siblingOrderBy = new ArrayList<>();
	}

	public static HierarchyGeneratorBuilder create(Source source) {
		return new HierarchyGeneratorBuilder(source);
	}

	public static HierarchyGeneratorBuilder create(CqnSelect source) {
		return new HierarchyGeneratorBuilder((Source) source);
	}

	@Override
	public void accept(CqnVisitor visitor) {
	}

	@Override
	public String toJson() {
		Jsonizer cqn = Jsonizer.object("source", source);
		if (depth != null) {
			cqn.put("depth", depth);
		}
		if (startWhere != null) {
			cqn.put("startWhere", startWhere);
		}
		if (!siblingOrderBy.isEmpty()) {
			cqn.put("siblingOrderBy", siblingOrderBy);
		}
		return Jsonizer.object("hierarchy", cqn).toJson();
	}

	@Override
	public StructuredType getType() {
		// TODO add hierarchy elements ?
		return source.getType();
	}

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

	@Override
	public List orderBy() {
		return siblingOrderBy;
	}

	@Override
	public Integer depth() {
		return depth;
	}

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

	@Override
	public HierarchyGeneratorBuilder orderBy(CqnSortSpecification... siblingOrderBy) {
		return orderBy(List.of(siblingOrderBy));
	}

	@Override
	public HierarchyGeneratorBuilder orderBy(List siblingOrderBy) {
		this.siblingOrderBy.clear();
		this.siblingOrderBy.addAll(siblingOrderBy);
		return this;
	}

	@Override
	public HierarchyGeneratorBuilder orderBy(String... siblingOrderBy) {
		this.siblingOrderBy.clear();
		this.siblingOrderBy.addAll(Arrays.stream(siblingOrderBy).map(o -> CQL.get(o).asc()).toList());
		return this;
	}

	/**
	 * Restrict the depth of the hierarchy
	 * 
	 * @param depth the depth; a depth of 0 selects root nodes only
	 * @return this HierarchyImpl
	 */
	@Override
	public HierarchyGeneratorBuilder depth(Integer depth) {
		this.depth = depth;
		return this;
	}

	@Override
	public HierarchyGeneratorBuilder startWhere(CqnPredicate startWhere) {
		this.startWhere = startWhere;
		return this;
	}

	@Override
	public HierarchyGeneratorBuilder copy(Source source) {
		return create(source).depth(depth).orderBy(siblingOrderBy).startWhere(startWhere);
	}

	@Override
	public CdsStructuredType rowType(CdsStructuredType sourceRowType) {
		return CqnStatementUtils.addElementsTo(sourceRowType, RANK, LEVEL, TREE_SIZE);
	}
	
	@Override
	public String name() {
		return "HIERARCHY";
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy