You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jb...@apache.org on 2011/07/22 03:59:10 UTC
svn commit: r1149432 - in /cassandra/drivers/java:
src/org/apache/cassandra/cql/jdbc/ test/org/apache/cassandra/cql/
test/org/apache/cassandra/cql/jdbc/
Author: jbellis
Date: Fri Jul 22 01:59:09 2011
New Revision: 1149432
URL: http://svn.apache.org/viewvc?rev=1149432&view=rev
Log:
clean up Connection and CassandraConnection
patch by Rick Shaw and jbellis for CASSANDRA-2924
Removed:
cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/Connection.java
cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/ConnectionPool.java
Modified:
cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CResultSet.java
cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraConnection.java
cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraDriver.java
cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java
cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraStatement.java
cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/Utils.java
cassandra/drivers/java/test/org/apache/cassandra/cql/JdbcDriverTest.java
cassandra/drivers/java/test/org/apache/cassandra/cql/jdbc/PreparedStatementTest.java
Modified: cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CResultSet.java
URL: http://svn.apache.org/viewvc/cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CResultSet.java?rev=1149432&r1=1149431&r2=1149432&view=diff
==============================================================================
--- cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CResultSet.java (original)
+++ cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CResultSet.java Fri Jul 22 01:59:09 2011
@@ -38,51 +38,75 @@ import org.apache.cassandra.utils.ByteBu
public class CResultSet extends AbstractResultSet implements CassandraResultSet
{
+ public static final int DEFAULT_TYPE = ResultSet.TYPE_FORWARD_ONLY;
+ public static final int DEFAULT_CONCURRENCY = ResultSet.CONCUR_READ_ONLY;
+ public static final int DEFAULT_HOLDABILITY = ResultSet.HOLD_CURSORS_OVER_COMMIT;
+
private final ColumnDecoder decoder;
private final String keyspace;
-
+
private final String columnFamily;
-
- /** The r set iter. */
+
+ /**
+ * The r set iter.
+ */
private Iterator<CqlRow> rSetIter;
-
+
int rowNumber = 0;
// the current row key when iterating through results.
private byte[] curRowKey = null;
-
+
private TypedColumn typedCurRowKey = null;
-
- /** The values. */
+
+ /**
+ * The values.
+ */
private List<TypedColumn> values = new ArrayList<TypedColumn>();
-
- /** The value map. */
+
+ /**
+ * The value map.
+ */
private Map<String, TypedColumn> valueMap = new HashMap<String, TypedColumn>();
-
- /** The index map. */
+
+ /**
+ * The index map.
+ */
private Map<String, Integer> indexMap = new HashMap<String, Integer>();
-
+
private final CResultSetMetaData meta;
-
+
private final Statement statement;
-
+
private int resultSetType;
-
+
private int fetchDirection;
-
+
private int fetchSize;
private boolean wasNull;
/**
+ * no argument constructor.
+ */
+ CResultSet()
+ {
+ keyspace = null;
+ columnFamily = null;
+ decoder = null;
+ statement = null;
+ meta = new CResultSetMetaData();
+ }
+
+ /**
* Instantiates a new cassandra result set.
*/
- CResultSet(Statement statement,CqlResult resultSet, ColumnDecoder decoder, String keyspace, String columnFamily) throws SQLException
+ CResultSet(Statement statement, CqlResult resultSet, ColumnDecoder decoder, String keyspace, String columnFamily) throws SQLException
{
this.statement = statement;
this.resultSetType = statement.getResultSetType();
this.fetchDirection = statement.getFetchDirection();
this.fetchSize = statement.getFetchSize();
-
+
this.decoder = decoder;
this.keyspace = keyspace;
this.columnFamily = columnFamily;
@@ -92,23 +116,24 @@ public class CResultSet extends Abstract
public boolean absolute(int arg0) throws SQLException
{
- throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void afterLast() throws SQLException
{
- throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void beforeFirst() throws SQLException
{
- throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
-
+
private final void checkIndex(int index) throws SQLException
{
// 1 <= index <= size()
- if (index < 1 || index > values.size()) throw new SQLSyntaxErrorException(String.format(MUST_BE_POSITIVE, String.valueOf(index)));
+ if (index < 1 || index > values.size())
+ throw new SQLSyntaxErrorException(String.format(MUST_BE_POSITIVE, String.valueOf(index)));
}
private final void checkName(String name) throws SQLException
@@ -143,29 +168,29 @@ public class CResultSet extends Abstract
public boolean first() throws SQLException
{
- throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
// Big Decimal (awaiting a new AbstractType implementation)
-
+
public BigDecimal getBigDecimal(int arg0) throws SQLException
{
- throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
-
+
public BigDecimal getBigDecimal(int arg0, int arg1) throws SQLException
{
- throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public BigDecimal getBigDecimal(String arg0) throws SQLException
{
- throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public BigDecimal getBigDecimal(String arg0, int arg1) throws SQLException
{
- throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public BigInteger getBigInteger(int index) throws SQLException
@@ -179,7 +204,7 @@ public class CResultSet extends Abstract
checkName(name);
return getBigInteger(valueMap.get(name));
}
-
+
private BigInteger getBigInteger(TypedColumn column) throws SQLException
{
checkNotClosed();
@@ -201,13 +226,13 @@ public class CResultSet extends Abstract
throw new SQLSyntaxErrorException(e);
}
- throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"BigInteger"));
+ throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(), "BigInteger"));
}
public boolean getBoolean(int index) throws SQLException
{
checkIndex(index);
- return getBoolean(values.get(index-1));
+ return getBoolean(values.get(index - 1));
}
public boolean getBoolean(String name) throws SQLException
@@ -237,7 +262,7 @@ public class CResultSet extends Abstract
throw new SQLSyntaxErrorException(String.format(NOT_BOOLEAN, str));
}
- throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"Boolean"));
+ throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(), "Boolean"));
}
public byte getByte(int index) throws SQLException
@@ -273,7 +298,7 @@ public class CResultSet extends Abstract
throw new SQLSyntaxErrorException(e);
}
- throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"Byte"));
+ throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(), "Byte"));
}
public byte[] getBytes(int index) throws SQLException
@@ -293,7 +318,7 @@ public class CResultSet extends Abstract
wasNull = value == null;
return value == null ? null : ByteBufferUtil.clone(value).array();
}
-
+
public TypedColumn getColumn(int index) throws SQLException
{
checkIndex(index);
@@ -317,7 +342,7 @@ public class CResultSet extends Abstract
public Date getDate(int index) throws SQLException
{
checkIndex(index);
- return getDate(values.get(index-1));
+ return getDate(values.get(index - 1));
}
public Date getDate(int index, Calendar calendar) throws SQLException
@@ -340,34 +365,34 @@ public class CResultSet extends Abstract
return getDate(name);
}
- private Date getDate(TypedColumn column) throws SQLException
+ private Date getDate(TypedColumn column) throws SQLException
{
checkNotClosed();
Object value = column.getValue();
- wasNull = value==null;
-
+ wasNull = value == null;
+
if (wasNull) return null;
-
- if (value instanceof Long ) return new Date((Long)value);
-
- if (value instanceof java.util.Date ) return new Date(((java.util.Date) value).getTime());
-
+
+ if (value instanceof Long) return new Date((Long) value);
+
+ if (value instanceof java.util.Date) return new Date(((java.util.Date) value).getTime());
+
try
{
if (value instanceof String) return Date.valueOf((String) value);
}
catch (IllegalArgumentException e)
{
- throw new SQLSyntaxErrorException(e);
+ throw new SQLSyntaxErrorException(e);
}
-
- throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"SQL Date"));
+
+ throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(), "SQL Date"));
}
public double getDouble(int index) throws SQLException
{
checkIndex(index);
- return getDouble(values.get(index-1));
+ return getDouble(values.get(index - 1));
}
public double getDouble(String name) throws SQLException
@@ -398,10 +423,10 @@ public class CResultSet extends Abstract
}
catch (NumberFormatException e)
{
- throw new SQLSyntaxErrorException(e);
+ throw new SQLSyntaxErrorException(e);
}
- throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"Double"));
+ throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(), "Double"));
}
public int getFetchDirection() throws SQLException
@@ -409,7 +434,7 @@ public class CResultSet extends Abstract
checkNotClosed();
return fetchDirection;
}
-
+
public int getFetchSize() throws SQLException
{
checkNotClosed();
@@ -427,7 +452,7 @@ public class CResultSet extends Abstract
checkName(name);
return getFloat(valueMap.get(name));
}
-
+
private final Float getFloat(TypedColumn column) throws SQLException
{
checkNotClosed();
@@ -458,7 +483,7 @@ public class CResultSet extends Abstract
public int getHoldability() throws SQLException
{
- checkNotClosed();
+ checkNotClosed();
return statement.getResultSetHoldability();
}
@@ -496,7 +521,7 @@ public class CResultSet extends Abstract
throw new SQLSyntaxErrorException(e);
}
- throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"int"));
+ throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(), "int"));
}
public byte[] getKey() throws SQLException
@@ -537,7 +562,7 @@ public class CResultSet extends Abstract
throw new SQLSyntaxErrorException(e);
}
- throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"Long"));
+ throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(), "Long"));
}
public ResultSetMetaData getMetaData() throws SQLException
@@ -576,7 +601,7 @@ public class CResultSet extends Abstract
// RowId (shall we just store the raw bytes as it is kept in C* ? Probably...
public RowId getRowId(String arg0) throws SQLException
{
- throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public short getShort(int index) throws SQLException
@@ -612,12 +637,12 @@ public class CResultSet extends Abstract
throw new SQLSyntaxErrorException(e);
}
- throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(),"Short"));
+ throw new SQLSyntaxErrorException(String.format(NOT_TRANSLATABLE, value.getClass().getSimpleName(), "Short"));
}
public Statement getStatement() throws SQLException
{
- checkNotClosed();
+ checkNotClosed();
return statement;
}
@@ -644,9 +669,9 @@ public class CResultSet extends Abstract
public Time getTime(int index) throws SQLException
{
checkIndex(index);
- return getTime(values.get(index-1));
+ return getTime(values.get(index - 1));
}
-
+
public Time getTime(int index, Calendar calendar) throws SQLException
{
checkIndex(index);
@@ -666,7 +691,7 @@ public class CResultSet extends Abstract
// silently ignore the Calendar argument; its a hint we do not need
return getTime(name);
}
-
+
private Time getTime(TypedColumn column) throws SQLException
{
checkNotClosed();
@@ -747,7 +772,7 @@ public class CResultSet extends Abstract
return resultSetType;
}
- public TypedColumn getTypedKey()throws SQLException
+ public TypedColumn getTypedKey() throws SQLException
{
return typedCurRowKey;
}
@@ -755,18 +780,18 @@ public class CResultSet extends Abstract
// URL (awaiting some clarifications as to how it is stored in C* ... just a validated Sting in URL format?
public URL getURL(int arg0) throws SQLException
{
- throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public URL getURL(String arg0) throws SQLException
{
- throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
// These Methods are planned to be implemented soon; but not right now...
// Each set of methods has a more detailed set of issues that should be considered fully...
-
-
+
+
public SQLWarning getWarnings() throws SQLException
{
checkNotClosed();
@@ -786,7 +811,7 @@ public class CResultSet extends Abstract
checkNotClosed();
return rowNumber == 0;
}
-
+
public boolean isClosed() throws SQLException
{
return valueMap == null;
@@ -811,10 +836,10 @@ public class CResultSet extends Abstract
// Navigation between rows within the returned set of rows
// Need to use a list iterator so next() needs completely re-thought
-
+
public boolean last() throws SQLException
{
- throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public synchronized boolean next() throws SQLException
@@ -836,7 +861,7 @@ public class CResultSet extends Abstract
TypedColumn c = decoder.makeCol(keyspace, columnFamily, col);
String columnName = decoder.colNameAsString(keyspace, columnFamily, col.name);
- values.add(c);
+ values.add(c);
indexMap.put(columnName, values.size()); // one greater than 0 based index of a list
valueMap.put(columnName, c);
}
@@ -851,12 +876,12 @@ public class CResultSet extends Abstract
public boolean previous() throws SQLException
{
- throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public boolean relative(int arg0) throws SQLException
{
- throw new SQLFeatureNotSupportedException (NOT_SUPPORTED);
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setFetchDirection(int direction) throws SQLException
@@ -865,23 +890,24 @@ public class CResultSet extends Abstract
if (direction == FETCH_FORWARD || direction == FETCH_REVERSE || direction == FETCH_UNKNOWN)
{
- if ((getType() == TYPE_FORWARD_ONLY) && (direction != FETCH_FORWARD)) throw new SQLSyntaxErrorException("attempt to set an illegal direction : " + direction);
+ if ((getType() == TYPE_FORWARD_ONLY) && (direction != FETCH_FORWARD))
+ throw new SQLSyntaxErrorException("attempt to set an illegal direction : " + direction);
fetchDirection = direction;
}
throw new SQLSyntaxErrorException(String.format(BAD_FETCH_DIR, direction));
}
- public void setFetchSize(int size) throws SQLException
+ public void setFetchSize(int size) throws SQLException
{
checkNotClosed();
- if (size < 0 ) throw new SQLException(String.format(BAD_FETCH_SIZE, size));
+ if (size < 0) throw new SQLException(String.format(BAD_FETCH_SIZE, size));
fetchSize = size;
}
public <T> T unwrap(Class<T> iface) throws SQLException
{
if (iface.equals(CassandraResultSet.class)) return (T) this;
-
+
throw new SQLFeatureNotSupportedException(String.format(NO_INTERFACE, iface.getSimpleName()));
}
@@ -889,6 +915,7 @@ public class CResultSet extends Abstract
{
return wasNull;
}
+
/**
* RSMD implementation. The metadata returned refers to the column
* values, not the column names.
@@ -915,7 +942,7 @@ public class CResultSet extends Abstract
public int getColumnDisplaySize(int column) throws SQLException
{
checkIndex(column);
- return values.get(column-1).getValueString().length();
+ return values.get(column - 1).getValueString().length();
}
public String getColumnLabel(int column) throws SQLException
@@ -927,33 +954,33 @@ public class CResultSet extends Abstract
public String getColumnName(int column) throws SQLException
{
checkIndex(column);
- return values.get(column-1).getNameString();
+ return values.get(column - 1).getNameString();
}
public int getColumnType(int column) throws SQLException
{
checkIndex(column);
- return values.get(column-1).getValueType().getJdbcType();
+ return values.get(column - 1).getValueType().getJdbcType();
}
// Spec says "database specific type name". For Cassandra this means the abstract type.
public String getColumnTypeName(int column) throws SQLException
{
checkIndex(column);
- return values.get(column-1).getValueType().getClass().getSimpleName();
+ return values.get(column - 1).getValueType().getClass().getSimpleName();
}
public int getPrecision(int column) throws SQLException
{
checkIndex(column);
- TypedColumn col = values.get(column-1);
+ TypedColumn col = values.get(column - 1);
return col.getValueType().getPrecision(col.getValue());
}
public int getScale(int column) throws SQLException
{
checkIndex(column);
- TypedColumn tc = values.get(column-1);
+ TypedColumn tc = values.get(column - 1);
return tc.getValueType().getScale(tc.getValue());
}
@@ -972,20 +999,20 @@ public class CResultSet extends Abstract
public boolean isAutoIncrement(int column) throws SQLException
{
checkIndex(column);
- return values.get(column-1).getValueType() instanceof CounterColumnType; // todo: check Value is correct.
+ return values.get(column - 1).getValueType() instanceof CounterColumnType; // todo: check Value is correct.
}
public boolean isCaseSensitive(int column) throws SQLException
{
checkIndex(column);
- TypedColumn tc = values.get(column-1);
+ TypedColumn tc = values.get(column - 1);
return tc.getValueType().isCaseSensitive();
}
public boolean isCurrency(int column) throws SQLException
{
checkIndex(column);
- TypedColumn tc = values.get(column-1);
+ TypedColumn tc = values.get(column - 1);
return tc.getValueType().isCurrency();
}
@@ -995,7 +1022,9 @@ public class CResultSet extends Abstract
return isWritable(column);
}
- /** absence is the equivalent of null in Cassandra */
+ /**
+ * absence is the equivalent of null in Cassandra
+ */
public int isNullable(int column) throws SQLException
{
checkIndex(column);
@@ -1017,7 +1046,7 @@ public class CResultSet extends Abstract
public boolean isSigned(int column) throws SQLException
{
checkIndex(column);
- TypedColumn tc = values.get(column-1);
+ TypedColumn tc = values.get(column - 1);
return tc.getValueType().isSigned();
}
Modified: cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraConnection.java
URL: http://svn.apache.org/viewvc/cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraConnection.java?rev=1149432&r1=1149431&r2=1149432&view=diff
==============================================================================
--- cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraConnection.java (original)
+++ cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraConnection.java Fri Jul 22 01:59:09 2011
@@ -20,14 +20,22 @@
*/
package org.apache.cassandra.cql.jdbc;
-import static org.apache.cassandra.cql.jdbc.Utils.*;
+import static org.apache.cassandra.cql.jdbc.Utils.ALWAYS_AUTOCOMMIT;
+import static org.apache.cassandra.cql.jdbc.Utils.BAD_TIMEOUT;
+import static org.apache.cassandra.cql.jdbc.Utils.NO_INTERFACE;
+import static org.apache.cassandra.cql.jdbc.Utils.NO_TRANSACTIONS;
+import static org.apache.cassandra.cql.jdbc.Utils.SCHEMA_MISMATCH;
+import static org.apache.cassandra.cql.jdbc.Utils.TAG_SERVER_NAME;
+import static org.apache.cassandra.cql.jdbc.Utils.TAG_DATABASE_NAME;
+import static org.apache.cassandra.cql.jdbc.Utils.TAG_PASSWORD;
+import static org.apache.cassandra.cql.jdbc.Utils.TAG_PORT_NUMBER;
+import static org.apache.cassandra.cql.jdbc.Utils.TAG_USER;
+import static org.apache.cassandra.cql.jdbc.Utils.WAS_CLOSED_CON;
+import static org.apache.cassandra.cql.jdbc.Utils.determineCurrentKeyspace;
-import java.net.URI;
-import java.net.URISyntaxException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
-import java.sql.ResultSet;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
@@ -40,73 +48,113 @@ import java.sql.SQLTransientConnectionEx
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Properties;
import org.apache.cassandra.thrift.AuthenticationException;
+import org.apache.cassandra.thrift.AuthenticationRequest;
import org.apache.cassandra.thrift.AuthorizationException;
+import org.apache.cassandra.thrift.Cassandra;
+import org.apache.cassandra.thrift.Compression;
+import org.apache.cassandra.thrift.CqlResult;
import org.apache.cassandra.thrift.InvalidRequestException;
import org.apache.cassandra.thrift.SchemaDisagreementException;
import org.apache.cassandra.thrift.TimedOutException;
import org.apache.cassandra.thrift.UnavailableException;
import org.apache.thrift.TException;
+import org.apache.thrift.protocol.TBinaryProtocol;
+import org.apache.thrift.protocol.TProtocol;
+import org.apache.thrift.transport.TFramedTransport;
+import org.apache.thrift.transport.TSocket;
+import org.apache.thrift.transport.TTransport;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Implementation class for {@link Connection}.
*/
class CassandraConnection extends AbstractCassandraConnection implements Connection
{
+
+ private static final Logger logger = LoggerFactory.getLogger(CassandraConnection.class);
+
+ public static final int DB_MAJOR_VERSION = 0;
+ public static final int DB_MINOR_VERSION = 8;
+ public static final String DB_PRODUCT_NAME = "Cassandra";
+
+ public static Compression defaultCompression = Compression.GZIP;
+
private final boolean autoCommit = true;
-
+
private final int transactionIsolation = Connection.TRANSACTION_NONE;
-
- /** Client Info Properties (currently unused) */
+
+ /**
+ * Client Info Properties (currently unused)
+ */
private Properties clientInfo = new Properties();
-
- /** List of all Statements that have been created by this connection */
+
+ /**
+ * List of all Statements that have been created by this connection
+ */
private List<Statement> statements;
-
- /** The Cassandra connection to the Thrift transport. */
- private org.apache.cassandra.cql.jdbc.Connection cassandraCon;
-
+
+ private Cassandra.Client client;
+ private TTransport transport;
+
+ protected long timeOfLastFailure = 0;
+ protected int numFailures = 0;
+
+ String currentKeyspace;
+ ColumnDecoder decoder;
+
+
/**
* Instantiates a new CassandraConnection.
*/
- public CassandraConnection(String url,Properties props) throws SQLException
+ public CassandraConnection(Properties props) throws SQLException
{
statements = new ArrayList<Statement>();
clientInfo = new Properties();
try
{
- String rawUri = url.substring(PROTOCOL.length());
- URI uri = new URI(rawUri);
+ String host = props.getProperty(TAG_SERVER_NAME);
+ int port = Integer.parseInt(props.getProperty(TAG_PORT_NUMBER));
+ String keyspace = props.getProperty(TAG_DATABASE_NAME);
+ String username = props.getProperty(TAG_USER);
+ String password = props.getProperty(TAG_PASSWORD);
+
+ TSocket socket = new TSocket(host, port);
+ transport = new TFramedTransport(socket);
+ TProtocol protocol = new TBinaryProtocol(transport);
+ client = new Cassandra.Client(protocol);
+ socket.open();
+ decoder = new ColumnDecoder(client.describe_keyspaces());
+
+ if (username != null)
+ {
+ Map<String, String> credentials = new HashMap<String, String>();
+ credentials.put("username", username);
+ if (password != null) credentials.put("password", password);
+ AuthenticationRequest areq = new AuthenticationRequest(credentials);
+ client.login(areq);
+
+ }
+
+ logger.info("Connected to {}:{}", host, port);
- String host = uri.getHost() == null ? "localhost" : uri.getHost();
- int port = (uri.getPort() == -1) ? 9160 : uri.getPort();
- String keyspace = (uri.getPath().length() == 0) ? null : uri.getPath().substring(1);
- String userInfo = uri.getUserInfo();
- String[] s = new String[0];
-
- if ((userInfo != null) && (!userInfo.isEmpty()))
- s = userInfo.split(":");
-
- // use user and password from the properties file( which takes precedence over url values)
- String username = props.getProperty("user", (s.length > 0) ? s[0] : null);
- String password = props.getProperty("password", (s.length > 1) ? s[1] : null);
- cassandraCon = new org.apache.cassandra.cql.jdbc.Connection(host, port, username, password);
- final String useQ = "USE " + keyspace;
if (keyspace != null)
- cassandraCon.execute(useQ);
+ {
+ execute("USE " + keyspace);
+ }
}
catch (SchemaDisagreementException e)
{
throw new SQLRecoverableException(SCHEMA_MISMATCH);
}
- catch (URISyntaxException e)
- {
- throw new SQLNonTransientConnectionException(e);
- }
catch (InvalidRequestException e)
{
throw new SQLSyntaxErrorException(e);
@@ -132,12 +180,12 @@ class CassandraConnection extends Abstra
throw new SQLInvalidAuthorizationSpecException(e);
}
}
-
+
private final void checkNotClosed() throws SQLException
{
if (isClosed()) throw new SQLNonTransientConnectionException(WAS_CLOSED_CON);
}
-
+
public void clearWarnings() throws SQLException
{
// This implementation does not support the collection of warnings so clearing is a no-op
@@ -150,11 +198,12 @@ class CassandraConnection extends Abstra
*/
public synchronized void close() throws SQLException
{
- if (cassandraCon != null)
+ if (isConnected())
{
// spec says to close all statements associated with this connection upon close
for (Statement statement : statements) statement.close();
- cassandraCon.close();
+ // then disconnect from the transport
+ disconnect();
}
}
@@ -167,21 +216,21 @@ class CassandraConnection extends Abstra
public Statement createStatement() throws SQLException
{
checkNotClosed();
- statements.add(new CassandraStatement(this.cassandraCon));
+ statements.add(new CassandraStatement(this));
return statements.get(statements.size() - 1);
}
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException
{
checkNotClosed();
- statements.add(new CassandraStatement(this.cassandraCon, null, resultSetType, resultSetConcurrency));
+ statements.add(new CassandraStatement(this, null, resultSetType, resultSetConcurrency));
return statements.get(statements.size() - 1);
}
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException
{
checkNotClosed();
- statements.add(new CassandraStatement(this.cassandraCon, null, resultSetType, resultSetConcurrency, resultSetHoldability));
+ statements.add(new CassandraStatement(this, null, resultSetType, resultSetConcurrency, resultSetHoldability));
return statements.get(statements.size() - 1);
}
@@ -204,7 +253,7 @@ class CassandraConnection extends Abstra
checkNotClosed();
return clientInfo;
}
-
+
public String getClientInfo(String label) throws SQLException
{
checkNotClosed();
@@ -215,9 +264,9 @@ class CassandraConnection extends Abstra
{
checkNotClosed();
// the rationale is there are really no commits in Cassandra so no boundary...
- return ResultSet.HOLD_CURSORS_OVER_COMMIT;
+ return CResultSet.DEFAULT_HOLDABILITY;
}
-
+
public DatabaseMetaData getMetaData() throws SQLException
{
checkNotClosed();
@@ -240,9 +289,8 @@ class CassandraConnection extends Abstra
public synchronized boolean isClosed() throws SQLException
{
- if (cassandraCon == null) return true;
- return !cassandraCon.isOpen();
+ return !isConnected();
}
public boolean isReadOnly() throws SQLException
@@ -276,8 +324,8 @@ class CassandraConnection extends Abstra
public PreparedStatement prepareStatement(String sql) throws SQLException
{
checkNotClosed();
- statements.add(new CassandraPreparedStatement(this.cassandraCon, sql));
- return (PreparedStatement)statements.get(statements.size() - 1);
+ statements.add(new CassandraPreparedStatement(this, sql));
+ return (PreparedStatement) statements.get(statements.size() - 1);
}
public PreparedStatement prepareStatement(String arg0, int arg1, int arg2) throws SQLException
@@ -327,7 +375,7 @@ class CassandraConnection extends Abstra
// the rationale is there are no holdability to set in this implementation...
// so we are "silently ignoring" the request
}
-
+
public void setReadOnly(boolean arg0) throws SQLException
{
checkNotClosed();
@@ -345,4 +393,64 @@ class CassandraConnection extends Abstra
{
throw new SQLFeatureNotSupportedException(String.format(NO_INTERFACE, iface.getSimpleName()));
}
+
+ /**
+ * Execute a CQL query.
+ *
+ * @param queryStr a CQL query string
+ * @param compression query compression to use
+ * @return the query results encoded as a CqlResult structure
+ * @throws InvalidRequestException on poorly constructed or illegal requests
+ * @throws UnavailableException when not all required replicas could be created/read
+ * @throws TimedOutException when a cluster operation timed out
+ * @throws SchemaDisagreementException when the client side and server side are at different versions of schema (Thrift)
+ * @throws TException when there is a error in Thrift processing
+ */
+ public CqlResult execute(String queryStr, Compression compression) throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException, TException
+ {
+ currentKeyspace = determineCurrentKeyspace(queryStr, currentKeyspace);
+
+ try
+ {
+ return client.execute_cql_query(Utils.compressQuery(queryStr, compression), compression);
+ }
+ catch (TException error)
+ {
+ numFailures++;
+ timeOfLastFailure = System.currentTimeMillis();
+ throw error;
+ }
+ }
+
+ /**
+ * Execute a CQL query using the default compression methodology.
+ *
+ * @param queryStr a CQL query string
+ * @return the query results encoded as a CqlResult structure
+ * @throws InvalidRequestException on poorly constructed or illegal requests
+ * @throws UnavailableException when not all required replicas could be created/read
+ * @throws TimedOutException when a cluster operation timed out
+ * @throws SchemaDisagreementException when the client side and server side are at different versions of schema (Thrift)
+ * @throws TException when there is a error in Thrift processing
+ */
+ public CqlResult execute(String queryStr) throws InvalidRequestException, UnavailableException, TimedOutException, SchemaDisagreementException, TException
+ {
+ return execute(queryStr, defaultCompression);
+ }
+
+ /**
+ * Shutdown the remote connection
+ */
+ public void disconnect()
+ {
+ transport.close();
+ }
+
+ /**
+ * Connection state.
+ */
+ public boolean isConnected()
+ {
+ return transport.isOpen();
+ }
}
Modified: cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraDriver.java
URL: http://svn.apache.org/viewvc/cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraDriver.java?rev=1149432&r1=1149431&r2=1149432&view=diff
==============================================================================
--- cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraDriver.java (original)
+++ cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraDriver.java Fri Jul 22 01:59:09 2011
@@ -20,29 +20,34 @@
*/
package org.apache.cassandra.cql.jdbc;
-import static org.apache.cassandra.cql.jdbc.Utils.*;
+import static org.apache.cassandra.cql.jdbc.Utils.PROTOCOL;
+import static org.apache.cassandra.cql.jdbc.Utils.TAG_PASSWORD;
+import static org.apache.cassandra.cql.jdbc.Utils.TAG_USER;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
-import java.sql.SQLNonTransientConnectionException;
import java.util.Properties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
- * The Class CassandraDriver.
- */
- public class CassandraDriver implements Driver
+ * The Class CassandraDriver.
+ */
+public class CassandraDriver implements Driver
{
-
- /** The Constant MAJOR_VERSION. */
- private static final int MAJOR_VERSION = 1;
-
- /** The Constant MINOR_VERSION. */
- private static final int MINOR_VERSION = 0;
+ public static final int DVR_MAJOR_VERSION = 1;
+
+ public static final int DVR_MINOR_VERSION = 0;
+
+ public static final int DVR_PATCH_VERSION = 4;
-// private static final Logger logger = LoggerFactory.getLogger(CassandraDriver.class);
+ public static final String DVR_NAME = "Cassandra JDBC Driver";
+
+ private static final Logger logger = LoggerFactory.getLogger(CassandraDriver.class);
static
{
@@ -54,10 +59,10 @@ import java.util.Properties;
}
catch (SQLException e)
{
- throw new DriverResolverException(e.getMessage());
+ throw new RuntimeException(e.getMessage());
}
}
-
+
/**
* Method to validate whether provided connection url matches with pattern or not.
*/
@@ -71,9 +76,18 @@ import java.util.Properties;
*/
public Connection connect(String url, Properties props) throws SQLException
{
+ Properties finalProps;
if (acceptsURL(url))
{
- return new CassandraConnection(url, props);
+ // parse the URL into a set of Properties
+ finalProps = Utils.parseURL(url);
+
+ // override any matching values in finalProps with values from props
+ finalProps.putAll(props);
+
+ if (logger.isDebugEnabled()) logger.debug("Final Properties to Connection: {}", finalProps);
+
+ return new CassandraConnection(finalProps);
}
else
{
@@ -86,7 +100,7 @@ import java.util.Properties;
*/
public int getMajorVersion()
{
- return MAJOR_VERSION;
+ return DVR_MAJOR_VERSION;
}
/**
@@ -94,15 +108,25 @@ import java.util.Properties;
*/
public int getMinorVersion()
{
- return MINOR_VERSION;
+ return DVR_MINOR_VERSION;
}
/**
* Returns default driver property info object.
*/
- public DriverPropertyInfo[] getPropertyInfo(String arg0, Properties arg1) throws SQLException
+ public DriverPropertyInfo[] getPropertyInfo(String url, Properties props) throws SQLException
{
- return new DriverPropertyInfo[0];
+ if (props == null) props = new Properties();
+
+ DriverPropertyInfo[] info = new DriverPropertyInfo[2];
+
+ info[0] = new DriverPropertyInfo(TAG_USER, props.getProperty(TAG_USER));
+ info[0].description = "The 'user' property";
+
+ info[1] = new DriverPropertyInfo(TAG_PASSWORD, props.getProperty(TAG_PASSWORD));
+ info[1].description = "The 'password' property";
+
+ return info;
}
/**
Modified: cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java
URL: http://svn.apache.org/viewvc/cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java?rev=1149432&r1=1149431&r2=1149432&view=diff
==============================================================================
--- cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java (original)
+++ cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java Fri Jul 22 01:59:09 2011
@@ -20,6 +20,11 @@ package org.apache.cassandra.cql.jdbc;
*
*/
+import static org.apache.cassandra.cql.jdbc.Utils.determineCurrentKeyspace;
+import static org.apache.cassandra.cql.jdbc.Utils.determineCurrentColumnFamily;
+import static org.apache.cassandra.cql.jdbc.Utils.NO_CF;
+import static org.apache.cassandra.cql.jdbc.Utils.NO_COMPARATOR;
+import static org.apache.cassandra.cql.jdbc.Utils.NO_VALIDATOR;
import org.apache.cassandra.db.marshal.*;
@@ -40,8 +45,10 @@ import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.RowId;
+import java.sql.SQLDataException;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
+import java.sql.SQLTransientException;
import java.sql.SQLXML;
import java.sql.Time;
import java.sql.Timestamp;
@@ -55,31 +62,31 @@ import java.util.regex.Pattern;
public class CassandraPreparedStatement extends CassandraStatement implements PreparedStatement
{
-// private static final Pattern Parameterizable = Pattern.compile("(SELECT|DELETE|UPDATE)\\s+.*", Pattern.CASE_INSENSITIVE);
+ // private static final Pattern Parameterizable = Pattern.compile("(SELECT|DELETE|UPDATE)\\s+.*", Pattern.CASE_INSENSITIVE);
private static final Pattern Select = Pattern.compile("SELECT[\\s+FIRST\\s+\\d+]?[\\s+REVERSED]?\\s+(.*)WHERE\\s+(.*)", Pattern.CASE_INSENSITIVE);
private static final Pattern Update = Pattern.compile("UPDATE\\s+\\w+.*\\s+SET\\s+(.*)\\s+WHERE KEY(.*)", Pattern.CASE_INSENSITIVE);
private static final Pattern Delete = Pattern.compile("DELETE\\s+(.*)\\s+FROM\\s+\\w+\\s+WHERE KEY(.*)", Pattern.CASE_INSENSITIVE);
-
+
// current set of bound variables.
private final Map<Integer, Object> variables = new HashMap<Integer, Object>();
-
+
// for batching. These are the queries that have been batched and not executed.
private final List<String> queries = new ArrayList<String>();
-
- CassandraPreparedStatement(Connection con, String cql) throws SQLException
+
+ CassandraPreparedStatement(CassandraConnection con, String cql) throws SQLException
{
super(con, cql);
}
-
+
// impl specific methods start here.
// double quotes strings (in parameters)
- private static String makeCqlString(String s)
+ private static String makeCqlString(String s)
{
// escape any single-quotes with double single-quotes.
return s.replaceAll("\'", "\'\'");
}
-
+
// null type means just call param.toString() and quote it (default for keys).
private static String applySimpleBindings(String q, AbstractType type, ParameterIterator params) throws SQLException
{
@@ -113,11 +120,11 @@ public class CassandraPreparedStatement
}
else
sb.append(c);
-
+
}
return sb.toString();
}
-
+
private static String applyDualBindings(String q, AbstractType ltype, AbstractType rtype, ParameterIterator params) throws SQLException
{
StringBuffer sb = new StringBuffer();
@@ -131,7 +138,7 @@ public class CassandraPreparedStatement
left = false;
if (c == ',' && !between)
left = true;
-
+
if (c == '?' && !between)
{
try
@@ -153,10 +160,12 @@ public class CassandraPreparedStatement
}
return sb.toString();
}
-
- /** applies current bindings to produce a string that can be sent to the server. */
+
+ /**
+ * applies current bindings to produce a string that can be sent to the server.
+ */
public synchronized String makeCql() throws SQLException
- {
+ {
// break cql up
Matcher m;
m = Delete.matcher(cql);
@@ -168,77 +177,79 @@ public class CassandraPreparedStatement
m = Select.matcher(cql);
if (m.matches())
return makeSelect(m.end(1));
-
+
// if we made it this far, cql is not parameterizable. this isn't bad, there is just nothing to be done.
return cql;
}
-
+
// subs parameters into a delete statement.
private String makeDelete(int pivot) throws SQLException
- {
- String keyspace = connection.getKeyspace(cql);
- String columnFamily = connection.getColumnFamily(cql);
+ {
+ String keyspace = determineCurrentKeyspace(cql, connection.currentKeyspace);
+ String columnFamily = determineCurrentColumnFamily(cql);
+ if (columnFamily == null) throw new SQLTransientException(NO_CF);
+
ParameterIterator params = new ParameterIterator();
String left = cql.substring(0, pivot);
AbstractType leftType = connection.decoder.getComparator(keyspace, columnFamily);
- if (leftType == null)
- throw new SQLException("Could not find comparator for " + keyspace + "." + columnFamily);
+ if (leftType == null) throw new SQLDataException(String.format(NO_COMPARATOR, keyspace, columnFamily));
left = applySimpleBindings(left, leftType, params);
+
String right = cql.substring(pivot);
AbstractType keyVald = connection.decoder.getKeyValidator(keyspace, columnFamily);
- if (keyVald == null)
- throw new SQLException("Could not find key validator for " + keyspace + "." + columnFamily);
+ if (keyVald == null) throw new SQLDataException(String.format(NO_VALIDATOR, keyspace, columnFamily));
right = applySimpleBindings(right, keyVald, params);
return left + right;
}
-
+
// subs parameters into a select statement.
private String makeSelect(int pivot) throws SQLException
- {
- String keyspace = connection.getKeyspace(cql);
- String columnFamily = connection.getColumnFamily(cql);
+ {
+ String keyspace = determineCurrentKeyspace(cql, connection.currentKeyspace);
+ String columnFamily = determineCurrentColumnFamily(cql);
+ if (columnFamily == null) throw new SQLTransientException(NO_CF);
+
ParameterIterator params = new ParameterIterator();
String left = cql.substring(0, pivot);
AbstractType leftType = connection.decoder.getComparator(keyspace, columnFamily);
- if (leftType == null)
- throw new SQLException("Could not find comparator for " + keyspace + "." + columnFamily);
+ if (leftType == null) throw new SQLDataException(String.format(NO_COMPARATOR, keyspace, columnFamily));
left = applySimpleBindings(left, leftType, params);
+
String right = cql.substring(pivot);
AbstractType keyVald = connection.decoder.getKeyValidator(keyspace, columnFamily);
- if (keyVald == null)
- throw new SQLException("Could not find key validator for " + keyspace + "." + columnFamily);
+ if (keyVald == null) throw new SQLDataException(String.format(NO_VALIDATOR, keyspace, columnFamily));
right = applySimpleBindings(right, keyVald, params);
return left + right;
}
-
+
// subs parameters into an update statement.
private String makeUpdate(int pivot) throws SQLException
{
// this one is a little bit different. left contains key=value pairs. we use the comparator for the left side,
// the validator for the right side. right side is treated as a key.
- String keyspace = connection.getKeyspace(cql);
- String columnFamily = connection.getColumnFamily(cql);
+ String keyspace = determineCurrentKeyspace(cql, connection.currentKeyspace);
+ String columnFamily = determineCurrentColumnFamily(cql);
+ if (columnFamily == null) throw new SQLTransientException(NO_CF);
+
ParameterIterator params = new ParameterIterator();
String left = cql.substring(0, pivot);
AbstractType leftComp = connection.decoder.getComparator(keyspace, columnFamily);
- if (leftComp == null)
- throw new SQLException("Could not find comparator for " + keyspace + "." + columnFamily);
+ if (leftComp == null) throw new SQLDataException(String.format(NO_COMPARATOR, keyspace, columnFamily));
+
AbstractType leftVald = connection.decoder.getComparator(keyspace, columnFamily);
- if (leftVald == null)
- throw new SQLException("Could not find validator for " + keyspace + "." + columnFamily);
+ if (leftVald == null) throw new SQLDataException(String.format(NO_VALIDATOR, keyspace, columnFamily));
left = applyDualBindings(left, leftComp, leftVald, params);
+
String right = cql.substring(pivot);
AbstractType keyVald = connection.decoder.getKeyValidator(keyspace, columnFamily);
- if (keyVald == null)
- throw new SQLException("Could not find key validator for " + keyspace + "." + columnFamily);
+ if (keyVald == null) throw new SQLDataException(String.format(NO_VALIDATOR, keyspace, columnFamily));
right = applySimpleBindings(right, keyVald, params);
- return left + right;
+ return left + right;
}
-
-
-
+
+
// standard API methods follow.
-
+
public void addBatch() throws SQLException
{
queries.add(makeCql());
@@ -253,12 +264,12 @@ public class CassandraPreparedStatement
{
return this.cql != null && super.execute(makeCql());
}
-
+
public ResultSet executeQuery() throws SQLException
{
return this.cql != null ? super.executeQuery(makeCql()) : null;
}
-
+
public int executeUpdate() throws SQLException
{
String q = makeCql();
@@ -273,13 +284,13 @@ public class CassandraPreparedStatement
{
// todo: current impl of RSMD relies on knowing the results. implementing this will require refactoring CRSMD into
// two classes: the first will be an implementation whose methods don't rely on knowing the results, the second
- // will implement the full CRSMD interfae and extend or compose the first.
+ // will implement the full CRSMD interface and extend or compose the first.
throw new SQLFeatureNotSupportedException("PreparedStatement.getMetaData() hasn't been implemented yet.");
}
public void setByte(int parameterIndex, byte x) throws SQLException
{
- setObject(parameterIndex, new byte[]{x});
+ setObject(parameterIndex, new byte[]{ x });
}
public void setBytes(int parameterIndex, byte[] x) throws SQLException
@@ -316,11 +327,11 @@ public class CassandraPreparedStatement
{
setObject(parameterIndex, x);
}
-
-
+
+
// everything below here is not implemented and will let you know about it.
-
-
+
+
public ParameterMetaData getParameterMetaData() throws SQLException
{
throw new SQLFeatureNotSupportedException("PreparedStatement.getParameterMetaData() hasn't been implemented yet.");
@@ -328,77 +339,77 @@ public class CassandraPreparedStatement
public void setArray(int parameterIndex, Array x) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setBlob(int parameterIndex, Blob x) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setBoolean(int parameterIndex, boolean x) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setClob(int parameterIndex, Clob x) throws SQLException
@@ -408,142 +419,141 @@ public class CassandraPreparedStatement
public void setClob(int parameterIndex, Reader reader) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setClob(int parameterIndex, Reader reader, long length) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setDate(int parameterIndex, Date x) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setDouble(int parameterIndex, double x) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setFloat(int parameterIndex, float x) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
-
+
public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setNClob(int parameterIndex, NClob value) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setNClob(int parameterIndex, Reader reader) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
-
+
public void setNull(int parameterIndex, int sqlType) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
-
+
public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setRef(int parameterIndex, Ref x) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setRowId(int parameterIndex, RowId x) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
-
+
public void setTime(int parameterIndex, Time x) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setURL(int parameterIndex, URL x) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException
{
- throw new SQLFeatureNotSupportedException("method not supported");
+ throw new SQLFeatureNotSupportedException(NOT_SUPPORTED);
}
-
-
+
+
// done with API methods.
-
-
-
+
+
// provides a way to iterate through the parameters. it will blow up if it discovers any missing parameters.
// not thread-safe.
private class ParameterIterator
{
private Map<Integer, Object> params = new HashMap<Integer, Object>(variables);
private int index = 1;
-
+
// throws SQLException if a parameter is not specified.
private Object nextParam() throws SQLException
{
Object p = params.get(index++);
if (p == null)
- throw new SQLException("No parameter bound to " + (index-1));
+ throw new SQLException("No parameter bound to " + (index - 1));
return p;
}
Modified: cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraStatement.java
URL: http://svn.apache.org/viewvc/cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraStatement.java?rev=1149432&r1=1149431&r2=1149432&view=diff
==============================================================================
--- cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraStatement.java (original)
+++ cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraStatement.java Fri Jul 22 01:59:09 2011
@@ -50,72 +50,77 @@ class CassandraStatement extends Abstrac
{
protected static final Pattern UpdatePattern = Pattern.compile("UPDATE .*", Pattern.CASE_INSENSITIVE);
- /** The connection. */
- protected org.apache.cassandra.cql.jdbc.Connection connection;
-
- /** The cql. */
+ /**
+ * The connection.
+ */
+ protected CassandraConnection connection;
+
+ /**
+ * The cql.
+ */
protected String cql;
-
+
protected int fetchDirection = ResultSet.FETCH_FORWARD;
-
+
protected int fetchSize = 0;
protected int maxFieldSize = 0;
protected int maxRows = 0;
-
- protected int resultSetType = ResultSet.TYPE_FORWARD_ONLY;
-
- protected int resultSetConcurrency = ResultSet.TYPE_FORWARD_ONLY;
-
- protected int resultSetHoldability = ResultSet.HOLD_CURSORS_OVER_COMMIT;
-
+
+ protected int resultSetType = CResultSet.DEFAULT_TYPE;
+
+ protected int resultSetConcurrency = CResultSet.DEFAULT_CONCURRENCY;
+
+ protected int resultSetHoldability = CResultSet.DEFAULT_HOLDABILITY;
+
protected ResultSet currentResultSet = null;
-
+
protected int updateCount = -1;
-
+
protected boolean escapeProcessing = true;
- CassandraStatement(org.apache.cassandra.cql.jdbc.Connection con) throws SQLException
+ CassandraStatement(CassandraConnection con) throws SQLException
{
this(con, null);
}
- CassandraStatement(org.apache.cassandra.cql.jdbc.Connection con, String cql) throws SQLException
+ CassandraStatement(CassandraConnection con, String cql) throws SQLException
{
this.connection = con;
this.cql = cql;
}
- CassandraStatement(org.apache.cassandra.cql.jdbc.Connection con, String cql, int resultSetType, int resultSetConcurrency) throws SQLException
+ CassandraStatement(CassandraConnection con, String cql, int resultSetType, int resultSetConcurrency) throws SQLException
{
- this(con,cql,resultSetType,resultSetConcurrency, ResultSet.HOLD_CURSORS_OVER_COMMIT);
+ this(con, cql, resultSetType, resultSetConcurrency, ResultSet.HOLD_CURSORS_OVER_COMMIT);
}
-
- CassandraStatement(org.apache.cassandra.cql.jdbc.Connection con, String cql, int resultSetType, int resultSetConcurrency,
+
+ CassandraStatement(CassandraConnection con, String cql, int resultSetType, int resultSetConcurrency,
int resultSetHoldability) throws SQLException
{
this.connection = con;
this.cql = cql;
- if (!(resultSetType == ResultSet.TYPE_FORWARD_ONLY
- || resultSetType == ResultSet.TYPE_SCROLL_INSENSITIVE
- || resultSetType == ResultSet.TYPE_SCROLL_SENSITIVE)) throw new SQLSyntaxErrorException(BAD_TYPE_RSET);
+ if (!(resultSetType == ResultSet.TYPE_FORWARD_ONLY
+ || resultSetType == ResultSet.TYPE_SCROLL_INSENSITIVE
+ || resultSetType == ResultSet.TYPE_SCROLL_SENSITIVE)) throw new SQLSyntaxErrorException(BAD_TYPE_RSET);
this.resultSetType = resultSetType;
if (!(resultSetConcurrency == ResultSet.CONCUR_READ_ONLY
- || resultSetConcurrency == ResultSet.CONCUR_UPDATABLE )) throw new SQLSyntaxErrorException(BAD_TYPE_RSET);
+ || resultSetConcurrency == ResultSet.CONCUR_UPDATABLE)) throw new SQLSyntaxErrorException(BAD_TYPE_RSET);
this.resultSetConcurrency = resultSetConcurrency;
- if (!(resultSetHoldability == ResultSet.HOLD_CURSORS_OVER_COMMIT
- || resultSetHoldability == ResultSet.CLOSE_CURSORS_AT_COMMIT)) throw new SQLSyntaxErrorException(BAD_HOLD_RSET);
+ if (!(resultSetHoldability == ResultSet.HOLD_CURSORS_OVER_COMMIT
+ || resultSetHoldability == ResultSet.CLOSE_CURSORS_AT_COMMIT))
+ throw new SQLSyntaxErrorException(BAD_HOLD_RSET);
this.resultSetHoldability = resultSetHoldability;
}
-
+
public void addBatch(String arg0) throws SQLException
{
- checkNotClosed();
+ checkNotClosed();
throw new SQLFeatureNotSupportedException(NO_BATCH);
}
@@ -123,10 +128,10 @@ class CassandraStatement extends Abstrac
{
if (isClosed()) throw new SQLRecoverableException(WAS_CLOSED_STMT);
}
-
+
public void clearBatch() throws SQLException
{
- checkNotClosed();
+ checkNotClosed();
throw new SQLFeatureNotSupportedException(NO_BATCH);
}
@@ -149,11 +154,13 @@ class CassandraStatement extends Abstrac
{
resetResults();
CqlResult rSet = connection.execute(sql);
-
- switch(rSet.getType())
+ String keyspace = connection.currentKeyspace;
+ String columnfamily = determineCurrentColumnFamily(sql);
+
+ switch (rSet.getType())
{
case ROWS:
- currentResultSet = new CResultSet(this,rSet, connection.decoder, connection.curKeyspace, connection.curColumnFamily);
+ currentResultSet = new CResultSet(this, rSet, connection.decoder, keyspace, columnfamily);
break;
case INT:
updateCount = rSet.getNum();
@@ -162,7 +169,7 @@ class CassandraStatement extends Abstrac
updateCount = 0;
break;
}
- }
+ }
catch (InvalidRequestException e)
{
throw new SQLSyntaxErrorException(e.getWhy());
@@ -183,24 +190,25 @@ class CassandraStatement extends Abstrac
{
throw new SQLNonTransientConnectionException(e.getMessage());
}
-
+
}
- public boolean execute(String query) throws SQLException
+ public boolean execute(String query) throws SQLException
{
checkNotClosed();
doExecute(query);
- return !(currentResultSet==null);
+ return !(currentResultSet == null);
}
+
public boolean execute(String sql, int autoGeneratedKeys) throws SQLException
{
checkNotClosed();
-
- if (!(autoGeneratedKeys==RETURN_GENERATED_KEYS || autoGeneratedKeys==NO_GENERATED_KEYS))
- throw new SQLSyntaxErrorException(BAD_AUTO_GEN);
-
- if (autoGeneratedKeys==RETURN_GENERATED_KEYS) throw new SQLFeatureNotSupportedException(NO_GEN_KEYS);
-
+
+ if (!(autoGeneratedKeys == RETURN_GENERATED_KEYS || autoGeneratedKeys == NO_GENERATED_KEYS))
+ throw new SQLSyntaxErrorException(BAD_AUTO_GEN);
+
+ if (autoGeneratedKeys == RETURN_GENERATED_KEYS) throw new SQLFeatureNotSupportedException(NO_GEN_KEYS);
+
return execute(sql);
}
@@ -221,7 +229,7 @@ class CassandraStatement extends Abstrac
checkNotClosed();
if (!UpdatePattern.matcher(query).matches())
throw new SQLSyntaxErrorException("Not an update statement.");
-
+
doExecute(query);
return updateCount;
}
@@ -229,9 +237,10 @@ class CassandraStatement extends Abstrac
public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException
{
checkNotClosed();
-
- if (!(autoGeneratedKeys==RETURN_GENERATED_KEYS || autoGeneratedKeys==NO_GENERATED_KEYS)) throw new SQLFeatureNotSupportedException(BAD_AUTO_GEN);
-
+
+ if (!(autoGeneratedKeys == RETURN_GENERATED_KEYS || autoGeneratedKeys == NO_GENERATED_KEYS))
+ throw new SQLFeatureNotSupportedException(BAD_AUTO_GEN);
+
return executeUpdate(sql);
}
@@ -240,7 +249,7 @@ class CassandraStatement extends Abstrac
checkNotClosed();
return (Connection) connection;
}
-
+
public int getFetchDirection() throws SQLException
{
checkNotClosed();
@@ -258,7 +267,7 @@ class CassandraStatement extends Abstrac
checkNotClosed();
return maxFieldSize;
}
-
+
public int getMaxRows() throws SQLException
{
checkNotClosed();
@@ -272,24 +281,24 @@ class CassandraStatement extends Abstrac
// in the current Cassandra implementation there are never MORE results
return false;
}
-
+
public boolean getMoreResults(int current) throws SQLException
{
checkNotClosed();
-
+
switch (current)
{
- case CLOSE_CURRENT_RESULT:
+ case CLOSE_CURRENT_RESULT:
resetResults();
break;
-
- case CLOSE_ALL_RESULTS:
- case KEEP_CURRENT_RESULT:
+
+ case CLOSE_ALL_RESULTS:
+ case KEEP_CURRENT_RESULT:
throw new SQLFeatureNotSupportedException(NO_MULTIPLE);
-
- default:
+
+ default:
throw new SQLSyntaxErrorException(String.format(BAD_KEEP_RSET, current));
- }
+ }
// in the current Cassandra implementation there are never MORE results
return false;
}
@@ -299,13 +308,13 @@ class CassandraStatement extends Abstrac
// the Cassandra implementation does not support timeouts on queries
return 0;
}
-
+
public ResultSet getResultSet() throws SQLException
{
checkNotClosed();
return currentResultSet;
}
-
+
public int getResultSetConcurrency() throws SQLException
{
checkNotClosed();
@@ -317,14 +326,14 @@ class CassandraStatement extends Abstrac
checkNotClosed();
// the Cassandra implementations does not support commits so this is the closest match
return ResultSet.HOLD_CURSORS_OVER_COMMIT;
- }
-
+ }
+
public int getResultSetType() throws SQLException
{
checkNotClosed();
return ResultSet.TYPE_FORWARD_ONLY;
}
-
+
public int getUpdateCount() throws SQLException
{
checkNotClosed();
@@ -339,7 +348,7 @@ class CassandraStatement extends Abstrac
public boolean isClosed() throws SQLException
{
- return connection==null;
+ return connection == null;
}
public boolean isPoolable() throws SQLException
@@ -352,13 +361,13 @@ class CassandraStatement extends Abstrac
{
return false;
}
-
+
private final void resetResults()
{
currentResultSet = null;
updateCount = -1;
}
-
+
public void setEscapeProcessing(boolean enable) throws SQLException
{
checkNotClosed();
@@ -372,18 +381,18 @@ class CassandraStatement extends Abstrac
if (direction == ResultSet.FETCH_FORWARD || direction == ResultSet.FETCH_REVERSE || direction == ResultSet.FETCH_UNKNOWN)
{
- if ((getResultSetType() == ResultSet.TYPE_FORWARD_ONLY) && (direction != ResultSet.FETCH_FORWARD))
+ if ((getResultSetType() == ResultSet.TYPE_FORWARD_ONLY) && (direction != ResultSet.FETCH_FORWARD))
throw new SQLSyntaxErrorException(String.format(BAD_FETCH_DIR, direction));
fetchDirection = direction;
}
throw new SQLSyntaxErrorException(String.format(BAD_FETCH_DIR, direction));
}
-
-
+
+
public void setFetchSize(int size) throws SQLException
{
checkNotClosed();
- if (size < 0 ) throw new SQLSyntaxErrorException(String.format(BAD_FETCH_SIZE, size));
+ if (size < 0) throw new SQLSyntaxErrorException(String.format(BAD_FETCH_SIZE, size));
fetchSize = size;
}
@@ -392,7 +401,7 @@ class CassandraStatement extends Abstrac
checkNotClosed();
// silently ignore this setting. always use default 0 (unlimited)
}
-
+
public void setMaxRows(int arg0) throws SQLException
{
checkNotClosed();
@@ -410,7 +419,7 @@ class CassandraStatement extends Abstrac
checkNotClosed();
// silently ignore any attempt to set this away from the current default (0)
}
-
+
public <T> T unwrap(Class<T> iface) throws SQLException
{
throw new SQLFeatureNotSupportedException(String.format(NO_INTERFACE, iface.getSimpleName()));
Modified: cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/Utils.java
URL: http://svn.apache.org/viewvc/cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/Utils.java?rev=1149432&r1=1149431&r2=1149432&view=diff
==============================================================================
--- cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/Utils.java (original)
+++ cassandra/drivers/java/src/org/apache/cassandra/cql/jdbc/Utils.java Fri Jul 22 01:59:09 2011
@@ -22,30 +22,61 @@
package org.apache.cassandra.cql.jdbc;
import java.io.ByteArrayOutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.nio.ByteBuffer;
+import java.sql.SQLException;
+import java.sql.SQLNonTransientConnectionException;
+import java.sql.SQLSyntaxErrorException;
+import java.util.Properties;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import java.util.zip.Deflater;
-import com.google.common.base.Charsets;
import org.apache.cassandra.thrift.Compression;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Charsets;
+
+/**
+ * A set of static utility methods used by the JDBC Suite, and various default values and error message strings
+ * that can be shared across classes.
+ */
class Utils
{
- protected static final String PROTOCOL = "jdbc:cassandra:";
+ private static final Pattern KEYSPACE_PATTERN = Pattern.compile("USE (\\w+);?", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
+ private static final Pattern SELECT_PATTERN = Pattern.compile("(?:SELECT|DELETE)\\s+.+\\s+FROM\\s+(\\w+).*", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
+ private static final Pattern UPDATE_PATTERN = Pattern.compile("UPDATE\\s+(\\w+)\\s+.*", Pattern.CASE_INSENSITIVE);
+
+ public static final String PROTOCOL = "jdbc:cassandra:";
+ public static final String DEFAULT_HOST = "localhost";
+ public static final int DEFAULT_PORT = 9160;
+
+ public static final String TAG_DESCRIPTION = "description";
+ public static final String TAG_USER = "user";
+ public static final String TAG_PASSWORD = "password";
+ public static final String TAG_DATABASE_NAME = "databaseName";
+ public static final String TAG_SERVER_NAME = "serverName";
+ public static final String TAG_PORT_NUMBER = "portNumber";
+
protected static final String WAS_CLOSED_CON = "method was called on a closed Connection";
protected static final String WAS_CLOSED_STMT = "method was called on a closed Statement";
protected static final String WAS_CLOSED_RSLT = "method was called on a closed ResultSet";
protected static final String NO_INTERFACE = "no object was found that matched the provided interface: %s";
protected static final String NO_TRANSACTIONS = "the Cassandra implementation does not support transactions";
- protected static final String NO_SERVER = "no Cassandra server is available";
+ protected static final String NO_SERVER = "no Cassandra server is available";
protected static final String ALWAYS_AUTOCOMMIT = "the Cassandra implementation is always in auto-commit mode";
protected static final String BAD_TIMEOUT = "the timeout value was less than zero";
- protected static final String SCHEMA_MISMATCH = "schema does not match across nodes, (try again later)";
+ protected static final String SCHEMA_MISMATCH = "schema does not match across nodes, (try again later)";
protected static final String NOT_SUPPORTED = "the Cassandra implementation does not support this method";
protected static final String NO_GEN_KEYS = "the Cassandra implementation does not currently support returning generated keys";
protected static final String NO_BATCH = "the Cassandra implementation does not currently support this batch in Statement";
protected static final String NO_MULTIPLE = "the Cassandra implementation does not currently support multiple open Result Sets";
+ protected static final String NO_VALIDATOR = "Could not find key validator for: %s.%s";
+ protected static final String NO_COMPARATOR = "Could not find key comparator for: %s.%s";
+ protected static final String NO_CF = "no column family reference could be extracted from the provided CQL statement";
protected static final String BAD_KEEP_RSET = "the argument for keeping the current result set : %s is not a valid value";
protected static final String BAD_TYPE_RSET = "the argument for result set type : %s is not a valid value";
protected static final String BAD_CONCUR_RSET = "the argument for result set concurrency : %s is not a valid value";
@@ -57,30 +88,123 @@ class Utils
protected static final String VALID_LABELS = "name provided was not in the list of valid column labels: %s";
protected static final String NOT_TRANSLATABLE = "column was stored in %s format which is not translatable to %s";
protected static final String NOT_BOOLEAN = "string value was neither 'true' nor 'false' : %s";
+ protected static final String HOST_IN_URL = "Connection url must specify a host, e.g., jdbc:cassandra://localhost:9170/Keyspace1";
+ protected static final String HOST_REQUIRED = "a 'host' name is required to build a Connection";
+ protected static final String BAD_KEYSPACE = "Keyspace names must be composed of alphanumerics and underscores (parsed: '%s')";
+ protected static final String URI_IS_SIMPLE = "Connection url may only include host, port, and keyspace, e.g., jdbc:cassandra://localhost:9170/Keyspace1";
-
protected static final Logger logger = LoggerFactory.getLogger(Utils.class);
-
+
+ /**
+ * Use the Compression object method to deflate the query string
+ *
+ * @param queryStr An un-compressed CQL query string
+ * @param compression The compression object
+ * @return A compressed string
+ */
public static ByteBuffer compressQuery(String queryStr, Compression compression)
{
byte[] data = queryStr.getBytes(Charsets.UTF_8);
Deflater compressor = new Deflater();
compressor.setInput(data);
compressor.finish();
-
+
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
-
+
while (!compressor.finished())
{
int size = compressor.deflate(buffer);
byteArray.write(buffer, 0, size);
}
-
- logger.trace("Compressed query statement {} bytes in length to {} bytes",
- data.length,
- byteArray.size());
-
+
+ logger.trace("Compressed query statement {} bytes in length to {} bytes", data.length, byteArray.size());
+
return ByteBuffer.wrap(byteArray.toByteArray());
}
+
+ /**
+ * Parse a URL for the Cassandra JDBC Driver
+ * <p/>
+ * The URL must start with the Protocol: "jdbc:cassandra:"
+ * The URI part(the "Subname") must contain a host and an optional port and optional keyspace name
+ * ie. "//localhost:9160/Test1"
+ *
+ * @param url The full JDBC URL to be parsed
+ * @return A list of properties that were parsed from the Subname
+ * @throws SQLException
+ */
+ public static final Properties parseURL(String url) throws SQLException
+ {
+ Properties props = new Properties();
+
+ if (!(url == null))
+ {
+ props.setProperty(TAG_PORT_NUMBER, "" + DEFAULT_PORT);
+ String rawUri = url.substring(PROTOCOL.length());
+ URI uri = null;
+ try
+ {
+ uri = new URI(rawUri);
+ }
+ catch (URISyntaxException e)
+ {
+ throw new SQLSyntaxErrorException(e);
+ }
+
+ String host = uri.getHost();
+ if (host == null) throw new SQLNonTransientConnectionException(HOST_IN_URL);
+ props.setProperty(TAG_SERVER_NAME, host);
+
+ int port = uri.getPort() >= 0 ? uri.getPort() : DEFAULT_PORT;
+ props.setProperty(TAG_PORT_NUMBER, "" + port);
+
+ String keyspace = uri.getPath();
+ if ((keyspace != null) && (!keyspace.isEmpty()))
+ {
+ if (keyspace.startsWith("/")) keyspace = keyspace.substring(1);
+ if (!keyspace.matches("[a-zA-Z]\\w+"))
+ throw new SQLNonTransientConnectionException(String.format(BAD_KEYSPACE, keyspace));
+ props.setProperty(TAG_DATABASE_NAME, keyspace);
+ }
+
+ if (uri.getUserInfo() != null)
+ throw new SQLNonTransientConnectionException(URI_IS_SIMPLE);
+ }
+
+ if (logger.isTraceEnabled()) logger.trace("URL : '{}' parses to: {}", url, props);
+
+ return props;
+ }
+
+ /**
+ * Determine the current keyspace by inspecting the CQL string to see if a USE statement is provided; which would change the keyspace.
+ *
+ * @param cql A CQL query string
+ * @param current The current keyspace stored as state in the connection
+ * @return the provided keyspace name or the keyspace from the contents of the CQL string
+ */
+ public static String determineCurrentKeyspace(String cql, String current)
+ {
+ String ks = current;
+ Matcher isKeyspace = KEYSPACE_PATTERN.matcher(cql);
+ if (isKeyspace.matches()) ks = isKeyspace.group(1);
+ return ks;
+ }
+
+ /**
+ * Determine the current column family by inspecting the CQL to find a CF reference.
+ *
+ * @param cql A CQL query string
+ * @return The column family name from the contents of the CQL string or null in none was found
+ */
+ public static String determineCurrentColumnFamily(String cql)
+ {
+ String cf = null;
+ Matcher isSelect = SELECT_PATTERN.matcher(cql);
+ if (isSelect.matches()) cf = isSelect.group(1);
+ Matcher isUpdate = UPDATE_PATTERN.matcher(cql);
+ if (isUpdate.matches()) cf = isUpdate.group(1);
+ return cf;
+ }
}
Modified: cassandra/drivers/java/test/org/apache/cassandra/cql/JdbcDriverTest.java
URL: http://svn.apache.org/viewvc/cassandra/drivers/java/test/org/apache/cassandra/cql/JdbcDriverTest.java?rev=1149432&r1=1149431&r2=1149432&view=diff
==============================================================================
--- cassandra/drivers/java/test/org/apache/cassandra/cql/JdbcDriverTest.java (original)
+++ cassandra/drivers/java/test/org/apache/cassandra/cql/JdbcDriverTest.java Fri Jul 22 01:59:09 2011
@@ -59,7 +59,7 @@ public class JdbcDriverTest extends Embe
{
startCassandraServer();
Class.forName("org.apache.cassandra.cql.jdbc.CassandraDriver");
- con = DriverManager.getConnection("jdbc:cassandra://root:root@localhost:9170/Keyspace1");
+ con = DriverManager.getConnection("jdbc:cassandra://localhost:9170/Keyspace1");
String[] inserts =
{
String.format("UPDATE Standard1 SET '%s' = '%s', '%s' = '%s' WHERE KEY = '%s'", first, firstrec, last, lastrec, jsmith),
@@ -82,7 +82,7 @@ public class JdbcDriverTest extends Embe
}
}
}
-
+
private static void expectedMetaData(ResultSetMetaData md, int col, String colClass, String table, String schema,
String label, int type, String typeName, boolean signed, boolean caseSensitive) throws SQLException
{
@@ -106,7 +106,25 @@ public class JdbcDriverTest extends Embe
assertEquals(valuSigned, md.isSigned(col));
assertEquals(valuCaseSense, md.isCaseSensitive(col));
}
-
+
+ @Test(expected=SQLNonTransientConnectionException.class)
+ public void testNoHost() throws SQLException
+ {
+ DriverManager.getConnection("jdbc:cassandra:localhost");
+ }
+
+ @Test(expected=SQLNonTransientConnectionException.class)
+ public void testBadKeyspace() throws SQLException
+ {
+ DriverManager.getConnection("jdbc:cassandra://localhost/Keysp@ce");
+ }
+
+ @Test(expected=SQLNonTransientConnectionException.class)
+ public void testBadUserinfo() throws SQLException
+ {
+ DriverManager.getConnection("jdbc:cassandra://root;root@localhost");
+ }
+
@Test
public void testNonDefaultColumnValidators() throws SQLException
{
Modified: cassandra/drivers/java/test/org/apache/cassandra/cql/jdbc/PreparedStatementTest.java
URL: http://svn.apache.org/viewvc/cassandra/drivers/java/test/org/apache/cassandra/cql/jdbc/PreparedStatementTest.java?rev=1149432&r1=1149431&r2=1149432&view=diff
==============================================================================
--- cassandra/drivers/java/test/org/apache/cassandra/cql/jdbc/PreparedStatementTest.java (original)
+++ cassandra/drivers/java/test/org/apache/cassandra/cql/jdbc/PreparedStatementTest.java Fri Jul 22 01:59:09 2011
@@ -44,7 +44,7 @@ public class PreparedStatementTest exten
{
startCassandraServer();
Class.forName("org.apache.cassandra.cql.jdbc.CassandraDriver");
- con = DriverManager.getConnection("jdbc:cassandra://root:root@localhost:9170/Keyspace1");
+ con = DriverManager.getConnection("jdbc:cassandra://localhost:9170/Keyspace1");
}
@Test
@@ -291,7 +291,7 @@ public class PreparedStatementTest exten
@Test
public void testInteger() throws SQLException
{
- PreparedStatement stmt = con.prepareStatement("update JdbcInteger set ?=?, ?=? where key = ?");
+รท PreparedStatement stmt = con.prepareStatement("update JdbcInteger set ?=?, ?=? where key = ?");
for (int i = 0; i < 5; i++)
{
byte[] key = Integer.toString(i).getBytes();