merged latest master into mavenized source tree
This commit is contained in:
@@ -69,14 +69,15 @@ sourceCompatibility = 1.6
|
|||||||
targetCompatibility = 1.6
|
targetCompatibility = 1.6
|
||||||
|
|
||||||
javadoc {
|
javadoc {
|
||||||
ext.srcDir = file("${projectDir}/docs/src/api")
|
ext.srcDir = file("${projectDir}/src/main/doc")
|
||||||
destinationDir = file("${buildDir}/api")
|
ext.destinationDir = file("${buildDir}/docs/javadoc")
|
||||||
ext.tmpDir = file("${buildDir}/api-work")
|
ext.tmpDir = file("${buildDir}/api-work")
|
||||||
|
|
||||||
configure(options) {
|
configure(options) {
|
||||||
//stylesheetFile = file("${srcDir}/spring-javadoc.css")
|
stylesheetFile = file("${srcDir}/spring-javadoc.css")
|
||||||
//overview = "${srcDir}/overview.html"
|
//overview = "${srcDir}/overview.html"
|
||||||
docFilesSubDirs = true
|
docFilesSubDirs = true
|
||||||
|
|
||||||
outputLevel = org.gradle.external.javadoc.JavadocOutputLevel.QUIET
|
outputLevel = org.gradle.external.javadoc.JavadocOutputLevel.QUIET
|
||||||
breakIterator = true
|
breakIterator = true
|
||||||
showFromProtected()
|
showFromProtected()
|
||||||
@@ -94,6 +95,16 @@ javadoc {
|
|||||||
exclude "org/springframework/data/cassandra/config/**"
|
exclude "org/springframework/data/cassandra/config/**"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.error("BuildDir => ${buildDir}");
|
||||||
|
logger.error("DestDir => ${destinationDir}");
|
||||||
|
logger.error("ExtDestDir => ${ext.destinationDir}");
|
||||||
|
|
||||||
|
copy {
|
||||||
|
from "src/main/doc/resources"
|
||||||
|
into "${ext.destinationDir}/resources"
|
||||||
|
include '**/*'
|
||||||
|
}
|
||||||
|
|
||||||
title = "${rootProject.description} ${version} API"
|
title = "${rootProject.description} ${version} API"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,4 +23,4 @@ nettyVersion = 3.6.2.Final
|
|||||||
# --------------------
|
# --------------------
|
||||||
# Project wide version
|
# Project wide version
|
||||||
# --------------------
|
# --------------------
|
||||||
version=2.0.0.BUILD-SNAPSHOT
|
version=1.2.0.BUILD-SNAPSHOT
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011-2013 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed 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 org.springframework.cassandra.core;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
|
||||||
import com.datastax.driver.core.PreparedStatement;
|
|
||||||
import com.datastax.driver.core.Session;
|
|
||||||
import com.datastax.driver.core.exceptions.DriverException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created a PreparedStatement and retrieved the PreparedStatement from cache if the statement has been prepared
|
|
||||||
* previously. In general, this creator should be used over the {@link SimplePreparedStatementCreator} as it provides
|
|
||||||
* better performance.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* There is overhead in Cassandra when Preparing a Statement. This is negligible on a single data center configuration,
|
|
||||||
* but when your cluster spans multiple data centers, preparing the same statement over and over again is not necessary
|
|
||||||
* and causes performance issues in high throughput use cases.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author David Webb
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class CachedPreparedStatementCreator implements PreparedStatementCreator, CqlProvider {
|
|
||||||
|
|
||||||
private static Logger log = LoggerFactory.getLogger(CachedPreparedStatementCreator.class);
|
|
||||||
|
|
||||||
private final String cql;
|
|
||||||
|
|
||||||
private PreparedStatement cache;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a CachedPreparedStatementCreator from the provided CQL.
|
|
||||||
*
|
|
||||||
* @param cql
|
|
||||||
*/
|
|
||||||
public CachedPreparedStatementCreator(String cql) {
|
|
||||||
Assert.notNull(cql, "CQL is required to create a PreparedStatement");
|
|
||||||
this.cql = cql;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.springframework.cassandra.core.PreparedStatementCreator#createPreparedStatement(com.datastax.driver.core.Session)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public PreparedStatement createPreparedStatement(Session session) throws DriverException {
|
|
||||||
if (cache == null) {
|
|
||||||
log.debug("PreparedStatement cache is null, preparing new Statement");
|
|
||||||
cache = session.prepare(getCql());
|
|
||||||
} else {
|
|
||||||
log.debug("Using cached PreparedStatement");
|
|
||||||
}
|
|
||||||
return cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.springframework.cassandra.core.CqlProvider#getCql()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getCql() {
|
|
||||||
return this.cql;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -398,4 +398,44 @@ public interface CassandraOperations {
|
|||||||
*/
|
*/
|
||||||
Session getSession();
|
Session getSession();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is an operation designed for high performance writes. The cql is used to create a PreparedStatement once, then
|
||||||
|
* all row values are bound to the single PreparedStatement and executed against the Session.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This is used internally by the other ingest() methods, but can be used if you want to write your own RowIterator.
|
||||||
|
* The Object[] length returned by the next() implementation must match the number of bind variables in the CQL.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param cql The CQL
|
||||||
|
* @param rowIterator Implementation to provide the Object[] to be bound to the CQL.
|
||||||
|
*/
|
||||||
|
void ingest(String cql, RowIterator rowIterator);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is an operation designed for high performance writes. The cql is used to create a PreparedStatement once, then
|
||||||
|
* all row values are bound to the single PreparedStatement and executed against the Session.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The List<?> length must match the number of bind variables in the CQL.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param cql The CQL
|
||||||
|
* @param rows List of List<?> with data to bind to the CQL.
|
||||||
|
*/
|
||||||
|
void ingest(String cql, List<List<?>> rows);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is an operation designed for high performance writes. The cql is used to create a PreparedStatement once, then
|
||||||
|
* all row values are bound to the single PreparedStatement and executed against the Session.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The Object[] length of the nested array must match the number of bind variables in the CQL.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param cql The CQL
|
||||||
|
* @param rows Object array of Object array of values to bind to the CQL.
|
||||||
|
*/
|
||||||
|
void ingest(String cql, Object[][] rows);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -560,4 +560,60 @@ public class CassandraTemplate extends CassandraAccessor implements CassandraOpe
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.springframework.cassandra.core.CassandraOperations#execute(java.lang.String, org.springframework.cassandra.core.RowProvider, int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void ingest(String cql, RowIterator rowIterator) {
|
||||||
|
|
||||||
|
PreparedStatement preparedStatement = getSession().prepare(cql);
|
||||||
|
|
||||||
|
while (rowIterator.hasNext()) {
|
||||||
|
getSession().execute(preparedStatement.bind(rowIterator.next()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.springframework.cassandra.core.CassandraOperations#execute(java.lang.String, java.util.List)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void ingest(String cql, List<List<?>> rows) {
|
||||||
|
|
||||||
|
Assert.notNull(rows);
|
||||||
|
Assert.notEmpty(rows);
|
||||||
|
|
||||||
|
Object[][] values = new Object[rows.size()][];
|
||||||
|
int i = 0;
|
||||||
|
for (List<?> row : rows) {
|
||||||
|
values[i++] = row.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
ingest(cql, values);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.springframework.cassandra.core.CassandraOperations#execute(java.lang.String, java.lang.Object[][])
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void ingest(String cql, final Object[][] rows) {
|
||||||
|
|
||||||
|
ingest(cql, new RowIterator() {
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object[] next() {
|
||||||
|
return rows[index++];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return index < rows.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,139 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011-2013 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed 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 org.springframework.cassandra.core;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
|
||||||
import com.datastax.driver.core.DataType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author David Webb
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class CqlParameter {
|
|
||||||
|
|
||||||
/** The name of the parameter, if any */
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
/** SQL type constant from {@link DataType} */
|
|
||||||
private final DataType type;
|
|
||||||
|
|
||||||
/** The scale to apply in case of a NUMERIC or DECIMAL type, if any */
|
|
||||||
private Integer scale;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new anonymous CqlParameter, supplying the SQL type.
|
|
||||||
*
|
|
||||||
* @param type Cassandra Data Type of the parameter according to {@link DataType}
|
|
||||||
*/
|
|
||||||
public CqlParameter(DataType type) {
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new anonymous CqlParameter, supplying the SQL type.
|
|
||||||
*
|
|
||||||
* @param type Cassandra Data Type of the parameter according to {@link DataType}
|
|
||||||
* @param scale the number of digits after the decimal point
|
|
||||||
*/
|
|
||||||
public CqlParameter(DataType type, int scale) {
|
|
||||||
this.type = type;
|
|
||||||
this.scale = scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new CqlParameter, supplying name and SQL type.
|
|
||||||
*
|
|
||||||
* @param name name of the parameter, as used in input and output maps
|
|
||||||
* @param type Cassandra Data Type of the parameter according to {@link DataType}
|
|
||||||
*/
|
|
||||||
public CqlParameter(String name, DataType type) {
|
|
||||||
this.name = name;
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new CqlParameter, supplying name and SQL type.
|
|
||||||
*
|
|
||||||
* @param name name of the parameter, as used in input and output maps
|
|
||||||
* @param type Cassandra Data Type of the parameter according to {@link DataType}
|
|
||||||
* @param scale the number of digits after the decimal point (for DECIMAL and NUMERIC types)
|
|
||||||
*/
|
|
||||||
public CqlParameter(String name, DataType type, int scale) {
|
|
||||||
this.name = name;
|
|
||||||
this.type = type;
|
|
||||||
this.scale = scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy constructor.
|
|
||||||
*
|
|
||||||
* @param otherParam the CqlParameter object to copy from
|
|
||||||
*/
|
|
||||||
public CqlParameter(CqlParameter otherParam) {
|
|
||||||
Assert.notNull(otherParam, "CqlParameter object must not be null");
|
|
||||||
this.name = otherParam.name;
|
|
||||||
this.type = otherParam.type;
|
|
||||||
this.scale = otherParam.scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the name of the parameter.
|
|
||||||
*/
|
|
||||||
public String getName() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the SQL type of the parameter.
|
|
||||||
*/
|
|
||||||
public DataType getType() {
|
|
||||||
return this.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the scale of the parameter, if any.
|
|
||||||
*/
|
|
||||||
public Integer getScale() {
|
|
||||||
return this.scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return whether this parameter holds input values that should be set before execution even if they are {@code null}.
|
|
||||||
* <p>
|
|
||||||
* This implementation always returns {@code true}.
|
|
||||||
*/
|
|
||||||
public boolean isInputValueProvided() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a list of JDBC types, as defined in {@code java.sql.Types}, to a List of CqlParameter objects as used in
|
|
||||||
* this package.
|
|
||||||
*/
|
|
||||||
public static List<CqlParameter> sqlTypesToAnonymousParameterList(DataType[] types) {
|
|
||||||
List<CqlParameter> result = new LinkedList<CqlParameter>();
|
|
||||||
if (types != null) {
|
|
||||||
for (DataType type : types) {
|
|
||||||
result.add(new CqlParameter(type));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011-2013 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed 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 org.springframework.cassandra.core;
|
|
||||||
|
|
||||||
import com.datastax.driver.core.DataType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author David Webb
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class CqlParameterValue extends CqlParameter {
|
|
||||||
|
|
||||||
private final Object value;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new CqlParameterValue, supplying the Cassandra DataType.
|
|
||||||
*
|
|
||||||
* @param type Cassandra Data Type of the parameter according to {@link DataType}
|
|
||||||
* @param value the value object
|
|
||||||
*/
|
|
||||||
public CqlParameterValue(DataType type, Object value) {
|
|
||||||
super(type);
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new CqlParameterValue, supplying the Cassandra DataType.
|
|
||||||
*
|
|
||||||
* @param type Cassandra Data Type of the parameter according to {@link DataType}
|
|
||||||
* @param scale the number of digits after the decimal point (for DECIMAL and NUMERIC types)
|
|
||||||
* @param value the value object
|
|
||||||
*/
|
|
||||||
public CqlParameterValue(DataType type, int scale, Object value) {
|
|
||||||
super(type, scale);
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new CqlParameterValue based on the given CqlParameter declaration.
|
|
||||||
*
|
|
||||||
* @param declaredParam the declared CqlParameter to define a value for
|
|
||||||
* @param value the value object
|
|
||||||
*/
|
|
||||||
public CqlParameterValue(CqlParameter declaredParam, Object value) {
|
|
||||||
super(declaredParam);
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the value object that this parameter value holds.
|
|
||||||
*/
|
|
||||||
public Object getValue() {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,202 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011-2013 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed 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 org.springframework.cassandra.core;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
|
||||||
import com.datastax.driver.core.BoundStatement;
|
|
||||||
import com.datastax.driver.core.PreparedStatement;
|
|
||||||
import com.datastax.driver.core.Session;
|
|
||||||
import com.datastax.driver.core.exceptions.DriverException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author David Webb
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class PreparedStatementCreatorFactory {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The CQL, which won't change when the parameters change
|
|
||||||
*/
|
|
||||||
private final String cql;
|
|
||||||
|
|
||||||
/** List of CqlParameter objects. May not be {@code null}. */
|
|
||||||
private final List<CqlParameter> declaredParameters;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new factory.
|
|
||||||
*/
|
|
||||||
public PreparedStatementCreatorFactory(String cql) {
|
|
||||||
this.cql = cql;
|
|
||||||
this.declaredParameters = new LinkedList<CqlParameter>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new factory with the given CQL and parameters.
|
|
||||||
*
|
|
||||||
* @param cql CQL
|
|
||||||
* @param declaredParameters list of {@link CqlParameter} objects
|
|
||||||
* @see CqlParameter
|
|
||||||
*/
|
|
||||||
public PreparedStatementCreatorFactory(String cql, List<CqlParameter> declaredParameters) {
|
|
||||||
this.cql = cql;
|
|
||||||
this.declaredParameters = declaredParameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a new PreparedStatementBinder for the given parameters.
|
|
||||||
*
|
|
||||||
* @param params list of parameters (may be {@code null})
|
|
||||||
*/
|
|
||||||
public PreparedStatementBinder newPreparedStatementBinder(List<CqlParameterValue> params) {
|
|
||||||
return new PreparedStatementCreatorImpl(params != null ? params : Collections.emptyList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a new PreparedStatementBinder for the given parameters.
|
|
||||||
*
|
|
||||||
* @param params the parameter array (may be {@code null})
|
|
||||||
*/
|
|
||||||
public PreparedStatementBinder newPreparedStatementBinder(Object[] params) {
|
|
||||||
return new PreparedStatementCreatorImpl(params != null ? Arrays.asList(params) : Collections.emptyList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a new PreparedStatementCreator for the given parameters.
|
|
||||||
*
|
|
||||||
* @param params list of parameters (may be {@code null})
|
|
||||||
*/
|
|
||||||
public PreparedStatementCreator newPreparedStatementCreator(List<CqlParameterValue> params) {
|
|
||||||
return new PreparedStatementCreatorImpl(params != null ? params : Collections.emptyList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a new PreparedStatementCreator for the given parameters.
|
|
||||||
*
|
|
||||||
* @param params the parameter array (may be {@code null})
|
|
||||||
*/
|
|
||||||
public PreparedStatementCreator newPreparedStatementCreator(Object[] params) {
|
|
||||||
return new PreparedStatementCreatorImpl(params != null ? Arrays.asList(params) : Collections.emptyList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a new PreparedStatementCreator for the given parameters.
|
|
||||||
*
|
|
||||||
* @param sqlToUse the actual SQL statement to use (if different from the factory's, for example because of named
|
|
||||||
* parameter expanding)
|
|
||||||
* @param params the parameter array (may be {@code null})
|
|
||||||
*/
|
|
||||||
public PreparedStatementCreator newPreparedStatementCreator(String sqlToUse, Object[] params) {
|
|
||||||
return new PreparedStatementCreatorImpl(sqlToUse, params != null ? Arrays.asList(params) : Collections.emptyList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PreparedStatementCreator implementation returned by this class.
|
|
||||||
*/
|
|
||||||
private class PreparedStatementCreatorImpl implements PreparedStatementCreator, PreparedStatementBinder, CqlProvider {
|
|
||||||
|
|
||||||
private final String actualCql;
|
|
||||||
|
|
||||||
private final List<?> parameters;
|
|
||||||
|
|
||||||
public PreparedStatementCreatorImpl(List<?> parameters) {
|
|
||||||
this(cql, parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param actualCql
|
|
||||||
* @param parameters
|
|
||||||
*/
|
|
||||||
public PreparedStatementCreatorImpl(String actualCql, List<?> parameters) {
|
|
||||||
this.actualCql = actualCql;
|
|
||||||
Assert.notNull(parameters, "Parameters List must not be null");
|
|
||||||
this.parameters = parameters;
|
|
||||||
if (this.parameters.size() != declaredParameters.size()) {
|
|
||||||
Set<String> names = new HashSet<String>();
|
|
||||||
for (int i = 0; i < parameters.size(); i++) {
|
|
||||||
Object param = parameters.get(i);
|
|
||||||
if (param instanceof CqlParameterValue) {
|
|
||||||
names.add(((CqlParameterValue) param).getName());
|
|
||||||
} else {
|
|
||||||
names.add("Parameter #" + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (names.size() != declaredParameters.size()) {
|
|
||||||
throw new InvalidDataAccessApiUsageException("CQL [" + cql + "]: given " + names.size()
|
|
||||||
+ " parameters but expected " + declaredParameters.size());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.springframework.cassandra.core.PreparedStatementCreator#createPreparedStatement(com.datastax.driver.core.Session)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public PreparedStatement createPreparedStatement(Session session) throws DriverException {
|
|
||||||
return session.prepare(this.actualCql);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.springframework.cassandra.core.PreparedStatementBinder#bindValues(com.datastax.driver.core.PreparedStatement)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public BoundStatement bindValues(PreparedStatement ps) throws DriverException {
|
|
||||||
if (this.parameters == null || this.parameters.size() == 0) {
|
|
||||||
return ps.bind();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test the type of the first value
|
|
||||||
Object v = this.parameters.get(0);
|
|
||||||
Object[] values;
|
|
||||||
if (v instanceof CqlParameterValue) {
|
|
||||||
LinkedList<Object> valuesList = new LinkedList<Object>();
|
|
||||||
for (Object value : this.parameters) {
|
|
||||||
valuesList.add(((CqlParameterValue) value).getValue());
|
|
||||||
}
|
|
||||||
values = valuesList.toArray();
|
|
||||||
} else {
|
|
||||||
values = this.parameters.toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ps.bind(values);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.springframework.cassandra.core.CqlProvider#getCql()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getCql() {
|
|
||||||
return cql;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("PreparedStatementCreatorFactory.PreparedStatementCreatorImpl: cql=[");
|
|
||||||
sb.append(cql).append("]; parameters=").append(this.parameters);
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -47,7 +47,7 @@ public class PreparedStatementCreatorImpl implements PreparedStatementCreator, C
|
|||||||
public BoundStatement bindValues(PreparedStatement ps) throws DriverException {
|
public BoundStatement bindValues(PreparedStatement ps) throws DriverException {
|
||||||
// Nothing to set if there are no values
|
// Nothing to set if there are no values
|
||||||
if (values == null) {
|
if (values == null) {
|
||||||
return null;
|
return new BoundStatement(ps);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ps.bind(values.toArray());
|
return ps.bind(values.toArray());
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011-2013 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed 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 org.springframework.cassandra.core;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author David Webb
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface RowIterator {
|
||||||
|
|
||||||
|
Object[] next();
|
||||||
|
|
||||||
|
boolean hasNext();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -27,7 +27,7 @@ public class ColumnSpecification {
|
|||||||
/**
|
/**
|
||||||
* Default ordering of primary key fields; value is {@link Ordering#ASCENDING}.
|
* Default ordering of primary key fields; value is {@link Ordering#ASCENDING}.
|
||||||
*/
|
*/
|
||||||
public static final Ordering DFAULT_ORDERING = ASCENDING;
|
public static final Ordering DEFAULT_ORDERING = ASCENDING;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private DataType type; // TODO: determining if we should be coupling this to Datastax Java Driver type?
|
private DataType type; // TODO: determining if we should be coupling this to Datastax Java Driver type?
|
||||||
@@ -80,12 +80,12 @@ public class ColumnSpecification {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifies this column as a primary key column with default ordering. Sets the column's {@link #keyType} to
|
* Identifies this column as a primary key column with default ordering. Sets the column's {@link #keyType} to
|
||||||
* {@link KeyType#PRIMARY} and its {@link #ordering} to {@link #DFAULT_ORDERING}.
|
* {@link KeyType#PRIMARY} and its {@link #ordering} to {@link #DEFAULT_ORDERING}.
|
||||||
*
|
*
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
public ColumnSpecification primary() {
|
public ColumnSpecification primary() {
|
||||||
return primary(DFAULT_ORDERING);
|
return primary(DEFAULT_ORDERING);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -70,14 +70,14 @@ public class CassandraExceptionTranslator implements PersistenceExceptionTransla
|
|||||||
*/
|
*/
|
||||||
public DataAccessException translateExceptionIfPossible(RuntimeException x) {
|
public DataAccessException translateExceptionIfPossible(RuntimeException x) {
|
||||||
|
|
||||||
if (!(x instanceof DriverException)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x instanceof DataAccessException) {
|
if (x instanceof DataAccessException) {
|
||||||
return (DataAccessException) x;
|
return (DataAccessException) x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(x instanceof DriverException)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Remember: subclasses must come before superclasses, otherwise the
|
// Remember: subclasses must come before superclasses, otherwise the
|
||||||
// superclass would match before the subclass!
|
// superclass would match before the subclass!
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.springframework.cassandra.test.integration.core.cql.generator;
|
package org.springframework.cassandra.test.integration;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@@ -6,6 +6,7 @@ import java.util.UUID;
|
|||||||
import org.apache.cassandra.exceptions.ConfigurationException;
|
import org.apache.cassandra.exceptions.ConfigurationException;
|
||||||
import org.apache.thrift.transport.TTransportException;
|
import org.apache.thrift.transport.TTransportException;
|
||||||
import org.cassandraunit.utils.EmbeddedCassandraServerHelper;
|
import org.cassandraunit.utils.EmbeddedCassandraServerHelper;
|
||||||
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
|
||||||
@@ -15,12 +16,20 @@ import com.datastax.driver.core.Session;
|
|||||||
|
|
||||||
public abstract class AbstractEmbeddedCassandraIntegrationTest {
|
public abstract class AbstractEmbeddedCassandraIntegrationTest {
|
||||||
|
|
||||||
|
protected final static String CASSANDRA_CONFIG = "cassandra.yaml";
|
||||||
|
protected final static String CASSANDRA_HOST = "localhost";
|
||||||
|
protected final static int CASSANDRA_NATIVE_PORT = 9042;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void beforeClass() throws ConfigurationException, TTransportException, IOException,
|
public static void beforeClass() throws ConfigurationException, TTransportException, IOException,
|
||||||
InterruptedException {
|
InterruptedException {
|
||||||
EmbeddedCassandraServerHelper.startEmbeddedCassandra("cassandra.yaml");
|
EmbeddedCassandraServerHelper.startEmbeddedCassandra(CASSANDRA_CONFIG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to clear the cluster before the next test.
|
||||||
|
*/
|
||||||
|
protected boolean clear = true;
|
||||||
/**
|
/**
|
||||||
* Whether to connect to Cassandra.
|
* Whether to connect to Cassandra.
|
||||||
*/
|
*/
|
||||||
@@ -46,7 +55,7 @@ public abstract class AbstractEmbeddedCassandraIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Cluster cluster() {
|
public Cluster cluster() {
|
||||||
return Cluster.builder().addContactPoint("localhost").withPort(9042).build();
|
return Cluster.builder().addContactPoint(CASSANDRA_HOST).withPort(CASSANDRA_NATIVE_PORT).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -64,8 +73,17 @@ public abstract class AbstractEmbeddedCassandraIntegrationTest {
|
|||||||
session.execute("CREATE KEYSPACE " + keyspace
|
session.execute("CREATE KEYSPACE " + keyspace
|
||||||
+ " WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};");
|
+ " WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};");
|
||||||
session.execute("USE " + keyspace + ";");
|
session.execute("USE " + keyspace + ";");
|
||||||
} // else keyspace already exists
|
} else {// else keyspace already exists
|
||||||
|
session = cluster.connect(keyspace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void after() {
|
||||||
|
if (clear && connected()) {
|
||||||
|
EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package org.springframework.cassandra.test.integration.core.cql.generator;
|
|||||||
import static org.springframework.cassandra.test.integration.core.cql.generator.CqlTableSpecificationAssertions.assertTable;
|
import static org.springframework.cassandra.test.integration.core.cql.generator.CqlTableSpecificationAssertions.assertTable;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.springframework.cassandra.test.integration.AbstractEmbeddedCassandraIntegrationTest;
|
||||||
import org.springframework.cassandra.test.unit.core.cql.generator.CreateTableCqlGeneratorTests.BasicTest;
|
import org.springframework.cassandra.test.unit.core.cql.generator.CreateTableCqlGeneratorTests.BasicTest;
|
||||||
import org.springframework.cassandra.test.unit.core.cql.generator.CreateTableCqlGeneratorTests.CompositePartitionKeyTest;
|
import org.springframework.cassandra.test.unit.core.cql.generator.CreateTableCqlGeneratorTests.CompositePartitionKeyTest;
|
||||||
import org.springframework.cassandra.test.unit.core.cql.generator.CreateTableCqlGeneratorTests.CreateTableTest;
|
import org.springframework.cassandra.test.unit.core.cql.generator.CreateTableCqlGeneratorTests.CreateTableTest;
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011-2013 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed 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 org.springframework.cassandra.test.integration.core.template;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test POJO
|
||||||
|
*
|
||||||
|
* @author David Webb
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Book {
|
||||||
|
|
||||||
|
private String isbn;
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
private String author;
|
||||||
|
private int pages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the isbn.
|
||||||
|
*/
|
||||||
|
public String getIsbn() {
|
||||||
|
return isbn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param isbn The isbn to set.
|
||||||
|
*/
|
||||||
|
public void setIsbn(String isbn) {
|
||||||
|
this.isbn = isbn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the title.
|
||||||
|
*/
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param title The title to set.
|
||||||
|
*/
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the author.
|
||||||
|
*/
|
||||||
|
public String getAuthor() {
|
||||||
|
return author;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param author The author to set.
|
||||||
|
*/
|
||||||
|
public void setAuthor(String author) {
|
||||||
|
this.author = author;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the pages.
|
||||||
|
*/
|
||||||
|
public int getPages() {
|
||||||
|
return pages;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param pages The pages to set.
|
||||||
|
*/
|
||||||
|
public void setPages(int pages) {
|
||||||
|
this.pages = pages;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("isbn -> " + isbn).append("\n");
|
||||||
|
sb.append("tile -> " + title).append("\n");
|
||||||
|
sb.append("author -> " + author).append("\n");
|
||||||
|
sb.append("pages -> " + pages).append("\n");
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,274 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011-2013 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed 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 org.springframework.cassandra.test.integration.core.template;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
import org.cassandraunit.CassandraCQLUnit;
|
||||||
|
import org.cassandraunit.dataset.cql.ClassPathCQLDataSet;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.cassandra.core.CassandraOperations;
|
||||||
|
import org.springframework.cassandra.core.CassandraTemplate;
|
||||||
|
import org.springframework.cassandra.core.HostMapper;
|
||||||
|
import org.springframework.cassandra.core.PreparedStatementBinder;
|
||||||
|
import org.springframework.cassandra.core.ResultSetExtractor;
|
||||||
|
import org.springframework.cassandra.core.RingMember;
|
||||||
|
import org.springframework.cassandra.core.RowIterator;
|
||||||
|
import org.springframework.cassandra.test.integration.AbstractEmbeddedCassandraIntegrationTest;
|
||||||
|
import org.springframework.dao.DataAccessException;
|
||||||
|
|
||||||
|
import com.datastax.driver.core.BoundStatement;
|
||||||
|
import com.datastax.driver.core.Host;
|
||||||
|
import com.datastax.driver.core.PreparedStatement;
|
||||||
|
import com.datastax.driver.core.ResultSet;
|
||||||
|
import com.datastax.driver.core.Row;
|
||||||
|
import com.datastax.driver.core.exceptions.DriverException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit Tests for CassandraTemplate
|
||||||
|
*
|
||||||
|
* @author David Webb
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CassandraOperationsTest extends AbstractEmbeddedCassandraIntegrationTest {
|
||||||
|
|
||||||
|
private CassandraOperations cassandraTemplate;
|
||||||
|
|
||||||
|
private static Logger log = LoggerFactory.getLogger(CassandraOperationsTest.class);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Objects used for test data
|
||||||
|
*/
|
||||||
|
final Object[] o1 = new Object[] { "1234", "Moby Dick", "Herman Manville", new Integer(456) };
|
||||||
|
final Object[] o2 = new Object[] { "2345", "War and Peace", "Russian Dude", new Integer(456) };
|
||||||
|
final Object[] o3 = new Object[] { "3456", "Jane Ayre", "Charlotte", new Integer(456) };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This loads any test specific Cassandra objects
|
||||||
|
*/
|
||||||
|
@Rule
|
||||||
|
public CassandraCQLUnit cassandraCQLUnit = new CassandraCQLUnit(new ClassPathCQLDataSet(
|
||||||
|
"cassandraOperationsTest-cql-dataload.cql", this.keyspace), CASSANDRA_CONFIG, CASSANDRA_HOST,
|
||||||
|
CASSANDRA_NATIVE_PORT);
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setupTemplate() {
|
||||||
|
cassandraTemplate = new CassandraTemplate(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ringTest() {
|
||||||
|
|
||||||
|
List<RingMember> ring = cassandraTemplate.describeRing();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There must be 1 node in the cluster if the embedded server is
|
||||||
|
* running.
|
||||||
|
*/
|
||||||
|
assertNotNull(ring);
|
||||||
|
|
||||||
|
for (RingMember h : ring) {
|
||||||
|
log.info("ringTest Host -> " + h.address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hostMapperTest() {
|
||||||
|
|
||||||
|
List<MyHost> ring = (List<MyHost>) cassandraTemplate.describeRing(new HostMapper<MyHost>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<MyHost> mapHosts(Set<Host> host) throws DriverException {
|
||||||
|
|
||||||
|
List<MyHost> list = new LinkedList<CassandraOperationsTest.MyHost>();
|
||||||
|
|
||||||
|
for (Host h : host) {
|
||||||
|
MyHost mh = new MyHost();
|
||||||
|
mh.someName = h.getAddress().getCanonicalHostName();
|
||||||
|
list.add(mh);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
assertNotNull(ring);
|
||||||
|
Assert.assertTrue(ring.size() > 0);
|
||||||
|
|
||||||
|
for (MyHost h : ring) {
|
||||||
|
log.info("hostMapperTest Host -> " + h.someName);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ingestionTestListOfList() {
|
||||||
|
|
||||||
|
String cql = "insert into book (isbn, title, author, pages) values (?, ?, ?, ?)";
|
||||||
|
|
||||||
|
List<List<?>> values = new LinkedList<List<?>>();
|
||||||
|
|
||||||
|
List<Object> l1 = new LinkedList<Object>();
|
||||||
|
l1.add("1234");
|
||||||
|
l1.add("Moby Dick");
|
||||||
|
l1.add("Herman Manville");
|
||||||
|
l1.add(new Integer(456));
|
||||||
|
|
||||||
|
values.add(l1);
|
||||||
|
|
||||||
|
List<Object> l2 = new LinkedList<Object>();
|
||||||
|
l2.add("2345");
|
||||||
|
l2.add("War and Peace");
|
||||||
|
l2.add("Russian Dude");
|
||||||
|
l2.add(new Integer(456));
|
||||||
|
|
||||||
|
values.add(l2);
|
||||||
|
|
||||||
|
// values.add(new Object[] { "3456", "Jane Ayre", "Charlotte", new Integer(456) });
|
||||||
|
|
||||||
|
cassandraTemplate.ingest(cql, values);
|
||||||
|
|
||||||
|
// Assert that the rows were inserted into Cassandra
|
||||||
|
Book b1 = getBook("1234");
|
||||||
|
Book b2 = getBook("2345");
|
||||||
|
|
||||||
|
Assert.assertEquals(b1.getIsbn(), l1.get(0));
|
||||||
|
Assert.assertEquals(b2.getIsbn(), l2.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ingestionTestObjectArray() {
|
||||||
|
|
||||||
|
String cql = "insert into book (isbn, title, author, pages) values (?, ?, ?, ?)";
|
||||||
|
|
||||||
|
Object[][] values = new Object[3][];
|
||||||
|
values[0] = o1;
|
||||||
|
values[1] = o2;
|
||||||
|
values[2] = o3;
|
||||||
|
|
||||||
|
cassandraTemplate.ingest(cql, values);
|
||||||
|
|
||||||
|
// Assert that the rows were inserted into Cassandra
|
||||||
|
Book b1 = getBook("1234");
|
||||||
|
Book b2 = getBook("2345");
|
||||||
|
Book b3 = getBook("3456");
|
||||||
|
|
||||||
|
Assert.assertEquals(b1.getIsbn(), values[0][0]);
|
||||||
|
Assert.assertEquals(b2.getTitle(), values[1][1]);
|
||||||
|
Assert.assertEquals(b3.getAuthor(), values[2][2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is an implementation of RowIterator for the purposes of testing passing your own Impl to CassandraTemplate
|
||||||
|
*
|
||||||
|
* @author David Webb
|
||||||
|
*/
|
||||||
|
final class MyRowIterator implements RowIterator {
|
||||||
|
|
||||||
|
private Object[][] values;
|
||||||
|
|
||||||
|
public MyRowIterator(Object[][] values) {
|
||||||
|
this.values = values;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.springframework.cassandra.core.RowIterator#next()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Object[] next() {
|
||||||
|
return values[index++];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.springframework.cassandra.core.RowIterator#hasNext()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return index < values.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ingestionTestRowIterator() {
|
||||||
|
|
||||||
|
String cql = "insert into book (isbn, title, author, pages) values (?, ?, ?, ?)";
|
||||||
|
|
||||||
|
final Object[][] v = new Object[3][];
|
||||||
|
v[0] = o1;
|
||||||
|
v[1] = o2;
|
||||||
|
v[2] = o3;
|
||||||
|
RowIterator ri = new MyRowIterator(v);
|
||||||
|
|
||||||
|
cassandraTemplate.ingest(cql, ri);
|
||||||
|
|
||||||
|
// Assert that the rows were inserted into Cassandra
|
||||||
|
Book b1 = getBook("1234");
|
||||||
|
Book b2 = getBook("2345");
|
||||||
|
Book b3 = getBook("3456");
|
||||||
|
|
||||||
|
Assert.assertEquals(b1.getIsbn(), o1[0]);
|
||||||
|
Assert.assertEquals(b2.getTitle(), o2[1]);
|
||||||
|
Assert.assertEquals(b3.getAuthor(), o3[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Book getBook(final String isbn) {
|
||||||
|
|
||||||
|
Book b = this.cassandraTemplate.query("select * from book where isbn = ?", new PreparedStatementBinder() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BoundStatement bindValues(PreparedStatement ps) throws DriverException {
|
||||||
|
return ps.bind(isbn);
|
||||||
|
}
|
||||||
|
}, new ResultSetExtractor<Book>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Book extractData(ResultSet rs) throws DriverException, DataAccessException {
|
||||||
|
Book b = new Book();
|
||||||
|
Row r = rs.one();
|
||||||
|
b.setIsbn(r.getString("isbn"));
|
||||||
|
b.setTitle(r.getString("title"));
|
||||||
|
b.setAuthor(r.getString("author"));
|
||||||
|
b.setPages(r.getInt("pages"));
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return b;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For testing a HostMapper Implementation
|
||||||
|
*/
|
||||||
|
public class MyHost {
|
||||||
|
public String someName;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,12 +22,14 @@ import com.datastax.driver.core.Cluster.Builder;
|
|||||||
@Configuration
|
@Configuration
|
||||||
public class TestConfig extends AbstractCassandraConfiguration {
|
public class TestConfig extends AbstractCassandraConfiguration {
|
||||||
|
|
||||||
|
public static final String keyspace = "test";
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.cassandra.config.AbstractCassandraConfiguration#getKeyspaceName()
|
* @see org.springframework.data.cassandra.config.AbstractCassandraConfiguration#getKeyspaceName()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected String getKeyspaceName() {
|
protected String getKeyspaceName() {
|
||||||
return "test";
|
return keyspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
|||||||
@@ -1,299 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011-2013 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed 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 org.springframework.data.cassandra.test.integration.template;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import junit.framework.Assert;
|
|
||||||
|
|
||||||
import org.apache.cassandra.exceptions.ConfigurationException;
|
|
||||||
import org.apache.thrift.transport.TTransportException;
|
|
||||||
import org.cassandraunit.CassandraCQLUnit;
|
|
||||||
import org.cassandraunit.DataLoader;
|
|
||||||
import org.cassandraunit.dataset.cql.ClassPathCQLDataSet;
|
|
||||||
import org.cassandraunit.dataset.yaml.ClassPathYamlDataSet;
|
|
||||||
import org.cassandraunit.utils.EmbeddedCassandraServerHelper;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.AfterClass;
|
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
|
||||||
import org.springframework.cache.interceptor.DefaultKeyGenerator;
|
|
||||||
import org.springframework.cassandra.core.CachedPreparedStatementCreator;
|
|
||||||
import org.springframework.cassandra.core.CassandraOperations;
|
|
||||||
import org.springframework.cassandra.core.CqlParameter;
|
|
||||||
import org.springframework.cassandra.core.CqlParameterValue;
|
|
||||||
import org.springframework.cassandra.core.HostMapper;
|
|
||||||
import org.springframework.cassandra.core.PreparedStatementBinder;
|
|
||||||
import org.springframework.cassandra.core.PreparedStatementCreatorFactory;
|
|
||||||
import org.springframework.cassandra.core.ResultSetExtractor;
|
|
||||||
import org.springframework.cassandra.core.RingMember;
|
|
||||||
import org.springframework.dao.DataAccessException;
|
|
||||||
import org.springframework.data.cassandra.test.integration.config.TestConfig;
|
|
||||||
import org.springframework.data.cassandra.test.integration.table.Book;
|
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|
||||||
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
|
||||||
|
|
||||||
import com.datastax.driver.core.BoundStatement;
|
|
||||||
import com.datastax.driver.core.DataType;
|
|
||||||
import com.datastax.driver.core.Host;
|
|
||||||
import com.datastax.driver.core.PreparedStatement;
|
|
||||||
import com.datastax.driver.core.ResultSet;
|
|
||||||
import com.datastax.driver.core.Row;
|
|
||||||
import com.datastax.driver.core.Session;
|
|
||||||
import com.datastax.driver.core.exceptions.DriverException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unit Tests for CassandraTemplate
|
|
||||||
*
|
|
||||||
* @author David Webb
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
|
||||||
@ContextConfiguration(classes = { TestConfig.class }, loader = AnnotationConfigContextLoader.class)
|
|
||||||
public class CassandraOperationsTest {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author David Webb
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class MyHost {
|
|
||||||
|
|
||||||
public String someName;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private CassandraOperations cassandraTemplate;
|
|
||||||
|
|
||||||
private static Logger log = LoggerFactory.getLogger(CassandraOperationsTest.class);
|
|
||||||
|
|
||||||
private final static String CASSANDRA_CONFIG = "cassandra.yaml";
|
|
||||||
private final static String KEYSPACE_NAME = "test";
|
|
||||||
private final static String CASSANDRA_HOST = "localhost";
|
|
||||||
private final static int CASSANDRA_NATIVE_PORT = 9042;
|
|
||||||
private final static int CASSANDRA_THRIFT_PORT = 9160;
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public CassandraCQLUnit cassandraCQLUnit = new CassandraCQLUnit(new ClassPathCQLDataSet(
|
|
||||||
"cassandraOperationsTest-cql-dataload.cql", KEYSPACE_NAME), CASSANDRA_CONFIG, CASSANDRA_HOST,
|
|
||||||
CASSANDRA_NATIVE_PORT);
|
|
||||||
|
|
||||||
@BeforeClass
|
|
||||||
public static void startCassandra() throws IOException, TTransportException, ConfigurationException,
|
|
||||||
InterruptedException {
|
|
||||||
|
|
||||||
EmbeddedCassandraServerHelper.startEmbeddedCassandra(CASSANDRA_CONFIG);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Load data file to creat the test keyspace before we init the template
|
|
||||||
*/
|
|
||||||
DataLoader dataLoader = new DataLoader("Test Cluster", CASSANDRA_HOST + ":" + CASSANDRA_THRIFT_PORT);
|
|
||||||
dataLoader.load(new ClassPathYamlDataSet("cassandra-keyspace.yaml"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void ringTest() {
|
|
||||||
|
|
||||||
List<RingMember> ring = cassandraTemplate.describeRing();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* There must be 1 node in the cluster if the embedded server is
|
|
||||||
* running.
|
|
||||||
*/
|
|
||||||
assertNotNull(ring);
|
|
||||||
|
|
||||||
for (RingMember h : ring) {
|
|
||||||
log.info("ringTest Host -> " + h.address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void hostMapperTest() {
|
|
||||||
|
|
||||||
List<MyHost> ring = (List<MyHost>) cassandraTemplate.describeRing(new HostMapper<MyHost>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<MyHost> mapHosts(Set<Host> host) throws DriverException {
|
|
||||||
|
|
||||||
List<MyHost> list = new LinkedList<CassandraOperationsTest.MyHost>();
|
|
||||||
|
|
||||||
for (Host h : host) {
|
|
||||||
MyHost mh = new MyHost();
|
|
||||||
mh.someName = h.getAddress().getCanonicalHostName();
|
|
||||||
list.add(mh);
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
assertNotNull(ring);
|
|
||||||
Assert.assertTrue(ring.size() > 0);
|
|
||||||
|
|
||||||
for (MyHost h : ring) {
|
|
||||||
log.info("hostMapperTest Host -> " + h.someName);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void preparedStatementFactoryTest() {
|
|
||||||
|
|
||||||
String cql = "select * from book where isbn = ?";
|
|
||||||
|
|
||||||
List<CqlParameter> parameters = new LinkedList<CqlParameter>();
|
|
||||||
parameters.add(new CqlParameter("isbn", DataType.text()));
|
|
||||||
|
|
||||||
PreparedStatementCreatorFactory factory = new PreparedStatementCreatorFactory(cql, parameters);
|
|
||||||
|
|
||||||
List<CqlParameterValue> values = new LinkedList<CqlParameterValue>();
|
|
||||||
values.add(new CqlParameterValue(DataType.text(), "999999999"));
|
|
||||||
|
|
||||||
Book b = cassandraTemplate.query(factory.newPreparedStatementCreator(values),
|
|
||||||
factory.newPreparedStatementBinder(values), new ResultSetExtractor<Book>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Book extractData(ResultSet rs) throws DriverException, DataAccessException {
|
|
||||||
Row r = rs.one();
|
|
||||||
Book b = new Book();
|
|
||||||
b.setIsbn(r.getString("isbn"));
|
|
||||||
b.setTitle(r.getString("title"));
|
|
||||||
b.setAuthor(r.getString("author"));
|
|
||||||
b.setPages(r.getInt("pages"));
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
log.info(b.toString());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Test
|
|
||||||
public void cachedPreparedStatementTest() {
|
|
||||||
|
|
||||||
log.info(echoString("Hello"));
|
|
||||||
log.info(echoString("Hello"));
|
|
||||||
|
|
||||||
String cql = "select * from book where isbn = ?";
|
|
||||||
|
|
||||||
CachedPreparedStatementCreator cpsc = new CachedPreparedStatementCreator(cql);
|
|
||||||
|
|
||||||
Book b = cassandraTemplate.query(cpsc, new PreparedStatementBinder() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BoundStatement bindValues(PreparedStatement ps) throws DriverException {
|
|
||||||
return ps.bind("999999999");
|
|
||||||
}
|
|
||||||
}, new ResultSetExtractor<Book>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Book extractData(ResultSet rs) throws DriverException, DataAccessException {
|
|
||||||
Row r = rs.one();
|
|
||||||
Book b = new Book();
|
|
||||||
b.setIsbn(r.getString("isbn"));
|
|
||||||
b.setTitle(r.getString("title"));
|
|
||||||
b.setAuthor(r.getString("author"));
|
|
||||||
b.setPages(r.getInt("pages"));
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
assertNotNull(b);
|
|
||||||
|
|
||||||
log.info(b.toString());
|
|
||||||
|
|
||||||
try {
|
|
||||||
DefaultKeyGenerator generator = new DefaultKeyGenerator();
|
|
||||||
|
|
||||||
// TODO Why does method have to be public to work? Options?
|
|
||||||
Object cacheKey = generator.generate(CachedPreparedStatementCreator.class,
|
|
||||||
CachedPreparedStatementCreator.class.getMethod("getCachedPreparedStatement", Session.class, String.class),
|
|
||||||
cassandraTemplate.getSession(), cql);
|
|
||||||
|
|
||||||
log.info("cacheKey -> " + cacheKey);
|
|
||||||
|
|
||||||
// ConcurrentMapCache cache = (ConcurrentMapCache) cacheManager.getCache("sdc-pstmts");
|
|
||||||
// ConcurrentMap cacheMap = cache.getNativeCache();
|
|
||||||
// assertNotNull(cacheMap);
|
|
||||||
// log.info("CacheMap.size() -> " + cacheMap.size());
|
|
||||||
// ValueWrapper vw = cache.get(cacheKey);
|
|
||||||
// PreparedStatement pstmt = (PreparedStatement) vw.get();
|
|
||||||
// assertNotNull(pstmt);
|
|
||||||
// log.info(pstmt.getQueryString());
|
|
||||||
// assertEquals(pstmt.getQueryString(), cql);
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
log.error("Failed to find method", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
CachedPreparedStatementCreator cpsc2 = new CachedPreparedStatementCreator(cql);
|
|
||||||
|
|
||||||
Book b2 = cassandraTemplate.query(cpsc2, new PreparedStatementBinder() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BoundStatement bindValues(PreparedStatement ps) throws DriverException {
|
|
||||||
return ps.bind("999999999");
|
|
||||||
}
|
|
||||||
}, new ResultSetExtractor<Book>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Book extractData(ResultSet rs) throws DriverException, DataAccessException {
|
|
||||||
Row r = rs.one();
|
|
||||||
Book b = new Book();
|
|
||||||
b.setIsbn(r.getString("isbn"));
|
|
||||||
b.setTitle(r.getString("title"));
|
|
||||||
b.setAuthor(r.getString("author"));
|
|
||||||
b.setPages(r.getInt("pages"));
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
assertNotNull(b2);
|
|
||||||
|
|
||||||
log.info(b2.toString());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Cacheable("sdc-pstmts")
|
|
||||||
public String echoString(String s) {
|
|
||||||
log.info("In EchoString");
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void clearCassandra() {
|
|
||||||
EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterClass
|
|
||||||
public static void stopCassandra() {
|
|
||||||
// EmbeddedCassandraServerHelper.stopEmbeddedCassandra();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user