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

com.sap.cds.impl.ResultImpl Maven / Gradle / Ivy

/************************************************************************
 * © 2019-2024 SAP SE or an SAP affiliate company. All rights reserved. *
 ************************************************************************/
package com.sap.cds.impl;

import static java.util.stream.Collectors.toList;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import com.google.common.collect.Lists;
import com.sap.cds.EmptyResultException;
import com.sap.cds.NonUniqueResultException;
import com.sap.cds.Result;
import com.sap.cds.ResultBuilder;
import com.sap.cds.Row;
import com.sap.cds.impl.parser.token.Jsonizer;
import com.sap.cds.reflect.CdsEntity;
import com.sap.cds.reflect.CdsStructuredType;

public class ResultImpl extends ResultBuilder {

	private CdsEntity entity;
	private CdsStructuredType rowType;
	private List> rows = new ArrayList<>();
	private long[] rowCounts = new long[0];
	private long inlineCount = -1l;

	public static ResultImpl from(Result result) {
		if (!(result instanceof MaterializedResult)) {
			throw new UnsupportedOperationException(
					"Result builder not yet supported for type: " + result.getClass().getName());
		}
		ResultImpl builder = new ResultImpl();
		MaterializedResult r = (MaterializedResult) result;
		builder.entity = r.entity;
		builder.rowType = r.rowType;
		builder.rows = new ArrayList<>();
		r.rows.forEach(builder.rows::add);
		builder.rowCounts = r.rowCount;
		builder.inlineCount = r.inlineCount;

		return builder;
	}

	@Override
	public ResultBuilder entity(CdsEntity entity) {
		this.entity = entity;

		return this;
	}

	@Override
	public ResultImpl rowType(CdsStructuredType rowType) {
		this.rowType = rowType;

		return this;
	}

	@SuppressWarnings("unchecked")
	@Override
	public ResultImpl rows(List> rows) {
		this.rows = (List>) rows;

		return this;
	}

	@Override
	public ResultImpl rows(Stream> rows) {
		this.rows = rows.collect(toList());

		return this;
	}

	@Override
	public ResultImpl rowCount(long[] rc) {
		this.rowCounts = Arrays.copyOf(rc, rc.length);

		return this;
	}

	@Override
	public long rowCount() {
		return rows.size();
	}

	@Override
	public ResultImpl inlineCount(long inlineCount) {
		this.inlineCount = inlineCount;

		return this;
	}

	@Override
	public Result result() {
		List rows = this.rows.stream().map(r -> RowImpl.row(entity, r)).collect(toList());
		return new MaterializedResult(entity, rowType, rows, rowCounts, inlineCount);
	}

	private static long countRows(long[] counts) {
		return Arrays.stream(counts).sum();
	}

	private static class MaterializedResult implements Result {
		private final CdsEntity entity;
		private final CdsStructuredType rowType;
		private final Iterable rows;
		private final long[] rowCount;
		private final long inlineCount;

		public MaterializedResult(CdsEntity entity, CdsStructuredType rowType, Iterable rows, long[] rowCount,
				long inlineCount) {
			this.entity = entity;
			this.rowType = rowType;
			this.rows = rows;
			this.rowCount = rowCount;
			this.inlineCount = inlineCount;
		}

		@Override
		public CdsStructuredType rowType() {
			return rowType;
		}

		@Override
		public String toJson() {
			return Jsonizer.json(rows);
		}

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

		@Override
		public Iterator iterator() {
			return rows.iterator();
		}

		@Override
		public Row single() {
			Iterator iterator = iterator();
			if (!iterator.hasNext()) {
				throw new EmptyResultException("Result is empty");
			}
			Row row = iterator.next();
			if (iterator.hasNext()) {
				throw new NonUniqueResultException("Result contains more than one row");
			}
			return row;
		}

		@Override
		public  T single(Class type) {
			return single().as(type);
		}

		@Override
		public Optional first() {
			return stream().findFirst();
		}

		@Override
		public  Optional first(Class type) {
			return stream().findFirst().map(row -> row.as(type));
		}

		@Override
		public Stream stream() {
			return StreamSupport.stream(rows.spliterator(), false);
		}

		@Override
		public  Stream streamOf(Class type) {
			return stream().map(row -> row.as(type));
		}

		@Override
		public List list() {
			return Lists.newArrayList(rows.iterator());
		}

		@Override
		public  List listOf(Class type) {
			return streamOf(type).collect(Collectors.toList());
		}

		@Override
		public long rowCount() {
			return countRows(rowCount);
		}

		@Override
		public long rowCount(int batch) {
			return rowCount[batch];
		}

		@Override
		public int batchCount() {
			return rowCount.length;
		}

		@Override
		public long inlineCount() {
			return inlineCount;
		}
	}

	@Override
	public ResultBuilder addUpdatedRows(long updateCount, Map updateData) {
		int length = rowCounts.length;
		long[] newCounts = new long[length + 1];
		System.arraycopy(rowCounts, 0, newCounts, 0, length);
		newCounts[length] = updateCount;
		rowCounts = newCounts;
		rows.add(updateData);

		return this;
	}

	@Override
	public ResultBuilder addUpdatedRows(long[] updateCounts, List> updateData) {
		this.rowCounts = Arrays.copyOf(updateCounts, updateCounts.length);

		return rows(updateData);
	}

	public static class Factory implements ResultBuilder.Factory {
		@Override
		public ResultBuilder create() {
			return new ResultImpl();
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy