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 2010/11/11 04:07:12 UTC
svn commit: r1033808 - in /cassandra/branches/cassandra-0.7: ./
src/java/org/apache/cassandra/cli/ test/unit/org/apache/cassandra/cli/
Author: jbellis
Date: Thu Nov 11 03:07:12 2010
New Revision: 1033808
URL: http://svn.apache.org/viewvc?rev=1033808&view=rev
Log:
add ASSUME cli statement
patch by Pavel Yaskevich; reviewed by jbellis for CASSANDRA-1693
Modified:
cassandra/branches/cassandra-0.7/CHANGES.txt
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/Cli.g
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/CliClient.java
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/CliUserHelp.java
cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/cli/CliTest.java
Modified: cassandra/branches/cassandra-0.7/CHANGES.txt
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/CHANGES.txt?rev=1033808&r1=1033807&r2=1033808&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/CHANGES.txt (original)
+++ cassandra/branches/cassandra-0.7/CHANGES.txt Thu Nov 11 03:07:12 2010
@@ -16,7 +16,8 @@ dev
* add friendlier error for UnknownHostException on startup (CASSANDRA-1697)
* include jna dependency in RPM package (CASSANDRA-1690)
* add --skip-keys option to stress.py (CASSANDRA-1696)
- * improve cli handling of non-string column names (CASSANDRA-1701)
+ * improve cli handling of non-string keys and column names
+ (CASSANDRA-1701, -1693)
* enable skipping bad rows on LazilyCompacted path (CASSANDRA-1702)
* r/m extra subcomparator line in cli keyspaces output (CASSANDRA-1712)
* add read repair chance to cli "show keyspaces"
Modified: cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/Cli.g
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/Cli.g?rev=1033808&r1=1033807&r2=1033808&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/Cli.g (original)
+++ cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/Cli.g Thu Nov 11 03:07:12 2010
@@ -56,6 +56,7 @@ tokens {
NODE_UPDATE_COLUMN_FAMILY;
NODE_LIST;
NODE_TRUNCATE;
+ NODE_ASSUME;
// Internal Nodes.
NODE_COLUMN_ACCESS;
@@ -151,6 +152,7 @@ statement
| showStatement
| listStatement
| truncateStatement
+ | assumeStatement
| -> ^(NODE_NO_OP)
;
@@ -204,6 +206,8 @@ helpStatement
-> ^(NODE_HELP NODE_LIST)
| HELP TRUNCATE
-> ^(NODE_HELP NODE_TRUNCATE)
+ | HELP ASSUME
+ -> ^(NODE_HELP NODE_ASSUME)
| HELP
-> ^(NODE_HELP)
| '?'
@@ -266,6 +270,11 @@ truncateStatement
-> ^(NODE_TRUNCATE columnFamily)
;
+assumeStatement
+ : ASSUME columnFamily assumptionElement=Identifier 'AS' defaultType=Identifier
+ -> ^(NODE_ASSUME columnFamily $assumptionElement $defaultType)
+ ;
+
showClusterName
: SHOW CLUSTER NAME
-> ^(NODE_SHOW_CLUSTER_NAME)
@@ -515,6 +524,7 @@ UPDATE: 'UPDATE';
LIST: 'LIST';
LIMIT: 'LIMIT';
TRUNCATE: 'TRUNCATE';
+ASSUME: 'ASSUME';
IP_ADDRESS
: IntegerLiteral '.' IntegerLiteral '.' IntegerLiteral '.' IntegerLiteral
Modified: cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/CliClient.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/CliClient.java?rev=1033808&r1=1033807&r2=1033808&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/CliClient.java (original)
+++ cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/CliClient.java Thu Nov 11 03:07:12 2010
@@ -35,7 +35,7 @@ import java.nio.ByteBuffer;
import java.util.*;
// Cli Client Side Library
-public class CliClient extends CliUserHelp
+public class CliClient extends CliUserHelp
{
/**
@@ -94,13 +94,15 @@ public class CliClient extends CliUserHe
private String keySpace = null;
private String username = null;
private Map<String, KsDef> keyspacesMap = new HashMap<String, KsDef>();
-
+ private Map<String, AbstractType> cfKeysComparators;
+
private final String DEFAULT_PLACEMENT_STRATEGY = "org.apache.cassandra.locator.SimpleStrategy";
public CliClient(CliSessionState cliSessionState, Cassandra.Client thriftClient)
{
this.sessionState = cliSessionState;
this.thriftClient = thriftClient;
+ this.cfKeysComparators = new HashMap<String, AbstractType>();
}
// Execute a CLI Statement
@@ -175,6 +177,9 @@ public class CliClient extends CliUserHe
case CliParser.NODE_TRUNCATE:
executeTruncate(tree.getChild(0).getText());
break;
+ case CliParser.NODE_ASSUME:
+ executeAssumeStatement(tree);
+ break;
case CliParser.NODE_NO_OP:
// comment lines come here; they are treated as no ops.
break;
@@ -214,28 +219,28 @@ public class CliClient extends CliUserHe
private void executeCount(Tree statement)
throws TException, InvalidRequestException, UnavailableException, TimedOutException
{
- if (!CliMain.isConnected() || !hasKeySpace())
- return;
+ if (!CliMain.isConnected() || !hasKeySpace())
+ return;
- Tree columnFamilySpec = statement.getChild(0);
+ Tree columnFamilySpec = statement.getChild(0);
- String key = CliCompiler.getKey(columnFamilySpec);
- String columnFamily = CliCompiler.getColumnFamily(columnFamilySpec);
- int columnSpecCnt = CliCompiler.numColumnSpecifiers(columnFamilySpec);
+ String key = CliCompiler.getKey(columnFamilySpec);
+ String columnFamily = CliCompiler.getColumnFamily(columnFamilySpec);
+ int columnSpecCnt = CliCompiler.numColumnSpecifiers(columnFamilySpec);
- ColumnParent colParent = new ColumnParent(columnFamily).setSuper_column((ByteBuffer) null);
+ ColumnParent colParent = new ColumnParent(columnFamily).setSuper_column((ByteBuffer) null);
- if (columnSpecCnt != 0)
- {
- byte[] superColumn = columnNameAsByteArray(CliCompiler.getColumn(columnFamilySpec, 0), columnFamily);
- colParent = new ColumnParent(columnFamily).setSuper_column(superColumn);
- }
+ if (columnSpecCnt != 0)
+ {
+ byte[] superColumn = columnNameAsByteArray(CliCompiler.getColumn(columnFamilySpec, 0), columnFamily);
+ colParent = new ColumnParent(columnFamily).setSuper_column(superColumn);
+ }
- SliceRange range = new SliceRange(FBUtilities.EMPTY_BYTE_BUFFER, FBUtilities.EMPTY_BYTE_BUFFER, false, Integer.MAX_VALUE);
- SlicePredicate predicate = new SlicePredicate().setColumn_names(null).setSlice_range(range);
-
- int count = thriftClient.get_count(ByteBuffer.wrap(key.getBytes(Charsets.UTF_8)), colParent, predicate, ConsistencyLevel.ONE);
- sessionState.out.printf("%d columns\n", count);
+ SliceRange range = new SliceRange(FBUtilities.EMPTY_BYTE_BUFFER, FBUtilities.EMPTY_BYTE_BUFFER, false, Integer.MAX_VALUE);
+ SlicePredicate predicate = new SlicePredicate().setColumn_names(null).setSlice_range(range);
+
+ int count = thriftClient.get_count(ByteBuffer.wrap(key.getBytes(Charsets.UTF_8)), colParent, predicate, ConsistencyLevel.ONE);
+ sessionState.out.printf("%d columns\n", count);
}
private void executeDelete(Tree statement)
@@ -607,8 +612,11 @@ public class CliClient extends CliUserHe
parent.setSuper_column(superColumnName);
// do the insert
- thriftClient.insert(ByteBuffer.wrap(key.getBytes(Charsets.UTF_8)), parent,
- new Column(columnName, columnValueInBytes, FBUtilities.timestampMicros()), ConsistencyLevel.ONE);
+ AbstractType keyComparator = this.cfKeysComparators.get(columnFamily);
+ ByteBuffer keyBytes = keyComparator == null
+ ? ByteBuffer.wrap(key.getBytes(Charsets.UTF_8))
+ : getBytesAccordingToType(key, keyComparator);
+ thriftClient.insert(keyBytes, parent, new Column(columnName, columnValueInBytes, FBUtilities.timestampMicros()), ConsistencyLevel.ONE);
sessionState.out.println("Value inserted.");
}
@@ -979,6 +987,63 @@ public class CliClient extends CliUserHe
}
}
+ /**
+ * Command: ASSUME <columnFamily> (VALIDATOR | COMPARATOR | KEYS | SUB_COMPARATOR) AS <type>
+ * Tree: ^(NODE_ASSUME <columnFamily> (VALIDATOR | COMPARATOR | KEYS | SUB_COMPARATOR) <type>))
+ * @param statement - tree representing current statement
+ */
+ private void executeAssumeStatement(Tree statement)
+ {
+ if (!CliMain.isConnected() || !hasKeySpace())
+ return;
+
+ CfDef columnFamily = getCfDef(statement.getChild(0).getText());
+
+ // VALIDATOR | COMPARATOR | KEYS | SUB_COMPARATOR
+ String assumptionElement = statement.getChild(1).getText().toUpperCase();
+ // used to store in this.cfKeysComparator
+ AbstractType comparator;
+
+ // Could be UTF8Type, IntegerType, LexicalUUIDType etc.
+ String defaultType = statement.getChild(2).getText();
+
+ try
+ {
+ comparator = Function.valueOf(defaultType.toUpperCase()).getValidator();
+ }
+ catch (Exception e)
+ {
+ String functions = Function.getFunctionNames();
+ sessionState.out.println("Type '" + defaultType + "' was not found. Available: " + functions);
+ return;
+ }
+
+ if (assumptionElement.equals("COMPARATOR"))
+ {
+ columnFamily.setComparator_type(defaultType);
+ }
+ else if (assumptionElement.equals("SUB_COMPARATOR"))
+ {
+ columnFamily.setSubcomparator_type(defaultType);
+ }
+ else if (assumptionElement.equals("VALIDATOR"))
+ {
+ columnFamily.setDefault_validation_class(defaultType);
+ }
+ else if (assumptionElement.equals("KEYS"))
+ {
+ this.cfKeysComparators.put(columnFamily.getName(), comparator);
+ }
+ else
+ {
+ String elements = "VALIDATOR, COMPARATOR, KEYS, SUB_COMPARATOR.";
+ sessionState.out.println(String.format("'%s' is invalid. Available: %s", assumptionElement, elements));
+ return;
+ }
+
+ sessionState.out.println(String.format("Assumption for column family '%s' added successfully.", columnFamily.getName()));
+ }
+
// SHOW API VERSION
private void executeShowVersion() throws TException
{
@@ -1260,7 +1325,7 @@ public class CliClient extends CliUserHe
/**
* Used to parse meta tree and compile meta attributes into List<ColumnDef>
- * @param cfDef
+ * @param cfDef - column family definition
* @param meta (Tree representing Array of the hashes with metadata attributes)
* @return List<ColumnDef> List of the ColumnDef's
*
@@ -1444,7 +1509,7 @@ public class CliClient extends CliUserHe
/**
* Converts column name into byte[] according to comparator type
* @param column - column name from parser
- * @param columnFamilyDef - column family from parser
+ * @param cfDef - column family from parser
* @return bytes[] - into which column name was converted according to comparator type
*/
private byte[] columnNameAsByteArray(String column, CfDef cfDef)
@@ -1710,12 +1775,14 @@ public class CliClient extends CliUserHe
{
AbstractType validator;
String columnFamilyName = columnFamilyDef.getName();
+ AbstractType keyComparator = this.cfKeysComparators.get(columnFamilyName);
for (KeySlice ks : slices)
{
- sessionState.out.printf("-------------------\n");
- sessionState.out.printf("RowKey: %s\n", ByteBufferUtil.string(ks.key, Charsets.UTF_8));
+ String keyName = (keyComparator == null) ? ByteBufferUtil.string(ks.key, Charsets.UTF_8) : keyComparator.getString(ks.key);
+ sessionState.out.printf("-------------------\n");
+ sessionState.out.printf("RowKey: %s\n", keyName);
Iterator<ColumnOrSuperColumn> iterator = ks.getColumnsIterator();
while (iterator.hasNext())
Modified: cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/CliUserHelp.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/CliUserHelp.java?rev=1033808&r1=1033807&r2=1033808&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/CliUserHelp.java (original)
+++ cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/cli/CliUserHelp.java Thu Nov 11 03:07:12 2010
@@ -287,7 +287,18 @@ public class CliUserHelp {
state.out.println("example:");
state.out.println("truncate Category");
break;
-
+
+ case CliParser.NODE_ASSUME:
+ state.out.println("assume <column_family> comparator as <type>");
+ state.out.println("assume <column_family> sub_comparator as <type>");
+ state.out.println("assume <column_family> validator as <type>");
+ state.out.println("assume <column_family> keys as <type>\n");
+ state.out.println("Assume one of the attributes (comparator, sub_comparator, validator or keys)");
+ state.out.println("of the given column family to match specified type. Available types: " + CliClient.Function.getFunctionNames());
+ state.out.println("example:");
+ state.out.println("assume Users comparator as lexicaluuid");
+ break;
+
default:
state.out.println("?");
break;
@@ -331,7 +342,9 @@ public class CliUserHelp {
state.out.println("del <cf>['<key>']['<super>']['<col>'] Delete sub column.");
state.out.println("count <cf>['<key>'] Count columns in record.");
state.out.println("count <cf>['<key>']['<super>'] Count columns in a super column.");
- state.out.println("truncate <column_family> Truncate specified column family.");
+ state.out.println("truncate <column_family> Truncate specified column family.");
+ state.out.println("assume <column_family> <attribute> as <type>");
+ state.out.println("Assume one of the attributes of the given column family to match specified type.");
state.out.println("list <cf> List all rows in the column family.");
state.out.println("list <cf>[<startKey>:]");
state.out.println(" List rows in the column family beginning with <startKey>.");
Modified: cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/cli/CliTest.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/cli/CliTest.java?rev=1033808&r1=1033807&r2=1033808&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/cli/CliTest.java (original)
+++ cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/cli/CliTest.java Thu Nov 11 03:07:12 2010
@@ -80,7 +80,11 @@ public class CliTest extends CleanupHelp
"get SCF1['hello'][1][9999]",
"truncate CF1",
"update keyspace TestKeySpace with placement_strategy='org.apache.cassandra.locator.LocalStrategy'",
- "update keyspace TestKeySpace with replication_factor=1 and strategy_options=[{DC1:3, DC2:4, DC5:1}]"
+ "update keyspace TestKeySpace with replication_factor=1 and strategy_options=[{DC1:3, DC2:4, DC5:1}]",
+ "assume CF1 comparator as utf8",
+ "assume CF1 sub_comparator as integer",
+ "assume CF1 validator as lexicaluuid",
+ "assume CF1 keys as timeuuid"
};
@Test
@@ -135,6 +139,10 @@ public class CliTest extends CleanupHelp
{
assertTrue(result.contains(" truncated."));
}
+ else if (statement.startsWith("assume "))
+ {
+ assertTrue(result.contains("successfully."));
+ }
outStream.reset(); // reset stream so we have only output from next statement all the time
errStream.reset(); // no errors to the end user.