Skip to content
Permalink
Browse files
fix: make compiled statements immutable (#843)
  • Loading branch information
olavloite committed Feb 2, 2021
1 parent 77b7cfc commit 118d1b31f5f7771023766fd72a8229db80f1f5a2
@@ -16,26 +16,13 @@

package com.google.cloud.spanner.connection;

import com.google.cloud.spanner.connection.ClientSideStatementImpl.CompileException;

/**
* A {@link ClientSideStatementExecutor} is used to compile {@link ClientSideStatement}s from the
* json source file, and to execute these against a {@link Connection} (through a {@link
* ConnectionStatementExecutor}).
*/
interface ClientSideStatementExecutor {

/**
* Compiles the given {@link ClientSideStatementImpl} and registers this statement with this
* executor. A statement must be compiled before it can be executed. The parser automatically
* compiles all available statements during initialization.
*
* @param statement The statement to compile.
* @throws CompileException If the statement could not be compiled. This should never happen, as
* it would indicate that an invalid statement has been defined in the source file.
*/
void compile(ClientSideStatementImpl statement) throws CompileException;

/**
* Executes the {@link ClientSideStatementImpl} that has been compiled and registered with this
* executor on the specified connection.
@@ -19,6 +19,7 @@
import com.google.cloud.spanner.SpannerException;
import com.google.cloud.spanner.connection.StatementResult.ResultType;
import com.google.common.base.Preconditions;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.List;
@@ -143,10 +144,12 @@ public String getMessage() {
ClientSideStatementImpl compile() throws CompileException {
try {
this.pattern = Pattern.compile(regex);
this.executor =
(ClientSideStatementExecutor)
Class.forName(getClass().getPackage().getName() + "." + executorName).newInstance();
this.executor.compile(this);
@SuppressWarnings("unchecked")
Constructor<ClientSideStatementExecutor> constructor =
(Constructor<ClientSideStatementExecutor>)
Class.forName(getClass().getPackage().getName() + "." + executorName)
.getDeclaredConstructor(ClientSideStatementImpl.class);
this.executor = constructor.newInstance(this);
return this;
} catch (Exception e) {
throw new CompileException(e, this);
@@ -24,12 +24,16 @@
* SHOW AUTOCOMMIT. The executor just calls a method with no parameters.
*/
class ClientSideStatementNoParamExecutor implements ClientSideStatementExecutor {
private Method method;
private final Method method;

ClientSideStatementNoParamExecutor() {}

@Override
public void compile(ClientSideStatementImpl statement) throws CompileException {
/**
* Creates and compiles the given {@link ClientSideStatementImpl}.
*
* @param statement The statement to compile.
* @throws CompileException If the statement could not be compiled. This should never happen, as
* it would indicate that an invalid statement has been defined in the source file.
*/
ClientSideStatementNoParamExecutor(ClientSideStatementImpl statement) throws CompileException {
try {
this.method = ConnectionStatementExecutor.class.getDeclaredMethod(statement.getMethodName());
} catch (NoSuchMethodException | SecurityException e) {
@@ -30,14 +30,20 @@
* AUTOCOMMIT=TRUE.
*/
class ClientSideStatementSetExecutor<T> implements ClientSideStatementExecutor {
private ClientSideStatementImpl statement;
private Method method;
private ClientSideStatementValueConverter<T> converter;
private Pattern allowedValuesPattern;
private final ClientSideStatementImpl statement;
private final Method method;
private final ClientSideStatementValueConverter<T> converter;
private final Pattern allowedValuesPattern;

/**
* Creates and compiles the given {@link ClientSideStatementImpl}.
*
* @param statement The statement to compile.
* @throws CompileException If the statement could not be compiled. This should never happen, as
* it would indicate that an invalid statement has been defined in the source file.
*/
@SuppressWarnings("unchecked")
@Override
public void compile(ClientSideStatementImpl statement) throws CompileException {
ClientSideStatementSetExecutor(ClientSideStatementImpl statement) throws CompileException {
Preconditions.checkNotNull(statement.getSetStatement());
try {
this.statement = statement;

0 comments on commit 118d1b3

Please sign in to comment.