spring-cassandra now compiling
This commit is contained in:
@@ -22,6 +22,7 @@ import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.cassandra.core.CassandraOperations;
|
||||
import org.springframework.cassandra.core.CassandraTemplate;
|
||||
import org.springframework.cassandra.core.Keyspace;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -31,7 +32,6 @@ import org.springframework.data.cassandra.convert.CassandraConverter;
|
||||
import org.springframework.data.cassandra.convert.MappingCassandraConverter;
|
||||
import org.springframework.data.cassandra.core.CassandraAdminOperations;
|
||||
import org.springframework.data.cassandra.core.CassandraAdminTemplate;
|
||||
import org.springframework.data.cassandra.core.Keyspace;
|
||||
import org.springframework.data.cassandra.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cassandra.core.Keyspace;
|
||||
import org.springframework.cassandra.core.SessionCallback;
|
||||
import org.springframework.cassandra.support.CassandraExceptionTranslator;
|
||||
import org.springframework.cassandra.support.exception.CassandraTableExistsException;
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.cassandra.core.Keyspace;
|
||||
import org.springframework.cassandra.support.CassandraExceptionTranslator;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
|
||||
@@ -11,8 +11,8 @@ import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cassandra.core.Keyspace;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.data.cassandra.core.Keyspace;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,401 +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.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
||||
import com.datastax.driver.core.ResultSet;
|
||||
import com.datastax.driver.core.Session;
|
||||
|
||||
/**
|
||||
* Operations for interacting with Cassandra at the lowest level. This interface provides Exception Translation.
|
||||
*
|
||||
* @author David Webb
|
||||
* @author Matthew Adams
|
||||
*/
|
||||
public interface CassandraOperations {
|
||||
|
||||
/**
|
||||
* Executes the supplied {@link SessionCallback} in the current Template Session. The implementation of
|
||||
* SessionCallback can decide whether or not to <code>execute()</code> or <code>executeAsync()</code> the operation.
|
||||
*
|
||||
* @param sessionCallback
|
||||
* @return Type<T> defined in the SessionCallback
|
||||
*/
|
||||
<T> T execute(SessionCallback<T> sessionCallback) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Executes the supplied CQL Query and returns nothing.
|
||||
*
|
||||
* @param cql
|
||||
*/
|
||||
void execute(final String cql) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Executes the supplied CQL Query Asynchronously and returns nothing.
|
||||
*
|
||||
* @param cql The CQL Statement to execute
|
||||
*/
|
||||
void executeAsynchronously(final String cql) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Executes the provided CQL Query, and extracts the results with the ResultSetExtractor.
|
||||
*
|
||||
* @param cql The Query
|
||||
* @param rse The implementation for extracting the ResultSet
|
||||
*
|
||||
* @return Type <T> specified in the ResultSetExtractor
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
<T> T query(final String cql, ResultSetExtractor<T> rse) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Executes the provided CQL Query asynchronously, and extracts the results with the ResultSetFutureExtractor
|
||||
*
|
||||
* @param cql The Query
|
||||
* @param rse The implementation for extracting the future results
|
||||
* @return
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
<T> T queryAsynchronously(final String cql, ResultSetFutureExtractor<T> rse) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Executes the provided CQL Query, and then processes the results with the <code>RowCallbackHandler</code>.
|
||||
*
|
||||
* @param cql The Query
|
||||
* @param rch The implementation for processing the rows returned.
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
void query(final String cql, RowCallbackHandler rch) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Processes the ResultSet through the RowCallbackHandler and return nothing. This is used internal to the Template
|
||||
* for core operations, but is made available through Operations in the event you have a ResultSet to process. The
|
||||
* ResultsSet could come from a ResultSetFuture after an asynchronous query.
|
||||
*
|
||||
* @param resultSet Results to process
|
||||
* @param rch RowCallbackHandler with the processing implementation
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
void process(ResultSet resultSet, RowCallbackHandler rch) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Executes the provided CQL Query, and maps all Rows returned with the supplied RowMapper.
|
||||
*
|
||||
* @param cql The Query
|
||||
* @param rowMapper The implementation for mapping all rows
|
||||
* @return List of <T> processed by the RowMapper
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
<T> List<T> query(final String cql, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Processes the ResultSet through the RowMapper and returns the List of mapped Rows. This is used internal to the
|
||||
* Template for core operations, but is made available through Operations in the event you have a ResultSet to
|
||||
* process. The ResultsSet could come from a ResultSetFuture after an asynchronous query.
|
||||
*
|
||||
* @param resultSet Results to process
|
||||
* @param rowMapper RowMapper with the processing implementation
|
||||
* @return List of <T> generated by the RowMapper
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
<T> List<T> process(ResultSet resultSet, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Executes the provided CQL Query, and maps <b>ONE</b> Row returned with the supplied RowMapper.
|
||||
*
|
||||
* <p>
|
||||
* This expects only ONE row to be returned. More than one Row will cause an Exception to be thrown.
|
||||
* </p>
|
||||
*
|
||||
* @param cql The Query
|
||||
* @param rowMapper The implementation for convert the Row to <T>
|
||||
* @return Object<T>
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
<T> T queryForObject(final String cql, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Process a ResultSet through a RowMapper. This is used internal to the Template for core operations, but is made
|
||||
* available through Operations in the event you have a ResultSet to process. The ResultsSet could come from a
|
||||
* ResultSetFuture after an asynchronous query.
|
||||
*
|
||||
* @param resultSet
|
||||
* @param rowMapper
|
||||
* @return
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
<T> T processOne(ResultSet resultSet, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Executes the provided query and tries to return the first column of the first Row as a Class<T>.
|
||||
*
|
||||
* @param cql The Query
|
||||
* @param requiredType Valid Class that Cassandra Data Types can be converted to.
|
||||
* @return The Object<T> - item [0,0] in the result table of the query.
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
<T> T queryForObject(final String cql, Class<T> requiredType) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Process a ResultSet, trying to convert the first columns of the first Row to Class<T>. This is used internal to the
|
||||
* Template for core operations, but is made available through Operations in the event you have a ResultSet to
|
||||
* process. The ResultsSet could come from a ResultSetFuture after an asynchronous query.
|
||||
*
|
||||
* @param resultSet
|
||||
* @param requiredType
|
||||
* @return
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
<T> T processOne(ResultSet resultSet, Class<T> requiredType) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Executes the provided CQL Query and maps <b>ONE</b> Row to a basic Map of Strings and Objects. If more than one Row
|
||||
* is returned from the Query, an exception will be thrown.
|
||||
*
|
||||
* @param cql The Query
|
||||
* @return Map representing the results of the Query
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
Map<String, Object> queryForMap(final String cql) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Process a ResultSet with <b>ONE</b> Row and convert to a Map. This is used internal to the Template for core
|
||||
* operations, but is made available through Operations in the event you have a ResultSet to process. The ResultsSet
|
||||
* could come from a ResultSetFuture after an asynchronous query.
|
||||
*
|
||||
* @param resultSet
|
||||
* @return
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
Map<String, Object> processMap(ResultSet resultSet) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Executes the provided CQL and returns all values in the first column of the Results as a List of the Type in the
|
||||
* second argument.
|
||||
*
|
||||
* @param cql The Query
|
||||
* @param elementType Type to cast the data values to
|
||||
* @return List of elementType
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
<T> List<T> queryForList(final String cql, Class<T> elementType) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Process a ResultSet and convert the first column of the results to a List. This is used internal to the Template
|
||||
* for core operations, but is made available through Operations in the event you have a ResultSet to process. The
|
||||
* ResultsSet could come from a ResultSetFuture after an asynchronous query.
|
||||
*
|
||||
* @param resultSet
|
||||
* @param elementType
|
||||
* @return
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
<T> List<T> processList(ResultSet resultSet, Class<T> elementType) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Executes the provided CQL and converts the results to a basic List of Maps. Each element in the List represents a
|
||||
* Row returned from the Query. Each Row's columns are put into the map as column/value.
|
||||
*
|
||||
* @param cql The Query
|
||||
* @return List of Maps with the query results
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
List<Map<String, Object>> queryForListOfMap(final String cql) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Process a ResultSet and convert it to a List of Maps with column/value. This is used internal to the Template for
|
||||
* core operations, but is made available through Operations in the event you have a ResultSet to process. The
|
||||
* ResultsSet could come from a ResultSetFuture after an asynchronous query.
|
||||
*
|
||||
* @param resultSet
|
||||
* @return
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
List<Map<String, Object>> processListOfMap(ResultSet resultSet) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Converts the CQL provided into a {@link SimplePreparedStatementCreator}. <b>This can only be used for CQL
|
||||
* Statements that do not have data binding.</b> The results of the PreparedStatement are processed with
|
||||
* PreparedStatementCallback implementation provided by the Application Code.
|
||||
*
|
||||
* @param cql The CQL Statement to Execute
|
||||
* @param action What to do with the results of the PreparedStatement
|
||||
* @return Type<T> as determined by the supplied Callback.
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
<T> T execute(String cql, PreparedStatementCallback<T> action) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Uses the provided PreparedStatementCreator to prepare a new Session call, then executes the statement and processes
|
||||
* the statement using the provided Callback. <b>This can only be used for CQL Statements that do not have data
|
||||
* binding.</b> The results of the PreparedStatement are processed with PreparedStatementCallback implementation
|
||||
* provided by the Application Code.
|
||||
*
|
||||
* @param psc The implementation to create the PreparedStatement
|
||||
* @param action What to do with the results of the PreparedStatement
|
||||
* @return Type<T> as determined by the supplied Callback.
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
<T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Converts the CQL provided into a {@link SimplePreparedStatementCreator}. Then, the PreparedStatementBinder will
|
||||
* bind its values to the bind variables in the provided CQL String. The results of the PreparedStatement are
|
||||
* processed with the ResultSetExtractor implementation provided by the Application Code. The can return any object,
|
||||
* including a List of Objects to support the ResultSet processing.
|
||||
*
|
||||
* @param cql The Query to Prepare
|
||||
* @param psb The Binding implementation
|
||||
* @param rse The implementation for extracting the results of the query.
|
||||
* @return Type<T> generated by the ResultSetExtractor
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
<T> T query(final String cql, PreparedStatementBinder psb, ResultSetExtractor<T> rse) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Converts the CQL provided into a {@link SimplePreparedStatementCreator}. Then, the PreparedStatementBinder will
|
||||
* bind its values to the bind variables in the provided CQL String. The results of the PreparedStatement are
|
||||
* processed with the RowCallbackHandler implementation provided and nothing is returned.
|
||||
*
|
||||
* @param cql The Query to Prepare
|
||||
* @param psb The Binding implementation
|
||||
* @param rch The RowCallbackHandler for processing the ResultSet
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
void query(final String cql, PreparedStatementBinder psb, RowCallbackHandler rch) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Converts the CQL provided into a {@link SimplePreparedStatementCreator}. Then, the PreparedStatementBinder will
|
||||
* bind its values to the bind variables in the provided CQL String. The results of the PreparedStatement are
|
||||
* processed with the RowMapper implementation provided and a List is returned with elements of Type <T> for each Row
|
||||
* returned.
|
||||
*
|
||||
* @param cql The Query to Prepare
|
||||
* @param psb The Binding implementation
|
||||
* @param rowMapper The implementation for Mapping a Row to Type <T>
|
||||
* @return List of <T> for each Row returned from the Query.
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
<T> List<T> query(final String cql, PreparedStatementBinder psb, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Uses the provided PreparedStatementCreator to prepare a new Session call. <b>This can only be used for CQL
|
||||
* Statements that do not have data binding.</b> The results of the PreparedStatement are processed with
|
||||
* ResultSetExtractor implementation provided by the Application Code.
|
||||
*
|
||||
* @param psc The implementation to create the PreparedStatement
|
||||
* @param rse Implementation for extracting from the ResultSet
|
||||
* @return Type <T> which is the output of the ResultSetExtractor
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
<T> T query(PreparedStatementCreator psc, ResultSetExtractor<T> rse) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Uses the provided PreparedStatementCreator to prepare a new Session call. <b>This can only be used for CQL
|
||||
* Statements that do not have data binding.</b> The results of the PreparedStatement are processed with
|
||||
* RowCallbackHandler and nothing is returned.
|
||||
*
|
||||
* @param psc The implementation to create the PreparedStatement
|
||||
* @param rch The implementation to process Results
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
void query(PreparedStatementCreator psc, RowCallbackHandler rch) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Uses the provided PreparedStatementCreator to prepare a new Session call. <b>This can only be used for CQL
|
||||
* Statements that do not have data binding.</b> The results of the PreparedStatement are processed with RowMapper
|
||||
* implementation provided and a List is returned with elements of Type <T> for each Row returned.
|
||||
*
|
||||
* @param psc The implementation to create the PreparedStatement
|
||||
* @param rowMapper The implementation for mapping each Row returned.
|
||||
* @return List of Type <T> mapped from each Row in the Results
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
<T> List<T> query(PreparedStatementCreator psc, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Uses the provided PreparedStatementCreator to prepare a new Session call. Binds the values from the
|
||||
* PreparedStatementBinder to the available bind variables. The results of the PreparedStatement are processed with
|
||||
* ResultSetExtractor implementation provided by the Application Code.
|
||||
*
|
||||
* @param psc The implementation to create the PreparedStatement
|
||||
* @param psb The implementation to bind variables to values
|
||||
* @param rse Implementation for extracting from the ResultSet
|
||||
* @return Type <T> which is the output of the ResultSetExtractor
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
<T> T query(PreparedStatementCreator psc, final PreparedStatementBinder psb, final ResultSetExtractor<T> rse)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Uses the provided PreparedStatementCreator to prepare a new Session call. Binds the values from the
|
||||
* PreparedStatementBinder to the available bind variables. The results of the PreparedStatement are processed with
|
||||
* RowCallbackHandler and nothing is returned.
|
||||
*
|
||||
* @param psc The implementation to create the PreparedStatement
|
||||
* @param psb The implementation to bind variables to values
|
||||
* @param rch The implementation to process Results
|
||||
* @return Type <T> which is the output of the ResultSetExtractor
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
void query(PreparedStatementCreator psc, final PreparedStatementBinder psb, final RowCallbackHandler rch)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Uses the provided PreparedStatementCreator to prepare a new Session call. Binds the values from the
|
||||
* PreparedStatementBinder to the available bind variables. The results of the PreparedStatement are processed with
|
||||
* RowMapper implementation provided and a List is returned with elements of Type <T> for each Row returned.
|
||||
*
|
||||
* @param psc The implementation to create the PreparedStatement
|
||||
* @param psb The implementation to bind variables to values
|
||||
* @param rowMapper The implementation for mapping each Row returned.
|
||||
* @return Type <T> which is the output of the ResultSetExtractor
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
<T> List<T> query(PreparedStatementCreator psc, final PreparedStatementBinder psb, final RowMapper<T> rowMapper)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Describe the current Ring. This uses the provided {@link RingMemberHostMapper} to provide the basics of the
|
||||
* Cassandra Ring topology.
|
||||
*
|
||||
* @return The list of ring tokens that are active in the cluster
|
||||
*/
|
||||
List<RingMember> describeRing() throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Describe the current Ring. Application code must provide its own {@link HostMapper} implementation to process the
|
||||
* lists of hosts returned by the Cassandra Cluster Metadata.
|
||||
*
|
||||
* @param hostMapper The implementation to use for host mapping.
|
||||
* @return Collection generated by the provided HostMapper.
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
<T> Collection<T> describeRing(HostMapper<T> hostMapper) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Get the current Session used for operations in the implementing class.
|
||||
*
|
||||
* @return The DataStax Driver Session Object
|
||||
*/
|
||||
Session getSession();
|
||||
|
||||
}
|
||||
@@ -1,562 +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.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.cassandra.support.CassandraAccessor;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.cassandra.core.CassandraDataTemplate;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.BoundStatement;
|
||||
import com.datastax.driver.core.ColumnDefinitions;
|
||||
import com.datastax.driver.core.ColumnDefinitions.Definition;
|
||||
import com.datastax.driver.core.Host;
|
||||
import com.datastax.driver.core.Metadata;
|
||||
import com.datastax.driver.core.PreparedStatement;
|
||||
import com.datastax.driver.core.ResultSet;
|
||||
import com.datastax.driver.core.ResultSetFuture;
|
||||
import com.datastax.driver.core.Row;
|
||||
import com.datastax.driver.core.Session;
|
||||
import com.datastax.driver.core.exceptions.DriverException;
|
||||
|
||||
/**
|
||||
* <b>This is the Central class in the Cassandra core package.</b> It simplifies the use of Cassandra and helps to avoid
|
||||
* common errors. It executes the core Cassandra workflow, leaving application code to provide CQL and result
|
||||
* extraction. This class execute CQL Queries, provides different ways to extract/map results, and provides Exception
|
||||
* translation to the generic, more informative exception hierarchy defined in the <code>org.springframework.dao</code>
|
||||
* package.
|
||||
*
|
||||
* <p>
|
||||
* For working with POJOs, use the {@link CassandraDataTemplate}.
|
||||
* </p>
|
||||
*
|
||||
* @author David Webb
|
||||
* @author Matthew Adams
|
||||
*/
|
||||
public class CassandraTemplate extends CassandraAccessor implements CassandraOperations {
|
||||
|
||||
/**
|
||||
* Blank constructor. You must wire in the Session before use.
|
||||
*
|
||||
*/
|
||||
public CassandraTemplate() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used for a basic template configuration
|
||||
*
|
||||
* @param session must not be {@literal null}.
|
||||
*/
|
||||
public CassandraTemplate(Session session) {
|
||||
setSession(session);
|
||||
afterPropertiesSet();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.CassandraOperations#execute(org.springframework.data.cassandra.core.SessionCallback)
|
||||
*/
|
||||
@Override
|
||||
public <T> T execute(SessionCallback<T> sessionCallback) throws DataAccessException {
|
||||
return doExecute(sessionCallback);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.CassandraOperations#execute(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void execute(final String cql) throws DataAccessException {
|
||||
doExecute(cql);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#query(java.lang.String, org.springframework.cassandra.core.FutureResultSetExtractor)
|
||||
*/
|
||||
@Override
|
||||
public <T> T queryAsynchronously(final String cql, ResultSetFutureExtractor<T> rse) throws DataAccessException {
|
||||
return rse.extractData(execute(new SessionCallback<ResultSetFuture>() {
|
||||
@Override
|
||||
public ResultSetFuture doInSession(Session s) throws DataAccessException {
|
||||
return s.executeAsync(cql);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#query(java.lang.String, org.springframework.cassandra.core.ResultSetExtractor)
|
||||
*/
|
||||
public <T> T query(String cql, ResultSetExtractor<T> rse) throws DataAccessException {
|
||||
ResultSet rs = doExecute(cql);
|
||||
return rse.extractData(rs);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#query(java.lang.String, org.springframework.cassandra.core.RowCallbackHandler)
|
||||
*/
|
||||
public void query(String cql, RowCallbackHandler rch) throws DataAccessException {
|
||||
process(doExecute(cql), rch);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#query(java.lang.String, org.springframework.cassandra.core.RowMapper)
|
||||
*/
|
||||
public <T> List<T> query(String cql, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
return process(doExecute(cql), rowMapper);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#queryForList(java.lang.String)
|
||||
*/
|
||||
public List<Map<String, Object>> queryForListOfMap(String cql) throws DataAccessException {
|
||||
return processListOfMap(doExecute(cql));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#queryForList(java.lang.String, java.lang.Class)
|
||||
*/
|
||||
public <T> List<T> queryForList(String cql, Class<T> elementType) throws DataAccessException {
|
||||
return processList(doExecute(cql), elementType);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#queryForMap(java.lang.String)
|
||||
*/
|
||||
public Map<String, Object> queryForMap(String cql) throws DataAccessException {
|
||||
return processMap(doExecute(cql));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#queryForObject(java.lang.String, java.lang.Class)
|
||||
*/
|
||||
public <T> T queryForObject(String cql, Class<T> requiredType) throws DataAccessException {
|
||||
return processOne(doExecute(cql), requiredType);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#queryForObject(java.lang.String, org.springframework.cassandra.core.RowMapper)
|
||||
*/
|
||||
public <T> T queryForObject(String cql, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
return processOne(doExecute(cql), rowMapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a command at the Session Level
|
||||
*
|
||||
* @param callback
|
||||
* @return
|
||||
*/
|
||||
protected <T> T doExecute(SessionCallback<T> callback) {
|
||||
|
||||
Assert.notNull(callback);
|
||||
|
||||
try {
|
||||
|
||||
return callback.doInSession(getSession());
|
||||
|
||||
} catch (DataAccessException e) {
|
||||
throw throwTranslated(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a command at the Session Level
|
||||
*
|
||||
* @param callback
|
||||
* @return
|
||||
*/
|
||||
protected ResultSet doExecute(final String cql) {
|
||||
|
||||
return doExecute(new SessionCallback<ResultSet>() {
|
||||
|
||||
@Override
|
||||
public ResultSet doInSession(Session s) throws DataAccessException {
|
||||
return s.execute(cql);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a command at the Session Level
|
||||
*
|
||||
* @param callback
|
||||
* @return
|
||||
*/
|
||||
protected ResultSet doExecute(final BoundStatement bs) {
|
||||
|
||||
return doExecute(new SessionCallback<ResultSet>() {
|
||||
|
||||
@Override
|
||||
public ResultSet doInSession(Session s) throws DataAccessException {
|
||||
return s.execute(bs);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param row
|
||||
* @return
|
||||
*/
|
||||
protected Object firstColumnToObject(Row row) {
|
||||
ColumnDefinitions cols = row.getColumnDefinitions();
|
||||
if (cols.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
return cols.getType(0).deserialize(row.getBytesUnsafe(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param row
|
||||
* @return
|
||||
*/
|
||||
protected Map<String, Object> toMap(Row row) {
|
||||
if (row == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ColumnDefinitions cols = row.getColumnDefinitions();
|
||||
Map<String, Object> map = new HashMap<String, Object>(cols.size());
|
||||
|
||||
for (Definition def : cols.asList()) {
|
||||
String name = def.getName();
|
||||
map.put(name, def.getType().deserialize(row.getBytesUnsafe(name)));
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#describeRing()
|
||||
*/
|
||||
@Override
|
||||
public List<RingMember> describeRing() throws DataAccessException {
|
||||
return new ArrayList<RingMember>(describeRing(new RingMemberHostMapper()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Pulls the list of Hosts for the current Session
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private Set<Host> getHosts() {
|
||||
|
||||
/*
|
||||
* Get the cluster metadata for this session
|
||||
*/
|
||||
Metadata clusterMetadata = doExecute(new SessionCallback<Metadata>() {
|
||||
|
||||
@Override
|
||||
public Metadata doInSession(Session s) throws DataAccessException {
|
||||
return s.getCluster().getMetadata();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/*
|
||||
* Get all hosts in the cluster
|
||||
*/
|
||||
Set<Host> hosts = clusterMetadata.getAllHosts();
|
||||
|
||||
return hosts;
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#describeRing(org.springframework.cassandra.core.HostMapper)
|
||||
*/
|
||||
@Override
|
||||
public <T> Collection<T> describeRing(HostMapper<T> hostMapper) throws DataAccessException {
|
||||
Set<Host> hosts = getHosts();
|
||||
return hostMapper.mapHosts(hosts);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#executeAsynchronously(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void executeAsynchronously(final String cql) throws DataAccessException {
|
||||
execute(new SessionCallback<Object>() {
|
||||
@Override
|
||||
public Object doInSession(Session s) throws DataAccessException {
|
||||
return s.executeAsync(cql);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#process(com.datastax.driver.core.ResultSet, org.springframework.cassandra.core.RowCallbackHandler)
|
||||
*/
|
||||
@Override
|
||||
public void process(ResultSet resultSet, RowCallbackHandler rch) throws DataAccessException {
|
||||
try {
|
||||
for (Row row : resultSet.all()) {
|
||||
rch.processRow(row);
|
||||
}
|
||||
} catch (DriverException dx) {
|
||||
throwTranslated(dx);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#process(com.datastax.driver.core.ResultSet, org.springframework.cassandra.core.RowMapper)
|
||||
*/
|
||||
@Override
|
||||
public <T> List<T> process(ResultSet resultSet, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
List<T> mappedRows = new ArrayList<T>();
|
||||
try {
|
||||
int i = 0;
|
||||
for (Row row : resultSet.all()) {
|
||||
mappedRows.add(rowMapper.mapRow(row, i++));
|
||||
}
|
||||
} catch (DriverException dx) {
|
||||
throwTranslated(dx);
|
||||
}
|
||||
return mappedRows;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#processOne(com.datastax.driver.core.ResultSet, org.springframework.cassandra.core.RowMapper)
|
||||
*/
|
||||
@Override
|
||||
public <T> T processOne(ResultSet resultSet, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
T row = null;
|
||||
Assert.notNull(resultSet, "ResultSet cannot be null");
|
||||
try {
|
||||
List<Row> rows = resultSet.all();
|
||||
Assert.notNull(rows, "null row list returned from query");
|
||||
Assert.isTrue(rows.size() == 1, "row list has " + rows.size() + " rows instead of one");
|
||||
row = rowMapper.mapRow(rows.get(0), 0);
|
||||
} catch (DriverException dx) {
|
||||
throwTranslated(dx);
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#processOne(com.datastax.driver.core.ResultSet, java.lang.Class)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> T processOne(ResultSet resultSet, Class<T> requiredType) throws DataAccessException {
|
||||
if (resultSet == null) {
|
||||
return null;
|
||||
}
|
||||
Row row = resultSet.one();
|
||||
if (row == null) {
|
||||
return null;
|
||||
}
|
||||
return (T) firstColumnToObject(row);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#processMap(com.datastax.driver.core.ResultSet)
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> processMap(ResultSet resultSet) throws DataAccessException {
|
||||
if (resultSet == null) {
|
||||
return null;
|
||||
}
|
||||
return toMap(resultSet.one());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#processList(com.datastax.driver.core.ResultSet, java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public <T> List<T> processList(ResultSet resultSet, Class<T> elementType) throws DataAccessException {
|
||||
List<Row> rows = resultSet.all();
|
||||
List<T> list = new ArrayList<T>(rows.size());
|
||||
for (Row row : rows) {
|
||||
list.add((T) firstColumnToObject(row));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#processListOfMap(com.datastax.driver.core.ResultSet)
|
||||
*/
|
||||
@Override
|
||||
public List<Map<String, Object>> processListOfMap(ResultSet resultSet) throws DataAccessException {
|
||||
List<Row> rows = resultSet.all();
|
||||
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(rows.size());
|
||||
for (Row row : rows) {
|
||||
list.add(toMap(row));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to translate a Runtime Exception to a Spring Data Exception
|
||||
*
|
||||
* @param ex
|
||||
* @return
|
||||
*/
|
||||
protected RuntimeException throwTranslated(RuntimeException ex) {
|
||||
RuntimeException resolved = getExceptionTranslator().translateExceptionIfPossible(ex);
|
||||
return resolved == null ? ex : resolved;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#execute(org.springframework.cassandra.core.PreparedStatementCreator, org.springframework.cassandra.core.PreparedStatementCallback)
|
||||
*/
|
||||
@Override
|
||||
public <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action) {
|
||||
|
||||
try {
|
||||
PreparedStatement ps = psc.createPreparedStatement(getSession());
|
||||
return action.doInPreparedStatement(ps);
|
||||
} catch (DriverException dx) {
|
||||
throwTranslated(dx);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#execute(java.lang.String, org.springframework.cassandra.core.PreparedStatementCallback)
|
||||
*/
|
||||
@Override
|
||||
public <T> T execute(String cql, PreparedStatementCallback<T> action) {
|
||||
return execute(new SimplePreparedStatementCreator(cql), action);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#query(org.springframework.cassandra.core.PreparedStatementCreator, org.springframework.cassandra.core.ResultSetExtractor)
|
||||
*/
|
||||
@Override
|
||||
public <T> T query(PreparedStatementCreator psc, ResultSetExtractor<T> rse) throws DataAccessException {
|
||||
return query(psc, null, rse);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#query(org.springframework.cassandra.core.PreparedStatementCreator, org.springframework.cassandra.core.RowCallbackHandler)
|
||||
*/
|
||||
@Override
|
||||
public void query(PreparedStatementCreator psc, RowCallbackHandler rch) throws DataAccessException {
|
||||
query(psc, null, rch);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#query(org.springframework.cassandra.core.PreparedStatementCreator, org.springframework.cassandra.core.RowMapper)
|
||||
*/
|
||||
@Override
|
||||
public <T> List<T> query(PreparedStatementCreator psc, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
return query(psc, null, rowMapper);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#query(org.springframework.cassandra.core.PreparedStatementCreator, org.springframework.cassandra.core.PreparedStatementSetter, org.springframework.cassandra.core.ResultSetExtractor)
|
||||
*/
|
||||
public <T> T query(PreparedStatementCreator psc, final PreparedStatementBinder psb, final ResultSetExtractor<T> rse)
|
||||
throws DataAccessException {
|
||||
|
||||
Assert.notNull(rse, "ResultSetExtractor must not be null");
|
||||
logger.debug("Executing prepared CQL query");
|
||||
|
||||
return execute(psc, new PreparedStatementCallback<T>() {
|
||||
public T doInPreparedStatement(PreparedStatement ps) throws DriverException {
|
||||
ResultSet rs = null;
|
||||
BoundStatement bs = null;
|
||||
if (psb != null) {
|
||||
bs = psb.bindValues(ps);
|
||||
} else {
|
||||
bs = ps.bind();
|
||||
}
|
||||
rs = doExecute(bs);
|
||||
return rse.extractData(rs);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#query(java.lang.String, org.springframework.cassandra.core.PreparedStatementSetter, org.springframework.cassandra.core.ResultSetExtractor)
|
||||
*/
|
||||
@Override
|
||||
public <T> T query(String cql, PreparedStatementBinder psb, ResultSetExtractor<T> rse) throws DataAccessException {
|
||||
return query(new SimplePreparedStatementCreator(cql), psb, rse);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#query(java.lang.String, org.springframework.cassandra.core.PreparedStatementSetter, org.springframework.cassandra.core.RowCallbackHandler)
|
||||
*/
|
||||
@Override
|
||||
public void query(String cql, PreparedStatementBinder psb, RowCallbackHandler rch) throws DataAccessException {
|
||||
query(new SimplePreparedStatementCreator(cql), psb, rch);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#query(java.lang.String, org.springframework.cassandra.core.PreparedStatementSetter, org.springframework.cassandra.core.RowMapper)
|
||||
*/
|
||||
@Override
|
||||
public <T> List<T> query(String cql, PreparedStatementBinder psb, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
return query(new SimplePreparedStatementCreator(cql), psb, rowMapper);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#query(org.springframework.cassandra.core.PreparedStatementCreator, org.springframework.cassandra.core.PreparedStatementBinder, org.springframework.cassandra.core.RowCallbackHandler)
|
||||
*/
|
||||
@Override
|
||||
public void query(PreparedStatementCreator psc, final PreparedStatementBinder psb, final RowCallbackHandler rch)
|
||||
throws DataAccessException {
|
||||
Assert.notNull(rch, "RowCallbackHandler must not be null");
|
||||
logger.debug("Executing prepared CQL query");
|
||||
|
||||
execute(psc, new PreparedStatementCallback<Object>() {
|
||||
public Object doInPreparedStatement(PreparedStatement ps) throws DriverException {
|
||||
ResultSet rs = null;
|
||||
BoundStatement bs = null;
|
||||
if (psb != null) {
|
||||
bs = psb.bindValues(ps);
|
||||
} else {
|
||||
bs = ps.bind();
|
||||
}
|
||||
rs = doExecute(bs);
|
||||
process(rs, rch);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CassandraOperations#query(org.springframework.cassandra.core.PreparedStatementCreator, org.springframework.cassandra.core.PreparedStatementBinder, org.springframework.cassandra.core.RowMapper)
|
||||
*/
|
||||
@Override
|
||||
public <T> List<T> query(PreparedStatementCreator psc, final PreparedStatementBinder psb, final RowMapper<T> rowMapper)
|
||||
throws DataAccessException {
|
||||
Assert.notNull(rowMapper, "RowMapper must not be null");
|
||||
logger.debug("Executing prepared CQL query");
|
||||
|
||||
return execute(psc, new PreparedStatementCallback<List<T>>() {
|
||||
public List<T> doInPreparedStatement(PreparedStatement ps) throws DriverException {
|
||||
ResultSet rs = null;
|
||||
BoundStatement bs = null;
|
||||
if (psb != null) {
|
||||
bs = psb.bindValues(ps);
|
||||
} else {
|
||||
bs = ps.bind();
|
||||
}
|
||||
rs = doExecute(bs);
|
||||
|
||||
return process(rs, rowMapper);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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,26 +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;
|
||||
|
||||
/**
|
||||
* @author David Webb
|
||||
*
|
||||
*/
|
||||
public interface CqlProvider {
|
||||
|
||||
String getCql();
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.springframework.cassandra.core;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import com.datastax.driver.core.Host;
|
||||
import com.datastax.driver.core.exceptions.DriverException;
|
||||
|
||||
public interface HostMapper<T> {
|
||||
|
||||
Collection<T> mapHosts(Set<Host> host) throws DriverException;
|
||||
|
||||
}
|
||||
@@ -1,30 +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.BoundStatement;
|
||||
import com.datastax.driver.core.PreparedStatement;
|
||||
import com.datastax.driver.core.exceptions.DriverException;
|
||||
|
||||
/**
|
||||
* @author David Webb
|
||||
*
|
||||
*/
|
||||
public interface PreparedStatementBinder {
|
||||
|
||||
BoundStatement bindValues(PreparedStatement ps) throws DriverException;
|
||||
|
||||
}
|
||||
@@ -1,31 +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.springframework.dao.DataAccessException;
|
||||
|
||||
import com.datastax.driver.core.PreparedStatement;
|
||||
import com.datastax.driver.core.exceptions.DriverException;
|
||||
|
||||
/**
|
||||
* @author David Webb
|
||||
*
|
||||
*/
|
||||
public interface PreparedStatementCallback<T> {
|
||||
|
||||
T doInPreparedStatement(PreparedStatement ps) throws DriverException, DataAccessException;
|
||||
|
||||
}
|
||||
@@ -1,41 +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.PreparedStatement;
|
||||
import com.datastax.driver.core.Session;
|
||||
import com.datastax.driver.core.exceptions.DriverException;
|
||||
|
||||
/**
|
||||
* Creates a PreparedStatement for the usage with the DataStax Java Driver
|
||||
*
|
||||
* @author David Webb
|
||||
*
|
||||
*/
|
||||
public interface PreparedStatementCreator {
|
||||
|
||||
/**
|
||||
* Create a statement in this session. Allows implementations to use PreparedStatements. The CassandraTemlate will
|
||||
* attempt to cache the PreparedStatement for future use without the overhead of re-preparing on the entire cluster.
|
||||
*
|
||||
* @param session Session to use to create statement
|
||||
* @return a prepared statement
|
||||
* @throws DriverException there is no need to catch DriverException that may be thrown in the implementation of this
|
||||
* method. The CassandraTemlate class will handle them.
|
||||
*/
|
||||
PreparedStatement createPreparedStatement(Session session) throws DriverException;
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,73 +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.List;
|
||||
|
||||
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 PreparedStatementCreatorImpl implements PreparedStatementCreator, CqlProvider, PreparedStatementBinder {
|
||||
|
||||
private final String cql;
|
||||
private List<Object> values;
|
||||
|
||||
public PreparedStatementCreatorImpl(String cql) {
|
||||
this.cql = cql;
|
||||
}
|
||||
|
||||
public PreparedStatementCreatorImpl(String cql, List<Object> values) {
|
||||
this.cql = cql;
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.PreparedStatementSetter#setValues(com.datastax.driver.core.PreparedStatement)
|
||||
*/
|
||||
@Override
|
||||
public BoundStatement bindValues(PreparedStatement ps) throws DriverException {
|
||||
// Nothing to set if there are no values
|
||||
if (values == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ps.bind(values.toArray());
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CqlProvider#getCql()
|
||||
*/
|
||||
@Override
|
||||
public String getCql() {
|
||||
return this.cql;
|
||||
}
|
||||
|
||||
/* (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.cql);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package org.springframework.cassandra.core;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
||||
import com.datastax.driver.core.ResultSet;
|
||||
import com.datastax.driver.core.exceptions.DriverException;
|
||||
|
||||
public interface ResultSetExtractor<T> {
|
||||
|
||||
T extractData(ResultSet rs) throws DriverException, DataAccessException;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package org.springframework.cassandra.core;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
||||
import com.datastax.driver.core.ResultSetFuture;
|
||||
import com.datastax.driver.core.exceptions.DriverException;
|
||||
|
||||
public interface ResultSetFutureExtractor<T> {
|
||||
|
||||
T extractData(ResultSetFuture rs) throws DriverException, DataAccessException;
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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.io.Serializable;
|
||||
|
||||
import com.datastax.driver.core.Host;
|
||||
|
||||
/**
|
||||
* @author David Webb
|
||||
*
|
||||
*/
|
||||
public final class RingMember implements Serializable {
|
||||
|
||||
/*
|
||||
* Ring attributes
|
||||
*/
|
||||
public String hostName;
|
||||
public String address;
|
||||
public String DC;
|
||||
public String rack;
|
||||
|
||||
public RingMember(Host h) {
|
||||
this.hostName = h.getAddress().getHostName();
|
||||
this.address = h.getAddress().getHostAddress();
|
||||
this.DC = h.getDatacenter();
|
||||
this.rack = h.getRack();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,54 +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.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.Host;
|
||||
import com.datastax.driver.core.exceptions.DriverException;
|
||||
|
||||
/**
|
||||
* @author David Webb
|
||||
* @param <T>
|
||||
*
|
||||
*/
|
||||
public class RingMemberHostMapper implements HostMapper<RingMember> {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.HostMapper#mapHosts(java.util.Set)
|
||||
*/
|
||||
@Override
|
||||
public List<RingMember> mapHosts(Set<Host> hosts) throws DriverException {
|
||||
|
||||
List<RingMember> members = new ArrayList<RingMember>();
|
||||
|
||||
Assert.notNull(hosts);
|
||||
Assert.notEmpty(hosts);
|
||||
|
||||
RingMember r = null;
|
||||
for (Host host : hosts) {
|
||||
r = new RingMember(host);
|
||||
members.add(r);
|
||||
}
|
||||
|
||||
return members;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,29 +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.Row;
|
||||
|
||||
/**
|
||||
* Simple internal callback to allow operations on a {@link Row}.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*/
|
||||
|
||||
public interface RowCallback<T> {
|
||||
|
||||
T doWith(Row object);
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package org.springframework.cassandra.core;
|
||||
|
||||
import com.datastax.driver.core.Row;
|
||||
import com.datastax.driver.core.exceptions.DriverException;
|
||||
|
||||
public interface RowCallbackHandler {
|
||||
|
||||
void processRow(Row row) throws DriverException;
|
||||
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package org.springframework.cassandra.core;
|
||||
|
||||
import com.datastax.driver.core.Row;
|
||||
import com.datastax.driver.core.exceptions.DriverException;
|
||||
|
||||
public interface RowMapper<T> {
|
||||
|
||||
T mapRow(Row row, int rowNum) throws DriverException;
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2011 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.springframework.dao.DataAccessException;
|
||||
|
||||
import com.datastax.driver.core.Session;
|
||||
|
||||
/**
|
||||
* Interface for operations on a Cassandra Session.
|
||||
*
|
||||
* @author David Webb
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public interface SessionCallback<T> {
|
||||
|
||||
/**
|
||||
* Perform the operation in the given Session
|
||||
*
|
||||
* @param s
|
||||
* @return
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
T doInSession(Session s) throws DataAccessException;
|
||||
|
||||
}
|
||||
@@ -1,87 +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.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.data.cassandra.core.Keyspace;
|
||||
|
||||
import com.datastax.driver.core.Session;
|
||||
|
||||
/**
|
||||
* @author David Webb
|
||||
*
|
||||
*/
|
||||
public class SessionFactoryBean implements FactoryBean<Session>, InitializingBean {
|
||||
|
||||
private Keyspace keyspace;
|
||||
|
||||
public SessionFactoryBean() {
|
||||
}
|
||||
|
||||
public SessionFactoryBean(Keyspace keyspace) {
|
||||
setKeyspace(keyspace);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (keyspace == null) {
|
||||
throw new IllegalStateException("Keyspace required.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the keyspace.
|
||||
*/
|
||||
public Keyspace getKeyspace() {
|
||||
return keyspace;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param keyspace The keyspace to set.
|
||||
*/
|
||||
public void setKeyspace(Keyspace keyspace) {
|
||||
this.keyspace = keyspace;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.FactoryBean#getObject()
|
||||
*/
|
||||
@Override
|
||||
public Session getObject() {
|
||||
return keyspace.getSession();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
|
||||
*/
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return Session.class;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
|
||||
*/
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,58 +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.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.PreparedStatement;
|
||||
import com.datastax.driver.core.Session;
|
||||
import com.datastax.driver.core.exceptions.DriverException;
|
||||
|
||||
/**
|
||||
* @author David Webb
|
||||
*
|
||||
*/
|
||||
public class SimplePreparedStatementCreator implements PreparedStatementCreator, CqlProvider {
|
||||
|
||||
private final String cql;
|
||||
|
||||
/**
|
||||
* Create a PreparedStatementCreator from the provided CQL.
|
||||
*
|
||||
* @param cql
|
||||
*/
|
||||
public SimplePreparedStatementCreator(String cql) {
|
||||
Assert.notNull(cql, "CQL is required to create a PreparedStatement");
|
||||
this.cql = cql;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.cassandra.core.CqlProvider#getCql()
|
||||
*/
|
||||
@Override
|
||||
public String getCql() {
|
||||
return this.cql;
|
||||
}
|
||||
|
||||
/* (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.cql);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
package org.springframework.cassandra.core.cql;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class CqlStringUtils {
|
||||
|
||||
protected static final String SINGLE_QUOTE = "\'";
|
||||
protected static final String DOUBLE_SINGLE_QUOTE = "\'\'";
|
||||
protected static final String DOUBLE_QUOTE = "\"";
|
||||
protected static final String DOUBLE_DOUBLE_QUOTE = "\"\"";
|
||||
|
||||
public static StringBuilder noNull(StringBuilder sb) {
|
||||
return sb == null ? new StringBuilder() : sb;
|
||||
}
|
||||
|
||||
public static final String UNESCAPED_DOUBLE_QUOTE_REGEX = "TODO";
|
||||
public static final Pattern UNESCAPED_DOUBLE_QUOTE_PATTERN = Pattern.compile(UNESCAPED_DOUBLE_QUOTE_REGEX);
|
||||
|
||||
public static final String UNQUOTED_IDENTIFIER_REGEX = "[a-zA-Z_][a-zA-Z0-9_]*";
|
||||
public static final Pattern UNQUOTED_IDENTIFIER_PATTERN = Pattern.compile(UNQUOTED_IDENTIFIER_REGEX);
|
||||
|
||||
public static boolean isUnquotedIdentifier(CharSequence chars) {
|
||||
return UNQUOTED_IDENTIFIER_PATTERN.matcher(chars).matches();
|
||||
}
|
||||
|
||||
public static void checkUnquotedIdentifier(CharSequence chars) {
|
||||
if (!CqlStringUtils.isUnquotedIdentifier(chars)) {
|
||||
throw new IllegalArgumentException("[" + chars + "] is not a valid CQL identifier");
|
||||
}
|
||||
}
|
||||
|
||||
public static final String QUOTED_IDENTIFIER_REGEX = "[a-zA-Z_]([a-zA-Z0-9_]|\"{2}+)*";
|
||||
public static final Pattern QUOTED_IDENTIFIER_PATTERN = Pattern.compile(QUOTED_IDENTIFIER_REGEX);
|
||||
|
||||
public static boolean isQuotedIdentifier(CharSequence chars) {
|
||||
return QUOTED_IDENTIFIER_PATTERN.matcher(chars).matches();
|
||||
}
|
||||
|
||||
public static void checkQuotedIdentifier(CharSequence chars) {
|
||||
if (!CqlStringUtils.isQuotedIdentifier(chars)) {
|
||||
throw new IllegalArgumentException("[" + chars + "] is not a valid CQL quoted identifier");
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isIdentifier(CharSequence chars) {
|
||||
return isUnquotedIdentifier(chars) || isQuotedIdentifier(chars);
|
||||
}
|
||||
|
||||
public static void checkIdentifier(CharSequence chars) {
|
||||
if (!CqlStringUtils.isIdentifier(chars)) {
|
||||
throw new IllegalArgumentException("[" + chars + "] is not a valid CQL quoted or unquoted identifier");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the given string as a legal Cassandra identifier.
|
||||
* <ul>
|
||||
* <li>If the given identifier is a legal unquoted identifier, it is returned unchanged.</li>
|
||||
* <li>If the given identifier is a legal quoted identifier, it is returned encased in double quotes.</li>
|
||||
* <li>If the given identifier is illegal, an {@link IllegalArgumentException} is thrown.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public static String identifize(String candidate) {
|
||||
|
||||
checkIdentifier(candidate);
|
||||
|
||||
if (isUnquotedIdentifier(candidate)) {
|
||||
return candidate;
|
||||
}
|
||||
// else it must be quoted
|
||||
return doubleQuote(candidate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the given string as a legal Cassandra string column or table option value, by escaping single quotes and
|
||||
* encasing the result in single quotes. Given <code>null</code>, returns <code>null</code>.
|
||||
*/
|
||||
public static String valuize(String candidate) {
|
||||
|
||||
if (candidate == null) {
|
||||
return null;
|
||||
}
|
||||
return singleQuote(escapeSingle(candidate));
|
||||
}
|
||||
|
||||
/**
|
||||
* Doubles single quote characters (' -> ''). Given <code>null</code>, returns <code>null</code>.
|
||||
*/
|
||||
public static String escapeSingle(Object things) {
|
||||
return things == null ? (String) null : things.toString().replace(SINGLE_QUOTE, DOUBLE_SINGLE_QUOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Doubles double quote characters (" -> ""). Given <code>null</code>, returns <code>null</code>.
|
||||
*/
|
||||
public static String escapeDouble(Object things) {
|
||||
return things == null ? (String) null : things.toString().replace(DOUBLE_QUOTE, DOUBLE_DOUBLE_QUOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Surrounds given object's {@link Object#toString()} with single quotes. Given <code>null</code>, returns
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public static String singleQuote(Object thing) {
|
||||
return thing == null ? (String) null : new StringBuilder().append(SINGLE_QUOTE).append(thing).append(SINGLE_QUOTE)
|
||||
.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Surrounds given object's {@link Object#toString()} with double quotes. Given <code>null</code>, returns
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public static String doubleQuote(Object thing) {
|
||||
return thing == null ? (String) null : new StringBuilder().append(DOUBLE_QUOTE).append(thing).append(DOUBLE_QUOTE)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package org.springframework.cassandra.core.cql.generator;
|
||||
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.noNull;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.AddColumnSpecification;
|
||||
|
||||
/**
|
||||
* CQL generator for generating an <code>ADD</code> clause of an <code>ALTER TABLE</code> statement.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class AddColumnCqlGenerator extends ColumnChangeCqlGenerator<AddColumnSpecification> {
|
||||
|
||||
public AddColumnCqlGenerator(AddColumnSpecification specification) {
|
||||
super(specification);
|
||||
}
|
||||
|
||||
public StringBuilder toCql(StringBuilder cql) {
|
||||
return noNull(cql).append("ADD ").append(spec().getNameAsIdentifier()).append(" TYPE ")
|
||||
.append(spec().getType().getName());
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package org.springframework.cassandra.core.cql.generator;
|
||||
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.noNull;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.AlterColumnSpecification;
|
||||
|
||||
/**
|
||||
* CQL generator for generating an <code>ALTER</code> column clause of an <code>ALTER TABLE</code> statement.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class AlterColumnCqlGenerator extends ColumnChangeCqlGenerator<AlterColumnSpecification> {
|
||||
|
||||
public AlterColumnCqlGenerator(AlterColumnSpecification specification) {
|
||||
super(specification);
|
||||
}
|
||||
|
||||
public StringBuilder toCql(StringBuilder cql) {
|
||||
return noNull(cql).append("ALTER ").append(spec().getNameAsIdentifier()).append(" TYPE ")
|
||||
.append(spec().getType().getName());
|
||||
}
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
package org.springframework.cassandra.core.cql.generator;
|
||||
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.noNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.AddColumnSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.AlterColumnSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.AlterTableSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.ColumnChangeSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.DropColumnSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.Option;
|
||||
|
||||
/**
|
||||
* CQL generator for generating <code>ALTER TABLE</code> statements.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class AlterTableCqlGenerator extends TableOptionsCqlGenerator<AlterTableSpecification> {
|
||||
|
||||
public AlterTableCqlGenerator(AlterTableSpecification specification) {
|
||||
super(specification);
|
||||
}
|
||||
|
||||
public StringBuilder toCql(StringBuilder cql) {
|
||||
cql = noNull(cql);
|
||||
|
||||
preambleCql(cql);
|
||||
changesCql(cql);
|
||||
optionsCql(cql);
|
||||
|
||||
cql.append(";");
|
||||
|
||||
return cql;
|
||||
}
|
||||
|
||||
protected StringBuilder preambleCql(StringBuilder cql) {
|
||||
return noNull(cql).append("ALTER TABLE ").append(spec().getNameAsIdentifier()).append(" ");
|
||||
}
|
||||
|
||||
protected StringBuilder changesCql(StringBuilder cql) {
|
||||
cql = noNull(cql);
|
||||
|
||||
boolean first = true;
|
||||
for (ColumnChangeSpecification change : spec().getChanges()) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
cql.append(" ");
|
||||
}
|
||||
getCqlGeneratorFor(change).toCql(cql);
|
||||
}
|
||||
|
||||
return cql;
|
||||
}
|
||||
|
||||
protected ColumnChangeCqlGenerator<?> getCqlGeneratorFor(ColumnChangeSpecification change) {
|
||||
if (change instanceof AddColumnSpecification) {
|
||||
return new AddColumnCqlGenerator((AddColumnSpecification) change);
|
||||
}
|
||||
if (change instanceof DropColumnSpecification) {
|
||||
return new DropColumnCqlGenerator((DropColumnSpecification) change);
|
||||
}
|
||||
if (change instanceof AlterColumnSpecification) {
|
||||
return new AlterColumnCqlGenerator((AlterColumnSpecification) change);
|
||||
}
|
||||
throw new Error("unknown ColumnChangeSpecification type: " + change.getClass().getName());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected StringBuilder optionsCql(StringBuilder cql) {
|
||||
cql = noNull(cql);
|
||||
|
||||
Map<String, Object> options = spec().getOptions();
|
||||
if (options == null || options.isEmpty()) {
|
||||
return cql;
|
||||
}
|
||||
|
||||
cql.append(" WITH ");
|
||||
boolean first = true;
|
||||
for (String key : options.keySet()) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
cql.append(" AND ");
|
||||
}
|
||||
|
||||
cql.append(key);
|
||||
|
||||
Object value = options.get(key);
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
cql.append(" = ");
|
||||
|
||||
if (value instanceof Map) {
|
||||
optionValueMap((Map<Option, Object>) value, cql);
|
||||
continue;
|
||||
}
|
||||
|
||||
// else just use value as string
|
||||
cql.append(value.toString());
|
||||
}
|
||||
return cql;
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package org.springframework.cassandra.core.cql.generator;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.ColumnChangeSpecification;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Base class for column change CQL generators.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
* @param <T> The corresponding {@link ColumnChangeSpecification} type for this CQL generator.
|
||||
*/
|
||||
public abstract class ColumnChangeCqlGenerator<T extends ColumnChangeSpecification> {
|
||||
|
||||
public abstract StringBuilder toCql(StringBuilder cql);
|
||||
|
||||
private ColumnChangeSpecification specification;
|
||||
|
||||
public ColumnChangeCqlGenerator(ColumnChangeSpecification specification) {
|
||||
setSpecification(specification);
|
||||
}
|
||||
|
||||
protected void setSpecification(ColumnChangeSpecification specification) {
|
||||
Assert.notNull(specification);
|
||||
this.specification = specification;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T getSpecification() {
|
||||
return (T) specification;
|
||||
}
|
||||
|
||||
protected T spec() {
|
||||
return getSpecification();
|
||||
}
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
package org.springframework.cassandra.core.cql.generator;
|
||||
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.noNull;
|
||||
import static org.springframework.data.cassandra.mapping.KeyType.PARTITION;
|
||||
import static org.springframework.data.cassandra.mapping.KeyType.PRIMARY;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.ColumnSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.CreateTableSpecification;
|
||||
import org.springframework.cassandra.core.keyspace.Option;
|
||||
|
||||
/**
|
||||
* CQL generator for generating a <code>CREATE TABLE</code> statement.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CreateTableCqlGenerator extends TableCqlGenerator<CreateTableSpecification> {
|
||||
|
||||
public CreateTableCqlGenerator(CreateTableSpecification specification) {
|
||||
super(specification);
|
||||
}
|
||||
|
||||
public StringBuilder toCql(StringBuilder cql) {
|
||||
|
||||
cql = noNull(cql);
|
||||
|
||||
preambleCql(cql);
|
||||
columnsAndOptionsCql(cql);
|
||||
|
||||
cql.append(";");
|
||||
|
||||
return cql;
|
||||
}
|
||||
|
||||
protected StringBuilder preambleCql(StringBuilder cql) {
|
||||
return noNull(cql).append("CREATE TABLE ").append(spec().getIfNotExists() ? "IF NOT EXISTS " : "")
|
||||
.append(spec().getNameAsIdentifier());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected StringBuilder columnsAndOptionsCql(StringBuilder cql) {
|
||||
|
||||
cql = noNull(cql);
|
||||
|
||||
// begin columns
|
||||
cql.append(" (");
|
||||
|
||||
List<ColumnSpecification> partitionKeys = new ArrayList<ColumnSpecification>();
|
||||
List<ColumnSpecification> primaryKeys = new ArrayList<ColumnSpecification>();
|
||||
for (ColumnSpecification col : spec().getColumns()) {
|
||||
col.toCql(cql).append(", ");
|
||||
|
||||
if (col.getKeyType() == PARTITION) {
|
||||
partitionKeys.add(col);
|
||||
} else if (col.getKeyType() == PRIMARY) {
|
||||
primaryKeys.add(col);
|
||||
}
|
||||
}
|
||||
|
||||
// begin primary key clause
|
||||
cql.append("PRIMARY KEY ");
|
||||
StringBuilder partitions = new StringBuilder();
|
||||
StringBuilder primaries = new StringBuilder();
|
||||
|
||||
if (partitionKeys.size() > 1) {
|
||||
partitions.append("(");
|
||||
}
|
||||
|
||||
boolean first = true;
|
||||
for (ColumnSpecification col : partitionKeys) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
partitions.append(", ");
|
||||
}
|
||||
partitions.append(col.getName());
|
||||
|
||||
}
|
||||
if (partitionKeys.size() > 1) {
|
||||
partitions.append(")");
|
||||
}
|
||||
|
||||
StringBuilder clustering = null;
|
||||
boolean clusteringFirst = true;
|
||||
first = true;
|
||||
for (ColumnSpecification col : primaryKeys) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
primaries.append(", ");
|
||||
}
|
||||
primaries.append(col.getName());
|
||||
|
||||
if (col.getOrdering() != null) { // then ordering specified
|
||||
if (clustering == null) { // then initialize clustering clause
|
||||
clustering = new StringBuilder().append("CLUSTERING ORDER BY (");
|
||||
}
|
||||
if (clusteringFirst) {
|
||||
clusteringFirst = false;
|
||||
} else {
|
||||
clustering.append(", ");
|
||||
}
|
||||
clustering.append(col.getName()).append(" ").append(col.getOrdering().cql());
|
||||
}
|
||||
}
|
||||
if (clustering != null) { // then end clustering option
|
||||
clustering.append(")");
|
||||
}
|
||||
|
||||
boolean parenthesize = true;// partitionKeys.size() + primaryKeys.size() > 1;
|
||||
|
||||
cql.append(parenthesize ? "(" : "");
|
||||
cql.append(partitions);
|
||||
cql.append(primaryKeys.size() > 0 ? ", " : "");
|
||||
cql.append(primaries);
|
||||
cql.append(parenthesize ? ")" : "");
|
||||
// end primary key clause
|
||||
|
||||
cql.append(")");
|
||||
// end columns
|
||||
|
||||
// begin options
|
||||
// begin option clause
|
||||
Map<String, Object> options = spec().getOptions();
|
||||
|
||||
if (clustering != null || !options.isEmpty()) {
|
||||
|
||||
// option preamble
|
||||
first = true;
|
||||
cql.append(" WITH ");
|
||||
// end option preamble
|
||||
|
||||
if (clustering != null) {
|
||||
cql.append(clustering);
|
||||
first = false;
|
||||
}
|
||||
if (!options.isEmpty()) {
|
||||
for (String name : options.keySet()) {
|
||||
// append AND if we're not on first option
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
cql.append(" AND ");
|
||||
}
|
||||
|
||||
// append <name> = <value>
|
||||
cql.append(name);
|
||||
|
||||
Object value = options.get(name);
|
||||
if (value == null) { // then assume string-only, valueless option like "COMPACT STORAGE"
|
||||
continue;
|
||||
}
|
||||
|
||||
cql.append(" = ");
|
||||
|
||||
if (value instanceof Map) {
|
||||
optionValueMap((Map<Option, Object>) value, cql);
|
||||
continue; // end non-empty value map
|
||||
}
|
||||
|
||||
// else just use value as string
|
||||
cql.append(value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
// end options
|
||||
|
||||
return cql;
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package org.springframework.cassandra.core.cql.generator;
|
||||
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.noNull;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.DropColumnSpecification;
|
||||
|
||||
/**
|
||||
* CQL generator for generating a <code>DROP</code> column clause of an <code>ALTER TABLE</code> statement.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class DropColumnCqlGenerator extends ColumnChangeCqlGenerator<DropColumnSpecification> {
|
||||
|
||||
public DropColumnCqlGenerator(DropColumnSpecification specification) {
|
||||
super(specification);
|
||||
}
|
||||
|
||||
public StringBuilder toCql(StringBuilder cql) {
|
||||
return noNull(cql).append("DROP ").append(spec().getNameAsIdentifier());
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package org.springframework.cassandra.core.cql.generator;
|
||||
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.noNull;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.DropTableSpecification;
|
||||
|
||||
/**
|
||||
* CQL generator for generating a <code>DROP TABLE</code> statement.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class DropTableCqlGenerator extends TableNameCqlGenerator<DropTableSpecification> {
|
||||
|
||||
public DropTableCqlGenerator(DropTableSpecification specification) {
|
||||
super(specification);
|
||||
}
|
||||
|
||||
public StringBuilder toCql(StringBuilder cql) {
|
||||
return noNull(cql).append("DROP TABLE ").append(spec().getIfExists() ? "IF EXISTS " : "")
|
||||
.append(spec().getNameAsIdentifier()).append(";");
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package org.springframework.cassandra.core.cql.generator;
|
||||
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.escapeSingle;
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.noNull;
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.singleQuote;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.Option;
|
||||
import org.springframework.cassandra.core.keyspace.TableSpecification;
|
||||
|
||||
/**
|
||||
* Base class that contains behavior common to CQL generation for table operations.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
* @param T The subtype of this class for which this is a CQL generator.
|
||||
*/
|
||||
public abstract class TableCqlGenerator<T extends TableSpecification<T>> extends
|
||||
TableOptionsCqlGenerator<TableSpecification<T>> {
|
||||
|
||||
public TableCqlGenerator(TableSpecification<T> specification) {
|
||||
super(specification);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected T spec() {
|
||||
return (T) getSpecification();
|
||||
}
|
||||
|
||||
protected StringBuilder optionValueMap(Map<Option, Object> valueMap, StringBuilder cql) {
|
||||
cql = noNull(cql);
|
||||
|
||||
if (valueMap == null || valueMap.isEmpty()) {
|
||||
return cql;
|
||||
}
|
||||
// else option value is a non-empty map
|
||||
|
||||
// append { 'name' : 'value', ... }
|
||||
cql.append("{ ");
|
||||
boolean mapFirst = true;
|
||||
for (Map.Entry<Option, Object> entry : valueMap.entrySet()) {
|
||||
if (mapFirst) {
|
||||
mapFirst = false;
|
||||
} else {
|
||||
cql.append(", ");
|
||||
}
|
||||
|
||||
Option option = entry.getKey();
|
||||
cql.append(singleQuote(option.getName())); // entries in map keys are always quoted
|
||||
cql.append(" : ");
|
||||
Object entryValue = entry.getValue();
|
||||
entryValue = entryValue == null ? "" : entryValue.toString();
|
||||
if (option.escapesValue()) {
|
||||
entryValue = escapeSingle(entryValue);
|
||||
}
|
||||
if (option.quotesValue()) {
|
||||
entryValue = singleQuote(entryValue);
|
||||
}
|
||||
cql.append(entryValue);
|
||||
}
|
||||
cql.append(" }");
|
||||
|
||||
return cql;
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package org.springframework.cassandra.core.cql.generator;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.TableNameSpecification;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
public abstract class TableNameCqlGenerator<T extends TableNameSpecification<T>> {
|
||||
|
||||
public abstract StringBuilder toCql(StringBuilder cql);
|
||||
|
||||
private TableNameSpecification<T> specification;
|
||||
|
||||
public TableNameCqlGenerator(TableNameSpecification<T> specification) {
|
||||
setSpecification(specification);
|
||||
}
|
||||
|
||||
protected void setSpecification(TableNameSpecification<T> specification) {
|
||||
Assert.notNull(specification);
|
||||
this.specification = specification;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T getSpecification() {
|
||||
return (T) specification;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient synonymous method of {@link #getSpecification()}.
|
||||
*/
|
||||
protected T spec() {
|
||||
return getSpecification();
|
||||
}
|
||||
|
||||
public String toCql() {
|
||||
return toCql(null).toString();
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package org.springframework.cassandra.core.cql.generator;
|
||||
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.escapeSingle;
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.noNull;
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.singleQuote;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cassandra.core.keyspace.Option;
|
||||
import org.springframework.cassandra.core.keyspace.TableOptionsSpecification;
|
||||
|
||||
/**
|
||||
* Base class that contains behavior common to CQL generation for table operations.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
* @param T The subtype of this class for which this is a CQL generator.
|
||||
*/
|
||||
public abstract class TableOptionsCqlGenerator<T extends TableOptionsSpecification<T>> extends
|
||||
TableNameCqlGenerator<TableOptionsSpecification<T>> {
|
||||
|
||||
public TableOptionsCqlGenerator(TableOptionsSpecification<T> specification) {
|
||||
super(specification);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected T spec() {
|
||||
return (T) getSpecification();
|
||||
}
|
||||
|
||||
protected StringBuilder optionValueMap(Map<Option, Object> valueMap, StringBuilder cql) {
|
||||
cql = noNull(cql);
|
||||
|
||||
if (valueMap == null || valueMap.isEmpty()) {
|
||||
return cql;
|
||||
}
|
||||
// else option value is a non-empty map
|
||||
|
||||
// append { 'name' : 'value', ... }
|
||||
cql.append("{ ");
|
||||
boolean mapFirst = true;
|
||||
for (Map.Entry<Option, Object> entry : valueMap.entrySet()) {
|
||||
if (mapFirst) {
|
||||
mapFirst = false;
|
||||
} else {
|
||||
cql.append(", ");
|
||||
}
|
||||
|
||||
Option option = entry.getKey();
|
||||
cql.append(singleQuote(option.getName())); // entries in map keys are always quoted
|
||||
cql.append(" : ");
|
||||
Object entryValue = entry.getValue();
|
||||
entryValue = entryValue == null ? "" : entryValue.toString();
|
||||
if (option.escapesValue()) {
|
||||
entryValue = escapeSingle(entryValue);
|
||||
}
|
||||
if (option.quotesValue()) {
|
||||
entryValue = singleQuote(entryValue);
|
||||
}
|
||||
cql.append(entryValue);
|
||||
}
|
||||
cql.append(" }");
|
||||
|
||||
return cql;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
|
||||
public class AddColumnSpecification extends ColumnTypeChangeSpecification {
|
||||
|
||||
public AddColumnSpecification(String name, DataType type) {
|
||||
super(name, type);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
|
||||
public class AlterColumnSpecification extends ColumnTypeChangeSpecification {
|
||||
|
||||
public AlterColumnSpecification(String name, DataType type) {
|
||||
super(name, type);
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
|
||||
/**
|
||||
* Builder class to construct an <code>ALTER TABLE</code> specification.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class AlterTableSpecification extends TableOptionsSpecification<AlterTableSpecification> {
|
||||
|
||||
/**
|
||||
* The list of column changes.
|
||||
*/
|
||||
private List<ColumnChangeSpecification> changes = new ArrayList<ColumnChangeSpecification>();
|
||||
|
||||
/**
|
||||
* Adds a <code>DROP</code> to the list of column changes.
|
||||
*/
|
||||
public AlterTableSpecification drop(String column) {
|
||||
changes.add(new DropColumnSpecification(column));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an <code>ADD</code> to the list of column changes.
|
||||
*/
|
||||
public AlterTableSpecification add(String column, DataType type) {
|
||||
changes.add(new AddColumnSpecification(column, type));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an <code>ALTER</code> to the list of column changes.
|
||||
*/
|
||||
public AlterTableSpecification alter(String column, DataType type) {
|
||||
changes.add(new AlterColumnSpecification(column, type));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list of column changes.
|
||||
*/
|
||||
public List<ColumnChangeSpecification> getChanges() {
|
||||
return Collections.unmodifiableList(changes);
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.checkIdentifier;
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.identifize;
|
||||
|
||||
public abstract class ColumnChangeSpecification {
|
||||
|
||||
private String name;
|
||||
|
||||
public ColumnChangeSpecification(String name) {
|
||||
setName(name);
|
||||
}
|
||||
|
||||
private void setName(String name) {
|
||||
checkIdentifier(name);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getNameAsIdentifier() {
|
||||
return identifize(name);
|
||||
}
|
||||
}
|
||||
@@ -1,167 +0,0 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.checkIdentifier;
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.identifize;
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.noNull;
|
||||
import static org.springframework.data.cassandra.mapping.KeyType.PARTITION;
|
||||
import static org.springframework.data.cassandra.mapping.KeyType.PRIMARY;
|
||||
import static org.springframework.data.cassandra.mapping.Ordering.ASCENDING;
|
||||
|
||||
import org.springframework.data.cassandra.mapping.KeyType;
|
||||
import org.springframework.data.cassandra.mapping.Ordering;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
|
||||
/**
|
||||
* Builder class to help construct CQL statements that involve column manipulation. Not threadsafe.
|
||||
* <p/>
|
||||
* Use {@link #name(String)} and {@link #type(String)} to set the name and type of the column, respectively. To specify
|
||||
* a <code>PRIMARY KEY</code> column, use {@link #primary()} or {@link #primary(Ordering)}. To specify that the
|
||||
* <code>PRIMARY KEY</code> column is or is part of the partition key, use {@link #partition()} instead of
|
||||
* {@link #primary()} or {@link #primary(Ordering)}.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class ColumnSpecification {
|
||||
|
||||
/**
|
||||
* Default ordering of primary key fields; value is {@link Ordering#ASCENDING}.
|
||||
*/
|
||||
public static final Ordering DFAULT_ORDERING = ASCENDING;
|
||||
|
||||
private String name;
|
||||
private DataType type; // TODO: determining if we should be coupling this to Datastax Java Driver type?
|
||||
private KeyType keyType;
|
||||
private Ordering ordering;
|
||||
|
||||
/**
|
||||
* Sets the column's name.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public ColumnSpecification name(String name) {
|
||||
checkIdentifier(name);
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the column's type.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public ColumnSpecification type(DataType type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Identifies this column as a primary key column that is also part of a partition key. Sets the column's
|
||||
* {@link #keyType} to {@link KeyType#PARTITION} and its {@link #ordering} to <code>null</code>.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public ColumnSpecification partition() {
|
||||
return partition(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the identification of this column as a primary key column that also is or is part of a partition key. Sets
|
||||
* {@link #ordering} to <code>null</code> and, if the given boolean is <code>true</code>, then sets the column's
|
||||
* {@link #keyType} to {@link KeyType#PARTITION}, else sets it to <code>null</code>.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public ColumnSpecification partition(boolean partition) {
|
||||
this.keyType = partition ? PARTITION : null;
|
||||
this.ordering = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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}.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public ColumnSpecification primary() {
|
||||
return primary(DFAULT_ORDERING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Identifies this column as a primary key column with the given ordering. Sets the column's {@link #keyType} to
|
||||
* {@link KeyType#PRIMARY} and its {@link #ordering} to the given {@link Ordering}.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public ColumnSpecification primary(Ordering order) {
|
||||
return primary(order, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the identification of this column as a primary key column. If the given boolean is <code>true</code>, then
|
||||
* sets the column's {@link #keyType} to {@link KeyType#PARTITION} and {@link #ordering} to the given {@link Ordering}
|
||||
* , else sets both {@link #keyType} and {@link #ordering} to <code>null</code>.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public ColumnSpecification primary(Ordering order, boolean primary) {
|
||||
this.keyType = primary ? PRIMARY : null;
|
||||
this.ordering = primary ? order : null;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the column's {@link #keyType}.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
/* package */ColumnSpecification keyType(KeyType keyType) {
|
||||
this.keyType = keyType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the column's {@link #ordering}.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
/* package */ColumnSpecification ordering(Ordering ordering) {
|
||||
this.ordering = ordering;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getNameAsIdentifier() {
|
||||
return identifize(name);
|
||||
}
|
||||
|
||||
public DataType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public KeyType getKeyType() {
|
||||
return keyType;
|
||||
}
|
||||
|
||||
public Ordering getOrdering() {
|
||||
return ordering;
|
||||
}
|
||||
|
||||
public String toCql() {
|
||||
return toCql(null).toString();
|
||||
}
|
||||
|
||||
public StringBuilder toCql(StringBuilder cql) {
|
||||
return (cql = noNull(cql)).append(name).append(" ").append(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toCql(null).append(" /* keyType=").append(keyType).append(", ordering=").append(ordering).append(" */ ")
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
|
||||
public abstract class ColumnTypeChangeSpecification extends ColumnChangeSpecification {
|
||||
|
||||
private DataType type;
|
||||
|
||||
public ColumnTypeChangeSpecification(String name, DataType type) {
|
||||
super(name);
|
||||
setType(type);
|
||||
}
|
||||
|
||||
private void setType(DataType type) {
|
||||
Assert.notNull(type);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public DataType getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
/**
|
||||
* Builder class to construct a <code>CREATE TABLE</code> specification.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CreateTableSpecification extends TableSpecification<CreateTableSpecification> {
|
||||
|
||||
private boolean ifNotExists = false;
|
||||
|
||||
/**
|
||||
* Causes the inclusion of an <code>IF NOT EXISTS</code> clause.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public CreateTableSpecification ifNotExists() {
|
||||
return ifNotExists(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the inclusion of an <code>IF NOT EXISTS</code> clause.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public CreateTableSpecification ifNotExists(boolean ifNotExists) {
|
||||
this.ifNotExists = ifNotExists;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean getIfNotExists() {
|
||||
return ifNotExists;
|
||||
}
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.escapeSingle;
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.singleQuote;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A default implementation of {@link Option}.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class DefaultOption implements Option {
|
||||
|
||||
private String name;
|
||||
private Class<?> type;
|
||||
private boolean requiresValue;
|
||||
private boolean escapesValue;
|
||||
private boolean quotesValue;
|
||||
|
||||
public DefaultOption(String name, Class<?> type, boolean requiresValue, boolean escapesValue, boolean quotesValue) {
|
||||
setName(name);
|
||||
setType(type);
|
||||
this.requiresValue = requiresValue;
|
||||
this.escapesValue = escapesValue;
|
||||
this.quotesValue = quotesValue;
|
||||
|
||||
}
|
||||
|
||||
protected void setName(String name) {
|
||||
Assert.hasLength(name);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
protected void setType(Class<?> type) {
|
||||
if (type != null) {
|
||||
if (type.isInterface() && !(Map.class.isAssignableFrom(type) || Collection.class.isAssignableFrom(type))) {
|
||||
throw new IllegalArgumentException("given type [" + type.getName() + "] must be a class, Map or Collection");
|
||||
}
|
||||
}
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public boolean isCoerceable(Object value) {
|
||||
if (value == null || type == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// check map
|
||||
if (Map.class.isAssignableFrom(type)) {
|
||||
return Map.class.isAssignableFrom(value.getClass());
|
||||
}
|
||||
// check collection
|
||||
if (Collection.class.isAssignableFrom(type)) {
|
||||
return Collection.class.isAssignableFrom(value.getClass());
|
||||
}
|
||||
// check enum
|
||||
if (type.isEnum()) {
|
||||
try {
|
||||
String name = value instanceof Enum ? name = ((Enum) value).name() : value.toString();
|
||||
Enum.valueOf((Class<? extends Enum>) type, name);
|
||||
return true;
|
||||
} catch (NullPointerException x) {
|
||||
return false;
|
||||
} catch (IllegalArgumentException x) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// check class via String constructor
|
||||
try {
|
||||
Constructor<?> ctor = type.getConstructor(String.class);
|
||||
if (!ctor.isAccessible()) {
|
||||
ctor.setAccessible(true);
|
||||
}
|
||||
ctor.newInstance(value.toString());
|
||||
return true;
|
||||
} catch (InstantiationException e) {
|
||||
} catch (IllegalAccessException e) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
} catch (InvocationTargetException e) {
|
||||
} catch (NoSuchMethodException e) {
|
||||
} catch (SecurityException e) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean takesValue() {
|
||||
return type != null;
|
||||
}
|
||||
|
||||
public boolean requiresValue() {
|
||||
return this.requiresValue;
|
||||
}
|
||||
|
||||
public boolean escapesValue() {
|
||||
return this.escapesValue;
|
||||
}
|
||||
|
||||
public boolean quotesValue() {
|
||||
return this.quotesValue;
|
||||
}
|
||||
|
||||
public void checkValue(Object value) {
|
||||
if (takesValue()) {
|
||||
if (value == null) {
|
||||
if (requiresValue) {
|
||||
throw new IllegalArgumentException("Option [" + getName() + "] requires a value");
|
||||
}
|
||||
return; // doesn't require a value, so null is ok
|
||||
}
|
||||
// else value is not null
|
||||
if (isCoerceable(value)) {
|
||||
return;
|
||||
}
|
||||
// else value is not coerceable into the expected type
|
||||
throw new IllegalArgumentException("Option [" + getName() + "] takes value coerceable to type ["
|
||||
+ getType().getName() + "]");
|
||||
}
|
||||
// else this option doesn't take a value
|
||||
if (value != null) {
|
||||
throw new IllegalArgumentException("Option [" + getName() + "] takes no value");
|
||||
}
|
||||
}
|
||||
|
||||
public String toString(Object value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
checkValue(value);
|
||||
|
||||
String string = value.toString();
|
||||
string = escapesValue ? escapeSingle(string) : string;
|
||||
string = quotesValue ? singleQuote(string) : string;
|
||||
return string;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[name=" + name + ", type=" + type.getName() + ", requiresValue=" + requiresValue + ", escapesValue="
|
||||
+ escapesValue + ", quotesValue=" + quotesValue + "]";
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
/**
|
||||
* Convenient default implementation of {@link TableDescriptor} as an extension of {@link TableSpecification} that
|
||||
* doesn't require the use of generics.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class DefaultTableDescriptor extends TableSpecification<DefaultTableDescriptor> {
|
||||
|
||||
/**
|
||||
* Factory method to produce a new {@link DefaultTableDescriptor}. Convenient if imported statically.
|
||||
*/
|
||||
public static DefaultTableDescriptor table() {
|
||||
return new DefaultTableDescriptor();
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
public class DropColumnSpecification extends ColumnChangeSpecification {
|
||||
|
||||
public DropColumnSpecification(String name) {
|
||||
super(name);
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
/**
|
||||
* Builder class that supports the construction of <code>DROP TABLE</code> specifications.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class DropTableSpecification extends TableNameSpecification<DropTableSpecification> {
|
||||
|
||||
private boolean ifExists;
|
||||
|
||||
public DropTableSpecification ifExists() {
|
||||
return ifExists(true);
|
||||
}
|
||||
|
||||
public DropTableSpecification ifExists(boolean ifExists) {
|
||||
this.ifExists = ifExists;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean getIfExists() {
|
||||
return ifExists;
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
/**
|
||||
* Interface to represent option types.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public interface Option {
|
||||
|
||||
/**
|
||||
* The type that values must be able to be coerced into for this option.
|
||||
*/
|
||||
Class<?> getType();
|
||||
|
||||
/**
|
||||
* The (usually lower-cased, underscore-separated) name of this table option.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Whether this option takes a value.
|
||||
*/
|
||||
boolean takesValue();
|
||||
|
||||
/**
|
||||
* Whether this option should escape single quotes in its value.
|
||||
*/
|
||||
boolean escapesValue();
|
||||
|
||||
/**
|
||||
* Whether this option's value should be single-quoted.
|
||||
*/
|
||||
boolean quotesValue();
|
||||
|
||||
/**
|
||||
* Whether this option requires a value.
|
||||
*/
|
||||
boolean requiresValue();
|
||||
|
||||
/**
|
||||
* Checks that the given value can be coerced into the type given by {@link #getType()}.
|
||||
*/
|
||||
void checkValue(Object value);
|
||||
|
||||
/**
|
||||
* Tests whether the given value can be coerced into the type given by {@link #getType()}.
|
||||
*/
|
||||
boolean isCoerceable(Object value);
|
||||
|
||||
/**
|
||||
* First ensures that the given value is coerceable into the type expected by this option, then returns the result of
|
||||
* {@link Object#toString()} called on the given value. If this option is escaping quotes ({@link #escapesValue()} is
|
||||
* <code>true</code>), then single quotes will be escaped, and if this option is quoting values (
|
||||
* {@link #quotesValue()} is <code>true</code>), then the value will be surrounded by single quotes. Given
|
||||
* <code>null</code>, returns <code>null</code>.
|
||||
*
|
||||
* @see #escapesValue()
|
||||
* @see #quotesValue()
|
||||
*/
|
||||
String toString(Object value);
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Describes a table.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public interface TableDescriptor {
|
||||
|
||||
/**
|
||||
* Returns the name of the table.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Returns the name of the table as an identifer or quoted identifier as appropriate.
|
||||
*/
|
||||
String getNameAsIdentifier();
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable {@link List} of {@link ColumnSpecification}s.
|
||||
*/
|
||||
List<ColumnSpecification> getColumns();
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list of all partition key columns.
|
||||
*/
|
||||
public List<ColumnSpecification> getPartitionKeyColumns();
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list of all primary key columns that are not also partition key columns.
|
||||
*/
|
||||
public List<ColumnSpecification> getPrimaryKeyColumns();
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list of all partition and primary key columns.
|
||||
*/
|
||||
public List<ColumnSpecification> getKeyColumns();
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list of all non-key columns.
|
||||
*/
|
||||
public List<ColumnSpecification> getNonKeyColumns();
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable {@link Map} of table options.
|
||||
*/
|
||||
Map<String, Object> getOptions();
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.checkIdentifier;
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.identifize;
|
||||
|
||||
/**
|
||||
* Abstract builder class to support the construction of table specifications.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
* @param <T> The subtype of the {@link TableNameSpecification}
|
||||
*/
|
||||
public abstract class TableNameSpecification<T extends TableNameSpecification<T>> {
|
||||
|
||||
/**
|
||||
* The name of the table.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Sets the table name.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public T name(String name) {
|
||||
checkIdentifier(name);
|
||||
this.name = name;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getNameAsIdentifier() {
|
||||
return identifize(name);
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
/**
|
||||
* Class that offers static methods as entry points into the fluent API for building create, drop and alter table
|
||||
* specifications. These methods are most convenient when imported statically.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class TableOperations {
|
||||
|
||||
/**
|
||||
* Entry point into the {@link CreateTableSpecification}'s fluent API to create a table. Convenient if imported
|
||||
* statically.
|
||||
*/
|
||||
public static CreateTableSpecification createTable() {
|
||||
return new CreateTableSpecification();
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry point into the {@link DropTableSpecification}'s fluent API to drop a table. Convenient if imported
|
||||
* statically.
|
||||
*/
|
||||
public static DropTableSpecification dropTable() {
|
||||
return new DropTableSpecification();
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry point into the {@link AlterTableSpecification}'s fluent API to alter a table. Convenient if imported
|
||||
* statically.
|
||||
*/
|
||||
public static AlterTableSpecification alterTable() {
|
||||
return new AlterTableSpecification();
|
||||
}
|
||||
}
|
||||
@@ -1,287 +0,0 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Enumeration that represents all known table options. If a table option is not listed here, but is supported by
|
||||
* Cassandra, use the method {@link CreateTableSpecification#with(String, Object, boolean, boolean)} to write the raw
|
||||
* value.
|
||||
*
|
||||
* Implements {@link Option} via delegation, since {@link Enum}s can't extend anything.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
* @see CompactionOption
|
||||
* @see CompressionOption
|
||||
* @see CachingOption
|
||||
*/
|
||||
public enum TableOption implements Option {
|
||||
/**
|
||||
* <code>comment</code>
|
||||
*/
|
||||
COMMENT("comment", String.class, true, true, true),
|
||||
/**
|
||||
* <code>COMPACT STORAGE</code>
|
||||
*/
|
||||
COMPACT_STORAGE("COMPACT STORAGE", null, false, false, false),
|
||||
/**
|
||||
* <code>compaction</code>. Value is a <code>Map<CompactionOption,Object></code>.
|
||||
*
|
||||
* @see CompactionOption
|
||||
*/
|
||||
COMPACTION("compaction", Map.class, true, false, false),
|
||||
/**
|
||||
* <code>compression</code>. Value is a <code>Map<CompressionOption,Object></code>.
|
||||
*
|
||||
* @see {@link CompressionOption}
|
||||
*/
|
||||
COMPRESSION("compression", Map.class, true, false, false),
|
||||
/**
|
||||
* <code>replicate_on_write</code>
|
||||
*/
|
||||
REPLICATE_ON_WRITE("replicate_on_write", Boolean.class, true, false, false),
|
||||
/**
|
||||
* <code>caching</code>
|
||||
*
|
||||
* @see CachingOption
|
||||
*/
|
||||
CACHING("caching", CachingOption.class, true, false, false),
|
||||
/**
|
||||
* <code>bloom_filter_fp_chance</code>
|
||||
*/
|
||||
BLOOM_FILTER_FP_CHANCE("bloom_filter_fp_chance", Double.class, true, false, false),
|
||||
/**
|
||||
* <code>read_repair_chance</code>
|
||||
*/
|
||||
READ_REPAIR_CHANCE("read_repair_chance", Double.class, true, false, false),
|
||||
/**
|
||||
* <code>dclocal_read_repair_chance</code>
|
||||
*/
|
||||
DCLOCAL_READ_REPAIR_CHANCE("dclocal_read_repair_chance", Double.class, true, false, false),
|
||||
/**
|
||||
* <code>gc_grace_seconds</code>
|
||||
*/
|
||||
GC_GRACE_SECONDS("gc_grace_seconds", Long.class, true, false, false);
|
||||
|
||||
private Option delegate;
|
||||
|
||||
private TableOption(String name, Class<?> type, boolean requiresValue, boolean escapesValue, boolean quotesValue) {
|
||||
this.delegate = new DefaultOption(name, type, requiresValue, escapesValue, quotesValue);
|
||||
}
|
||||
|
||||
public Class<?> getType() {
|
||||
return delegate.getType();
|
||||
}
|
||||
|
||||
public boolean takesValue() {
|
||||
return delegate.takesValue();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return delegate.getName();
|
||||
}
|
||||
|
||||
public boolean escapesValue() {
|
||||
return delegate.escapesValue();
|
||||
}
|
||||
|
||||
public boolean quotesValue() {
|
||||
return delegate.quotesValue();
|
||||
}
|
||||
|
||||
public boolean requiresValue() {
|
||||
return delegate.requiresValue();
|
||||
}
|
||||
|
||||
public void checkValue(Object value) {
|
||||
delegate.checkValue(value);
|
||||
}
|
||||
|
||||
public boolean isCoerceable(Object value) {
|
||||
return delegate.isCoerceable(value);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return delegate.toString();
|
||||
}
|
||||
|
||||
public String toString(Object value) {
|
||||
return delegate.toString(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Known caching options.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public enum CachingOption {
|
||||
ALL("all"), KEYS_ONLY("keys_only"), ROWS_ONLY("rows_only"), NONE("none");
|
||||
|
||||
private String value;
|
||||
|
||||
private CachingOption(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getValue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Known compaction options.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public enum CompactionOption implements Option {
|
||||
/**
|
||||
* <code>tombstone_threshold</code>
|
||||
*/
|
||||
TOMBSTONE_THRESHOLD("tombstone_threshold", Double.class, true, false, false),
|
||||
/**
|
||||
* <code>tombstone_compaction_interval</code>
|
||||
*/
|
||||
TOMBSTONE_COMPACTION_INTERVAL("tombstone_compaction_interval", Double.class, true, false, false),
|
||||
/**
|
||||
* <code>min_sstable_size</code>
|
||||
*/
|
||||
MIN_SSTABLE_SIZE("min_sstable_size", Long.class, true, false, false),
|
||||
/**
|
||||
* <code>min_threshold</code>
|
||||
*/
|
||||
MIN_THRESHOLD("min_threshold", Long.class, true, false, false),
|
||||
/**
|
||||
* <code>max_threshold</code>
|
||||
*/
|
||||
MAX_THRESHOLD("max_threshold", Long.class, true, false, false),
|
||||
/**
|
||||
* <code>bucket_low</code>
|
||||
*/
|
||||
BUCKET_LOW("bucket_low", Double.class, true, false, false),
|
||||
/**
|
||||
* <code>bucket_high</code>
|
||||
*/
|
||||
BUCKET_HIGH("bucket_high", Double.class, true, false, false),
|
||||
/**
|
||||
* <code>sstable_size_in_mb</code>
|
||||
*/
|
||||
SSTABLE_SIZE_IN_MB("sstable_size_in_mb", Long.class, true, false, false);
|
||||
|
||||
private Option delegate;
|
||||
|
||||
private CompactionOption(String name, Class<?> type, boolean requiresValue, boolean escapesValue,
|
||||
boolean quotesValue) {
|
||||
this.delegate = new DefaultOption(name, type, requiresValue, escapesValue, quotesValue);
|
||||
}
|
||||
|
||||
public Class<?> getType() {
|
||||
return delegate.getType();
|
||||
}
|
||||
|
||||
public boolean takesValue() {
|
||||
return delegate.takesValue();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return delegate.getName();
|
||||
}
|
||||
|
||||
public boolean escapesValue() {
|
||||
return delegate.escapesValue();
|
||||
}
|
||||
|
||||
public boolean quotesValue() {
|
||||
return delegate.quotesValue();
|
||||
}
|
||||
|
||||
public boolean requiresValue() {
|
||||
return delegate.requiresValue();
|
||||
}
|
||||
|
||||
public void checkValue(Object value) {
|
||||
delegate.checkValue(value);
|
||||
}
|
||||
|
||||
public boolean isCoerceable(Object value) {
|
||||
return delegate.isCoerceable(value);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return delegate.toString();
|
||||
}
|
||||
|
||||
public String toString(Object value) {
|
||||
return delegate.toString(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Known compression options.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public enum CompressionOption implements Option {
|
||||
/**
|
||||
* <code>sstable_compression</code>
|
||||
*/
|
||||
STABLE_COMPRESSION("sstable_compression", String.class, true, false, false),
|
||||
/**
|
||||
* <code>chunk_length_kb</code>
|
||||
*/
|
||||
CHUNK_LENGTH_KB("chunk_length_kb", Long.class, true, false, false),
|
||||
/**
|
||||
* <code>crc_check_chance</code>
|
||||
*/
|
||||
CRC_CHECK_CHANCE("crc_check_chance", Double.class, true, false, false);
|
||||
|
||||
private Option delegate;
|
||||
|
||||
private CompressionOption(String name, Class<?> type, boolean requiresValue, boolean escapesValue,
|
||||
boolean quotesValue) {
|
||||
this.delegate = new DefaultOption(name, type, requiresValue, escapesValue, quotesValue);
|
||||
}
|
||||
|
||||
public Class<?> getType() {
|
||||
return delegate.getType();
|
||||
}
|
||||
|
||||
public boolean takesValue() {
|
||||
return delegate.takesValue();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return delegate.getName();
|
||||
}
|
||||
|
||||
public boolean escapesValue() {
|
||||
return delegate.escapesValue();
|
||||
}
|
||||
|
||||
public boolean quotesValue() {
|
||||
return delegate.quotesValue();
|
||||
}
|
||||
|
||||
public boolean requiresValue() {
|
||||
return delegate.requiresValue();
|
||||
}
|
||||
|
||||
public void checkValue(Object value) {
|
||||
delegate.checkValue(value);
|
||||
}
|
||||
|
||||
public boolean isCoerceable(Object value) {
|
||||
return delegate.isCoerceable(value);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return delegate.toString();
|
||||
}
|
||||
|
||||
public String toString(Object value) {
|
||||
return delegate.toString(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.escapeSingle;
|
||||
import static org.springframework.cassandra.core.cql.CqlStringUtils.singleQuote;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cassandra.core.cql.CqlStringUtils;
|
||||
|
||||
/**
|
||||
* Abstract builder class to support the construction of table specifications that have table options, that is, those
|
||||
* options normally specified by <code>WITH ... AND ...</code>.
|
||||
* <p/>
|
||||
* It is important to note that although this class depends on {@link TableOption} for convenient and typesafe use, it
|
||||
* ultimately stores its options in a <code>Map<String,Object></code> for flexibility. This means that
|
||||
* {@link #with(TableOption)} and {@link #with(TableOption, Object)} delegate to
|
||||
* {@link #with(String, Object, boolean, boolean)}. This design allows the API to support new Cassandra options as they
|
||||
* are introduced without having to update the code immediately.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
* @param <T> The subtype of the {@link TableOptionsSpecification}.
|
||||
*/
|
||||
public abstract class TableOptionsSpecification<T extends TableOptionsSpecification<T>> extends
|
||||
TableNameSpecification<TableOptionsSpecification<T>> {
|
||||
|
||||
protected Map<String, Object> options = new LinkedHashMap<String, Object>();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T name(String name) {
|
||||
return (T) super.name(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that calls <code>with(option, null)</code>.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public T with(TableOption option) {
|
||||
return with(option, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given table option. This is a convenience method that calls
|
||||
* {@link #with(String, Object, boolean, boolean)} appropriately from the given {@link TableOption} and value for that
|
||||
* option.
|
||||
*
|
||||
* @param option The option to set.
|
||||
* @param value The value of the option. Must be type-compatible with the {@link TableOption}.
|
||||
* @return this
|
||||
* @see #with(String, Object, boolean, boolean)
|
||||
*/
|
||||
public T with(TableOption option, Object value) {
|
||||
option.checkValue(value);
|
||||
return (T) with(option.getName(), value, option.escapesValue(), option.quotesValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given option by name to this table's options.
|
||||
* <p/>
|
||||
* Options that have <code>null</code> values are considered single string options where the name of the option is the
|
||||
* string to be used. Otherwise, the result of {@link Object#toString()} is considered to be the value of the option
|
||||
* with the given name. The value, after conversion to string, may have embedded single quotes escaped according to
|
||||
* parameter <code>escape</code> and may be single-quoted according to parameter <code>quote</code>.
|
||||
*
|
||||
* @param name The name of the option
|
||||
* @param value The value of the option. If <code>null</code>, the value is ignored and the option is considered to be
|
||||
* composed of only the name, otherwise the value's {@link Object#toString()} value is used.
|
||||
* @param escape Whether to escape the value via {@link CqlStringUtils#escapeSingle(Object)}. Ignored if given value
|
||||
* is an instance of a {@link Map}.
|
||||
* @param quote Whether to quote the value via {@link CqlStringUtils#singleQuote(Object)}. Ignored if given value is
|
||||
* an instance of a {@link Map}.
|
||||
* @return this
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public T with(String name, Object value, boolean escape, boolean quote) {
|
||||
if (!(value instanceof Map)) {
|
||||
if (escape) {
|
||||
value = escapeSingle(value);
|
||||
}
|
||||
if (quote) {
|
||||
value = singleQuote(value);
|
||||
}
|
||||
}
|
||||
options.put(name, value);
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public Map<String, Object> getOptions() {
|
||||
return Collections.unmodifiableMap(options);
|
||||
}
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
package org.springframework.cassandra.core.keyspace;
|
||||
|
||||
import static org.springframework.data.cassandra.mapping.KeyType.PARTITION;
|
||||
import static org.springframework.data.cassandra.mapping.KeyType.PRIMARY;
|
||||
import static org.springframework.data.cassandra.mapping.Ordering.ASCENDING;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.cassandra.mapping.KeyType;
|
||||
import org.springframework.data.cassandra.mapping.Ordering;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
|
||||
/**
|
||||
* Builder class to support the construction of table specifications that have columns. This class can also be used as a
|
||||
* standalone {@link TableDescriptor}, independent of {@link CreateTableSpecification}.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class TableSpecification<T> extends TableOptionsSpecification<TableSpecification<T>> implements TableDescriptor {
|
||||
|
||||
/**
|
||||
* List of all columns.
|
||||
*/
|
||||
private List<ColumnSpecification> columns = new ArrayList<ColumnSpecification>();
|
||||
|
||||
/**
|
||||
* List of only those columns that comprise the partition key.
|
||||
*/
|
||||
private List<ColumnSpecification> partitionKeyColumns = new ArrayList<ColumnSpecification>();
|
||||
|
||||
/**
|
||||
* List of only those columns that comprise the primary key that are not also part of the partition key.
|
||||
*/
|
||||
private List<ColumnSpecification> primaryKeyColumns = new ArrayList<ColumnSpecification>();
|
||||
|
||||
/**
|
||||
* List of only those columns that are not partition or primary key columns.
|
||||
*/
|
||||
private List<ColumnSpecification> nonKeyColumns = new ArrayList<ColumnSpecification>();
|
||||
|
||||
/**
|
||||
* Adds the given non-key column to the table. Must be specified after all primary key columns.
|
||||
*
|
||||
* @param name The column name; must be a valid unquoted or quoted identifier without the surrounding double quotes.
|
||||
* @param type The data type of the column.
|
||||
*/
|
||||
public T column(String name, DataType type) {
|
||||
return column(name, type, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given partition key column to the table. Must be specified before any other columns.
|
||||
*
|
||||
* @param name The column name; must be a valid unquoted or quoted identifier without the surrounding double quotes.
|
||||
* @param type The data type of the column.
|
||||
* @return this
|
||||
*/
|
||||
public T partitionKeyColumn(String name, DataType type) {
|
||||
return column(name, type, PARTITION, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given primary key column to the table with ascending ordering. Must be specified after all partition key
|
||||
* columns and before any non-key columns.
|
||||
*
|
||||
* @param name The column name; must be a valid unquoted or quoted identifier without the surrounding double quotes.
|
||||
* @param type The data type of the column.
|
||||
* @return this
|
||||
*/
|
||||
public T primaryKeyColumn(String name, DataType type) {
|
||||
return primaryKeyColumn(name, type, ASCENDING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given primary key column to the table with the given ordering (<code>null</code> meaning ascending). Must
|
||||
* be specified after all partition key columns and before any non-key columns.
|
||||
*
|
||||
* @param name The column name; must be a valid unquoted or quoted identifier without the surrounding double quotes.
|
||||
* @param type The data type of the column.
|
||||
* @return this
|
||||
*/
|
||||
public T primaryKeyColumn(String name, DataType type, Ordering ordering) {
|
||||
return column(name, type, PRIMARY, ordering);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given info as a new column to the table. Partition key columns must precede primary key columns, which
|
||||
* must precede non-key columns.
|
||||
*
|
||||
* @param name The column name; must be a valid unquoted or quoted identifier without the surrounding double quotes.
|
||||
* @param type The data type of the column.
|
||||
* @param keyType Indicates key type. Null means that the column is not a key column.
|
||||
* @param ordering If the given {@link KeyType} is {@link KeyType#PRIMARY}, then the given ordering is used, else
|
||||
* ignored.
|
||||
* @return this
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected T column(String name, DataType type, KeyType keyType, Ordering ordering) {
|
||||
|
||||
ColumnSpecification column = new ColumnSpecification().name(name).type(type).keyType(keyType)
|
||||
.ordering(keyType == PRIMARY ? ordering : null);
|
||||
|
||||
columns.add(column);
|
||||
|
||||
if (keyType == KeyType.PARTITION) {
|
||||
partitionKeyColumns.add(column);
|
||||
}
|
||||
|
||||
if (keyType == KeyType.PRIMARY) {
|
||||
primaryKeyColumns.add(column);
|
||||
}
|
||||
|
||||
if (keyType == null) {
|
||||
nonKeyColumns.add(column);
|
||||
}
|
||||
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list of all columns.
|
||||
*/
|
||||
public List<ColumnSpecification> getColumns() {
|
||||
return Collections.unmodifiableList(columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list of all partition key columns.
|
||||
*/
|
||||
public List<ColumnSpecification> getPartitionKeyColumns() {
|
||||
return Collections.unmodifiableList(partitionKeyColumns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list of all primary key columns that are not also partition key columns.
|
||||
*/
|
||||
public List<ColumnSpecification> getPrimaryKeyColumns() {
|
||||
return Collections.unmodifiableList(primaryKeyColumns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list of all primary key columns that are not also partition key columns.
|
||||
*/
|
||||
public List<ColumnSpecification> getKeyColumns() {
|
||||
|
||||
ArrayList<ColumnSpecification> keyColumns = new ArrayList<ColumnSpecification>();
|
||||
keyColumns.addAll(partitionKeyColumns);
|
||||
keyColumns.addAll(primaryKeyColumns);
|
||||
|
||||
return Collections.unmodifiableList(keyColumns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list of all non-key columns.
|
||||
*/
|
||||
public List<ColumnSpecification> getNonKeyColumns() {
|
||||
return Collections.unmodifiableList(nonKeyColumns);
|
||||
}
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
package org.springframework.cassandra.core.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Builder for maps, which also conveniently implements {@link Map} via delegation for convenience so you don't have to
|
||||
* actually {@link #build()} it (or forget to).
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
* @param <K> The key type of the map.
|
||||
* @param <V> The value type of the map.
|
||||
*/
|
||||
public class MapBuilder<K, V> implements Map<K, V> {
|
||||
|
||||
/**
|
||||
* Factory method to construct a new <code>MapBuilder<Object,Object></code>. Convenient if imported statically.
|
||||
*/
|
||||
public static MapBuilder<Object, Object> map() {
|
||||
return map(Object.class, Object.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to construct a new builder with the given key & value types. Convenient if imported statically.
|
||||
*/
|
||||
public static <K, V> MapBuilder<K, V> map(Class<K> keyType, Class<V> valueType) {
|
||||
return new MapBuilder<K, V>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to construct a new builder with a shallow copy of the given map. Convenient if imported statically.
|
||||
*/
|
||||
public static <K, V> MapBuilder<K, V> map(Map<K, V> source) {
|
||||
return new MapBuilder<K, V>(source);
|
||||
}
|
||||
|
||||
private Map<K, V> map;
|
||||
|
||||
public MapBuilder() {
|
||||
this(new LinkedHashMap<K, V>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance with a copy of the given map.
|
||||
*/
|
||||
public MapBuilder(Map<K, V> source) {
|
||||
this.map = new LinkedHashMap<K, V>(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an entry to this map, then returns <code>this</code>.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public MapBuilder<K, V> entry(K key, V value) {
|
||||
map.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new map based on the current state of this builder's map.
|
||||
*
|
||||
* @return A new Map<K, V> with this builder's map's current content.
|
||||
*/
|
||||
public Map<K, V> build() {
|
||||
return new LinkedHashMap<K, V>(map);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return map.isEmpty();
|
||||
}
|
||||
|
||||
public boolean containsKey(Object key) {
|
||||
return map.containsKey(key);
|
||||
}
|
||||
|
||||
public boolean containsValue(Object value) {
|
||||
return map.containsValue(value);
|
||||
}
|
||||
|
||||
public V get(Object key) {
|
||||
return map.get(key);
|
||||
}
|
||||
|
||||
public V put(K key, V value) {
|
||||
return map.put(key, value);
|
||||
}
|
||||
|
||||
public V remove(Object key) {
|
||||
return map.remove(key);
|
||||
}
|
||||
|
||||
public void putAll(Map<? extends K, ? extends V> m) {
|
||||
map.putAll(m);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
map.clear();
|
||||
}
|
||||
|
||||
public Set<K> keySet() {
|
||||
return map.keySet();
|
||||
}
|
||||
|
||||
public Collection<V> values() {
|
||||
return map.values();
|
||||
}
|
||||
|
||||
public Set<java.util.Map.Entry<K, V>> entrySet() {
|
||||
return map.entrySet();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return map.equals(o);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return map.hashCode();
|
||||
}
|
||||
}
|
||||
@@ -1,76 +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.support;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import com.datastax.driver.core.Session;
|
||||
|
||||
/**
|
||||
* @author David Webb
|
||||
*
|
||||
*/
|
||||
public class CassandraAccessor implements InitializingBean {
|
||||
|
||||
/** Logger available to subclasses */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private Session session;
|
||||
|
||||
private CassandraExceptionTranslator exceptionTranslator;
|
||||
|
||||
/**
|
||||
* Set the exception translator for this instance.
|
||||
*
|
||||
* @see org.springframework.cassandra.support.CassandraExceptionTranslator
|
||||
*/
|
||||
public void setExceptionTranslator(CassandraExceptionTranslator exceptionTranslator) {
|
||||
this.exceptionTranslator = exceptionTranslator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the exception translator for this instance.
|
||||
*/
|
||||
public CassandraExceptionTranslator getExceptionTranslator() {
|
||||
return this.exceptionTranslator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that the Cassandra Session has been set
|
||||
*/
|
||||
public void afterPropertiesSet() {
|
||||
if (getSession() == null) {
|
||||
throw new IllegalArgumentException("Property 'session' is required");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the session.
|
||||
*/
|
||||
public Session getSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param session The session to set.
|
||||
*/
|
||||
public void setSession(Session session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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.support;
|
||||
|
||||
import org.springframework.cassandra.support.exception.CassandraAuthenticationException;
|
||||
import org.springframework.cassandra.support.exception.CassandraConnectionFailureException;
|
||||
import org.springframework.cassandra.support.exception.CassandraInsufficientReplicasAvailableException;
|
||||
import org.springframework.cassandra.support.exception.CassandraInternalException;
|
||||
import org.springframework.cassandra.support.exception.CassandraInvalidConfigurationInQueryException;
|
||||
import org.springframework.cassandra.support.exception.CassandraInvalidQueryException;
|
||||
import org.springframework.cassandra.support.exception.CassandraKeyspaceExistsException;
|
||||
import org.springframework.cassandra.support.exception.CassandraQuerySyntaxException;
|
||||
import org.springframework.cassandra.support.exception.CassandraReadTimeoutException;
|
||||
import org.springframework.cassandra.support.exception.CassandraTableExistsException;
|
||||
import org.springframework.cassandra.support.exception.CassandraTraceRetrievalException;
|
||||
import org.springframework.cassandra.support.exception.CassandraTruncateException;
|
||||
import org.springframework.cassandra.support.exception.CassandraTypeMismatchException;
|
||||
import org.springframework.cassandra.support.exception.CassandraUnauthorizedException;
|
||||
import org.springframework.cassandra.support.exception.CassandraUncategorizedException;
|
||||
import org.springframework.cassandra.support.exception.CassandraWriteTimeoutException;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
|
||||
import com.datastax.driver.core.WriteType;
|
||||
import com.datastax.driver.core.exceptions.AlreadyExistsException;
|
||||
import com.datastax.driver.core.exceptions.AuthenticationException;
|
||||
import com.datastax.driver.core.exceptions.DriverException;
|
||||
import com.datastax.driver.core.exceptions.DriverInternalError;
|
||||
import com.datastax.driver.core.exceptions.InvalidConfigurationInQueryException;
|
||||
import com.datastax.driver.core.exceptions.InvalidQueryException;
|
||||
import com.datastax.driver.core.exceptions.InvalidTypeException;
|
||||
import com.datastax.driver.core.exceptions.NoHostAvailableException;
|
||||
import com.datastax.driver.core.exceptions.ReadTimeoutException;
|
||||
import com.datastax.driver.core.exceptions.SyntaxError;
|
||||
import com.datastax.driver.core.exceptions.TraceRetrievalException;
|
||||
import com.datastax.driver.core.exceptions.TruncateException;
|
||||
import com.datastax.driver.core.exceptions.UnauthorizedException;
|
||||
import com.datastax.driver.core.exceptions.UnavailableException;
|
||||
import com.datastax.driver.core.exceptions.WriteTimeoutException;
|
||||
|
||||
/**
|
||||
* Simple {@link PersistenceExceptionTranslator} for Cassandra. Convert the given runtime exception to an appropriate
|
||||
* exception from the {@code org.springframework.dao} hierarchy. Return {@literal null} if no translation is
|
||||
* appropriate: any other exception may have resulted from user code, and should not be translated.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
|
||||
public class CassandraExceptionTranslator implements PersistenceExceptionTranslator {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.dao.support.PersistenceExceptionTranslator#
|
||||
* translateExceptionIfPossible(java.lang.RuntimeException)
|
||||
*/
|
||||
public DataAccessException translateExceptionIfPossible(RuntimeException x) {
|
||||
|
||||
if (!(x instanceof DriverException)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (x instanceof DataAccessException) {
|
||||
return (DataAccessException) x;
|
||||
}
|
||||
|
||||
// Remember: subclasses must come before superclasses, otherwise the
|
||||
// superclass would match before the subclass!
|
||||
|
||||
if (x instanceof AuthenticationException) {
|
||||
return new CassandraAuthenticationException(((AuthenticationException) x).getHost(), x.getMessage(), x);
|
||||
}
|
||||
if (x instanceof DriverInternalError) {
|
||||
return new CassandraInternalException(x.getMessage(), x);
|
||||
}
|
||||
if (x instanceof InvalidTypeException) {
|
||||
return new CassandraTypeMismatchException(x.getMessage(), x);
|
||||
}
|
||||
if (x instanceof NoHostAvailableException) {
|
||||
return new CassandraConnectionFailureException(((NoHostAvailableException) x).getErrors(), x.getMessage(), x);
|
||||
}
|
||||
if (x instanceof ReadTimeoutException) {
|
||||
return new CassandraReadTimeoutException(((ReadTimeoutException) x).wasDataRetrieved(), x.getMessage(), x);
|
||||
}
|
||||
if (x instanceof WriteTimeoutException) {
|
||||
WriteType writeType = ((WriteTimeoutException) x).getWriteType();
|
||||
return new CassandraWriteTimeoutException(writeType == null ? null : writeType.name(), x.getMessage(), x);
|
||||
}
|
||||
if (x instanceof TruncateException) {
|
||||
return new CassandraTruncateException(x.getMessage(), x);
|
||||
}
|
||||
if (x instanceof UnavailableException) {
|
||||
UnavailableException ux = (UnavailableException) x;
|
||||
return new CassandraInsufficientReplicasAvailableException(ux.getRequiredReplicas(), ux.getAliveReplicas(),
|
||||
x.getMessage(), x);
|
||||
}
|
||||
if (x instanceof AlreadyExistsException) {
|
||||
AlreadyExistsException aex = (AlreadyExistsException) x;
|
||||
|
||||
return aex.wasTableCreation() ? new CassandraTableExistsException(aex.getTable(), x.getMessage(), x)
|
||||
: new CassandraKeyspaceExistsException(aex.getKeyspace(), x.getMessage(), x);
|
||||
}
|
||||
if (x instanceof InvalidConfigurationInQueryException) {
|
||||
return new CassandraInvalidConfigurationInQueryException(x.getMessage(), x);
|
||||
}
|
||||
if (x instanceof InvalidQueryException) {
|
||||
return new CassandraInvalidQueryException(x.getMessage(), x);
|
||||
}
|
||||
if (x instanceof SyntaxError) {
|
||||
return new CassandraQuerySyntaxException(x.getMessage(), x);
|
||||
}
|
||||
if (x instanceof UnauthorizedException) {
|
||||
return new CassandraUnauthorizedException(x.getMessage(), x);
|
||||
}
|
||||
if (x instanceof TraceRetrievalException) {
|
||||
return new CassandraTraceRetrievalException(x.getMessage(), x);
|
||||
}
|
||||
|
||||
// unknown or unhandled exception
|
||||
return new CassandraUncategorizedException(x.getMessage(), x);
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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.support.exception;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
import org.springframework.dao.PermissionDeniedDataAccessException;
|
||||
|
||||
/**
|
||||
* Spring data access exception for a Cassandra authentication failure.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraAuthenticationException extends PermissionDeniedDataAccessException {
|
||||
|
||||
private static final long serialVersionUID = 8556304586797273927L;
|
||||
|
||||
private InetAddress host;
|
||||
|
||||
public CassandraAuthenticationException(InetAddress host, String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public InetAddress getHost() {
|
||||
return host;
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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.support.exception;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
|
||||
/**
|
||||
* Spring data access exception for Cassandra when no host is available.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraConnectionFailureException extends DataAccessResourceFailureException {
|
||||
|
||||
private static final long serialVersionUID = 6299912054261646552L;
|
||||
|
||||
private final Map<InetAddress, String> messagesByHost = new HashMap<InetAddress, String>();
|
||||
|
||||
public CassandraConnectionFailureException(Map<InetAddress, String> messagesByHost, String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
this.messagesByHost.putAll(messagesByHost);
|
||||
}
|
||||
|
||||
public Map<InetAddress, String> getMessagesByHost() {
|
||||
return Collections.unmodifiableMap(messagesByHost);
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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.support.exception;
|
||||
|
||||
import org.springframework.dao.TransientDataAccessException;
|
||||
|
||||
/**
|
||||
* Spring data access exception for Cassandra when insufficient replicas are available for a given consistency level.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraInsufficientReplicasAvailableException extends TransientDataAccessException {
|
||||
|
||||
private static final long serialVersionUID = 6415130674604814905L;
|
||||
|
||||
private int numberRequired;
|
||||
private int numberAlive;
|
||||
|
||||
public CassandraInsufficientReplicasAvailableException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public CassandraInsufficientReplicasAvailableException(int numberRequired, int numberAlive, String msg,
|
||||
Throwable cause) {
|
||||
super(msg, cause);
|
||||
this.numberRequired = numberRequired;
|
||||
this.numberAlive = numberAlive;
|
||||
}
|
||||
|
||||
public int getNumberRequired() {
|
||||
return numberRequired;
|
||||
}
|
||||
|
||||
public int getNumberAlive() {
|
||||
return numberAlive;
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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.support.exception;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
||||
/**
|
||||
* Spring data access exception for a Cassandra internal error.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraInternalException extends DataAccessException {
|
||||
|
||||
private static final long serialVersionUID = 433061676465346338L;
|
||||
|
||||
public CassandraInternalException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public CassandraInternalException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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.support.exception;
|
||||
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
|
||||
/**
|
||||
* Spring data access exception for a Cassandra query that is syntactically correct but has an invalid configuration
|
||||
* clause.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraInvalidConfigurationInQueryException extends InvalidDataAccessApiUsageException {
|
||||
|
||||
private static final long serialVersionUID = 4594321191806182918L;
|
||||
|
||||
public CassandraInvalidConfigurationInQueryException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public CassandraInvalidConfigurationInQueryException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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.support.exception;
|
||||
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
|
||||
/**
|
||||
* Spring data access exception for a Cassandra query that's syntactically correct but invalid.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraInvalidQueryException extends InvalidDataAccessApiUsageException {
|
||||
|
||||
private static final long serialVersionUID = 4594321191806182918L;
|
||||
|
||||
public CassandraInvalidQueryException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public CassandraInvalidQueryException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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.support.exception;
|
||||
|
||||
/**
|
||||
* Spring data access exception for Cassandra when a keyspace being created already exists.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraKeyspaceExistsException extends CassandraSchemaElementExistsException {
|
||||
|
||||
private static final long serialVersionUID = 6032967419751410352L;
|
||||
|
||||
public CassandraKeyspaceExistsException(String keyspaceName, String msg, Throwable cause) {
|
||||
super(keyspaceName, ElementType.KEYSPACE, msg, cause);
|
||||
}
|
||||
|
||||
public String getKeyspaceName() {
|
||||
return getElementName();
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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.support.exception;
|
||||
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
|
||||
/**
|
||||
* Spring data access exception for a Cassandra query syntax error.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraQuerySyntaxException extends InvalidDataAccessApiUsageException {
|
||||
|
||||
private static final long serialVersionUID = 4398474399882434154L;
|
||||
|
||||
public CassandraQuerySyntaxException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public CassandraQuerySyntaxException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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.support.exception;
|
||||
|
||||
import org.springframework.dao.QueryTimeoutException;
|
||||
|
||||
/**
|
||||
* Spring data access exception for a Cassandra read timeout.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraReadTimeoutException extends QueryTimeoutException {
|
||||
|
||||
private static final long serialVersionUID = -787022307935203387L;
|
||||
|
||||
private boolean wasDataReceived;
|
||||
|
||||
public CassandraReadTimeoutException(boolean wasDataReceived, String msg, Throwable cause) {
|
||||
super(msg);
|
||||
this.wasDataReceived = wasDataReceived;
|
||||
}
|
||||
|
||||
public boolean getWasDataReceived() {
|
||||
return wasDataReceived;
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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.support.exception;
|
||||
|
||||
import org.springframework.dao.NonTransientDataAccessException;
|
||||
|
||||
/**
|
||||
* Spring data access exception for when Cassandra schema element being created already exists.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraSchemaElementExistsException extends NonTransientDataAccessException {
|
||||
|
||||
private static final long serialVersionUID = 7798361273692300162L;
|
||||
|
||||
public enum ElementType {
|
||||
KEYSPACE, TABLE, COLUMN, INDEX;
|
||||
}
|
||||
|
||||
private String elementName;
|
||||
private ElementType elementType;
|
||||
|
||||
public CassandraSchemaElementExistsException(String elementName, ElementType elementType, String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
this.elementName = elementName;
|
||||
this.elementType = elementType;
|
||||
}
|
||||
|
||||
public String getElementName() {
|
||||
return elementName;
|
||||
}
|
||||
|
||||
public ElementType getElementType() {
|
||||
return elementType;
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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.support.exception;
|
||||
|
||||
/**
|
||||
* Spring data access exception for when a Cassandra table being created already exists.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraTableExistsException extends CassandraSchemaElementExistsException {
|
||||
|
||||
private static final long serialVersionUID = 6032967419751410352L;
|
||||
|
||||
public CassandraTableExistsException(String tableName, String msg, Throwable cause) {
|
||||
super(tableName, ElementType.TABLE, msg, cause);
|
||||
}
|
||||
|
||||
public String getTableName() {
|
||||
return getElementName();
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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.support.exception;
|
||||
|
||||
import org.springframework.dao.TransientDataAccessException;
|
||||
|
||||
/**
|
||||
* Spring data access exception for a Cassandra trace retrieval exception.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraTraceRetrievalException extends TransientDataAccessException {
|
||||
|
||||
private static final long serialVersionUID = -3163557220324700239L;
|
||||
|
||||
public CassandraTraceRetrievalException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public CassandraTraceRetrievalException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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.support.exception;
|
||||
|
||||
import org.springframework.dao.TransientDataAccessException;
|
||||
|
||||
/**
|
||||
* Spring data access exception for a Cassandra truncate exception.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraTruncateException extends TransientDataAccessException {
|
||||
|
||||
private static final long serialVersionUID = 5730642491362430311L;
|
||||
|
||||
public CassandraTruncateException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public CassandraTruncateException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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.support.exception;
|
||||
|
||||
import org.springframework.dao.TypeMismatchDataAccessException;
|
||||
|
||||
/**
|
||||
* Spring data access exception for a Cassandra type mismatch exception.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraTypeMismatchException extends TypeMismatchDataAccessException {
|
||||
|
||||
private static final long serialVersionUID = -7420058975444905629L;
|
||||
|
||||
public CassandraTypeMismatchException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public CassandraTypeMismatchException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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.support.exception;
|
||||
|
||||
import org.springframework.dao.PermissionDeniedDataAccessException;
|
||||
|
||||
/**
|
||||
* Spring data access exception for when access to a Cassandra element is denied.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraUnauthorizedException extends PermissionDeniedDataAccessException {
|
||||
|
||||
private static final long serialVersionUID = 4618185356687726647L;
|
||||
|
||||
public CassandraUnauthorizedException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +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.support.exception;
|
||||
|
||||
import org.springframework.dao.UncategorizedDataAccessException;
|
||||
|
||||
/**
|
||||
* Spring data access exception for an uncategorized Cassandra exception.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraUncategorizedException extends UncategorizedDataAccessException {
|
||||
|
||||
private static final long serialVersionUID = 1029525121238025444L;
|
||||
|
||||
public CassandraUncategorizedException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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.support.exception;
|
||||
|
||||
import org.springframework.dao.QueryTimeoutException;
|
||||
|
||||
/**
|
||||
* Spring data access exception for a Cassandra write timeout.
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraWriteTimeoutException extends QueryTimeoutException {
|
||||
|
||||
private static final long serialVersionUID = -4374826375213670718L;
|
||||
|
||||
private String writeType;
|
||||
|
||||
public CassandraWriteTimeoutException(String writeType, String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
this.writeType = writeType;
|
||||
}
|
||||
|
||||
public String getWriteType() {
|
||||
return writeType;
|
||||
}
|
||||
}
|
||||
@@ -1,24 +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;
|
||||
|
||||
/**
|
||||
* @author David Webb
|
||||
*
|
||||
*/
|
||||
public interface Constants {
|
||||
|
||||
}
|
||||
@@ -1,203 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011-2012 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.config;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.cassandra.core.CassandraOperations;
|
||||
import org.springframework.cassandra.core.CassandraTemplate;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
import org.springframework.data.cassandra.convert.CassandraConverter;
|
||||
import org.springframework.data.cassandra.convert.MappingCassandraConverter;
|
||||
import org.springframework.data.cassandra.core.CassandraAdminOperations;
|
||||
import org.springframework.data.cassandra.core.CassandraAdminTemplate;
|
||||
import org.springframework.data.cassandra.core.Keyspace;
|
||||
import org.springframework.data.cassandra.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
|
||||
import org.springframework.data.cassandra.mapping.Table;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.datastax.driver.core.Cluster;
|
||||
import com.datastax.driver.core.Session;
|
||||
|
||||
/**
|
||||
* Base class for Spring Data Cassandra configuration using JavaConfig.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*/
|
||||
@Configuration
|
||||
public abstract class AbstractCassandraConfiguration implements BeanClassLoaderAware {
|
||||
|
||||
/**
|
||||
* Used by CassandraTemplate and CassandraAdminTemplate
|
||||
*/
|
||||
|
||||
private ClassLoader beanClassLoader;
|
||||
|
||||
/**
|
||||
* Return the name of the keyspace to connect to.
|
||||
*
|
||||
* @return must not be {@literal null}.
|
||||
*/
|
||||
protected abstract String getKeyspaceName();
|
||||
|
||||
/**
|
||||
* Return the {@link Cluster} instance to connect to.
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Bean
|
||||
public abstract Cluster cluster() throws Exception;
|
||||
|
||||
/**
|
||||
* Creates a {@link Session} to be used by the {@link Keyspace}. Will use the {@link Cluster} instance configured in
|
||||
* {@link #cluster()}.
|
||||
*
|
||||
* @see #cluster()
|
||||
* @see #Keyspace()
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Bean
|
||||
public Session session() throws Exception {
|
||||
String keyspace = getKeyspaceName();
|
||||
if (StringUtils.hasText(keyspace)) {
|
||||
return cluster().connect(keyspace);
|
||||
} else {
|
||||
return cluster().connect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Keyspace} to be used by the {@link CassandraTemplate}. Will use the {@link Session} instance
|
||||
* configured in {@link #session()} and {@link CassandraConverter} configured in {@link #converter()}.
|
||||
*
|
||||
* @see #cluster()
|
||||
* @see #Keyspace()
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Bean
|
||||
public Keyspace keyspace() throws Exception {
|
||||
return new Keyspace(getKeyspaceName(), session(), converter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the base package to scan for mapped {@link Table}s. Will return the package name of the configuration class'
|
||||
* (the concrete class, not this one here) by default. So if you have a {@code com.acme.AppConfig} extending
|
||||
* {@link AbstractCassandraConfiguration} the base package will be considered {@code com.acme} unless the method is
|
||||
* overriden to implement alternate behaviour.
|
||||
*
|
||||
* @return the base package to scan for mapped {@link Table} classes or {@literal null} to not enable scanning for
|
||||
* entities.
|
||||
*/
|
||||
protected String getMappingBasePackage() {
|
||||
return getClass().getPackage().getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link CassandraTemplate}.
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Bean
|
||||
public CassandraOperations cassandraTemplate() throws Exception {
|
||||
return new CassandraTemplate(session());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link CassandraAdminTemplate}.
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Bean
|
||||
public CassandraAdminOperations cassandraAdminTemplate() throws Exception {
|
||||
return new CassandraAdminTemplate(keyspace());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link MappingContext} instance to map Entities to properties.
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Bean
|
||||
public MappingContext<? extends CassandraPersistentEntity<?>, CassandraPersistentProperty> mappingContext() {
|
||||
return new CassandraMappingContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link CassandraConverter} instance to convert Rows to Objects, Objects to BuiltStatements
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Bean
|
||||
public CassandraConverter converter() {
|
||||
MappingCassandraConverter converter = new MappingCassandraConverter(mappingContext());
|
||||
converter.setBeanClassLoader(beanClassLoader);
|
||||
return converter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans the mapping base package for classes annotated with {@link Table}.
|
||||
*
|
||||
* @see #getMappingBasePackage()
|
||||
* @return
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
|
||||
String basePackage = getMappingBasePackage();
|
||||
Set<Class<?>> initialEntitySet = new HashSet<Class<?>>();
|
||||
|
||||
if (StringUtils.hasText(basePackage)) {
|
||||
ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(
|
||||
false);
|
||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Table.class));
|
||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class));
|
||||
|
||||
for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) {
|
||||
initialEntitySet.add(ClassUtils.forName(candidate.getBeanClassName(),
|
||||
AbstractCassandraConfiguration.class.getClassLoader()));
|
||||
}
|
||||
}
|
||||
|
||||
return initialEntitySet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bean ClassLoader Aware for CassandraTemplate/CassandraAdminTemplate
|
||||
*/
|
||||
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.beanClassLoader = classLoader;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* 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.config;
|
||||
|
||||
/**
|
||||
* @author Alex Shvid
|
||||
* @author David Webb
|
||||
*/
|
||||
public final class BeanNames {
|
||||
|
||||
private BeanNames() {
|
||||
}
|
||||
|
||||
public static final String CASSANDRA_CLUSTER = "cassandra-cluster";
|
||||
public static final String CASSANDRA_KEYSPACE = "cassandra-keyspace";
|
||||
public static final String CASSANDRA_SESSION = "cassandra-session";
|
||||
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011-2012 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.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.data.cassandra.core.CassandraClusterFactoryBean;
|
||||
import org.springframework.data.config.ParsingUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Parser for <cluster;gt; definitions.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*/
|
||||
|
||||
public class CassandraClusterParser extends AbstractSimpleBeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return CassandraClusterFactoryBean.class;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#resolveId(org.w3c.dom.Element, org.springframework.beans.factory.support.AbstractBeanDefinition, org.springframework.beans.factory.xml.ParserContext)
|
||||
*/
|
||||
@Override
|
||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
||||
throws BeanDefinitionStoreException {
|
||||
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
return StringUtils.hasText(id) ? id : BeanNames.CASSANDRA_CLUSTER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
|
||||
String contactPoints = element.getAttribute("contactPoints");
|
||||
if (StringUtils.hasText(contactPoints)) {
|
||||
builder.addPropertyValue("contactPoints", contactPoints);
|
||||
}
|
||||
|
||||
String port = element.getAttribute("port");
|
||||
if (StringUtils.hasText(port)) {
|
||||
builder.addPropertyValue("port", port);
|
||||
}
|
||||
|
||||
String compression = element.getAttribute("compression");
|
||||
if (StringUtils.hasText(compression)) {
|
||||
builder.addPropertyValue("compressionType", CompressionType.valueOf(compression));
|
||||
}
|
||||
|
||||
postProcess(builder, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postProcess(BeanDefinitionBuilder builder, Element element) {
|
||||
List<Element> subElements = DomUtils.getChildElements(element);
|
||||
|
||||
// parse nested elements
|
||||
for (Element subElement : subElements) {
|
||||
String name = subElement.getLocalName();
|
||||
|
||||
if ("local-pooling-options".equals(name)) {
|
||||
builder.addPropertyValue("localPoolingOptions", parsePoolingOptions(subElement));
|
||||
} else if ("remote-pooling-options".equals(name)) {
|
||||
builder.addPropertyValue("remotePoolingOptions", parsePoolingOptions(subElement));
|
||||
} else if ("socket-options".equals(name)) {
|
||||
builder.addPropertyValue("socketOptions", parseSocketOptions(subElement));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private BeanDefinition parsePoolingOptions(Element element) {
|
||||
BeanDefinitionBuilder defBuilder = BeanDefinitionBuilder.genericBeanDefinition(PoolingOptionsConfig.class);
|
||||
ParsingUtils.setPropertyValue(defBuilder, element, "min-simultaneous-requests", "minSimultaneousRequests");
|
||||
ParsingUtils.setPropertyValue(defBuilder, element, "max-simultaneous-requests", "maxSimultaneousRequests");
|
||||
ParsingUtils.setPropertyValue(defBuilder, element, "core-connections", "coreConnections");
|
||||
ParsingUtils.setPropertyValue(defBuilder, element, "max-connections", "maxConnections");
|
||||
return defBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
private BeanDefinition parseSocketOptions(Element element) {
|
||||
BeanDefinitionBuilder defBuilder = BeanDefinitionBuilder.genericBeanDefinition(SocketOptionsConfig.class);
|
||||
ParsingUtils.setPropertyValue(defBuilder, element, "connect-timeout-mls", "connectTimeoutMls");
|
||||
ParsingUtils.setPropertyValue(defBuilder, element, "keep-alive", "keepAlive");
|
||||
ParsingUtils.setPropertyValue(defBuilder, element, "reuse-address", "reuseAddress");
|
||||
ParsingUtils.setPropertyValue(defBuilder, element, "so-linger", "soLinger");
|
||||
ParsingUtils.setPropertyValue(defBuilder, element, "tcp-no-delay", "tcpNoDelay");
|
||||
ParsingUtils.setPropertyValue(defBuilder, element, "receive-buffer-size", "receiveBufferSize");
|
||||
ParsingUtils.setPropertyValue(defBuilder, element, "send-buffer-size", "sendBufferSize");
|
||||
return defBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011-2012 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.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.ManagedList;
|
||||
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.data.cassandra.core.CassandraKeyspaceFactoryBean;
|
||||
import org.springframework.data.config.ParsingUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Parser for <keyspace;gt; definitions.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*/
|
||||
|
||||
public class CassandraKeyspaceParser extends AbstractSimpleBeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return CassandraKeyspaceFactoryBean.class;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#resolveId(org.w3c.dom.Element, org.springframework.beans.factory.support.AbstractBeanDefinition, org.springframework.beans.factory.xml.ParserContext)
|
||||
*/
|
||||
@Override
|
||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
||||
throws BeanDefinitionStoreException {
|
||||
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
return StringUtils.hasText(id) ? id : BeanNames.CASSANDRA_KEYSPACE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
|
||||
String name = element.getAttribute("name");
|
||||
if (StringUtils.hasText(name)) {
|
||||
builder.addPropertyValue("keyspace", name);
|
||||
}
|
||||
|
||||
String clusterRef = element.getAttribute("cassandra-cluster-ref");
|
||||
if (!StringUtils.hasText(clusterRef)) {
|
||||
clusterRef = BeanNames.CASSANDRA_CLUSTER;
|
||||
}
|
||||
builder.addPropertyReference("cluster", clusterRef);
|
||||
|
||||
String converterRef = element.getAttribute("cassandra-converter-ref");
|
||||
if (StringUtils.hasText(converterRef)) {
|
||||
builder.addPropertyReference("converter", converterRef);
|
||||
}
|
||||
|
||||
postProcess(builder, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postProcess(BeanDefinitionBuilder builder, Element element) {
|
||||
List<Element> subElements = DomUtils.getChildElements(element);
|
||||
|
||||
// parse nested elements
|
||||
for (Element subElement : subElements) {
|
||||
String name = subElement.getLocalName();
|
||||
|
||||
if ("keyspace-attributes".equals(name)) {
|
||||
builder.addPropertyValue("keyspaceAttributes", parseKeyspaceAttributes(subElement));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private BeanDefinition parseKeyspaceAttributes(Element element) {
|
||||
BeanDefinitionBuilder defBuilder = BeanDefinitionBuilder.genericBeanDefinition(KeyspaceAttributes.class);
|
||||
ParsingUtils.setPropertyValue(defBuilder, element, "auto", "auto");
|
||||
ParsingUtils.setPropertyValue(defBuilder, element, "replication-strategy", "replicationStrategy");
|
||||
ParsingUtils.setPropertyValue(defBuilder, element, "replication-factor", "replicationFactor");
|
||||
ParsingUtils.setPropertyValue(defBuilder, element, "durable-writes", "durableWrites");
|
||||
|
||||
List<Element> subElements = DomUtils.getChildElements(element);
|
||||
ManagedList<Object> tables = new ManagedList<Object>(subElements.size());
|
||||
|
||||
// parse nested elements
|
||||
for (Element subElement : subElements) {
|
||||
String name = subElement.getLocalName();
|
||||
|
||||
if ("table".equals(name)) {
|
||||
tables.add(parseTable(subElement));
|
||||
}
|
||||
}
|
||||
if (!tables.isEmpty()) {
|
||||
defBuilder.addPropertyValue("tables", tables);
|
||||
}
|
||||
|
||||
return defBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
private BeanDefinition parseTable(Element element) {
|
||||
BeanDefinitionBuilder defBuilder = BeanDefinitionBuilder.genericBeanDefinition(TableAttributes.class);
|
||||
ParsingUtils.setPropertyValue(defBuilder, element, "entity", "entity");
|
||||
ParsingUtils.setPropertyValue(defBuilder, element, "name", "name");
|
||||
return defBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,36 +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.config;
|
||||
|
||||
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
||||
|
||||
/**
|
||||
* Namespace handler for <cassandra;gt;.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*/
|
||||
|
||||
public class CassandraNamespaceHandler extends NamespaceHandlerSupport {
|
||||
|
||||
public void init() {
|
||||
|
||||
registerBeanDefinitionParser("cluster", new CassandraClusterParser());
|
||||
registerBeanDefinitionParser("keyspace", new CassandraKeyspaceParser());
|
||||
registerBeanDefinitionParser("session", new CassandraSessionParser());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011-2012 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.config;
|
||||
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.cassandra.core.SessionFactoryBean;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Parser for <session;gt; definitions.
|
||||
*
|
||||
* @author David Webb
|
||||
*/
|
||||
|
||||
public class CassandraSessionParser extends AbstractSimpleBeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return SessionFactoryBean.class;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#resolveId(org.w3c.dom.Element, org.springframework.beans.factory.support.AbstractBeanDefinition, org.springframework.beans.factory.xml.ParserContext)
|
||||
*/
|
||||
@Override
|
||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
||||
throws BeanDefinitionStoreException {
|
||||
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
return StringUtils.hasText(id) ? id : BeanNames.CASSANDRA_SESSION;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
|
||||
String keyspaceRef = element.getAttribute("cassandra-keyspace-ref");
|
||||
if (!StringUtils.hasText(keyspaceRef)) {
|
||||
keyspaceRef = BeanNames.CASSANDRA_KEYSPACE;
|
||||
}
|
||||
builder.addPropertyReference("keyspace", keyspaceRef);
|
||||
|
||||
postProcess(builder, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postProcess(BeanDefinitionBuilder builder, Element element) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.config;
|
||||
|
||||
/**
|
||||
* Simple enumeration for the various compression types.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*/
|
||||
public enum CompressionType {
|
||||
NONE, SNAPPY;
|
||||
}
|
||||
@@ -1,107 +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.config;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Keyspace attributes are used for manipulation around keyspace at the startup. Auto property defines the way how to do
|
||||
* this. Other attributes used to ensure or update keyspace settings.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*/
|
||||
public class KeyspaceAttributes {
|
||||
|
||||
public static final String DEFAULT_REPLICATION_STRATEGY = "SimpleStrategy";
|
||||
public static final int DEFAULT_REPLICATION_FACTOR = 1;
|
||||
public static final boolean DEFAULT_DURABLE_WRITES = true;
|
||||
|
||||
/*
|
||||
* auto possible values:
|
||||
* validate: validate the keyspace, makes no changes.
|
||||
* update: update the keyspace.
|
||||
* create: creates the keyspace, destroying previous data.
|
||||
* create-drop: drop the keyspace at the end of the session.
|
||||
*/
|
||||
public static final String AUTO_VALIDATE = "validate";
|
||||
public static final String AUTO_UPDATE = "update";
|
||||
public static final String AUTO_CREATE = "create";
|
||||
public static final String AUTO_CREATE_DROP = "create-drop";
|
||||
|
||||
private String auto = AUTO_VALIDATE;
|
||||
private String replicationStrategy = DEFAULT_REPLICATION_STRATEGY;
|
||||
private int replicationFactor = DEFAULT_REPLICATION_FACTOR;
|
||||
private boolean durableWrites = DEFAULT_DURABLE_WRITES;
|
||||
|
||||
private Collection<TableAttributes> tables;
|
||||
|
||||
public String getAuto() {
|
||||
return auto;
|
||||
}
|
||||
|
||||
public void setAuto(String auto) {
|
||||
this.auto = auto;
|
||||
}
|
||||
|
||||
public boolean isValidate() {
|
||||
return AUTO_VALIDATE.equals(auto);
|
||||
}
|
||||
|
||||
public boolean isUpdate() {
|
||||
return AUTO_UPDATE.equals(auto);
|
||||
}
|
||||
|
||||
public boolean isCreate() {
|
||||
return AUTO_CREATE.equals(auto);
|
||||
}
|
||||
|
||||
public boolean isCreateDrop() {
|
||||
return AUTO_CREATE_DROP.equals(auto);
|
||||
}
|
||||
|
||||
public String getReplicationStrategy() {
|
||||
return replicationStrategy;
|
||||
}
|
||||
|
||||
public void setReplicationStrategy(String replicationStrategy) {
|
||||
this.replicationStrategy = replicationStrategy;
|
||||
}
|
||||
|
||||
public int getReplicationFactor() {
|
||||
return replicationFactor;
|
||||
}
|
||||
|
||||
public void setReplicationFactor(int replicationFactor) {
|
||||
this.replicationFactor = replicationFactor;
|
||||
}
|
||||
|
||||
public boolean isDurableWrites() {
|
||||
return durableWrites;
|
||||
}
|
||||
|
||||
public void setDurableWrites(boolean durableWrites) {
|
||||
this.durableWrites = durableWrites;
|
||||
}
|
||||
|
||||
public Collection<TableAttributes> getTables() {
|
||||
return tables;
|
||||
}
|
||||
|
||||
public void setTables(Collection<TableAttributes> tables) {
|
||||
this.tables = tables;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,62 +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.config;
|
||||
|
||||
/**
|
||||
* Pooling options POJO. Can be remote or local.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*/
|
||||
public class PoolingOptionsConfig {
|
||||
|
||||
private Integer minSimultaneousRequests;
|
||||
private Integer maxSimultaneousRequests;
|
||||
private Integer coreConnections;
|
||||
private Integer maxConnections;
|
||||
|
||||
public Integer getMinSimultaneousRequests() {
|
||||
return minSimultaneousRequests;
|
||||
}
|
||||
|
||||
public void setMinSimultaneousRequests(Integer minSimultaneousRequests) {
|
||||
this.minSimultaneousRequests = minSimultaneousRequests;
|
||||
}
|
||||
|
||||
public Integer getMaxSimultaneousRequests() {
|
||||
return maxSimultaneousRequests;
|
||||
}
|
||||
|
||||
public void setMaxSimultaneousRequests(Integer maxSimultaneousRequests) {
|
||||
this.maxSimultaneousRequests = maxSimultaneousRequests;
|
||||
}
|
||||
|
||||
public Integer getCoreConnections() {
|
||||
return coreConnections;
|
||||
}
|
||||
|
||||
public void setCoreConnections(Integer coreConnections) {
|
||||
this.coreConnections = coreConnections;
|
||||
}
|
||||
|
||||
public Integer getMaxConnections() {
|
||||
return maxConnections;
|
||||
}
|
||||
|
||||
public void setMaxConnections(Integer maxConnections) {
|
||||
this.maxConnections = maxConnections;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,89 +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.config;
|
||||
|
||||
/**
|
||||
* Socket options POJO. Uses to configure Netty.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*/
|
||||
public class SocketOptionsConfig {
|
||||
|
||||
private Integer connectTimeoutMls;
|
||||
private Boolean keepAlive;
|
||||
private Boolean reuseAddress;
|
||||
private Integer soLinger;
|
||||
private Boolean tcpNoDelay;
|
||||
private Integer receiveBufferSize;
|
||||
private Integer sendBufferSize;
|
||||
|
||||
public Integer getConnectTimeoutMls() {
|
||||
return connectTimeoutMls;
|
||||
}
|
||||
|
||||
public void setConnectTimeoutMls(Integer connectTimeoutMls) {
|
||||
this.connectTimeoutMls = connectTimeoutMls;
|
||||
}
|
||||
|
||||
public Boolean getKeepAlive() {
|
||||
return keepAlive;
|
||||
}
|
||||
|
||||
public void setKeepAlive(Boolean keepAlive) {
|
||||
this.keepAlive = keepAlive;
|
||||
}
|
||||
|
||||
public Boolean getReuseAddress() {
|
||||
return reuseAddress;
|
||||
}
|
||||
|
||||
public void setReuseAddress(Boolean reuseAddress) {
|
||||
this.reuseAddress = reuseAddress;
|
||||
}
|
||||
|
||||
public Integer getSoLinger() {
|
||||
return soLinger;
|
||||
}
|
||||
|
||||
public void setSoLinger(Integer soLinger) {
|
||||
this.soLinger = soLinger;
|
||||
}
|
||||
|
||||
public Boolean getTcpNoDelay() {
|
||||
return tcpNoDelay;
|
||||
}
|
||||
|
||||
public void setTcpNoDelay(Boolean tcpNoDelay) {
|
||||
this.tcpNoDelay = tcpNoDelay;
|
||||
}
|
||||
|
||||
public Integer getReceiveBufferSize() {
|
||||
return receiveBufferSize;
|
||||
}
|
||||
|
||||
public void setReceiveBufferSize(Integer receiveBufferSize) {
|
||||
this.receiveBufferSize = receiveBufferSize;
|
||||
}
|
||||
|
||||
public Integer getSendBufferSize() {
|
||||
return sendBufferSize;
|
||||
}
|
||||
|
||||
public void setSendBufferSize(Integer sendBufferSize) {
|
||||
this.sendBufferSize = sendBufferSize;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,49 +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.config;
|
||||
|
||||
/**
|
||||
* Table attributes are used for manipulation around table at the startup (create/update/validate).
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*/
|
||||
public class TableAttributes {
|
||||
|
||||
private String entity;
|
||||
private String name;
|
||||
|
||||
public String getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
public void setEntity(String entity) {
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TableAttributes [entity=" + entity + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,67 +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.convert;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.data.convert.EntityInstantiators;
|
||||
|
||||
/**
|
||||
* Base class for {@link CassandraConverter} implementations. Sets up a {@link GenericConversionService} and populates
|
||||
* basic converters.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*/
|
||||
public abstract class AbstractCassandraConverter implements CassandraConverter, InitializingBean {
|
||||
|
||||
protected final GenericConversionService conversionService;
|
||||
protected EntityInstantiators instantiators = new EntityInstantiators();
|
||||
|
||||
/**
|
||||
* Creates a new {@link AbstractCassandraConverter} using the given {@link GenericConversionService}.
|
||||
*
|
||||
* @param conversionService
|
||||
*/
|
||||
public AbstractCassandraConverter(GenericConversionService conversionService) {
|
||||
this.conversionService = conversionService == null ? new DefaultConversionService() : conversionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers {@link EntityInstantiators} to customize entity instantiation.
|
||||
*
|
||||
* @param instantiators
|
||||
*/
|
||||
public void setInstantiators(EntityInstantiators instantiators) {
|
||||
this.instantiators = instantiators == null ? new EntityInstantiators() : instantiators;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.core.convert.MongoConverter#getConversionService()
|
||||
*/
|
||||
public ConversionService getConversionService() {
|
||||
return conversionService;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
public void afterPropertiesSet() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2011 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.convert;
|
||||
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
|
||||
import org.springframework.data.convert.EntityConverter;
|
||||
|
||||
/**
|
||||
* Central Cassandra specific converter interface from Object to Row.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*/
|
||||
public interface CassandraConverter extends
|
||||
EntityConverter<CassandraPersistentEntity<?>, CassandraPersistentProperty, Object, Object> {
|
||||
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012 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.convert;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
|
||||
import org.springframework.data.cassandra.util.CqlUtils;
|
||||
import org.springframework.data.mapping.model.DefaultSpELExpressionEvaluator;
|
||||
import org.springframework.data.mapping.model.PropertyValueProvider;
|
||||
import org.springframework.data.mapping.model.SpELExpressionEvaluator;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
import com.datastax.driver.core.Row;
|
||||
|
||||
/**
|
||||
* {@link PropertyValueProvider} to read property values from a {@link Row}.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*/
|
||||
public class CassandraPropertyValueProvider implements PropertyValueProvider<CassandraPersistentProperty> {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(CassandraPropertyValueProvider.class);
|
||||
|
||||
private final Row source;
|
||||
private final SpELExpressionEvaluator evaluator;
|
||||
|
||||
/**
|
||||
* Creates a new {@link CassandraPropertyValueProvider} with the given {@link Row} and
|
||||
* {@link DefaultSpELExpressionEvaluator}.
|
||||
*
|
||||
* @param source must not be {@literal null}.
|
||||
* @param evaluator must not be {@literal null}.
|
||||
*/
|
||||
public CassandraPropertyValueProvider(Row source, DefaultSpELExpressionEvaluator evaluator) {
|
||||
Assert.notNull(source);
|
||||
Assert.notNull(evaluator);
|
||||
|
||||
this.source = source;
|
||||
this.evaluator = evaluator;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.PropertyValueProvider#getPropertyValue(org.springframework.data.mapping.PersistentProperty)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getPropertyValue(CassandraPersistentProperty property) {
|
||||
|
||||
String expression = property.getSpelExpression();
|
||||
if (expression != null) {
|
||||
return evaluator.evaluate(expression);
|
||||
}
|
||||
|
||||
String columnName = property.getColumnName();
|
||||
if (source.isNull(property.getColumnName())) {
|
||||
return null;
|
||||
}
|
||||
DataType columnType = source.getColumnDefinitions().getType(columnName);
|
||||
|
||||
log.info(columnType.getName().name());
|
||||
|
||||
/*
|
||||
* Dave Webb - Added handler for text since getBytes was throwing
|
||||
* InvalidTypeException when using getBytes on a text column.
|
||||
*/
|
||||
// TODO Might need to qualify all DataTypes as we encounter them.
|
||||
if (columnType.equals(DataType.text())) {
|
||||
return (T) source.getString(columnName);
|
||||
}
|
||||
if (columnType.equals(DataType.cint())) {
|
||||
return (T) new Integer(source.getInt(columnName));
|
||||
}
|
||||
|
||||
ByteBuffer bytes = source.getBytes(columnName);
|
||||
return (T) columnType.deserialize(bytes);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,278 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011-2013 by the original author(s).
|
||||
*
|
||||
* 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.convert;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
|
||||
import org.springframework.data.convert.EntityInstantiator;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.BeanWrapper;
|
||||
import org.springframework.data.mapping.model.DefaultSpELExpressionEvaluator;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.mapping.model.PersistentEntityParameterValueProvider;
|
||||
import org.springframework.data.mapping.model.PropertyValueProvider;
|
||||
import org.springframework.data.mapping.model.SpELContext;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import com.datastax.driver.core.Row;
|
||||
import com.datastax.driver.core.querybuilder.Delete.Where;
|
||||
import com.datastax.driver.core.querybuilder.Insert;
|
||||
import com.datastax.driver.core.querybuilder.QueryBuilder;
|
||||
import com.datastax.driver.core.querybuilder.Update;
|
||||
|
||||
/**
|
||||
* {@link CassandraConverter} that uses a {@link MappingContext} to do sophisticated mapping of domain objects to
|
||||
* {@link Row}.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*/
|
||||
public class MappingCassandraConverter extends AbstractCassandraConverter implements ApplicationContextAware,
|
||||
BeanClassLoaderAware {
|
||||
|
||||
protected static final Logger log = LoggerFactory.getLogger(MappingCassandraConverter.class);
|
||||
|
||||
protected final MappingContext<? extends CassandraPersistentEntity<?>, CassandraPersistentProperty> mappingContext;
|
||||
protected ApplicationContext applicationContext;
|
||||
private SpELContext spELContext;
|
||||
private boolean useFieldAccessOnly = true;
|
||||
|
||||
private ClassLoader beanClassLoader;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MappingCassandraConverter} given the new {@link MappingContext}.
|
||||
*
|
||||
* @param mappingContext must not be {@literal null}.
|
||||
*/
|
||||
public MappingCassandraConverter(
|
||||
MappingContext<? extends CassandraPersistentEntity<?>, CassandraPersistentProperty> mappingContext) {
|
||||
super(new DefaultConversionService());
|
||||
this.mappingContext = mappingContext;
|
||||
this.spELContext = new SpELContext(RowReaderPropertyAccessor.INSTANCE);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <R> R readRow(Class<R> clazz, Row row) {
|
||||
|
||||
Class<R> beanClassLoaderClass = transformClassToBeanClassLoaderClass(clazz);
|
||||
|
||||
TypeInformation<? extends R> type = ClassTypeInformation.from(beanClassLoaderClass);
|
||||
// TypeInformation<? extends R> typeToUse = typeMapper.readType(row, type);
|
||||
TypeInformation<? extends R> typeToUse = type;
|
||||
Class<? extends R> rawType = typeToUse.getType();
|
||||
|
||||
if (Row.class.isAssignableFrom(rawType)) {
|
||||
return (R) row;
|
||||
}
|
||||
|
||||
CassandraPersistentEntity<R> persistentEntity = (CassandraPersistentEntity<R>) mappingContext
|
||||
.getPersistentEntity(typeToUse);
|
||||
if (persistentEntity == null) {
|
||||
throw new MappingException("No mapping metadata found for " + rawType.getName());
|
||||
}
|
||||
|
||||
return readRowInternal(persistentEntity, row);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.EntityConverter#getMappingContext()
|
||||
*/
|
||||
public MappingContext<? extends CassandraPersistentEntity<?>, CassandraPersistentProperty> getMappingContext() {
|
||||
return mappingContext;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
|
||||
*/
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
this.spELContext = new SpELContext(this.spELContext, applicationContext);
|
||||
}
|
||||
|
||||
private <S extends Object> S readRowInternal(final CassandraPersistentEntity<S> entity, final Row row) {
|
||||
|
||||
final DefaultSpELExpressionEvaluator evaluator = new DefaultSpELExpressionEvaluator(row, spELContext);
|
||||
|
||||
final PropertyValueProvider<CassandraPersistentProperty> propertyProvider = new CassandraPropertyValueProvider(row,
|
||||
evaluator);
|
||||
PersistentEntityParameterValueProvider<CassandraPersistentProperty> parameterProvider = new PersistentEntityParameterValueProvider<CassandraPersistentProperty>(
|
||||
entity, propertyProvider, null);
|
||||
|
||||
EntityInstantiator instantiator = instantiators.getInstantiatorFor(entity);
|
||||
S instance = instantiator.createInstance(entity, parameterProvider);
|
||||
|
||||
final BeanWrapper<CassandraPersistentEntity<S>, S> wrapper = BeanWrapper.create(instance, conversionService);
|
||||
final S result = wrapper.getBean();
|
||||
|
||||
// Set properties not already set in the constructor
|
||||
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty prop) {
|
||||
|
||||
boolean isConstructorProperty = entity.isConstructorArgument(prop);
|
||||
boolean hasValueForProperty = row.getColumnDefinitions().contains(prop.getColumnName());
|
||||
|
||||
if (!hasValueForProperty || isConstructorProperty) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object obj = propertyProvider.getPropertyValue(prop);
|
||||
wrapper.setProperty(prop, obj, useFieldAccessOnly);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setUseFieldAccessOnly(boolean useFieldAccessOnly) {
|
||||
this.useFieldAccessOnly = useFieldAccessOnly;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.EntityWriter#write(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public <R> R read(Class<R> type, Object row) {
|
||||
if (row instanceof Row) {
|
||||
return readRow(type, (Row) row);
|
||||
}
|
||||
throw new MappingException("Unknown row object " + row.getClass().getName());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.EntityWriter#write(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void write(Object obj, Object builtStatement) {
|
||||
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Class<?> beanClassLoaderClass = transformClassToBeanClassLoaderClass(obj.getClass());
|
||||
CassandraPersistentEntity<?> entity = mappingContext.getPersistentEntity(beanClassLoaderClass);
|
||||
|
||||
if (entity == null) {
|
||||
throw new MappingException("No mapping metadata found for " + obj.getClass());
|
||||
}
|
||||
|
||||
if (builtStatement instanceof Insert) {
|
||||
writeInsertInternal(obj, (Insert) builtStatement, entity);
|
||||
} else if (builtStatement instanceof Update) {
|
||||
writeUpdateInternal(obj, (Update) builtStatement, entity);
|
||||
} else if (builtStatement instanceof Where) {
|
||||
writeDeleteWhereInternal(obj, (Where) builtStatement, entity);
|
||||
} else {
|
||||
throw new MappingException("Unknown buildStatement " + builtStatement.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
private void writeInsertInternal(final Object objectToSave, final Insert insert, CassandraPersistentEntity<?> entity) {
|
||||
|
||||
final BeanWrapper<CassandraPersistentEntity<Object>, Object> wrapper = BeanWrapper.create(objectToSave,
|
||||
conversionService);
|
||||
|
||||
// Write the properties
|
||||
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty prop) {
|
||||
|
||||
Object propertyObj = wrapper.getProperty(prop, prop.getType(), useFieldAccessOnly);
|
||||
|
||||
if (propertyObj != null) {
|
||||
insert.value(prop.getColumnName(), propertyObj);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void writeUpdateInternal(final Object objectToSave, final Update update, CassandraPersistentEntity<?> entity) {
|
||||
|
||||
final BeanWrapper<CassandraPersistentEntity<Object>, Object> wrapper = BeanWrapper.create(objectToSave,
|
||||
conversionService);
|
||||
|
||||
// Write the properties
|
||||
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty prop) {
|
||||
|
||||
Object propertyObj = wrapper.getProperty(prop, prop.getType(), useFieldAccessOnly);
|
||||
|
||||
if (propertyObj != null) {
|
||||
if (prop.isIdProperty()) {
|
||||
update.where(QueryBuilder.eq(prop.getColumnName(), propertyObj));
|
||||
} else {
|
||||
update.with(QueryBuilder.set(prop.getColumnName(), propertyObj));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void writeDeleteWhereInternal(final Object objectToSave, final Where whereId,
|
||||
CassandraPersistentEntity<?> entity) {
|
||||
|
||||
final BeanWrapper<CassandraPersistentEntity<Object>, Object> wrapper = BeanWrapper.create(objectToSave,
|
||||
conversionService);
|
||||
|
||||
// Write the properties
|
||||
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty prop) {
|
||||
|
||||
if (prop.isIdProperty()) {
|
||||
|
||||
Object propertyObj = wrapper.getProperty(prop, prop.getType(), useFieldAccessOnly);
|
||||
|
||||
if (propertyObj != null) {
|
||||
whereId.and(QueryBuilder.eq(prop.getColumnName(), propertyObj));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> Class<T> transformClassToBeanClassLoaderClass(Class<T> entity) {
|
||||
try {
|
||||
return (Class<T>) ClassUtils.forName(entity.getName(), beanClassLoader);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return entity;
|
||||
} catch (LinkageError e) {
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.beanClassLoader = classLoader;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012 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.convert;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
import com.datastax.driver.core.Row;
|
||||
|
||||
/**
|
||||
* {@link PropertyAccessor} to read values from a {@link Row}.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*/
|
||||
enum RowReaderPropertyAccessor implements PropertyAccessor {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.expression.PropertyAccessor#getSpecificTargetClasses()
|
||||
*/
|
||||
public Class<?>[] getSpecificTargetClasses() {
|
||||
return new Class<?>[] { Row.class };
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.expression.PropertyAccessor#canRead(org.springframework.expression.EvaluationContext, java.lang.Object, java.lang.String)
|
||||
*/
|
||||
public boolean canRead(EvaluationContext context, Object target, String name) {
|
||||
return ((Row) target).getColumnDefinitions().contains(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.expression.PropertyAccessor#read(org.springframework.expression.EvaluationContext, java.lang.Object, java.lang.String)
|
||||
*/
|
||||
public TypedValue read(EvaluationContext context, Object target, String name) {
|
||||
Row row = (Row) target;
|
||||
if (row.isNull(name)) {
|
||||
return TypedValue.NULL;
|
||||
}
|
||||
DataType columnType = row.getColumnDefinitions().getType(name);
|
||||
ByteBuffer bytes = row.getBytes(name);
|
||||
Object object = columnType.deserialize(bytes);
|
||||
return new TypedValue(object);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.expression.PropertyAccessor#canWrite(org.springframework.expression.EvaluationContext, java.lang.Object, java.lang.String)
|
||||
*/
|
||||
public boolean canWrite(EvaluationContext context, Object target, String name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.expression.PropertyAccessor#write(org.springframework.expression.EvaluationContext, java.lang.Object, java.lang.String, java.lang.Object)
|
||||
*/
|
||||
public void write(EvaluationContext context, Object target, String name, Object newValue) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,79 +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.core;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.datastax.driver.core.TableMetadata;
|
||||
|
||||
/**
|
||||
* Operations for managing a Cassandra keyspace.
|
||||
*
|
||||
* @author David Webb
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public interface CassandraAdminOperations {
|
||||
|
||||
/**
|
||||
* Get the given table's metadata.
|
||||
*
|
||||
* @param tableName The name of the table.
|
||||
*/
|
||||
TableMetadata getTableMetadata(String tableName);
|
||||
|
||||
/**
|
||||
* Create a table with the name given and fields corresponding to the given class. If the table already exists and
|
||||
* parameter <code>ifNotExists</code> is {@literal true}, this is a no-op and {@literal false} is returned. If the
|
||||
* table doesn't exist, parameter <code>ifNotExists</code> is ignored, the table is created and {@literal true} is
|
||||
* returned.
|
||||
*
|
||||
* @param ifNotExists If true, will only create the table if it doesn't exist, else the create operation will be
|
||||
* ignored and the method will return {@literal false}.
|
||||
* @param tableName The name of the table.
|
||||
* @param entityClass The class whose fields determine the columns created.
|
||||
* @param optionsByName Table options, given by the string option name and the appropriate option value.
|
||||
* @return Returns true if a table was created, false if not.
|
||||
*/
|
||||
boolean createTable(boolean ifNotExists, String tableName, Class<?> entityClass, Map<String, Object> optionsByName);
|
||||
|
||||
/**
|
||||
* Add columns to the given table from the given class. If parameter dropRemovedAttributColumns is true, then this
|
||||
* effectively becomes a synchronization operation between the class's fields and the existing table's columns.
|
||||
*
|
||||
* @param tableName The name of the existing table.
|
||||
* @param entityClass The class whose fields determine the columns added.
|
||||
* @param dropRemovedAttributeColumns Whether to drop columns that exist on the table but that don't have
|
||||
* corresponding fields in the class. If true, this effectively becomes a synchronziation operation.
|
||||
*/
|
||||
void alterTable(String tableName, Class<?> entityClass, boolean dropRemovedAttributeColumns);
|
||||
|
||||
/**
|
||||
* Drops the existing table with the given name and creates a new one; basically a {@link #dropTable(String)} followed
|
||||
* by a {@link #createTable(boolean, String, Class, Map)}.
|
||||
*
|
||||
* @param tableName The name of the table.
|
||||
* @param entityClass The class whose fields determine the new table's columns.
|
||||
* @param optionsByName Table options, given by the string option name and the appropriate option value.
|
||||
*/
|
||||
void replaceTable(String tableName, Class<?> entityClass, Map<String, Object> optionsByName);
|
||||
|
||||
/**
|
||||
* Drops the named table.
|
||||
*
|
||||
* @param tableName The name of the table.
|
||||
*/
|
||||
void dropTable(String tableName);
|
||||
}
|
||||
@@ -1,243 +0,0 @@
|
||||
package org.springframework.data.cassandra.core;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cassandra.core.SessionCallback;
|
||||
import org.springframework.cassandra.support.CassandraExceptionTranslator;
|
||||
import org.springframework.cassandra.support.exception.CassandraTableExistsException;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.data.cassandra.convert.CassandraConverter;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentEntity;
|
||||
import org.springframework.data.cassandra.mapping.CassandraPersistentProperty;
|
||||
import org.springframework.data.cassandra.util.CqlUtils;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.ResultSet;
|
||||
import com.datastax.driver.core.Session;
|
||||
import com.datastax.driver.core.TableMetadata;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link CassandraAdminOperations}.
|
||||
*/
|
||||
public class CassandraAdminTemplate implements CassandraAdminOperations {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(CassandraAdminTemplate.class);
|
||||
|
||||
private Keyspace keyspace;
|
||||
private Session session;
|
||||
private CassandraConverter converter;
|
||||
private MappingContext<? extends CassandraPersistentEntity<?>, CassandraPersistentProperty> mappingContext;
|
||||
|
||||
private final PersistenceExceptionTranslator exceptionTranslator = new CassandraExceptionTranslator();
|
||||
|
||||
/**
|
||||
* Constructor used for a basic template configuration
|
||||
*
|
||||
* @param keyspace must not be {@literal null}.
|
||||
*/
|
||||
public CassandraAdminTemplate(Keyspace keyspace) {
|
||||
setKeyspace(keyspace);
|
||||
}
|
||||
|
||||
protected CassandraAdminTemplate setKeyspace(Keyspace keyspace) {
|
||||
Assert.notNull(keyspace);
|
||||
this.keyspace = keyspace;
|
||||
return setSession(keyspace.getSession()).setCassandraConverter(keyspace.getCassandraConverter());
|
||||
}
|
||||
|
||||
protected CassandraAdminTemplate setSession(Session session) {
|
||||
Assert.notNull(session);
|
||||
return this;
|
||||
}
|
||||
|
||||
protected CassandraAdminTemplate setCassandraConverter(CassandraConverter converter) {
|
||||
Assert.notNull(converter);
|
||||
this.converter = converter;
|
||||
return setMappingContext(converter.getMappingContext());
|
||||
}
|
||||
|
||||
protected CassandraAdminTemplate setMappingContext(
|
||||
MappingContext<? extends CassandraPersistentEntity<?>, CassandraPersistentProperty> mappingContext) {
|
||||
Assert.notNull(mappingContext);
|
||||
return this;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.CassandraAdminOperations#createTable(boolean, java.lang.String, java.lang.Class, java.util.Map)
|
||||
*/
|
||||
@Override
|
||||
public boolean createTable(boolean ifNotExists, final String tableName, Class<?> entityClass,
|
||||
Map<String, Object> optionsByName) {
|
||||
|
||||
try {
|
||||
|
||||
final CassandraPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass);
|
||||
|
||||
execute(new SessionCallback<Object>() {
|
||||
public Object doInSession(Session s) throws DataAccessException {
|
||||
|
||||
String cql = CqlUtils.createTable(tableName, entity);
|
||||
log.info("CREATE TABLE CQL -> " + cql);
|
||||
s.execute(cql);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
|
||||
} catch (CassandraTableExistsException ctex) {
|
||||
return !ifNotExists;
|
||||
} catch (RuntimeException x) {
|
||||
throw tryToConvert(x);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.CassandraAdminOperations#alterTable(java.lang.String, java.lang.Class, boolean)
|
||||
*/
|
||||
@Override
|
||||
public void alterTable(String tableName, Class<?> entityClass, boolean dropRemovedAttributeColumns) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.CassandraAdminOperations#replaceTable(java.lang.String, java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public void replaceTable(String tableName, Class<?> entityClass, Map<String, Object> optionsByName) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a list of query operations to alter the table for the given entity
|
||||
*
|
||||
* @param entityClass
|
||||
* @param tableName
|
||||
*/
|
||||
protected void doAlterTable(Class<?> entityClass, String tableName) {
|
||||
|
||||
CassandraPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass);
|
||||
|
||||
Assert.notNull(entity);
|
||||
|
||||
final TableMetadata tableMetadata = getTableMetadata(tableName);
|
||||
|
||||
final List<String> queryList = CqlUtils.alterTable(tableName, entity, tableMetadata);
|
||||
|
||||
execute(new SessionCallback<Object>() {
|
||||
|
||||
public Object doInSession(Session s) throws DataAccessException {
|
||||
|
||||
for (String q : queryList) {
|
||||
log.info(q);
|
||||
s.execute(q);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.CassandraOperations#dropTable(java.lang.Class)
|
||||
*/
|
||||
public void dropTable(Class<?> entityClass) {
|
||||
|
||||
final String tableName = determineTableName(entityClass);
|
||||
|
||||
dropTable(tableName);
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.CassandraOperations#dropTable(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void dropTable(String tableName) {
|
||||
|
||||
log.info("Dropping table => " + tableName);
|
||||
|
||||
final String q = CqlUtils.dropTable(tableName);
|
||||
log.info(q);
|
||||
|
||||
execute(new SessionCallback<ResultSet>() {
|
||||
|
||||
@Override
|
||||
public ResultSet doInSession(Session s) throws DataAccessException {
|
||||
|
||||
return s.execute(q);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.CassandraOperations#getTableMetadata(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public TableMetadata getTableMetadata(final String tableName) {
|
||||
|
||||
Assert.notNull(tableName);
|
||||
|
||||
return execute(new SessionCallback<TableMetadata>() {
|
||||
|
||||
public TableMetadata doInSession(Session s) throws DataAccessException {
|
||||
|
||||
log.info("Keyspace => " + keyspace.getKeyspace());
|
||||
|
||||
return s.getCluster().getMetadata().getKeyspace(keyspace.getKeyspace()).getTable(tableName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a command at the Session Level
|
||||
*
|
||||
* @param callback
|
||||
* @return
|
||||
*/
|
||||
protected <T> T execute(SessionCallback<T> callback) {
|
||||
|
||||
Assert.notNull(callback);
|
||||
|
||||
try {
|
||||
return callback.doInSession(session);
|
||||
} catch (RuntimeException x) {
|
||||
throw tryToConvert(x);
|
||||
}
|
||||
}
|
||||
|
||||
protected RuntimeException tryToConvert(RuntimeException x) {
|
||||
RuntimeException resolved = exceptionTranslator.translateExceptionIfPossible(x);
|
||||
return resolved == null ? x : resolved;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entityClass
|
||||
* @return
|
||||
*/
|
||||
public String determineTableName(Class<?> entityClass) {
|
||||
|
||||
if (entityClass == null) {
|
||||
throw new InvalidDataAccessApiUsageException(
|
||||
"No class parameter provided, entity table name can't be determined!");
|
||||
}
|
||||
|
||||
CassandraPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass);
|
||||
if (entity == null) {
|
||||
throw new InvalidDataAccessApiUsageException("No Persitent Entity information found for the class "
|
||||
+ entityClass.getName());
|
||||
}
|
||||
return entity.getTable();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,263 +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.core;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.cassandra.support.CassandraExceptionTranslator;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.data.cassandra.config.CompressionType;
|
||||
import org.springframework.data.cassandra.config.PoolingOptionsConfig;
|
||||
import org.springframework.data.cassandra.config.SocketOptionsConfig;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.datastax.driver.core.AuthProvider;
|
||||
import com.datastax.driver.core.Cluster;
|
||||
import com.datastax.driver.core.HostDistance;
|
||||
import com.datastax.driver.core.PoolingOptions;
|
||||
import com.datastax.driver.core.ProtocolOptions.Compression;
|
||||
import com.datastax.driver.core.SocketOptions;
|
||||
import com.datastax.driver.core.policies.LoadBalancingPolicy;
|
||||
import com.datastax.driver.core.policies.ReconnectionPolicy;
|
||||
import com.datastax.driver.core.policies.RetryPolicy;
|
||||
|
||||
/**
|
||||
* Convenient factory for configuring a Cassandra Cluster.
|
||||
*
|
||||
* @author Alex Shvid
|
||||
*/
|
||||
|
||||
public class CassandraClusterFactoryBean implements FactoryBean<Cluster>, InitializingBean, DisposableBean,
|
||||
PersistenceExceptionTranslator {
|
||||
|
||||
private static final int DEFAULT_PORT = 9042;
|
||||
|
||||
private Cluster cluster;
|
||||
|
||||
private String contactPoints;
|
||||
private int port = DEFAULT_PORT;
|
||||
private CompressionType compressionType;
|
||||
|
||||
private PoolingOptionsConfig localPoolingOptions;
|
||||
private PoolingOptionsConfig remotePoolingOptions;
|
||||
private SocketOptionsConfig socketOptions;
|
||||
|
||||
private AuthProvider authProvider;
|
||||
private LoadBalancingPolicy loadBalancingPolicy;
|
||||
private ReconnectionPolicy reconnectionPolicy;
|
||||
private RetryPolicy retryPolicy;
|
||||
|
||||
private boolean metricsEnabled = true;
|
||||
|
||||
private final PersistenceExceptionTranslator exceptionTranslator = new CassandraExceptionTranslator();
|
||||
|
||||
public Cluster getObject() throws Exception {
|
||||
return cluster;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
|
||||
*/
|
||||
public Class<? extends Cluster> getObjectType() {
|
||||
return Cluster.class;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
|
||||
*/
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.dao.support.PersistenceExceptionTranslator#translateExceptionIfPossible(java.lang.RuntimeException)
|
||||
*/
|
||||
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
||||
return exceptionTranslator.translateExceptionIfPossible(ex);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
|
||||
if (!StringUtils.hasText(contactPoints)) {
|
||||
throw new IllegalArgumentException("at least one server is required");
|
||||
}
|
||||
|
||||
Cluster.Builder builder = Cluster.builder();
|
||||
|
||||
builder.addContactPoints(StringUtils.commaDelimitedListToStringArray(contactPoints)).withPort(port);
|
||||
|
||||
if (compressionType != null) {
|
||||
builder.withCompression(convertCompressionType(compressionType));
|
||||
}
|
||||
|
||||
if (localPoolingOptions != null) {
|
||||
builder.withPoolingOptions(configPoolingOptions(HostDistance.LOCAL, localPoolingOptions));
|
||||
}
|
||||
|
||||
if (remotePoolingOptions != null) {
|
||||
builder.withPoolingOptions(configPoolingOptions(HostDistance.REMOTE, remotePoolingOptions));
|
||||
}
|
||||
|
||||
if (socketOptions != null) {
|
||||
builder.withSocketOptions(configSocketOptions(socketOptions));
|
||||
}
|
||||
|
||||
if (authProvider != null) {
|
||||
builder.withAuthProvider(authProvider);
|
||||
}
|
||||
|
||||
if (loadBalancingPolicy != null) {
|
||||
builder.withLoadBalancingPolicy(loadBalancingPolicy);
|
||||
}
|
||||
|
||||
if (reconnectionPolicy != null) {
|
||||
builder.withReconnectionPolicy(reconnectionPolicy);
|
||||
}
|
||||
|
||||
if (retryPolicy != null) {
|
||||
builder.withRetryPolicy(retryPolicy);
|
||||
}
|
||||
|
||||
if (!metricsEnabled) {
|
||||
builder.withoutMetrics();
|
||||
}
|
||||
|
||||
Cluster cluster = builder.build();
|
||||
|
||||
// initialize property
|
||||
this.cluster = cluster;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.DisposableBean#destroy()
|
||||
*/
|
||||
public void destroy() throws Exception {
|
||||
this.cluster.shutdown();
|
||||
}
|
||||
|
||||
public void setContactPoints(String contactPoints) {
|
||||
this.contactPoints = contactPoints;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public void setCompressionType(CompressionType compressionType) {
|
||||
this.compressionType = compressionType;
|
||||
}
|
||||
|
||||
public void setLocalPoolingOptions(PoolingOptionsConfig localPoolingOptions) {
|
||||
this.localPoolingOptions = localPoolingOptions;
|
||||
}
|
||||
|
||||
public void setRemotePoolingOptions(PoolingOptionsConfig remotePoolingOptions) {
|
||||
this.remotePoolingOptions = remotePoolingOptions;
|
||||
}
|
||||
|
||||
public void setSocketOptions(SocketOptionsConfig socketOptions) {
|
||||
this.socketOptions = socketOptions;
|
||||
}
|
||||
|
||||
public void setAuthProvider(AuthProvider authProvider) {
|
||||
this.authProvider = authProvider;
|
||||
}
|
||||
|
||||
public void setLoadBalancingPolicy(LoadBalancingPolicy loadBalancingPolicy) {
|
||||
this.loadBalancingPolicy = loadBalancingPolicy;
|
||||
}
|
||||
|
||||
public void setReconnectionPolicy(ReconnectionPolicy reconnectionPolicy) {
|
||||
this.reconnectionPolicy = reconnectionPolicy;
|
||||
}
|
||||
|
||||
public void setRetryPolicy(RetryPolicy retryPolicy) {
|
||||
this.retryPolicy = retryPolicy;
|
||||
}
|
||||
|
||||
public void setMetricsEnabled(boolean metricsEnabled) {
|
||||
this.metricsEnabled = metricsEnabled;
|
||||
}
|
||||
|
||||
private static Compression convertCompressionType(CompressionType type) {
|
||||
switch (type) {
|
||||
case NONE:
|
||||
return Compression.NONE;
|
||||
case SNAPPY:
|
||||
return Compression.SNAPPY;
|
||||
}
|
||||
throw new IllegalArgumentException("unknown compression type " + type);
|
||||
}
|
||||
|
||||
private static PoolingOptions configPoolingOptions(HostDistance hostDistance, PoolingOptionsConfig config) {
|
||||
PoolingOptions poolingOptions = new PoolingOptions();
|
||||
|
||||
if (config.getMinSimultaneousRequests() != null) {
|
||||
poolingOptions
|
||||
.setMinSimultaneousRequestsPerConnectionThreshold(hostDistance, config.getMinSimultaneousRequests());
|
||||
}
|
||||
if (config.getMaxSimultaneousRequests() != null) {
|
||||
poolingOptions
|
||||
.setMaxSimultaneousRequestsPerConnectionThreshold(hostDistance, config.getMaxSimultaneousRequests());
|
||||
}
|
||||
if (config.getCoreConnections() != null) {
|
||||
poolingOptions.setCoreConnectionsPerHost(hostDistance, config.getCoreConnections());
|
||||
}
|
||||
if (config.getMaxConnections() != null) {
|
||||
poolingOptions.setMaxConnectionsPerHost(hostDistance, config.getMaxConnections());
|
||||
}
|
||||
|
||||
return poolingOptions;
|
||||
}
|
||||
|
||||
private static SocketOptions configSocketOptions(SocketOptionsConfig config) {
|
||||
SocketOptions socketOptions = new SocketOptions();
|
||||
|
||||
if (config.getConnectTimeoutMls() != null) {
|
||||
socketOptions.setConnectTimeoutMillis(config.getConnectTimeoutMls());
|
||||
}
|
||||
if (config.getKeepAlive() != null) {
|
||||
socketOptions.setKeepAlive(config.getKeepAlive());
|
||||
}
|
||||
if (config.getReuseAddress() != null) {
|
||||
socketOptions.setReuseAddress(config.getReuseAddress());
|
||||
}
|
||||
if (config.getSoLinger() != null) {
|
||||
socketOptions.setSoLinger(config.getSoLinger());
|
||||
}
|
||||
if (config.getTcpNoDelay() != null) {
|
||||
socketOptions.setTcpNoDelay(config.getTcpNoDelay());
|
||||
}
|
||||
if (config.getReceiveBufferSize() != null) {
|
||||
socketOptions.setReceiveBufferSize(config.getReceiveBufferSize());
|
||||
}
|
||||
if (config.getSendBufferSize() != null) {
|
||||
socketOptions.setSendBufferSize(config.getSendBufferSize());
|
||||
}
|
||||
|
||||
return socketOptions;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user