Author: eevans
Date: Mon Apr 26 18:19:04 2010
New Revision: 938172

URL: http://svn.apache.org/viewvc?rev=938172&view=rev
Log:
update cassandra-cli for mandatory login()

Patch by Todd Blose; reviewed by eevans for CASSANDRA-859

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/CliCompiler.java
    cassandra/trunk/src/java/org/apache/cassandra/cli/CliMain.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=938172&r1=938171&r2=938172&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cli/Cli.g (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cli/Cli.g Mon Apr 26 18:19:04 
2010
@@ -36,6 +36,7 @@ tokens {
     //
     NODE_CONNECT;
     NODE_DESCRIBE_TABLE;
+    NODE_USE_TABLE;
     NODE_EXIT;
     NODE_HELP;
     NODE_NO_OP;
@@ -72,6 +73,7 @@ stmt
     | exitStmt
     | countStmt
     | describeTable
+    | useTable
     | delStmt
     | getStmt
     | helpStmt
@@ -131,17 +133,24 @@ showTables
 
 describeTable
     : K_DESCRIBE K_TABLE table -> ^(NODE_DESCRIBE_TABLE table);
+    
+useTable
+    : K_USE table ( username )? ( password )? -> ^(NODE_USE_TABLE table ( 
username )? ( password )?);
 
 columnFamilyExpr
-    : table DOT columnFamily '[' rowKey ']' 
+    : columnFamily '[' rowKey ']' 
         ( '[' a+=columnOrSuperColumn ']' 
             ('[' a+=columnOrSuperColumn ']')? 
         )?
-      -> ^(NODE_COLUMN_ACCESS table columnFamily rowKey ($a+)?)
+      -> ^(NODE_COLUMN_ACCESS columnFamily rowKey ($a+)?)
     ;
 
 table: Identifier;
 
+username: Identifier;
+
+password: StringLiteral;
+
 columnFamily: Identifier;
 
 rowKey:   StringLiteral;
@@ -172,6 +181,7 @@ K_COUNT:      'COUNT';
 K_CLUSTER:    'CLUSTER';
 K_DEL:        'DEL';
 K_DESCRIBE:   'DESCRIBE';
+K_USE:        'USE';
 K_GET:        'GET';
 K_HELP:       'HELP';
 K_EXIT:       'EXIT';
@@ -224,7 +234,7 @@ IntegerLiteral
 DOT
     : '.'
     ;
-
+       
 SLASH
     : '/'
     ;

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=938172&r1=938171&r2=938172&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cli/CliClient.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cli/CliClient.java Mon Apr 26 
18:19:04 2010
@@ -17,6 +17,7 @@
  */
 package org.apache.cassandra.cli;
 
+import org.apache.cassandra.auth.SimpleAuthenticator;
 import org.apache.cassandra.db.marshal.AbstractType;
 import org.apache.cassandra.db.marshal.BytesType;
 import org.apache.cassandra.thrift.*;
@@ -34,6 +35,8 @@ public class CliClient 
 {
     private Cassandra.Client thriftClient_ = null;
     private CliSessionState css_ = null;
+    private String keySpace = null;
+    private String username = null;
     private Map<String, Map<String, Map<String, String>>> keyspacesMap = new 
HashMap<String, Map<String,Map<String,String>>>();
 
     public CliClient(CliSessionState css, Cassandra.Client thriftClient)
@@ -82,6 +85,9 @@ public class CliClient 
                 case CliParser.NODE_DESCRIBE_TABLE:
                     executeDescribeTable(ast);
                     break;
+                case CliParser.NODE_USE_TABLE:
+                       executeUseTable(ast);
+                       break;
                 case CliParser.NODE_CONNECT:
                     executeConnect(ast);
                     break;
@@ -105,23 +111,25 @@ public class CliClient 
        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 <ksp>.<cf>['<key>']                               
   Get a slice of columns.");
-       css_.out.println("get <ksp>.<cf>['<key>']['<super>']                   
Get a slice of sub columns.");
-       css_.out.println("get <ksp>.<cf>['<key>']['<col>']                      
       Get a column value.");
-       css_.out.println("get <ksp>.<cf>['<key>']['<super>']['<col>']           
   Get a sub column value.");
-       css_.out.println("set <ksp>.<cf>['<key>']['<col>'] = '<value>'          
             Set a column.");
-       css_.out.println("set <ksp>.<cf>['<key>']['<super>']['<col>'] = 
'<value>'        Set a sub column.");
-       css_.out.println("del <ksp>.<cf>['<key>']                               
            Delete record.");
-       css_.out.println("del <ksp>.<cf>['<key>']['<col>']                      
            Delete column.");
-       css_.out.println("del <ksp>.<cf>['<key>']['<super>']['<col>']           
        Delete sub column.");
-       css_.out.println("count <ksp>.<cf>['<key>']                             
  Count columns in record.");
-       css_.out.println("count <ksp>.<cf>['<key>']['<super>']            Count 
columns in a super column.");
+       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.");
     }
 
     private void cleanupAndExit()
@@ -140,7 +148,7 @@ public class CliClient 
     
     private void executeCount(CommonTree ast) throws TException, 
InvalidRequestException, UnavailableException, TimedOutException, 
UnsupportedEncodingException
     {
-       if (!CliMain.isConnected())
+       if (!CliMain.isConnected() || !hasKeySpace())
            return;
 
        int childCount = ast.getChildCount();
@@ -149,7 +157,6 @@ public class CliClient 
        CommonTree columnFamilySpec = (CommonTree)ast.getChild(0);
        assert(columnFamilySpec.getType() == CliParser.NODE_COLUMN_ACCESS);
 
-       String tableName = CliCompiler.getTableName(columnFamilySpec);
        String key = CliCompiler.getKey(columnFamilySpec);
        String columnFamily = CliCompiler.getColumnFamily(columnFamilySpec);
        int columnSpecCnt = CliCompiler.numColumnSpecifiers(columnFamilySpec);
@@ -169,13 +176,13 @@ public class CliClient 
        SliceRange range = new SliceRange(ArrayUtils.EMPTY_BYTE_ARRAY, 
ArrayUtils.EMPTY_BYTE_ARRAY, false, Integer.MAX_VALUE);
        SlicePredicate predicate = new 
SlicePredicate().setColumn_names(null).setSlice_range(range);
        
-       int count = thriftClient_.get_count(tableName, key.getBytes(), 
colParent, predicate, ConsistencyLevel.ONE);
+       int count = thriftClient_.get_count(key.getBytes(), colParent, 
predicate, ConsistencyLevel.ONE);
        css_.out.printf("%d columns\n", count);
     }
     
     private void executeDelete(CommonTree ast) throws TException, 
InvalidRequestException, UnavailableException, TimedOutException, 
UnsupportedEncodingException
     {
-        if (!CliMain.isConnected())
+        if (!CliMain.isConnected() || !hasKeySpace())
             return;
 
         int childCount = ast.getChildCount();
@@ -184,7 +191,6 @@ public class CliClient 
         CommonTree columnFamilySpec = (CommonTree)ast.getChild(0);
         assert(columnFamilySpec.getType() == CliParser.NODE_COLUMN_ACCESS);
 
-        String tableName = CliCompiler.getTableName(columnFamilySpec);
         String key = CliCompiler.getKey(columnFamilySpec);
         String columnFamily = CliCompiler.getColumnFamily(columnFamilySpec);
         int columnSpecCnt = CliCompiler.numColumnSpecifiers(columnFamilySpec);
@@ -193,21 +199,13 @@ public class CliClient 
         byte[] columnName = null;
         boolean isSuper;
         
-        try
-        {
-            if (!(getCFMetaData(tableName).containsKey(columnFamily)))
-            {
-                css_.out.println("No such column family: " + columnFamily);
-                return;
-            }
-            
-            isSuper = 
getCFMetaData(tableName).get(columnFamily).get("Type").equals("Super") ? true : 
false;
-        }
-        catch (NotFoundException nfe)
+        if (!(keyspacesMap.get(keySpace).containsKey(columnFamily)))
         {
-            css_.out.printf("No such keyspace: %s\n", tableName);
+            css_.out.println("No such column family: " + columnFamily);
             return;
         }
+            
+        isSuper = 
keyspacesMap.get(keySpace).get(columnFamily).get("Type").equals("Super") ? true 
: false;
      
         if ((columnSpecCnt < 0) || (columnSpecCnt > 2))
         {
@@ -230,7 +228,7 @@ public class CliClient 
             columnName = CliCompiler.getColumn(columnFamilySpec, 
1).getBytes("UTF-8");
         }
 
-        thriftClient_.remove(tableName, key.getBytes(), new 
ColumnPath(columnFamily).setSuper_column(superColumnName).setColumn(columnName),
+        thriftClient_.remove(key.getBytes(), new 
ColumnPath(columnFamily).setSuper_column(superColumnName).setColumn(columnName),
                              timestampMicros(), ConsistencyLevel.ONE);
         css_.out.println(String.format("%s removed.", (columnSpecCnt == 0) ? 
"row" : "column"));
     }
@@ -246,7 +244,7 @@ public class CliClient 
             throws InvalidRequestException, UnavailableException, 
TimedOutException, TException, UnsupportedEncodingException, 
IllegalAccessException, NotFoundException, InstantiationException, 
ClassNotFoundException
     {
         SliceRange range = new SliceRange(ArrayUtils.EMPTY_BYTE_ARRAY, 
ArrayUtils.EMPTY_BYTE_ARRAY, true, 1000000);
-        List<ColumnOrSuperColumn> columns = thriftClient_.get_slice(keyspace, 
key.getBytes(),
+        List<ColumnOrSuperColumn> columns = 
thriftClient_.get_slice(key.getBytes(),
                                                                     new 
ColumnParent(columnFamily).setSuper_column(superColumnName),
                                                                     new 
SlicePredicate().setColumn_names(null).setSlice_range(range), 
ConsistencyLevel.ONE);
         int size = columns.size();
@@ -278,17 +276,17 @@ public class CliClient 
  
     private String formatSuperColumnName(String keyspace, String columnFamily, 
SuperColumn column) throws NotFoundException, TException, 
ClassNotFoundException, IllegalAccessException, InstantiationException
     {
-        return 
getFormatTypeForColumn(getCFMetaData(keyspace).get(columnFamily).get("CompareWith")).getString(column.name);
+        return 
getFormatTypeForColumn(keyspacesMap.get(keyspace).get(columnFamily).get("CompareWith")).getString(column.name);
     }
 
     private String formatSubcolumnName(String keyspace, String columnFamily, 
Column subcolumn) throws NotFoundException, TException, ClassNotFoundException, 
IllegalAccessException, InstantiationException
     {
-        return 
getFormatTypeForColumn(getCFMetaData(keyspace).get(columnFamily).get("CompareSubcolumnsWith")).getString(subcolumn.name);
+        return 
getFormatTypeForColumn(keyspacesMap.get(keyspace).get(columnFamily).get("CompareSubcolumnsWith")).getString(subcolumn.name);
     }
 
     private String formatColumnName(String keyspace, String columnFamily, 
Column column) throws ClassNotFoundException, NotFoundException, TException, 
IllegalAccessException, InstantiationException
     {
-        return 
getFormatTypeForColumn(getCFMetaData(keyspace).get(columnFamily).get("CompareWith")).getString(column.name);
+        return 
getFormatTypeForColumn(keyspacesMap.get(keyspace).get(columnFamily).get("CompareWith")).getString(column.name);
     }
 
     private AbstractType getFormatTypeForColumn(String compareWith) throws 
ClassNotFoundException, IllegalAccessException, InstantiationException
@@ -305,7 +303,7 @@ public class CliClient 
     // Execute GET statement
     private void executeGet(CommonTree ast) throws TException, 
NotFoundException, InvalidRequestException, UnavailableException, 
TimedOutException, UnsupportedEncodingException, IllegalAccessException, 
InstantiationException, ClassNotFoundException
     {
-        if (!CliMain.isConnected())
+        if (!CliMain.isConnected() || !hasKeySpace())
             return;
 
         // This will never happen unless the grammar is broken
@@ -314,18 +312,17 @@ public class CliClient 
         CommonTree columnFamilySpec = (CommonTree)ast.getChild(0);
         assert(columnFamilySpec.getType() == CliParser.NODE_COLUMN_ACCESS);
 
-        String tableName = CliCompiler.getTableName(columnFamilySpec);
         String key = CliCompiler.getKey(columnFamilySpec);
         String columnFamily = CliCompiler.getColumnFamily(columnFamilySpec);
         int columnSpecCnt = CliCompiler.numColumnSpecifiers(columnFamilySpec); 
         
-        if (!(getCFMetaData(tableName).containsKey(columnFamily)))
+        if (!(keyspacesMap.get(keySpace).containsKey(columnFamily)))
         {
             css_.out.println("No such column family: " + columnFamily);
             return;
         }
         
-        boolean isSuper = 
getCFMetaData(tableName).get(columnFamily).get("Type").equals("Super") ? true : 
false;
+        boolean isSuper = 
keyspacesMap.get(keySpace).get(columnFamily).get("Type").equals("Super") ? true 
: false;
         
         byte[] superColumnName = null;
         byte[] columnName = null;
@@ -333,7 +330,7 @@ public class CliClient 
         // table.cf['key'] -- row slice
         if (columnSpecCnt == 0)
         {
-            doSlice(tableName, key, columnFamily, superColumnName);
+            doSlice(keySpace, key, columnFamily, superColumnName);
             return;
         }
         
@@ -343,7 +340,7 @@ public class CliClient 
             if (isSuper)
             {
                 superColumnName = CliCompiler.getColumn(columnFamilySpec, 
0).getBytes("UTF-8");
-                doSlice(tableName, key, columnFamily, superColumnName);
+                doSlice(keySpace, key, columnFamily, superColumnName);
                 return;
             }
             else
@@ -366,15 +363,15 @@ public class CliClient 
         
         // Perform a get(), print out the results.
         ColumnPath path = new 
ColumnPath(columnFamily).setSuper_column(superColumnName).setColumn(columnName);
-        Column column = thriftClient_.get(tableName, key.getBytes(), path, 
ConsistencyLevel.ONE).column;
-        css_.out.printf("=> (column=%s, value=%s, timestamp=%d)\n", 
formatColumnName(tableName, columnFamily, column),
+        Column column = thriftClient_.get(key.getBytes(), path, 
ConsistencyLevel.ONE).column;
+        css_.out.printf("=> (column=%s, value=%s, timestamp=%d)\n", 
formatColumnName(keySpace, columnFamily, column),
                         new String(column.value, "UTF-8"), column.timestamp);
     }
 
     // Execute SET statement
     private void executeSet(CommonTree ast) throws TException, 
InvalidRequestException, UnavailableException, TimedOutException, 
UnsupportedEncodingException
     { 
-        if (!CliMain.isConnected())
+        if (!CliMain.isConnected() || !hasKeySpace())
             return;
 
         assert (ast.getChildCount() == 2) : "serious parsing error (this is a 
bug).";
@@ -382,7 +379,6 @@ public class CliClient 
         CommonTree columnFamilySpec = (CommonTree)ast.getChild(0);
         assert(columnFamilySpec.getType() == CliParser.NODE_COLUMN_ACCESS);
 
-        String tableName = CliCompiler.getTableName(columnFamilySpec);
         String key = CliCompiler.getKey(columnFamilySpec);
         String columnFamily = CliCompiler.getColumnFamily(columnFamilySpec);
         int columnSpecCnt = CliCompiler.numColumnSpecifiers(columnFamilySpec);
@@ -414,7 +410,7 @@ public class CliClient 
         }
         
         // do the insert
-        thriftClient_.insert(tableName, key.getBytes(), new 
ColumnParent(columnFamily).setSuper_column(superColumnName),
+        thriftClient_.insert(key.getBytes(), new 
ColumnParent(columnFamily).setSuper_column(superColumnName),
                              new Column(columnName, value.getBytes(), 
timestampMicros()), ConsistencyLevel.ONE);
         
         css_.out.println("Value inserted.");
@@ -446,6 +442,111 @@ public class CliClient 
             css_.out.println(table);
         }
     }
+    
+    private boolean hasKeySpace() 
+    {
+       if (keySpace == null)
+        {
+            css_.out.println("Not authenticated to a working keyspace.");
+            return false;
+        }
+        return true;
+    }
+    
+    public String getKeySpace() 
+    {
+        return keySpace == null ? "unknown" : keySpace;
+    }
+    
+    public void setKeyspace(String keySpace) throws NotFoundException, 
TException 
+    {
+        this.keySpace = keySpace;
+        getCFMetaData(keySpace);
+    }
+    
+    public String getUsername() 
+    {
+        return username == null ? "default" : username;
+    }
+    
+    public void setUsername(String username)
+    {
+        this.username = username;
+    }
+    
+    private void executeUseTable(CommonTree ast) throws TException
+    {
+        if (!CliMain.isConnected())
+            return;
+       
+        int childCount = ast.getChildCount();
+        String tableName, username = null, password = null;
+        assert(childCount > 0);
+
+        // Get table name
+        tableName = ast.getChild(0).getText();
+        
+        if (childCount == 3) {
+            username  = ast.getChild(1).getText();
+            password  = ast.getChild(2).getText();
+        }
+        
+        if( tableName == null ) 
+        {
+            css_.out.println("Keyspace argument required");
+            return;
+        }
+        
+        try 
+        {
+               AuthenticationRequest authRequest;
+               Map<String, String> credentials = new HashMap<String, String>();
+               
+               if (username != null && password != null) 
+               {
+                   /* remove quotes */
+                   password = password.replace("\'", "");
+                   credentials.put(SimpleAuthenticator.USERNAME_KEY, username);
+                credentials.put(SimpleAuthenticator.PASSWORD_KEY, password);
+               }
+               
+               authRequest = new AuthenticationRequest(credentials);
+            thriftClient_.login(tableName, authRequest);
+            keySpace = tableName;
+            this.username = username != null ? username : "default";
+            
+            if (!(keyspacesMap.containsKey(keySpace))) 
+            {
+                keyspacesMap.put(keySpace, 
thriftClient_.describe_keyspace(keySpace));
+            }
+            CliMain.updateCompletor(keyspacesMap.get(keySpace).keySet());
+            css_.out.println("Authenticated to keyspace: " + keySpace);
+        } 
+        catch (AuthenticationException e) 
+        {
+            css_.err.println("Exception during authentication to the cassandra 
node: " +
+                       "verify keyspace exists, and you are using correct 
credentials.");
+            return;
+        } 
+        catch (AuthorizationException e) 
+        {
+            css_.err.println("You are not authorized to use keyspace: " + 
tableName);
+            return;
+        }
+        catch (NotFoundException e)
+        {
+            css_.err.println("This keyspace does not exist: " + tableName);
+            return;
+        }
+        catch (TException e) 
+        {
+            if (css_.debug)
+                e.printStackTrace();
+            
+            css_.err.println("Login failure. Did you specify 'keyspace', 
'username' and 'password'?");
+            return;
+        } 
+    }
 
     // process a statement of the form: describe table <tablename> 
     private void executeDescribeTable(CommonTree ast) throws TException

Modified: cassandra/trunk/src/java/org/apache/cassandra/cli/CliCompiler.java
URL: 
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cli/CliCompiler.java?rev=938172&r1=938171&r2=938172&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cli/CliCompiler.java 
(original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cli/CliCompiler.java Mon Apr 
26 18:19:04 2010
@@ -85,38 +85,32 @@ public class CliCompiler
     /*
      * NODE_COLUMN_ACCESS related functions.
      */
-    public static String getTableName(CommonTree astNode)
-    {
-        assert(astNode.getType() == CliParser.NODE_COLUMN_ACCESS);
-
-        return astNode.getChild(0).getText();
-    }
 
     public static String getColumnFamily(CommonTree astNode)
     {
         assert(astNode.getType() == CliParser.NODE_COLUMN_ACCESS);
 
-        return astNode.getChild(1).getText();
+        return astNode.getChild(0).getText();
     }
 
     public static String getKey(CommonTree astNode)
     {
         assert(astNode.getType() == CliParser.NODE_COLUMN_ACCESS);
 
-        return CliUtils.unescapeSQLString(astNode.getChild(2).getText());
+        return CliUtils.unescapeSQLString(astNode.getChild(1).getText());
     }
 
     public static int numColumnSpecifiers(CommonTree astNode)
     {
         // Skip over table, column family and rowKey
-        return astNode.getChildCount() - 3;
+        return astNode.getChildCount() - 2;
     }
 
     // Returns the pos'th (0-based index) column specifier in the astNode
     public static String getColumn(CommonTree astNode, int pos)
     {
         // Skip over table, column family and rowKey
-        return CliUtils.unescapeSQLString(astNode.getChild(pos + 
3).getText()); 
+        return CliUtils.unescapeSQLString(astNode.getChild(pos + 
2).getText()); 
     }
  
 }

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=938172&r1=938171&r2=938172&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cli/CliMain.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cli/CliMain.java Mon Apr 26 
18:19:04 2010
@@ -26,6 +26,7 @@ import org.apache.cassandra.thrift.Authe
 import org.apache.cassandra.thrift.AuthorizationException;
 import org.apache.cassandra.thrift.Cassandra;
 import org.apache.cassandra.thrift.InvalidRequestException;
+import org.apache.cassandra.thrift.NotFoundException;
 import org.apache.thrift.TException;
 import org.apache.thrift.protocol.TBinaryProtocol;
 import org.apache.thrift.transport.TFramedTransport;
@@ -34,8 +35,11 @@ import org.apache.thrift.transport.TTran
 
 import java.io.File;
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 import static org.apache.cassandra.db.Table.SYSTEM_TABLE;
 
@@ -107,26 +111,30 @@ public class CliMain
             try 
             {
                 thriftClient_.login(css_.keyspace, authRequest);
+                
updateCompletor(cliClient_.getCFMetaData(css_.keyspace).keySet());
+                cliClient_.setKeyspace(css_.keyspace);
+                cliClient_.setUsername(css_.username);
             } 
             catch (AuthenticationException e) 
             {
                 css_.err.println("Exception during authentication to the 
cassandra node, " +
-                               "verify you are using correct credentials.");
+                               "Verify the keyspace exists, and that you are 
using the correct credentials.");
                 return;
             } 
             catch (AuthorizationException e) 
             {
                 css_.err.println("You are not authorized to use keyspace: " + 
css_.keyspace);
                 return;
-            } 
+            }
             catch (TException e) 
             {
-                if (css_.debug)
-                    e.printStackTrace();
-                
                 css_.err.println("Login failure. Did you specify 'keyspace', 
'username' and 'password'?");
                 return;
+            } catch (NotFoundException e) {
+                css_.err.println("Keyspace not found.");
+                return;
             }
+            
         }
         
         // Lookup the cluster name, this is to make it clear which cluster the 
user is connected to
@@ -147,31 +155,6 @@ public class CliMain
             return;
         }
 
-        // Extend the completer with keyspace and column family data.
-        try
-        {
-            for (String keyspace : thriftClient_.describe_keyspaces())
-            {
-                // Ignore system column family
-                if (keyspace.equals(SYSTEM_TABLE))
-                    continue;
-
-                for (String cf : cliClient_.getCFMetaData(keyspace).keySet())
-                {
-                    for (String cmd : completer_.getKeyspaceCommands())
-                        completer_.addCandidateString(String.format("%s 
%s.%s", cmd, keyspace, cf));
-                }
-            }
-        }
-        catch (Exception e)
-        {
-            // Yes, we really do want to ignore any exceptions encountered 
here.
-            if (css_.debug)
-                e.printStackTrace();
-
-            return;
-        }
-
         css_.out.printf("Connected to: \"%s\" on %s/%d%n", clusterName, 
server, port);
     }
 
@@ -205,6 +188,20 @@ public class CliMain
         }
         return true;
     }
+    
+    public static void updateCompletor(Set<String> candidates)
+    {
+        Set<String> actions = new HashSet<String>();
+        for (String cf : candidates)
+        {
+            for (String cmd : completer_.getKeyspaceCommands())
+                actions.add(String.format("%s %s", cmd, cf));
+        }
+        
+        String[] strs = Arrays.copyOf(actions.toArray(), 
actions.toArray().length, String[].class);
+        
+        completer_.setCandidateStrings(strs);
+    }
 
     private static void processCLIStmt(String query)
     {
@@ -265,7 +262,7 @@ public class CliMain
         printBanner();
 
         String line;
-        while ((line = reader.readLine(PROMPT + "> ")) != null)
+        while ((line = reader.readLine("[" + cliClient_.getUsername() + "@" + 
cliClient_.getKeySpace() + "] ")) != null)
         {
             processCLIStmt(line);
         }


Reply via email to