Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package com.scalar.db.sql;
import com.google.common.annotations.VisibleForTesting;
import com.scalar.db.sql.common.SqlError;
import com.scalar.db.sql.exception.SqlException;
import com.scalar.db.sql.exception.TransactionRetryableException;
import com.scalar.db.sql.exception.UnknownTransactionStatusException;
import com.scalar.db.sql.metadata.Metadata;
import com.scalar.db.sql.statement.BindableStatement;
import com.scalar.db.sql.statement.CommandStatement;
import com.scalar.db.sql.statement.Statement;
import com.scalar.db.sql.util.CommandStatementParser;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;
/** An SQL session in which users can execute all the operations (DDL, DML, etc.). */
@NotThreadSafe
public class SqlSession implements AutoCloseable {
private final SqlTransactionSessionStrategy sqlTransactionSessionStrategy;
@Nullable
private final SqlTwoPhaseCommitTransactionSessionStrategy
sqlTwoPhaseCommitTransactionSessionStrategy;
private final CommandStatementExecutor commandStatementExecutor;
private TransactionMode transactionMode;
@Nullable private String defaultNamespaceName;
private boolean closed;
SqlSession(
SqlTransactionManager sqlTransactionManager,
@Nullable SqlTwoPhaseCommitTransactionManager sqlTwoPhaseCommitTransactionManager,
TransactionMode transactionMode,
@Nullable String defaultNamespaceName,
boolean defaultNamespaceNameExistenceCheckEnabled) {
this.sqlTransactionSessionStrategy =
new SqlTransactionSessionStrategy(Objects.requireNonNull(sqlTransactionManager));
if (sqlTwoPhaseCommitTransactionManager == null) {
this.sqlTwoPhaseCommitTransactionSessionStrategy = null;
} else {
this.sqlTwoPhaseCommitTransactionSessionStrategy =
new SqlTwoPhaseCommitTransactionSessionStrategy(sqlTwoPhaseCommitTransactionManager);
}
commandStatementExecutor = new CommandStatementExecutor();
checkTransactionMode(Objects.requireNonNull(transactionMode));
this.transactionMode = transactionMode;
setDefaultNamespaceName(defaultNamespaceName, defaultNamespaceNameExistenceCheckEnabled);
}
@VisibleForTesting
SqlSession(
SqlTransactionSessionStrategy sqlTransactionSessionStrategy,
@Nullable
SqlTwoPhaseCommitTransactionSessionStrategy sqlTwoPhaseCommitTransactionSessionStrategy,
CommandStatementExecutor commandStatementExecutor,
TransactionMode transactionMode,
@Nullable String defaultNamespaceName) {
this.sqlTransactionSessionStrategy = sqlTransactionSessionStrategy;
this.sqlTwoPhaseCommitTransactionSessionStrategy = sqlTwoPhaseCommitTransactionSessionStrategy;
this.commandStatementExecutor = commandStatementExecutor;
this.transactionMode = transactionMode;
this.defaultNamespaceName = defaultNamespaceName;
}
/**
* Begins a transaction.
*
* @return a transaction ID associated with the begun transaction
* @throws TransactionRetryableException if the transaction fails to begin due to retryable
* faults. You can retry the transaction.
* @throws SqlException if the transaction fails to begin due to transient or nontransient faults.
* You can try retrying the transaction, but you may not be able to begin the transaction due
* to nontransient faults
*/
public String begin() {
checkIfClosed();
checkIfTransactionInProgress();
return getSqlSessionStrategy().begin();
}
/**
* Starts a transaction. This method is an alias of {@link #begin()}.
*
* @return a transaction ID associated with the started transaction
* @throws TransactionRetryableException if the transaction fails to start due to retryable
* faults. You can retry the transaction.
* @throws SqlException if the transaction fails to start due to transient or nontransient faults.
* You can try retrying the transaction, but you may not be able to start the transaction due
* to nontransient faults
*/
public String start() {
checkIfClosed();
checkIfTransactionInProgress();
return getSqlSessionStrategy().start();
}
/**
* Joins an ongoing transaction associated with the specified transaction ID.
*
* @param transactionId a transaction ID associated with the transaction to join
* @throws TransactionRetryableException if the transaction fails to join due to retryable faults
* (e.g., the transaction not found). You can retry the transaction from the beginning.
* @throws SqlException if the transaction fails to join due to transient or nontransient faults.
* You can try retrying the transaction from the beginning, but the transaction may still fail
* if the cause is nontranient
*/
public void join(String transactionId) {
checkIfClosed();
checkIfTransactionInProgress();
getSqlSessionStrategy().join(transactionId);
}
/**
* Suspends the current transaction.
*
* @throws SqlException if an unexpected error occurs
*/
public void suspend() {
checkIfClosed();
if (getSqlSessionStrategy().isTransactionInProgress()) {
getSqlSessionStrategy().suspend();
}
}
/**
* Resumes an ongoing transaction associated with the specified transaction ID.
*
* @param transactionId a transaction ID associated with the transaction to resume
* @throws TransactionRetryableException if the transaction fails to resume due to retryable
* faults (e.g., the transaction not found). You can retry the transaction from the beginning.
* @throws SqlException if the transaction fails to resume due to transient or nontransient
* faults. You can try retrying the transaction from the beginning, but the transaction may
* still fail if the cause is nontranient
*/
public void resume(String transactionId) {
checkIfClosed();
checkIfTransactionInProgress();
getSqlSessionStrategy().resume(transactionId);
}
/**
* Executes the specified SQL statement.
*
* @param sql an SQL statement to execute
* @return a {@link ResultSet} object that contains the data produced by the query
* @throws TransactionRetryableException if the transaction operation execution fails due to
* retryable faults (e.g., a transaction conflict). You can retry the transaction from the
* beginning.
* @throws UnknownTransactionStatusException if the transaction status (committed or aborted) is
* unknown when executing the COMMIT statement
* @throws SqlException if the transaction operation execution fails due to transient or
* nontransient faults. You can try retrying the transaction from the beginning, but the
* transaction may still fail if the cause is nontranient
*/
public ResultSet execute(String sql) {
checkIfClosed();
// if the SQL is a command statement, execute it
CommandStatement commandStatement = CommandStatementParser.parse(sql);
if (commandStatement != null) {
return commandStatementExecutor.execute(commandStatement, this);
}
return getSqlSessionStrategy().execute(sql, (List) null, defaultNamespaceName);
}
/**
* Executes the specified statement.
*
* @param statement a statement to execute
* @return a {@link ResultSet} object that contains the data produced by the query
* @throws TransactionRetryableException if the transaction operation execution fails due to
* retryable faults (e.g., a transaction conflict). You can retry the transaction from the
* beginning.
* @throws UnknownTransactionStatusException if the transaction status (committed or aborted) is
* unknown when executing the COMMIT statement
* @throws SqlException if the transaction operation execution fails due to transient or
* nontransient faults. You can try retrying the transaction from the beginning, but the
* transaction may still fail if the cause is nontranient
*/
public ResultSet execute(Statement statement) {
checkIfClosed();
// if the statement is a command statement, execute it
if (statement instanceof CommandStatement) {
return commandStatementExecutor.execute((CommandStatement) statement, this);
}
return getSqlSessionStrategy().execute(statement, (List) null, defaultNamespaceName);
}
/**
* Returns a {@link PreparedStatement} object with the specified SQL statement.
*
* @param sql an SQL statement to prepare
* @return a {@link PreparedStatement} object
*/
public PreparedStatement prepareStatement(String sql) {
checkIfClosed();
return new PreparedStatement(this, sql);
}
/**
* Returns a {@link PreparedStatement} object with the specified statement.
*
* @param bindableStatement a statement to prepare
* @return a {@link PreparedStatement} object
*/
public PreparedStatement prepareStatement(BindableStatement> bindableStatement) {
checkIfClosed();
return new PreparedStatement(this, bindableStatement);
}
ResultSet execute(String sql, List positionalValues) {
checkIfClosed();
// if the SQL is a command statement, execute it
CommandStatement commandStatement = CommandStatementParser.parse(sql);
if (commandStatement != null) {
return commandStatementExecutor.execute(commandStatement, this);
}
return getSqlSessionStrategy().execute(sql, positionalValues, defaultNamespaceName);
}
ResultSet execute(String sql, Map namedValues) {
checkIfClosed();
// if the SQL is a command statement, execute it
CommandStatement commandStatement = CommandStatementParser.parse(sql);
if (commandStatement != null) {
return commandStatementExecutor.execute(commandStatement, this);
}
return getSqlSessionStrategy().execute(sql, namedValues, defaultNamespaceName);
}
ResultSet execute(BindableStatement> bindableStatement, List positionalValues) {
checkIfClosed();
// if the statement is a command statement, execute it
if (bindableStatement instanceof CommandStatement) {
return commandStatementExecutor.execute((CommandStatement) bindableStatement, this);
}
return getSqlSessionStrategy()
.execute(bindableStatement, positionalValues, defaultNamespaceName);
}
ResultSet execute(BindableStatement> bindableStatement, Map namedValues) {
checkIfClosed();
// if the statement is a command statement, execute it
if (bindableStatement instanceof CommandStatement) {
return commandStatementExecutor.execute((CommandStatement) bindableStatement, this);
}
return getSqlSessionStrategy().execute(bindableStatement, namedValues, defaultNamespaceName);
}
/**
* Prepares the current transaction. This method is for the {@code TWO_PHASE_COMMIT_TRANSACTION}
* mode.
*
* @throws TransactionRetryableException if the transaction fails to prepare due to retryable
* faults (e.g., a transaction conflict). You can retry the transaction from the beginning.
* @throws SqlException if the transaction fails to prepare due to transient or nontransient
* faults. You can try retrying the transaction from the beginning, but the transaction may
* still fail if the cause is nontranient
*/
public void prepare() {
checkIfClosed();
if (transactionMode != TransactionMode.TWO_PHASE_COMMIT_TRANSACTION) {
throw new IllegalStateException(SqlError.PREPARE_NOT_SUPPORTED.buildMessage());
}
checkIfTransactionBegun();
getSqlSessionStrategy().prepare();
}
/**
* Validates the current transaction. This method is for the {@code TWO_PHASE_COMMIT_TRANSACTION}
* mode.
*
* @throws TransactionRetryableException if the transaction fails to validate due to retryable
* faults (e.g., a transaction conflict). You can retry the transaction from the beginning.
* @throws SqlException if the transaction fails to validate due to transient or nontransient
* faults. You can try retrying the transaction from the beginning, but the transaction may
* still fail if the cause is nontranient
*/
public void validate() {
checkIfClosed();
if (transactionMode != TransactionMode.TWO_PHASE_COMMIT_TRANSACTION) {
throw new IllegalStateException(SqlError.VALIDATE_NOT_SUPPORTED.buildMessage());
}
checkIfTransactionBegun();
getSqlSessionStrategy().validate();
}
/**
* Commits the current transaction.
*
* @throws TransactionRetryableException if the transaction fails to commit due to retryable
* faults (e.g., a transaction conflict). You can retry the transaction from the beginning.
* @throws UnknownTransactionStatusException if the transaction status (committed or aborted) is
* unknown
* @throws SqlException if the transaction fails to commit due to transient or nontransient
* faults. You can try retrying the transaction from the beginning, but the transaction may
* still fail if the cause is nontranient
*/
public void commit() {
checkIfClosed();
checkIfTransactionBegun();
getSqlSessionStrategy().commit();
}
/** Rolls back the current transaction. If a transaction is not begun, does nothing. */
public void rollback() {
checkIfClosed();
if (getSqlSessionStrategy().isTransactionInProgress()) {
getSqlSessionStrategy().rollback();
}
}
/** Aborts the current transaction. This method is an alias of {@link #rollback()}. */
public void abort() {
checkIfClosed();
if (getSqlSessionStrategy().isTransactionInProgress()) {
getSqlSessionStrategy().abort();
}
}
/**
* Returns whether a transaction is in progress.
*
* @return whether a transaction is in progress
*/
public boolean isTransactionInProgress() {
checkIfClosed();
return getSqlSessionStrategy().isTransactionInProgress();
}
/**
* Returns the current transaction ID.
*
* @return the current transaction ID
*/
public Optional getTransactionId() {
checkIfClosed();
return getSqlSessionStrategy().getTransactionId();
}
/**
* Sets a transaction mode.
*
* @param transactionMode a transaction mode
*/
public void setTransactionMode(TransactionMode transactionMode) {
checkIfClosed();
if (getSqlSessionStrategy().isTransactionInProgress()) {
throw new IllegalStateException(
SqlError.PREVIOUS_TRANSACTION_STILL_IN_PROGRESS.buildMessage());
}
checkTransactionMode(transactionMode);
this.transactionMode = transactionMode;
}
private void checkTransactionMode(TransactionMode transactionMode) {
if (transactionMode == TransactionMode.TWO_PHASE_COMMIT_TRANSACTION
&& sqlTwoPhaseCommitTransactionSessionStrategy == null) {
throw new IllegalArgumentException(
SqlError.TWO_PHASE_COMMIT_TRANSACTION_MODE_NOT_SUPPORTED.buildMessage());
}
}
/**
* Returns the current transaction mode.
*
* @return the current transaction mode
*/
public TransactionMode getTransactionMode() {
checkIfClosed();
return transactionMode;
}
/**
* Sets a default namespace name with existence check enabled
*
* @param defaultNamespaceName a default namespace name
* @throws SqlException if an unexpected error happens
*/
public void setDefaultNamespaceName(@Nullable String defaultNamespaceName) {
setDefaultNamespaceName(defaultNamespaceName, true);
}
/**
* Sets a default namespace name.
*
* @param defaultNamespaceName a default namespace name
* @param defaultNamespaceNameExistenceCheckEnabled true if existence check should be done on the
* default namespace name, false otherwise
* @throws SqlException if an unexpected error happens
*/
public void setDefaultNamespaceName(
@Nullable String defaultNamespaceName, boolean defaultNamespaceNameExistenceCheckEnabled) {
checkIfClosed();
if (defaultNamespaceName == null) {
this.defaultNamespaceName = null;
return;
}
if (defaultNamespaceNameExistenceCheckEnabled) {
this.defaultNamespaceName =
getSqlSessionStrategy()
.getMetadata()
.getNamespace(defaultNamespaceName)
.orElseThrow(
() ->
new IllegalArgumentException(
SqlError.NAMESPACE_NOT_FOUND.buildMessage(defaultNamespaceName)))
.getName();
} else {
this.defaultNamespaceName = defaultNamespaceName;
}
}
/**
* Returns the current default namespace name.
*
* @return the current default namespace name
*/
public Optional getDefaultNamespaceName() {
checkIfClosed();
return Optional.ofNullable(defaultNamespaceName);
}
/**
* Returns a {@link Metadata} object.
*
* @return a {@link Metadata} object.
*/
public Metadata getMetadata() {
checkIfClosed();
return getSqlSessionStrategy().getMetadata();
}
/**
* Returns whether this session is closed.
*
* @return whether this session is closed
*/
public boolean isClosed() {
return closed;
}
/** Closes this session. */
@Override
public void close() {
closed = true;
}
private void checkIfClosed() {
if (closed) {
throw new IllegalStateException(SqlError.SQL_SESSION_ALREADY_CLOSED.buildMessage());
}
}
private void checkIfTransactionInProgress() {
if (isTransactionInProgress()) {
throw new IllegalStateException(
SqlError.PREVIOUS_TRANSACTION_STILL_IN_PROGRESS.buildMessage());
}
}
private void checkIfTransactionBegun() {
if (!isTransactionInProgress()) {
throw new IllegalStateException(SqlError.TRANSACTION_NOT_BEGUN.buildMessage());
}
}
private SqlSessionStrategy getSqlSessionStrategy() {
switch (transactionMode) {
case TRANSACTION:
return sqlTransactionSessionStrategy;
case TWO_PHASE_COMMIT_TRANSACTION:
return sqlTwoPhaseCommitTransactionSessionStrategy;
default:
throw new AssertionError();
}
}
}