/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cli;
import java.util.EnumMap;
import org.antlr.runtime.tree.Tree;
/**
* @author Pavel A. Yaskevich
*/
public class CliUserHelp {
/*
* the <i>add column family</i> command requires a list of arguments,
* this enum defines which arguments are valid.
*/
protected enum ColumnFamilyArgument
{
COLUMN_TYPE,
COMPARATOR,
SUBCOMPARATOR,
COMMENT,
ROWS_CACHED,
ROW_CACHE_SAVE_PERIOD,
KEYS_CACHED,
KEY_CACHE_SAVE_PERIOD,
READ_REPAIR_CHANCE,
GC_GRACE,
COLUMN_METADATA,
MEMTABLE_OPERATIONS,
MEMTABLE_THROUGHPUT,
MEMTABLE_FLUSH_AFTER,
DEFAULT_VALIDATION_CLASS,
MIN_COMPACTION_THRESHOLD,
MAX_COMPACTION_THRESHOLD,
ROWKEY_SIZE,
COLUMNFAMILY_SIZE,
COLUMNFAMILY_TYPE,
MYSQL_ENGINE,
KC_DBCLASS,
}
protected EnumMap<ColumnFamilyArgument, String> argumentExplanations = new EnumMap<ColumnFamilyArgument, String>(ColumnFamilyArgument.class)
{{
put(ColumnFamilyArgument.COLUMN_TYPE, "Super or Standard");
put(ColumnFamilyArgument.COMMENT, "Human-readable column family description. Any string is acceptable");
put(ColumnFamilyArgument.COMPARATOR, "The class used as a comparator when sorting column names.\n Valid options include: AsciiType, BytesType, LexicalUUIDType,\n LongType, IntegerType, TimeUUIDType, and UTF8Type");
put(ColumnFamilyArgument.SUBCOMPARATOR, "Comparator for sorting subcolumn names, for Super columns only");
put(ColumnFamilyArgument.MEMTABLE_OPERATIONS, "Flush memtables after this many operations (in millions)");
put(ColumnFamilyArgument.MEMTABLE_THROUGHPUT, "... or after this many MB have been written");
put(ColumnFamilyArgument.MEMTABLE_FLUSH_AFTER, "... or after this many minutes");
put(ColumnFamilyArgument.ROWS_CACHED, "Number or percentage of rows to cache");
put(ColumnFamilyArgument.ROW_CACHE_SAVE_PERIOD, "Period with which to persist the row cache, in seconds");
put(ColumnFamilyArgument.KEYS_CACHED, "Number or percentage of keys to cache");
put(ColumnFamilyArgument.KEY_CACHE_SAVE_PERIOD, "Period with which to persist the key cache, in seconds");
put(ColumnFamilyArgument.READ_REPAIR_CHANCE, "Probability (0.0-1.0) with which to perform read repairs on CL.ONE reads");
put(ColumnFamilyArgument.GC_GRACE, "Discard tombstones after this many seconds");
put(ColumnFamilyArgument.MIN_COMPACTION_THRESHOLD, "Avoid minor compactions of less than this number of sstable files");
put(ColumnFamilyArgument.MAX_COMPACTION_THRESHOLD, "Compact no more than this number of sstable files at once");
put(ColumnFamilyArgument.ROWKEY_SIZE, "Max Key Size (16-) With MyCassandra-MySQL");
put(ColumnFamilyArgument.COLUMNFAMILY_SIZE, "Max CF Size (1024-) With MyCassandra-MySQL");
put(ColumnFamilyArgument.COLUMNFAMILY_TYPE, "CF type (MySQL data type) With MyCassandra-MySQL");
put(ColumnFamilyArgument.MYSQL_ENGINE, "Storage Engine With MySQL");
put(ColumnFamilyArgument.KC_DBCLASS, "DB CLASS With KyotoCabinet");
}};
protected void printCmdHelp(Tree statement, CliSessionState state)
{
if (statement.getChildCount() > 0)
{
int helpType = statement.getChild(0).getType();
switch(helpType)
{
case CliParser.NODE_HELP:
state.out.println("help <command>;\n");
state.out.println("Display the general help page with a list of available commands.");
break;
case CliParser.NODE_CONNECT:
state.out.println("connect <hostname>/<port> (<username> '<password>')?;\n");
state.out.println("Connect to the specified host on the specified port (using specified username and password).\n");
state.out.println("example:");
state.out.println("connect localhost/9160;");
state.out.println("connect localhost/9160 user 'badpasswd';");
state.out.println("connect 127.0.0.1/9160 user 'badpasswd';");
break;
case CliParser.NODE_USE_TABLE:
state.out.println("use <keyspace>;");
state.out.println("use <keyspace> <username> '<password>';\n");
state.out.println("Switch to the specified keyspace. The optional username and password fields");
state.out.println("are needed when performing authentication.\n");
break;
case CliParser.NODE_DESCRIBE_TABLE:
state.out.println("describe keyspace (<keyspace>)?;\n");
state.out.println("Show additional information about the specified keyspace.");
state.out.println("Command could be used without <keyspace> argument if you are already authenticated to keyspace.\n");
state.out.println("example:");
state.out.println("describe keyspace system;");
break;
case CliParser.NODE_DESCRIBE_CLUSTER:
state.out.println("describe cluster;\n");
state.out.println("Display information about cluster: snitch, partitioner, schema versions.");
break;
case CliParser.NODE_EXIT:
state.out.println("exit;");
state.out.println("quit;\n");
state.out.println("Exit this utility.");
break;
case CliParser.NODE_SHOW_CLUSTER_NAME:
state.out.println("show cluster name;\n");
state.out.println("Displays the name of the currently connected cluster.");
break;
case CliParser.NODE_SHOW_VERSION:
state.out.println("show api version;\n");
state.out.println("Displays the API version number.");
break;
case CliParser.NODE_SHOW_KEYSPACES:
state.out.println("show keyspaces;\n");
state.out.println("Displays a list of the keyspaces available on the currently connected cluster.");
break;
case CliParser.NODE_ADD_KEYSPACE:
state.out.println("create keyspace <keyspace>;");
state.out.println("create keyspace <keyspace> with <att1>=<value1>;");
state.out.println("create keyspace <keyspace> with <att1>=<value1> and <att2>=<value2> ...;\n");
state.out.println("Create a new keyspace with the specified values for the given set of attributes.\n");
state.out.println("valid attributes are:");
state.out.println(" replication_factor: to how many nodes should entries to this keyspace be");
state.out.println(" replicated. Valid entries are integers greater than 0.");
state.out.println(" Applies to Simple and OldNT strategies but NOT NTS.");
state.out.println(" placement_strategy: the fully qualified class used to place replicas in");
state.out.println(" this keyspace. Valid values are");
state.out.println(" org.apache.cassandra.locator.SimpleStrategy,");
state.out.println(" org.apache.cassandra.locator.NetworkTopologyStrategy,");
state.out.println(" and org.apache.cassandra.locator.OldNetworkTopologyStrategy");
state.out.println(" strategy_options: additional options for placement_strategy.");
state.out.println(" Applies only to NetworkTopologyStrategy.");
state.out.println("\nexamples:");
state.out.println("create keyspace foo with");
state.out.println(" placement_strategy = 'org.apache.cassandra.locator.SimpleStrategy';");
state.out.println(" and replication_factor = 3;");
state.out.println("create keyspace foo with");
state.out.println(" placement_strategy = 'org.apache.cassandra.locator.NetworkTopologyStrategy';");
state.out.println(" and strategy_options=[{DC1:2, DC2:2}];");
break;
case CliParser.NODE_UPDATE_KEYSPACE:
state.out.println("update keyspace <keyspace>;");
state.out.println("update keyspace <keyspace> with <att1>=<value1>;");
state.out.println("update keyspace <keyspace> with <att1>=<value1> and <att2>=<value2> ...;\n");
state.out.println("Update a keyspace with the specified values for the given set of attributes.\n");
state.out.println("valid attributes are:");
state.out.println(" replication_factor: to how many nodes should entries to this keyspace be");
state.out.println(" replicated. Valid entries are integers greater than 0.");
state.out.println(" Applies to Simple and OldNT strategies but NOT NTS.");
state.out.println(" placement_strategy: the fully qualified class used to place replicas in");
state.out.println(" this keyspace. Valid values are");
state.out.println(" org.apache.cassandra.locator.SimpleStrategy,");
state.out.println(" org.apache.cassandra.locator.NetworkTopologyStrategy,");
state.out.println(" and org.apache.cassandra.locator.OldNetworkTopologyStrategy");
state.out.println(" strategy_options: additional options for placement_strategy.");
state.out.println(" Applies only to NetworkTopologyStrategy.");
state.out.println("\nexamples:");
state.out.println("update keyspace foo with");
state.out.println(" placement_strategy = 'org.apache.cassandra.locator.SimpleStrategy';");
state.out.println(" and replication_factor = 3;");
state.out.println("update keyspace foo with");
state.out.println(" placement_strategy = 'org.apache.cassandra.locator.NetworkTopologyStrategy';");
state.out.println(" and strategy_options=[{DC1:2, DC2:2}];");
break;
case CliParser.NODE_ADD_COLUMN_FAMILY:
state.out.println("create column family Bar;");
state.out.println("create column family Bar with <att1>=<value1>;");
state.out.println("create column family Bar with <att1>=<value1> and <att2>=<value2>...;\n");
state.out.println("create column family Bar with rowkey_size = 32 and columnfamily_size = 2048 and columnfamily_type = 'VARBINARY' and mysql_engine = 'MyISAM'");
state.out.println("create column family Bar with kc_dbclass = 'TreeDB'");
state.out.println("Create a new column family with the specified values for the given set of");
state.out.println("attributes. Note that you must be using a keyspace.\n");
state.out.println("valid attributes are:");
for (ColumnFamilyArgument argument : ColumnFamilyArgument.values())
state.out.printf(" - %s: %s%n", argument.toString().toLowerCase(), argumentExplanations.get(argument));
state.out.println(" - column_metadata: Metadata which describes columns of column family.");
state.out.println(" Supported format is [{ k:v, k:v, ... }, { ... }, ...]");
state.out.println(" Valid attributes: column_name, validation_class (see comparator),");
state.out.println(" index_type (integer), index_name.");
state.out.println("example:\n");
state.out.println("create column family Bar with column_type = 'Super' and comparator = 'AsciiType'");
state.out.println(" and rows_cached = 10000;");
state.out.println("create column family Baz with comparator = 'LongType' and rows_cached = 10000;");
state.out.print("create column family Foo with comparator=UTF8Type and column_metadata=");
state.out.print("[{ column_name:test, validation_class:IntegerType, index_type:0, index_name:TextIdx");
state.out.println("}, { column_name:'other name', validation_class:LongType }];");
break;
case CliParser.NODE_UPDATE_COLUMN_FAMILY:
state.out.println("update column family Bar;");
state.out.println("update column family Bar with <att1>=<value1>;");
state.out.println("update column family Bar with <att1>=<value1> and <att2>=<value2>...;\n");
state.out.println("Update a column family with the specified values for the given set of");
state.out.println("attributes. Note that you must be using a keyspace.\n");
state.out.println("valid attributes are:");
for (ColumnFamilyArgument argument : ColumnFamilyArgument.values())
{
if (argument == ColumnFamilyArgument.COMPARATOR || argument == ColumnFamilyArgument.SUBCOMPARATOR)
continue;
state.out.printf(" - %s: %s%n", argument.toString().toLowerCase(), argumentExplanations.get(argument));
}
state.out.println(" - column_metadata: Metadata which describes columns of column family.");
state.out.println(" Supported format is [{ k:v, k:v, ... }, { ... }, ...]");
state.out.println(" Valid attributes: column_name, validation_class (see comparator),");
state.out.println(" index_type (integer), index_name.");
state.out.println("example:\n");
state.out.print("update column family Foo with column_metadata=");
state.out.print("[{ column_name:Test, validation_class:IntegerType, index_type:0, index_name:IdxName");
state.out.println("}] and rows_cached=100 and comment='this is helpful comment.';");
break;
case CliParser.NODE_DEL_KEYSPACE:
state.out.println("drop keyspace <keyspace>;\n");
state.out.println("Drops the specified keyspace.\n");
state.out.println("example:");
state.out.println("drop keyspace foo;");
break;
case CliParser.NODE_DEL_COLUMN_FAMILY:
state.out.println("drop column family <name>;\n");
state.out.println("Drops the specified column family.\n");
state.out.println("example:");
state.out.println("drop column family foo;");
break;
case CliParser.NODE_THRIFT_GET :
state.out.println("get <cf>['<key>'];");
state.out.println("get <cf>['<key>']['<col>'] (as <type>)*;");
state.out.println("get <cf>['<key>']['<super>'];");
state.out.println("get <cf>['<key>'][<function>];");
state.out.println("get <cf>['<key>'][<function>(<super>)][<function>(<col>)];");
state.out.println("get <cf> where <column> = <value> [and <column> > <value> and ...] [limit <integer>];");
state.out.println("Default LIMIT is 100. Available operations: =, >, >=, <, <=\n");
state.out.println("get <cf>['<key>']['<super>']['<col>'] (as <type>)*;");
state.out.print("Note: `as <type>` is optional, it dynamically converts column value to the specified type");
state.out.println(", column value validator will be set to <type>.");
state.out.println("Available functions: " + CliClient.Function.getFunctionNames());
state.out.println("Available types: IntegerType, LongType, UTF8Type, ASCIIType, TimeUUIDType, LexicalUUIDType.\n");
state.out.println("examples:");
state.out.println("get bar[testkey];");
state.out.println("get bar[testkey][test_column] as IntegerType;");
state.out.println("get bar[testkey][utf8(hello)];");
break;
case CliParser.NODE_THRIFT_SET:
state.out.println("set <cf>['<key>']['<col>'] = <value>;");
state.out.println("set <cf>['<key>']['<super>']['<col>'] = <value>;");
state.out.println("set <cf>['<key>']['<col>'] = <function>(<argument>);");
state.out.println("set <cf>['<key>']['<super>']['<col>'] = <function>(<argument>);");
state.out.println("set <cf>[<key>][<function>(<col>)] = <value> || <function>;");
state.out.println("set <cf>[<key>][<function>(<col>) || <col>] = <value> || <function> with ttl = <secs>;");
state.out.println("Available functions: " + CliClient.Function.getFunctionNames() + "\n");
state.out.println("examples:");
state.out.println("set bar['testkey']['my super']['test col']='this is a test';");
state.out.println("set baz['testkey']['test col']='this is also a test';");
state.out.println("set diz[testkey][testcol] = utf8('this is utf8 string.');");
state.out.println("set bar[testkey][timeuuid()] = utf('hello world');");
state.out.println("set bar[testkey][timeuuid()] = utf('hello world') with ttl = 30;");
state.out.println("set diz[testkey][testcol] = 'this is utf8 string.' with ttl = 150;");
break;
case CliParser.NODE_THRIFT_DEL:
state.out.println("del <cf>['<key>'];");
state.out.println("del <cf>['<key>']['<col>'];");
state.out.println("del <cf>['<key>']['<super>']['<col>'];\n");
state.out.println("Deletes a record, a column, or a subcolumn.\n");
state.out.println("example:");
state.out.println("del bar['testkey']['my super']['test col'];");
state.out.println("del baz['testkey']['test col'];");
state.out.println("del baz['testkey'];");
break;
case CliParser.NODE_THRIFT_COUNT:
state.out.println("count <cf>['<key>'];");
state.out.println("count <cf>['<key>']['<super>'];\n");
state.out.println("Count the number of columns in the specified key or subcolumns in the specified");
state.out.println("super column.\n");
state.out.println("example:");
state.out.println("count bar['testkey']['my super'];");
state.out.println("count baz['testkey'];");
break;
case CliParser.NODE_LIST:
state.out.println("list <cf>;");
state.out.println("list <cf>[<startKey>:];");
state.out.println("list <cf>[<startKey>:<endKey>];");
state.out.println("list ... limit N;");
state.out.println("List a range of rows in the column or supercolumn family.\n");
state.out.println("example:");
state.out.println("list Users[j:] limit 40;");
break;
case CliParser.NODE_TRUNCATE:
state.out.println("truncate <column_family>;");
state.out.println("Truncate specified column family.\n");
state.out.println("example:");
state.out.println("truncate Category;");
break;
case CliParser.NODE_ASSUME:
state.out.println("assume <column_family> comparator as <type>;");
state.out.println("assume <column_family> sub_comparator as <type>;");
state.out.println("assume <column_family> validator as <type>;");
state.out.println("assume <column_family> keys as <type>;\n");
state.out.println("Assume one of the attributes (comparator, sub_comparator, validator or keys)");
state.out.println("of the given column family to match specified type. Available types: " + CliClient.Function.getFunctionNames());
state.out.println("example:");
state.out.println("assume Users comparator as lexicaluuid;");
break;
case CliParser.NODE_CONSISTENCY_LEVEL:
state.out.println("consistencylevel as <level>");
state.out.println("example:");
state.out.println("consistencylevel as QUORUM");
break;
default:
state.out.println("?");
break;
}
}
else
{
state.out.println("List of all CLI commands:");
state.out.println("? Display this message.");
state.out.println("help; Display this help.");
state.out.println("help <command>; Display detailed, command-specific help.");
state.out.println("connect <hostname>/<port> (<username> '<password>')?; Connect to thrift service.");
state.out.println("use <keyspace> [<username> 'password']; Switch to a keyspace.");
state.out.println("describe keyspace (<keyspacename>)?; Describe keyspace.");
state.out.println("exit; Exit CLI.");
state.out.println("quit; Exit CLI.");
state.out.println("describe cluster; Display information about cluster.");
state.out.println("show cluster name; Display cluster name.");
state.out.println("show keyspaces; Show list of keyspaces.");
state.out.println("show api version; Show server API version.");
state.out.println("create keyspace <keyspace> [with <att1>=<value1> [and <att2>=<value2> ...]];");
state.out.println(" Add a new keyspace with the specified attribute(s) and value(s).");
state.out.println("update keyspace <keyspace> [with <att1>=<value1> [and <att2>=<value2> ...]];");
state.out.println(" Update a keyspace with the specified attribute(s) and value(s).");
state.out.println("create column family <cf> [with <att1>=<value1> [and <att2>=<value2> ...]];");
state.out.println(" Create a new column family with the specified attribute(s) and value(s).");
state.out.println("update column family <cf> [with <att1>=<value1> [and <att2>=<value2> ...]];");
state.out.println(" Update a column family with the specified attribute(s) and value(s).");
state.out.println("drop keyspace <keyspace>; Delete a keyspace.");
state.out.println("drop column family <cf>; Delete a column family.");
state.out.println("get <cf>['<key>']; Get a slice of columns.");
state.out.println("get <cf>['<key>']['<super>']; Get a slice of sub columns.");
state.out.println("get <cf> where <column> = <value> [and <column> > <value> and ...] [limit int]; ");
state.out.println("get <cf>['<key>']['<col>'] (as <type>)*; Get a column value.");
state.out.println("get <cf>['<key>']['<super>']['<col>'] (as <type>)*; Get a sub column value.");
state.out.println("set <cf>['<key>']['<col>'] = <value> (with ttl = <secs>)*; Set a column.");
state.out.println("set <cf>['<key>']['<super>']['<col>'] = <value> (with ttl = <secs>)*;");
state.out.println(" Set a sub column.");
state.out.println("del <cf>['<key>']; Delete record.");
state.out.println("del <cf>['<key>']['<col>']; Delete column.");
state.out.println("del <cf>['<key>']['<super>']['<col>']; Delete sub column.");
state.out.println("count <cf>['<key>']; Count columns in record.");
state.out.println("count <cf>['<key>']['<super>']; Count columns in a super column.");
state.out.println("truncate <column_family>; Truncate specified column family.");
state.out.println("assume <column_family> <attribute> as <type>;");
state.out.println(" Assume a given column family attributes to match a specified type.");
state.out.println("consistencylevel as <level>;");
state.out.println(" Change the consistency level for set,get, and list operations.");
state.out.println("list <cf>; List all rows in the column family.");
state.out.println("list <cf>[<startKey>:];");
state.out.println(" List rows in the column family beginning with <startKey>.");
state.out.println("list <cf>[<startKey>:<endKey>];");
state.out.println(" List rows in the column family in the range from <startKey> to <endKey>.");
state.out.println("list ... limit N; Limit the list results to N.");
}
}
}