com.datastax.oss.driver.api.core.cql.PreparedStatement Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.datastax.oss.driver.api.core.cql;
import com.datastax.oss.driver.api.core.CqlSession;
import com.datastax.oss.driver.api.core.DefaultProtocolVersion;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import java.nio.ByteBuffer;
import java.util.List;
/**
* A query with bind variables that has been pre-parsed by the database.
*
* Client applications create instances with {@link CqlSession#prepare(SimpleStatement)}. Then
* they use {@link #bind(Object...)} to obtain an executable {@link BoundStatement}.
*
*
The default prepared statement implementation returned by the driver is thread-safe.
* Client applications can -- and are expected to -- prepare each query once and store the result in
* a place where it can be accessed concurrently by application threads (for example a final field).
* Preparing the same query string twice is suboptimal and a bad practice, and will cause the driver
* to log a warning.
*/
public interface PreparedStatement {
/**
* A unique identifier for this prepared statement.
*
*
Note: the returned buffer is read-only.
*/
@NonNull
ByteBuffer getId();
@NonNull
String getQuery();
/** A description of the bind variables of this prepared statement. */
@NonNull
ColumnDefinitions getVariableDefinitions();
/**
* The indices of the variables in {@link #getVariableDefinitions()} that correspond to the target
* table's partition key.
*
*
This is only present if all the partition key columns are expressed as bind variables.
* Otherwise, the list will be empty. For example, given the following schema:
*
*
* CREATE TABLE foo (pk1 int, pk2 int, cc int, v int, PRIMARY KEY ((pk1, pk2), cc));
*
*
* And the following definitions:
*
*
* PreparedStatement ps1 = session.prepare("UPDATE foo SET v = ? WHERE pk1 = ? AND pk2 = ? AND v = ?");
* PreparedStatement ps2 = session.prepare("UPDATE foo SET v = ? WHERE pk1 = 1 AND pk2 = ? AND v = ?");
*
*
* Then {@code ps1.getPartitionKeyIndices()} contains 1 and 2, and {@code
* ps2.getPartitionKeyIndices()} is empty (because one of the partition key components is
* hard-coded in the query string).
*/
@NonNull
List getPartitionKeyIndices();
/**
* A unique identifier for result metadata (essentially a hash of {@link
* #getResultSetDefinitions()}).
*
* This information is mostly for internal use: with protocol {@link DefaultProtocolVersion#V5}
* or higher, the driver sends it with every execution of the prepared statement, to validate that
* its result metadata is still up-to-date.
*
*
Note: this method returns {@code null} for protocol {@link DefaultProtocolVersion#V4} or
* lower; otherwise, the returned buffer is read-only.
*
* @see CASSANDRA-10786
*/
@Nullable
ByteBuffer getResultMetadataId();
/**
* A description of the result set that will be returned when this prepared statement is bound and
* executed.
*
*
This information is only present for {@code SELECT} queries, otherwise it is always empty.
* Note that this is slightly incorrect for conditional updates (e.g. {@code INSERT ... IF NOT
* EXISTS}), which do return columns; for those cases, use {@link
* ResultSet#getColumnDefinitions()} on the result, not this method.
*/
@NonNull
ColumnDefinitions getResultSetDefinitions();
/**
* Updates {@link #getResultMetadataId()} and {@link #getResultSetDefinitions()} atomically.
*
*
This is for internal use by the driver. Calling this manually with incorrect information can
* cause existing queries to fail.
*/
void setResultMetadata(
@NonNull ByteBuffer newResultMetadataId, @NonNull ColumnDefinitions newResultSetDefinitions);
/**
* Builds an executable statement that associates a set of values with the bind variables.
*
*
Note that the built-in bound statement implementation is immutable. If you need to set
* multiple execution parameters on the bound statement (such as {@link
* BoundStatement#setExecutionProfileName(String)}, {@link
* BoundStatement#setPagingState(ByteBuffer)}, etc.), consider using {@link
* #boundStatementBuilder(Object...)} instead to avoid unnecessary allocations.
*
* @param values the values of the bound variables in the statement. You can provide less values
* than the actual number of variables (or even none at all), in which case the remaining
* variables will be left unset. However, this method will throw an {@link
* IllegalArgumentException} if there are more values than variables. Individual values can be
* {@code null}, but the vararg array itself can't.
*/
@NonNull
BoundStatement bind(@NonNull Object... values);
/**
* Returns a builder to construct an executable statement.
*
*
Note that this builder is mutable and not thread-safe.
*
* @see #bind(Object...)
*/
@NonNull
BoundStatementBuilder boundStatementBuilder(@NonNull Object... values);
}