Return-Path: Delivered-To: apmail-cassandra-commits-archive@www.apache.org Received: (qmail 26120 invoked from network); 29 Jul 2010 20:23:32 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 29 Jul 2010 20:23:32 -0000 Received: (qmail 51633 invoked by uid 500); 29 Jul 2010 20:23:32 -0000 Delivered-To: apmail-cassandra-commits-archive@cassandra.apache.org Received: (qmail 51609 invoked by uid 500); 29 Jul 2010 20:23:32 -0000 Mailing-List: contact commits-help@cassandra.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cassandra.apache.org Delivered-To: mailing list commits@cassandra.apache.org Received: (qmail 51589 invoked by uid 99); 29 Jul 2010 20:23:31 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 29 Jul 2010 20:23:31 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 29 Jul 2010 20:23:26 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 7C34623889B3; Thu, 29 Jul 2010 20:22:09 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 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 Date: Thu, 29 Jul 2010 20:22:09 -0000 To: commits@cassandra.apache.org From: eevans@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100729202209.7C34623889B3@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 add column family 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 add keyspace 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 / Connect to thrift service."); - css_.out.println("use Switch to a specific keyspace."); - css_.out.println("use 'password' Switch to privileged keyspace."); - css_.out.println("describe keyspace 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 [''] Get a slice of columns."); - css_.out.println("get [''][''] Get a slice of sub columns."); - css_.out.println("get [''][''] Get a column value."); - css_.out.println("get [''][''][''] Get a sub column value."); - css_.out.println("set [''][''] = '' Set a column."); - css_.out.println("set [''][''][''] = '' Set a sub column."); - css_.out.println("del [''] Delete record."); - css_.out.println("del [''][''] Delete column."); - css_.out.println("del [''][''][''] Delete sub column."); - css_.out.println("count [''] Count columns in record."); - css_.out.println("count [''][''] 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 "); + 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 /"); + 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 "); + css_.out.println("use ''"); + 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 "); + 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 "); + css_.out.println("create keyspace with ="); + css_.out.println("create keyspace with = and = ..."); + 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 ="); + css_.out.println("create column family Bar with = and =..."); + 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 "); + 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 "); + 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 "); + 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 "); + 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 ['']"); + css_.out.println("get [''][''] "); + css_.out.println("get [''][''] "); + css_.out.println("get [''][''][''] "); + css_.out.println(""); + css_.out.println("eg:"); + css_.out.println("get bar['testkey']"); + break; + + case CliParser.NODE_THRIFT_SET: + css_.out.println("set [''][''] = '' "); + css_.out.println("set [''][''][''] = '' "); + 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 [''] "); + css_.out.println("del [''][''] "); + css_.out.println("del [''][''][''] "); + 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 ['']"); + css_.out.println("count [''][''] "); + 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 Displays a detailed help message for the specified command."); + css_.out.println("connect / Connect to thrift service."); + css_.out.println("use Switch to a specific keyspace."); + css_.out.println("use 'password' Switch to privileged keyspace."); + css_.out.println("describe keyspace 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 Add a new keyspace."); + css_.out.println("create keyspace with = "); + css_.out.println(" Add a new keyspace with the specified attribute and value.\n"); + css_.out.println("create keyspace with = and = ... "); + css_.out.println(" Add a new keyspace with the specified attributes and values.\n"); + css_.out.println("create column family Create a new column family."); + css_.out.println("create column family with = Create a new column "); + css_.out.println(" family with the specified attribute and value.\n"); + css_.out.println("create column family with = and = ... "); + css_.out.println(" Create a new column family with the spcified attributes and values.\n"); + css_.out.println("drop keyspace Delete a keyspace."); + css_.out.println("drop column family Delete a column family."); + css_.out.println("rename keyspace Rename a keyspace."); + css_.out.println("rename column family Rename a column family."); + css_.out.println("get [''] Get a slice of columns."); + css_.out.println("get [''][''] Get a slice of sub columns."); + css_.out.println("get [''][''] Get a column value."); + css_.out.println("get [''][''][''] Get a sub column value."); + css_.out.println("set [''][''] = '' Set a column."); + css_.out.println("set [''][''][''] = '' Set a sub column."); + css_.out.println("del [''] Delete record."); + css_.out.println("del [''][''] Delete column."); + css_.out.println("del [''][''][''] Delete sub column."); + css_.out.println("count [''] Count columns in record."); + css_.out.println("count [''][''] 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 mList = new LinkedList(); + 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> columnFamiliesMap; - try { + try + { columnFamiliesMap = thriftClient_.describe_keyspace(tableName); - for (String columnFamilyName: columnFamiliesMap.keySet()) { + for (String columnFamilyName: columnFamiliesMap.keySet()) + { Map 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 {