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

com.sap.cds.impl.JdbcDataSourceAdapter 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;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Locale;
import java.util.Optional;

import com.sap.cds.DataStoreConfiguration;
import com.sap.cds.impl.docstore.DocStoreDeleteStatementBuilder;
import com.sap.cds.impl.docstore.DocStoreSelectStatementBuilder;
import com.sap.cds.impl.docstore.DocStoreUpdateStatementBuilder;
import com.sap.cds.impl.docstore.DocStoreUtils;
import com.sap.cds.impl.localized.LocaleUtils;
import com.sap.cds.impl.qat.QatSelectableNode;
import com.sap.cds.impl.sql.DeleteStatementBuilder;
import com.sap.cds.impl.sql.InsertStatementBuilder;
import com.sap.cds.impl.sql.SQLStatementBuilder.SQLStatement;
import com.sap.cds.impl.sql.SelectStatementBuilder;
import com.sap.cds.impl.sql.UpdateStatementBuilder;
import com.sap.cds.impl.sql.UpsertStatementBuilder;
import com.sap.cds.jdbc.spi.StatementResolver;
import com.sap.cds.ql.cqn.CqnFilterableStatement;
import com.sap.cds.ql.cqn.CqnSelect;
import com.sap.cds.ql.cqn.CqnStatement;

public class JdbcDataSourceAdapter implements SQLDataSourceAdapter {

	private static final ArrayDeque ROOT = new ArrayDeque<>();
	private final Context context;
	private final StatementResolver statementResolver;
	private final LocaleUtils localeUtils;
	private final DocStoreUtils docStoreUtils;

	public JdbcDataSourceAdapter(Context context) {
		this.context = context;
		this.statementResolver = context.getDbContext().getStatementResolver();
		this.localeUtils = new LocaleUtils(context.getCdsModel(), context.getDataStoreConfiguration());
		this.docStoreUtils = new DocStoreUtils(context.getCdsModel());
	}

	@Override
	public SQLStatement process(CqnStatement statement) {
		if (docStoreUtils.targetsDocStore(statement)) {
			return getDocStoreSqlStatement(statement);
		}
		return getColumnStoreSqlStatement(statement);
	}

	private SQLStatement getDocStoreSqlStatement(CqnStatement statement) {
		assertThatDocStoreSupportIsEnabled();

		if (statement.isSelect()) {
			return new DocStoreSelectStatementBuilder(context, statement.asSelect()).build();
		}

		if (statement.isInsert()) {
			return DocStoreUtils.getDocStoreInsertStatement(statement.asInsert(), context);
		}

		if (statement.isUpdate()) {
			return new DocStoreUpdateStatementBuilder(context, statement.asUpdate()).build();
		}

		if (statement.isDelete()) {
			return new DocStoreDeleteStatementBuilder(context, statement.asDelete()).build();
		}

		throw new UnsupportedOperationException("Unsupported statement type: " + statement);
	}

	private SQLStatement getColumnStoreSqlStatement(CqnStatement statement) {
		if (statement.isSelect()) {
			CqnSelect select = statement.asSelect();
			return appendCollation(new SelectStatementBuilder(context, new ArrayList<>(), select, ROOT).build(),
					select);
		}
		if (statement.isInsert()) {
			return new InsertStatementBuilder(context, statement.asInsert()).build();
		}
		if (statement.isUpsert()) {
			return new UpsertStatementBuilder(context, statement.asUpsert()).build();
		}
		if (statement.isUpdate()) {
			return appendCollation(new UpdateStatementBuilder(context, statement.asUpdate()).build(),
					statement.asUpdate());
		}
		if (statement.isDelete()) {
			return appendCollation(new DeleteStatementBuilder(context, statement.asDelete()).build(),
					statement.asDelete());
		}
		throw new UnsupportedOperationException("Unsupported statement type: " + statement);
	}

	private SQLStatement appendCollation(SQLStatement sqlStatement, CqnFilterableStatement statement) {
		Locale locale = context.getSessionContext().getLocale();
		if (localeUtils.requiresCollationClause(statement, locale)) { // TODO only required on HANA
			Optional collationClause = statementResolver.withCollation(statement, locale);
			if (collationClause.isPresent()) {
				String sql = String.join(" ", sqlStatement.sql(), collationClause.get());
				return new SQLStatement(sql, sqlStatement.params());
			}
		}
		return sqlStatement;
	}

	public void assertThatDocStoreSupportIsEnabled() {
		if (!context.getDataStoreConfiguration().getProperty(DataStoreConfiguration.DOCSTORE_INTEGRATION_ENABLED,
				false)) {
			throw new UnsupportedOperationException(
					"Can't handle an entity annotated as doc-store enabled: DocStore integration is not enabled.");
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy