You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by br...@apache.org on 2011/08/08 23:08:04 UTC
svn commit: r1155100 - in /cassandra/branches/cassandra-0.8:
src/java/org/apache/cassandra/cli/ src/resources/org/apache/cassandra/cli/
test/unit/org/apache/cassandra/cli/
Author: brandonwilliams
Date: Mon Aug 8 21:08:04 2011
New Revision: 1155100
URL: http://svn.apache.org/viewvc?rev=1155100&view=rev
Log:
Add 'show creates' commands to the cli to export schema.
Patch by Aaron Morton, reviewed by xedin for CASSANDRA-2221
Modified:
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cli/Cli.g
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cli/CliClient.java
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cli/CliCompleter.java
cassandra/branches/cassandra-0.8/src/resources/org/apache/cassandra/cli/CliHelp.yaml
cassandra/branches/cassandra-0.8/test/unit/org/apache/cassandra/cli/CliTest.java
Modified: cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cli/Cli.g
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cli/Cli.g?rev=1155100&r1=1155099&r2=1155100&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cli/Cli.g (original)
+++ cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cli/Cli.g Mon Aug 8 21:08:04 2011
@@ -44,6 +44,7 @@ tokens {
NODE_SHOW_CLUSTER_NAME;
NODE_SHOW_VERSION;
NODE_SHOW_KEYSPACES;
+ NODE_SHOW_SCHEMA;
NODE_THRIFT_GET;
NODE_THRIFT_GET_WITH_CONDITIONS;
NODE_THRIFT_SET;
@@ -191,6 +192,8 @@ helpStatement
-> ^(NODE_HELP NODE_SHOW_CLUSTER_NAME)
| HELP SHOW KEYSPACES
-> ^(NODE_HELP NODE_SHOW_KEYSPACES)
+ | HELP SHOW SCHEMA
+ -> ^(NODE_HELP NODE_SHOW_SCHEMA)
| HELP SHOW API_VERSION
-> ^(NODE_HELP NODE_SHOW_VERSION)
| HELP CREATE KEYSPACE
@@ -284,6 +287,7 @@ showStatement
: showClusterName
| showVersion
| showKeyspaces
+ | showSchema
;
listStatement
@@ -356,6 +360,11 @@ showKeyspaces
-> ^(NODE_SHOW_KEYSPACES)
;
+showSchema
+ : SHOW SCHEMA (keyspace)?
+ -> ^(NODE_SHOW_SCHEMA (keyspace)?)
+ ;
+
describeTable
: DESCRIBE KEYSPACE (keyspace)?
-> ^(NODE_DESCRIBE_TABLE (keyspace)?)
@@ -573,6 +582,7 @@ TTL: 'TTL';
CONSISTENCYLEVEL: 'CONSISTENCYLEVEL';
INDEX: 'INDEX';
ON: 'ON';
+SCHEMA: 'SCHEMA';
IP_ADDRESS
: IntegerPositiveLiteral '.' IntegerPositiveLiteral '.' IntegerPositiveLiteral '.' IntegerPositiveLiteral
Modified: cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cli/CliClient.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cli/CliClient.java?rev=1155100&r1=1155099&r2=1155100&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cli/CliClient.java (original)
+++ cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cli/CliClient.java Mon Aug 8 21:08:04 2011
@@ -26,6 +26,9 @@ import java.nio.ByteBuffer;
import java.nio.charset.CharacterCodingException;
import java.util.*;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import org.apache.commons.lang.StringUtils;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
@@ -71,7 +74,7 @@ public class CliClient
COUNTERCOLUMN (CounterColumnType.instance);
private AbstractType validator;
-
+
Function(AbstractType validator)
{
this.validator = validator;
@@ -136,6 +139,8 @@ public class CliClient
}
private static final String DEFAULT_PLACEMENT_STRATEGY = "org.apache.cassandra.locator.NetworkTopologyStrategy";
+ private final String NEWLINE = System.getProperty("line.separator");
+ private final String TAB = " ";
private Cassandra.Client thriftClient = null;
private CliSessionState sessionState = null;
@@ -241,6 +246,9 @@ public class CliClient
case CliParser.NODE_SHOW_KEYSPACES:
executeShowKeySpaces();
break;
+ case CliParser.NODE_SHOW_SCHEMA:
+ executeShowSchema(tree);
+ break;
case CliParser.NODE_DESCRIBE_TABLE:
executeDescribeKeySpace(tree);
break;
@@ -1246,7 +1254,7 @@ public class CliClient
cfDef.setReplicate_on_write(Boolean.parseBoolean(mValue));
break;
case ROW_CACHE_PROVIDER:
- cfDef.setRow_cache_provider(mValue);
+ cfDef.setRow_cache_provider(CliUtils.unescapeSQLString(mValue));
break;
case KEY_VALIDATION_CLASS:
cfDef.setKey_validation_class(CliUtils.unescapeSQLString(mValue));
@@ -1560,6 +1568,187 @@ public class CliClient
}
}
+ // SHOW SCHEMA
+ private void executeShowSchema(Tree statement) throws TException, InvalidRequestException
+ {
+ if (!CliMain.isConnected())
+ return;
+
+ final List<KsDef> keyspaces = thriftClient.describe_keyspaces();
+ Collections.sort(keyspaces, new KsDefNamesComparator());
+ final String keyspaceName = (statement.getChildCount() == 0)
+ ? keySpace
+ : CliCompiler.getKeySpace(statement, keyspaces);
+
+ Iterator<KsDef> ksIter;
+ if (keyspaceName != null)
+ ksIter = Collections2.filter(keyspaces, new Predicate<KsDef>()
+ {
+ public boolean apply(KsDef ksDef)
+ {
+ return keyspaceName.equals(ksDef.name);
+ }
+ }).iterator();
+ else
+ ksIter = keyspaces.iterator();
+
+
+ final StringBuilder sb = new StringBuilder();
+ while (ksIter.hasNext())
+ showKeyspace(sb, ksIter.next());
+
+ sessionState.out.printf(sb.toString());
+ }
+
+ /**
+ * Creates a CLI script to create the Keyspace it's Column Families
+ * @param sb StringBuilder to write to.
+ * @param ksDef KsDef to create the cli script for.
+ */
+ private void showKeyspace(StringBuilder sb, KsDef ksDef)
+ {
+
+ sb.append("create keyspace " + ksDef.name);
+ if (ksDef.isSetReplication_factor())
+ writeAttr(sb, false, "replication_factor", ksDef.getReplication_factor());
+ writeAttr(sb, true, "placement_strategy", normaliseType(ksDef.strategy_class, "org.apache.cassandra.locator"));
+ if (ksDef.strategy_options != null && !ksDef.strategy_options.isEmpty())
+ {
+ final StringBuilder opts = new StringBuilder();
+ opts.append("[{");
+ String prefix = "";
+ for (Map.Entry<String, String> opt : ksDef.strategy_options.entrySet())
+ {
+ opts.append(prefix + CliUtils.escapeSQLString(opt.getKey()) + " : " + CliUtils.escapeSQLString(opt.getValue()));
+ prefix = ", ";
+ }
+ opts.append("}]");
+ writeAttrRaw(sb, false, "strategy_options", opts.toString());
+ }
+ sb.append(";" + NEWLINE);
+ sb.append(NEWLINE);
+
+ sb.append("use " + ksDef.name + ";");
+ sb.append(NEWLINE);
+ sb.append(NEWLINE);
+
+ Collections.sort(ksDef.cf_defs, new CfDefNamesComparator());
+ for (CfDef cfDef : ksDef.cf_defs)
+ showColumnFamily(sb, cfDef);
+ sb.append(NEWLINE);
+ sb.append(NEWLINE);
+ }
+
+ /**
+ * Creates a CLI script for the CfDef including meta data to the supplied StringBuilder.
+ * @param sb
+ * @param cfDef
+ */
+ private void showColumnFamily(StringBuilder sb, CfDef cfDef)
+ {
+ sb.append("create column family " + CliUtils.escapeSQLString(cfDef.name));
+
+ writeAttr(sb, true, "column_type", cfDef.column_type);
+ writeAttr(sb, false, "comparator", normaliseType(cfDef.comparator_type, "org.apache.cassandra.db.marshal"));
+ if (cfDef.column_type == "Super")
+ writeAttr(sb, false, "subcomparator", normaliseType(cfDef.subcomparator_type, "org.apache.cassandra.db.marshal"));
+ if (!StringUtils.isEmpty(cfDef.default_validation_class))
+ writeAttr(sb, false, "default_validation_class",
+ normaliseType(cfDef.default_validation_class, "org.apache.cassandra.db.marshal"));
+ writeAttr(sb, false, "key_validation_class",
+ normaliseType(cfDef.key_validation_class, "org.apache.cassandra.db.marshal"));
+ writeAttr(sb, false, "memtable_operations", cfDef.memtable_operations_in_millions);
+ writeAttr(sb, false, "memtable_throughput", cfDef.memtable_throughput_in_mb);
+ writeAttr(sb, false, "memtable_flush_after", cfDef.memtable_flush_after_mins);
+ writeAttr(sb, false, "rows_cached", cfDef.row_cache_size);
+ writeAttr(sb, false, "row_cache_save_period", cfDef.row_cache_save_period_in_seconds);
+ writeAttr(sb, false, "keys_cached", cfDef.key_cache_size);
+ writeAttr(sb, false, "key_cache_save_period", cfDef.key_cache_save_period_in_seconds);
+ writeAttr(sb, false, "read_repair_chance", cfDef.read_repair_chance);
+ writeAttr(sb, false, "gc_grace", cfDef.gc_grace_seconds);
+ writeAttr(sb, false, "min_compaction_threshold", cfDef.min_compaction_threshold);
+ writeAttr(sb, false, "max_compaction_threshold", cfDef.max_compaction_threshold);
+ writeAttr(sb, false, "replicate_on_write", cfDef.replicate_on_write);
+ writeAttr(sb, false, "row_cache_provider", normaliseType(cfDef.row_cache_provider, "org.apache.cassandra.cache"));
+
+ if (!StringUtils.isEmpty(cfDef.comment))
+ writeAttr(sb, false, "comment", cfDef.comment);
+
+ if (!cfDef.column_metadata.isEmpty())
+ {
+ StringBuilder colSb = new StringBuilder();
+ colSb.append("[");
+ boolean first = true;
+ for (ColumnDef colDef : cfDef.column_metadata)
+ {
+ if (!first)
+ colSb.append(",");
+ first = false;
+ showColumnMeta(colSb, cfDef, colDef);
+ }
+ colSb.append("]");
+ writeAttrRaw(sb, false, "column_metadata", colSb.toString());
+ }
+ sb.append(";");
+ sb.append(NEWLINE);
+ sb.append(NEWLINE);
+ }
+
+ /**
+ * Writes the supplied ColumnDef to the StringBuilder as a cli script.
+ * @param sb
+ * @param cfDef
+ * @param colDef
+ */
+ private void showColumnMeta(StringBuilder sb, CfDef cfDef, ColumnDef colDef)
+ {
+ sb.append(NEWLINE + TAB + TAB + "{");
+
+ final AbstractType comparator = getFormatType((cfDef.column_type == "Super")
+ ? cfDef.subcomparator_type
+ : cfDef.comparator_type);
+ sb.append("column_name : '" + CliUtils.escapeSQLString(comparator.getString(colDef.name)) + "'," + NEWLINE);
+ String validationClass = normaliseType(colDef.validation_class, "org.apache.cassandra.db.marshal");
+ sb.append(TAB + TAB + "validation_class : " + CliUtils.escapeSQLString(validationClass));
+ if (colDef.isSetIndex_name())
+ {
+ sb.append("," + NEWLINE);
+ sb.append(TAB + TAB + "index_name : '" + CliUtils.escapeSQLString(colDef.index_name) + "'," + NEWLINE);
+ sb.append(TAB + TAB + "index_type : " + CliUtils.escapeSQLString(Integer.toString(colDef.index_type.getValue())));
+
+ }
+ sb.append("}");
+ }
+
+ private String normaliseType(String path, String expectedPackage)
+ {
+ if (path.startsWith(expectedPackage))
+ return path.substring(expectedPackage.length() + 1);
+
+ return path;
+ }
+
+ private void writeAttr(StringBuilder sb, boolean first, String name, Boolean value)
+ {
+ writeAttrRaw(sb, first, name, value.toString());
+ }
+ private void writeAttr(StringBuilder sb, boolean first, String name, Number value)
+ {
+ writeAttrRaw(sb, first, name, value.toString());
+ }
+
+ private void writeAttr(StringBuilder sb, boolean first, String name, String value)
+ {
+ writeAttrRaw(sb, first, name, "'" + CliUtils.escapeSQLString(value) + "'");
+ }
+
+ private void writeAttrRaw(StringBuilder sb, boolean first, String name, String value)
+ {
+ sb.append(NEWLINE + TAB);
+ sb.append(first ? "with " : "and ");
+ sb.append(name + " = ");
+ sb.append(value);
+ }
/**
* Returns true if this.keySpace is set, false otherwise
* @return boolean
Modified: cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cli/CliCompleter.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cli/CliCompleter.java?rev=1155100&r1=1155099&r2=1155100&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cli/CliCompleter.java (original)
+++ cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cli/CliCompleter.java Mon Aug 8 21:08:04 2011
@@ -29,6 +29,7 @@ public class CliCompleter extends Simple
"quit",
"show cluster name",
"show keyspaces",
+ "show schema",
"show api version",
"create keyspace",
"create column family",
@@ -45,6 +46,7 @@ public class CliCompleter extends Simple
"help quit",
"help show cluster name",
"help show keyspaces",
+ "help show schema",
"help show api version",
"help create keyspace",
"help create column family",
Modified: cassandra/branches/cassandra-0.8/src/resources/org/apache/cassandra/cli/CliHelp.yaml
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/resources/org/apache/cassandra/cli/CliHelp.yaml?rev=1155100&r1=1155099&r2=1155100&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/src/resources/org/apache/cassandra/cli/CliHelp.yaml (original)
+++ cassandra/branches/cassandra-0.8/src/resources/org/apache/cassandra/cli/CliHelp.yaml Mon Aug 8 21:08:04 2011
@@ -52,6 +52,7 @@ help: |
show api version Show the server API version.
show cluster name Show the cluster name.
show keyspaces Show all keyspaces and their column families.
+ show schema Show a cli script to create keyspaces and column families.
truncate Drop the data in a column family.
update column family Update the settings for a column family.
update keyspace Update the settings for a keyspace.
@@ -116,7 +117,8 @@ commands:
use Keyspace1 user 'badpasswd';
- name: NODE_DESCRIBE_TABLE
help: |
- describe keyspace (<keyspace>)?;
+ describe keyspace;
+ describe keyspace <keyspace>;
Describes the settings for the current or named keyspace, and the settings
for all column families in the keyspace.
@@ -126,7 +128,7 @@ commands:
Examples:
describe keyspace;
- describe keyspace system;
+ describe keyspace Keyspace1;
- name: NODE_DESCRIBE_CLUSTER
help: |
describe cluster;
@@ -177,6 +179,22 @@ commands:
Examples:
show keyspaces;
+ - name: NODE_SHOW_SCHEMA
+ help: |
+ show schema;
+ show schema <keyspace>;
+
+ Creates a CLI script to create the current, specified or all keyspaces
+ and their column families.
+
+ Optional Parameters:
+ - keyspace: Name of the keyspace to create the script for. If omitted
+ the current keyspace is used, if there is no current keyspace all
+ keyspaces are considered.
+
+ Examples:
+ show schema;
+ show schema Keyspace1;
- name: NODE_ADD_KEYSPACE
help: |
create keyspace <keyspace>;
Modified: cassandra/branches/cassandra-0.8/test/unit/org/apache/cassandra/cli/CliTest.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/test/unit/org/apache/cassandra/cli/CliTest.java?rev=1155100&r1=1155099&r2=1155100&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/test/unit/org/apache/cassandra/cli/CliTest.java (original)
+++ cassandra/branches/cassandra-0.8/test/unit/org/apache/cassandra/cli/CliTest.java Mon Aug 8 21:08:04 2011
@@ -166,6 +166,7 @@ public class CliTest extends CleanupHelp
"help QUIT",
"help show cluster name",
"help show keyspaces",
+ "help show schema",
"help show api version",
"help create keyspace",
"HELP update KEYSPACE",
@@ -181,7 +182,9 @@ public class CliTest extends CleanupHelp
"HELP TRUNCATE",
"help assume",
"HELP",
- "?"
+ "?",
+ "show schema",
+ "show schema TestKeySpace"
};
@Test
@@ -270,4 +273,4 @@ public class CliTest extends CleanupHelp
assertEquals(unescaped, CliUtils.unescapeSQLString("'" + escaped + "'"));
assertEquals(escaped, CliUtils.escapeSQLString(unescaped));
}
-}
\ No newline at end of file
+}