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

com.scalar.db.sql.springdata.ScalarDbJdbcAggregateTemplate Maven / Gradle / Ivy

package com.scalar.db.sql.springdata;

import com.scalar.db.sql.util.SqlUtils;
import java.sql.ResultSet;
import java.util.Collections;
import javax.annotation.Nonnull;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jdbc.core.JdbcAggregateTemplate;
import org.springframework.data.jdbc.core.convert.DataAccessStrategy;
import org.springframework.data.jdbc.core.convert.JdbcConverter;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;

/**
 * An extended ${@link JdbcAggregateTemplate} customized for ScalarDB SQL. This prevents users from
 * using some APIs that are not supported in ScalarDB by throwing ${@link
 * UnsupportedOperationException}.
 */
public class ScalarDbJdbcAggregateTemplate extends JdbcAggregateTemplate {
  private final NamedParameterJdbcOperations operations;

  public ScalarDbJdbcAggregateTemplate(
      ApplicationContext publisher,
      RelationalMappingContext context,
      JdbcConverter converter,
      DataAccessStrategy dataAccessStrategy,
      NamedParameterJdbcOperations operations) {
    super(publisher, context, converter, dataAccessStrategy);
    this.operations = operations;
  }

  public ScalarDbJdbcAggregateTemplate(
      ApplicationEventPublisher publisher,
      RelationalMappingContext context,
      JdbcConverter converter,
      DataAccessStrategy dataAccessStrategy,
      NamedParameterJdbcOperations operations) {
    super(publisher, context, converter, dataAccessStrategy);
    this.operations = operations;
  }

  @Override
  @Nonnull
  public  T save(@Nonnull T instance) {
    throw new UnsupportedOperationException(
        "This operation isn't supported in ScalarDB SQL: save. "
            + "The original method depends on underlying database's autoincrement ID column, "
            + "but ScalarDB SQL doesn't support the feature. Please use insert() or update() of ScalarDbRepository");
  }

  @Override
  public long count(@Nonnull Class domainType) {
    // ScalarDB SQL doesn't have COUNT() function.
    int count = 0;
    for (Object unused : findAll(domainType)) {
      count++;
    }
    return count;
  }

  // Spring Data JDBC issues `SELECT ... FROM ... ORDER BY ...` (without WHERE) that isn't supported
  // by ScalarDB SQL.
  @Override
  @Nonnull
  public  Iterable findAll(@Nonnull Class domainType, @Nonnull Sort sort) {
    throw new UnsupportedOperationException(
        "This operation isn't supported in ScalarDB SQL: findAll(Sort)");
  }

  // Spring Data JDBC implicitly issues `SELECT COUNT(*) FROM ...` that isn't supported by ScalarDB
  // SQL.
  @Override
  @Nonnull
  public  Page findAll(@Nonnull Class domainType, @Nonnull Pageable pageable) {
    throw new UnsupportedOperationException(
        "This operation isn't supported in ScalarDB SQL: findAll(Pageable)");
  }

  // Spring Data JDBC issues `DELETE FROM ...` (without WHERE) that isn't supported by ScalarDB SQL.
  @Override
  public void deleteAll(@Nonnull Class domainType) {
    throw new UnsupportedOperationException(
        "This operation isn't supported in ScalarDB SQL: deleteAll");
  }

  public String begin() {
    return operations.execute(
        "BEGIN",
        ps -> {
          if (!ps.execute()) {
            throw new IllegalStateException(
                "This return value isn't ResultSet unexpectedly: BEGIN");
          }
          ResultSet resultSet = ps.getResultSet();
          if (!resultSet.next()) {
            throw new IllegalStateException(
                "This return value is an empty ResultSet unexpectedly: BEGIN");
          }
          return resultSet.getString(1);
        });
  }

  public void prepare() {
    operations.update("PREPARE", Collections.emptyMap());
  }

  public void validate() {
    operations.update("VALIDATE", Collections.emptyMap());
  }

  public void suspend() {
    operations.update("SUSPEND", Collections.emptyMap());
  }

  public void commit() {
    operations.update("COMMIT", Collections.emptyMap());
  }

  public void rollback() {
    operations.update("ROLLBACK", Collections.emptyMap());
  }

  private void executeWithTransactionId(String clause, String transactionId) {
    String escapedTxId;
    escapedTxId = SqlUtils.escapeString(transactionId);

    operations.update(String.format("%s '%s'", clause, escapedTxId), Collections.emptyMap());
  }

  public void join(String transactionId) {
    executeWithTransactionId("JOIN", transactionId);
  }

  public void resume(String transactionId) {
    executeWithTransactionId("RESUME", transactionId);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy