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
         {