You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by ee...@apache.org on 2010/07/29 22:22:09 UTC
svn commit: r980558 - in /cassandra/trunk/src/java/org/apache/cassandra:
cli/Cli.g cli/CliClient.java cli/CliCompleter.java cli/CliMain.java
thrift/CassandraServer.java
Author: eevans
Date: Thu Jul 29 20:22:08 2010
New Revision: 980558
URL: http://svn.apache.org/viewvc?rev=980558&view=rev
Log:
cli support for keyspace/cf add, drop, and rename
Patch by Mason Bryant; review by eevans for CASSANDRA-1204
Modified:
cassandra/trunk/src/java/org/apache/cassandra/cli/Cli.g
cassandra/trunk/src/java/org/apache/cassandra/cli/CliClient.java
cassandra/trunk/src/java/org/apache/cassandra/cli/CliCompleter.java
cassandra/trunk/src/java/org/apache/cassandra/cli/CliMain.java
cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java
Modified: cassandra/trunk/src/java/org/apache/cassandra/cli/Cli.g
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cli/Cli.g?rev=980558&r1=980557&r2=980558&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cli/Cli.g (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cli/Cli.g Thu Jul 29 20:22:08 2010
@@ -47,10 +47,18 @@ tokens {
NODE_THRIFT_SET;
NODE_THRIFT_COUNT;
NODE_THRIFT_DEL;
+ NODE_ADD_COLUMN_FAMILY;
+ NODE_ADD_KEYSPACE;
+ NODE_DEL_KEYSPACE;
+ NODE_DEL_COLUMN_FAMILY;
+ NODE_RENAME_KEYSPACE;
+ NODE_RENAME_COLUMN_FAMILY;
// Internal Nodes.
NODE_COLUMN_ACCESS;
NODE_ID_LIST;
+ NODE_NEW_CF_ACCESS;
+ NODE_NEW_KEYSPACE_ACCESS;
}
@parser::header {
@@ -73,6 +81,12 @@ stmt
| exitStmt
| countStmt
| describeTable
+ | addColumnFamily
+ | addKeyspace
+ | delColumnFamily
+ | delKeyspace
+ | renameColumnFamily
+ | renameKeyspace
| useTable
| delStmt
| getStmt
@@ -88,7 +102,26 @@ connectStmt
;
helpStmt
- : K_HELP -> ^(NODE_HELP)
+ : K_HELP K_HELP -> ^(NODE_HELP NODE_HELP)
+ | K_HELP K_CONNECT -> ^(NODE_HELP NODE_CONNECT)
+ | K_HELP K_USE -> ^(NODE_HELP NODE_USE_TABLE)
+ | K_HELP K_DESCRIBE K_TABLE -> ^(NODE_HELP NODE_DESCRIBE_TABLE)
+ | K_HELP K_EXIT -> ^(NODE_HELP NODE_EXIT)
+ | K_HELP K_QUIT -> ^(NODE_HELP NODE_EXIT)
+ | K_HELP K_SHOW K_CLUSTER K_NAME -> ^(NODE_HELP NODE_SHOW_CLUSTER_NAME)
+ | K_HELP K_SHOW K_TABLES -> ^(NODE_HELP NODE_SHOW_TABLES)
+ | K_HELP K_SHOW K_VERSION -> ^(NODE_HELP NODE_SHOW_VERSION)
+ | K_HELP K_CREATE K_TABLE -> ^(NODE_HELP NODE_ADD_KEYSPACE)
+ | K_HELP K_CREATE K_COLUMN K_FAMILY -> ^(NODE_HELP NODE_ADD_COLUMN_FAMILY)
+ | K_HELP K_DROP K_TABLE -> ^(NODE_HELP NODE_DEL_KEYSPACE)
+ | K_HELP K_DROP K_COLUMN K_FAMILY -> ^(NODE_HELP NODE_DEL_COLUMN_FAMILY)
+ | K_HELP K_RENAME K_TABLE -> ^(NODE_HELP NODE_RENAME_KEYSPACE)
+ | K_HELP K_RENAME K_COLUMN K_FAMILY -> ^(NODE_HELP NODE_RENAME_COLUMN_FAMILY)
+ | K_HELP K_GET -> ^(NODE_HELP NODE_THRIFT_GET)
+ | K_HELP K_SET -> ^(NODE_HELP NODE_THRIFT_SET)
+ | K_HELP K_DEL -> ^(NODE_HELP NODE_THRIFT_DEL)
+ | K_HELP K_COUNT -> ^(NODE_HELP NODE_THRIFT_COUNT)
+ | K_HELP -> ^(NODE_HELP)
| '?' -> ^(NODE_HELP)
;
@@ -123,6 +156,31 @@ showClusterName
: K_SHOW K_CLUSTER K_NAME -> ^(NODE_SHOW_CLUSTER_NAME)
;
+addKeyspace
+ : K_CREATE K_TABLE keyValuePairExpr -> ^(NODE_ADD_KEYSPACE keyValuePairExpr)
+ ;
+
+addColumnFamily
+ : K_CREATE K_COLUMN K_FAMILY keyValuePairExpr -> ^(NODE_ADD_COLUMN_FAMILY keyValuePairExpr)
+ ;
+
+delKeyspace
+ : K_DROP K_TABLE keyspace -> ^(NODE_DEL_KEYSPACE keyspace)
+ ;
+
+delColumnFamily
+ : K_DROP K_COLUMN K_FAMILY columnFamily -> ^(NODE_DEL_COLUMN_FAMILY columnFamily)
+ ;
+
+renameKeyspace
+ : K_RENAME K_TABLE keyspace keyspaceNewName -> ^(NODE_RENAME_KEYSPACE keyspace keyspaceNewName)
+ ;
+
+renameColumnFamily
+ : K_RENAME K_COLUMN K_FAMILY columnFamily newColumnFamily -> ^(NODE_RENAME_COLUMN_FAMILY columnFamily newColumnFamily)
+ ;
+
+
showVersion
: K_SHOW K_VERSION -> ^(NODE_SHOW_VERSION)
;
@@ -137,6 +195,13 @@ describeTable
useTable
: K_USE table ( username )? ( password )? -> ^(NODE_USE_TABLE table ( username )? ( password )?);
+
+keyValuePairExpr
+ : objectName
+ ( (K_AND|K_WITH) a+=attname '=' b+=attvaluestring)*
+ ( (K_AND|K_WITH) c+=attname '=' d+=attvalueint)*
+ -> ^(NODE_NEW_KEYSPACE_ACCESS objectName ($a $b)* ($c $d)*);
+
columnFamilyExpr
: columnFamily '[' rowKey ']'
( '[' a+=columnOrSuperColumn ']'
@@ -147,6 +212,30 @@ columnFamilyExpr
table: Identifier;
+columnName: Identifier;
+
+attname: Identifier;
+
+attvaluestring: StringLiteral;
+
+attvalueint: IntegerLiteral;
+
+objectName: Identifier;
+
+keyspace: Identifier;
+
+replica_placement_strategy: StringLiteral;
+
+replication_factor: IntegerLiteral;
+
+keyspaceNewName: Identifier;
+
+comparator: StringLiteral;
+
+command: Identifier;
+
+newColumnFamily: Identifier;
+
username: Identifier;
password: StringLiteral;
@@ -193,6 +282,13 @@ K_SHOW: 'SHOW';
K_TABLE: 'KEYSPACE';
K_TABLES: 'KEYSPACES';
K_VERSION: 'API VERSION';
+K_CREATE: 'CREATE';
+K_DROP: 'DROP';
+K_RENAME: 'RENAME';
+K_COLUMN: 'COLUMN';
+K_FAMILY: 'FAMILY';
+K_WITH: 'WITH';
+K_AND: 'AND';
// private syntactic rules
fragment
Modified: cassandra/trunk/src/java/org/apache/cassandra/cli/CliClient.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cli/CliClient.java?rev=980558&r1=980557&r2=980558&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cli/CliClient.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cli/CliClient.java Thu Jul 29 20:22:08 2010
@@ -35,6 +35,33 @@ import org.apache.commons.lang.ArrayUtil
// Cli Client Side Library
public class CliClient
{
+
+ /*
+ * the <i>add column family</i> command requires a list of arguments,
+ * this enum defines which arguments are valid.
+ */
+ private enum AddColumnFamilyArgument {
+ COLUMN_TYPE,
+ CLOCK_TYPE,
+ COMPARATOR,
+ SUBCOMPARATOR,
+ RECONCILER,
+ COMMENT,
+ ROWS_CACHED,
+ PRELOAD_ROW_CACHE,
+ KEY_CACHE_SIZE,
+ READ_REPAIR_CHANCE
+ }
+
+ /*
+ * the <i>add keyspace</i> command requires a list of arguments,
+ * this enum defines which arguments are valid
+ */
+ private enum AddKeyspaceArgument {
+ REPLICATION_FACTOR,
+ PLACEMENT_STRATEGY
+ }
+
private Cassandra.Client thriftClient_ = null;
private CliSessionState css_ = null;
private String keySpace = null;
@@ -64,7 +91,7 @@ public class CliClient
executeGet(ast);
break;
case CliParser.NODE_HELP:
- printCmdHelp();
+ printCmdHelp(ast);
break;
case CliParser.NODE_THRIFT_SET:
executeSet(ast);
@@ -75,6 +102,24 @@ public class CliClient
case CliParser.NODE_THRIFT_COUNT:
executeCount(ast);
break;
+ case CliParser.NODE_ADD_COLUMN_FAMILY:
+ executeAddColumnFamily(ast);
+ break;
+ case CliParser.NODE_ADD_KEYSPACE:
+ executeAddKeyspace(ast);
+ break;
+ case CliParser.NODE_DEL_COLUMN_FAMILY:
+ executeDelColumnFamily(ast);
+ break;
+ case CliParser.NODE_DEL_KEYSPACE:
+ executeDelKeyspace(ast);
+ break;
+ case CliParser.NODE_RENAME_COLUMN_FAMILY:
+ executeRenameColumnFamily(ast);
+ break;
+ case CliParser.NODE_RENAME_KEYSPACE:
+ executeRenameKeyspace(ast);
+ break;
case CliParser.NODE_SHOW_CLUSTER_NAME:
executeShowClusterName();
break;
@@ -106,32 +151,260 @@ public class CliClient
throw new RuntimeException("Unable to encode string as UTF-8", e);
}
}
-
- private void printCmdHelp()
+
+ private void printCmdHelp(CommonTree ast)
{
- css_.out.println("List of all CLI commands:");
- css_.out.println("? Same as help.");
- css_.out.println("help Display this help.");
- css_.out.println("connect <hostname>/<port> Connect to thrift service.");
- css_.out.println("use <keyspace> Switch to a specific keyspace.");
- css_.out.println("use <keyspace> <username> 'password' Switch to privileged keyspace.");
- css_.out.println("describe keyspace <keyspacename> Describe keyspace.");
- css_.out.println("exit Exit CLI.");
- css_.out.println("quit Exit CLI.");
- css_.out.println("show cluster name Display cluster name.");
- css_.out.println("show keyspaces Show list of keyspaces.");
- css_.out.println("show api version Show server API version.");
- css_.out.println("get <cf>['<key>'] Get a slice of columns.");
- css_.out.println("get <cf>['<key>']['<super>'] Get a slice of sub columns.");
- css_.out.println("get <cf>['<key>']['<col>'] Get a column value.");
- css_.out.println("get <cf>['<key>']['<super>']['<col>'] Get a sub column value.");
- css_.out.println("set <cf>['<key>']['<col>'] = '<value>' Set a column.");
- css_.out.println("set <cf>['<key>']['<super>']['<col>'] = '<value>' Set a sub column.");
- css_.out.println("del <cf>['<key>'] Delete record.");
- css_.out.println("del <cf>['<key>']['<col>'] Delete column.");
- css_.out.println("del <cf>['<key>']['<super>']['<col>'] Delete sub column.");
- css_.out.println("count <cf>['<key>'] Count columns in record.");
- css_.out.println("count <cf>['<key>']['<super>'] Count columns in a super column.");
+
+ if(ast.getChildCount() > 0) {
+ int helpType = ast.getChild(0).getType();
+
+ switch(helpType)
+ {
+ case CliParser.NODE_HELP:
+ css_.out.println("help <command>");
+ css_.out.println("");
+ css_.out.println("Display the general help page with a list of available commands.");
+ break;
+ case CliParser.NODE_CONNECT:
+ css_.out.println("connect <hostname>/<port>");
+ css_.out.println("");
+ css_.out.println("connect to the specified host name on the specified port. ");
+ css_.out.println("");
+ css_.out.println("eg:");
+ css_.out.println("connect localhost/9160");
+ break;
+
+ case CliParser.NODE_USE_TABLE:
+ css_.out.println("use <keyspace>");
+ css_.out.println("use <keyspace> <username> '<password>'");
+ css_.out.println("");
+ css_.out.println("Authenticated to and use the specified keyspace. Username and password fields");
+ css_.out.println(" are optional.");
+ css_.out.println("");
+ break;
+
+ case CliParser.NODE_DESCRIBE_TABLE:
+ css_.out.println("describe keyspace <keyspace>");
+ css_.out.println("");
+ css_.out.println("Show additional information about the specified keyspace.");
+ css_.out.println("eg:");
+ css_.out.println("describe keyspace system");
+ break;
+
+ case CliParser.NODE_EXIT:
+ css_.out.println("exit");
+ css_.out.println("quit");
+ css_.out.println("");
+ css_.out.println("Exit this utility.");
+ break;
+
+ case CliParser.NODE_SHOW_CLUSTER_NAME:
+ css_.out.println("show cluster name");
+ css_.out.println("");
+ css_.out.println("Displays the name of the currently connected cluster.");
+ break;
+
+ case CliParser.NODE_SHOW_VERSION:
+ css_.out.println("show api version");
+ css_.out.println("");
+ css_.out.println("Displays the api version number.");
+ break;
+
+ case CliParser.NODE_SHOW_TABLES:
+ css_.out.println("show keyspaces");
+ css_.out.println("");
+ css_.out.println("Displays a list of the keyspaces available on the currently connected cluster.");
+ break;
+
+ case CliParser.NODE_ADD_KEYSPACE:
+ css_.out.println("create keyspace <keyspace>");
+ css_.out.println("create keyspace <keyspace> with <att1>=<value1>");
+ css_.out.println("create keyspace <keyspace> with <att1>=<value1> and <att2>=<value2> ...");
+ css_.out.println("");
+ css_.out.println("Create a new keyspace with the specified values for the given set of attributes.");
+ css_.out.println("");
+ css_.out.println("valid attributes are:");
+ css_.out.println(" replication_factor: to how many nodes should entries to this keyspace be");
+ css_.out.println(" replicated. Valid entries are all integers greater than 0.");
+ css_.out.println(" placement_strategy: the fully qualified class responsible for determining");
+ css_.out.println(" the replication of entries in this keyspace. ");
+ css_.out.println(" valid values for this attribute are:");
+ css_.out.println(" org.apache.cassandra.locator.RackUnawareStrategy");
+ css_.out.println(" org.apache.cassandra.locator.DatacenterShardStrategy");
+ css_.out.println(" org.apache.cassandra.locator.RackAwareStrategy");
+ css_.out.println("");
+ css_.out.println(" example:");
+ css_.out.println(" create keyspace foo with");
+ css_.out.println(" placement_strategy = 'org.apache.cassandra.locator.RackUnawareStrategy'");
+ css_.out.println(" and replication_factor = 3");
+ break;
+
+ case CliParser.NODE_ADD_COLUMN_FAMILY:
+ css_.out.println("create column family Bar");
+ css_.out.println("create column family Bar with <att1>=<value1>");
+ css_.out.println("create column family Bar with <att1>=<value1> and <att2>=<value2>...");
+ css_.out.println("");
+ css_.out.println("Create a new column family with the specified values for the given set of");
+ css_.out.println(" attributes. Note that you must be using a keyspace.");
+ css_.out.println("");
+ css_.out.println("valid attributes are:");
+ css_.out.println(" column_type: should this be Super or Standard");
+ css_.out.println(" clock_type: Timestamp");
+ css_.out.println(" comparator: This is the class that determins how ");
+ css_.out.println(" valid values for this attribute are:");
+ css_.out.println(" AsciiType, BytesType, LexicalUUIDType, Long, TimeUUID, UTF8Type");
+ css_.out.println(" subcomparator: Name of comparator used for subcolumns (when");
+ css_.out.println(" column_type=Super only)");
+ css_.out.println(" all comparator values are valid values for this attribute as well.");
+ css_.out.println(" reconciler: reconciler class decides what to do with two conflicting");
+ css_.out.println(" versions of a column by comparing them in a clock specific manner.");
+ css_.out.println(" Timestamp is the only valid value for this");
+ css_.out.println(" comment: Human-readable description of column family. Any string is valid.");
+ css_.out.println(" rows_cached: number of rows to cache");
+ css_.out.println(" preload_row_cache: Set to true to automatically load the row cache");
+ css_.out.println(" key_cache_size: Number of keys to cache");
+ css_.out.println(" read_repair_chance: valid values for this attribute are any number between");
+ css_.out.println(" 0.0 and 1.0");
+ css_.out.println("");
+ css_.out.println("eg:");
+ css_.out.println("");
+ css_.out.println("create column family bar with column_type = 'Super' and comparator = 'AsciiType'");
+ css_.out.println(" and rows_cached = 10000");
+ css_.out.println("create column family baz with comparator = 'LongType' and rows_cached = 10000");
+ break;
+
+ case CliParser.NODE_RENAME_KEYSPACE:
+ css_.out.println("rename keyspace <old_name> <new_name>");
+ css_.out.println("");
+ css_.out.println("Renames the specified keyspace with the given new name.");
+ css_.out.println("");
+ css_.out.println("eg:");
+ css_.out.println("rename keyspace foo bar");
+ break;
+
+ case CliParser.NODE_RENAME_COLUMN_FAMILY:
+ css_.out.println("rename column family <name> <new_name>");
+ css_.out.println("");
+ css_.out.println("Renames the specified column family with the given new name.");
+ css_.out.println("");
+ css_.out.println("eg:");
+ css_.out.println("rename column family foo bar");
+ break;
+
+ case CliParser.NODE_DEL_KEYSPACE:
+ css_.out.println("drop keyspace <keyspace>");
+ css_.out.println("");
+ css_.out.println("Drops the specified keyspace.");
+ css_.out.println("");
+ css_.out.println("eg:");
+ css_.out.println("drop keyspace foo");
+ break;
+
+ case CliParser.NODE_DEL_COLUMN_FAMILY:
+ css_.out.println("drop column family <name>");
+ css_.out.println("");
+ css_.out.println("Drops the specified column family.");
+ css_.out.println("");
+ css_.out.println("eg:");
+ css_.out.println("drop column family foo");
+ break;
+
+ case CliParser.NODE_THRIFT_GET :
+ css_.out.println("get <cf>['<key>']");
+ css_.out.println("get <cf>['<key>']['<col>'] ");
+ css_.out.println("get <cf>['<key>']['<super>'] ");
+ css_.out.println("get <cf>['<key>']['<super>']['<col>'] ");
+ css_.out.println("");
+ css_.out.println("eg:");
+ css_.out.println("get bar['testkey']");
+ break;
+
+ case CliParser.NODE_THRIFT_SET:
+ css_.out.println("set <cf>['<key>']['<col>'] = '<value>' ");
+ css_.out.println("set <cf>['<key>']['<super>']['<col>'] = '<value>' ");
+ css_.out.println("");
+ css_.out.println("");
+ css_.out.println("");
+ css_.out.println("eg:");
+ css_.out.println("");
+ css_.out.println("set bar['testkey']['my super']['test col']='this is a test'");
+ css_.out.println("set baz['testkey']['test col']='this is also a test'");
+ break;
+
+ case CliParser.NODE_THRIFT_DEL:
+ css_.out.println("del <cf>['<key>'] ");
+ css_.out.println("del <cf>['<key>']['<col>'] ");
+ css_.out.println("del <cf>['<key>']['<super>']['<col>'] ");
+ css_.out.println("");
+ css_.out.println("Deletes a record, a column, or a subcolumn.");
+ css_.out.println("");
+ css_.out.println("eg:");
+ css_.out.println("");
+ css_.out.println("del bar['testkey']['my super']['test col']");
+ css_.out.println("del baz['testkey']['test col']");
+ css_.out.println("del baz['testkey']");
+ break;
+
+ case CliParser.NODE_THRIFT_COUNT:
+ css_.out.println("count <cf>['<key>']");
+ css_.out.println("count <cf>['<key>']['<super>'] ");
+ css_.out.println("");
+ css_.out.println("Count the number of columns in the specified key or subcolumns in the specified");
+ css_.out.println(" super column.");
+ css_.out.println("");
+ css_.out.println("eg:");
+ css_.out.println("");
+ css_.out.println("count bar['testkey']['my super']");
+ css_.out.println("count baz['testkey']");
+ break;
+
+ default:
+ css_.out.println("?");
+ break;
+ }
+ }
+ else
+ {
+ css_.out.println("List of all CLI commands:");
+ css_.out.println("? Display this message.");
+ css_.out.println("help Display this help.");
+ css_.out.println("help <command> Displays a detailed help message for the specified command.");
+ css_.out.println("connect <hostname>/<port> Connect to thrift service.");
+ css_.out.println("use <keyspace> Switch to a specific keyspace.");
+ css_.out.println("use <keyspace> <username> 'password' Switch to privileged keyspace.");
+ css_.out.println("describe keyspace <keyspacename> Describe keyspace.");
+ css_.out.println("exit Exit CLI.");
+ css_.out.println("quit Exit CLI.");
+ css_.out.println("show cluster name Display cluster name.");
+ css_.out.println("show keyspaces Show list of keyspaces.");
+ css_.out.println("show api version Show server API version.");
+ css_.out.println("create keyspace <keyspace> Add a new keyspace.");
+ css_.out.println("create keyspace <keyspace> with <att1>=<value1> ");
+ css_.out.println(" Add a new keyspace with the specified attribute and value.\n");
+ css_.out.println("create keyspace <keyspace> with <att1>=<value1> and <att2>=<value2> ... ");
+ css_.out.println(" Add a new keyspace with the specified attributes and values.\n");
+ css_.out.println("create column family <cf> Create a new column family.");
+ css_.out.println("create column family <cf> with <att1>=<value1> Create a new column ");
+ css_.out.println(" family with the specified attribute and value.\n");
+ css_.out.println("create column family <cf> with <att1>=<value1> and <att2>=<value2> ... ");
+ css_.out.println(" Create a new column family with the spcified attributes and values.\n");
+ css_.out.println("drop keyspace <keyspace> Delete a keyspace.");
+ css_.out.println("drop column family <cf> Delete a column family.");
+ css_.out.println("rename keyspace <keyspace> <keyspace_new_name> Rename a keyspace.");
+ css_.out.println("rename column family <cf> <new_name> Rename a column family.");
+ css_.out.println("get <cf>['<key>'] Get a slice of columns.");
+ css_.out.println("get <cf>['<key>']['<super>'] Get a slice of sub columns.");
+ css_.out.println("get <cf>['<key>']['<col>'] Get a column value.");
+ css_.out.println("get <cf>['<key>']['<super>']['<col>'] Get a sub column value.");
+ css_.out.println("set <cf>['<key>']['<col>'] = '<value>' Set a column.");
+ css_.out.println("set <cf>['<key>']['<super>']['<col>'] = '<value>' Set a sub column.");
+ css_.out.println("del <cf>['<key>'] Delete record.");
+ css_.out.println("del <cf>['<key>']['<col>'] Delete column.");
+ css_.out.println("del <cf>['<key>']['<super>']['<col>'] Delete sub column.");
+ css_.out.println("count <cf>['<key>'] Count columns in record.");
+ css_.out.println("count <cf>['<key>']['<super>'] Count columns in a super column.");
+ return;
+ }
}
private void cleanupAndExit()
@@ -421,7 +694,215 @@ public class CliClient
return;
css_.out.println(thriftClient_.describe_cluster_name());
}
-
+
+ /**
+ * Add a keyspace
+ * @throws TException
+ * @throws InvalidRequestException
+ * @throws NotFoundException
+ */
+ private void executeAddKeyspace(CommonTree ast) throws TException, InvalidRequestException, NotFoundException
+ {
+
+ if (!CliMain.isConnected())
+ {
+ return;
+ }
+ CommonTree newKSSpec = (CommonTree)ast.getChild(0);
+
+ //parser send the keyspace, plus a series of key value pairs, ie should always be an odd number...
+ assert(newKSSpec.getChildCount() > 0);
+ assert(newKSSpec.getChildCount() % 2 == 1);
+
+ //defaults
+ String replicaPlacementStrategy = "org.apache.cassandra.locator.RackUnawareStrategy";
+ int replicationFactor = 2;
+
+ /*
+ * first value is the keyspace name, after that it is all key=value
+ */
+ String keyspaceName = newKSSpec.getChild(0).getText();
+ int argumentLength = newKSSpec.getChildCount();
+
+ for(int i = 1; i < argumentLength; i = i + 2)
+ {
+ AddKeyspaceArgument mArgument = AddKeyspaceArgument.valueOf(newKSSpec.getChild(i).getText().toUpperCase());
+ String mValue = newKSSpec.getChild(i + 1).getText();
+
+ switch(mArgument)
+ {
+ case PLACEMENT_STRATEGY:
+ replicaPlacementStrategy = CliUtils.unescapeSQLString(mValue);
+ break;
+ case REPLICATION_FACTOR:
+ replicationFactor = Integer.parseInt( mValue);
+ break;
+ default:
+ //must match one of the above or we'd throw an exception at the valueOf statement above.
+ assert(false);
+ }
+ }
+ List<CfDef> mList = new LinkedList<CfDef>();
+ KsDef ks_def = new KsDef(keyspaceName, replicaPlacementStrategy, replicationFactor, mList);
+ css_.out.println(thriftClient_.system_add_keyspace(ks_def));
+
+ keyspacesMap.put(keyspaceName, thriftClient_.describe_keyspace(keyspaceName));
+ }
+
+
+ /**
+ * Add a column family
+ * @throws TException
+ * @throws InvalidRequestException
+ * @throws NotFoundException
+ */
+ private void executeAddColumnFamily(CommonTree ast) throws TException, InvalidRequestException, NotFoundException
+ {
+ if (!CliMain.isConnected() || !hasKeySpace())
+ {
+ return;
+ }
+ CommonTree newCFTree = (CommonTree)ast.getChild(0);
+ //parser send the keyspace, plus a series of key value pairs, ie should always be an odd number...
+ assert(newCFTree.getChildCount() > 0);
+ assert(newCFTree.getChildCount() % 2 == 1);
+
+
+ /*
+ * first value is the keyspace name, after that it is all key=value
+ */
+ String columnName = newCFTree.getChild(0).getText();
+ int argumentLength = newCFTree.getChildCount();
+ CfDef cfDef = new CfDef(keySpace, columnName);
+
+ for(int i = 1; i < argumentLength; i = i + 2)
+ {
+ AddColumnFamilyArgument mArgument = AddColumnFamilyArgument.valueOf(newCFTree.getChild(i).getText().toUpperCase());
+ String mValue = newCFTree.getChild(i + 1).getText();
+
+
+ switch(mArgument)
+ {
+ case COLUMN_TYPE:
+ cfDef.setColumn_type(CliUtils.unescapeSQLString(mValue));
+ break;
+
+ case CLOCK_TYPE:
+ cfDef.setClock_type(CliUtils.unescapeSQLString(mValue));
+ break;
+
+ case COMPARATOR:
+ cfDef.setComparator_type(CliUtils.unescapeSQLString(mValue));
+ break;
+
+ case SUBCOMPARATOR:
+ cfDef.setSubcomparator_type(CliUtils.unescapeSQLString(mValue));
+ break;
+
+ case RECONCILER:
+ cfDef.setReconciler(CliUtils.unescapeSQLString(mValue));
+ break;
+
+ case COMMENT:
+ cfDef.setComment(CliUtils.unescapeSQLString(mValue));
+ break;
+
+ case ROWS_CACHED:
+ cfDef.setRow_cache_size(Double.parseDouble(mValue));
+ break;
+
+ case PRELOAD_ROW_CACHE:
+ cfDef.setPreload_row_cache(Boolean.parseBoolean(CliUtils.unescapeSQLString(mValue)));
+ break;
+
+ case KEY_CACHE_SIZE:
+ cfDef.setKey_cache_size(Double.parseDouble(mValue));
+ break;
+
+ case READ_REPAIR_CHANCE:
+ cfDef.setKey_cache_size(Double.parseDouble(CliUtils.unescapeSQLString(mValue)));
+ break;
+
+ default:
+ //must match one of the above or we'd throw an exception at the valueOf statement above.
+ assert(false);
+
+ }
+ }
+ css_.out.println(thriftClient_.system_add_column_family(cfDef));
+ keyspacesMap.put(keySpace, thriftClient_.describe_keyspace(keySpace));
+ }
+
+ /**
+ * Delete a keyspace
+ * @throws TException
+ * @throws InvalidRequestException
+ * @throws NotFoundException
+ */
+ private void executeDelKeyspace(CommonTree ast) throws TException, InvalidRequestException, NotFoundException
+ {
+ if (!CliMain.isConnected())
+ {
+ return;
+ }
+
+ String keyspaceName = ast.getChild(0).getText();
+
+ css_.out.println(thriftClient_.system_drop_keyspace(keyspaceName));
+ }
+
+ /**
+ * Delete a column family
+ * @throws TException
+ * @throws InvalidRequestException
+ * @throws NotFoundException
+ */
+ private void executeDelColumnFamily(CommonTree ast) throws TException, InvalidRequestException, NotFoundException
+ {
+ if (!CliMain.isConnected() || !hasKeySpace())
+ {
+ return;
+ }
+ String columnName = ast.getChild(0).getText();
+ css_.out.println(thriftClient_.system_drop_column_family(columnName));
+ }
+
+ /**
+ * Add a column family
+ * @throws TException
+ * @throws InvalidRequestException
+ * @throws NotFoundException
+ */
+ private void executeRenameKeyspace(CommonTree ast) throws TException, InvalidRequestException, NotFoundException
+ {
+ if (!CliMain.isConnected())
+ {
+ return;
+ }
+ String keyspaceName = ast.getChild(0).getText();
+ String keyspaceNewName = ast.getChild(1).getText();
+
+ css_.out.println(thriftClient_.system_rename_keyspace(keyspaceName, keyspaceNewName));
+ }
+
+ /**
+ * Add a column family
+ * @throws TException
+ * @throws InvalidRequestException
+ * @throws NotFoundException
+ */
+ private void executeRenameColumnFamily(CommonTree ast) throws TException, InvalidRequestException, NotFoundException
+ {
+ if (!CliMain.isConnected() || !hasKeySpace())
+ {
+ return;
+ }
+ String columnName = ast.getChild(0).getText();
+ String columnNewName = ast.getChild(1).getText();
+
+ css_.out.println(thriftClient_.system_rename_column_family(columnName, columnNewName));
+ }
+
private void executeShowVersion() throws TException
{
if (!CliMain.isConnected())
@@ -573,22 +1054,29 @@ public class CliClient
}
// Describe and display
+ css_.out.println("Keyspace: " + tableName);
+
Map<String, Map<String, String>> columnFamiliesMap;
- try {
+ try
+ {
columnFamiliesMap = thriftClient_.describe_keyspace(tableName);
- for (String columnFamilyName: columnFamiliesMap.keySet()) {
+ for (String columnFamilyName: columnFamiliesMap.keySet())
+ {
Map<String, String> columnMap = columnFamiliesMap.get(columnFamilyName);
String desc = columnMap.get("Desc");
String columnFamilyType = columnMap.get("Type");
String sort = columnMap.get("CompareWith");
String flushperiod = columnMap.get("FlushPeriodInMinutes");
css_.out.println(desc);
+ css_.out.println("Column Family Name: " + columnFamilyName);
css_.out.println("Column Family Type: " + columnFamilyType);
css_.out.println("Column Sorted By: " + sort);
css_.out.println("flush period: " + flushperiod + " minutes");
css_.out.println("------");
}
- } catch (NotFoundException e) {
+ }
+ catch (NotFoundException e)
+ {
css_.out.println("Keyspace " + tableName + " could not be found.");
}
}
Modified: cassandra/trunk/src/java/org/apache/cassandra/cli/CliCompleter.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cli/CliCompleter.java?rev=980558&r1=980557&r2=980558&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cli/CliCompleter.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cli/CliCompleter.java Thu Jul 29 20:22:08 2010
@@ -30,6 +30,31 @@ public class CliCompleter extends Simple
"show cluster name",
"show keyspaces",
"show api version",
+ "create keyspace",
+ "create column family",
+ "drop keyspace",
+ "drop column family",
+ "rename keyspace",
+ "rename column family",
+
+ "help connect",
+ "help describe keyspace",
+ "help exit",
+ "help help",
+ "help quit",
+ "help show cluster name",
+ "help show keyspaces",
+ "help show api version",
+ "help create keyspace",
+ "help create column family",
+ "help drop keyspace",
+ "help drop column family",
+ "help rename keyspace",
+ "help rename column family",
+ "help get",
+ "help set",
+ "help del",
+ "help count",
};
private static String[] keyspaceCommands = {
"get",
Modified: cassandra/trunk/src/java/org/apache/cassandra/cli/CliMain.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cli/CliMain.java?rev=980558&r1=980557&r2=980558&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cli/CliMain.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cli/CliMain.java Thu Jul 29 20:22:08 2010
@@ -80,7 +80,7 @@ public class CliMain
transport_ = socket;
}
- TBinaryProtocol binaryProtocol = new TBinaryProtocol(transport_);
+ TBinaryProtocol binaryProtocol = new TBinaryProtocol(transport_, true, true);
Cassandra.Client cassandraClient = new Cassandra.Client(binaryProtocol);
try
Modified: cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java?rev=980558&r1=980557&r2=980558&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java Thu Jul 29 20:22:08 2010
@@ -917,7 +917,11 @@ public class CassandraServer implements
public String system_drop_keyspace(String keyspace) throws InvalidRequestException, TException
{
- checkKeyspaceAndLoginAuthorized(AccessLevel.FULL);
+ // IAuthenticator was devised prior to, and without thought for, dynamic keyspace creation. As
+ // a result, we must choose between letting anyone/everyone create keyspaces (which they likely
+ // won't even be able to use), or be honest and disallow it entirely if configured for auth.
+ if (!(DatabaseDescriptor.getAuthenticator() instanceof AllowAllAuthenticator))
+ throw new InvalidRequestException("Unable to create new keyspace while authentication is enabled.");
try
{