cli support for keyspace/cf add, drop, and rename

Patch by Mason Bryant; review by eevans for CASSANDRA-1204

git-svn-id: https://svn.apache.org/repos/asf/cassandra/trunk@980558 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Eric Evans 2010-07-29 20:22:08 +00:00
parent de5715e14f
commit cdc48e527b
5 changed files with 646 additions and 33 deletions

View File

@ -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

View File

@ -35,6 +35,33 @@ import org.apache.commons.lang.ArrayUtils;
// 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.");
}
}

View File

@ -30,6 +30,31 @@ public class CliCompleter extends SimpleCompletor
"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",

View File

@ -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

View File

@ -917,7 +917,11 @@ public class CassandraServer implements Cassandra.Iface
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
{