You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by fe...@apache.org on 2016/01/24 19:04:55 UTC
[1/6] incubator-zeppelin git commit: [ZEPPELIN-559] Cassandra
interpreter v2
Repository: incubator-zeppelin
Updated Branches:
refs/heads/master 9308ee151 -> 11a45e2e2
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/test/scala/org/apache/zeppelin/cassandra/ParagraphParserTest.scala
----------------------------------------------------------------------
diff --git a/cassandra/src/test/scala/org/apache/zeppelin/cassandra/ParagraphParserTest.scala b/cassandra/src/test/scala/org/apache/zeppelin/cassandra/ParagraphParserTest.scala
index b1a8866..520f7a6 100644
--- a/cassandra/src/test/scala/org/apache/zeppelin/cassandra/ParagraphParserTest.scala
+++ b/cassandra/src/test/scala/org/apache/zeppelin/cassandra/ParagraphParserTest.scala
@@ -23,6 +23,8 @@ import org.scalatest.{BeforeAndAfterEach, FlatSpec, Matchers}
import org.apache.zeppelin.cassandra.ParagraphParser._
import org.apache.zeppelin.cassandra.TextBlockHierarchy._
+import scala.Option
+
class ParagraphParserTest extends FlatSpec
with BeforeAndAfterEach
with Matchers
@@ -57,34 +59,46 @@ class ParagraphParserTest extends FlatSpec
val parsed = parser.parse(parser.queries,query)
- parsed.get should be(List(
- SimpleStm("SELECT * FROM albums LIMIT 10;"),
- BatchStm(BatchStatement.Type.UNLOGGED,
- List(
- SimpleStm("INSERT INTO users(id) VALUES(10);"),
- BoundStm("test","'a',12.34")
- )
- ),
- SimpleStm("SELECT * FROM users LIMIT 10;"),
- BatchStm(BatchStatement.Type.LOGGED,
- List(
- SimpleStm("Insert INTO users(id) VALUES(11);"),
- SimpleStm("INSERT INTO users(id) VALUES(12);")
- )
- ),
- BoundStm("toto","'a',12.34"),
- DescribeTableCmd(Option("zeppelin"),"users"),
- DescribeKeyspaceCmd("zeppelin")
- ))
+ parsed should matchPattern {
+ case parser.Success(List(
+ SimpleStm("SELECT * FROM albums LIMIT 10;"),
+ BatchStm(BatchStatement.Type.UNLOGGED,
+ List(
+ SimpleStm("INSERT INTO users(id) VALUES(10);"),
+ BoundStm("test","'a',12.34")
+ )
+ ),
+ SimpleStm("SELECT * FROM users LIMIT 10;"),
+ BatchStm(BatchStatement.Type.LOGGED,
+ List(
+ SimpleStm("Insert INTO users(id) VALUES(11);"),
+ SimpleStm("INSERT INTO users(id) VALUES(12);")
+ )
+ ),
+ BoundStm("toto","'a',12.34"),
+ DescribeTableCmd(Some("zeppelin"),"users"),
+ DescribeKeyspaceCmd("zeppelin")
+ ),_) =>
+ }
}
- "Parser" should "parse single-line comment" in {
+ "Parser" should "parse hash single-line comment" in {
val query :CharSequence="""#This is a comment""".stripMargin
val parsed = parser.parseAll[Comment](parser.singleLineComment, query)
- parsed.get should be(Comment("This is a comment"))
+ parsed should matchPattern {
+ case parser.Success(Comment("This is a comment"), _) =>
+ }
}
+ "Parser" should "parse double slashes single-line comment" in {
+ val query :CharSequence="""//This is another comment""".stripMargin
+
+ val parsed = parser.parseAll[Comment](parser.singleLineComment, query)
+ parsed should matchPattern {
+ case parser.Success(Comment("This is another comment"), _) =>
+ }
+ }
"Parser" should "parse multi-line comment" in {
val query:String =
@@ -96,13 +110,17 @@ class ParagraphParserTest extends FlatSpec
""".stripMargin
val parsed = parser.parseAll(parser.multiLineComment, query)
- parsed.get should be(Comment("This is a comment\nline1\nline2\nline3\n"))
+ parsed should matchPattern {
+ case parser.Success(Comment("This is a comment\nline1\nline2\nline3\n"), _) =>
+ }
}
"Parser" should "parse consistency level" in {
val query:String =""" @consistency=ONE""".stripMargin
val parsed = parser.parseAll(parser.consistency, query)
- parsed.get should be(Consistency(ConsistencyLevel.ONE))
+ parsed should matchPattern {
+ case parser.Success(Consistency(ConsistencyLevel.ONE), _) =>
+ }
}
"Parser" should "fails parsing unknown consistency level" in {
@@ -116,7 +134,9 @@ class ParagraphParserTest extends FlatSpec
"Parser" should "parse serial consistency level" in {
val query:String =""" @serialConsistency=LOCAL_SERIAL""".stripMargin
val parsed = parser.parseAll(parser.serialConsistency, query)
- parsed.get should be(SerialConsistency(ConsistencyLevel.LOCAL_SERIAL))
+ parsed should matchPattern {
+ case parser.Success(SerialConsistency(ConsistencyLevel.LOCAL_SERIAL), _) =>
+ }
}
"Parser" should "fails parsing unknown serial consistency level" in {
@@ -130,7 +150,8 @@ class ParagraphParserTest extends FlatSpec
"Parser" should "parse timestamp" in {
val query:String =""" @timestamp=111""".stripMargin
val parsed = parser.parseAll(parser.timestamp, query)
- parsed.get should be(Timestamp(111L))
+ parsed should matchPattern {
+ case parser.Success(Timestamp(111L), _) => }
}
"Parser" should "fails parsing invalid timestamp" in {
@@ -144,7 +165,7 @@ class ParagraphParserTest extends FlatSpec
"Parser" should "parse retry policy" in {
val query:String ="@retryPolicy="+CassandraInterpreter.DOWNGRADING_CONSISTENCY_RETRY
val parsed = parser.parseAll(parser.retryPolicy, query)
- parsed.get should be(DowngradingRetryPolicy)
+ parsed should matchPattern {case parser.Success(DowngradingRetryPolicy, _) => }
}
"Parser" should "fails parsing invalid retry policy" in {
@@ -158,7 +179,7 @@ class ParagraphParserTest extends FlatSpec
"Parser" should "parse fetch size" in {
val query:String ="@fetchSize=100"
val parsed = parser.parseAll(parser.fetchSize, query)
- parsed.get should be(FetchSize(100))
+ parsed should matchPattern { case parser.Success(FetchSize(100), _) =>}
}
"Parser" should "fails parsing invalid fetch size" in {
@@ -177,7 +198,7 @@ class ParagraphParserTest extends FlatSpec
val parsed = parser.parseAll(parser.genericStatement, query)
//Then
- parsed.get should be(SimpleStm("sElecT * FROM users LIMIT ? ;"))
+ parsed should matchPattern { case parser.Success(SimpleStm("sElecT * FROM users LIMIT ? ;"), _) =>}
}
"Parser" should "parse prepare" in {
@@ -188,7 +209,7 @@ class ParagraphParserTest extends FlatSpec
val parsed = parser.parseAll(parser.prepare, query)
//Then
- parsed.get should be(PrepareStm("select_users","SELECT * FROM users LIMIT ?"))
+ parsed should matchPattern { case parser.Success(PrepareStm("select_users","SELECT * FROM users LIMIT ?"), _) => }
}
"Parser" should "fails parsing invalid prepared statement" in {
@@ -207,7 +228,7 @@ class ParagraphParserTest extends FlatSpec
val parsed = parser.parseAll(parser.removePrepare, query)
//Then
- parsed.get should be(RemovePrepareStm("select_users"))
+ parsed should matchPattern { case parser.Success(RemovePrepareStm("select_users"), _) => }
}
"Parser" should "fails parsing invalid remove prepared statement" in {
@@ -226,7 +247,7 @@ class ParagraphParserTest extends FlatSpec
val parsed = parser.parseAll(parser.bind, query)
//Then
- parsed.get should be(BoundStm("select_users","10,'toto'"))
+ parsed should matchPattern { case parser.Success(BoundStm("select_users","10,'toto'"), _) => }
}
"Parser" should "fails parsing invalid bind statement" in {
@@ -251,17 +272,17 @@ class ParagraphParserTest extends FlatSpec
val parsed = parser.parseAll(parser.batch, query)
//Then
- parsed.get should be(
- BatchStm(
- BatchStatement.Type.LOGGED,
- List[QueryStatement](
- SimpleStm("Insert INTO users(id) VALUES(10);"),
- BoundStm("select_users", "10,'toto'"),
- SimpleStm("update users SET name ='John DOE' WHERE id=10;"),
- SimpleStm("dElEtE users WHERE id=11;")
+ parsed should matchPattern {
+ case parser.Success(BatchStm(
+ BatchStatement.Type.LOGGED,
+ List(
+ SimpleStm("Insert INTO users(id) VALUES(10);"),
+ BoundStm("select_users", "10,'toto'"),
+ SimpleStm("update users SET name ='John DOE' WHERE id=10;"),
+ SimpleStm("dElEtE users WHERE id=11;")
)
- )
- )
+ ), _) =>
+ }
}
"Parser" should "fails parsing invalid batch type" in {
@@ -280,10 +301,12 @@ class ParagraphParserTest extends FlatSpec
val parsed = parser.parseAll(parser.queries, query)
- parsed.get should be (List(
- SerialConsistency(ConsistencyLevel.SERIAL),
- SimpleStm("SELECT * FROM zeppelin.artists LIMIT 1;")
- ))
+ parsed should matchPattern {
+ case parser.Success(List(
+ SerialConsistency(ConsistencyLevel.SERIAL),
+ SimpleStm("SELECT * FROM zeppelin.artists LIMIT 1;")
+ ), _) =>
+ }
}
"Parser" should "parse multi-line single statement" in {
@@ -292,13 +315,15 @@ class ParagraphParserTest extends FlatSpec
" title text PRIMARY KEY,\n" +
" artist text,\n" +
" year int\n" +
- ");\n";
+ ");\n"
val parsed = parser.parseAll(parser.queries, query)
- parsed.get should be (List(
- SimpleStm("CREATE TABLE IF NOT EXISTS zeppelin.albums(\n title text PRIMARY KEY,\n artist text,\n year int\n);")
- ))
+ parsed should matchPattern {
+ case parser.Success(List(
+ SimpleStm("CREATE TABLE IF NOT EXISTS zeppelin.albums(\n title text PRIMARY KEY,\n artist text,\n year int\n);")
+ ), _) =>
+ }
}
"Parser" should "parse multi-line statements" in {
@@ -316,11 +341,12 @@ class ParagraphParserTest extends FlatSpec
"APPLY BATCH;\n"+
"@timestamp=10\n" +
"@retryPolicy=DOWNGRADING_CONSISTENCY\n" +
- "SELECT * FROM zeppelin.albums;";
+ "SELECT * FROM zeppelin.albums;"
val parsed = parser.parseAll(parser.queries, query)
- parsed.get should be (List(
+ parsed should matchPattern {
+ case parser.Success(List(
SimpleStm("CREATE TABLE IF NOT EXISTS zeppelin.albums(\n title text PRIMARY KEY,\n artist text,\n year int\n);"),
Consistency(ConsistencyLevel.THREE),
SerialConsistency(ConsistencyLevel.SERIAL),
@@ -334,7 +360,8 @@ class ParagraphParserTest extends FlatSpec
Timestamp(10L),
DowngradingRetryPolicy,
SimpleStm("SELECT * FROM zeppelin.albums;")
- ))
+ ), _) =>
+ }
}
"Parser" should "parse mixed single-line and multi-line statements" in {
@@ -349,11 +376,12 @@ class ParagraphParserTest extends FlatSpec
" INSERT INTO zeppelin.albums(title,artist,year) VALUES('The Way You Are','Tears for Fears',1983);"+
" INSERT INTO zeppelin.albums(title,artist,year) VALUES('Primitive','Soulfly',2003);\n"+
"APPLY BATCH;"+
- "SELECT * FROM zeppelin.albums;";
+ "SELECT * FROM zeppelin.albums;"
val parsed = parser.parseAll(parser.queries, query)
- parsed.get should be (List(
+ parsed should matchPattern {
+ case parser.Success(List(
SimpleStm("CREATE TABLE IF NOT EXISTS zeppelin.albums(\n title text PRIMARY KEY,\n artist text,\n year int\n);"),
BatchStm(BatchStatement.Type.LOGGED,
List(
@@ -363,7 +391,8 @@ class ParagraphParserTest extends FlatSpec
)
),
SimpleStm("SELECT * FROM zeppelin.albums;")
- ))
+ ), _) =>
+ }
}
"Parser" should "parse a block queries with comments" in {
@@ -395,7 +424,8 @@ class ParagraphParserTest extends FlatSpec
val parsed = parser.parseAll(parser.queries, query)
- parsed.get should be (List(
+ parsed should matchPattern {
+ case parser.Success(List(
Comment("\n This example show how to force a\n timestamp on the query\n "),
Comment("Timestamp in the past"),
Timestamp(10L),
@@ -409,8 +439,9 @@ class ParagraphParserTest extends FlatSpec
SimpleStm("INSERT INTO spark_demo.ts(key,value) VALUES(1,'val2');"),
Comment("Check the result"),
SimpleStm("SELECT * FROM spark_demo.ts WHERE key=1;")
- )
- )
+ ), _
+ ) =>
+ }
}
"Parser" should "remove prepared statement" in {
@@ -426,13 +457,14 @@ class ParagraphParserTest extends FlatSpec
val parsed = parser.parseAll(parser.queries, queries)
- parsed.get should be(List(
+ parsed should matchPattern {
+ case parser.Success(List(
Comment("Removing an unknown statement should has no side effect"),
RemovePrepareStm("unknown_statement"),
RemovePrepareStm("select_artist_by_name"),
Comment("This should fail because the 'select_artist_by_name' has been removed"),
BoundStm("select_artist_by_name","'The Beatles'")
- ))
+ ), _) => }
}
"Parser" should "parse only parameter" in {
@@ -441,7 +473,9 @@ class ParagraphParserTest extends FlatSpec
val parsed = parser.parseAll(parser.queries, queries)
- parsed.get should be(List(FetchSize(1000)))
+ parsed should matchPattern {
+ case parser.Success(List(FetchSize(1000)), _) =>
+ }
}
@@ -450,7 +484,9 @@ class ParagraphParserTest extends FlatSpec
val parsed = parser.parseAll(parser.queries, queries)
- parsed.get(0) shouldBe a [DescribeClusterCmd]
+ parsed should matchPattern {
+ case parser.Success(List(DescribeClusterCmd("DESCRIBE CLUSTER;")), _) =>
+ }
}
"Parser" should "fail parsing describe cluster" in {
@@ -462,12 +498,33 @@ class ParagraphParserTest extends FlatSpec
ex.getMessage should be(s"Invalid syntax for DESCRIBE CLUSTER. It should comply to the pattern: ${DESCRIBE_CLUSTER_PATTERN.toString}")
}
+ "Parser" should "parse describe keyspace" in {
+ val queries ="Describe KeYsPaCe toto;"
+
+ val parsed = parser.parseAll(parser.queries, queries)
+
+ parsed should matchPattern {
+ case parser.Success(List(DescribeKeyspaceCmd("toto")), _) =>
+ }
+ }
+
+ "Parser" should "fail parsing describe keyspace" in {
+ val queries ="Describe KeYsPaCe toto"
+
+ val ex = intercept[InterpreterException] {
+ parser.parseAll(parser.queries, queries)
+ }
+ ex.getMessage should be(s"Invalid syntax for DESCRIBE KEYSPACE. It should comply to the pattern: ${DESCRIBE_KEYSPACE_PATTERN.toString}")
+ }
+
"Parser" should "parse describe keyspaces" in {
val queries ="Describe KeYsPaCeS;"
val parsed = parser.parseAll(parser.queries, queries)
- parsed.get(0) shouldBe a [DescribeKeyspacesCmd]
+ parsed should matchPattern {
+ case parser.Success(List(DescribeKeyspacesCmd("DESCRIBE KEYSPACES;")), _) =>
+ }
}
"Parser" should "fail parsing describe keyspaces" in {
@@ -479,12 +536,40 @@ class ParagraphParserTest extends FlatSpec
ex.getMessage should be(s"Invalid syntax for DESCRIBE KEYSPACES. It should comply to the pattern: ${DESCRIBE_KEYSPACES_PATTERN.toString}")
}
+ "Parser" should "parse describe table" in {
+ val queries ="Describe TaBlE toto;"
+
+ val parsed = parser.parseAll(parser.queries, queries)
+
+ parsed.get should be(List(DescribeTableCmd(None,"toto")))
+ }
+
+ "Parser" should "parse describe table with keyspace" in {
+ val queries ="Describe TaBlE ks.toto;"
+
+ val parsed = parser.parseAll(parser.queries, queries)
+
+ parsed.get should be(List(DescribeTableCmd(Some("ks"),"toto")))
+ }
+
+ "Parser" should "fail parsing describe table" in {
+ val queries ="Describe TaBlE toto"
+
+ val ex = intercept[InterpreterException] {
+ parser.parseAll(parser.queries, queries)
+ }
+ ex.getMessage should be(s"Invalid syntax for DESCRIBE TABLE. It should comply to the patterns: " +
+ s"${DESCRIBE_TABLE_WITH_KEYSPACE_PATTERN.toString} or ${DESCRIBE_TABLE_PATTERN.toString}")
+ }
+
"Parser" should "parse describe tables" in {
val queries ="Describe TaBlEs;"
val parsed = parser.parseAll(parser.queries, queries)
- parsed.get(0) shouldBe a [DescribeTablesCmd]
+ parsed should matchPattern {
+ case parser.Success(List(DescribeTablesCmd("DESCRIBE TABLES;")), _) =>
+ }
}
"Parser" should "fail parsing describe tables" in {
@@ -496,73 +581,206 @@ class ParagraphParserTest extends FlatSpec
ex.getMessage should be(s"Invalid syntax for DESCRIBE TABLES. It should comply to the pattern: ${DESCRIBE_TABLES_PATTERN.toString}")
}
- "Parser" should "parse describe keyspace" in {
- val queries ="Describe KeYsPaCe toto;"
+ "Parser" should "parse describe type" in {
+ val queries ="Describe Type toto;"
val parsed = parser.parseAll(parser.queries, queries)
- parsed.get should be(List(DescribeKeyspaceCmd("toto")))
+ parsed should matchPattern {
+ case parser.Success(List(DescribeTypeCmd(None, "toto")), _) =>
+ }
}
- "Parser" should "fail parsing describe keyspace" in {
- val queries ="Describe KeYsPaCe toto"
+ "Parser" should "parse describe type with keyspace" in {
+ val queries ="Describe Type ks.toto;"
+
+ val parsed = parser.parseAll(parser.queries, queries)
+
+ parsed should matchPattern {
+ case parser.Success(List(DescribeTypeCmd(Some("ks"), "toto")), _) =>
+ }
+ }
+
+ "Parser" should "fail parsing describe type" in {
+ val queries ="Describe Type toto"
val ex = intercept[InterpreterException] {
parser.parseAll(parser.queries, queries)
}
- ex.getMessage should be(s"Invalid syntax for DESCRIBE KEYSPACE. It should comply to the pattern: ${DESCRIBE_KEYSPACE_PATTERN.toString}")
+ ex.getMessage should be(s"Invalid syntax for DESCRIBE TYPE. It should comply to the patterns: " +
+ s"${DESCRIBE_TYPE_WITH_KEYSPACE_PATTERN.toString} or ${DESCRIBE_TYPE_PATTERN.toString}")
}
- "Parser" should "parse describe table" in {
- val queries ="Describe TaBlE toto;"
+ "Parser" should "parse describe types" in {
+ val queries ="Describe types;"
val parsed = parser.parseAll(parser.queries, queries)
- parsed.get should be(List(DescribeTableCmd(None,"toto")))
+ parsed should matchPattern {
+ case parser.Success(List(DescribeTypesCmd("DESCRIBE TYPES;")), _) =>
+ }
}
- "Parser" should "parse describe table with keyspace" in {
- val queries ="Describe TaBlE ks.toto;"
+ "Parser" should "fail parsing describe types" in {
+ val queries ="Describe types"
+
+ val ex = intercept[InterpreterException] {
+ parser.parseAll(parser.queries, queries)
+ }
+ ex.getMessage should be(s"Invalid syntax for DESCRIBE TYPES. It should comply to the pattern: ${DESCRIBE_TYPES_PATTERN.toString}")
+ }
+
+ "Parser" should "parse describe function" in {
+ val queries ="Describe function toto;"
val parsed = parser.parseAll(parser.queries, queries)
- parsed.get should be(List(DescribeTableCmd(Some("ks"),"toto")))
+ parsed should matchPattern {
+ case parser.Success(List(DescribeFunctionCmd(None,"toto")),_) =>
+ }
}
- "Parser" should "fail parsing describe table" in {
- val queries ="Describe TaBlE toto"
+
+
+ "Parser" should "parse describe function with keyspace" in {
+ val queries ="Describe function ks.toto;"
+
+ val parsed = parser.parseAll(parser.queries, queries)
+
+ parsed should matchPattern {
+ case parser.Success(List(DescribeFunctionCmd(Some("ks"), "toto")), _) =>
+ }
+ }
+
+ "Parser" should "fail parsing describe function" in {
+ val queries ="Describe function toto"
val ex = intercept[InterpreterException] {
parser.parseAll(parser.queries, queries)
}
- ex.getMessage should be(s"Invalid syntax for DESCRIBE TABLE. It should comply to the patterns: " +
- s"${DESCRIBE_TABLE_WITH_KEYSPACE_PATTERN.toString} or ${DESCRIBE_TABLE_PATTERN.toString}")
+ ex.getMessage should be(s"Invalid syntax for DESCRIBE FUNCTION. It should comply to the patterns: " +
+ s"${DESCRIBE_FUNCTION_WITH_KEYSPACE_PATTERN.toString} or ${DESCRIBE_FUNCTION_PATTERN.toString}")
}
- "Parser" should "parse describe type" in {
- val queries ="Describe Type toto;"
+ "Parser" should "parse describe functions" in {
+ val queries ="Describe functions;"
val parsed = parser.parseAll(parser.queries, queries)
- parsed.get should be(List(DescribeUDTCmd(None,"toto")))
+ parsed should matchPattern {
+ case parser.Success(List(DescribeFunctionsCmd("DESCRIBE FUNCTIONS;")), _) =>
+ }
+ }
+
+ "Parser" should "fail parsing describe functions" in {
+ val queries ="Describe functions toto"
+
+ val ex = intercept[InterpreterException] {
+ parser.parseAll(parser.queries, queries)
+ }
+ ex.getMessage should be(s"Invalid syntax for DESCRIBE FUNCTIONS. It should comply to the pattern: " +
+ s"${DESCRIBE_FUNCTIONS_PATTERN.toString}")
}
- "Parser" should "parse describe type with keyspace" in {
- val queries ="Describe Type ks.toto;"
+
+ "Parser" should "parse describe aggregate" in {
+ val queries ="Describe aggregate toto;"
val parsed = parser.parseAll(parser.queries, queries)
- parsed.get should be(List(DescribeUDTCmd(Some("ks"),"toto")))
+ parsed should matchPattern {
+ case parser.Success(List(DescribeAggregateCmd(None, "toto")), _) =>
+ }
}
- "Parser" should "fail parsing describe type" in {
- val queries ="Describe Type toto"
+ "Parser" should "parse describe aggregate with keyspace" in {
+ val queries ="Describe aggregate ks.toto;"
+
+ val parsed = parser.parseAll(parser.queries, queries)
+
+ parsed should matchPattern {
+ case parser.Success(List(DescribeAggregateCmd(Some("ks"),"toto")), _) =>
+ }
+ }
+
+ "Parser" should "fail parsing describe aggregate" in {
+ val queries ="Describe aggregate toto"
val ex = intercept[InterpreterException] {
parser.parseAll(parser.queries, queries)
}
- ex.getMessage should be(s"Invalid syntax for DESCRIBE TYPE. It should comply to the patterns: " +
- s"${DESCRIBE_TYPE_WITH_KEYSPACE_PATTERN.toString} or ${DESCRIBE_TYPE_PATTERN.toString}")
+ ex.getMessage should be(s"Invalid syntax for DESCRIBE AGGREGATE. It should comply to the patterns: " +
+ s"${DESCRIBE_AGGREGATE_WITH_KEYSPACE_PATTERN.toString} or ${DESCRIBE_AGGREGATE_PATTERN.toString}")
+ }
+
+ "Parser" should "parse describe aggregates" in {
+ val queries ="Describe aggregates;"
+
+ val parsed = parser.parseAll(parser.queries, queries)
+
+ parsed should matchPattern {
+ case parser.Success(List(DescribeAggregatesCmd("DESCRIBE AGGREGATES;")), _) =>
+ }
+ }
+
+ "Parser" should "fail parsing describe aggregates" in {
+ val queries ="Describe aggregates toto"
+
+ val ex = intercept[InterpreterException] {
+ parser.parseAll(parser.queries, queries)
+ }
+ ex.getMessage should be(s"Invalid syntax for DESCRIBE AGGREGATES. It should comply to the pattern: " +
+ s"${DESCRIBE_AGGREGATES_PATTERN.toString}")
+ }
+
+ "Parser" should "parse describe materialized view" in {
+ val queries ="Describe materialized view toto;"
+
+ val parsed = parser.parseAll(parser.queries, queries)
+
+ parsed should matchPattern {
+ case parser.Success(List(DescribeMaterializedViewCmd(None, "toto")), _) =>
+ }
+ }
+
+ "Parser" should "parse describe materialized view with keyspace" in {
+ val queries ="Describe materialized view ks.toto;"
+
+ val parsed = parser.parseAll(parser.queries, queries)
+
+ parsed should matchPattern {
+ case parser.Success(List(DescribeMaterializedViewCmd(Some("ks"), "toto")), _) =>
+ }
+ }
+
+ "Parser" should "fail parsing describe materialized view" in {
+ val queries ="Describe materialized view toto"
+
+ val ex = intercept[InterpreterException] {
+ parser.parseAll(parser.queries, queries)
+ }
+ ex.getMessage should be(s"Invalid syntax for DESCRIBE MATERIALIZED VIEW. It should comply to the patterns: " +
+ s"${DESCRIBE_MATERIALIZED_VIEW_WITH_KEYSPACE_PATTERN.toString} or ${DESCRIBE_MATERIALIZED_VIEW_PATTERN.toString}")
+ }
+
+ "Parser" should "parse describe materialized views" in {
+ val queries ="Describe materialized views;"
+
+ val parsed = parser.parseAll(parser.queries, queries)
+
+ parsed should matchPattern {
+ case parser.Success(List(DescribeMaterializedViewsCmd("DESCRIBE MATERIALIZED VIEWS;")), _) =>
+ }
+ }
+
+ "Parser" should "fail parsing describe materialized views" in {
+ val queries ="Describe materialized views toto"
+
+ val ex = intercept[InterpreterException] {
+ parser.parseAll(parser.queries, queries)
+ }
+ ex.getMessage should be(s"Invalid syntax for DESCRIBE MATERIALIZED VIEWS. It should comply to the pattern: " +
+ s"${DESCRIBE_MATERIALIZED_VIEWS_PATTERN.toString}")
}
"Parser" should "parse help" in {
@@ -570,7 +788,9 @@ class ParagraphParserTest extends FlatSpec
val parsed = parser.parseAll(parser.queries, queries)
- parsed.get(0) shouldBe a [HelpCmd]
+ parsed should matchPattern {
+ case parser.Success(List(HelpCmd("HELP;")), _) =>
+ }
}
"Parser" should "fail parsing help" in {
@@ -582,4 +802,146 @@ class ParagraphParserTest extends FlatSpec
ex.getMessage should be(s"Invalid syntax for HELP. It should comply to the patterns: " +
s"${HELP_PATTERN.toString}")
}
+
+ "Parser" should "parse CREATE FUNCTION" in {
+ val query = "CREATE FUNCTION keyspace.udf xxx AS 'return true;';"
+
+ val parsed = parser.parseAll(parser.queries, query)
+
+ parsed should matchPattern {
+ case parser.Success(List(SimpleStm(query)), _) =>
+ }
+
+ }
+
+ "Parser" should "parse CREATE OR REPLACE FUNCTION" in {
+ val query = "CREATE or Replace FUNCTION keyspace.udf xxx AS 'return true;';"
+
+ val parsed = parser.parseAll(parser.queries, query)
+
+ parsed should matchPattern {
+ case parser.Success(List(SimpleStm(query)), _) =>
+ }
+
+ }
+
+ "Parser" should "parse CREATE FUNCTION IF NOT Exists" in {
+ val query = "CREATE FUNCTION IF NOT EXISTS keyspace.udf xxx AS 'return true;';"
+
+ val parsed = parser.parseAll(parser.queries, query)
+
+ parsed should matchPattern {
+ case parser.Success(List(SimpleStm(query)), _) =>
+ }
+ }
+
+ "Parser" should "parse CREATE FUNCTION multiline with simple quote" in {
+ val query =
+ """CREATE FUNCTION IF NOT EXISTS keyspace.udf(input text) xxx
+ | CALLED ON NULL INPUT
+ | RETURN text
+ | LANGUAGE java
+ | AS '
+ | return input.toLowerCase("abc");
+ | ';""".stripMargin
+
+ val parsed = parser.parseAll(parser.queries, query)
+
+ parsed should matchPattern {
+ case parser.Success(List(SimpleStm(query)), _) =>
+ }
+ }
+
+ "Parser" should "parse CREATE FUNCTION multiline with double dollar" in {
+ val query =
+ """CREATE FUNCTION IF NOT EXISTS keyspace.udf(input text) xxx
+ | CALLED ON NULL INPUT
+ | RETURN text
+ | LANGUAGE java
+ | AS $$
+ | return input.toLowerCase("abc");
+ | $$;""".stripMargin
+
+ val parsed = parser.parseAll(parser.queries, query)
+
+ parsed should matchPattern {
+ case parser.Success(List(SimpleStm(query)), _) =>
+ }
+ }
+
+ "Parser" should "parse CREATE FUNCTION multiline with SELECT" in {
+
+ val udf =
+ """CREATE FUNCTION IF NOT EXISTS keyspace.udf(input text) xxx
+ | CALLED ON NULL INPUT
+ | RETURN text
+ | LANGUAGE java
+ | AS '
+ | return input.toLowerCase("abc");
+ | ';""".stripMargin
+
+ val select = "SELECT udf(val) from table WHERe id=1;"
+ val queries =
+ s"""$udf
+ |$select
+ """.stripMargin
+
+ val parsed = parser.parseAll(parser.queries, queries)
+
+ parsed should matchPattern {
+ case parser.Success(List(SimpleStm(udf), SimpleStm(select)), _) =>
+ }
+ }
+
+ "Parser" should "parse CREATE multiple FUNCTIONS" in {
+
+ val udf1 =
+ """CREATE FUNCTION IF NOT EXISTS keyspace.udf(input text) xxx
+ | CALLED ON NULL INPUT
+ | RETURN text
+ | LANGUAGE java
+ | AS '
+ | return input.toLowerCase("abc");
+ | ';""".stripMargin
+
+ val select = "SELECT * FROM keyspace.table;"
+
+ val udf2 = """CREATE FUNCTION IF NOT EXISTS keyspace.maxOf(val1 int, val2 int)
+ | CALLED ON NULL INPUT
+ | RETURN text
+ | LANGUAGE java
+ | AS '
+ | return Math.max(val1,val2);
+ | ';""".stripMargin
+
+ val queries =
+ s"""$udf1
+ |
+ |$select
+ |
+ |$udf2
+ """.stripMargin
+
+ val parsed = parser.parseAll(parser.queries, queries)
+
+ parsed.get.size should be(3)
+
+ parsed should matchPattern {
+ case parser.Success(List(SimpleStm(udf1), SimpleStm(select), SimpleStm(udf2)), _) =>
+ }
+ }
+
+ "Parser" should "parse CREATE Materialized View" in {
+ val query =
+ """CREATE MATERIALIZED VIEW xxx
+ | AS SELECT * FROM myTable
+ | WHERE partition IS NOT NULL
+ | PRIMARY KEY(col, partition);""".stripMargin
+
+ val parsed = parser.parseAll(parser.queries, query)
+
+ parsed should matchPattern {
+ case parser.Success(List(SimpleStm(query)), _) =>
+ }
+ }
}
[6/6] incubator-zeppelin git commit: [ZEPPELIN-559] Cassandra
interpreter v2
Posted by fe...@apache.org.
[ZEPPELIN-559] Cassandra interpreter v2
### What is this PR for?
* Update the **Cassandra** interpreter to V2 to support new **schema commands** to describe **Cassandra** 3.x features:
* User Defined Functions
* User Defined Aggregates
* Materialized Views
* Add support for single line comment using **double slashes** (//)
* Add **DESCRIBE TYPES**
* The Java driver version is bumped to **3.0.0-rc1**
* The contextual **HELP menu** is also updated and a _ChangeLog_ section is added.
### What type of PR is it?
[Improvement]
### Todos
* [x] - Add new PR to update official Cassandra interpreter with new features
* [x] - Test steps executed and confirmed working by the community
* [x] - Code review by the community (warning, **Scala** inside)
### Is there a relevant Jira issue?
**[ZEPPELIN-559]**
**[ZEPPELIN-575]** for doc
### How should this be tested?
1. Download and install locally **[Cassandra 3.1.1]**
2. Start **Cassandra**
3. Clone this pull request locally with:
1. _git fetch origin pull/600/head:CassandraInterpreterV2_
2. _git checkout CassandraInterpreterV2_
4. Build this version of Zeppelin with _mvn clean package -DskipTests_
5. Start **Zeppelin** and update the property _cassandra.hosts_ of the **Cassandra** interpreter (set it to _localhost_ or _127.0.0.1_ depending on your configuration)
6. In a paragraph, execute all the **CQL** statements given in this **[CassandraInterpreterV2TestData.cql]** by copy-pasting them
7. Start a new _%cassandra_ paragraph and execute **DESCRIBE FUNCTION test.maxOf;**. You should be able to see:
![image](https://cloud.githubusercontent.com/assets/1532977/12138932/edaf45d4-b45c-11e5-8724-104085d6e30d.png)
8. Start a new _%cassandra_ paragraph and execute **DESCRIBE AGGREGATE test.group_by;**. You should be able to see:
![image](https://cloud.githubusercontent.com/assets/1532977/12138970/2ecd784c-b45d-11e5-9076-a7b674439fa5.png)
9. Start a new _%cassandra_ paragraph and execute **DESCRIBE MATERIALIZED VIEW test.user_by_country;**. You should be able to see:
![image](https://cloud.githubusercontent.com/assets/1532977/12139025/a223a104-b45d-11e5-8331-b97323016fa3.png)
10. Start a new _%cassandra_ paragraph and execute **SELECT id,val1,val2,maxOf(val1,val2) FROM test.test_max;**. You should be able to see:
![image](https://cloud.githubusercontent.com/assets/1532977/12139046/c43febf8-b45d-11e5-9b96-290aff23730e.png)
11. Start a new _%cassandra_ paragraph and execute **SELECT group_by(category,sales_count) FROM test.items;**. You should be able to see:
![image](https://cloud.githubusercontent.com/assets/1532977/12139071/fb06b1e4-b45d-11e5-9077-6ec3275c1319.png)
12. Start a new _%cassandra_ paragraph and execute **SELECT * FROM test.user_by_country WHERE country='FR';**. You should be able to see:
![image](https://cloud.githubusercontent.com/assets/1532977/12139085/1671f3d0-b45e-11e5-9dc2-4bf6bd87e84e.png)
### Questions:
* Does the licenses files need update? --> **No**
* Is there breaking changes for older versions? --> **No**
* Does this needs documentation? --> **Yes**
[ZEPPELIN-559]: https://issues.apache.org/jira/browse/ZEPPELIN-559
[ZEPPELIN-575]: https://issues.apache.org/jira/browse/ZEPPELIN-575
[Cassandra 3.1.1]: http://cassandra.apache.org/download/
[CassandraInterpreterV2TestData.cql]: https://gist.githubusercontent.com/doanduyhai/5d88aaf3820be28474d2/raw/e5b5d9c325a17a58c2f27bff454db999fd3a3a66/CassandraInterpreterV2TestData.cql
Author: DuyHai DOAN <do...@gmail.com>
Closes #600 from doanduyhai/CassandraInterpreter-V2 and squashes the following commits:
36e3bdb [DuyHai DOAN] Fix random test failure
a2d831b [DuyHai DOAN] Refactor after code review
41b8667 [DuyHai DOAN] Tune regular expression for FUNCTION creation pattern
138804c [DuyHai DOAN] Fix CSS style for UDF & MV in menu display
6509da5 [DuyHai DOAN] Fix failing tests
7a5ac39 [DuyHai DOAN] Update RegExp for UDF creation to fix multiple statements match
6ea9e55 [DuyHai DOAN] Update help menu and changelog
6b46076 [DuyHai DOAN] Add Support for UDF, UDA and Materialized Views
058161d [DuyHai DOAN] Upgrade Java driver version to 3.0.0-rc1
Project: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/commit/11a45e2e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/tree/11a45e2e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/diff/11a45e2e
Branch: refs/heads/master
Commit: 11a45e2e225b404e5ca5f2f2137217202895d2d8
Parents: 9308ee1
Author: DuyHai DOAN <do...@gmail.com>
Authored: Sun Jan 10 15:44:53 2016 +0100
Committer: Felix Cheung <fe...@apache.org>
Committed: Sun Jan 24 10:04:46 2016 -0800
----------------------------------------------------------------------
cassandra/pom.xml | 30 +-
.../main/resources/scalate/aggregateDetails.ssp | 81 ++
.../main/resources/scalate/allAggregates.ssp | 68 ++
.../src/main/resources/scalate/allFunctions.ssp | 68 ++
.../resources/scalate/allMaterializedViews.ssp | 68 ++
.../src/main/resources/scalate/allTables.ssp | 8 -
.../src/main/resources/scalate/allUDTs.ssp | 61 ++
.../scalate/dropDownMenuForKeyspace.ssp | 37 +-
.../main/resources/scalate/functionDetails.ssp | 77 ++
.../src/main/resources/scalate/helpMenu.ssp | 135 ++-
.../main/resources/scalate/keyspaceContent.ssp | 90 ++
.../main/resources/scalate/keyspaceDetails.ssp | 2 +-
.../scalate/materializedViewDetails.ssp | 109 +++
cassandra/src/main/resources/scalate/menu.ssp | 22 +-
.../src/main/resources/scalate/tableDetails.ssp | 83 +-
.../src/main/resources/scalate/udtDetails.ssp | 2 +-
.../driver/core/TableMetadataWrapper.scala | 23 +
.../zeppelin/cassandra/DisplaySystem.scala | 417 +++++++--
.../zeppelin/cassandra/EnhancedSession.scala | 108 ++-
.../zeppelin/cassandra/InterpreterLogic.scala | 25 +-
.../zeppelin/cassandra/MetaDataHierarchy.scala | 31 +-
.../zeppelin/cassandra/ParagraphParser.scala | 188 +++-
.../zeppelin/cassandra/TextBlockHierarchy.scala | 54 +-
.../cassandra/CassandraInterpreterTest.java | 114 ++-
.../cassandra/InterpreterLogicTest.java | 4 +-
.../test/resources/scalate/DescribeCluster.html | 99 +--
.../scalate/DescribeKeyspace_live_data.html | 820 +----------------
.../resources/scalate/DescribeKeyspaces.html | 401 +--------
.../DescribeTable_live_data_complex_table.html | 327 +------
.../scalate/DescribeType_live_data_address.html | 138 +--
...ve_data_address_within_current_keyspace.html | 138 +--
cassandra/src/test/resources/scalate/Help.html | 871 +------------------
.../cassandra/ParagraphParserTest.scala | 544 ++++++++++--
33 files changed, 2122 insertions(+), 3121 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/pom.xml
----------------------------------------------------------------------
diff --git a/cassandra/pom.xml b/cassandra/pom.xml
index 57b501a..1b825b4 100644
--- a/cassandra/pom.xml
+++ b/cassandra/pom.xml
@@ -35,18 +35,19 @@
<url>http://zeppelin.incubator.apache.org</url>
<properties>
- <cassandra.driver.version>2.1.7.1</cassandra.driver.version>
+ <cassandra.driver.version>3.0.0-rc1</cassandra.driver.version>
<snappy.version>1.0.5.4</snappy.version>
- <lz4.version>1.2.0</lz4.version>
- <scala.version>2.11.7</scala.version>
- <scala.binary.version>2.11</scala.binary.version>
- <commons-lang.version>3.4</commons-lang.version>
+ <lz4.version>1.3.0</lz4.version>
+ <scala.version>2.10.4</scala.version>
+ <scala.binary.version>2.10</scala.binary.version>
+ <commons-lang.version>3.3.2</commons-lang.version>
<scalate.version>1.7.1</scalate.version>
+ <cassandra.guava.version>16.0.1</cassandra.guava.version>
<!--TEST-->
<scalatest.version>2.2.4</scalatest.version>
<junit.version>4.12</junit.version>
- <achilles.version>3.2.2</achilles.version>
+ <achilles.version>3.2.4-Zeppelin</achilles.version>
<assertj.version>1.7.0</assertj.version>
<mockito.version>1.9.5</mockito.version>
</properties>
@@ -65,6 +66,12 @@
<version>${cassandra.driver.version}</version>
</dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>${cassandra.guava.version}</version>
+ </dependency>
+
<!-- Compression libraries for the cassandra-driver protocol. -->
<!-- Include both compression options to make to simplify deployment. -->
@@ -130,7 +137,7 @@
<dependency>
<groupId>info.archinnov</groupId>
- <artifactId>achilles-junit</artifactId>
+ <artifactId>achilles-embedded</artifactId>
<version>${achilles.version}</version>
<scope>test</scope>
<exclusions>
@@ -146,13 +153,6 @@
</dependency>
<dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- <version>16.0</version>
- <scope>test</scope>
- </dependency>
-
- <dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
@@ -167,7 +167,6 @@
</dependency>
</dependencies>
-
<build>
<plugins>
<!-- Plugin to compile Scala code -->
@@ -293,7 +292,6 @@
</execution>
</executions>
</plugin>
-
</plugins>
</build>
</project>
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/resources/scalate/aggregateDetails.ssp
----------------------------------------------------------------------
diff --git a/cassandra/src/main/resources/scalate/aggregateDetails.ssp b/cassandra/src/main/resources/scalate/aggregateDetails.ssp
new file mode 100644
index 0000000..02800a2
--- /dev/null
+++ b/cassandra/src/main/resources/scalate/aggregateDetails.ssp
@@ -0,0 +1,81 @@
+<%--
+/*
+* 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.
+*/
+--%>
+#import(org.apache.zeppelin.cassandra.MetaDataHierarchy._)
+<%@ val sameNameAggregateDetails: SameNameAggregateDetails %>
+<%@ val withCaption: Boolean%>
+<div class="row">
+ <div class="col-md-2"/>
+ <div class="col-md-8 col-offset-md-2">
+ #for (aggregate <- sameNameAggregateDetails.aggregates)
+ <div class="panel panel-default table-responsive table-bordered">
+ <table class="table">
+ #if(withCaption)
+ <caption><h4 class="text-success"><i class="glyphicon glyphicon-retweet"/> ${aggregate.name}</h4></caption>
+ #end
+ <tbody>
+ <tr>
+ <td class="col-md-6"><strong>Keyspace</strong></td>
+ <td class="col-md-6 text-danger">${aggregate.keyspace}</td>
+ </tr>
+ <tr>
+ <td class="col-md-6"><strong>Arguments</strong></td>
+ <td class="col-md-6">${aggregate.arguments.toList.mkString(", ")}</td>
+ </tr>
+ <tr>
+ <td class="col-md-6"><strong>State Function</strong></td>
+ <td class="col-md-6">${aggregate.sFunc}</td>
+ </tr>
+ <tr>
+ <td class="col-md-6"><strong>State Type</strong></td>
+ <td class="col-md-6">${aggregate.sType}</td>
+ </tr>
+ #if(aggregate.finalFunc.isDefined)
+ <tr>
+ <td class="col-md-6"><strong>Final Function</strong></td>
+ <td class="col-md-6">${aggregate.finalFunc.get}</td>
+ </tr>
+ #end
+ #if(aggregate.initCond.isDefined)
+ <tr>
+ <td class="col-md-6"><strong>Initial State</strong></td>
+ <td class="col-md-6">${aggregate.initCond.get}</td>
+ </tr>
+ #end
+ <tr>
+ <td class="col-md-6"><strong>Return type</strong></td>
+ <td class="col-md-6">${aggregate.returnType}</td>
+ </tr>
+ </tbody>
+ </table>
+ <div class="panel-footer">
+ <a data-toggle="collapse" data-target="#${aggregate.uniqueId}_asCQL">
+ <strong>As CQL statement</strong>
+ <span class="caret"></span>
+ </a>
+ <br/><br/>
+ <div class="text-success collapse" id="${aggregate.uniqueId}_asCQL">
+ <pre class="well">${aggregate.asCQL}</pre>
+ </div>
+ </div>
+ </div>
+ <hr/>
+ #end
+ </div>
+ <div class="col-md-2"></div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/resources/scalate/allAggregates.ssp
----------------------------------------------------------------------
diff --git a/cassandra/src/main/resources/scalate/allAggregates.ssp b/cassandra/src/main/resources/scalate/allAggregates.ssp
new file mode 100644
index 0000000..f093c50
--- /dev/null
+++ b/cassandra/src/main/resources/scalate/allAggregates.ssp
@@ -0,0 +1,68 @@
+<%--
+/*
+* 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.
+*/
+--%>
+
+#import(org.apache.zeppelin.cassandra.MetaDataHierarchy._)
+#import(java.util.UUID)
+<%@ val allAggregates: Map[(UUID, String), List[AggregateSummary]] %>
+
+<div class="container">
+
+ <div class="row">
+ <div class="panel-group" role="tablist" aria-multiselectable="true">
+ #for (((ksId,ksName), aggregates) <- allAggregates)
+ <div class="panel panel-default">
+ <div class="panel-heading" role="tab">
+ <h4 class="panel-title">
+ <a role="button" data-toggle="collapse" data-target="#${ksId}" aria-expanded="false">
+ <span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> ${ksName}</span>
+ </a>
+ </h4>
+ </div>
+ <div id="${ksId}" class="panel-collapse collapse" role="tabpanel">
+ <div class="panel-body">
+ <div class="row">
+ <div class="col-md-2"/>
+ <div class="col-md-8 col-offset-md-2 table-responsive table-bordered">
+ <table class="table">
+ <thead>
+ <tr>
+ <th>Aggregate</th>
+ <th>Return Type</th>
+ </tr>
+ </thead>
+ <tbody>
+ #for (aggregate <- aggregates)
+ <tr class="text-success">
+ <td>${aggregate.name + aggregate.arguments.mkString("(", ", ", ")")}</td>
+ <td>${aggregate.returnType}</td>
+ </tr>
+ #end
+
+ </tbody>
+ </table>
+ </div>
+ <div class="col-md-2"/>
+ </div>
+ </div>
+ </div>
+ </div>
+ #end
+ </div>
+ </div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/resources/scalate/allFunctions.ssp
----------------------------------------------------------------------
diff --git a/cassandra/src/main/resources/scalate/allFunctions.ssp b/cassandra/src/main/resources/scalate/allFunctions.ssp
new file mode 100644
index 0000000..fc756a4
--- /dev/null
+++ b/cassandra/src/main/resources/scalate/allFunctions.ssp
@@ -0,0 +1,68 @@
+<%--
+/*
+* 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.
+*/
+--%>
+
+#import(org.apache.zeppelin.cassandra.MetaDataHierarchy._)
+#import(java.util.UUID)
+<%@ val allFunctions: Map[(UUID, String), List[FunctionSummary]] %>
+
+<div class="container">
+
+ <div class="row">
+ <div class="panel-group" role="tablist" aria-multiselectable="true">
+ #for (((ksId,ksName), functions) <- allFunctions)
+ <div class="panel panel-default">
+ <div class="panel-heading" role="tab">
+ <h4 class="panel-title">
+ <a role="button" data-toggle="collapse" data-target="#${ksId}" aria-expanded="false">
+ <span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> ${ksName}</span>
+ </a>
+ </h4>
+ </div>
+ <div id="${ksId}" class="panel-collapse collapse" role="tabpanel">
+ <div class="panel-body">
+ <div class="row">
+ <div class="col-md-2"/>
+ <div class="col-md-8 col-offset-md-2 table-responsive table-bordered">
+ <table class="table">
+ <thead>
+ <tr>
+ <th>Function</th>
+ <th>Return Type</th>
+ </tr>
+ </thead>
+ <tbody>
+ #for (function <- functions)
+ <tr class="text-success">
+ <td>${function.name + function.arguments.mkString("(",", ", ")")}</td>
+ <td>${function.returnType}</td>
+ </tr>
+ #end
+
+ </tbody>
+ </table>
+ </div>
+ <div class="col-md-2"/>
+ </div>
+ </div>
+ </div>
+ </div>
+ #end
+ </div>
+ </div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/resources/scalate/allMaterializedViews.ssp
----------------------------------------------------------------------
diff --git a/cassandra/src/main/resources/scalate/allMaterializedViews.ssp b/cassandra/src/main/resources/scalate/allMaterializedViews.ssp
new file mode 100644
index 0000000..8ffee57
--- /dev/null
+++ b/cassandra/src/main/resources/scalate/allMaterializedViews.ssp
@@ -0,0 +1,68 @@
+<%--
+/*
+* 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.
+*/
+--%>
+#import(org.apache.zeppelin.cassandra.MetaDataHierarchy._)
+#import(java.util.UUID)
+<%@ val allMVs: Map[(UUID,String),List[MaterializedViewSummary]] %>
+<div class="container">
+
+ <div class="row">
+ <div class="panel-group" role="tablist" aria-multiselectable="true">
+ #for (((ksId,ksName), mvs) <- allMVs)
+ <div class="panel panel-default">
+ <div class="panel-heading" role="tab">
+ <h4 class="panel-title">
+ <a role="button" data-toggle="collapse" data-target="#${ksId}" aria-expanded="false">
+ <span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> ${ksName}</span>
+ </a>
+ </h4>
+ </div>
+ <div id="${ksId}" class="panel-collapse collapse" role="tabpanel">
+ <div class="panel-body">
+ <div class="row">
+ <div class="col-md-2"/>
+ <div class="col-md-8 col-offset-md-2 table-responsive table-bordered">
+ <table class="table">
+ <thead>
+ <tr><th>Materialized View</th></tr>
+ </thead>
+ <tbody>
+ #for (mv <- mvs)
+
+ <tr class="text-primary">
+ <td>
+ ${mv.name}
+ <i class="glyphicon glyphicon-arrow-right"/>
+ <i class="glyphicon glyphicon-th-list"/>
+ ${mv.baseTable}
+ </td>
+ </tr>
+ #end
+
+ </tbody>
+ </table>
+ </div>
+ <div class="col-md-2"/>
+ </div>
+ </div>
+ </div>
+ </div>
+ #end
+ </div>
+ </div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/resources/scalate/allTables.ssp
----------------------------------------------------------------------
diff --git a/cassandra/src/main/resources/scalate/allTables.ssp b/cassandra/src/main/resources/scalate/allTables.ssp
index b363bee..810881b 100644
--- a/cassandra/src/main/resources/scalate/allTables.ssp
+++ b/cassandra/src/main/resources/scalate/allTables.ssp
@@ -24,7 +24,6 @@
<div class="row">
<div class="panel-group" role="tablist" aria-multiselectable="true">
#for (((ksId,ksName), tables) <- allTables)
-
<div class="panel panel-default">
<div class="panel-heading" role="tab">
<h4 class="panel-title">
@@ -38,8 +37,6 @@
<div class="row">
<div class="col-md-2"/>
<div class="col-md-8 col-offset-md-2 table-responsive table-bordered">
- #if (tables.nonEmpty)
-
<table class="table">
<thead>
<tr><th>Tables</th></tr>
@@ -52,10 +49,6 @@
</tbody>
</table>
- #else
- <span><h4>No Table</h4></span>
-
- #end
</div>
<div class="col-md-2"/>
</div>
@@ -63,7 +56,6 @@
</div>
</div>
#end
-
</div>
</div>
</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/resources/scalate/allUDTs.ssp
----------------------------------------------------------------------
diff --git a/cassandra/src/main/resources/scalate/allUDTs.ssp b/cassandra/src/main/resources/scalate/allUDTs.ssp
new file mode 100644
index 0000000..559ef41
--- /dev/null
+++ b/cassandra/src/main/resources/scalate/allUDTs.ssp
@@ -0,0 +1,61 @@
+<%--
+/*
+* 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.
+*/
+--%>
+#import(org.apache.zeppelin.cassandra.MetaDataHierarchy._)
+#import(java.util.UUID)
+<%@ val allUDTs: Map[(UUID,String),List[String]] %>
+<div class="container">
+
+ <div class="row">
+ <div class="panel-group" role="tablist" aria-multiselectable="true">
+ #for (((ksId,ksName), udts) <- allUDTs)
+ <div class="panel panel-default">
+ <div class="panel-heading" role="tab">
+ <h4 class="panel-title">
+ <a role="button" data-toggle="collapse" data-target="#${ksId}" aria-expanded="false">
+ <span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> ${ksName}</span>
+ </a>
+ </h4>
+ </div>
+ <div id="${ksId}" class="panel-collapse collapse" role="tabpanel">
+ <div class="panel-body">
+ <div class="row">
+ <div class="col-md-2"/>
+ <div class="col-md-8 col-offset-md-2 table-responsive table-bordered">
+ <table class="table">
+ <thead>
+ <tr><th>UDT</th></tr>
+ </thead>
+ <tbody>
+ #for (udt <- udts)
+
+ <tr class="text-warning"><td>${udt}</td></tr>
+ #end
+
+ </tbody>
+ </table>
+ </div>
+ <div class="col-md-2"/>
+ </div>
+ </div>
+ </div>
+ </div>
+ #end
+ </div>
+ </div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/resources/scalate/dropDownMenuForKeyspace.ssp
----------------------------------------------------------------------
diff --git a/cassandra/src/main/resources/scalate/dropDownMenuForKeyspace.ssp b/cassandra/src/main/resources/scalate/dropDownMenuForKeyspace.ssp
index 74f6fbc..6c2aad1 100644
--- a/cassandra/src/main/resources/scalate/dropDownMenuForKeyspace.ssp
+++ b/cassandra/src/main/resources/scalate/dropDownMenuForKeyspace.ssp
@@ -35,8 +35,19 @@
#end
#end
- #if(ksContent.udts.nonEmpty)
+ #if(ksContent.views.nonEmpty)
+ <li role="separator" class="divider text-muted"></li>
+ <li class="dropdown-header"><span class="text-primary">Materialized Views</span></li>
+ #for((id,name,_) <- ksContent.views)
+ <li>
+ <a role="button" data-toggle="collapse" data-target="#${id}">
+ <span class="text-primary"><i class="glyphicon glyphicon-eye-open"/> ${name}</span>
+ </a>
+ </li>
+ #end
+ #end
+ #if(ksContent.udts.nonEmpty)
<li role="separator" class="divider text-muted"></li>
<li class="dropdown-header"><span class="text-warning">User Defined Types</span></li>
#for((id,name,_) <- ksContent.udts)
@@ -47,6 +58,30 @@
</li>
#end
#end
+
+ #if(ksContent.functions.nonEmpty)
+ <li role="separator" class="divider text-muted"></li>
+ <li class="dropdown-header"><span class="text-success">Functions</span></li>
+ #for((id,name,_) <- ksContent.functions)
+ <li>
+ <a role="button" data-toggle="collapse" data-target="#${id}">
+ <span class="text-success"><i class="glyphicon glyphicon-random"/> ${name}</span>
+ </a>
+ </li>
+ #end
+ #end
+
+ #if(ksContent.aggregates.nonEmpty)
+ <li role="separator" class="divider text-muted"></li>
+ <li class="dropdown-header"><span class="text-success">Aggregates</span></li>
+ #for((id,name,_) <- ksContent.aggregates)
+ <li>
+ <a role="button" data-toggle="collapse" data-target="#${id}">
+ <span class="text-success"><i class="glyphicon glyphicon-retweet"/> ${name}</span>
+ </a>
+ </li>
+ #end
+ #end
</ul>
</a>
</li>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/resources/scalate/functionDetails.ssp
----------------------------------------------------------------------
diff --git a/cassandra/src/main/resources/scalate/functionDetails.ssp b/cassandra/src/main/resources/scalate/functionDetails.ssp
new file mode 100644
index 0000000..7d61400
--- /dev/null
+++ b/cassandra/src/main/resources/scalate/functionDetails.ssp
@@ -0,0 +1,77 @@
+<%--
+/*
+* 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.
+*/
+--%>
+#import(org.apache.zeppelin.cassandra.MetaDataHierarchy._)
+<%@ val sameNameFunctionDetails: SameNameFunctionDetails %>
+<%@ val withCaption: Boolean%>
+<div class="row">
+ <div class="col-md-2"/>
+ <div class="col-md-8 col-offset-md-2">
+ #for (function <- sameNameFunctionDetails.functions)
+ <div class="panel panel-default table-responsive table-bordered">
+ <table class="table">
+ #if(withCaption)
+ <caption><h4 class="text-success"><i class="glyphicon glyphicon-random"/> ${function.name}</h4></caption>
+ #end
+ <tbody>
+ <tr>
+ <td class="col-md-6"><strong>Keyspace</strong></td>
+ <td class="col-md-6 text-danger">${function.keyspace}</td>
+ </tr>
+ <tr>
+ <td class="col-md-6"><strong>Arguments</strong></td>
+ <td class="col-md-6">${function.arguments.toList.mkString(", ")}</td>
+ </tr>
+ <tr>
+ <td class="col-md-6"><strong>Null Input</strong></td>
+ #if(function.calledOnNullInput)
+ <td class="col-md-6">CALLED ON NULL INPUT</td>
+ #else
+ <td class="col-md-6">RETURN NULL ON NULL INPUT</td>
+ #end
+ </tr>
+ <tr>
+ <td class="col-md-6"><strong>Return type</strong></td>
+ <td class="col-md-6">${function.returnType}</td>
+ </tr>
+ <tr>
+ <td class="col-md-6"><strong>Language</strong></td>
+ <td class="col-md-6">${function.language}</td>
+ </tr>
+ <tr>
+ <td class="col-md-6"><strong>Body</strong></td>
+ <td class="col-md-6">${escape(function.body)}</td>
+ </tr>
+ </tbody>
+ </table>
+ <div class="panel-footer">
+ <a data-toggle="collapse" data-target="#${function.uniqueId}_asCQL">
+ <strong>As CQL statement</strong>
+ <span class="caret"></span>
+ </a>
+ <br/><br/>
+ <div class="text-success collapse" id="${function.uniqueId}_asCQL">
+ <pre class="well">${function.asCQL}</pre>
+ </div>
+ </div>
+ </div>
+ <hr/>
+ #end
+ </div>
+ <div class="col-md-2"></div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/resources/scalate/helpMenu.ssp
----------------------------------------------------------------------
diff --git a/cassandra/src/main/resources/scalate/helpMenu.ssp b/cassandra/src/main/resources/scalate/helpMenu.ssp
index 1c793ec..26ff117 100644
--- a/cassandra/src/main/resources/scalate/helpMenu.ssp
+++ b/cassandra/src/main/resources/scalate/helpMenu.ssp
@@ -27,7 +27,9 @@
<%@ val preparedStatementsId: UUID = UUIDs.random() %>
<%@ val dynamicFormsId: UUID = UUIDs.random() %>
<%@ val configurationId: UUID = UUIDs.random() %>
-<%@ val miscId: UUID = UUIDs.random() %>
+<%@ val sharedStatesId: UUID = UUIDs.random() %>
+<%@ val changelogId: UUID = UUIDs.random() %>
+<%@ val contactsId: UUID = UUIDs.random() %>
<br/>
<br/>
@@ -70,10 +72,20 @@
</a>
</li>
<li>
- <a role="button" data-toggle="collapse" data-target="#${miscId}">
- <span class="text-info"><i class="glyphicon glyphicon-bookmark"/> Misc</span>
+ <a role="button" data-toggle="collapse" data-target="#${sharedStatesId}">
+ <span class="text-info"><i class="glyphicon glyphicon-bookmark"/> Shared States</span>
</a>
</li>
+ <li>
+ <a role="button" data-toggle="collapse" data-target="#${changelogId}">
+ <span class="text-info"><i class="glyphicon glyphicon-bookmark"/> Change Log</span>
+ </a>
+ </li>
+ <li>
+ <a role="button" data-toggle="collapse" data-target="#${contactsId}">
+ <span class="text-info"><i class="glyphicon glyphicon-bookmark"/> Contacts & Bugs</span>
+ </a>
+ </li>
</ul>
</a>
</li>
@@ -91,12 +103,12 @@
<ul class="dropdown-menu">
<li>
<a role="button">
- <span class="text-info">Version <strong>1.0</strong></span>
+ <span class="text-info">Version <strong>2.0</strong></span>
</a>
</li>
<li>
<a role="button">
- <span class="text-info">Java Driver Version <strong>2.1.7.1</strong></span>
+ <span class="text-info">Java Driver Version <strong>3.0.0-rc1</strong></span>
</a>
</li>
<li>
@@ -237,7 +249,7 @@
<h3>II Comments</h3>
<p>
It is possible to add comments between statements. Single line comments start with the
- <strong>hash</strong> sign (#). Multi-line comments are enclosed between
+ <strong>hash</strong> sign (#) or <strong>double slashes</strong> (//). Multi-line comments are enclosed between
<strong>/**</strong> and <strong>**/</strong>. Ex:
<br/>
@@ -246,9 +258,12 @@
<div class="col-md-8 col-md-offset-2">
<pre>
- #First comment
+ #Single line comment style 1
INSERT INTO users(login,name) VALUES('jdoe','John DOE');
+ //Single line comment style 2
+
+
/**
Multi line
comments
@@ -314,6 +329,22 @@
<td>List all existing keyspaces in the cluster and for each, all the tables name</td>
</tr>
<tr>
+ <td><strong>DESCRIBE TYPES;</strong></td>
+ <td>List all existing keyspaces in the cluster and for each, all the types name</td>
+ </tr>
+ <tr>
+ <td><strong>DESCRIBE FUNCTIONS;</strong></td>
+ <td>List all existing keyspaces in the cluster and for each, all the functions name and arguments</td>
+ </tr>
+ <tr>
+ <td><strong>DESCRIBE AGGREGATES;</strong></td>
+ <td>List all existing keyspaces in the cluster and for each, all the aggregates name and arguments</td>
+ </tr>
+ <tr>
+ <td><strong>DESCRIBE MATERIALIZED VIEWS;</strong></td>
+ <td>List all existing keyspaces in the cluster and for each, all the materialized view name</td>
+ </tr>
+ <tr>
<td><strong>DESCRIBE KEYSPACE <keyspace name>;</strong></td>
<td>Describe the given keyspace configuration and all its table details (name, columns, ...)</td>
</tr>
@@ -333,6 +364,30 @@
the default <em>system</em> keyspace is used. If no type is found, an error message is raised
</td>
</tr>
+ <tr>
+ <td><strong>DESCRIBE FUNCTION <em>(<keyspace name>).</em><function name>;</strong></td>
+ <td>
+ Describe the given function. If the keyspace is not provided, the current
+ <strong>logged in</strong> keyspace is used. If there is no logged in keyspace,
+ the default <em>system</em> keyspace is used. If no function is found, an error message is raised
+ </td>
+ </tr>
+ <tr>
+ <td><strong>DESCRIBE AGGREGATE <em>(<keyspace name>).</em><aggregate name>;</strong></td>
+ <td>
+ Describe the given aggregate. If the keyspace is not provided, the current
+ <strong>logged in</strong> keyspace is used. If there is no logged in keyspace,
+ the default <em>system</em> keyspace is used. If no aggregate is found, an error message is raised
+ </td>
+ </tr>
+ <tr>
+ <td><strong>DESCRIBE MATERIALIZED VIEW <em>(<keyspace name>).</em><view name>;</strong></td>
+ <td>
+ Describe the given materialized view. If the keyspace is not provided, the current
+ <strong>logged in</strong> keyspace is used. If there is no logged in keyspace,
+ the default <em>system</em> keyspace is used. If no materialized view is found, an error message is raised
+ </td>
+ </tr>
</tbody>
</table>
<br/>
@@ -342,9 +397,7 @@
</p>
<h3>II Schema Display</h3>
<p>
- The schema objects (cluster, keyspace, table & type) are displayed in a tabular format.
- There is a <strong>drop-down</strong> menu on the top left corner to expand objects details.
- On the top right menu is shown the Icon legend.
+ The schema objects (cluster, keyspace, table, type, view, function & aggregate) are displayed in a tabular format. There is a <strong>drop-down</strong> menu on the top left corner to expand objects details. On the top right menu is shown the Icon legend.
</p>
</div>
@@ -886,16 +939,68 @@
<div class="panel panel-default">
<div class="panel-heading" role="tab">
<h4 class="panel-title">
- <a role="button" data-toggle="collapse" data-target="#${miscId}" aria-expanded="false">
- <span class="text-info"><strong>Miscellaneous</strong></span>
+ <a role="button" data-toggle="collapse" data-target="#${sharedStatesId}" aria-expanded="false">
+ <span class="text-info"><strong>Shared states</strong></span>
</a>
</h4>
</div>
- <div id="${miscId}" class="panel-collapse collapse" role="tabpanel">
+ <div id="${sharedStatesId}" class="panel-collapse collapse" role="tabpanel">
<div class="panel-body">
- <h3>Execution parallelism</h3>
- It is possible to execute many paragraphs in parallel. However, at the back-end side, we’re still using <strong>synchronous</strong> queries. Asynchronous execution is only possible when it is possible to return a Future value in the <strong>InterpreterResult</strong>. It may be an interesting proposal for the Zeppelin project.
+ It is possible to execute many paragraphs in parallel. However, at the back-end side, we’re still using synchronous queries. <em>Asynchronous execution</em> is only possible when it is possible to return a <strong>Future</strong> value in the <strong>InterpreterResult</strong>. It may be an interesting proposal for the <strong>Zeppelin</strong> project.
+ <br/>
+ Another caveat is that the same <strong>com.datastax.driver.core.Session</strong> object is used for <strong>all</strong> notebooks and paragraphs. Consequently, if you use the <em>USE keyspace name;</em> statement to log into a keyspace, it will change the keyspace for <strong>all current users</strong> of the Cassandra interpreter because we only create 1 <strong>com.datastax.driver.core.Session</strong> object per instance of <strong>Cassandra</strong> interpreter.
+ <br/>
+ The same remark does apply to the <strong>prepared statement hash map</strong>, it is shared by <strong>all users</strong> using the same instance of <strong>Cassandra</strong> interpreter.
+ <br/>
+ Until <strong>Zeppelin</strong> offers a real multi-users separation, there is a work-around to segregate user environment and states: <em>create different Cassandra interpreter instances</em>
+ <br/>
+ <ol>
+ <li>First go to the <strong>Interpreter</strong> menu and click on the <strong>Create</strong> button</li>
+ <li>In the interpreter creation form, put <strong>cass-instance2</strong> as <strong>Name</strong> and select the <strong>cassandra</strong> in the interpreter drop-down list</li>
+ <li>Click on <strong>Save</strong> to create the new interpreter instance. Now you should be able to see it in the interpreter list</li>
+ <li>Go back to your notebook and click on the <strong>Gear</strong> icon to configure interpreter bindings. You should be able to see and select the <strong>cass-instance2</strong> interpreter instance in the available interpreter list instead of the standard <strong>cassandra</strong> instance</li>
+ </ol>
</div>
</div>
+ </div>
+
+ <div class="panel panel-default">
+ <div class="panel-heading" role="tab">
+ <h4 class="panel-title">
+ <a role="button" data-toggle="collapse" data-target="#${changelogId}" aria-expanded="false">
+ <span class="text-info"><strong>Change Log</strong></span>
+ </a>
+ </h4>
+ </div>
+ <div id="${changelogId}" class="panel-collapse collapse" role="tabpanel">
+ <div class="panel-body">
+ <strong>2.0</strong> :
+ <br/>
+ <ul>
+ <li>Update help menu and add changelog</li>
+ <li>Add Support for User Defined Functions, User Defined Aggregates and Materialized Views</li>
+ <li>Upgrade Java driver version to <strong>3.0.0-rc1</strong></li>
+ </ul>
+ <strong>1.0</strong> :
+ <br/>
+ <ul>
+ <li>Initial version</li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <div class="panel panel-default">
+ <div class="panel-heading" role="tab">
+ <h4 class="panel-title">
+ <a role="button" data-toggle="collapse" data-target="#${contactsId}" aria-expanded="false">
+ <span class="text-info"><strong>Contact & Bugs</strong></span>
+ </a>
+ </h4>
+ </div>
+ <div id="${contactsId}" class="panel-collapse collapse" role="tabpanel">
+ <div class="panel-body">
+ If you encounter a bug for this interpreter, please create a <a href="https://issues.apache.org/jira/browse/ZEPPELIN-382?jql=project%20%3D%20ZEPPELIN" target="_blank"><strong>JIRA</strong></a> ticket and ping me on Twitter at <a href="https://twitter.com/doanduyhai" target="_blank"><strong>@doanduyhai</strong></a>
+ </div>
+ </div>
</div>
</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/resources/scalate/keyspaceContent.ssp
----------------------------------------------------------------------
diff --git a/cassandra/src/main/resources/scalate/keyspaceContent.ssp b/cassandra/src/main/resources/scalate/keyspaceContent.ssp
index 5139069..152c657 100644
--- a/cassandra/src/main/resources/scalate/keyspaceContent.ssp
+++ b/cassandra/src/main/resources/scalate/keyspaceContent.ssp
@@ -57,6 +57,36 @@
</div>
#end
+ #if (ksContent.views.nonEmpty)
+ <!-- Materialized Views -->
+ <table width="100%">
+ <td><hr /></td>
+ <td style="width:1px; padding: 0 10px; white-space: nowrap;"><strong class="text-primary">Materialized Views</strong></td>
+ <td><hr /></td>
+ </table>
+ <div class="row">
+ <div class="panel-group" role="tablist" aria-multiselectable="true">
+ #for((id,name,viewHTML) <- ksContent.views)
+
+ <div class="panel panel-default">
+ <div class="panel-heading" role="tab">
+ <h4 class="panel-title">
+ <a role="button" data-toggle="collapse" data-target="#${id}" aria-expanded="false">
+ <span class="text-primary"><i class="glyphicon glyphicon-eye-open"/> ${name}</span>
+ </a>
+ </h4>
+ </div>
+ <div id="${id}" class="panel-collapse collapse" role="tabpanel">
+ <div class="panel-body">
+ ${unescape(viewHTML)}
+ </div>
+ </div>
+ </div>
+ #end
+ </div>
+ </div>
+ #end
+
#if (ksContent.udts.nonEmpty)
<!-- UDTs -->
<table width="100%">
@@ -88,4 +118,64 @@
</div>
#end
+ #if (ksContent.functions.nonEmpty)
+ <!-- Functions -->
+ <table width="100%">
+ <td><hr /></td>
+ <td style="width:1px; padding: 0 10px; white-space: nowrap;"><strong class="text-success">Functions</strong></td>
+ <td><hr /></td>
+ </table>
+ <div class="row">
+ <div class="panel-group" role="tablist" aria-multiselectable="true">
+ #for((id,name,functionHTML) <- ksContent.functions)
+
+ <div class="panel panel-default">
+ <div class="panel-heading" role="tab">
+ <h4 class="panel-title">
+ <a role="button" data-toggle="collapse" data-target="#${id}" aria-expanded="false">
+ <span class="text-success"><i class="glyphicon glyphicon-random"/> ${name}</span>
+ </a>
+ </h4>
+ </div>
+ <div id="${id}" class="panel-collapse collapse" role="tabpanel">
+ <div class="panel-body">
+ ${unescape(functionHTML)}
+ </div>
+ </div>
+ </div>
+ #end
+ </div>
+ </div>
+ #end
+
+ #if (ksContent.aggregates.nonEmpty)
+ <!-- Aggregates -->
+ <table width="100%">
+ <td><hr /></td>
+ <td style="width:1px; padding: 0 10px; white-space: nowrap;"><strong class="text-success">Aggregates</strong></td>
+ <td><hr /></td>
+ </table>
+ <div class="row">
+ <div class="panel-group" role="tablist" aria-multiselectable="true">
+ #for((id,name,aggregateHTML) <- ksContent.aggregates)
+
+ <div class="panel panel-default">
+ <div class="panel-heading" role="tab">
+ <h4 class="panel-title">
+ <a role="button" data-toggle="collapse" data-target="#${id}" aria-expanded="false">
+ <span class="text-success"><i class="glyphicon glyphicon-retweet"/> ${name}</span>
+ </a>
+ </h4>
+ </div>
+ <div id="${id}" class="panel-collapse collapse" role="tabpanel">
+ <div class="panel-body">
+ ${unescape(aggregateHTML)}
+ </div>
+ </div>
+ </div>
+ #end
+ </div>
+ </div>
+ #end
+
</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/resources/scalate/keyspaceDetails.ssp
----------------------------------------------------------------------
diff --git a/cassandra/src/main/resources/scalate/keyspaceDetails.ssp b/cassandra/src/main/resources/scalate/keyspaceDetails.ssp
index beaf182..c0b9f8f 100644
--- a/cassandra/src/main/resources/scalate/keyspaceDetails.ssp
+++ b/cassandra/src/main/resources/scalate/keyspaceDetails.ssp
@@ -46,7 +46,7 @@
<tbody>
</table>
<div class="panel-footer">
- <a data-toggle="collapse" data-target="#${ksDetails.uniqueId}_asCQL">
+ <a data-toggle="collapse" data-target="#${ksDetails.uniqueId}_asCQL" class="text-danger">
<strong>As CQL statement</strong>
<span class="caret"></span>
</a>
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/resources/scalate/materializedViewDetails.ssp
----------------------------------------------------------------------
diff --git a/cassandra/src/main/resources/scalate/materializedViewDetails.ssp b/cassandra/src/main/resources/scalate/materializedViewDetails.ssp
new file mode 100644
index 0000000..459b5bc
--- /dev/null
+++ b/cassandra/src/main/resources/scalate/materializedViewDetails.ssp
@@ -0,0 +1,109 @@
+<%--
+/*
+* 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.
+*/
+--%>
+#import(org.apache.zeppelin.cassandra.MetaDataHierarchy._)
+<%@ val mvDetails: MaterializedViewDetails %>
+<%@ val withCaption: Boolean%>
+<div class="row">
+ <div class="col-md-2"/>
+ <div class="col-md-8 col-offset-md-2">
+ <div class="panel panel-default table-responsive table-bordered">
+ <table class="table">
+ #if(withCaption)
+ <caption>
+ <h4 class="text-primary">
+ <i class="glyphicon glyphicon-eye-open"/>
+ ${mvDetails.name}
+ <i class="glyphicon glyphicon-arrow-right"/>
+ <i class="glyphicon glyphicon-th-list"/>
+ ${mvDetails.baseTable}
+ </h4>
+ </caption>
+ #end
+ <thead>
+ <tr>
+ <th class="col-md-4">Column Type</th>
+ <th class="col-md-4">Column Name</th>
+ <th class="col-md-4">Data Type</th>
+ </tr>
+ </thead>
+ <tbody>
+ #for (column <- mvDetails.columns)
+ #match (column.columnType)
+ #case(PartitionKey)
+
+ <tr class="info">
+ <td class="col-md-4">
+ <i class="glyphicon glyphicon-fullscreen" title="Partition Key"/>
+ </td>
+ <td class="col-md-4">${column.name}</td>
+ <td class="col-md-4">${column.dataType}</td>
+ </tr>
+ #case(StaticColumn)
+ <tr class="warning">
+ <td class="col-md-4">
+ <i class="glyphicon glyphicon-pushpin" title="Static Column"/>
+ </td>
+ <td class="col-md-4">${column.name}</td>
+ <td class="col-md-4">${column.dataType}</td>
+ </tr>
+ #case(ClusteringColumn(ASC))
+ <tr class="success">
+ <td class="col-md-4">
+ <i class="glyphicon glyphicon-sort" title="Clustering Column"/>
+
+ <i class="glyphicon glyphicon-sort-by-attributes" title="Sort ASC"/>
+ </td>
+ <td class="col-md-4">${column.name}</td>
+ <td class="col-md-4">${column.dataType}</td>
+ </tr>
+ #case(ClusteringColumn(DESC))
+ <tr class="success">
+ <td class="col-md-4">
+ <i class="glyphicon glyphicon-sort" title="Clustering Column"/>
+
+ <i class="glyphicon glyphicon-sort-by-attributes-alt" title="Sort DESC"/>
+ </td>
+ <td class="col-md-4">${column.name}</td>
+ <td class="col-md-4">${column.dataType}</td>
+ </tr>
+ #otherwise
+ <tr>
+ <td class="col-md-4"></td>
+ <td class="col-md-4">${column.name}</td>
+ <td class="col-md-4">${column.dataType}</td>
+ </tr>
+ #end
+ #end
+
+ </tbody>
+ </table>
+ <div class="panel-footer">
+ <a data-toggle="collapse" data-target="#${mvDetails.uniqueId}_asCQL" class="text-primary">
+ <strong>As CQL statement</strong>
+ <span class="caret"></span>
+ </a>
+ <br/><br/>
+ <div class="collapse" id="${mvDetails.uniqueId}_asCQL">
+ <pre class="well">${mvDetails.asCQL}</pre>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="col-md-2"></div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/resources/scalate/menu.ssp
----------------------------------------------------------------------
diff --git a/cassandra/src/main/resources/scalate/menu.ssp b/cassandra/src/main/resources/scalate/menu.ssp
index 91afc8b..0d5a36e 100644
--- a/cassandra/src/main/resources/scalate/menu.ssp
+++ b/cassandra/src/main/resources/scalate/menu.ssp
@@ -54,6 +54,23 @@
<i class="glyphicon glyphicon-th-list text-primary" /> Table
</a>
</li>
+ <li>
+ <a role="button">
+ <i class="glyphicon glyphicon-eye-open text-primary" /> Materialized View
+ </a>
+ </li>
+ <li>
+ <a role="button">
+ <i class="glyphicon glyphicon-random text-success" /> Function
+ </a>
+ </li>
+ <li>
+ <a role="button">
+ <i class="glyphicon glyphicon-retweet text-success" /> Aggregate
+ </a>
+ </li>
+ <li role="separator" class="divider text-muted"></li>
+ <li class="dropdown-header"><span class="text-primary">Table icons</span></li>
<li class="bg-info">
<a role="button">
<i class="glyphicon glyphicon-fullscreen" /> Partition Key
@@ -79,11 +96,6 @@
<i class="glyphicon glyphicon-sort-by-attributes-alt" /> Clustering Order DESC
</a>
</li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-info-sign" /> Indexed Column
- </a>
- </li>
</ul>
</li>
<li>
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/resources/scalate/tableDetails.ssp
----------------------------------------------------------------------
diff --git a/cassandra/src/main/resources/scalate/tableDetails.ssp b/cassandra/src/main/resources/scalate/tableDetails.ssp
index 6cfbc49..41e4517 100644
--- a/cassandra/src/main/resources/scalate/tableDetails.ssp
+++ b/cassandra/src/main/resources/scalate/tableDetails.ssp
@@ -42,15 +42,6 @@
<tr class="info">
<td class="col-md-4">
<i class="glyphicon glyphicon-fullscreen" title="Partition Key"/>
- #match (column.index)
- #case (Some(index))
-
- <i class="glyphicon glyphicon-info-sign" title="Indexed Column"/>
- <em>${index.name}</em> <strong>${index.info}</strong>
- #case (None)
- <span></span>
- #end
-
</td>
<td class="col-md-4">${column.name}</td>
<td class="col-md-4">${column.dataType}</td>
@@ -59,15 +50,6 @@
<tr class="warning">
<td class="col-md-4">
<i class="glyphicon glyphicon-pushpin" title="Static Column"/>
- #match (column.index)
- #case (Some(index))
-
- <i class="glyphicon glyphicon-info-sign" title="Indexed Column"/>
- <em>${index.name}</em> <strong>${index.info}</strong>
- #case (None)
- <span></span>
- #end
-
</td>
<td class="col-md-4">${column.name}</td>
<td class="col-md-4">${column.dataType}</td>
@@ -78,15 +60,6 @@
<i class="glyphicon glyphicon-sort" title="Clustering Column"/>
<i class="glyphicon glyphicon-sort-by-attributes" title="Sort ASC"/>
- #match (column.index)
- #case (Some(index))
-
- <i class="glyphicon glyphicon-info-sign" title="Indexed Column"/>
- <em>${index.name}</em> <strong>${index.info}</strong>
- #case (None)
- <span></span>
- #end
-
</td>
<td class="col-md-4">${column.name}</td>
<td class="col-md-4">${column.dataType}</td>
@@ -97,32 +70,13 @@
<i class="glyphicon glyphicon-sort" title="Clustering Column"/>
<i class="glyphicon glyphicon-sort-by-attributes-alt" title="Sort DESC"/>
- #match (column.index)
- #case (Some(index))
-
- <i class="glyphicon glyphicon-info-sign" title="Indexed Column"/>
- <em>${index.name}</em> <strong>${index.info}</strong>
- #case (None)
- <span></span>
- #end
-
</td>
<td class="col-md-4">${column.name}</td>
<td class="col-md-4">${column.dataType}</td>
</tr>
#otherwise
<tr>
- <td class="col-md-4">
- #match (column.index)
- #case (Some(index))
-
- <i class="glyphicon glyphicon-info-sign" title="Indexed Column"/>
- <em>${index.name}</em> <strong>${index.info}</strong>
- #case (None)
- <span></span>
- #end
-
- </td>
+ <td class="col-md-4"></td>
<td class="col-md-4">${column.name}</td>
<td class="col-md-4">${column.dataType}</td>
</tr>
@@ -132,7 +86,7 @@
</tbody>
</table>
<div class="panel-footer">
- <a data-toggle="collapse" data-target="#${tableDetails.uniqueId}_asCQL">
+ <a data-toggle="collapse" data-target="#${tableDetails.uniqueId}_asCQL" class="text-primary">
<strong>As CQL statement</strong>
<span class="caret"></span>
</a>
@@ -142,6 +96,39 @@
</div>
</div>
</div>
+ #if(tableDetails.indices.size > 0)
+ <hr/>
+ <div class="panel panel-default table-responsive table-bordered">
+ <table class="table">
+ <caption><h4 class="text-danger"><i class="glyphicon glyphicon-info-sign"/> ${tableDetails.tableName}'s indices</h4>
+ </caption>
+ <thead>
+ <tr>
+ <th class="col-md-6">Name</th>
+ <th class="col-md-6">Target</th>
+ </tr>
+ </thead>
+ <tbody>
+ #for (index <- tableDetails.indices)
+ <tr>
+ <td class="col-md-6">${index.name}</td>
+ <td class="col-md-6">${index.target}</td>
+ </tr>
+ #end
+ </tbody>
+ </table>
+ <div class="panel-footer">
+ <a data-toggle="collapse" data-target="#${tableDetails.uniqueId}_indices_asCQL" class="text-danger">
+ <strong>As CQL statement</strong>
+ <span class="caret"></span>
+ </a>
+ <br/><br/>
+ <div class="collapse" id="${tableDetails.uniqueId}_indices_asCQL">
+ <pre class="well">${tableDetails.indicesAsCQL}</pre>
+ </div>
+ </div>
+ </div>
+ #end
</div>
<div class="col-md-2"></div>
</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/resources/scalate/udtDetails.ssp
----------------------------------------------------------------------
diff --git a/cassandra/src/main/resources/scalate/udtDetails.ssp b/cassandra/src/main/resources/scalate/udtDetails.ssp
index 80380a4..28858f2 100644
--- a/cassandra/src/main/resources/scalate/udtDetails.ssp
+++ b/cassandra/src/main/resources/scalate/udtDetails.ssp
@@ -46,7 +46,7 @@
<tbody>
</table>
<div class="panel-footer">
- <a data-toggle="collapse" data-target="#${udtDetails.uniqueId}_asCQL">
+ <a data-toggle="collapse" data-target="#${udtDetails.uniqueId}_asCQL" class="text-warning">
<strong>As CQL statement</strong>
<span class="caret"></span>
</a>
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/scala/com/datastax/driver/core/TableMetadataWrapper.scala
----------------------------------------------------------------------
diff --git a/cassandra/src/main/scala/com/datastax/driver/core/TableMetadataWrapper.scala b/cassandra/src/main/scala/com/datastax/driver/core/TableMetadataWrapper.scala
new file mode 100644
index 0000000..feddbe1
--- /dev/null
+++ b/cassandra/src/main/scala/com/datastax/driver/core/TableMetadataWrapper.scala
@@ -0,0 +1,23 @@
+/*
+ * 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 com.datastax.driver.core
+
+case class TableMetadataWrapper(val meta: TableMetadata) {
+ def exportTableOnlyAsString(): String = {
+ meta.asCQLQuery(true)
+ }
+}
[3/6] incubator-zeppelin git commit: [ZEPPELIN-559] Cassandra
interpreter v2
Posted by fe...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/test/resources/scalate/DescribeKeyspaces.html
----------------------------------------------------------------------
diff --git a/cassandra/src/test/resources/scalate/DescribeKeyspaces.html b/cassandra/src/test/resources/scalate/DescribeKeyspaces.html
index 77293ab..b5c364e 100644
--- a/cassandra/src/test/resources/scalate/DescribeKeyspaces.html
+++ b/cassandra/src/test/resources/scalate/DescribeKeyspaces.html
@@ -1,400 +1 @@
-<br/>
-<br/>
-<nav class="navbar navbar-default">
- <ul class="nav navbar-nav">
-
- <li role="presentation" class="dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
- <span class="text-muted"><i class="glyphicon glyphicon-dashboard"/> <strong>Test Cluster</strong></span>
- <span class="text-muted caret"></span>
- <ul class="dropdown-menu">
- <li class="dropdown-header"><span class="text-danger">Keyspaces</span></li>
- <li>
- <a role="button" data-toggle="collapse" data-target="#8f72f0b0-3518-11e5-aee3-8f0ea8ae1a37">
- <span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> live_data</span>
- </a>
- </li>
- <li>
- <a role="button" data-toggle="collapse" data-target="#8fb85e20-3518-11e5-aee3-8f0ea8ae1a37">
- <span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> samples</span>
- </a>
- </li>
- <li>
- <a role="button" data-toggle="collapse" data-target="#8fb996a0-3518-11e5-aee3-8f0ea8ae1a37">
- <span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> system</span>
- </a>
- </li>
- <li>
- <a role="button" data-toggle="collapse" data-target="#8fb9e4c0-3518-11e5-aee3-8f0ea8ae1a37">
- <span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> system_traces</span>
- </a>
- </li>
- <li>
- <a role="button" data-toggle="collapse" data-target="#8fba32e0-3518-11e5-aee3-8f0ea8ae1a37">
- <span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> zeppelin</span>
- </a>
- </li>
- </ul>
- </a>
- </li>
-
- <li>
- <a><strong>DESCRIBE KEYSPACES;</strong></a>
- </li>
- </ul>
- <ul class="nav navbar-nav navbar-right">
- <li class="dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
- <strong>Legend</strong>
- <span class="caret"></span>
- </a>
- <ul class="dropdown-menu">
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-dashboard text-muted" /> Cluster
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-folder-open text-danger" /> Keyspace
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-copyright-mark text-warning" /> UDT
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-th-list text-primary" /> Table
- </a>
- </li>
- <li class="bg-info">
- <a role="button">
- <i class="glyphicon glyphicon-fullscreen" /> Partition Key
- </a>
- </li>
- <li class="bg-warning">
- <a role="button">
- <i class="glyphicon glyphicon-pushpin" /> Static Column
- </a>
- </li>
- <li class="bg-success">
- <a role="button">
- <i class="glyphicon glyphicon-sort" /> Clustering Column
- </a>
- </li>
- <li class="bg-success">
- <a role="button">
- <i class="glyphicon glyphicon-sort-by-attributes" /> Clustering Order ASC
- </a>
- </li>
- <li class="bg-success">
- <a role="button">
- <i class="glyphicon glyphicon-sort-by-attributes-alt" /> Clustering Order DESC
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-info-sign" /> Indexed Column
- </a>
- </li>
- </ul>
- </li>
- <li>
- <a href="#"></a>
- </li>
- </ul>
-</nav>
-<hr/>
-<div class="container">
- <!-- Cluster -->
-
- <div class="row">
- <div class="col-md-4"></div>
- <div class="col-md-4 col-offset-md-4">
- <div class="table-responsive table-bordered">
- <table class="table">
- <caption>
- <h4 class="text-muted">
- <i class="glyphicon glyphicon-dashboard"/> Test Cluster
- </h4>
- </caption>
- <thead>
- <tr>
- <th>Partitioner</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>org.apache.cassandra.dht.Murmur3Partitioner</td>
- </tr>
- <tbody>
- </table>
- </div>
- </div>
- </div>
-
-
- <div class="row"></div>
- <!-- Keyspaces -->
- <table width="100%">
- <td><hr /></td>
- <td style="width:1px; padding: 0 10px; white-space: nowrap;"><strong class="text-danger">Keyspaces</strong></td>
- <td><hr /></td>
- </table>
- <div class="row">
- <div class="panel-group" role="tablist" aria-multiselectable="true">
-
- <div class="panel panel-default">
- <div class="panel-heading" role="tab">
- <h4 class="panel-title">
- <a role="button" data-toggle="collapse" data-target="#8f72f0b0-3518-11e5-aee3-8f0ea8ae1a37" aria-expanded="false">
- <span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> live_data</span>
- </a>
- </h4>
- </div>
- <div id="8f72f0b0-3518-11e5-aee3-8f0ea8ae1a37" class="panel-collapse collapse" role="tabpanel">
- <div class="panel-body">
-
-
- <div class="row">
- <div class="col-md-2"></div>
- <div class="col-md-8 col-offset-md-2">
- <div class="panel panel-default table-responsive table-bordered">
- <table class="table">
- <thead>
- <tr>
- <th class="col-md-10">Replication</th>
- <th class="col-md-2">Durable Writes</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td class="col-md-10">{'replication_factor' : '1', 'class' : 'org.apache.cassandra.locator.SimpleStrategy'}</td>
- <td class="col-md-2">false</td>
- </tr>
- <tbody>
- </table>
- <div class="panel-footer">
- <a data-toggle="collapse" data-target="#8f738cf0-3518-11e5-aee3-8f0ea8ae1a37_asCQL">
- <strong>As CQL statement</strong>
- <span class="caret"></span>
- </a>
- <br/><br/>
- <div class="collapse" id="8f738cf0-3518-11e5-aee3-8f0ea8ae1a37_asCQL">
- <pre class="well">CREATE KEYSPACE live_data WITH REPLICATION = {
- 'class' : 'org.apache.cassandra.locator.SimpleStrategy',
- 'replication_factor': '1' }
-AND DURABLE_WRITES = false;</pre>
- </div>
- </div>
- </div>
- </div>
- <div class="col-md-2"></div>
- </div>
- </div>
- </div>
- </div>
- <div class="panel panel-default">
- <div class="panel-heading" role="tab">
- <h4 class="panel-title">
- <a role="button" data-toggle="collapse" data-target="#8fb85e20-3518-11e5-aee3-8f0ea8ae1a37" aria-expanded="false">
- <span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> samples</span>
- </a>
- </h4>
- </div>
- <div id="8fb85e20-3518-11e5-aee3-8f0ea8ae1a37" class="panel-collapse collapse" role="tabpanel">
- <div class="panel-body">
-
-
- <div class="row">
- <div class="col-md-2"></div>
- <div class="col-md-8 col-offset-md-2">
- <div class="panel panel-default table-responsive table-bordered">
- <table class="table">
- <thead>
- <tr>
- <th class="col-md-10">Replication</th>
- <th class="col-md-2">Durable Writes</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td class="col-md-10">{'replication_factor' : '1', 'class' : 'org.apache.cassandra.locator.SimpleStrategy'}</td>
- <td class="col-md-2">false</td>
- </tr>
- <tbody>
- </table>
- <div class="panel-footer">
- <a data-toggle="collapse" data-target="#8fb85e21-3518-11e5-aee3-8f0ea8ae1a37_asCQL">
- <strong>As CQL statement</strong>
- <span class="caret"></span>
- </a>
- <br/><br/>
- <div class="collapse" id="8fb85e21-3518-11e5-aee3-8f0ea8ae1a37_asCQL">
- <pre class="well">CREATE KEYSPACE samples WITH REPLICATION = {
- 'class' : 'org.apache.cassandra.locator.SimpleStrategy',
- 'replication_factor': '1' }
-AND DURABLE_WRITES = false;</pre>
- </div>
- </div>
- </div>
- </div>
- <div class="col-md-2"></div>
- </div>
- </div>
- </div>
- </div>
- <div class="panel panel-default">
- <div class="panel-heading" role="tab">
- <h4 class="panel-title">
- <a role="button" data-toggle="collapse" data-target="#8fb996a0-3518-11e5-aee3-8f0ea8ae1a37" aria-expanded="false">
- <span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> system</span>
- </a>
- </h4>
- </div>
- <div id="8fb996a0-3518-11e5-aee3-8f0ea8ae1a37" class="panel-collapse collapse" role="tabpanel">
- <div class="panel-body">
-
-
- <div class="row">
- <div class="col-md-2"></div>
- <div class="col-md-8 col-offset-md-2">
- <div class="panel panel-default table-responsive table-bordered">
- <table class="table">
- <thead>
- <tr>
- <th class="col-md-10">Replication</th>
- <th class="col-md-2">Durable Writes</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td class="col-md-10">{'class' : 'org.apache.cassandra.locator.LocalStrategy'}</td>
- <td class="col-md-2">true</td>
- </tr>
- <tbody>
- </table>
- <div class="panel-footer">
- <a data-toggle="collapse" data-target="#8fb9bdb0-3518-11e5-aee3-8f0ea8ae1a37_asCQL">
- <strong>As CQL statement</strong>
- <span class="caret"></span>
- </a>
- <br/><br/>
- <div class="collapse" id="8fb9bdb0-3518-11e5-aee3-8f0ea8ae1a37_asCQL">
- <pre class="well">CREATE KEYSPACE system WITH REPLICATION = {
- 'class' : 'org.apache.cassandra.locator.LocalStrategy' }
-AND DURABLE_WRITES = true;</pre>
- </div>
- </div>
- </div>
- </div>
- <div class="col-md-2"></div>
- </div>
- </div>
- </div>
- </div>
- <div class="panel panel-default">
- <div class="panel-heading" role="tab">
- <h4 class="panel-title">
- <a role="button" data-toggle="collapse" data-target="#8fb9e4c0-3518-11e5-aee3-8f0ea8ae1a37" aria-expanded="false">
- <span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> system_traces</span>
- </a>
- </h4>
- </div>
- <div id="8fb9e4c0-3518-11e5-aee3-8f0ea8ae1a37" class="panel-collapse collapse" role="tabpanel">
- <div class="panel-body">
-
-
- <div class="row">
- <div class="col-md-2"></div>
- <div class="col-md-8 col-offset-md-2">
- <div class="panel panel-default table-responsive table-bordered">
- <table class="table">
- <thead>
- <tr>
- <th class="col-md-10">Replication</th>
- <th class="col-md-2">Durable Writes</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td class="col-md-10">{'replication_factor' : '2', 'class' : 'org.apache.cassandra.locator.SimpleStrategy'}</td>
- <td class="col-md-2">true</td>
- </tr>
- <tbody>
- </table>
- <div class="panel-footer">
- <a data-toggle="collapse" data-target="#8fb9e4c1-3518-11e5-aee3-8f0ea8ae1a37_asCQL">
- <strong>As CQL statement</strong>
- <span class="caret"></span>
- </a>
- <br/><br/>
- <div class="collapse" id="8fb9e4c1-3518-11e5-aee3-8f0ea8ae1a37_asCQL">
- <pre class="well">CREATE KEYSPACE system_traces WITH REPLICATION = {
- 'class' : 'org.apache.cassandra.locator.SimpleStrategy',
- 'replication_factor': '2' }
-AND DURABLE_WRITES = true;</pre>
- </div>
- </div>
- </div>
- </div>
- <div class="col-md-2"></div>
- </div>
- </div>
- </div>
- </div>
- <div class="panel panel-default">
- <div class="panel-heading" role="tab">
- <h4 class="panel-title">
- <a role="button" data-toggle="collapse" data-target="#8fba32e0-3518-11e5-aee3-8f0ea8ae1a37" aria-expanded="false">
- <span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> zeppelin</span>
- </a>
- </h4>
- </div>
- <div id="8fba32e0-3518-11e5-aee3-8f0ea8ae1a37" class="panel-collapse collapse" role="tabpanel">
- <div class="panel-body">
-
-
- <div class="row">
- <div class="col-md-2"></div>
- <div class="col-md-8 col-offset-md-2">
- <div class="panel panel-default table-responsive table-bordered">
- <table class="table">
- <thead>
- <tr>
- <th class="col-md-10">Replication</th>
- <th class="col-md-2">Durable Writes</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td class="col-md-10">{'replication_factor' : '1', 'class' : 'org.apache.cassandra.locator.SimpleStrategy'}</td>
- <td class="col-md-2">false</td>
- </tr>
- <tbody>
- </table>
- <div class="panel-footer">
- <a data-toggle="collapse" data-target="#8fba32e1-3518-11e5-aee3-8f0ea8ae1a37_asCQL">
- <strong>As CQL statement</strong>
- <span class="caret"></span>
- </a>
- <br/><br/>
- <div class="collapse" id="8fba32e1-3518-11e5-aee3-8f0ea8ae1a37_asCQL">
- <pre class="well">CREATE KEYSPACE zeppelin WITH REPLICATION = {
- 'class' : 'org.apache.cassandra.locator.SimpleStrategy',
- 'replication_factor': '1' }
-AND DURABLE_WRITES = false;</pre>
- </div>
- </div>
- </div>
- </div>
- <div class="col-md-2"></div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
-</div>
\ No newline at end of file
+<br/><br/><nav class="navbar navbar-default"><ul class="nav navbar-nav"><li role="presentation" class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="text-muted"><i class="glyphicon glyphicon-dashboard"/> <strong>Test Cluster</strong></span><span class="text-muted caret"></span><ul class="dropdown-menu"><li class="dropdown-header"><span class="text-danger">Keyspaces</span></li><li><a role="button" data-toggle="collapse" ><span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> live_data</span></a></li><li><a role="button" data-toggle="collapse" ><span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> samples</span></a></li><li><a role="button" data-toggle="collapse" ><span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> system</span></a></li><li><a role="button" data-toggle="collapse" ><span class="text-danger"><i clas
s="glyphicon glyphicon-folder-open"/> system_auth</span></a></li><li><a role="button" data-toggle="collapse" ><span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> system_distributed</span></a></li><li><a role="button" data-toggle="collapse" ><span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> system_traces</span></a></li><li><a role="button" data-toggle="collapse" ><span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> zeppelin</span></a></li></ul></a></li><li><a><strong>DESCRIBE KEYSPACES;</strong></a></li></ul><ul class="nav navbar-nav navbar-right"><li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><strong>Legend</strong><span class="caret"></span></a><ul class="dropdown-menu"><li><a role="button"><i class="glyphicon glyphicon-dashboard text-muted" /> Cluster</a></li><li><a role="button"><i class="glyphi
con glyphicon-folder-open text-danger" /> Keyspace</a></li><li><a role="button"><i class="glyphicon glyphicon-copyright-mark text-warning" /> UDT</a></li><li><a role="button"><i class="glyphicon glyphicon-th-list text-primary" /> Table</a></li><li><a role="button"><i class="glyphicon glyphicon-eye-open text-primary" /> Materialized View</a></li><li><a role="button"><i class="glyphicon glyphicon-random text-success" /> Function</a></li><li><a role="button"><i class="glyphicon glyphicon-retweet text-success" /> Aggregate</a></li><li role="separator" class="divider text-muted"></li><li class="dropdown-header"><span class="text-primary">Table icons</span></li><li class="bg-info"><a role="button"><i class="glyphicon glyphicon-fullscreen" /> Partition Key</a></li><li class="bg-warning"><a role="button"><i class="glyphicon glyphicon-pushpin" /> Static Column</a></li><li class="bg-success"><a role="butto
n"><i class="glyphicon glyphicon-sort" /> Clustering Column</a></li><li class="bg-success"><a role="button"><i class="glyphicon glyphicon-sort-by-attributes" /> Clustering Order ASC</a></li><li class="bg-success"><a role="button"><i class="glyphicon glyphicon-sort-by-attributes-alt" /> Clustering Order DESC</a></li></ul></li><li><a href="#"></a></li></ul></nav><hr/><div class="container"><!-- Cluster --><div class="row"><div class="col-md-4"></div><div class="col-md-4 col-offset-md-4"><div class="table-responsive table-bordered"><table class="table"><caption><h4 class="text-muted"><i class="glyphicon glyphicon-dashboard"/> Test Cluster</h4></caption><thead><tr><th>Partitioner</th></tr></thead><tbody><tr><td>org.apache.cassandra.dht.Murmur3Partitioner</td></tr><tbody></table></div></div></div><div class="row"></div><!-- Keyspaces --><table width="100%"><td><hr /></td><td style="width:1px; padding: 0 10px; white-space: nowrap;"><strong class="text
-danger">Keyspaces</strong></td><td><hr /></td></table><div class="row"><div class="panel-group" role="tablist" aria-multiselectable="true"><div class="panel panel-default"><div class="panel-heading" role="tab"><h4 class="panel-title"><a role="button" data-toggle="collapse" aria-expanded="false"><span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> live_data</span></a></h4></div><div class="panel-collapse collapse" role="tabpanel"><div class="panel-body"><div class="row"><div class="col-md-2"></div><div class="col-md-8 col-offset-md-2"><div class="panel panel-default table-responsive table-bordered"><table class="table"><thead><tr><th class="col-md-10">Replication</th><th class="col-md-2">Durable Writes</th></tr></thead><tbody><tr><td class="col-md-10">{'replication_factor' : '1', 'class' : 'org.apache.cassandra.locator.SimpleStrategy'}</td><td class="col-md-2">false</td></tr><tbody></table><div class="panel-footer"><a data-toggle="collapse" class="tex
t-danger"><strong>As CQL statement</strong><span class="caret"></span></a><br/><br/><div class="collapse" ><pre class="well">CREATE KEYSPACE live_data WITH REPLICATION = {'class' : 'org.apache.cassandra.locator.SimpleStrategy','replication_factor': '1' }AND DURABLE_WRITES = false;</pre></div></div></div></div><div class="col-md-2"></div></div></div></div></div><div class="panel panel-default"><div class="panel-heading" role="tab"><h4 class="panel-title"><a role="button" data-toggle="collapse" aria-expanded="false"><span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> samples</span></a></h4></div><div class="panel-collapse collapse" role="tabpanel"><div class="panel-body"><div class="row"><div class="col-md-2"></div><div class="col-md-8 col-offset-md-2"><div class="panel panel-default table-responsive table-bordered"><table class="table"><thead><tr><th class="col-md-10">Replication</th><th class="col-md-2">Durable Writes</th></tr></thead><tbody><tr><td c
lass="col-md-10">{'replication_factor' : '1', 'class' : 'org.apache.cassandra.locator.SimpleStrategy'}</td><td class="col-md-2">false</td></tr><tbody></table><div class="panel-footer"><a data-toggle="collapse" class="text-danger"><strong>As CQL statement</strong><span class="caret"></span></a><br/><br/><div class="collapse" ><pre class="well">CREATE KEYSPACE samples WITH REPLICATION = {'class' : 'org.apache.cassandra.locator.SimpleStrategy','replication_factor': '1' }AND DURABLE_WRITES = false;</pre></div></div></div></div><div class="col-md-2"></div></div></div></div></div><div class="panel panel-default"><div class="panel-heading" role="tab"><h4 class="panel-title"><a role="button" data-toggle="collapse" aria-expanded="false"><span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> system</span></a></h4></div><div class="panel-collapse collapse" role="tabpanel"><div class="panel-body"><div class="row"><div class="col-md-2"></div><div class="col-md-8 col
-offset-md-2"><div class="panel panel-default table-responsive table-bordered"><table class="table"><thead><tr><th class="col-md-10">Replication</th><th class="col-md-2">Durable Writes</th></tr></thead><tbody><tr><td class="col-md-10">{'class' : 'org.apache.cassandra.locator.LocalStrategy'}</td><td class="col-md-2">true</td></tr><tbody></table><div class="panel-footer"><a data-toggle="collapse" class="text-danger"><strong>As CQL statement</strong><span class="caret"></span></a><br/><br/><div class="collapse" ><pre class="well">CREATE KEYSPACE system WITH REPLICATION = {'class' : 'org.apache.cassandra.locator.LocalStrategy' }AND DURABLE_WRITES = true;</pre></div></div></div></div><div class="col-md-2"></div></div></div></div></div><div class="panel panel-default"><div class="panel-heading" role="tab"><h4 class="panel-title"><a role="button" data-toggle="collapse" aria-expanded="false"><span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> system_auth</spa
n></a></h4></div><div class="panel-collapse collapse" role="tabpanel"><div class="panel-body"><div class="row"><div class="col-md-2"></div><div class="col-md-8 col-offset-md-2"><div class="panel panel-default table-responsive table-bordered"><table class="table"><thead><tr><th class="col-md-10">Replication</th><th class="col-md-2">Durable Writes</th></tr></thead><tbody><tr><td class="col-md-10">{'replication_factor' : '1', 'class' : 'org.apache.cassandra.locator.SimpleStrategy'}</td><td class="col-md-2">true</td></tr><tbody></table><div class="panel-footer"><a data-toggle="collapse" class="text-danger"><strong>As CQL statement</strong><span class="caret"></span></a><br/><br/><div class="collapse" ><pre class="well">CREATE KEYSPACE system_auth WITH REPLICATION = {'class' : 'org.apache.cassandra.locator.SimpleStrategy','replication_factor': '1' }AND DURABLE_WRITES = true;</pre></div></div></div></div><div class="col-md-2"></div></div></div></div></div><div class="panel panel-default
"><div class="panel-heading" role="tab"><h4 class="panel-title"><a role="button" data-toggle="collapse" aria-expanded="false"><span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> system_distributed</span></a></h4></div><div class="panel-collapse collapse" role="tabpanel"><div class="panel-body"><div class="row"><div class="col-md-2"></div><div class="col-md-8 col-offset-md-2"><div class="panel panel-default table-responsive table-bordered"><table class="table"><thead><tr><th class="col-md-10">Replication</th><th class="col-md-2">Durable Writes</th></tr></thead><tbody><tr><td class="col-md-10">{'replication_factor' : '3', 'class' : 'org.apache.cassandra.locator.SimpleStrategy'}</td><td class="col-md-2">true</td></tr><tbody></table><div class="panel-footer"><a data-toggle="collapse" class="text-danger"><strong>As CQL statement</strong><span class="caret"></span></a><br/><br/><div class="collapse" ><pre class="well">CREATE KEYSPACE system_distributed WIT
H REPLICATION = {'class' : 'org.apache.cassandra.locator.SimpleStrategy','replication_factor': '3' }AND DURABLE_WRITES = true;</pre></div></div></div></div><div class="col-md-2"></div></div></div></div></div><div class="panel panel-default"><div class="panel-heading" role="tab"><h4 class="panel-title"><a role="button" data-toggle="collapse" aria-expanded="false"><span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> system_traces</span></a></h4></div><div class="panel-collapse collapse" role="tabpanel"><div class="panel-body"><div class="row"><div class="col-md-2"></div><div class="col-md-8 col-offset-md-2"><div class="panel panel-default table-responsive table-bordered"><table class="table"><thead><tr><th class="col-md-10">Replication</th><th class="col-md-2">Durable Writes</th></tr></thead><tbody><tr><td class="col-md-10">{'replication_factor' : '2', 'class' : 'org.apache.cassandra.locator.SimpleStrategy'}</td><td class="col-md-2">true</td></tr><tbody>
</table><div class="panel-footer"><a data-toggle="collapse" class="text-danger"><strong>As CQL statement</strong><span class="caret"></span></a><br/><br/><div class="collapse" ><pre class="well">CREATE KEYSPACE system_traces WITH REPLICATION = {'class' : 'org.apache.cassandra.locator.SimpleStrategy','replication_factor': '2' }AND DURABLE_WRITES = true;</pre></div></div></div></div><div class="col-md-2"></div></div></div></div></div><div class="panel panel-default"><div class="panel-heading" role="tab"><h4 class="panel-title"><a role="button" data-toggle="collapse" aria-expanded="false"><span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> zeppelin</span></a></h4></div><div class="panel-collapse collapse" role="tabpanel"><div class="panel-body"><div class="row"><div class="col-md-2"></div><div class="col-md-8 col-offset-md-2"><div class="panel panel-default table-responsive table-bordered"><table class="table"><thead><tr><th class="col-md-10">Replicatio
n</th><th class="col-md-2">Durable Writes</th></tr></thead><tbody><tr><td class="col-md-10">{'replication_factor' : '1', 'class' : 'org.apache.cassandra.locator.SimpleStrategy'}</td><td class="col-md-2">true</td></tr><tbody></table><div class="panel-footer"><a data-toggle="collapse" class="text-danger"><strong>As CQL statement</strong><span class="caret"></span></a><br/><br/><div class="collapse" ><pre class="well">CREATE KEYSPACE zeppelin WITH REPLICATION = {'class' : 'org.apache.cassandra.locator.SimpleStrategy','replication_factor': '1' }AND DURABLE_WRITES = true;</pre></div></div></div></div><div class="col-md-2"></div></div></div></div></div></div></div></div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/test/resources/scalate/DescribeTable_live_data_complex_table.html
----------------------------------------------------------------------
diff --git a/cassandra/src/test/resources/scalate/DescribeTable_live_data_complex_table.html b/cassandra/src/test/resources/scalate/DescribeTable_live_data_complex_table.html
index 9ff84f1..fd3ee67 100644
--- a/cassandra/src/test/resources/scalate/DescribeTable_live_data_complex_table.html
+++ b/cassandra/src/test/resources/scalate/DescribeTable_live_data_complex_table.html
@@ -1,326 +1 @@
-<br/>
-<br/>
-<nav class="navbar navbar-default">
- <ul class="nav navbar-nav">
-
- <li>
- <a><strong>DESCRIBE TABLE live_data.complex_table;</strong></a>
- </li>
- </ul>
- <ul class="nav navbar-nav navbar-right">
- <li class="dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
- <strong>Legend</strong>
- <span class="caret"></span>
- </a>
- <ul class="dropdown-menu">
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-dashboard text-muted" /> Cluster
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-folder-open text-danger" /> Keyspace
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-copyright-mark text-warning" /> UDT
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-th-list text-primary" /> Table
- </a>
- </li>
- <li class="bg-info">
- <a role="button">
- <i class="glyphicon glyphicon-fullscreen" /> Partition Key
- </a>
- </li>
- <li class="bg-warning">
- <a role="button">
- <i class="glyphicon glyphicon-pushpin" /> Static Column
- </a>
- </li>
- <li class="bg-success">
- <a role="button">
- <i class="glyphicon glyphicon-sort" /> Clustering Column
- </a>
- </li>
- <li class="bg-success">
- <a role="button">
- <i class="glyphicon glyphicon-sort-by-attributes" /> Clustering Order ASC
- </a>
- </li>
- <li class="bg-success">
- <a role="button">
- <i class="glyphicon glyphicon-sort-by-attributes-alt" /> Clustering Order DESC
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-info-sign" /> Indexed Column
- </a>
- </li>
- </ul>
- </li>
- <li>
- <a href="#"></a>
- </li>
- </ul>
-</nav>
-<hr/>
-<div class="row">
- <div class="col-md-2"/>
- <div class="col-md-8 col-offset-md-2">
- <div class="panel panel-default table-responsive table-bordered">
- <table class="table">
-
- <caption><h4 class="text-primary"><i class="glyphicon glyphicon-th-list"/> complex_table</h4></caption>
- <thead>
- <tr>
- <th class="col-md-4">Column Type</th>
- <th class="col-md-4">Column Name</th>
- <th class="col-md-4">Data Type</th>
- </tr>
- </thead>
- <tbody>
-
-
- <tr class="info">
- <td class="col-md-4">
- <i class="glyphicon glyphicon-fullscreen" title="Partition Key"/>
-
- <span></span>
-
- </td>
- <td class="col-md-4">pk1</td>
- <td class="col-md-4">uuid</td>
- </tr>
-
-
- <tr class="info">
- <td class="col-md-4">
- <i class="glyphicon glyphicon-fullscreen" title="Partition Key"/>
-
-
- <i class="glyphicon glyphicon-info-sign" title="Indexed Column"/>
- <em>pk2idx</em> <strong></strong>
-
- </td>
- <td class="col-md-4">pk2</td>
- <td class="col-md-4">int</td>
- </tr>
-
- <tr class="warning">
- <td class="col-md-4">
- <i class="glyphicon glyphicon-pushpin" title="Static Column"/>
-
- <span></span>
-
- </td>
- <td class="col-md-4">my_static1</td>
- <td class="col-md-4">text</td>
- </tr>
-
- <tr class="warning">
- <td class="col-md-4">
- <i class="glyphicon glyphicon-pushpin" title="Static Column"/>
-
- <span></span>
-
- </td>
- <td class="col-md-4">my_static2</td>
- <td class="col-md-4">text</td>
- </tr>
-
- <tr class="success">
- <td class="col-md-4">
- <i class="glyphicon glyphicon-sort" title="Clustering Column"/>
-
- <i class="glyphicon glyphicon-sort-by-attributes-alt" title="Sort DESC"/>
-
- <span></span>
-
- </td>
- <td class="col-md-4">clustering1</td>
- <td class="col-md-4">timestamp</td>
- </tr>
-
- <tr class="success">
- <td class="col-md-4">
- <i class="glyphicon glyphicon-sort" title="Clustering Column"/>
-
- <i class="glyphicon glyphicon-sort-by-attributes" title="Sort ASC"/>
-
-
- <i class="glyphicon glyphicon-info-sign" title="Indexed Column"/>
- <em>clustering2idx</em> <strong></strong>
-
- </td>
- <td class="col-md-4">clustering2</td>
- <td class="col-md-4">int</td>
- </tr>
-
- <tr class="success">
- <td class="col-md-4">
- <i class="glyphicon glyphicon-sort" title="Clustering Column"/>
-
- <i class="glyphicon glyphicon-sort-by-attributes-alt" title="Sort DESC"/>
-
- <span></span>
-
- </td>
- <td class="col-md-4">clustering3</td>
- <td class="col-md-4">text</td>
- </tr>
-
- <tr>
- <td class="col-md-4">
-
- <span></span>
-
- </td>
- <td class="col-md-4">entries_indexed_map</td>
- <td class="col-md-4">map<int, text></td>
- </tr>
-
- <tr>
- <td class="col-md-4">
-
-
- <i class="glyphicon glyphicon-info-sign" title="Indexed Column"/>
- <em>idx1</em> <strong></strong>
-
- </td>
- <td class="col-md-4">indexed1</td>
- <td class="col-md-4">text</td>
- </tr>
-
- <tr>
- <td class="col-md-4">
-
-
- <i class="glyphicon glyphicon-info-sign" title="Indexed Column"/>
- <em>idx2</em> <strong></strong>
-
- </td>
- <td class="col-md-4">indexed2</td>
- <td class="col-md-4">int</td>
- </tr>
-
- <tr>
- <td class="col-md-4">
-
-
- <i class="glyphicon glyphicon-info-sign" title="Indexed Column"/>
- <em>keys_map_idx</em> <strong></strong>
-
- </td>
- <td class="col-md-4">key_indexed_map</td>
- <td class="col-md-4">map<int, text></td>
- </tr>
-
- <tr>
- <td class="col-md-4">
-
- <span></span>
-
- </td>
- <td class="col-md-4">my_list</td>
- <td class="col-md-4">list<text></td>
- </tr>
-
- <tr>
- <td class="col-md-4">
-
- <span></span>
-
- </td>
- <td class="col-md-4">my_map</td>
- <td class="col-md-4">map<int, text></td>
- </tr>
-
- <tr>
- <td class="col-md-4">
-
- <span></span>
-
- </td>
- <td class="col-md-4">my_udt</td>
- <td class="col-md-4">frozen<live_data.address></td>
- </tr>
-
- <tr>
- <td class="col-md-4">
-
- <span></span>
-
- </td>
- <td class="col-md-4">my_udt_list</td>
- <td class="col-md-4">frozen<list<frozen<live_data.address>>></td>
- </tr>
-
- <tr>
- <td class="col-md-4">
-
- <span></span>
-
- </td>
- <td class="col-md-4">simple</td>
- <td class="col-md-4">double</td>
- </tr>
-
- </tbody>
- </table>
- <div class="panel-footer">
- <a data-toggle="collapse" data-target="#26dd4330-350d-11e5-9539-8f0ea8ae1a37_asCQL">
- <strong>As CQL statement</strong>
- <span class="caret"></span>
- </a>
- <br/><br/>
- <div class="collapse" id="26dd4330-350d-11e5-9539-8f0ea8ae1a37_asCQL">
- <pre class="well">CREATE TABLE live_data.complex_table (
- pk1 uuid,
- pk2 int,
- clustering1 timestamp,
- clustering2 int,
- clustering3 text,
- entries_indexed_map map<int, text>,
- indexed1 text,
- indexed2 int,
- key_indexed_map map<int, text>,
- my_list list<text>,
- my_map map<int, text>,
- my_static1 text static,
- my_static2 text static,
- my_udt frozen<live_data.address>,
- my_udt_list frozen<list<frozen<live_data.address>>>,
- simple double,
- PRIMARY KEY ((pk1, pk2), clustering1, clustering2, clustering3)
-) WITH CLUSTERING ORDER BY (clustering1 DESC, clustering2 ASC, clustering3 DESC)
- AND read_repair_chance = 0.0
- AND dclocal_read_repair_chance = 0.1
- AND gc_grace_seconds = 864000
- AND bloom_filter_fp_chance = 0.01
- AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' }
- AND comment = ''
- AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy' }
- AND compression = { 'sstable_compression' : 'org.apache.cassandra.io.compress.LZ4Compressor' }
- AND default_time_to_live = 0
- AND speculative_retry = '99.0PERCENTILE'
- AND min_index_interval = 128
- AND max_index_interval = 2048;
-CREATE INDEX pk2idx ON live_data.complex_table (pk2);
-CREATE INDEX clustering2idx ON live_data.complex_table (clustering2);
-CREATE INDEX idx1 ON live_data.complex_table (indexed1);
-CREATE INDEX idx2 ON live_data.complex_table (indexed2);
-CREATE INDEX keys_map_idx ON live_data.complex_table (KEYS(key_indexed_map));</pre>
- </div>
- </div>
- </div>
- </div>
- <div class="col-md-2"></div>
-</div>
\ No newline at end of file
+<br/><br/><nav class="navbar navbar-default"><ul class="nav navbar-nav"><li><a><strong>DESCRIBE TABLE live_data.complex_table;</strong></a></li></ul><ul class="nav navbar-nav navbar-right"><li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><strong>Legend</strong><span class="caret"></span></a><ul class="dropdown-menu"><li><a role="button"><i class="glyphicon glyphicon-dashboard text-muted" /> Cluster</a></li><li><a role="button"><i class="glyphicon glyphicon-folder-open text-danger" /> Keyspace</a></li><li><a role="button"><i class="glyphicon glyphicon-copyright-mark text-warning" /> UDT</a></li><li><a role="button"><i class="glyphicon glyphicon-th-list text-primary" /> Table</a></li><li><a role="button"><i class="glyphicon glyphicon-eye-open text-primary" /> Materialized View</a></li><li><a role="button"><i class="glyphicon glyphicon-random text-success" />&
nbsp; Function</a></li><li><a role="button"><i class="glyphicon glyphicon-retweet text-success" /> Aggregate</a></li><li role="separator" class="divider text-muted"></li><li class="dropdown-header"><span class="text-primary">Table icons</span></li><li class="bg-info"><a role="button"><i class="glyphicon glyphicon-fullscreen" /> Partition Key</a></li><li class="bg-warning"><a role="button"><i class="glyphicon glyphicon-pushpin" /> Static Column</a></li><li class="bg-success"><a role="button"><i class="glyphicon glyphicon-sort" /> Clustering Column</a></li><li class="bg-success"><a role="button"><i class="glyphicon glyphicon-sort-by-attributes" /> Clustering Order ASC</a></li><li class="bg-success"><a role="button"><i class="glyphicon glyphicon-sort-by-attributes-alt" /> Clustering Order DESC</a></li></ul></li><li><a href="#"></a></li></ul></nav><hr/><div class="row"><div class="col-md-2"/><div class="col-md-8 col-
offset-md-2"><div class="panel panel-default table-responsive table-bordered"><table class="table"><caption><h4 class="text-primary"><i class="glyphicon glyphicon-th-list"/> complex_table</h4></caption><thead><tr><th class="col-md-4">Column Type</th><th class="col-md-4">Column Name</th><th class="col-md-4">Data Type</th></tr></thead><tbody><tr class="info"><td class="col-md-4"><i class="glyphicon glyphicon-fullscreen" title="Partition Key"/></td><td class="col-md-4">pk1</td><td class="col-md-4">uuid</td></tr><tr class="info"><td class="col-md-4"><i class="glyphicon glyphicon-fullscreen" title="Partition Key"/></td><td class="col-md-4">pk2</td><td class="col-md-4">int</td></tr><tr class="warning"><td class="col-md-4"><i class="glyphicon glyphicon-pushpin" title="Static Column"/></td><td class="col-md-4">my_static1</td><td class="col-md-4">text</td></tr><tr class="warning"><td class="col-md-4"><i class="glyphicon glyphicon-pushpin" title="Static Column"/></td><td class="col-md-4"
>my_static2</td><td class="col-md-4">text</td></tr><tr class="success"><td class="col-md-4"><i class="glyphicon glyphicon-sort" title="Clustering Column"/> <i class="glyphicon glyphicon-sort-by-attributes-alt" title="Sort DESC"/></td><td class="col-md-4">clustering1</td><td class="col-md-4">timestamp</td></tr><tr class="success"><td class="col-md-4"><i class="glyphicon glyphicon-sort" title="Clustering Column"/> <i class="glyphicon glyphicon-sort-by-attributes" title="Sort ASC"/></td><td class="col-md-4">clustering2</td><td class="col-md-4">int</td></tr><tr class="success"><td class="col-md-4"><i class="glyphicon glyphicon-sort" title="Clustering Column"/> <i class="glyphicon glyphicon-sort-by-attributes-alt" title="Sort DESC"/></td><td class="col-md-4">clustering3</td><td class="col-md-4">text</td></tr><tr><td class="col-md-4"></td><td class="col-md-4">entries_indexed_map</td><td class="col-md-4">map<int, text></td></tr><tr><td class="col-md-4"></td><td class="
col-md-4">indexed1</td><td class="col-md-4">text</td></tr><tr><td class="col-md-4"></td><td class="col-md-4">indexed2</td><td class="col-md-4">int</td></tr><tr><td class="col-md-4"></td><td class="col-md-4">key_indexed_map</td><td class="col-md-4">map<int, text></td></tr><tr><td class="col-md-4"></td><td class="col-md-4">my_list</td><td class="col-md-4">list<text></td></tr><tr><td class="col-md-4"></td><td class="col-md-4">my_map</td><td class="col-md-4">map<int, text></td></tr><tr><td class="col-md-4"></td><td class="col-md-4">my_udt</td><td class="col-md-4">frozen<live_data.address></td></tr><tr><td class="col-md-4"></td><td class="col-md-4">my_udt_list</td><td class="col-md-4">frozen<list<frozen<live_data.address>>></td></tr><tr><td class="col-md-4"></td><td class="col-md-4">simple</td><td class="col-md-4">double</td></tr></tbody></table><div class="panel-footer"><a data-toggle="collapse" class="text-primary"><strong>As CQL statement</st
rong><span class="caret"></span></a><br/><br/><div class="collapse" ><pre class="well">CREATE TABLE live_data.complex_table (pk1 uuid,pk2 int,clustering1 timestamp,clustering2 int,clustering3 text,entries_indexed_map map<int, text>,indexed1 text,indexed2 int,key_indexed_map map<int, text>,my_list list<text>,my_map map<int, text>,my_static1 text static,my_static2 text static,my_udt frozen<live_data.address>,my_udt_list frozen<list<frozen<live_data.address>>>,simple double,PRIMARY KEY ((pk1, pk2), clustering1, clustering2, clustering3)) WITH CLUSTERING ORDER BY (clustering1 DESC, clustering2 ASC, clustering3 DESC)AND read_repair_chance = 0.0AND dclocal_read_repair_chance = 0.1AND gc_grace_seconds = 864000AND bloom_filter_fp_chance = 0.01AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' }AND comment = ''AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy' }AND compression = { 'sstable_
compression' : 'org.apache.cassandra.io.compress.LZ4Compressor' }AND default_time_to_live = 0AND speculative_retry = '99.0PERCENTILE'AND min_index_interval = 128AND max_index_interval = 2048;</pre></div></div></div><hr/><div class="panel panel-default table-responsive table-bordered"><table class="table"><caption><h4 class="text-danger"><i class="glyphicon glyphicon-info-sign"/> complex_table's indices</h4></caption><thead><tr><th class="col-md-6">Name</th><th class="col-md-6">Target</th></tr></thead><tbody><tr><td class="col-md-6">clustering2idx</td><td class="col-md-6">clustering2</td></tr><tr><td class="col-md-6">idx1</td><td class="col-md-6">indexed1</td></tr><tr><td class="col-md-6">idx2</td><td class="col-md-6">indexed2</td></tr><tr><td class="col-md-6">keys_map_idx</td><td class="col-md-6">keys(key_indexed_map)</td></tr><tr><td class="col-md-6">pk2idx</td><td class="col-md-6">pk2</td></tr></tbody></table><div class="panel-footer"><a data-toggle="collapse" class="text-da
nger"><strong>As CQL statement</strong><span class="caret"></span></a><br/><br/><div class="collapse" ><pre class="well">CREATE INDEX clustering2idx ON live_data.complex_table (clustering2);CREATE INDEX idx1 ON live_data.complex_table (indexed1);CREATE INDEX idx2 ON live_data.complex_table (indexed2);CREATE INDEX keys_map_idx ON live_data.complex_table (keys(key_indexed_map));CREATE INDEX pk2idx ON live_data.complex_table (pk2);</pre></div></div></div></div><div class="col-md-2"></div></div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/test/resources/scalate/DescribeType_live_data_address.html
----------------------------------------------------------------------
diff --git a/cassandra/src/test/resources/scalate/DescribeType_live_data_address.html b/cassandra/src/test/resources/scalate/DescribeType_live_data_address.html
index 5c4546f..9d4aaff 100644
--- a/cassandra/src/test/resources/scalate/DescribeType_live_data_address.html
+++ b/cassandra/src/test/resources/scalate/DescribeType_live_data_address.html
@@ -1,137 +1 @@
-<br/>
-<br/>
-<nav class="navbar navbar-default">
- <ul class="nav navbar-nav">
-
- <li>
- <a><strong>DESCRIBE TYPE live_data.address;</strong></a>
- </li>
- </ul>
- <ul class="nav navbar-nav navbar-right">
- <li class="dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
- <strong>Legend</strong>
- <span class="caret"></span>
- </a>
- <ul class="dropdown-menu">
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-dashboard text-muted" /> Cluster
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-folder-open text-danger" /> Keyspace
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-copyright-mark text-warning" /> UDT
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-th-list text-primary" /> Table
- </a>
- </li>
- <li class="bg-info">
- <a role="button">
- <i class="glyphicon glyphicon-fullscreen" /> Partition Key
- </a>
- </li>
- <li class="bg-warning">
- <a role="button">
- <i class="glyphicon glyphicon-pushpin" /> Static Column
- </a>
- </li>
- <li class="bg-success">
- <a role="button">
- <i class="glyphicon glyphicon-sort" /> Clustering Column
- </a>
- </li>
- <li class="bg-success">
- <a role="button">
- <i class="glyphicon glyphicon-sort-by-attributes" /> Clustering Order ASC
- </a>
- </li>
- <li class="bg-success">
- <a role="button">
- <i class="glyphicon glyphicon-sort-by-attributes-alt" /> Clustering Order DESC
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-info-sign" /> Indexed Column
- </a>
- </li>
- </ul>
- </li>
- <li>
- <a href="#"></a>
- </li>
- </ul>
-</nav>
-<hr/>
-<div class="row">
- <div class="col-md-3"></div>
- <div class="col-md-6 col-offset-md-3">
- <div class="panel panel-default table-responsive table-bordered">
- <table class="table">
-
- <caption><h4 class="text-warning"><i class="glyphicon glyphicon-copyright-mark"/> address</h4></caption>
-
- <thead>
- <tr>
- <th class="col-md-6">Column Name</th>
- <th class="col-md-6">Data Type</th>
- </tr>
- </thead>
- <tbody>
-
- <tr>
- <td class="col-md-6">number</td>
- <td class="col-md-6">int</td>
- </tr>
-
- <tr>
- <td class="col-md-6">street</td>
- <td class="col-md-6">text</td>
- </tr>
-
- <tr>
- <td class="col-md-6">zip</td>
- <td class="col-md-6">int</td>
- </tr>
-
- <tr>
- <td class="col-md-6">city</td>
- <td class="col-md-6">text</td>
- </tr>
-
- <tr>
- <td class="col-md-6">country</td>
- <td class="col-md-6">text</td>
- </tr>
-
- <tbody>
- </table>
- <div class="panel-footer">
- <a data-toggle="collapse" data-target="#984da320-350d-11e5-a7a9-8f0ea8ae1a37_asCQL">
- <strong>As CQL statement</strong>
- <span class="caret"></span>
- </a>
- <br/><br/>
- <div class="collapse" id="984da320-350d-11e5-a7a9-8f0ea8ae1a37_asCQL">
- <pre class="well">CREATE TYPE live_data.address (
- number int,
- street text,
- zip int,
- city text,
- country text
-);</pre>
- </div>
- </div>
- </div>
- </div>
- <div class="col-md-3"></div>
-</div>
+<br/><br/><nav class="navbar navbar-default"><ul class="nav navbar-nav"><li><a><strong>DESCRIBE TYPE live_data.address;</strong></a></li></ul><ul class="nav navbar-nav navbar-right"><li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><strong>Legend</strong><span class="caret"></span></a><ul class="dropdown-menu"><li><a role="button"><i class="glyphicon glyphicon-dashboard text-muted" /> Cluster</a></li><li><a role="button"><i class="glyphicon glyphicon-folder-open text-danger" /> Keyspace</a></li><li><a role="button"><i class="glyphicon glyphicon-copyright-mark text-warning" /> UDT</a></li><li><a role="button"><i class="glyphicon glyphicon-th-list text-primary" /> Table</a></li><li><a role="button"><i class="glyphicon glyphicon-eye-open text-primary" /> Materialized View</a></li><li><a role="button"><i class="glyphicon glyphicon-random text-success" /> &n
bsp;Function</a></li><li><a role="button"><i class="glyphicon glyphicon-retweet text-success" /> Aggregate</a></li><li role="separator" class="divider text-muted"></li><li class="dropdown-header"><span class="text-primary">Table icons</span></li><li class="bg-info"><a role="button"><i class="glyphicon glyphicon-fullscreen" /> Partition Key</a></li><li class="bg-warning"><a role="button"><i class="glyphicon glyphicon-pushpin" /> Static Column</a></li><li class="bg-success"><a role="button"><i class="glyphicon glyphicon-sort" /> Clustering Column</a></li><li class="bg-success"><a role="button"><i class="glyphicon glyphicon-sort-by-attributes" /> Clustering Order ASC</a></li><li class="bg-success"><a role="button"><i class="glyphicon glyphicon-sort-by-attributes-alt" /> Clustering Order DESC</a></li></ul></li><li><a href="#"></a></li></ul></nav><hr/><div class="row"><div class="col-md-3"></div><div class="col-md-6 col-of
fset-md-3"><div class="panel panel-default table-responsive table-bordered"><table class="table"><caption><h4 class="text-warning"><i class="glyphicon glyphicon-copyright-mark"/> address</h4></caption><thead><tr><th class="col-md-6">Column Name</th><th class="col-md-6">Data Type</th></tr></thead><tbody><tr><td class="col-md-6">number</td><td class="col-md-6">int</td></tr><tr><td class="col-md-6">street</td><td class="col-md-6">text</td></tr><tr><td class="col-md-6">zip</td><td class="col-md-6">int</td></tr><tr><td class="col-md-6">city</td><td class="col-md-6">text</td></tr><tr><td class="col-md-6">country</td><td class="col-md-6">text</td></tr><tbody></table><div class="panel-footer"><a data-toggle="collapse" class="text-warning"><strong>As CQL statement</strong><span class="caret"></span></a><br/><br/><div class="collapse" ><pre class="well">CREATE TYPE live_data.address (number int,street text,zip int,city text,country text);</pre></div></div></div></div><div class="col-md-
3"></div></div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/test/resources/scalate/DescribeType_live_data_address_within_current_keyspace.html
----------------------------------------------------------------------
diff --git a/cassandra/src/test/resources/scalate/DescribeType_live_data_address_within_current_keyspace.html b/cassandra/src/test/resources/scalate/DescribeType_live_data_address_within_current_keyspace.html
index aa657f9..13b1ce4 100644
--- a/cassandra/src/test/resources/scalate/DescribeType_live_data_address_within_current_keyspace.html
+++ b/cassandra/src/test/resources/scalate/DescribeType_live_data_address_within_current_keyspace.html
@@ -1,137 +1 @@
-<br/>
-<br/>
-<nav class="navbar navbar-default">
- <ul class="nav navbar-nav">
-
- <li>
- <a><strong>DESCRIBE TYPE address;</strong></a>
- </li>
- </ul>
- <ul class="nav navbar-nav navbar-right">
- <li class="dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
- <strong>Legend</strong>
- <span class="caret"></span>
- </a>
- <ul class="dropdown-menu">
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-dashboard text-muted" /> Cluster
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-folder-open text-danger" /> Keyspace
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-copyright-mark text-warning" /> UDT
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-th-list text-primary" /> Table
- </a>
- </li>
- <li class="bg-info">
- <a role="button">
- <i class="glyphicon glyphicon-fullscreen" /> Partition Key
- </a>
- </li>
- <li class="bg-warning">
- <a role="button">
- <i class="glyphicon glyphicon-pushpin" /> Static Column
- </a>
- </li>
- <li class="bg-success">
- <a role="button">
- <i class="glyphicon glyphicon-sort" /> Clustering Column
- </a>
- </li>
- <li class="bg-success">
- <a role="button">
- <i class="glyphicon glyphicon-sort-by-attributes" /> Clustering Order ASC
- </a>
- </li>
- <li class="bg-success">
- <a role="button">
- <i class="glyphicon glyphicon-sort-by-attributes-alt" /> Clustering Order DESC
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-info-sign" /> Indexed Column
- </a>
- </li>
- </ul>
- </li>
- <li>
- <a href="#"></a>
- </li>
- </ul>
-</nav>
-<hr/>
-<div class="row">
- <div class="col-md-3"></div>
- <div class="col-md-6 col-offset-md-3">
- <div class="panel panel-default table-responsive table-bordered">
- <table class="table">
-
- <caption><h4 class="text-warning"><i class="glyphicon glyphicon-copyright-mark"/> address</h4></caption>
-
- <thead>
- <tr>
- <th class="col-md-6">Column Name</th>
- <th class="col-md-6">Data Type</th>
- </tr>
- </thead>
- <tbody>
-
- <tr>
- <td class="col-md-6">number</td>
- <td class="col-md-6">int</td>
- </tr>
-
- <tr>
- <td class="col-md-6">street</td>
- <td class="col-md-6">text</td>
- </tr>
-
- <tr>
- <td class="col-md-6">zip</td>
- <td class="col-md-6">int</td>
- </tr>
-
- <tr>
- <td class="col-md-6">city</td>
- <td class="col-md-6">text</td>
- </tr>
-
- <tr>
- <td class="col-md-6">country</td>
- <td class="col-md-6">text</td>
- </tr>
-
- <tbody>
- </table>
- <div class="panel-footer">
- <a data-toggle="collapse" data-target="#984da320-350d-11e5-a7a9-8f0ea8ae1a37_asCQL">
- <strong>As CQL statement</strong>
- <span class="caret"></span>
- </a>
- <br/><br/>
- <div class="collapse" id="984da320-350d-11e5-a7a9-8f0ea8ae1a37_asCQL">
- <pre class="well">CREATE TYPE live_data.address (
- number int,
- street text,
- zip int,
- city text,
- country text
-);</pre>
- </div>
- </div>
- </div>
- </div>
- <div class="col-md-3"></div>
-</div>
+<br/><br/><nav class="navbar navbar-default"><ul class="nav navbar-nav"><li><a><strong>DESCRIBE TYPE address;</strong></a></li></ul><ul class="nav navbar-nav navbar-right"><li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><strong>Legend</strong><span class="caret"></span></a><ul class="dropdown-menu"><li><a role="button"><i class="glyphicon glyphicon-dashboard text-muted" /> Cluster</a></li><li><a role="button"><i class="glyphicon glyphicon-folder-open text-danger" /> Keyspace</a></li><li><a role="button"><i class="glyphicon glyphicon-copyright-mark text-warning" /> UDT</a></li><li><a role="button"><i class="glyphicon glyphicon-th-list text-primary" /> Table</a></li><li><a role="button"><i class="glyphicon glyphicon-eye-open text-primary" /> Materialized View</a></li><li><a role="button"><i class="glyphicon glyphicon-random text-success" /> Functi
on</a></li><li><a role="button"><i class="glyphicon glyphicon-retweet text-success" /> Aggregate</a></li><li role="separator" class="divider text-muted"></li><li class="dropdown-header"><span class="text-primary">Table icons</span></li><li class="bg-info"><a role="button"><i class="glyphicon glyphicon-fullscreen" /> Partition Key</a></li><li class="bg-warning"><a role="button"><i class="glyphicon glyphicon-pushpin" /> Static Column</a></li><li class="bg-success"><a role="button"><i class="glyphicon glyphicon-sort" /> Clustering Column</a></li><li class="bg-success"><a role="button"><i class="glyphicon glyphicon-sort-by-attributes" /> Clustering Order ASC</a></li><li class="bg-success"><a role="button"><i class="glyphicon glyphicon-sort-by-attributes-alt" /> Clustering Order DESC</a></li></ul></li><li><a href="#"></a></li></ul></nav><hr/><div class="row"><div class="col-md-3"></div><div class="col-md-6 col-offset-md-3"
><div class="panel panel-default table-responsive table-bordered"><table class="table"><caption><h4 class="text-warning"><i class="glyphicon glyphicon-copyright-mark"/> address</h4></caption><thead><tr><th class="col-md-6">Column Name</th><th class="col-md-6">Data Type</th></tr></thead><tbody><tr><td class="col-md-6">number</td><td class="col-md-6">int</td></tr><tr><td class="col-md-6">street</td><td class="col-md-6">text</td></tr><tr><td class="col-md-6">zip</td><td class="col-md-6">int</td></tr><tr><td class="col-md-6">city</td><td class="col-md-6">text</td></tr><tr><td class="col-md-6">country</td><td class="col-md-6">text</td></tr><tbody></table><div class="panel-footer"><a data-toggle="collapse" class="text-warning"><strong>As CQL statement</strong><span class="caret"></span></a><br/><br/><div class="collapse" ><pre class="well">CREATE TYPE live_data.address (number int,street text,zip int,city text,country text);</pre></div></div></div></div><div class="col-md-3"></div><
/div>
\ No newline at end of file
[2/6] incubator-zeppelin git commit: [ZEPPELIN-559] Cassandra
interpreter v2
Posted by fe...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/test/resources/scalate/Help.html
----------------------------------------------------------------------
diff --git a/cassandra/src/test/resources/scalate/Help.html b/cassandra/src/test/resources/scalate/Help.html
index de71d64..1c82c66 100644
--- a/cassandra/src/test/resources/scalate/Help.html
+++ b/cassandra/src/test/resources/scalate/Help.html
@@ -1,870 +1 @@
-<br/>
-<br/>
-<nav class="navbar navbar-default">
- <ul class="nav navbar-nav">
- <li role="presentation" class="dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
- <span class="text-info"><i class="glyphicon glyphicon-book"/> <strong>Please select ...</strong></span>
- <span class="text-info caret"></span>
- <ul class="dropdown-menu">
- <li class="dropdown-header"><span class="text-info">Topics</span></li>
- <li>
- <a role="button" data-toggle="collapse" data-target="#d977b63a-9900-4ecd-a438-70eb490d6a48">
- <span class="text-info"><i class="glyphicon glyphicon-bookmark"/> Basic Commands</span>
- </a>
- </li>
- <li>
- <a role="button" data-toggle="collapse" data-target="#eb22d00b-9be8-478a-b4bf-740f98e1e6ec">
- <span class="text-info"><i class="glyphicon glyphicon-bookmark"/> Schema Discovery</span>
- </a>
- </li>
- <li>
- <a role="button" data-toggle="collapse" data-target="#881a5e0b-5e52-4474-ba80-787dfe0a770d">
- <span class="text-info"><i class="glyphicon glyphicon-bookmark"/> Query Parameters</span>
- </a>
- </li>
- <li>
- <a role="button" data-toggle="collapse" data-target="#2af5a125-8754-40fb-a044-bda10395504f">
- <span class="text-info"><i class="glyphicon glyphicon-bookmark"/> Prepared Statements</span>
- </a>
- </li>
- <li>
- <a role="button" data-toggle="collapse" data-target="#4dfe08e1-7ee0-4222-8be0-3d9d43aab38e">
- <span class="text-info"><i class="glyphicon glyphicon-bookmark"/> Dynamic Forms</span>
- </a>
- </li>
- <li>
- <a role="button" data-toggle="collapse" data-target="#6485679a-ab5b-406b-8281-37f586459754">
- <span class="text-info"><i class="glyphicon glyphicon-bookmark"/> Interpreter Configuration</span>
- </a>
- </li>
- <li>
- <a role="button" data-toggle="collapse" data-target="#2d060cba-7f9a-40de-8cc3-d82586d4321e">
- <span class="text-info"><i class="glyphicon glyphicon-bookmark"/> Misc</span>
- </a>
- </li>
- </ul>
- </a>
- </li>
-
- <li>
- <a><span class="text-info"><strong>CASSANDRA INTERPRETER DOCUMENTATION</strong></span></a>
- </li>
- </ul>
- <ul class="nav navbar-nav navbar-right">
- <li class="dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
- <span class="text-info"><strong>About ...</strong></span>
- <span class="caret"></span>
- </a>
- <ul class="dropdown-menu">
- <li>
- <a role="button">
- <span class="text-info">Version <strong>1.0</strong></span>
- </a>
- </li>
- <li>
- <a role="button">
- <span class="text-info">Java Driver Version <strong>2.1.7.1</strong></span>
- </a>
- </li>
- <li>
- <a role="button">
- <span class="text-info">Author <strong>@doanduyhai</strong></span>
- </a>
- </li>
- </ul>
- </li>
- <li>
- <a href="#"></a>
- </li>
-</nav>
-<br/><br/>
-<div class="container">
- <div class="panel panel-default">
- <div class="panel-heading" role="tab">
- <h4 class="panel-title">
- <a role="button" data-toggle="collapse" data-target="#d977b63a-9900-4ecd-a438-70eb490d6a48" aria-expanded="false">
- <span class="text-info"><strong>Basic Commands</strong></span>
- </a>
- </h4>
- </div>
- <div id="d977b63a-9900-4ecd-a438-70eb490d6a48" class="panel-collapse collapse in" role="tabpanel">
- <div class="panel-body">
-
- <div class="panel panel-default">
- <div class="panel-body">
- <h3>I CQL Statements</h3>
- <p>This interpreter is compatible with any CQL statement supported by Cassandra. Ex:
- <br/><br/>
- <div class="row">
- <div class="col-md-6 col-md-offset-3">
- <pre>
-
- INSERT INTO users(login,name) VALUES('jdoe','John DOE');
- SELECT * FROM users WHERE login='jdoe';
- </pre>
- </div>
- </div>
- <br/>
- Each statement should be separated by a <strong>semi-colon</strong> (;).
- <br/>
- <strong>Multi-line</strong> statements as well as multiple statements on the <strong>same line</strong>
- are also supported as long as they are separated by a semi-colon. Ex:
- <br/>
- <br/>
- <div class="row">
- <div class="col-md-8 col-md-offset-2">
- <pre>
-
- USE spark_demo;
-
- SELECT * FROM albums_by_country LIMIT 1; SELECT * FROM countries LIMIT 1;
-
- SELECT *
- FROM artists
- WHERE login='jlennon';
- </pre>
- </div>
- </div>
- <br/>
- <strong>Batch</strong> statements are supported and can span multiple lines, as well as
- <strong>DDL</strong>(CREATE/ALTER/DROP) statements:
- <br/>
- <br/>
- <div class="row">
- <div class="col-md-8 col-md-offset-2">
- <pre>
-
- BEGIN BATCH
- INSERT INTO users(login,name) VALUES('jdoe','John DOE');
- INSERT INTO users_preferences(login,account_type) VALUES('jdoe','BASIC');
- APPLY BATCH;
-
- CREATE TABLE IF NOT EXISTS test(
- key int PRIMARY KEY,
- value text
- );
- </pre>
- </div>
- </div>
- <br/>
- CQL statements are <strong>case-insensitive</strong> (except for column names and values).
- This means that the following statements are equivalent and valid:
- <br/>
- <br/>
- <div class="row">
- <div class="col-md-8 col-md-offset-2">
- <pre>
-
- INSERT INTO users(login,name) VALUES('jdoe','John DOE');
- Insert into users(login,name) vAlues('hsue','Helen SUE');
- </pre>
- </div>
- </div>
- <br/>
- The complete list of all CQL statements and versions can be found below:
- <br/><br/>
- <div class="row">
- <div class="col-md-6 col-md-offset-3">
- <table class="table table-bordered">
- <thead>
- <tr><th>Cassandra version</th><th>Documentation</th></tr>
- </thead>
- <tbody>
- <tr>
- <td><strong>2.2</strong></td>
- <td>
- <a href="http://docs.datastax.com/en/cql/3.3/cql/cqlIntro.html" target="_blank">
- http://docs.datastax.com/en/cql/3.3/cql/cqlIntro.html
- </a>
- </td>
- </tr>
- <tr>
- <td><strong>2.1 & 2.0</strong></td>
- <td>
- <a href="http://docs.datastax.com/en/cql/3.1/cql/cql_intro_c.html" target="_blank">
- http://docs.datastax.com/en/cql/3.1/cql/cql_intro_c.html
- </a>
- </td>
- </tr>
- <tr>
- <td><strong>1.2</strong></td>
- <td>
- <a href="http://docs.datastax.com/en/cql/3.0/cql/aboutCQL.html" target="_blank">
- http://docs.datastax.com/en/cql/3.0/cql/aboutCQL.html
- </a>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
-
-
- </p>
- <h3>II Comments</h3>
- <p>
- It is possible to add comments between statements. Single line comments start with the
- <strong>hash</strong> sign (#). Multi-line comments are enclosed between
- <strong>/**</strong> and <strong>**/</strong>. Ex:
-
- <br/>
- <br/>
- <div class="row">
- <div class="col-md-8 col-md-offset-2">
- <pre>
-
- #First comment
- INSERT INTO users(login,name) VALUES('jdoe','John DOE');
-
- /**
- Multi line
- comments
- **/
- Insert into users(login,name) vAlues('hsue','Helen SUE');
- </pre>
- </div>
- </div>
- <br/>
-
- </p>
- <h3>III Syntax Validation</h3>
- <p>
- The interpreters is shipped with a <em>built-in syntax validator</em>. This validator only
- checks for <strong>basic syntax errors</strong>. All CQL-related syntax validation is delegated
- directly to <strong>Cassandra</strong>
- <br/><br/>
- Most of the time, syntax errors are due to missing semi-colons between statements or typo errors.
-
- </p>
-
- </div>
- </div>
-
-
-
- </div>
- </div>
- </div>
- <div class="panel panel-default">
- <div class="panel-heading" role="tab">
- <h4 class="panel-title">
- <a role="button" data-toggle="collapse" data-target="#eb22d00b-9be8-478a-b4bf-740f98e1e6ec" aria-expanded="false">
- <span class="text-info"><strong>Schema Discovery</strong></span>
- </a>
- </h4>
- </div>
- <div id="eb22d00b-9be8-478a-b4bf-740f98e1e6ec" class="panel-collapse collapse" role="tabpanel">
- <div class="panel-body">
-
- <div class="panel panel-default">
- <div class="panel-body">
- <h3>I Commands For Discovery</h3>
- <p>
- To make schema discovery easier and more interactive, the following commands are supported:
- <br/><br/>
- <table class="table table-bordered">
- <thead>
- <tr><th>Command</th><th>Description</th></tr>
- </thead>
- <tbody>
- <tr>
- <td><strong>DESCRIBE CLUSTER;</strong></td>
- <td>Show the current cluster name and its partitioner</td>
- </tr>
- <tr>
- <td><strong>DESCRIBE KEYSPACES;</strong></td>
- <td>List all existing keyspaces in the cluster and their configuration
- (replication factor, durable write ...)</td>
- </tr>
- <tr>
- <td><strong>DESCRIBE TABLES;</strong></td>
- <td>List all existing keyspaces in the cluster and for each, all the tables name</td>
- </tr>
- <tr>
- <td><strong>DESCRIBE KEYSPACE <keyspace name>;</strong></td>
- <td>Describe the given keyspace configuration and all its table details (name, columns, ...)</td>
- </tr>
- <tr>
- <td><strong>DESCRIBE TABLE <em>(<keyspace name>).</em><table name>;</strong></td>
- <td>
- Describe the given table. If the keyspace is not provided, the current
- <strong>logged in</strong> keyspace is used. If there is no logged in keyspace,
- the default <em>system</em> keyspace is used. If no table is found, an error message is raised
- </td>
- </tr>
- <tr>
- <td><strong>DESCRIBE TYPE <em>(<keyspace name>).</em><type name>;</strong></td>
- <td>
- Describe the given type(UDT). If the keyspace is not provided, the current
- <strong>logged in</strong> keyspace is used. If there is no logged in keyspace,
- the default <em>system</em> keyspace is used. If no type is found, an error message is raised
- </td>
- </tr>
- </tbody>
- </table>
- <br/>
- <div class="alert alert-danger" role="alert">
- Please note that each <strong>DESCRIBE</strong> command should be ended by <strong>a semi-colon</strong>.
- </div>
- </p>
- <h3>II Schema Display</h3>
- <p>
- The schema objects (cluster, keyspace, table & type) are displayed in a tabular format.
- There is a <strong>drop-down</strong> menu on the top left corner to expand objects details.
- On the top right menu is shown the Icon legend.
-
- </p>
- </div>
- </div>
-
- </div>
- </div>
- </div>
- <div class="panel panel-default">
- <div class="panel-heading" role="tab">
- <h4 class="panel-title">
- <a role="button" data-toggle="collapse" data-target="#881a5e0b-5e52-4474-ba80-787dfe0a770d" aria-expanded="false">
- <span class="text-info"><strong>Query Parameters</strong></span>
- </a>
- </h4>
- </div>
- <div id="881a5e0b-5e52-4474-ba80-787dfe0a770d" class="panel-collapse collapse" role="tabpanel">
- <div class="panel-body">
-
- <div class="panel panel-default">
- <div class="panel-body">
- <p>
- Sometimes you want to be able to pass runtime query parameters to your statements.
- Those parameters are <strong>not</strong> part of the CQL specs and are specific to the interpreter.
- Below is the list of all parameters:
-
- <br/><br/>
- <table class="table table-bordered">
- <caption>
- <h4>Query Parameters</h4>
- </caption>
- <thead>
- <tr>
- <th>Parameter</th>
- <th>Syntax</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>Consistency Level</td>
- <td><strong>@consistency=<em>value</em></strong></td>
- <td>Apply the given consistency level to all queries in the paragraph</td>
- </tr>
- <tr>
- <td>Serial Consistency Level</td>
- <td><strong>@serialConsistency=<em>value</em></strong></td>
- <td>Apply the given serial consistency level to all queries in the paragraph</td>
- </tr>
- <tr>
- <td>Timestamp</td>
- <td><strong>@timestamp=<em>long value</em></strong></td>
- <td>Apply the given timestamp to all queries in the paragraph.<br/>
- Please note that timestamp value passed directly in CQL statement will override this value
- </td>
- </tr>
- <tr>
- <td>Retry Policy</td>
- <td><strong>@retryPolicy=<em>value</em></strong></td>
- <td>Apply the given retry policy to all queries in the paragraph</td>
- </tr>
- <tr>
- <td>Fetch Size</td>
- <td><strong>@fetchSize=<em>int value</em></strong></td>
- <td>Apply the given fetch size to all queries in the paragraph</td>
- </tr>
- </tbody>
- </table>
- <br/>
- Some parameters only accept restricted values:
-
- <br/><br/>
- <table class="table table-bordered">
- <caption>
- <h4>Allowed Values</h4>
- </caption>
- <thead>
- <tr>
- <th>Parameter</th>
- <th>Possible Values</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>Consistency Level</td>
- <td><strong>ALL, ANY, ONE, TWO, THREE, QUORUM, LOCAL_ONE, LOCAL_QUORUM, EACH_QUORUM</strong></td>
- </tr>
- <tr>
- <td>Serial Consistency Level</td>
- <td><strong>SERIAL, LOCAL_SERIAL</strong></td>
- </tr>
- <tr>
- <td>Timestamp</td>
- <td>Any long value</td>
- </tr>
- <tr>
- <td>Retry Policy</td>
- <td>
- <strong>
- DEFAULT, DOWNGRADING_CONSISTENCY, FALLTHROUGH, LOGGING_DEFAULT,
- LOGGING_DOWNGRADING, LOGGING_FALLTHROUGH
- </strong>
- </td>
- </tr>
- <tr>
- <td>Fetch Size</td>
- <td>Any integer value</td>
- </tr>
- </tbody>
- </table>
- <br/>
-
- <div class="alert alert-danger" role="alert">
- Please note that you <strong>should not add semi-colon (;)</strong> at the end of each parameter statement
- </div>
-
- Some example:
- <br/><br/>
- <div class="row">
- <div class="col-md-8 col-md-offset-2">
- <pre>
-
- CREATE TABLE IF NOT EXISTS spark_demo.ts(
- key int PRIMARY KEY,
- value text
- );
- TRUNCATE spark_demo.ts;
-
- # Timestamp in the past
- @timestamp=10
-
- # Force timestamp directly in the first insert
- INSERT INTO spark_demo.ts(key,value) VALUES(1,'first insert') USING TIMESTAMP 100;
-
- # Select some data to make the clock turn
- SELECT * FROM spark_demo.albums LIMIT 100;
-
- # Now insert using the timestamp parameter set at the beginning(10)
- INSERT INTO spark_demo.ts(key,value) VALUES(1,'second insert');
-
- # Check for the result. You should see 'first insert'
- SELECT value FROM spark_demo.ts WHERE key=1;
- </pre>
- </div>
- </div>
- <br/>
-
- Some remarks about query parameters:
- <br/><br/>
- <div class="alert alert-info" role="alert">
- <ul>
- <li><strong>many</strong> query parameters can be set in the same paragraph</li>
- <li>if the <strong>same</strong> query parameter is set many time with different values,
- the interpreter only take into account the first value
- </li>
- <li>each query parameter applies to <strong>all</strong> CQL statement in the same paragraph,
- unless you override the option using plain CQL text (like forcing timestamp with the USING clause)
- </li>
- <li>the order of each query parameter with regard to CQL statement does not matter</li>
- </ul>
- </div>
- </p>
- </div>
- </div>
-
-
- </div>
- </div>
- </div>
-
- <div class="panel panel-default">
- <div class="panel-heading" role="tab">
- <h4 class="panel-title">
- <a role="button" data-toggle="collapse" data-target="#2af5a125-8754-40fb-a044-bda10395504f" aria-expanded="false">
- <span class="text-info"><strong>Prepared Statements</strong></span>
- </a>
- </h4>
- </div>
- <div id="2af5a125-8754-40fb-a044-bda10395504f" class="panel-collapse collapse" role="tabpanel">
- <div class="panel-body">
- <div class="panel panel-default">
- <div class="panel-body">
- <h3>I Syntax</h3>
- <br/>
- <p>
- For performance reason, it is better to <strong>prepare statements</strong> before-hand and reuse
- them later by providing bound values. This interpreter provides 3 commands to handle prepared and
- bound statements:
- <br/><br/>
- <ol>
- <li><strong>@prepare</strong></li>
- <li><strong>@bind</strong></li>
- <li><strong>@remove_prepared</strong></li>
- </ol>
- <br/>
- Example:
- <br/>
- <div class="row">
- <div class="col-md-10 col-md-offset-1">
- <pre>
-
- @prepare[statement_name]=...
-
- @bind[statement_name]=’text’, 1223, ’2015-07-30 12:00:01’, null, true, [‘list_item1’, ’list_item2’]
-
- @bind[statement_name_with_no_bound_value]
-
- @remove_prepare[statement_name]
-
- </pre>
- </div>
- </div>
- <br/>
-
- <h3>II @prepare</h3>
- <br/>
- <p>
- You can use the syntax "<strong>@prepare[statement_name]=SELECT ...</strong>" to create a prepared statement.
- The <em>statement_name</em> is mandatory because the interpreter prepares the given statement with the
- Java driver and saves the generated prepared statement in an internal map, using the provided
- <em>statement_name</em> as search key.
- <br/><br/>
- <div class="alert alert-info">
- Please note that this internal prepared statement map is shared with <strong>all notebooks</strong>
- and <strong>all paragraphs</strong> because there is only one instance of the interpreter for Cassandra
- </div>
- <br/>
- <div class="alert alert-warning">
- If the interpreter encounters many @prepare for the <strong>same statement_name</strong> (key),
- only the <strong>first</strong> statement will be taken into account.
- </div>
- <br/>
- Example:
- <br/>
- <div class="row">
- <div class="col-md-10 col-md-offset-1">
- <pre>
-
- @prepare[select]=SELECT * FROM spark_demo.albums LIMIT ?
-
- @prepare[select]=SELECT * FROM spark_demo.artists LIMIT ?
- </pre>
- </div>
- </div>
- <br/>
-
- For the above example, the prepared statement is <strong>"SELECT * FROM spark_demo.albums LIMIT ?"</strong>.
- <em>"SELECT * FROM spark_demo.artists LIMIT ?"</em> is ignored because an entry already exists in the
- prepared statements map with the key <strong>select</strong>.
- <br/><br/>
- In the context of Zeppelin, a notebook can be scheduled to be executed at regular interval,
- thus it is necessary to avoid re-preparing many time the same statement (considered an anti-pattern).
- </p>
- <h3>III @bind</h3>
- <br/>
- <p>
- Once the statement is prepared (possibly in a separated notebook/paragraph). You can bind values to it:
- <br/><br/>
- <div class="row">
- <div class="col-md-10 col-md-offset-1">
- <pre>
-
- @bind[select_first]=10
- </pre>
- </div>
- </div>
- <br/>
- Bound values are not mandatory for the <strong>@bind</strong> statement.
- However if you provide bound values, they need to comply to some syntax:
-
- <ul>
- <li>String values should be enclosed between simple quotes ( ‘ )</li>
- <li>Date values should be enclosed between simple quotes ( ‘ ) and respect the formats:
- <ol>
- <li>yyyy-MM-dd HH:MM:ss</li>
- <li>yyyy-MM-dd HH:MM:ss.SSS</li>
- </ol>
- </li>
- <li><strong>null</strong> is parsed as-is</li>
- <li><strong>boolean</strong> (true|false) are parsed as-is </li>
- <li>collection values must follow the
- <a href="http://docs.datastax.com/en/cql/3.1/cql/cql_using/use_collections_c.html" target="_blank">standard CQL syntax</a>:
- <ul>
- <li>list: [‘list_item1’, ’list_item2’, ...]</li>
- <li>set: {‘set_item1’, ‘set_item2’, …}</li>
- <li>map: {‘key1’: ‘val1’, ‘key2’: ‘val2’, …}</li>
- </ul>
- </li>
- <li>
- tuple values should be enclosed between parenthesis
- (see <a href="http://docs.datastax.com/en/cql/3.1/cql/cql_reference/tupleType.html" target="_blank">tuple CQL syntax</a>):
- (‘text’, 123, true)
- </li>
- <li>
- udt values should be enclosed between brackets
- (see <a href="http://docs.datastax.com/en/cql/3.1/cql/cql_using/cqlUseUDT.html" target="_blank">udt CQL syntax</a>):
- {stree_name: ‘Beverly Hills’, number: 104, zip_code: 90020, state: ‘California’, …}
- </li>
- </ul>
- <br/>
- <div class="alert alert-info">
- It is possible to use the <strong>@bind</strong> statement inside a batch: <br/>
- <pre>
- BEGIN BATCH
- @bind[insert_user]='jdoe','John DOE'
- UPDATE users SET age = 27 WHERE login='hsue';
- APPLY BATCH;
- </pre>
- </div>
- <br/>
- </p>
- <h3>IV @remove_prepare</h3>
- <br/>
- <p>
- To avoid for a prepared statement to stay forever in the prepared statement map, you can use the <strong>@remove_prepare[statement_name]</strong> syntax
- to remove it. Removing a non-existing prepared statement yields no error.
- </p>
- </div>
- </div>
- </div>
- </div>
- </div>
-
- <div class="panel panel-default">
- <div class="panel-heading" role="tab">
- <h4 class="panel-title">
- <a role="button" data-toggle="collapse" data-target="#4dfe08e1-7ee0-4222-8be0-3d9d43aab38e" aria-expanded="false">
- <span class="text-info"><strong>Dynamic Forms</strong></span>
- </a>
- </h4>
- </div>
- <div id="4dfe08e1-7ee0-4222-8be0-3d9d43aab38e" class="panel-collapse collapse" role="tabpanel">
- <div class="panel-body">
-
- <div class="panel panel-default">
- <div class="panel-body">
- <p>
- Instead of hard-coding your CQL queries, it is possible to use the mustache syntax (<strong>{{ }}</strong>)
- to inject simple value or multiple choices forms.
- <br/><br/>
-
- The syntax for simple parameter is: <strong>{{input_Label=default value}}</strong>.
- The default value is mandatory because the first time the paragraph is executed,
- we launch the CQL query before rendering the form so at least one value should be provided.
- <br/><br/>
- The syntax for multiple choices parameter is: <strong>{{input_Label=value1 | value2 | … | valueN }}</strong>.
- By default the first choice is used for CQL query the first time the paragraph is executed.
- <br/><br/>
- Example:
- <br/>
- <div class="row">
- <div class="col-md-10 col-md-offset-1">
- <pre>
-
- #Secondary index on performer style
- SELECT name, country, performer
- FROM spark_demo.performers
- WHERE name='{{performer=Sheryl Crow|Doof|Fanfarlo|Los Paranoia}}'
- AND styles CONTAINS '{{style=Rock}}';
-
- </pre>
- </div>
- </div>
- <br/>
-
- In the above example, the first CQL query will be executed for <em>performer='Sheryl Crow'</em>
- AND <em>style='Rock'</em>. For subsequent queries, you can change the value directly using the form.
- Please note that we enclosed the {{ }} block between simple quotes (') because Cassandra expects a String here.
- We could have also use the <strong>{{style='Rock'}}</strong> syntax but this time, the value
- displayed on the form is <em>'Rock'</em> and not <em>Rock</em>.
-
- <br/><br/>
- <div class="alert alert-info">
- It is also possible to use dynamic forms for <strong>prepared statements</strong>: <br/>
- <strong>@bind[select]=='{{performer=Sheryl Crow|Doof|Fanfarlo|Los Paranoia}}', '{{style=Rock}}'</strong>
- </div>
- </pre>
- </p>
- </div>
- </div>
-
- </div>
- </div>
- </div>
-
- <div class="panel panel-default">
- <div class="panel-heading" role="tab">
- <h4 class="panel-title">
- <a role="button" data-toggle="collapse" data-target="#6485679a-ab5b-406b-8281-37f586459754" aria-expanded="false">
- <span class="text-info"><strong>Interpreter Configuration</strong></span>
- </a>
- </h4>
- </div>
- <div id="6485679a-ab5b-406b-8281-37f586459754" class="panel-collapse collapse" role="tabpanel">
- <div class="panel-body">
- The <strong>Cassandra</strong> interpreter comes with some some configuration values for the Java driver:
-
- <table class="table table-bordered">
- <caption>
- <h4>Interpreter Configuration</h4>
- </caption>
- <thead>
- <tr>
- <th>Parameter</th>
- <th>Default Value</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>cassandra.cluster</td>
- <td><strong>Test Cluster</strong></td>
- </tr>
- <tr>
- <td>cassandra.compression.protocol</td>
- <td><strong>NONE</strong>, possible values: LZ4, SNAPPY</td>
- </tr>
- <tr>
- <td>cassandra.credentials.password</td>
- <td><strong>none</strong></td>
- </tr>
- <tr>
- <td>cassandra.credentials.username</td>
- <td><strong>none</strong></td>
- </tr>
- <tr>
- <td>cassandra.hosts</td>
- <td><strong>localhost</strong></td>
- </tr>
- <tr>
- <td>cassandra.interpreter.parallelism</td>
- <td><strong>10</strong></td>
- </tr>
- <tr>
- <td>cassandra.keyspace</td>
- <td><strong>system</strong></td>
- </tr>
- <tr>
- <td>cassandra.load.balancing.policy</td>
- <td><strong>DEFAULT</strong>, or a FQCN of a custom class</td>
- </tr>
- <tr>
- <td>cassandra.max.schema.agreement.wait.second</td>
- <td><strong>10</strong></td>
- </tr>
- <tr>
- <td>cassandra.native.port</td>
- <td><strong>9042</strong></td>
- </tr>
- <tr>
- <td>cassandra.pooling.core.connection.per.host.local</td>
- <td><strong>Protocol V2 and below: 2, V3 and above: 1</strong></td>
- </tr>
- <tr>
- <td>cassandra.pooling.core.connection.per.host.remote</td>
- <td><strong>Protocol V2 and below: 1, V3 and above: 1</strong></td>
- </tr>
- <tr>
- <td>cassandra.pooling.heartbeat.interval.seconds</td>
- <td><strong>30</strong></td>
- </tr>
- <tr>
- <td>cassandra.pooling.idle.timeout.seconds</td>
- <td><strong>Test Cluster</strong></td>
- </tr>
- <tr>
- <td>cassandra.pooling.max.connection.per.host.local</td>
- <td><strong>Protocol V2 and below: 8, V3 and above: 1</strong></td>
- </tr>
- <tr>
- <td>cassandra.pooling.max.connection.per.host.remote</td>
- <td><strong>Protocol V2 and below: 2, V3 and above: 1</strong></td>
- </tr>
- <tr>
- <td>cassandra.pooling.max.request.per.connection.local</td>
- <td><strong>Protocol V2 and below: 128, V3 and above: 1024</strong></td>
- </tr>
- <tr>
- <td>cassandra.pooling.max.request.per.connection.remote</td>
- <td><strong>Protocol V2 and below: 128, V3 and above: 256</strong></td>
- </tr>
- <tr>
- <td>cassandra.pooling.new.connection.threshold.local</td>
- <td><strong>Protocol V2 and below: 100, V3 and above: 800</strong></td>
- </tr>
- <tr>
- <td>cassandra.pooling.new.connection.threshold.remote</td>
- <td><strong>Protocol V2 and below: 100, V3 and above: 200</strong></td>
- </tr>
- <tr>
- <td>cassandra.pooling.pool.timeout.millisecs</td>
- <td><strong>5000</strong></td>
- </tr>
- <tr>
- <td>cassandra.protocol.version</td>
- <td><strong>3</strong></td>
- </tr>
- <tr>
- <td>cassandra.query.default.consistency</td>
- <td><strong>ONE</strong></td>
- </tr>
- <tr>
- <td>cassandra.query.default.fetchSize</td>
- <td><strong>5000</strong></td>
- </tr>
- <tr>
- <td>cassandra.query.default.serial.consistency</td>
- <td><strong>SERIAL</strong></td>
- </tr>
- <tr>
- <td>cassandra.reconnection.policy</td>
- <td><strong>DEFAULT</strong>, or a FQCN of a custom class</td>
- </tr>
- <tr>
- <td>cassandra.retry.policy</td>
- <td><strong>DEFAULT</strong>, or a FQCN of a custom class</td>
- </tr>
- <tr>
- <td>cassandra.socket.connection.timeout.millisecs</td>
- <td><strong>500</strong></td>
- </tr>
- <tr>
- <td>cassandra.socket.read.timeout.millisecs</td>
- <td><strong>12000</strong></td>
- </tr>
- <tr>
- <td>cassandra.socket.tcp.no_delay</td>
- <td><strong>true</strong></td>
- </tr>
- <tr>
- <td>cassandra.speculative.execution.policy</td>
- <td><strong>DEFAULT</strong>, or a FQCN of a custom class</td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- </div>
-
- <div class="panel panel-default">
- <div class="panel-heading" role="tab">
- <h4 class="panel-title">
- <a role="button" data-toggle="collapse" data-target="#2d060cba-7f9a-40de-8cc3-d82586d4321e" aria-expanded="false">
- <span class="text-info"><strong>Miscellaneous</strong></span>
- </a>
- </h4>
- </div>
- <div id="2d060cba-7f9a-40de-8cc3-d82586d4321e" class="panel-collapse collapse" role="tabpanel">
- <div class="panel-body">
- <h3>Execution parallelism</h3>
- It is possible to execute many paragraphs in parallel. However, at the back-end side, we’re still using <strong>synchronous</strong> queries. Asynchronous execution is only possible when it is possible to return a Future value in the <strong>InterpreterResult</strong>. It may be an interesting proposal for the Zeppelin project.
- </div>
- </div>
- </div>
-</div>
\ No newline at end of file
+<br/><br/><nav class="navbar navbar-default"><ul class="nav navbar-nav"><li role="presentation" class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="text-info"><i class="glyphicon glyphicon-book"/> <strong>Please select ...</strong></span><span class="text-info caret"></span><ul class="dropdown-menu"><li class="dropdown-header"><span class="text-info">Topics</span></li><li><a role="button" data-toggle="collapse" ><span class="text-info"><i class="glyphicon glyphicon-bookmark"/> Basic Commands</span></a></li><li><a role="button" data-toggle="collapse" ><span class="text-info"><i class="glyphicon glyphicon-bookmark"/> Schema Discovery</span></a></li><li><a role="button" data-toggle="collapse" ><span class="text-info"><i class="glyphicon glyphicon-bookmark"/> Query Parameters</span></a></li><li><a role="button" data-toggle="collapse" ><span class="text-info"><i clas
s="glyphicon glyphicon-bookmark"/> Prepared Statements</span></a></li><li><a role="button" data-toggle="collapse" ><span class="text-info"><i class="glyphicon glyphicon-bookmark"/> Dynamic Forms</span></a></li><li><a role="button" data-toggle="collapse" ><span class="text-info"><i class="glyphicon glyphicon-bookmark"/> Interpreter Configuration</span></a></li><li><a role="button" data-toggle="collapse" ><span class="text-info"><i class="glyphicon glyphicon-bookmark"/> Shared States</span></a></li><li><a role="button" data-toggle="collapse" ><span class="text-info"><i class="glyphicon glyphicon-bookmark"/> Change Log</span></a></li><li><a role="button" data-toggle="collapse" ><span class="text-info"><i class="glyphicon glyphicon-bookmark"/> Contacts & Bugs</span></a></li></ul></a></li><li><a><span class="text-info"><strong>CASSANDRA INTERPRETER DOCUMENTATION</strong></span></a></li></ul><ul class="nav navbar-nav na
vbar-right"><li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="text-info"><strong>About ...</strong></span><span class="caret"></span></a><ul class="dropdown-menu"><li><a role="button"><span class="text-info">Version <strong>2.0</strong></span></a></li><li><a role="button"><span class="text-info">Java Driver Version <strong>3.0.0-rc1</strong></span></a></li><li><a role="button"><span class="text-info">Author <strong>@doanduyhai</strong></span></a></li></ul></li><li><a href="#"></a></li></nav><br/><br/><div class="container"><div class="panel panel-default"><div class="panel-heading" role="tab"><h4 class="panel-title"><a role="button" data-toggle="collapse" aria-expanded="false"><span class="text-info"><strong>Basic Commands</strong></span></a></h4></div><div class="panel-collapse collapse in" role="tabpanel"><div class="panel-body"><div class="panel panel-default"><div class="panel-body"><h3>
I CQL Statements</h3><p>This interpreter is compatible with any CQL statement supported by Cassandra. Ex:<br/><br/><div class="row"><div class="col-md-6 col-md-offset-3"><pre>INSERT INTO users(login,name) VALUES('jdoe','John DOE');SELECT * FROM users WHERE login='jdoe';</pre></div></div><br/>Each statement should be separated by a <strong>semi-colon</strong> (;).<br/><strong>Multi-line</strong> statements as well as multiple statements on the <strong>same line</strong>are also supported as long as they are separated by a semi-colon. Ex:<br/><br/><div class="row"><div class="col-md-8 col-md-offset-2"><pre>USE spark_demo;SELECT * FROM albums_by_country LIMIT 1; SELECT * FROM countries LIMIT 1;SELECT *FROM artistsWHERE login='jlennon';</pre></div></div><br/><strong>Batch</strong> statements are supported and can span multiple lines, as well as<strong>DDL</strong>(CREATE/ALTER/DROP) statements:<br/><br/><div class="row"><div class="col-md-8 col-md-offset-2"><pre>BEGIN BATCHINSERT INTO u
sers(login,name) VALUES('jdoe','John DOE');INSERT INTO users_preferences(login,account_type) VALUES('jdoe','BASIC');APPLY BATCH;CREATE TABLE IF NOT EXISTS test(key int PRIMARY KEY,value text);</pre></div></div><br/>CQL statements are <strong>case-insensitive</strong> (except for column names and values).This means that the following statements are equivalent and valid:<br/><br/><div class="row"><div class="col-md-8 col-md-offset-2"><pre>INSERT INTO users(login,name) VALUES('jdoe','John DOE');Insert into users(login,name) vAlues('hsue','Helen SUE');</pre></div></div><br/>The complete list of all CQL statements and versions can be found below:<br/><br/><div class="row"><div class="col-md-6 col-md-offset-3"><table class="table table-bordered"><thead><tr><th>Cassandra version</th><th>Documentation</th></tr></thead><tbody><tr><td><strong>2.2</strong></td><td><a href="http://docs.datastax.com/en/cql/3.3/cql/cqlIntro.html" target="_blank">http://docs.datastax.com/en/cql/3.3/cql/cqlIntro.ht
ml</a></td></tr><tr><td><strong>2.1 & 2.0</strong></td><td><a href="http://docs.datastax.com/en/cql/3.1/cql/cql_intro_c.html" target="_blank">http://docs.datastax.com/en/cql/3.1/cql/cql_intro_c.html</a></td></tr><tr><td><strong>1.2</strong></td><td><a href="http://docs.datastax.com/en/cql/3.0/cql/aboutCQL.html" target="_blank">http://docs.datastax.com/en/cql/3.0/cql/aboutCQL.html</a></td></tr></tbody></table></div></div></p><h3>II Comments</h3><p>It is possible to add comments between statements. Single line comments start with the<strong>hash</strong> sign (#) or <strong>double slashes</strong> (//). Multi-line comments are enclosed between<strong>/**</strong> and <strong>**/</strong>. Ex:<br/><br/><div class="row"><div class="col-md-8 col-md-offset-2"><pre>#Single line comment style 1INSERT INTO users(login,name) VALUES('jdoe','John DOE');//Single line comment style 2/**Multi linecomments**/Insert into users(login,name) vAlues('hsue','Helen SUE');</pre></di
v></div><br/></p><h3>III Syntax Validation</h3><p>The interpreters is shipped with a <em>built-in syntax validator</em>. This validator onlychecks for <strong>basic syntax errors</strong>. All CQL-related syntax validation is delegateddirectly to <strong>Cassandra</strong><br/><br/>Most of the time, syntax errors are due to missing semi-colons between statements or typo errors.</p></div></div></div></div></div><div class="panel panel-default"><div class="panel-heading" role="tab"><h4 class="panel-title"><a role="button" data-toggle="collapse" aria-expanded="false"><span class="text-info"><strong>Schema Discovery</strong></span></a></h4></div><div class="panel-collapse collapse" role="tabpanel"><div class="panel-body"><div class="panel panel-default"><div class="panel-body"><h3>I Commands For Discovery</h3><p>To make schema discovery easier and more interactive, the following commands are supported:<br/><br/><table class="table table-bordered"><thead><tr><th>Command</th><th>Descrip
tion</th></tr></thead><tbody><tr><td><strong>DESCRIBE CLUSTER;</strong></td><td>Show the current cluster name and its partitioner</td></tr><tr><td><strong>DESCRIBE KEYSPACES;</strong></td><td>List all existing keyspaces in the cluster and their configuration(replication factor, durable write ...)</td></tr><tr><td><strong>DESCRIBE TABLES;</strong></td><td>List all existing keyspaces in the cluster and for each, all the tables name</td></tr><tr><td><strong>DESCRIBE TYPES;</strong></td><td>List all existing keyspaces in the cluster and for each, all the types name</td></tr><tr><td><strong>DESCRIBE FUNCTIONS;</strong></td><td>List all existing keyspaces in the cluster and for each, all the functions name and arguments</td></tr><tr><td><strong>DESCRIBE AGGREGATES;</strong></td><td>List all existing keyspaces in the cluster and for each, all the aggregates name and arguments</td></tr><tr><td><strong>DESCRIBE MATERIALIZED VIEWS;</strong></td><td>List all existing keyspaces in the cluster a
nd for each, all the materialized view name</td></tr><tr><td><strong>DESCRIBE KEYSPACE <keyspace name>;</strong></td><td>Describe the given keyspace configuration and all its table details (name, columns, ...)</td></tr><tr><td><strong>DESCRIBE TABLE <em>(<keyspace name>).</em><table name>;</strong></td><td>Describe the given table. If the keyspace is not provided, the current<strong>logged in</strong> keyspace is used. If there is no logged in keyspace,the default <em>system</em> keyspace is used. If no table is found, an error message is raised</td></tr><tr><td><strong>DESCRIBE TYPE <em>(<keyspace name>).</em><type name>;</strong></td><td>Describe the given type(UDT). If the keyspace is not provided, the current<strong>logged in</strong> keyspace is used. If there is no logged in keyspace,the default <em>system</em> keyspace is used. If no type is found, an error message is raised</td></tr><tr><td><strong>DESCRIBE FUNCTION <em>(<keyspace name>).<
/em><function name>;</strong></td><td>Describe the given function. If the keyspace is not provided, the current<strong>logged in</strong> keyspace is used. If there is no logged in keyspace,the default <em>system</em> keyspace is used. If no function is found, an error message is raised</td></tr><tr><td><strong>DESCRIBE AGGREGATE <em>(<keyspace name>).</em><aggregate name>;</strong></td><td>Describe the given aggregate. If the keyspace is not provided, the current<strong>logged in</strong> keyspace is used. If there is no logged in keyspace,the default <em>system</em> keyspace is used. If no aggregate is found, an error message is raised</td></tr><tr><td><strong>DESCRIBE MATERIALIZED VIEW <em>(<keyspace name>).</em><view name>;</strong></td><td>Describe the given materialized view. If the keyspace is not provided, the current<strong>logged in</strong> keyspace is used. If there is no logged in keyspace,the default <em>system</em> keyspace is used. If no
materialized view is found, an error message is raised</td></tr></tbody></table><br/><div class="alert alert-danger" role="alert">Please note that each <strong>DESCRIBE</strong> command should be ended by <strong>a semi-colon</strong>.</div></p><h3>II Schema Display</h3><p>The schema objects (cluster, keyspace, table, type, view, function & aggregate) are displayed in a tabular format. There is a <strong>drop-down</strong> menu on the top left corner to expand objects details. On the top right menu is shown the Icon legend.</p></div></div></div></div></div><div class="panel panel-default"><div class="panel-heading" role="tab"><h4 class="panel-title"><a role="button" data-toggle="collapse" aria-expanded="false"><span class="text-info"><strong>Query Parameters</strong></span></a></h4></div><div class="panel-collapse collapse" role="tabpanel"><div class="panel-body"><div class="panel panel-default"><div class="panel-body"><p>Sometimes you want to be able to pass runtime query pa
rameters to your statements.Those parameters are <strong>not</strong> part of the CQL specs and are specific to the interpreter.Below is the list of all parameters:<br/><br/><table class="table table-bordered"><caption><h4>Query Parameters</h4></caption><thead><tr><th>Parameter</th><th>Syntax</th><th>Description</th></tr></thead><tbody><tr><td>Consistency Level</td><td><strong>@consistency=<em>value</em></strong></td><td>Apply the given consistency level to all queries in the paragraph</td></tr><tr><td>Serial Consistency Level</td><td><strong>@serialConsistency=<em>value</em></strong></td><td>Apply the given serial consistency level to all queries in the paragraph</td></tr><tr><td>Timestamp</td><td><strong>@timestamp=<em>long value</em></strong></td><td>Apply the given timestamp to all queries in the paragraph.<br/>Please note that timestamp value passed directly in CQL statement will override this value</td></tr><tr><td>Retry Policy</td><td><strong>@retryPolicy=<em>value</em></stro
ng></td><td>Apply the given retry policy to all queries in the paragraph</td></tr><tr><td>Fetch Size</td><td><strong>@fetchSize=<em>int value</em></strong></td><td>Apply the given fetch size to all queries in the paragraph</td></tr></tbody></table><br/>Some parameters only accept restricted values:<br/><br/><table class="table table-bordered"><caption><h4>Allowed Values</h4></caption><thead><tr><th>Parameter</th><th>Possible Values</th></tr></thead><tbody><tr><td>Consistency Level</td><td><strong>ALL, ANY, ONE, TWO, THREE, QUORUM, LOCAL_ONE, LOCAL_QUORUM, EACH_QUORUM</strong></td></tr><tr><td>Serial Consistency Level</td><td><strong>SERIAL, LOCAL_SERIAL</strong></td></tr><tr><td>Timestamp</td><td>Any long value</td></tr><tr><td>Retry Policy</td><td><strong>DEFAULT, DOWNGRADING_CONSISTENCY, FALLTHROUGH, LOGGING_DEFAULT,LOGGING_DOWNGRADING, LOGGING_FALLTHROUGH</strong></td></tr><tr><td>Fetch Size</td><td>Any integer value</td></tr></tbody></table><br/><div class="alert alert-danger" r
ole="alert">Please note that you <strong>should not add semi-colon (;)</strong> at the end of each parameter statement</div>Some example:<br/><br/><div class="row"><div class="col-md-8 col-md-offset-2"><pre>CREATE TABLE IF NOT EXISTS spark_demo.ts(key int PRIMARY KEY,value text);TRUNCATE spark_demo.ts;# Timestamp in the past@timestamp=10# Force timestamp directly in the first insertINSERT INTO spark_demo.ts(key,value) VALUES(1,'first insert') USING TIMESTAMP 100;# Select some data to make the clock turnSELECT * FROM spark_demo.albums LIMIT 100;# Now insert using the timestamp parameter set at the beginning(10)INSERT INTO spark_demo.ts(key,value) VALUES(1,'second insert');# Check for the result. You should see 'first insert'SELECT value FROM spark_demo.ts WHERE key=1;</pre></div></div><br/>Some remarks about query parameters:<br/><br/><div class="alert alert-info" role="alert"><ul><li><strong>many</strong> query parameters can be set in the same paragraph</li><li>if the <strong>same<
/strong> query parameter is set many time with different values,the interpreter only take into account the first value</li><li>each query parameter applies to <strong>all</strong> CQL statement in the same paragraph,unless you override the option using plain CQL text (like forcing timestamp with the USING clause)</li><li>the order of each query parameter with regard to CQL statement does not matter</li></ul></div></p></div></div></div></div></div><div class="panel panel-default"><div class="panel-heading" role="tab"><h4 class="panel-title"><a role="button" data-toggle="collapse" aria-expanded="false"><span class="text-info"><strong>Prepared Statements</strong></span></a></h4></div><div class="panel-collapse collapse" role="tabpanel"><div class="panel-body"><div class="panel panel-default"><div class="panel-body"><h3>I Syntax</h3><br/><p>For performance reason, it is better to <strong>prepare statements</strong> before-hand and reusethem later by providing bound values. This interp
reter provides 3 commands to handle prepared andbound statements:<br/><br/><ol><li><strong>@prepare</strong></li><li><strong>@bind</strong></li><li><strong>@remove_prepared</strong></li></ol><br/>Example:<br/><div class="row"><div class="col-md-10 col-md-offset-1"><pre>@prepare[statement_name]=...@bind[statement_name]=’text’, 1223, ’2015-07-30 12:00:01’, null, true, [‘list_item1’, ’list_item2’]@bind[statement_name_with_no_bound_value]@remove_prepare[statement_name]</pre></div></div><br/><h3>II @prepare</h3><br/><p>You can use the syntax "<strong>@prepare[statement_name]=SELECT ...</strong>" to create a prepared statement.The <em>statement_name</em> is mandatory because the interpreter prepares the given statement with theJava driver and saves the generated prepared statement in an internal map, using the provided<em>statement_name</em> as search key.<br/><br/><div class="alert alert-info">Please note that this internal prepared statement map is shared with <strong>al
l notebooks</strong>and <strong>all paragraphs</strong> because there is only one instance of the interpreter for Cassandra</div><br/><div class="alert alert-warning">If the interpreter encounters many @prepare for the <strong>same statement_name</strong> (key),only the <strong>first</strong> statement will be taken into account.</div><br/>Example:<br/><div class="row"><div class="col-md-10 col-md-offset-1"><pre>@prepare[select]=SELECT * FROM spark_demo.albums LIMIT ?@prepare[select]=SELECT * FROM spark_demo.artists LIMIT ?</pre></div></div><br/>For the above example, the prepared statement is <strong>"SELECT * FROM spark_demo.albums LIMIT ?"</strong>.<em>"SELECT * FROM spark_demo.artists LIMIT ?"</em> is ignored because an entry already exists in theprepared statements map with the key <strong>select</strong>.<br/><br/>In the context of Zeppelin, a notebook can be scheduled to be executed at regular interval,thus it is necessary to avoid re-preparing many time the same statement (c
onsidered an anti-pattern).</p><h3>III @bind</h3><br/><p>Once the statement is prepared (possibly in a separated notebook/paragraph). You can bind values to it:<br/><br/><div class="row"><div class="col-md-10 col-md-offset-1"><pre>@bind[select_first]=10</pre></div></div><br/>Bound values are not mandatory for the <strong>@bind</strong> statement.However if you provide bound values, they need to comply to some syntax:<ul><li>String values should be enclosed between simple quotes ( ‘ )</li><li>Date values should be enclosed between simple quotes ( ‘ ) and respect the formats:<ol><li>yyyy-MM-dd HH:MM:ss</li><li>yyyy-MM-dd HH:MM:ss.SSS</li></ol></li><li><strong>null</strong> is parsed as-is</li><li><strong>boolean</strong> (true|false) are parsed as-is </li><li>collection values must follow the<a href="http://docs.datastax.com/en/cql/3.1/cql/cql_using/use_collections_c.html" target="_blank">standard CQL syntax</a>:<ul><li>list: [‘list_item1’, ’list_item2’, ...]</li><li>set:
{‘set_item1’, ‘set_item2’, …}</li><li>map: {‘key1’: ‘val1’, ‘key2’: ‘val2’, …}</li></ul></li><li>tuple values should be enclosed between parenthesis(see <a href="http://docs.datastax.com/en/cql/3.1/cql/cql_reference/tupleType.html" target="_blank">tuple CQL syntax</a>):(‘text’, 123, true)</li><li>udt values should be enclosed between brackets(see <a href="http://docs.datastax.com/en/cql/3.1/cql/cql_using/cqlUseUDT.html" target="_blank">udt CQL syntax</a>):{stree_name: ‘Beverly Hills’, number: 104, zip_code: 90020, state: ‘California’, …}</li></ul><br/><div class="alert alert-info">It is possible to use the <strong>@bind</strong> statement inside a batch: <br/><pre>BEGIN BATCH@bind[insert_user]='jdoe','John DOE'UPDATE users SET age = 27 WHERE login='hsue';APPLY BATCH;</pre></div><br/></p><h3>IV @remove_prepare</h3><br/><p>To avoid for a prepared statement to stay forever in the prepared statement map, you can use the <strong>@remove_prepare
[statement_name]</strong> syntaxto remove it. Removing a non-existing prepared statement yields no error.</p></div></div></div></div></div><div class="panel panel-default"><div class="panel-heading" role="tab"><h4 class="panel-title"><a role="button" data-toggle="collapse" aria-expanded="false"><span class="text-info"><strong>Dynamic Forms</strong></span></a></h4></div><div class="panel-collapse collapse" role="tabpanel"><div class="panel-body"><div class="panel panel-default"><div class="panel-body"><p>Instead of hard-coding your CQL queries, it is possible to use the mustache syntax (<strong>{{ }}</strong>)to inject simple value or multiple choices forms.<br/><br/>The syntax for simple parameter is: <strong>{{input_Label=default value}}</strong>.The default value is mandatory because the first time the paragraph is executed,we launch the CQL query before rendering the form so at least one value should be provided.<br/><br/>The syntax for multiple choices parameter is: <strong>{{
input_Label=value1 | value2 | … | valueN }}</strong>.By default the first choice is used for CQL query the first time the paragraph is executed.<br/><br/>Example:<br/><div class="row"><div class="col-md-10 col-md-offset-1"><pre>#Secondary index on performer styleSELECT name, country, performerFROM spark_demo.performersWHERE name='{{performer=Sheryl Crow|Doof|Fanfarlo|Los Paranoia}}'AND styles CONTAINS '{{style=Rock}}';</pre></div></div><br/>In the above example, the first CQL query will be executed for <em>performer='Sheryl Crow'</em>AND <em>style='Rock'</em>. For subsequent queries, you can change the value directly using the form.Please note that we enclosed the {{ }} block between simple quotes (') because Cassandra expects a String here.We could have also use the <strong>{{style='Rock'}}</strong> syntax but this time, the valuedisplayed on the form is <em>'Rock'</em> and not <em>Rock</em>.<br/><br/><div class="alert alert-info">It is also possible to use dynamic forms for <str
ong>prepared statements</strong>: <br/><strong>@bind[select]=='{{performer=Sheryl Crow|Doof|Fanfarlo|Los Paranoia}}', '{{style=Rock}}'</strong></div></pre></p></div></div></div></div></div><div class="panel panel-default"><div class="panel-heading" role="tab"><h4 class="panel-title"><a role="button" data-toggle="collapse" aria-expanded="false"><span class="text-info"><strong>Interpreter Configuration</strong></span></a></h4></div><div class="panel-collapse collapse" role="tabpanel"><div class="panel-body">The <strong>Cassandra</strong> interpreter comes with some some configuration values for the Java driver:<table class="table table-bordered"><caption><h4>Interpreter Configuration</h4></caption><thead><tr><th>Parameter</th><th>Default Value</th></tr></thead><tbody><tr><td>cassandra.cluster</td><td><strong>Test Cluster</strong></td></tr><tr><td>cassandra.compression.protocol</td><td><strong>NONE</strong>, possible values: LZ4, SNAPPY</td></tr><tr><td>cassandra.credentials.password
</td><td><strong>none</strong></td></tr><tr><td>cassandra.credentials.username</td><td><strong>none</strong></td></tr><tr><td>cassandra.hosts</td><td><strong>localhost</strong></td></tr><tr><td>cassandra.interpreter.parallelism</td><td><strong>10</strong></td></tr><tr><td>cassandra.keyspace</td><td><strong>system</strong></td></tr><tr><td>cassandra.load.balancing.policy</td><td><strong>DEFAULT</strong>, or a FQCN of a custom class</td></tr><tr><td>cassandra.max.schema.agreement.wait.second</td><td><strong>10</strong></td></tr><tr><td>cassandra.native.port</td><td><strong>9042</strong></td></tr><tr><td>cassandra.pooling.core.connection.per.host.local</td><td><strong>Protocol V2 and below: 2, V3 and above: 1</strong></td></tr><tr><td>cassandra.pooling.core.connection.per.host.remote</td><td><strong>Protocol V2 and below: 1, V3 and above: 1</strong></td></tr><tr><td>cassandra.pooling.heartbeat.interval.seconds</td><td><strong>30</strong></td></tr><tr><td>cassandra.pooling.idle.timeout.
seconds</td><td><strong>Test Cluster</strong></td></tr><tr><td>cassandra.pooling.max.connection.per.host.local</td><td><strong>Protocol V2 and below: 8, V3 and above: 1</strong></td></tr><tr><td>cassandra.pooling.max.connection.per.host.remote</td><td><strong>Protocol V2 and below: 2, V3 and above: 1</strong></td></tr><tr><td>cassandra.pooling.max.request.per.connection.local</td><td><strong>Protocol V2 and below: 128, V3 and above: 1024</strong></td></tr><tr><td>cassandra.pooling.max.request.per.connection.remote</td><td><strong>Protocol V2 and below: 128, V3 and above: 256</strong></td></tr><tr><td>cassandra.pooling.new.connection.threshold.local</td><td><strong>Protocol V2 and below: 100, V3 and above: 800</strong></td></tr><tr><td>cassandra.pooling.new.connection.threshold.remote</td><td><strong>Protocol V2 and below: 100, V3 and above: 200</strong></td></tr><tr><td>cassandra.pooling.pool.timeout.millisecs</td><td><strong>5000</strong></td></tr><tr><td>cassandra.protocol.version
</td><td><strong>3</strong></td></tr><tr><td>cassandra.query.default.consistency</td><td><strong>ONE</strong></td></tr><tr><td>cassandra.query.default.fetchSize</td><td><strong>5000</strong></td></tr><tr><td>cassandra.query.default.serial.consistency</td><td><strong>SERIAL</strong></td></tr><tr><td>cassandra.reconnection.policy</td><td><strong>DEFAULT</strong>, or a FQCN of a custom class</td></tr><tr><td>cassandra.retry.policy</td><td><strong>DEFAULT</strong>, or a FQCN of a custom class</td></tr><tr><td>cassandra.socket.connection.timeout.millisecs</td><td><strong>500</strong></td></tr><tr><td>cassandra.socket.read.timeout.millisecs</td><td><strong>12000</strong></td></tr><tr><td>cassandra.socket.tcp.no_delay</td><td><strong>true</strong></td></tr><tr><td>cassandra.speculative.execution.policy</td><td><strong>DEFAULT</strong>, or a FQCN of a custom class</td></tr></tbody></table></div></div></div><div class="panel panel-default"><div class="panel-heading" role="tab"><h4 class="pan
el-title"><a role="button" data-toggle="collapse" aria-expanded="false"><span class="text-info"><strong>Shared states</strong></span></a></h4></div><div class="panel-collapse collapse" role="tabpanel"><div class="panel-body">It is possible to execute many paragraphs in parallel. However, at the back-end side, we’re still using synchronous queries. <em>Asynchronous execution</em> is only possible when it is possible to return a <strong>Future</strong> value in the <strong>InterpreterResult</strong>. It may be an interesting proposal for the <strong>Zeppelin</strong> project.<br/>Another caveat is that the same <strong>com.datastax.driver.core.Session</strong> object is used for <strong>all</strong> notebooks and paragraphs. Consequently, if you use the <em>USE keyspace name;</em> statement to log into a keyspace, it will change the keyspace for <strong>all current users</strong> of the Cassandra interpreter because we only create 1 <strong>com.datastax.driver.core.Session</strong
> object per instance of <strong>Cassandra</strong> interpreter.<br/>The same remark does apply to the <strong>prepared statement hash map</strong>, it is shared by <strong>all users</strong> using the same instance of <strong>Cassandra</strong> interpreter.<br/>Until <strong>Zeppelin</strong> offers a real multi-users separation, there is a work-around to segregate user environment and states: <em>create different Cassandra interpreter instances</em><br/><ol><li>First go to the <strong>Interpreter</strong> menu and click on the <strong>Create</strong> button</li><li>In the interpreter creation form, put <strong>cass-instance2</strong> as <strong>Name</strong> and select the <strong>cassandra</strong> in the interpreter drop-down list</li><li>Click on <strong>Save</strong> to create the new interpreter instance. Now you should be able to see it in the interpreter list</li><li>Go back to your notebook and click on the <strong>Gear</strong> icon to configure interpreter bindings. You
should be able to see and select the <strong>cass-instance2</strong> interpreter instance in the available interpreter list instead of the standard <strong>cassandra</strong> instance</li></ol></div></div></div><div class="panel panel-default"><div class="panel-heading" role="tab"><h4 class="panel-title"><a role="button" data-toggle="collapse" aria-expanded="false"><span class="text-info"><strong>Change Log</strong></span></a></h4></div><div class="panel-collapse collapse" role="tabpanel"><div class="panel-body"><strong>2.0</strong> :<br/><ul><li>Update help menu and add changelog</li><li>Add Support for User Defined Functions, User Defined Aggregates and Materialized Views</li><li>Upgrade Java driver version to <strong>3.0.0-rc1</strong></li></ul><strong>1.0</strong> :<br/><ul><li>Initial version</li></ul></div></div></div><div class="panel panel-default"><div class="panel-heading" role="tab"><h4 class="panel-title"><a role="button" data-toggle="collapse" aria-expanded
="false"><span class="text-info"><strong>Contact & Bugs</strong></span></a></h4></div><div class="panel-collapse collapse" role="tabpanel"><div class="panel-body">If you encounter a bug for this interpreter, please create a <a href="https://issues.apache.org/jira/browse/ZEPPELIN-382?jql=project%20%3D%20ZEPPELIN" target="_blank"><strong>JIRA</strong></a> ticket and ping me on Twitter at <a href="https://twitter.com/doanduyhai" target="_blank"><strong>@doanduyhai</strong></a></div></div></div></div>
\ No newline at end of file
[4/6] incubator-zeppelin git commit: [ZEPPELIN-559] Cassandra
interpreter v2
Posted by fe...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/test/resources/scalate/DescribeKeyspace_live_data.html
----------------------------------------------------------------------
diff --git a/cassandra/src/test/resources/scalate/DescribeKeyspace_live_data.html b/cassandra/src/test/resources/scalate/DescribeKeyspace_live_data.html
index 09e7342..344780a 100644
--- a/cassandra/src/test/resources/scalate/DescribeKeyspace_live_data.html
+++ b/cassandra/src/test/resources/scalate/DescribeKeyspace_live_data.html
@@ -1,819 +1 @@
-<br/>
-<br/>
-<nav class="navbar navbar-default">
- <ul class="nav navbar-nav">
-
- <li role="presentation" class="dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
- <span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> <strong>live_data</strong></span>
- <span class="text-danger caret"></span>
- <ul class="dropdown-menu">
-
-
- <li class="dropdown-header"><span class="text-primary">Tables</span></li>
- <li>
- <a role="button" data-toggle="collapse" data-target="#91e7ac20-3516-11e5-9d5f-8f0ea8ae1a37">
- <span class="text-primary"><i class="glyphicon glyphicon-th-list"/> complex_table</span>
- </a>
- </li>
- <li>
- <a role="button" data-toggle="collapse" data-target="#93e1a760-3516-11e5-9d5f-8f0ea8ae1a37">
- <span class="text-primary"><i class="glyphicon glyphicon-th-list"/> sensor_data</span>
- </a>
- </li>
- <li>
- <a role="button" data-toggle="collapse" data-target="#93e306f0-3516-11e5-9d5f-8f0ea8ae1a37">
- <span class="text-primary"><i class="glyphicon glyphicon-th-list"/> stations</span>
- </a>
- </li>
-
-
-
- <li role="separator" class="divider text-muted"></li>
- <li class="dropdown-header"><span class="text-warning">User Defined Types</span></li>
- <li>
- <a role="button" data-toggle="collapse" data-target="#93e48d90-3516-11e5-9d5f-8f0ea8ae1a37">
- <span class="text-warning"><i class="glyphicon glyphicon-copyright-mark"/> address</span>
- </a>
- </li>
- <li>
- <a role="button" data-toggle="collapse" data-target="#942c9310-3516-11e5-9d5f-8f0ea8ae1a37">
- <span class="text-warning"><i class="glyphicon glyphicon-copyright-mark"/> geolocation</span>
- </a>
- </li>
- </ul>
- </a>
- </li>
- <li>
- <a><strong>DESCRIBE KEYSPACE live_data;</strong></a>
- </li>
- </ul>
- <ul class="nav navbar-nav navbar-right">
- <li class="dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
- <strong>Legend</strong>
- <span class="caret"></span>
- </a>
- <ul class="dropdown-menu">
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-dashboard text-muted" /> Cluster
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-folder-open text-danger" /> Keyspace
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-copyright-mark text-warning" /> UDT
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-th-list text-primary" /> Table
- </a>
- </li>
- <li class="bg-info">
- <a role="button">
- <i class="glyphicon glyphicon-fullscreen" /> Partition Key
- </a>
- </li>
- <li class="bg-warning">
- <a role="button">
- <i class="glyphicon glyphicon-pushpin" /> Static Column
- </a>
- </li>
- <li class="bg-success">
- <a role="button">
- <i class="glyphicon glyphicon-sort" /> Clustering Column
- </a>
- </li>
- <li class="bg-success">
- <a role="button">
- <i class="glyphicon glyphicon-sort-by-attributes" /> Clustering Order ASC
- </a>
- </li>
- <li class="bg-success">
- <a role="button">
- <i class="glyphicon glyphicon-sort-by-attributes-alt" /> Clustering Order DESC
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-info-sign" /> Indexed Column
- </a>
- </li>
- </ul>
- </li>
- <li>
- <a href="#"></a>
- </li>
- </ul>
-</nav>
-<hr/>
-<div class="container">
- <!-- Keyspace -->
-
-
- <div class="row">
- <div class="col-md-2"></div>
- <div class="col-md-8 col-offset-md-2">
- <div class="panel panel-default table-responsive table-bordered">
- <table class="table">
- <thead>
- <tr>
- <th class="col-md-10">Replication</th>
- <th class="col-md-2">Durable Writes</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td class="col-md-10">{'replication_factor' : '1', 'class' : 'org.apache.cassandra.locator.SimpleStrategy'}</td>
- <td class="col-md-2">false</td>
- </tr>
- <tbody>
- </table>
- <div class="panel-footer">
- <a data-toggle="collapse" data-target="#8db09220-3516-11e5-9d5f-8f0ea8ae1a37_asCQL">
- <strong>As CQL statement</strong>
- <span class="caret"></span>
- </a>
- <br/><br/>
- <div class="collapse" id="8db09220-3516-11e5-9d5f-8f0ea8ae1a37_asCQL">
- <pre class="well">CREATE KEYSPACE live_data WITH REPLICATION = {
- 'class' : 'org.apache.cassandra.locator.SimpleStrategy',
- 'replication_factor': '1' }
-AND DURABLE_WRITES = false;</pre>
- </div>
- </div>
- </div>
- </div>
- <div class="col-md-2"></div>
- </div>
-
- <!-- Tables -->
- <div class="row"></div>
-
-
- <table width="100%">
- <td><hr /></td>
- <td style="width:1px; padding: 0 10px; white-space: nowrap;"><strong class="text-primary">Tables</strong></td>
- <td><hr /></td>
- </table>
- <div class="row">
- <div class="panel-group" role="tablist" aria-multiselectable="true">
-
- <div class="panel panel-default">
- <div class="panel-heading" role="tab">
- <h4 class="panel-title">
- <a role="button" data-toggle="collapse" data-target="#91e7ac20-3516-11e5-9d5f-8f0ea8ae1a37" aria-expanded="false">
- <span class="text-primary">
- <i class="glyphicon glyphicon-th-list"/> complex_table
- </span>
- </a>
- </h4>
- </div>
- <div id="91e7ac20-3516-11e5-9d5f-8f0ea8ae1a37" class="panel-collapse collapse" role="tabpanel">
- <div class="panel-body">
-
- <div class="row">
- <div class="col-md-2"/>
- <div class="col-md-8 col-offset-md-2">
- <div class="panel panel-default table-responsive table-bordered">
- <table class="table">
- <thead>
- <tr>
- <th class="col-md-4">Column Type</th>
- <th class="col-md-4">Column Name</th>
- <th class="col-md-4">Data Type</th>
- </tr>
- </thead>
- <tbody>
-
-
- <tr class="info">
- <td class="col-md-4">
- <i class="glyphicon glyphicon-fullscreen" title="Partition Key"/>
-
- <span></span>
-
- </td>
- <td class="col-md-4">pk1</td>
- <td class="col-md-4">uuid</td>
- </tr>
-
-
- <tr class="info">
- <td class="col-md-4">
- <i class="glyphicon glyphicon-fullscreen" title="Partition Key"/>
-
-
- <i class="glyphicon glyphicon-info-sign" title="Indexed Column"/>
- <em>pk2idx</em> <strong></strong>
-
- </td>
- <td class="col-md-4">pk2</td>
- <td class="col-md-4">int</td>
- </tr>
-
- <tr class="warning">
- <td class="col-md-4">
- <i class="glyphicon glyphicon-pushpin" title="Static Column"/>
-
- <span></span>
-
- </td>
- <td class="col-md-4">my_static1</td>
- <td class="col-md-4">text</td>
- </tr>
-
- <tr class="warning">
- <td class="col-md-4">
- <i class="glyphicon glyphicon-pushpin" title="Static Column"/>
-
- <span></span>
-
- </td>
- <td class="col-md-4">my_static2</td>
- <td class="col-md-4">text</td>
- </tr>
-
- <tr class="success">
- <td class="col-md-4">
- <i class="glyphicon glyphicon-sort" title="Clustering Column"/>
-
- <i class="glyphicon glyphicon-sort-by-attributes-alt" title="Sort DESC"/>
-
- <span></span>
-
- </td>
- <td class="col-md-4">clustering1</td>
- <td class="col-md-4">timestamp</td>
- </tr>
-
- <tr class="success">
- <td class="col-md-4">
- <i class="glyphicon glyphicon-sort" title="Clustering Column"/>
-
- <i class="glyphicon glyphicon-sort-by-attributes" title="Sort ASC"/>
-
-
- <i class="glyphicon glyphicon-info-sign" title="Indexed Column"/>
- <em>clustering2idx</em> <strong></strong>
-
- </td>
- <td class="col-md-4">clustering2</td>
- <td class="col-md-4">int</td>
- </tr>
-
- <tr class="success">
- <td class="col-md-4">
- <i class="glyphicon glyphicon-sort" title="Clustering Column"/>
-
- <i class="glyphicon glyphicon-sort-by-attributes-alt" title="Sort DESC"/>
-
- <span></span>
-
- </td>
- <td class="col-md-4">clustering3</td>
- <td class="col-md-4">text</td>
- </tr>
-
- <tr>
- <td class="col-md-4">
-
- <span></span>
-
- </td>
- <td class="col-md-4">entries_indexed_map</td>
- <td class="col-md-4">map<int, text></td>
- </tr>
-
- <tr>
- <td class="col-md-4">
-
-
- <i class="glyphicon glyphicon-info-sign" title="Indexed Column"/>
- <em>idx1</em> <strong></strong>
-
- </td>
- <td class="col-md-4">indexed1</td>
- <td class="col-md-4">text</td>
- </tr>
-
- <tr>
- <td class="col-md-4">
-
-
- <i class="glyphicon glyphicon-info-sign" title="Indexed Column"/>
- <em>idx2</em> <strong></strong>
-
- </td>
- <td class="col-md-4">indexed2</td>
- <td class="col-md-4">int</td>
- </tr>
-
- <tr>
- <td class="col-md-4">
-
-
- <i class="glyphicon glyphicon-info-sign" title="Indexed Column"/>
- <em>keys_map_idx</em> <strong></strong>
-
- </td>
- <td class="col-md-4">key_indexed_map</td>
- <td class="col-md-4">map<int, text></td>
- </tr>
-
- <tr>
- <td class="col-md-4">
-
- <span></span>
-
- </td>
- <td class="col-md-4">my_list</td>
- <td class="col-md-4">list<text></td>
- </tr>
-
- <tr>
- <td class="col-md-4">
-
- <span></span>
-
- </td>
- <td class="col-md-4">my_map</td>
- <td class="col-md-4">map<int, text></td>
- </tr>
-
- <tr>
- <td class="col-md-4">
-
- <span></span>
-
- </td>
- <td class="col-md-4">my_udt</td>
- <td class="col-md-4">frozen<live_data.address></td>
- </tr>
-
- <tr>
- <td class="col-md-4">
-
- <span></span>
-
- </td>
- <td class="col-md-4">my_udt_list</td>
- <td class="col-md-4">frozen<list<frozen<live_data.address>>></td>
- </tr>
-
- <tr>
- <td class="col-md-4">
-
- <span></span>
-
- </td>
- <td class="col-md-4">simple</td>
- <td class="col-md-4">double</td>
- </tr>
-
- </tbody>
- </table>
- <div class="panel-footer">
- <a data-toggle="collapse" data-target="#91eb0780-3516-11e5-9d5f-8f0ea8ae1a37_asCQL">
- <strong>As CQL statement</strong>
- <span class="caret"></span>
- </a>
- <br/><br/>
- <div class="collapse" id="91eb0780-3516-11e5-9d5f-8f0ea8ae1a37_asCQL">
- <pre class="well">CREATE TABLE live_data.complex_table (
- pk1 uuid,
- pk2 int,
- clustering1 timestamp,
- clustering2 int,
- clustering3 text,
- entries_indexed_map map<int, text>,
- indexed1 text,
- indexed2 int,
- key_indexed_map map<int, text>,
- my_list list<text>,
- my_map map<int, text>,
- my_static1 text static,
- my_static2 text static,
- my_udt frozen<live_data.address>,
- my_udt_list frozen<list<frozen<live_data.address>>>,
- simple double,
- PRIMARY KEY ((pk1, pk2), clustering1, clustering2, clustering3)
-) WITH CLUSTERING ORDER BY (clustering1 DESC, clustering2 ASC, clustering3 DESC)
- AND read_repair_chance = 0.0
- AND dclocal_read_repair_chance = 0.1
- AND gc_grace_seconds = 864000
- AND bloom_filter_fp_chance = 0.01
- AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' }
- AND comment = ''
- AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy' }
- AND compression = { 'sstable_compression' : 'org.apache.cassandra.io.compress.LZ4Compressor' }
- AND default_time_to_live = 0
- AND speculative_retry = '99.0PERCENTILE'
- AND min_index_interval = 128
- AND max_index_interval = 2048;
-CREATE INDEX pk2idx ON live_data.complex_table (pk2);
-CREATE INDEX clustering2idx ON live_data.complex_table (clustering2);
-CREATE INDEX idx1 ON live_data.complex_table (indexed1);
-CREATE INDEX idx2 ON live_data.complex_table (indexed2);
-CREATE INDEX keys_map_idx ON live_data.complex_table (KEYS(key_indexed_map));</pre>
- </div>
- </div>
- </div>
- </div>
- <div class="col-md-2"></div>
- </div>
- </div>
- </div>
- </div>
-
- <div class="panel panel-default">
- <div class="panel-heading" role="tab">
- <h4 class="panel-title">
- <a role="button" data-toggle="collapse" data-target="#93e1a760-3516-11e5-9d5f-8f0ea8ae1a37" aria-expanded="false">
- <span class="text-primary">
- <i class="glyphicon glyphicon-th-list"/> sensor_data
- </span>
- </a>
- </h4>
- </div>
- <div id="93e1a760-3516-11e5-9d5f-8f0ea8ae1a37" class="panel-collapse collapse" role="tabpanel">
- <div class="panel-body">
-
- <div class="row">
- <div class="col-md-2"/>
- <div class="col-md-8 col-offset-md-2">
- <div class="panel panel-default table-responsive table-bordered">
- <table class="table">
- <thead>
- <tr>
- <th class="col-md-4">Column Type</th>
- <th class="col-md-4">Column Name</th>
- <th class="col-md-4">Data Type</th>
- </tr>
- </thead>
- <tbody>
-
-
- <tr class="info">
- <td class="col-md-4">
- <i class="glyphicon glyphicon-fullscreen" title="Partition Key"/>
-
- <span></span>
-
- </td>
- <td class="col-md-4">sensor_id</td>
- <td class="col-md-4">uuid</td>
- </tr>
-
-
- <tr class="info">
- <td class="col-md-4">
- <i class="glyphicon glyphicon-fullscreen" title="Partition Key"/>
-
- <span></span>
-
- </td>
- <td class="col-md-4">month</td>
- <td class="col-md-4">int</td>
- </tr>
-
- <tr class="warning">
- <td class="col-md-4">
- <i class="glyphicon glyphicon-pushpin" title="Static Column"/>
-
- <span></span>
-
- </td>
- <td class="col-md-4">characteristics</td>
- <td class="col-md-4">map<text, text></td>
- </tr>
-
- <tr class="warning">
- <td class="col-md-4">
- <i class="glyphicon glyphicon-pushpin" title="Static Column"/>
-
- <span></span>
-
- </td>
- <td class="col-md-4">model_number</td>
- <td class="col-md-4">text</td>
- </tr>
-
- <tr class="warning">
- <td class="col-md-4">
- <i class="glyphicon glyphicon-pushpin" title="Static Column"/>
-
- <span></span>
-
- </td>
- <td class="col-md-4">provider</td>
- <td class="col-md-4">text</td>
- </tr>
-
- <tr class="success">
- <td class="col-md-4">
- <i class="glyphicon glyphicon-sort" title="Clustering Column"/>
-
- <i class="glyphicon glyphicon-sort-by-attributes-alt" title="Sort DESC"/>
-
- <span></span>
-
- </td>
- <td class="col-md-4">date</td>
- <td class="col-md-4">timestamp</td>
- </tr>
-
- <tr>
- <td class="col-md-4">
-
- <span></span>
-
- </td>
- <td class="col-md-4">value</td>
- <td class="col-md-4">double</td>
- </tr>
-
- </tbody>
- </table>
- <div class="panel-footer">
- <a data-toggle="collapse" data-target="#93e1a761-3516-11e5-9d5f-8f0ea8ae1a37_asCQL">
- <strong>As CQL statement</strong>
- <span class="caret"></span>
- </a>
- <br/><br/>
- <div class="collapse" id="93e1a761-3516-11e5-9d5f-8f0ea8ae1a37_asCQL">
- <pre class="well">CREATE TABLE live_data.sensor_data (
- sensor_id uuid,
- month int,
- date timestamp,
- characteristics map<text, text> static,
- model_number text static,
- provider text static,
- value double,
- PRIMARY KEY ((sensor_id, month), date)
-) WITH CLUSTERING ORDER BY (date DESC)
- AND read_repair_chance = 0.0
- AND dclocal_read_repair_chance = 0.1
- AND gc_grace_seconds = 864000
- AND bloom_filter_fp_chance = 0.01
- AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' }
- AND comment = ''
- AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy' }
- AND compression = { 'sstable_compression' : 'org.apache.cassandra.io.compress.LZ4Compressor' }
- AND default_time_to_live = 0
- AND speculative_retry = '99.0PERCENTILE'
- AND min_index_interval = 128
- AND max_index_interval = 2048;</pre>
- </div>
- </div>
- </div>
- </div>
- <div class="col-md-2"></div>
- </div>
- </div>
- </div>
- </div>
-
- <div class="panel panel-default">
- <div class="panel-heading" role="tab">
- <h4 class="panel-title">
- <a role="button" data-toggle="collapse" data-target="#93e306f0-3516-11e5-9d5f-8f0ea8ae1a37" aria-expanded="false">
- <span class="text-primary">
- <i class="glyphicon glyphicon-th-list"/> stations
- </span>
- </a>
- </h4>
- </div>
- <div id="93e306f0-3516-11e5-9d5f-8f0ea8ae1a37" class="panel-collapse collapse" role="tabpanel">
- <div class="panel-body">
-
- <div class="row">
- <div class="col-md-2"/>
- <div class="col-md-8 col-offset-md-2">
- <div class="panel panel-default table-responsive table-bordered">
- <table class="table">
- <thead>
- <tr>
- <th class="col-md-4">Column Type</th>
- <th class="col-md-4">Column Name</th>
- <th class="col-md-4">Data Type</th>
- </tr>
- </thead>
- <tbody>
-
-
- <tr class="info">
- <td class="col-md-4">
- <i class="glyphicon glyphicon-fullscreen" title="Partition Key"/>
-
- <span></span>
-
- </td>
- <td class="col-md-4">station_id</td>
- <td class="col-md-4">uuid</td>
- </tr>
-
- <tr>
- <td class="col-md-4">
-
- <span></span>
-
- </td>
- <td class="col-md-4">sensors</td>
- <td class="col-md-4">frozen<map<uuid, frozen<live_data.geolocation>>></td>
- </tr>
-
- </tbody>
- </table>
- <div class="panel-footer">
- <a data-toggle="collapse" data-target="#93e306f1-3516-11e5-9d5f-8f0ea8ae1a37_asCQL">
- <strong>As CQL statement</strong>
- <span class="caret"></span>
- </a>
- <br/><br/>
- <div class="collapse" id="93e306f1-3516-11e5-9d5f-8f0ea8ae1a37_asCQL">
- <pre class="well">CREATE TABLE live_data.stations (
- station_id uuid,
- sensors frozen<map<uuid, frozen<live_data.geolocation>>>,
- PRIMARY KEY (station_id)
-) WITH read_repair_chance = 0.0
- AND dclocal_read_repair_chance = 0.1
- AND gc_grace_seconds = 864000
- AND bloom_filter_fp_chance = 0.01
- AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' }
- AND comment = ''
- AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy' }
- AND compression = { 'sstable_compression' : 'org.apache.cassandra.io.compress.LZ4Compressor' }
- AND default_time_to_live = 0
- AND speculative_retry = '99.0PERCENTILE'
- AND min_index_interval = 128
- AND max_index_interval = 2048;</pre>
- </div>
- </div>
- </div>
- </div>
- <div class="col-md-2"></div>
- </div>
- </div>
- </div>
- </div>
-
- </div>
- </div>
-
-
- <!-- UDTs -->
- <table width="100%">
- <td><hr /></td>
- <td style="width:1px; padding: 0 10px; white-space: nowrap;"><strong class="text-warning">User Defined Types</strong></td>
- <td><hr /></td>
- </table>
- <div class="row">
- <div class="panel-group" role="tablist" aria-multiselectable="true">
-
- <div class="panel panel-default">
- <div class="panel-heading" role="tab">
- <h4 class="panel-title">
- <a role="button" data-toggle="collapse" data-target="#93e48d90-3516-11e5-9d5f-8f0ea8ae1a37" aria-expanded="false">
- <span class="text-warning"><i class="glyphicon glyphicon-copyright-mark"/> address</span>
- </a>
- </h4>
- </div>
- <div id="93e48d90-3516-11e5-9d5f-8f0ea8ae1a37" class="panel-collapse collapse" role="tabpanel">
- <div class="panel-body">
-
- <div class="row">
- <div class="col-md-3"></div>
- <div class="col-md-6 col-offset-md-3">
- <div class="panel panel-default table-responsive table-bordered">
- <table class="table">
-
- <thead>
- <tr>
- <th class="col-md-6">Column Name</th>
- <th class="col-md-6">Data Type</th>
- </tr>
- </thead>
- <tbody>
-
- <tr>
- <td class="col-md-6">number</td>
- <td class="col-md-6">int</td>
- </tr>
-
- <tr>
- <td class="col-md-6">street</td>
- <td class="col-md-6">text</td>
- </tr>
-
- <tr>
- <td class="col-md-6">zip</td>
- <td class="col-md-6">int</td>
- </tr>
-
- <tr>
- <td class="col-md-6">city</td>
- <td class="col-md-6">text</td>
- </tr>
-
- <tr>
- <td class="col-md-6">country</td>
- <td class="col-md-6">text</td>
- </tr>
-
- <tbody>
- </table>
- <div class="panel-footer">
- <a data-toggle="collapse" data-target="#93e529d0-3516-11e5-9d5f-8f0ea8ae1a37_asCQL">
- <strong>As CQL statement</strong>
- <span class="caret"></span>
- </a>
- <br/><br/>
- <div class="collapse" id="93e529d0-3516-11e5-9d5f-8f0ea8ae1a37_asCQL">
- <pre class="well">CREATE TYPE live_data.address (
- number int,
- street text,
- zip int,
- city text,
- country text
-);</pre>
- </div>
- </div>
- </div>
- </div>
- <div class="col-md-3"></div>
- </div>
-
- </div>
- </div>
- </div>
-
- <div class="panel panel-default">
- <div class="panel-heading" role="tab">
- <h4 class="panel-title">
- <a role="button" data-toggle="collapse" data-target="#942c9310-3516-11e5-9d5f-8f0ea8ae1a37" aria-expanded="false">
- <span class="text-warning"><i class="glyphicon glyphicon-copyright-mark"/> geolocation</span>
- </a>
- </h4>
- </div>
- <div id="942c9310-3516-11e5-9d5f-8f0ea8ae1a37" class="panel-collapse collapse" role="tabpanel">
- <div class="panel-body">
-
- <div class="row">
- <div class="col-md-3"></div>
- <div class="col-md-6 col-offset-md-3">
- <div class="panel panel-default table-responsive table-bordered">
- <table class="table">
-
- <thead>
- <tr>
- <th class="col-md-6">Column Name</th>
- <th class="col-md-6">Data Type</th>
- </tr>
- </thead>
- <tbody>
-
- <tr>
- <td class="col-md-6">latitude</td>
- <td class="col-md-6">double</td>
- </tr>
-
- <tr>
- <td class="col-md-6">longitude</td>
- <td class="col-md-6">double</td>
- </tr>
-
- <tbody>
- </table>
- <div class="panel-footer">
- <a data-toggle="collapse" data-target="#942c9311-3516-11e5-9d5f-8f0ea8ae1a37_asCQL">
- <strong>As CQL statement</strong>
- <span class="caret"></span>
- </a>
- <br/><br/>
- <div class="collapse" id="942c9311-3516-11e5-9d5f-8f0ea8ae1a37_asCQL">
- <pre class="well">CREATE TYPE live_data.geolocation (
- latitude double,
- longitude double
-);</pre>
- </div>
- </div>
- </div>
- </div>
- <div class="col-md-3"></div>
- </div>
-
- </div>
- </div>
- </div>
-
- </div>
- </div>
-
-</div>
\ No newline at end of file
+<br/><br/><nav class="navbar navbar-default"><ul class="nav navbar-nav"><li role="presentation" class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="text-danger"><i class="glyphicon glyphicon-folder-open"/> <strong>live_data</strong></span><span class="text-danger caret"></span><ul class="dropdown-menu"><li class="dropdown-header"><span class="text-primary">Tables</span></li><li><a role="button" data-toggle="collapse" ><span class="text-primary"><i class="glyphicon glyphicon-th-list"/> complex_table</span></a></li><li><a role="button" data-toggle="collapse" ><span class="text-primary"><i class="glyphicon glyphicon-th-list"/> sensor_data</span></a></li><li><a role="button" data-toggle="collapse" ><span class="text-primary"><i class="glyphicon glyphicon-th-list"/> stations</span></a></li><li role="separator" class="divider text-muted"></li><li class="dropdown-header"><span cla
ss="text-warning">User Defined Types</span></li><li><a role="button" data-toggle="collapse" ><span class="text-warning"><i class="glyphicon glyphicon-copyright-mark"/> address</span></a></li><li><a role="button" data-toggle="collapse" ><span class="text-warning"><i class="glyphicon glyphicon-copyright-mark"/> geolocation</span></a></li></ul></a></li><li><a><strong>DESCRIBE KEYSPACE live_data;</strong></a></li></ul><ul class="nav navbar-nav navbar-right"><li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><strong>Legend</strong><span class="caret"></span></a><ul class="dropdown-menu"><li><a role="button"><i class="glyphicon glyphicon-dashboard text-muted" /> Cluster</a></li><li><a role="button"><i class="glyphicon glyphicon-folder-open text-danger" /> Keyspace</a></li><li><a role="button"><i class="glyphicon glyphicon-copyright-mark text-warning" /> UDT</a></li><li><a role
="button"><i class="glyphicon glyphicon-th-list text-primary" /> Table</a></li><li><a role="button"><i class="glyphicon glyphicon-eye-open text-primary" /> Materialized View</a></li><li><a role="button"><i class="glyphicon glyphicon-random text-success" /> Function</a></li><li><a role="button"><i class="glyphicon glyphicon-retweet text-success" /> Aggregate</a></li><li role="separator" class="divider text-muted"></li><li class="dropdown-header"><span class="text-primary">Table icons</span></li><li class="bg-info"><a role="button"><i class="glyphicon glyphicon-fullscreen" /> Partition Key</a></li><li class="bg-warning"><a role="button"><i class="glyphicon glyphicon-pushpin" /> Static Column</a></li><li class="bg-success"><a role="button"><i class="glyphicon glyphicon-sort" /> Clustering Column</a></li><li class="bg-success"><a role="button"><i class="glyphicon glyphicon-sort-by-attributes" /> Clus
tering Order ASC</a></li><li class="bg-success"><a role="button"><i class="glyphicon glyphicon-sort-by-attributes-alt" /> Clustering Order DESC</a></li></ul></li><li><a href="#"></a></li></ul></nav><hr/><div class="container"><!-- Keyspace --><div class="row"><div class="col-md-2"></div><div class="col-md-8 col-offset-md-2"><div class="panel panel-default table-responsive table-bordered"><table class="table"><caption><h4 class="text-danger"><i class="glyphicon glyphicon-folder-open"/> live_data</h4></caption><thead><tr><th class="col-md-10">Replication</th><th class="col-md-2">Durable Writes</th></tr></thead><tbody><tr><td class="col-md-10">{'replication_factor' : '1', 'class' : 'org.apache.cassandra.locator.SimpleStrategy'}</td><td class="col-md-2">false</td></tr><tbody></table><div class="panel-footer"><a data-toggle="collapse" class="text-danger"><strong>As CQL statement</strong><span class="caret"></span></a><br/><br/><div class="collapse" ><pre class="wel
l">CREATE KEYSPACE live_data WITH REPLICATION = {'class' : 'org.apache.cassandra.locator.SimpleStrategy','replication_factor': '1' }AND DURABLE_WRITES = false;</pre></div></div></div></div><div class="col-md-2"></div></div><!-- Tables --><div class="row"></div><table width="100%"><td><hr /></td><td style="width:1px; padding: 0 10px; white-space: nowrap;"><strong class="text-primary">Tables</strong></td><td><hr /></td></table><div class="row"><div class="panel-group" role="tablist" aria-multiselectable="true"><div class="panel panel-default"><div class="panel-heading" role="tab"><h4 class="panel-title"><a role="button" data-toggle="collapse" aria-expanded="false"><span class="text-primary"><i class="glyphicon glyphicon-th-list"/> complex_table</span></a></h4></div><div class="panel-collapse collapse" role="tabpanel"><div class="panel-body"><div class="row"><div class="col-md-2"/><div class="col-md-8 col-offset-md-2"><div class="panel panel-default table-responsive table-border
ed"><table class="table"><thead><tr><th class="col-md-4">Column Type</th><th class="col-md-4">Column Name</th><th class="col-md-4">Data Type</th></tr></thead><tbody><tr class="info"><td class="col-md-4"><i class="glyphicon glyphicon-fullscreen" title="Partition Key"/></td><td class="col-md-4">pk1</td><td class="col-md-4">uuid</td></tr><tr class="info"><td class="col-md-4"><i class="glyphicon glyphicon-fullscreen" title="Partition Key"/></td><td class="col-md-4">pk2</td><td class="col-md-4">int</td></tr><tr class="warning"><td class="col-md-4"><i class="glyphicon glyphicon-pushpin" title="Static Column"/></td><td class="col-md-4">my_static1</td><td class="col-md-4">text</td></tr><tr class="warning"><td class="col-md-4"><i class="glyphicon glyphicon-pushpin" title="Static Column"/></td><td class="col-md-4">my_static2</td><td class="col-md-4">text</td></tr><tr class="success"><td class="col-md-4"><i class="glyphicon glyphicon-sort" title="Clustering Column"/> <i class="glyphicon g
lyphicon-sort-by-attributes-alt" title="Sort DESC"/></td><td class="col-md-4">clustering1</td><td class="col-md-4">timestamp</td></tr><tr class="success"><td class="col-md-4"><i class="glyphicon glyphicon-sort" title="Clustering Column"/> <i class="glyphicon glyphicon-sort-by-attributes" title="Sort ASC"/></td><td class="col-md-4">clustering2</td><td class="col-md-4">int</td></tr><tr class="success"><td class="col-md-4"><i class="glyphicon glyphicon-sort" title="Clustering Column"/> <i class="glyphicon glyphicon-sort-by-attributes-alt" title="Sort DESC"/></td><td class="col-md-4">clustering3</td><td class="col-md-4">text</td></tr><tr><td class="col-md-4"></td><td class="col-md-4">entries_indexed_map</td><td class="col-md-4">map<int, text></td></tr><tr><td class="col-md-4"></td><td class="col-md-4">indexed1</td><td class="col-md-4">text</td></tr><tr><td class="col-md-4"></td><td class="col-md-4">indexed2</td><td class="col-md-4">int</td></tr><tr><td class="col-md-4"><
/td><td class="col-md-4">key_indexed_map</td><td class="col-md-4">map<int, text></td></tr><tr><td class="col-md-4"></td><td class="col-md-4">my_list</td><td class="col-md-4">list<text></td></tr><tr><td class="col-md-4"></td><td class="col-md-4">my_map</td><td class="col-md-4">map<int, text></td></tr><tr><td class="col-md-4"></td><td class="col-md-4">my_udt</td><td class="col-md-4">frozen<live_data.address></td></tr><tr><td class="col-md-4"></td><td class="col-md-4">my_udt_list</td><td class="col-md-4">frozen<list<frozen<live_data.address>>></td></tr><tr><td class="col-md-4"></td><td class="col-md-4">simple</td><td class="col-md-4">double</td></tr></tbody></table><div class="panel-footer"><a data-toggle="collapse" class="text-primary"><strong>As CQL statement</strong><span class="caret"></span></a><br/><br/><div class="collapse" ><pre class="well">CREATE TABLE live_data.complex_table (pk1 uuid,pk2 int,clustering1 timestamp,clustering2 int,cl
ustering3 text,entries_indexed_map map<int, text>,indexed1 text,indexed2 int,key_indexed_map map<int, text>,my_list list<text>,my_map map<int, text>,my_static1 text static,my_static2 text static,my_udt frozen<live_data.address>,my_udt_list frozen<list<frozen<live_data.address>>>,simple double,PRIMARY KEY ((pk1, pk2), clustering1, clustering2, clustering3)) WITH CLUSTERING ORDER BY (clustering1 DESC, clustering2 ASC, clustering3 DESC)AND read_repair_chance = 0.0AND dclocal_read_repair_chance = 0.1AND gc_grace_seconds = 864000AND bloom_filter_fp_chance = 0.01AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' }AND comment = ''AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy' }AND compression = { 'sstable_compression' : 'org.apache.cassandra.io.compress.LZ4Compressor' }AND default_time_to_live = 0AND speculative_retry = '99.0PERCENTILE'AND min_index_interval = 128AND max_index_interva
l = 2048;</pre></div></div></div><hr/><div class="panel panel-default table-responsive table-bordered"><table class="table"><caption><h4 class="text-danger"><i class="glyphicon glyphicon-info-sign"/> complex_table's indices</h4></caption><thead><tr><th class="col-md-6">Name</th><th class="col-md-6">Target</th></tr></thead><tbody><tr><td class="col-md-6">clustering2idx</td><td class="col-md-6">clustering2</td></tr><tr><td class="col-md-6">idx1</td><td class="col-md-6">indexed1</td></tr><tr><td class="col-md-6">idx2</td><td class="col-md-6">indexed2</td></tr><tr><td class="col-md-6">keys_map_idx</td><td class="col-md-6">keys(key_indexed_map)</td></tr><tr><td class="col-md-6">pk2idx</td><td class="col-md-6">pk2</td></tr></tbody></table><div class="panel-footer"><a data-toggle="collapse" class="text-danger"><strong>As CQL statement</strong><span class="caret"></span></a><br/><br/><div class="collapse" ><pre class="well">CREATE INDEX clustering2idx ON live_data.complex_table (clust
ering2);CREATE INDEX idx1 ON live_data.complex_table (indexed1);CREATE INDEX idx2 ON live_data.complex_table (indexed2);CREATE INDEX keys_map_idx ON live_data.complex_table (keys(key_indexed_map));CREATE INDEX pk2idx ON live_data.complex_table (pk2);</pre></div></div></div></div><div class="col-md-2"></div></div></div></div></div><div class="panel panel-default"><div class="panel-heading" role="tab"><h4 class="panel-title"><a role="button" data-toggle="collapse" aria-expanded="false"><span class="text-primary"><i class="glyphicon glyphicon-th-list"/> sensor_data</span></a></h4></div><div class="panel-collapse collapse" role="tabpanel"><div class="panel-body"><div class="row"><div class="col-md-2"/><div class="col-md-8 col-offset-md-2"><div class="panel panel-default table-responsive table-bordered"><table class="table"><thead><tr><th class="col-md-4">Column Type</th><th class="col-md-4">Column Name</th><th class="col-md-4">Data Type</th></tr></thead><tbody><tr class="info"><t
d class="col-md-4"><i class="glyphicon glyphicon-fullscreen" title="Partition Key"/></td><td class="col-md-4">sensor_id</td><td class="col-md-4">uuid</td></tr><tr class="info"><td class="col-md-4"><i class="glyphicon glyphicon-fullscreen" title="Partition Key"/></td><td class="col-md-4">month</td><td class="col-md-4">int</td></tr><tr class="warning"><td class="col-md-4"><i class="glyphicon glyphicon-pushpin" title="Static Column"/></td><td class="col-md-4">characteristics</td><td class="col-md-4">map<text, text></td></tr><tr class="warning"><td class="col-md-4"><i class="glyphicon glyphicon-pushpin" title="Static Column"/></td><td class="col-md-4">model_number</td><td class="col-md-4">text</td></tr><tr class="warning"><td class="col-md-4"><i class="glyphicon glyphicon-pushpin" title="Static Column"/></td><td class="col-md-4">provider</td><td class="col-md-4">text</td></tr><tr class="success"><td class="col-md-4"><i class="glyphicon glyphicon-sort" title="Clustering Column"/>&n
bsp;<i class="glyphicon glyphicon-sort-by-attributes-alt" title="Sort DESC"/></td><td class="col-md-4">date</td><td class="col-md-4">timestamp</td></tr><tr><td class="col-md-4"></td><td class="col-md-4">value</td><td class="col-md-4">double</td></tr></tbody></table><div class="panel-footer"><a data-toggle="collapse" class="text-primary"><strong>As CQL statement</strong><span class="caret"></span></a><br/><br/><div class="collapse" ><pre class="well">CREATE TABLE live_data.sensor_data (sensor_id uuid,month int,date timestamp,characteristics map<text, text> static,model_number text static,provider text static,value double,PRIMARY KEY ((sensor_id, month), date)) WITH CLUSTERING ORDER BY (date DESC)AND read_repair_chance = 0.0AND dclocal_read_repair_chance = 0.1AND gc_grace_seconds = 864000AND bloom_filter_fp_chance = 0.01AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' }AND comment = ''AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompac
tionStrategy' }AND compression = { 'sstable_compression' : 'org.apache.cassandra.io.compress.LZ4Compressor' }AND default_time_to_live = 0AND speculative_retry = '99.0PERCENTILE'AND min_index_interval = 128AND max_index_interval = 2048;</pre></div></div></div></div><div class="col-md-2"></div></div></div></div></div><div class="panel panel-default"><div class="panel-heading" role="tab"><h4 class="panel-title"><a role="button" data-toggle="collapse" aria-expanded="false"><span class="text-primary"><i class="glyphicon glyphicon-th-list"/> stations</span></a></h4></div><div class="panel-collapse collapse" role="tabpanel"><div class="panel-body"><div class="row"><div class="col-md-2"/><div class="col-md-8 col-offset-md-2"><div class="panel panel-default table-responsive table-bordered"><table class="table"><thead><tr><th class="col-md-4">Column Type</th><th class="col-md-4">Column Name</th><th class="col-md-4">Data Type</th></tr></thead><tbody><tr class="info"><td class="col-md-4"
><i class="glyphicon glyphicon-fullscreen" title="Partition Key"/></td><td class="col-md-4">station_id</td><td class="col-md-4">uuid</td></tr><tr><td class="col-md-4"></td><td class="col-md-4">sensors</td><td class="col-md-4">frozen<map<uuid, frozen<live_data.geolocation>>></td></tr></tbody></table><div class="panel-footer"><a data-toggle="collapse" class="text-primary"><strong>As CQL statement</strong><span class="caret"></span></a><br/><br/><div class="collapse" ><pre class="well">CREATE TABLE live_data.stations (station_id uuid,sensors frozen<map<uuid, frozen<live_data.geolocation>>>,PRIMARY KEY (station_id)) WITH read_repair_chance = 0.0AND dclocal_read_repair_chance = 0.1AND gc_grace_seconds = 864000AND bloom_filter_fp_chance = 0.01AND caching = { 'keys' : 'ALL', 'rows_per_partition' : 'NONE' }AND comment = ''AND compaction = { 'class' : 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy' }AND compression = { 'sstable_compressi
on' : 'org.apache.cassandra.io.compress.LZ4Compressor' }AND default_time_to_live = 0AND speculative_retry = '99.0PERCENTILE'AND min_index_interval = 128AND max_index_interval = 2048;</pre></div></div></div></div><div class="col-md-2"></div></div></div></div></div></div></div><!-- UDTs --><table width="100%"><td><hr /></td><td style="width:1px; padding: 0 10px; white-space: nowrap;"><strong class="text-warning">User Defined Types</strong></td><td><hr /></td></table><div class="row"><div class="panel-group" role="tablist" aria-multiselectable="true"><div class="panel panel-default"><div class="panel-heading" role="tab"><h4 class="panel-title"><a role="button" data-toggle="collapse" aria-expanded="false"><span class="text-warning"><i class="glyphicon glyphicon-copyright-mark"/> address</span></a></h4></div><div class="panel-collapse collapse" role="tabpanel"><div class="panel-body"><div class="row"><div class="col-md-3"></div><div class="col-md-6 col-offset-md-3"><div class="pan
el panel-default table-responsive table-bordered"><table class="table"><thead><tr><th class="col-md-6">Column Name</th><th class="col-md-6">Data Type</th></tr></thead><tbody><tr><td class="col-md-6">number</td><td class="col-md-6">int</td></tr><tr><td class="col-md-6">street</td><td class="col-md-6">text</td></tr><tr><td class="col-md-6">zip</td><td class="col-md-6">int</td></tr><tr><td class="col-md-6">city</td><td class="col-md-6">text</td></tr><tr><td class="col-md-6">country</td><td class="col-md-6">text</td></tr><tbody></table><div class="panel-footer"><a data-toggle="collapse" class="text-warning"><strong>As CQL statement</strong><span class="caret"></span></a><br/><br/><div class="collapse" ><pre class="well">CREATE TYPE live_data.address (number int,street text,zip int,city text,country text);</pre></div></div></div></div><div class="col-md-3"></div></div></div></div></div><div class="panel panel-default"><div class="panel-heading" role="tab"><h4 class="panel-title"><a role
="button" data-toggle="collapse" aria-expanded="false"><span class="text-warning"><i class="glyphicon glyphicon-copyright-mark"/> geolocation</span></a></h4></div><div class="panel-collapse collapse" role="tabpanel"><div class="panel-body"><div class="row"><div class="col-md-3"></div><div class="col-md-6 col-offset-md-3"><div class="panel panel-default table-responsive table-bordered"><table class="table"><thead><tr><th class="col-md-6">Column Name</th><th class="col-md-6">Data Type</th></tr></thead><tbody><tr><td class="col-md-6">latitude</td><td class="col-md-6">double</td></tr><tr><td class="col-md-6">longitude</td><td class="col-md-6">double</td></tr><tbody></table><div class="panel-footer"><a data-toggle="collapse" class="text-warning"><strong>As CQL statement</strong><span class="caret"></span></a><br/><br/><div class="collapse" ><pre class="well">CREATE TYPE live_data.geolocation (latitude double,longitude double);</pre></div></div></div></div><div class="col-md-3"></
div></div></div></div></div></div></div></div>
\ No newline at end of file
[5/6] incubator-zeppelin git commit: [ZEPPELIN-559] Cassandra
interpreter v2
Posted by fe...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/scala/org/apache/zeppelin/cassandra/DisplaySystem.scala
----------------------------------------------------------------------
diff --git a/cassandra/src/main/scala/org/apache/zeppelin/cassandra/DisplaySystem.scala b/cassandra/src/main/scala/org/apache/zeppelin/cassandra/DisplaySystem.scala
index 2881b4b..135d4cd 100644
--- a/cassandra/src/main/scala/org/apache/zeppelin/cassandra/DisplaySystem.scala
+++ b/cassandra/src/main/scala/org/apache/zeppelin/cassandra/DisplaySystem.scala
@@ -18,7 +18,6 @@ package org.apache.zeppelin.cassandra
import java.util.UUID
-import com.datastax.driver.core.ColumnMetadata.IndexMetadata
import com.datastax.driver.core.utils.UUIDs
import org.apache.zeppelin.cassandra.MetaDataHierarchy._
import org.fusesource.scalate.TemplateEngine
@@ -39,16 +38,30 @@ object DisplaySystem {
val CLUSTER_DETAILS_TEMPLATE = "scalate/clusterDetails.ssp"
val KEYSPACE_DETAILS_TEMPLATE = "scalate/keyspaceDetails.ssp"
+
val TABLE_DETAILS_TEMPLATE = "scalate/tableDetails.ssp"
+ val ALL_TABLES_TEMPLATE = "scalate/allTables.ssp"
+
val UDT_DETAILS_TEMPLATE = "scalate/udtDetails.ssp"
+ val ALL_UDTS_TEMPLATE = "scalate/allUDTs.ssp"
+
+ val FUNCTION_DETAILS_TEMPLATE = "scalate/functionDetails.ssp"
+ val ALL_FUNCTIONS_TEMPLATE = "scalate/allFunctions.ssp"
+
+ val AGGREGATE_DETAILS_TEMPLATE = "scalate/aggregateDetails.ssp"
+ val ALL_AGGREGATES_TEMPLATE = "scalate/allAggregates.ssp"
+
+ val MATERIALIZED_VIEW_DETAILS_TEMPLATE = "scalate/materializedViewDetails.ssp"
+ val ALL_MATERIALIZED_VIEWS_TEMPLATE = "scalate/allMaterializedViews.ssp"
val MENU_TEMPLATE = "scalate/menu.ssp"
val CLUSTER_DROPDOWN_TEMPLATE = "scalate/dropDownMenuForCluster.ssp"
- val KEYSPACE_DROPDOWN_TEMPLATE = "scalate/dropDownMenuForKeyspace.ssp"
+ val KEYSPACE_DROPDOWN_TEMPLATE = "scalate/dropDownMenuForKeyspace.ssp"
val CLUSTER_CONTENT_TEMPLATE = "scalate/clusterContent.ssp"
val KEYSPACE_CONTENT_TEMPLATE = "scalate/keyspaceContent.ssp"
- val ALL_TABLES_TEMPLATE = "scalate/allTables.ssp"
+
+
object TableDisplay {
@@ -58,10 +71,12 @@ object DisplaySystem {
protected[DisplaySystem] def formatWithoutMenu(meta: TableMetadata, withCaption: Boolean): String = {
val tableName: String = meta.getName
- val columnsDetails = MetaDataConverter.tableMetaToColumnDetails(meta)
+ val columnsDetails = MetaDataConverter.Table.tableMetaToColumnDetails(meta)
+ val indicesDetails = MetaDataConverter.Table.tableMetaToIndexDetails(meta)
+ val indicesAsCQL = indicesDetails.map(_.asCQL).mkString("\n")
engine.layout(TABLE_DETAILS_TEMPLATE,
- Map[String, Any]("tableDetails" -> TableDetails(tableName, columnsDetails, meta.exportAsString), "withCaption" -> withCaption))
+ Map[String, Any]("tableDetails" -> TableDetails(tableName, columnsDetails, indicesDetails, TableMetadataWrapper(meta).exportTableOnlyAsString(), indicesAsCQL), "withCaption" -> withCaption))
}
}
@@ -72,13 +87,49 @@ object DisplaySystem {
protected[DisplaySystem] def formatWithoutMenu(userType: UserType, withCaption: Boolean): String = {
val udtName: String = userType.getTypeName
- val columnsDetails = MetaDataConverter.userTypeToColumnDetails(userType)
+ val columnsDetails = MetaDataConverter.UDT.userTypeToColumnDetails(userType)
engine.layout(UDT_DETAILS_TEMPLATE,
- Map[String, Any]("udtDetails" -> UDTDetails(udtName, columnsDetails, userType.exportAsString), "withCaption" -> withCaption))
+ Map[String, Any]("udtDetails" -> UDTDetails(udtName,columnsDetails,userType.exportAsString()), "withCaption" -> withCaption))
+ }
+ }
+
+ object FunctionDisplay {
+ def format(statement: String, functions: List[FunctionMetadata], withCaption: Boolean): String = {
+ MenuDisplay.formatMenu(statement) ++ formatWithoutMenu(functions, withCaption)
+ }
+
+ protected[DisplaySystem] def formatWithoutMenu(functions: List[FunctionMetadata], withCaption: Boolean): String = {
+ val functionDetails: List[FunctionDetails] = functions.map(MetaDataConverter.functionMetaToFunctionDetails(_))
+ engine.layout(FUNCTION_DETAILS_TEMPLATE,
+ Map[String, Any]("sameNameFunctionDetails" -> SameNameFunctionDetails(functionDetails), "withCaption" -> withCaption))
}
}
-
+
+ object AggregateDisplay {
+ def format(statement: String, aggregates: List[AggregateMetadata], withCaption: Boolean, codecRegistry: CodecRegistry): String = {
+ MenuDisplay.formatMenu(statement) ++ formatWithoutMenu(aggregates, withCaption, codecRegistry)
+ }
+
+ protected[DisplaySystem] def formatWithoutMenu(aggregates: List[AggregateMetadata], withCaption: Boolean, codecRegistry: CodecRegistry): String = {
+ val aggDetails: List[AggregateDetails] = aggregates.map(agg => MetaDataConverter.aggregateMetaToAggregateDetails(codecRegistry, agg))
+ engine.layout(AGGREGATE_DETAILS_TEMPLATE,
+ Map[String, Any]("sameNameAggregateDetails" -> SameNameAggregateDetails(aggDetails), "withCaption" -> withCaption))
+ }
+ }
+
+ object MaterializedViewDisplay {
+ def format(statement: String, mv: MaterializedViewMetadata, withCaption: Boolean): String = {
+ MenuDisplay.formatMenu(statement) ++ formatWithoutMenu(mv, withCaption)
+ }
+
+ protected[DisplaySystem] def formatWithoutMenu(mv: MaterializedViewMetadata, withCaption: Boolean): String = {
+ val mvDetails = MetaDataConverter.mvMetaToMaterializedViewDetails(mv)
+ engine.layout(MATERIALIZED_VIEW_DETAILS_TEMPLATE,
+ Map[String, Any]("mvDetails" -> mvDetails, "withCaption" -> withCaption))
+ }
+ }
+
object KeyspaceDisplay {
private def formatCQLQuery(cql: String): String = {
@@ -97,19 +148,32 @@ object DisplaySystem {
Map[String, Any]("ksDetails" -> ksDetails, "withCaption" -> withCaption))
}
- def formatKeyspaceContent(statement: String, meta: KeyspaceMetadata): String = {
+ def formatKeyspaceContent(statement: String, meta: KeyspaceMetadata, codecRegistry: CodecRegistry): String = {
val ksName: String = meta.getName
- val ksDetails = formatKeyspaceOnly(meta, false)
+ val ksDetails = formatKeyspaceOnly(meta, true)
val tableDetails: List[(UUID, String, String)] = meta.getTables.asScala.toList
- .sortBy(meta => meta.getName)
- .map(meta => (UUIDs.timeBased(), meta.getName, TableDisplay.formatWithoutMenu(meta, false)))
+ .sortBy(_.getName)
+ .map(table => (UUIDs.timeBased(), table.getName, TableDisplay.formatWithoutMenu(table, false)))
+
+ val viewDetails: List[(UUID, String, String)] = meta.getMaterializedViews.asScala.toList
+ .sortBy(_.getName)
+ .map(view => (UUIDs.timeBased(), view.getName, MaterializedViewDisplay.formatWithoutMenu(view, false)))
val udtDetails: List[(UUID, String, String)] = meta.getUserTypes.asScala.toList
- .sortBy(udt => udt.getTypeName)
+ .sortBy(_.getTypeName)
.map(udt => (UUIDs.timeBased(), udt.getTypeName, UDTDisplay.formatWithoutMenu(udt, false)))
- val ksContent: KeyspaceContent = KeyspaceContent(ksName, ksDetails, tableDetails, udtDetails)
+ val functionDetails: List[(UUID, String, String)] = meta.getFunctions.asScala.toList
+ .sortBy(_.getSimpleName)
+ .map(function => (UUIDs.timeBased(), function.getSimpleName, FunctionDisplay.formatWithoutMenu(List(function), false)))
+
+ val aggregateDetails: List[(UUID, String, String)] = meta.getAggregates.asScala.toList
+ .sortBy(_.getSimpleName)
+ .map(agg => (UUIDs.timeBased(), agg.getSimpleName, AggregateDisplay.formatWithoutMenu(List(agg), false, codecRegistry)))
+
+ val ksContent: KeyspaceContent = KeyspaceContent(ksName, ksDetails, tableDetails, viewDetails,
+ udtDetails, functionDetails, aggregateDetails)
MenuDisplay.formatMenuForKeyspace(statement, ksContent) +
engine.layout(KEYSPACE_CONTENT_TEMPLATE,
@@ -144,26 +208,152 @@ object DisplaySystem {
def formatAllTables(statement: String, meta: Metadata): String = {
val ksMetas: List[KeyspaceMetadata] = meta.getKeyspaces.asScala.toList
+ .filter(_.getTables.size > 0)
.sortBy(ks => ks.getName)
+ if(ksMetas.isEmpty) {
+ NoResultDisplay.formatNoResult
+ } else {
+ val allTables: Map[(UUID, String), List[String]] = ListMap.empty ++
+ ksMetas
+ .map(ks => {
+ ((UUIDs.timeBased(), ks.getName),
+ ks.getTables.asScala.toList.map(table => table.getName).sortBy(name => name))
+ })
+ .sortBy{case ((id,name), _) => name}
+
+
+ val keyspaceDetails: List[(UUID, String, String)] = allTables
+ .keySet.toList.sortBy{case(id,ksName) => ksName}
+ .map{case(id,ksName) => (id,ksName, "")}
+
+ val clusterContent: ClusterContent = ClusterContent(meta.getClusterName, "", keyspaceDetails)
+
+ MenuDisplay.formatMenuForCluster(statement, clusterContent) +
+ engine.layout(ALL_TABLES_TEMPLATE,
+ Map[String, Any]("allTables" -> allTables))
+ }
+ }
- val allTables: Map[(UUID, String), List[String]] = ListMap.empty ++
- ksMetas
- .map(ks => {
- ((UUIDs.timeBased(), ks.getName),
- ks.getTables.asScala.toList.map(table => table.getName).sortBy(name => name))
- })
- .sortBy{case ((id,name), _) => name}
+ def formatAllUDTs(statement: String, meta: Metadata): String = {
+ val ksMetas: List[KeyspaceMetadata] = meta.getKeyspaces.asScala.toList
+ .filter(_.getUserTypes.size > 0)
+ .sortBy(ks => ks.getName)
+ if(ksMetas.isEmpty) {
+ NoResultDisplay.formatNoResult
+ } else {
+ val allUDTs: Map[(UUID, String), List[String]] = ListMap.empty ++
+ ksMetas
+ .map(ks => {
+ ((UUIDs.timeBased(), ks.getName),
+ ks.getUserTypes.asScala.toList.map(udt => udt.getTypeName).sortBy(name => name))
+ })
+ .sortBy { case ((id, name), _) => name }
- val keyspaceDetails: List[(UUID, String, String)] = allTables
- .keySet.toList.sortBy{case(id,ksName) => ksName}
- .map{case(id,ksName) => (id,ksName, "")}
- val clusterContent: ClusterContent = ClusterContent(meta.getClusterName, "", keyspaceDetails)
+ val keyspaceDetails: List[(UUID, String, String)] = allUDTs
+ .keySet.toList.sortBy { case (id, ksName) => ksName }
+ .map { case (id, ksName) => (id, ksName, "") }
- MenuDisplay.formatMenuForCluster(statement, clusterContent) +
- engine.layout(ALL_TABLES_TEMPLATE,
- Map[String, Any]("allTables" -> allTables))
+ val clusterContent: ClusterContent = ClusterContent(meta.getClusterName, "", keyspaceDetails)
+
+ MenuDisplay.formatMenuForCluster(statement, clusterContent) +
+ engine.layout(ALL_UDTS_TEMPLATE,
+ Map[String, Any]("allUDTs" -> allUDTs))
+ }
+ }
+
+ def formatAllFunctions(statement: String, meta: Metadata): String = {
+ val ksMetas: List[KeyspaceMetadata] = meta.getKeyspaces.asScala.toList
+ .filter(_.getFunctions.size > 0)
+ .sortBy(ks => ks.getName)
+
+ if(ksMetas.isEmpty) {
+ NoResultDisplay.formatNoResult
+ } else {
+ val allFunctions: Map[(UUID, String), List[FunctionSummary]] = ListMap.empty ++
+ ksMetas
+ .map(ks => {
+ ((UUIDs.timeBased(), ks.getName),
+ ks.getFunctions.asScala.toList
+ .map(MetaDataConverter.functionMetaToFunctionSummary(_))
+ .sortBy(_.name))
+ })
+ .sortBy { case ((id, name), _) => name }
+
+ val keyspaceDetails: List[(UUID, String, String)] = allFunctions
+ .keySet.toList.sortBy { case (id, ksName) => ksName }
+ .map { case (id, ksName) => (id, ksName, "") }
+
+
+ val clusterContent: ClusterContent = ClusterContent(meta.getClusterName, "", keyspaceDetails)
+
+ MenuDisplay.formatMenuForCluster(statement, clusterContent) +
+ engine.layout(ALL_FUNCTIONS_TEMPLATE,
+ Map[String, Any]("allFunctions" -> allFunctions))
+ }
+ }
+
+ def formatAllAggregates(statement: String, meta: Metadata): String = {
+ val ksMetas: List[KeyspaceMetadata] = meta.getKeyspaces.asScala.toList
+ .filter(_.getAggregates.size > 0)
+ .sortBy(ks => ks.getName)
+
+ if(ksMetas.isEmpty) {
+ NoResultDisplay.formatNoResult
+ } else {
+ val allAggregates: Map[(UUID, String), List[AggregateSummary]] = ListMap.empty ++
+ ksMetas
+ .map(ks => {
+ ((UUIDs.timeBased(), ks.getName),
+ ks.getAggregates.asScala.toList
+ .map(MetaDataConverter.aggregateMetaToAggregateSummary(_))
+ .sortBy(_.name))
+ })
+ .sortBy { case ((id, name), _) => name }
+
+ val keyspaceDetails: List[(UUID, String, String)] = allAggregates
+ .keySet.toList.sortBy { case (id, ksName) => ksName }
+ .map { case (id, ksName) => (id, ksName, "") }
+
+
+ val clusterContent: ClusterContent = ClusterContent(meta.getClusterName, "", keyspaceDetails)
+
+ MenuDisplay.formatMenuForCluster(statement, clusterContent) +
+ engine.layout(ALL_AGGREGATES_TEMPLATE,
+ Map[String, Any]("allAggregates" -> allAggregates))
+ }
+ }
+
+ def formatAllMaterializedViews(statement: String, meta: Metadata): String = {
+ val ksMetas: List[KeyspaceMetadata] = meta.getKeyspaces.asScala.toList
+ .filter(_.getMaterializedViews.size > 0)
+ .sortBy(ks => ks.getName)
+
+ if(ksMetas.isEmpty) {
+ NoResultDisplay.formatNoResult
+ } else {
+ val allMVs: Map[(UUID, String), List[MaterializedViewSummary]] = ListMap.empty ++
+ ksMetas
+ .map(ks => {
+ ((UUIDs.timeBased(), ks.getName),
+ ks.getMaterializedViews.asScala.toList
+ .map(MetaDataConverter.mvMetaToMaterializedViewSummary(_))
+ .sortBy(_.name))
+ })
+ .sortBy { case ((id, name), _) => name }
+
+ val keyspaceDetails: List[(UUID, String, String)] = allMVs
+ .keySet.toList.sortBy { case (id, ksName) => ksName }
+ .map { case (id, ksName) => (id, ksName, "") }
+
+
+ val clusterContent: ClusterContent = ClusterContent(meta.getClusterName, "", keyspaceDetails)
+
+ MenuDisplay.formatMenuForCluster(statement, clusterContent) +
+ engine.layout(ALL_MATERIALIZED_VIEWS_TEMPLATE,
+ Map[String, Any]("allMVs" -> allMVs))
+ }
}
}
@@ -233,63 +423,150 @@ class ColumnMetaWrapper(val columnMeta: ColumnMetadata) {
*/
object MetaDataConverter {
- def tableMetaToColumnDetails(meta: TableMetadata): List[ColumnDetails] = {
- val partitionKeys: List[ColumnMetaWrapper] = meta.getPartitionKey.asScala.toList.map(new ColumnMetaWrapper(_))
- val clusteringColumns: List[ColumnMetaWrapper] = meta.getClusteringColumns.asScala.toList.map(new ColumnMetaWrapper(_))
- val columns: List[ColumnMetaWrapper] = meta.getColumns.asScala.toList.map(new ColumnMetaWrapper(_))
- .diff(partitionKeys).diff(clusteringColumns)
- val clusteringOrders = meta.getClusteringOrder.asScala.toList
-
- convertPartitionKeys(partitionKeys):::
- extractStaticColumns(columns):::
- convertClusteringColumns(clusteringColumns, clusteringOrders):::
- extractNormalColumns(columns)
- }
-
- def userTypeToColumnDetails(userType: UserType): List[ColumnDetails] = {
- userType.getFieldNames.asScala.toList
- .map(name => new ColumnDetails(name, NormalColumn, userType.getFieldType(name), None))
+ type DriverClusteringOrder = com.datastax.driver.core.ClusteringOrder
+
+ def functionMetaToFunctionDetails(function: FunctionMetadata): FunctionDetails = {
+ new FunctionDetails(function.getKeyspace.getName,
+ function.getSimpleName,
+ function.getArguments.asScala
+ .toMap
+ .map{case(paramName, dataType) => paramName + " " + dataType.asFunctionParameterString()}
+ .toList,
+ function.isCalledOnNullInput,
+ function.getReturnType.asFunctionParameterString(),
+ function.getLanguage,
+ function.getBody,
+ function.exportAsString())
}
- private def extractNormalColumns(columns: List[ColumnMetaWrapper]): List[ColumnDetails] = {
- columns
- .filter(_.columnMeta.isStatic == false)
- .map(c => new ColumnDetails(c.columnMeta.getName, NormalColumn, c.columnMeta.getType, extractIndexDetail(c)))
+ def functionMetaToFunctionSummary(function: FunctionMetadata): FunctionSummary = {
+ new FunctionSummary(function.getKeyspace.getName,
+ function.getSimpleName,
+ function.getArguments.asScala.toMap
+ .mapValues(dataType => dataType.asFunctionParameterString())
+ .values.toList,
+ function.getReturnType.asFunctionParameterString()
+ )
}
- private def extractIndexDetail(column: ColumnMetaWrapper): Option[IndexDetails] = {
- val indexOption = Option(column.columnMeta.getIndex)
+ def aggregateMetaToAggregateDetails(codecRegistry: CodecRegistry, aggregate: AggregateMetadata): AggregateDetails = {
+ val sFunc: FunctionSummary = functionMetaToFunctionSummary(aggregate.getStateFunc)
+ val finalFunc: Option[String] = Option(aggregate.getFinalFunc).map(func => {
+ val finalFunction = functionMetaToFunctionSummary(func)
+ finalFunction.name + finalFunction.arguments.mkString("(", ", ", ")")
+ })
+ val sType = aggregate.getStateType
+ val initCond: Option[String] = Option(aggregate.getInitCond).map(codecRegistry.codecFor(sType).format(_))
+ val returnType: String = Option(aggregate.getFinalFunc) match {
+ case Some(finalFunc) => functionMetaToFunctionSummary(finalFunc).returnType
+ case None => sFunc.returnType
+ }
+
+ new AggregateDetails(aggregate.getKeyspace.getName,
+ aggregate.getSimpleName,
+ aggregate.getArgumentTypes.asScala.toList.map(_.asFunctionParameterString()),
+ sFunc.name + sFunc.arguments.mkString("(",", ", ")"),
+ sType.asFunctionParameterString(),
+ finalFunc,
+ initCond,
+ returnType,
+ aggregate.exportAsString())
+ }
- def buildIndexInfo(indexMeta: IndexMetadata): String = {
- if(indexMeta.isKeys) "KEYS"
- if(indexMeta.isEntries) "ENTRIES"
- if(indexMeta.isFull) "FULL"
- if(indexMeta.isCustomIndex) s"Class = ${indexMeta.getIndexClassName}"
- else ""
+ def aggregateMetaToAggregateSummary(aggregate: AggregateMetadata): AggregateSummary = {
+ val returnType: String = Option(aggregate.getFinalFunc) match {
+ case Some(finalFunc) => functionMetaToFunctionSummary(finalFunc).returnType
+ case None => aggregate.getStateType.asFunctionParameterString()
}
- indexOption.map(index => IndexDetails(index.getName, buildIndexInfo(index)))
+ new AggregateSummary(aggregate.getKeyspace.getName,
+ aggregate.getSimpleName,
+ aggregate.getArgumentTypes.asScala.toList.map(_.asFunctionParameterString()),
+ returnType
+ )
+ }
+
+ def mvMetaToMaterializedViewDetails(mv: MaterializedViewMetadata): MaterializedViewDetails = {
+ new MaterializedViewDetails(mv.getName, MV.mvMetaToColumnDetails(mv), mv.exportAsString(), mv.getBaseTable.getName)
+ }
+
+ def mvMetaToMaterializedViewSummary(mv: MaterializedViewMetadata): MaterializedViewSummary = {
+ new MaterializedViewSummary(mv.getName, mv.getBaseTable.getName)
}
- private def extractStaticColumns(columns: List[ColumnMetaWrapper]): List[ColumnDetails] = {
- columns
- .filter(_.columnMeta.isStatic == true)
- .map(c => new ColumnDetails(c.columnMeta.getName, StaticColumn, c.columnMeta.getType, extractIndexDetail(c)))
+ trait TableOrView {
+ protected def extractNormalColumns(columns: List[ColumnMetaWrapper]): List[ColumnDetails] = {
+ columns
+ .filter(_.columnMeta.isStatic == false)
+ .map(c => new ColumnDetails(c.columnMeta.getName, NormalColumn, c.columnMeta.getType))
+ }
+
+ protected def extractStaticColumns(columns: List[ColumnMetaWrapper]): List[ColumnDetails] = {
+ columns
+ .filter(_.columnMeta.isStatic == true)
+ .map(c => new ColumnDetails(c.columnMeta.getName, StaticColumn, c.columnMeta.getType))
+ }
+
+ protected def convertClusteringColumns(columns: List[ColumnMetaWrapper], orders: List[DriverClusteringOrder]): List[ColumnDetails] = {
+ columns
+ .zip(orders)
+ .map{case(c,order) => new ColumnDetails(c.columnMeta.getName,
+ new ClusteringColumn(OrderConverter.convert(order)),c.columnMeta.getType)}
+
+ }
+
+ protected def convertPartitionKeys(columns: List[ColumnMetaWrapper]): List[ColumnDetails] = {
+ columns
+ .map(c => new ColumnDetails(c.columnMeta.getName, PartitionKey, c.columnMeta.getType))
+ }
}
- private def convertClusteringColumns(columns: List[ColumnMetaWrapper], orders: List[TableMetadata.Order]): List[ColumnDetails] = {
- columns
- .zip(orders)
- .map{case(c,order) => new ColumnDetails(c.columnMeta.getName,
- new ClusteringColumn(OrderConverter.convert(order)),
- c.columnMeta.getType, extractIndexDetail(c))}
+ object Table extends TableOrView {
+ def tableMetaToColumnDetails(meta: TableMetadata): List[ColumnDetails] = {
+ val partitionKeys: List[ColumnMetaWrapper] = meta.getPartitionKey.asScala.toList.map(new ColumnMetaWrapper(_))
+ val clusteringColumns: List[ColumnMetaWrapper] = meta.getClusteringColumns.asScala.toList.map(new ColumnMetaWrapper(_))
+ val columns: List[ColumnMetaWrapper] = meta.getColumns.asScala.toList.map(new ColumnMetaWrapper(_))
+ .diff(partitionKeys).diff(clusteringColumns)
+ val clusteringOrders = meta.getClusteringOrder.asScala.toList
+
+ convertPartitionKeys(partitionKeys):::
+ extractStaticColumns(columns):::
+ convertClusteringColumns(clusteringColumns, clusteringOrders):::
+ extractNormalColumns(columns)
+ }
+
+ def tableMetaToIndexDetails(meta: TableMetadata): List[IndexDetails] = {
+ meta.getIndexes.asScala.toList
+ .map(index => IndexDetails(index.getName, index.getTarget, index.asCQLQuery()))
+ .sortBy(index => index.name)
+ }
+
}
- private def convertPartitionKeys(columns: List[ColumnMetaWrapper]): List[ColumnDetails] = {
- columns
- .map(c => new ColumnDetails(c.columnMeta.getName, PartitionKey, c.columnMeta.getType, extractIndexDetail(c)))
+ object MV extends TableOrView {
+ def mvMetaToColumnDetails(meta: MaterializedViewMetadata): List[ColumnDetails] = {
+ val partitionKeys: List[ColumnMetaWrapper] = meta.getPartitionKey.asScala.toList.map(new ColumnMetaWrapper(_))
+ val clusteringColumns: List[ColumnMetaWrapper] = meta.getClusteringColumns.asScala.toList.map(new ColumnMetaWrapper(_))
+ val columns: List[ColumnMetaWrapper] = meta.getColumns.asScala.toList.map(new ColumnMetaWrapper(_))
+ .diff(partitionKeys).diff(clusteringColumns)
+ val clusteringOrders = meta.getClusteringOrder.asScala.toList
+
+ convertPartitionKeys(partitionKeys):::
+ convertClusteringColumns(clusteringColumns, clusteringOrders):::
+ extractNormalColumns(columns)
+ }
}
+
+ object UDT {
+ def userTypeToColumnDetails(userType: UserType): List[ColumnDetails] = {
+ userType.getFieldNames.asScala.toList
+ .map(name => new ColumnDetails(name, NormalColumn, userType.getFieldType(name)))
+ }
+ }
+
+
+
}
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/scala/org/apache/zeppelin/cassandra/EnhancedSession.scala
----------------------------------------------------------------------
diff --git a/cassandra/src/main/scala/org/apache/zeppelin/cassandra/EnhancedSession.scala b/cassandra/src/main/scala/org/apache/zeppelin/cassandra/EnhancedSession.scala
index c636de9..a0c475a 100644
--- a/cassandra/src/main/scala/org/apache/zeppelin/cassandra/EnhancedSession.scala
+++ b/cassandra/src/main/scala/org/apache/zeppelin/cassandra/EnhancedSession.scala
@@ -20,6 +20,7 @@ import com.datastax.driver.core._
import org.apache.zeppelin.cassandra.TextBlockHierarchy._
import org.apache.zeppelin.interpreter.InterpreterException
+import scala.collection.JavaConverters._
/**
* Enhance the Java driver session
@@ -32,6 +33,9 @@ class EnhancedSession(val session: Session) {
val keyspaceDisplay = DisplaySystem.KeyspaceDisplay
val tableDisplay = DisplaySystem.TableDisplay
val udtDisplay = DisplaySystem.UDTDisplay
+ val functionDisplay = DisplaySystem.FunctionDisplay
+ val aggregateDisplay = DisplaySystem.AggregateDisplay
+ val materializedViewDisplay = DisplaySystem.MaterializedViewDisplay
val helpDisplay = DisplaySystem.HelpDisplay
private val noResultDisplay = DisplaySystem.NoResultDisplay
@@ -61,8 +65,12 @@ class EnhancedSession(val session: Session) {
private def execute(describeKeyspace: DescribeKeyspaceCmd): String = {
val keyspace: String = describeKeyspace.keyspace
- val metadata: KeyspaceMetadata = session.getCluster.getMetadata.getKeyspace(keyspace)
- HTML_MAGIC + keyspaceDisplay.formatKeyspaceContent(describeKeyspace.statement, metadata)
+ val metadata: Option[KeyspaceMetadata] = Option(session.getCluster.getMetadata.getKeyspace(keyspace))
+ metadata match {
+ case Some(ksMeta) => HTML_MAGIC + keyspaceDisplay.formatKeyspaceContent(describeKeyspace.statement, ksMeta,
+ session.getCluster.getConfiguration.getCodecRegistry)
+ case None => throw new InterpreterException(s"Cannot find keyspace $keyspace")
+ }
}
private def execute(describeTable: DescribeTableCmd): String = {
@@ -76,7 +84,7 @@ class EnhancedSession(val session: Session) {
}
}
- private def execute(describeUDT: DescribeUDTCmd): String = {
+ private def execute(describeUDT: DescribeTypeCmd): String = {
val metaData = session.getCluster.getMetadata
val keyspace: String = describeUDT.keyspace.orElse(Option(session.getLoggedKeyspace)).getOrElse("system")
val udtName: String = describeUDT.udtName
@@ -87,6 +95,87 @@ class EnhancedSession(val session: Session) {
}
}
+ private def execute(describeUDTs: DescribeTypesCmd): String = {
+ val metadata: Metadata = session.getCluster.getMetadata
+ HTML_MAGIC + clusterDisplay.formatAllUDTs(describeUDTs.statement, metadata)
+ }
+
+ private def execute(describeFunction: DescribeFunctionCmd): String = {
+ val metaData = session.getCluster.getMetadata
+ val keyspaceName: String = describeFunction.keyspace.orElse(Option(session.getLoggedKeyspace)).getOrElse("system")
+ val functionName: String = describeFunction.function;
+
+ Option(metaData.getKeyspace(keyspaceName)) match {
+ case Some(keyspace) => {
+ val functionMetas: List[FunctionMetadata] = keyspace.getFunctions.asScala.toList
+ .filter(func => func.getSimpleName.toLowerCase == functionName.toLowerCase)
+
+ if(functionMetas.isEmpty) {
+ throw new InterpreterException(s"Cannot find function ${keyspaceName}.$functionName")
+ } else {
+ HTML_MAGIC + functionDisplay.format(describeFunction.statement, functionMetas, true)
+ }
+ }
+ case None => throw new InterpreterException(s"Cannot find function ${keyspaceName}.$functionName")
+ }
+ }
+
+ private def execute(describeFunctions: DescribeFunctionsCmd): String = {
+ val metadata: Metadata = session.getCluster.getMetadata
+ HTML_MAGIC + clusterDisplay.formatAllFunctions(describeFunctions.statement, metadata)
+ }
+
+ private def execute(describeAggregate: DescribeAggregateCmd): String = {
+ val metaData = session.getCluster.getMetadata
+ val keyspaceName: String = describeAggregate.keyspace.orElse(Option(session.getLoggedKeyspace)).getOrElse("system")
+ val aggregateName: String = describeAggregate.aggregate;
+
+ Option(metaData.getKeyspace(keyspaceName)) match {
+ case Some(keyspace) => {
+ val aggMetas: List[AggregateMetadata] = keyspace.getAggregates.asScala.toList
+ .filter(agg => agg.getSimpleName.toLowerCase == aggregateName.toLowerCase)
+
+ if(aggMetas.isEmpty) {
+ throw new InterpreterException(s"Cannot find aggregate ${keyspaceName}.$aggregateName")
+ } else {
+ HTML_MAGIC + aggregateDisplay.format(describeAggregate.statement, aggMetas, true,
+ session
+ .getCluster
+ .getConfiguration
+ .getCodecRegistry)
+ }
+ }
+ case None => throw new InterpreterException(s"Cannot find aggregate ${keyspaceName}.$aggregateName")
+ }
+ }
+
+ private def execute(describeAggregates: DescribeAggregatesCmd): String = {
+ val metadata: Metadata = session.getCluster.getMetadata
+ HTML_MAGIC + clusterDisplay.formatAllAggregates(describeAggregates.statement, metadata)
+ }
+
+ private def execute(describeMV: DescribeMaterializedViewCmd): String = {
+ val metaData = session.getCluster.getMetadata
+ val keyspaceName: String = describeMV.keyspace.orElse(Option(session.getLoggedKeyspace)).getOrElse("system")
+ val viewName: String = describeMV.view
+
+ Option(metaData.getKeyspace(keyspaceName)) match {
+ case Some(keyspace) => {
+ val viewMeta: Option[MaterializedViewMetadata] = Option(keyspace.getMaterializedView(viewName))
+ viewMeta match {
+ case Some(vMeta) => HTML_MAGIC + materializedViewDisplay.format(describeMV.statement, vMeta, true)
+ case None => throw new InterpreterException(s"Cannot find materialized view ${keyspaceName}.$viewName")
+ }
+ }
+ case None => throw new InterpreterException(s"Cannot find materialized view ${keyspaceName}.$viewName")
+ }
+ }
+
+ private def execute(describeMVs: DescribeMaterializedViewsCmd): String = {
+ val metadata: Metadata = session.getCluster.getMetadata
+ HTML_MAGIC + clusterDisplay.formatAllMaterializedViews(describeMVs.statement, metadata)
+ }
+
private def execute(helpCmd: HelpCmd): String = {
HTML_MAGIC + helpDisplay.formatHelp()
}
@@ -95,11 +184,18 @@ class EnhancedSession(val session: Session) {
def execute(st: Any): Any = {
st match {
case x:DescribeClusterCmd => execute(x)
- case x:DescribeKeyspacesCmd => execute(x)
- case x:DescribeTablesCmd => execute(x)
case x:DescribeKeyspaceCmd => execute(x)
+ case x:DescribeKeyspacesCmd => execute(x)
case x:DescribeTableCmd => execute(x)
- case x:DescribeUDTCmd => execute(x)
+ case x:DescribeTablesCmd => execute(x)
+ case x:DescribeTypeCmd => execute(x)
+ case x:DescribeTypesCmd => execute(x)
+ case x:DescribeFunctionCmd => execute(x)
+ case x:DescribeFunctionsCmd => execute(x)
+ case x:DescribeAggregateCmd => execute(x)
+ case x:DescribeAggregatesCmd => execute(x)
+ case x:DescribeMaterializedViewCmd => execute(x)
+ case x:DescribeMaterializedViewsCmd => execute(x)
case x:HelpCmd => execute(x)
case x:Statement => session.execute(x)
case _ => throw new InterpreterException(s"Cannot execute statement '$st' of type ${st.getClass}")
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/scala/org/apache/zeppelin/cassandra/InterpreterLogic.scala
----------------------------------------------------------------------
diff --git a/cassandra/src/main/scala/org/apache/zeppelin/cassandra/InterpreterLogic.scala b/cassandra/src/main/scala/org/apache/zeppelin/cassandra/InterpreterLogic.scala
index 809bce7..707c16a8 100644
--- a/cassandra/src/main/scala/org/apache/zeppelin/cassandra/InterpreterLogic.scala
+++ b/cassandra/src/main/scala/org/apache/zeppelin/cassandra/InterpreterLogic.scala
@@ -100,7 +100,7 @@ class InterpreterLogic(val session: Session) {
logger.info(s"Executing CQL statements : \n\n$stringStatements\n")
try {
- val protocolVersion = session.getCluster.getConfiguration.getProtocolOptions.getProtocolVersionEnum
+ val protocolVersion = session.getCluster.getConfiguration.getProtocolOptions.getProtocolVersion
val queries:List[AnyBlock] = parseInput(stringStatements)
@@ -137,12 +137,12 @@ class InterpreterLogic(val session: Session) {
case x:BatchStm => {
val builtStatements: List[Statement] = x.statements.map {
case st:SimpleStm => generateSimpleStatement(st, queryOptions, context)
- case st:BoundStm => generateBoundStatement(st, queryOptions, context)
+ case st:BoundStm => generateBoundStatement(session, st, queryOptions, context)
case _ => throw new InterpreterException(s"Unknown statement type")
}
generateBatchStatement(x.batchType, queryOptions, builtStatements)
}
- case x:BoundStm => generateBoundStatement(x, queryOptions, context)
+ case x:BoundStm => generateBoundStatement(session, x, queryOptions, context)
case x:DescribeCommandStatement => x
case x:HelpCmd => x
case x => throw new InterpreterException(s"Unknown statement type : ${x}")
@@ -208,7 +208,7 @@ class InterpreterLogic(val session: Session) {
row => {
val data = columnsDefinitions.map {
case (name, dataType) => {
- if (row.isNull(name)) null else dataType.deserialize(row.getBytesUnsafe(name), protocolVersion)
+ if (row.isNull(name)) null else row.getObject(name)
}
}
output.append(data.mkString("\t")).append("\n")
@@ -283,12 +283,12 @@ class InterpreterLogic(val session: Session) {
statement
}
- def generateBoundStatement(st: BoundStm, options: CassandraQueryOptions,context: InterpreterContext): BoundStatement = {
+ def generateBoundStatement(session: Session, st: BoundStm, options: CassandraQueryOptions,context: InterpreterContext): BoundStatement = {
logger.debug(s"Generating bound statement with name : '${st.name}' and bound values : ${st.values}")
preparedStatements.get(st.name) match {
case Some(ps) => {
val boundValues = maybeExtractVariables(st.values, context)
- createBoundStatement(st.name, ps, boundValues)
+ createBoundStatement(session.getCluster.getConfiguration.getCodecRegistry, st.name, ps, boundValues)
}
case None => throw new InterpreterException(s"The statement '${st.name}' can not be bound to values. " +
s"Are you sure you did prepare it with @prepare[${st.name}] ?")
@@ -342,7 +342,7 @@ class InterpreterLogic(val session: Session) {
options.fetchSize.foreach(statement.setFetchSize(_))
}
- private def createBoundStatement(name: String, ps: PreparedStatement, rawBoundValues: String): BoundStatement = {
+ private def createBoundStatement(codecRegistry: CodecRegistry, name: String, ps: PreparedStatement, rawBoundValues: String): BoundStatement = {
val dataTypes = ps.getVariables.toList
.map(cfDef => cfDef.getType)
@@ -357,6 +357,7 @@ class InterpreterLogic(val session: Session) {
if(value.trim == "null") {
null
} else {
+ val codec: TypeCodec[AnyRef] = codecRegistry.codecFor[AnyRef](dataType)
dataType.getName match {
case (ASCII | TEXT | VARCHAR) => value.trim.replaceAll("(?<!')'","")
case (INT | VARINT) => value.trim.toInt
@@ -369,11 +370,11 @@ class InterpreterLogic(val session: Session) {
case INET => InetAddress.getByName(value.trim)
case TIMESTAMP => parseDate(value.trim)
case (UUID | TIMEUUID) => java.util.UUID.fromString(value.trim)
- case LIST => dataType.parse(boundValuesParser.parse(boundValuesParser.list, value).get)
- case SET => dataType.parse(boundValuesParser.parse(boundValuesParser.set, value).get)
- case MAP => dataType.parse(boundValuesParser.parse(boundValuesParser.map, value).get)
- case UDT => dataType.parse(boundValuesParser.parse(boundValuesParser.udt, value).get)
- case TUPLE => dataType.parse(boundValuesParser.parse(boundValuesParser.tuple, value).get)
+ case LIST => codec.parse(boundValuesParser.parse(boundValuesParser.list, value).get)
+ case SET => codec.parse(boundValuesParser.parse(boundValuesParser.set, value).get)
+ case MAP => codec.parse(boundValuesParser.parse(boundValuesParser.map, value).get)
+ case UDT => codec.parse(boundValuesParser.parse(boundValuesParser.udt, value).get)
+ case TUPLE => codec.parse(boundValuesParser.parse(boundValuesParser.tuple, value).get)
case _ => throw new InterpreterException(s"Cannot parse data of type : ${dataType.toString}")
}
}
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/scala/org/apache/zeppelin/cassandra/MetaDataHierarchy.scala
----------------------------------------------------------------------
diff --git a/cassandra/src/main/scala/org/apache/zeppelin/cassandra/MetaDataHierarchy.scala b/cassandra/src/main/scala/org/apache/zeppelin/cassandra/MetaDataHierarchy.scala
index 66a0776..4b88776 100644
--- a/cassandra/src/main/scala/org/apache/zeppelin/cassandra/MetaDataHierarchy.scala
+++ b/cassandra/src/main/scala/org/apache/zeppelin/cassandra/MetaDataHierarchy.scala
@@ -28,10 +28,10 @@ import scala.util.parsing.json.JSONObject
*/
object MetaDataHierarchy {
object OrderConverter {
- def convert(clusteringOrder: TableMetadata.Order): ClusteringOrder = {
+ def convert(clusteringOrder: com.datastax.driver.core.ClusteringOrder): ClusteringOrder = {
clusteringOrder match {
- case TableMetadata.Order.ASC => ASC
- case TableMetadata.Order.DESC => DESC
+ case com.datastax.driver.core.ClusteringOrder.ASC => ASC
+ case com.datastax.driver.core.ClusteringOrder.DESC => DESC
}
}
}
@@ -46,9 +46,8 @@ object MetaDataHierarchy {
case class ClusteringColumn(order: ClusteringOrder) extends ColumnType
object StaticColumn extends ColumnType
object NormalColumn extends ColumnType
- case class IndexDetails(name: String, info: String)
- case class ColumnDetails(name: String, columnType: ColumnType, dataType: DataType, index: Option[IndexDetails])
-
+ case class IndexDetails(name: String, target: String, asCQL: String)
+ case class ColumnDetails(name: String, columnType: ColumnType, dataType: DataType)
case class ClusterDetails(name: String, partitioner: String)
case class ClusterContent(clusterName: String, clusterDetails: String, keyspaces: List[(UUID, String, String)])
@@ -58,10 +57,26 @@ object MetaDataHierarchy {
JSONObject(replication).toString().replaceAll(""""""","'")
}
}
- case class KeyspaceContent(keyspaceName: String, keyspaceDetails: String, tables: List[(UUID,String, String)], udts: List[(UUID, String, String)])
- case class TableDetails(tableName: String, columns: List[ColumnDetails], asCQL: String, uniqueId: UUID = UUIDs.timeBased())
+ case class KeyspaceContent(keyspaceName: String, keyspaceDetails: String,
+ tables: List[(UUID,String, String)],
+ views: List[(UUID,String, String)],
+ udts: List[(UUID, String, String)],
+ functions: List[(UUID, String, String)],
+ aggregates: List[(UUID, String, String)])
+ case class TableDetails(tableName: String, columns: List[ColumnDetails], indices: List[IndexDetails], asCQL: String, indicesAsCQL: String, uniqueId: UUID = UUIDs.timeBased())
case class UDTDetails(typeName: String, columns: List[ColumnDetails], asCQL: String, uniqueId: UUID = UUIDs.timeBased())
+ case class SameNameFunctionDetails(functions: List[FunctionDetails])
+ case class FunctionDetails(keyspace:String, name: String, arguments: List[String], calledOnNullInput: Boolean, returnType: String,
+ language:String, body: String, asCQL: String, uniqueId: UUID = UUIDs.timeBased())
+ case class FunctionSummary(keyspace:String, name: String, arguments: List[String], returnType: String)
+ case class AggregateDetails(keyspace:String, name: String, arguments: List[String], sFunc: String, sType: String,
+ finalFunc: Option[String], initCond: Option[String], returnType: String,
+ asCQL: String, uniqueId: UUID = UUIDs.timeBased())
+ case class AggregateSummary(keyspace:String, name: String, arguments: List[String], returnType: String)
+ case class SameNameAggregateDetails(aggregates: List[AggregateDetails])
+ case class MaterializedViewDetails(name: String, columns: List[ColumnDetails], asCQL: String, baseTable: String, uniqueId: UUID = UUIDs.timeBased())
+ case class MaterializedViewSummary(name: String, baseTable: String)
}
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/scala/org/apache/zeppelin/cassandra/ParagraphParser.scala
----------------------------------------------------------------------
diff --git a/cassandra/src/main/scala/org/apache/zeppelin/cassandra/ParagraphParser.scala b/cassandra/src/main/scala/org/apache/zeppelin/cassandra/ParagraphParser.scala
index 0cd98ad..e2cb64d 100644
--- a/cassandra/src/main/scala/org/apache/zeppelin/cassandra/ParagraphParser.scala
+++ b/cassandra/src/main/scala/org/apache/zeppelin/cassandra/ParagraphParser.scala
@@ -19,10 +19,20 @@ package org.apache.zeppelin.cassandra
import com.datastax.driver.core._
import org.apache.zeppelin.cassandra.CassandraInterpreter._
import org.apache.zeppelin.interpreter.InterpreterException
+import scala.util.matching.Regex
import scala.util.parsing.combinator._
import org.apache.zeppelin.cassandra.TextBlockHierarchy._
+/**
+ * Parser using Scala combinator parsing
+ *
+ * (?i) means case-insensitive mode
+ * (?s) means DOT ALL mode
+ * (?is) means case-insensitive and DOT ALL mode
+ *
+ */
object ParagraphParser {
+
val CONSISTENCY_LEVEL_PATTERN = ConsistencyLevel.values().toList
.map(_.name()).filter(!_.contains("SERIAL")).mkString("""^\s*@consistency\s*=\s*(""", "|" , """)\s*$""").r
@@ -42,22 +52,43 @@ object ParagraphParser {
val BIND_PATTERN = """^\s*@bind\[([^]]+)\](?:=([^;]+))?""".r
val BATCH_PATTERN = """^(?i)\s*BEGIN\s+(UNLOGGED|COUNTER)?\s*BATCH""".r
+ /**
+ * Very complicated RegExp
+ * (?: OR REPLACE)? -> optional presence of OR REPLACE
+ * .+? -> match ANY character in RELUCTANT mode
+ * (?:\s*|\n|\r|\f) -> white space OR line returns (\n, \r, \f)
+ * (?:\s*|\n|\r|\f)AS(?:\s*|\n|\r|\f) -> AS preceded and followed by white space or line return
+ * (?:'|\$\$) -> simple quote (') OR double dollar ($$) as source code separator
+ * (?:'|\$\$).+?(?:'|\$\$)\s*; ->
+ * source code separator (?:'|\$\$)
+ * followed by ANY character in RELUCTANT mode (.+?)
+ * followed by source code separator (?:'|\$\$)
+ * followed by optional white-space(s) (\s*)
+ * followed by semi-colon (;)
+ */
+ val UDF_PATTERN = """(?is)\s*(CREATE(?:\s+OR REPLACE)?\s+FUNCTION(?:\s+IF\s+NOT\s+EXISTS)?.+?(?:\s+|\n|\r|\f)AS(?:\s+|\n|\r|\f)(?:'|\$\$).+?(?:'|\$\$)\s*;)""".r
+
val GENERIC_STATEMENT_PREFIX =
"""(?is)\s*(?:INSERT|UPDATE|DELETE|SELECT|CREATE|UPDATE|
|DROP|GRANT|REVOKE|TRUNCATE|LIST|USE)\s+""".r
val VALID_IDENTIFIER = "[a-z][a-z0-9_]*"
- val DESCRIBE_CLUSTER_PATTERN = """^(?i)\s*(?:DESCRIBE|DESC)\s+CLUSTER;\s*$""".r
- val DESCRIBE_KEYSPACES_PATTERN = """^(?i)\s*(?:DESCRIBE|DESC)\s+KEYSPACES;\s*$""".r
- val DESCRIBE_TABLES_PATTERN = """^(?i)\s*(?:DESCRIBE|DESC)\s+TABLES;\s*$""".r
+ val DESCRIBE_CLUSTER_PATTERN = """^(?i)\s*(?:DESCRIBE|DESC)\s+CLUSTER\s*;\s*$""".r
+
+
val DESCRIBE_KEYSPACE_PATTERN = ("""^(?i)\s*(?:DESCRIBE|DESC)\s+KEYSPACE\s*("""+VALID_IDENTIFIER+""");\s*$""").r
+ val DESCRIBE_KEYSPACES_PATTERN = """^(?i)\s*(?:DESCRIBE|DESC)\s+KEYSPACES\s*;\s*$""".r
+
+
val DESCRIBE_TABLE_PATTERN = ("""^(?i)\s*(?:DESCRIBE|DESC)\s+TABLE\s*("""+VALID_IDENTIFIER+""");\s*$""").r
val DESCRIBE_TABLE_WITH_KEYSPACE_PATTERN = ("""^(?i)\s*(?:DESCRIBE|DESC)\s+TABLE\s*(""" +
VALID_IDENTIFIER +
""")\.(""" +
VALID_IDENTIFIER +
""");\s*$""").r
+ val DESCRIBE_TABLES_PATTERN = """^(?i)\s*(?:DESCRIBE|DESC)\s+TABLES\s*;\s*$""".r
+
val DESCRIBE_TYPE_PATTERN = ("""^(?i)\s*(?:DESCRIBE|DESC)\s+TYPE\s*("""+VALID_IDENTIFIER+""");\s*$""").r
val DESCRIBE_TYPE_WITH_KEYSPACE_PATTERN = ("""^(?i)\s*(?:DESCRIBE|DESC)\s+TYPE\s*(""" +
@@ -65,6 +96,35 @@ object ParagraphParser {
""")\.(""" +
VALID_IDENTIFIER +
""");\s*$""").r
+ val DESCRIBE_TYPES_PATTERN = """^(?i)\s*(?:DESCRIBE|DESC)\s+TYPES\s*;\s*$""".r
+
+
+ val DESCRIBE_FUNCTION_PATTERN = ("""^(?i)\s*(?:DESCRIBE|DESC)\s+FUNCTION\s*("""+VALID_IDENTIFIER+""");\s*$""").r
+ val DESCRIBE_FUNCTION_WITH_KEYSPACE_PATTERN = ("""^(?i)\s*(?:DESCRIBE|DESC)\s+FUNCTION\s*(""" +
+ VALID_IDENTIFIER +
+ """)\.(""" +
+ VALID_IDENTIFIER +
+ """);\s*$""").r
+ val DESCRIBE_FUNCTIONS_PATTERN = ("""^(?i)\s*(?:DESCRIBE|DESC)\s+FUNCTIONS\s*;\s*$""").r
+
+
+ val DESCRIBE_AGGREGATE_PATTERN = ("""^(?i)\s*(?:DESCRIBE|DESC)\s+AGGREGATE\s*("""+VALID_IDENTIFIER+""");\s*$""").r
+ val DESCRIBE_AGGREGATE_WITH_KEYSPACE_PATTERN = ("""^(?i)\s*(?:DESCRIBE|DESC)\s+AGGREGATE\s*(""" +
+ VALID_IDENTIFIER +
+ """)\.(""" +
+ VALID_IDENTIFIER +
+ """);\s*$""").r
+ val DESCRIBE_AGGREGATES_PATTERN = ("""^(?i)\s*(?:DESCRIBE|DESC)\s+AGGREGATES\s*;\s*$""").r
+
+
+ val DESCRIBE_MATERIALIZED_VIEW_PATTERN = ("""^(?i)\s*(?:DESCRIBE|DESC)\s+MATERIALIZED\s+VIEW\s*("""+VALID_IDENTIFIER+""");\s*$""").r
+ val DESCRIBE_MATERIALIZED_VIEW_WITH_KEYSPACE_PATTERN = ("""^(?i)\s*(?:DESCRIBE|DESC)\s+MATERIALIZED\s+VIEW\s*(""" +
+ VALID_IDENTIFIER +
+ """)\.(""" +
+ VALID_IDENTIFIER +
+ """);\s*$""").r
+ val DESCRIBE_MATERIALIZED_VIEWS_PATTERN = ("""^(?i)\s*(?:DESCRIBE|DESC)\s+MATERIALIZED\s+VIEWS\s*;\s*$""").r
+
val HELP_PATTERN = """^(?i)\s*HELP;\s*$""".r
}
@@ -74,7 +134,10 @@ class ParagraphParser extends RegexParsers{
import ParagraphParser._
- def singleLineComment: Parser[Comment] = """\s*#.*""".r ^^ {case text => Comment(text.trim.replaceAll("#",""))}
+ def singleLineCommentHash: Parser[Comment] = """\s*#.*""".r ^^ {case text => Comment(text.trim.replaceAll("#",""))}
+ def singleLineCommentDoubleSlashes: Parser[Comment] = """\s*//.*""".r ^^ {case text => Comment(text.trim.replaceAll("//",""))}
+ def singleLineComment: Parser[Comment] = singleLineCommentHash | singleLineCommentDoubleSlashes
+
def multiLineComment: Parser[Comment] = """(?s)/\*(.*)\*/""".r ^^ {case text => Comment(text.trim.replaceAll("""/\*""","").replaceAll("""\*/""",""))}
//Query parameters
@@ -85,7 +148,10 @@ class ParagraphParser extends RegexParsers{
def fetchSize: Parser[FetchSize] = """\s*@fetchSize.+""".r ^^ {case x => extractFetchSize(x.trim)}
//Statements
+ def createFunctionStatement: Parser[SimpleStm] = UDF_PATTERN ^^{case x => extractUdfStatement(x.trim)}
def genericStatement: Parser[SimpleStm] = s"""$GENERIC_STATEMENT_PREFIX[^;]+;""".r ^^ {case x => extractSimpleStatement(x.trim)}
+// def allStatement: Parser[SimpleStm] = udfStatement | genericStatement
+
def prepare: Parser[PrepareStm] = """\s*@prepare.+""".r ^^ {case x => extractPreparedStatement(x.trim)}
def removePrepare: Parser[RemovePrepareStm] = """\s*@remove_prepare.+""".r ^^ {case x => extractRemovePreparedStatement(x.trim)}
def bind: Parser[BoundStm] = """\s*@bind.+""".r ^^ {case x => extractBoundStatement(x.trim)}
@@ -95,9 +161,17 @@ class ParagraphParser extends RegexParsers{
private def describeCluster: Parser[DescribeClusterCmd] = """(?i)\s*(?:DESCRIBE|DESC)\s+CLUSTER.*""".r ^^ {extractDescribeClusterCmd(_)}
private def describeKeyspaces: Parser[DescribeKeyspacesCmd] = """(?i)\s*(?:DESCRIBE|DESC)\s+KEYSPACES.*""".r ^^ {extractDescribeKeyspacesCmd(_)}
private def describeTables: Parser[DescribeTablesCmd] = """(?i)\s*(?:DESCRIBE|DESC)\s+TABLES.*""".r ^^ {extractDescribeTablesCmd(_)}
+ private def describeTypes: Parser[DescribeTypesCmd] = """(?i)\s*(?:DESCRIBE|DESC)\s+TYPES.*""".r ^^ {extractDescribeTypesCmd(_)}
+ private def describeFunctions: Parser[DescribeFunctionsCmd] = """(?i)\s*(?:DESCRIBE|DESC)\s+FUNCTIONS.*""".r ^^ {extractDescribeFunctionsCmd(_)}
+ private def describeAggregates: Parser[DescribeAggregatesCmd] = """(?i)\s*(?:DESCRIBE|DESC)\s+AGGREGATES.*""".r ^^ {extractDescribeAggregatesCmd(_)}
+ private def describeMaterializedViews: Parser[DescribeMaterializedViewsCmd] = """(?i)\s*(?:DESCRIBE|DESC)\s+MATERIALIZED\s+VIEWS.*""".r ^^ {extractDescribeMaterializedViewsCmd(_)}
private def describeKeyspace: Parser[DescribeKeyspaceCmd] = """\s*(?i)(?:DESCRIBE|DESC)\s+KEYSPACE\s+.+""".r ^^ {extractDescribeKeyspaceCmd(_)}
private def describeTable: Parser[DescribeTableCmd] = """(?i)\s*(?:DESCRIBE|DESC)\s+TABLE\s+.+""".r ^^ {extractDescribeTableCmd(_)}
- private def describeType: Parser[DescribeUDTCmd] = """(?i)\s*(?:DESCRIBE|DESC)\s+TYPE\s+.*""".r ^^ {extractDescribeTypeCmd(_)}
+ private def describeType: Parser[DescribeTypeCmd] = """(?i)\s*(?:DESCRIBE|DESC)\s+TYPE\s+.*""".r ^^ {extractDescribeTypeCmd(_)}
+ private def describeFunction: Parser[DescribeFunctionCmd] = """(?i)\s*(?:DESCRIBE|DESC)\s+FUNCTION\s+.*""".r ^^ {extractDescribeFunctionCmd(_)}
+ private def describeAggregate: Parser[DescribeAggregateCmd] = """(?i)\s*(?:DESCRIBE|DESC)\s+AGGREGATE\s+.*""".r ^^ {extractDescribeAggregateCmd(_)}
+ private def describeMaterializedView: Parser[DescribeMaterializedViewCmd] = """(?i)\s*(?:DESCRIBE|DESC)\s+MATERIALIZED\s+VIEW\s+.*""".r ^^ {extractDescribeMaterializedViewCmd(_)}
+
//Help
private def helpCommand: Parser[HelpCmd] = """(?i)\s*HELP.*""".r ^^{extractHelpCmd(_)}
@@ -114,8 +188,14 @@ class ParagraphParser extends RegexParsers{
case begin ~ cqls ~ end => BatchStm(extractBatchType(begin),cqls)}
def queries:Parser[List[AnyBlock]] = rep(singleLineComment | multiLineComment | consistency | serialConsistency |
- timestamp | retryPolicy | fetchSize | removePrepare | prepare | bind | batch | describeCluster | describeKeyspaces |
- describeTables | describeKeyspace | describeTable | describeType | helpCommand | genericStatement)
+ timestamp | retryPolicy | fetchSize | removePrepare | prepare | bind | batch | describeCluster |
+ describeKeyspace | describeKeyspaces |
+ describeTable | describeTables |
+ describeType | describeTypes |
+ describeFunction | describeFunctions |
+ describeAggregate | describeAggregates |
+ describeMaterializedView | describeMaterializedViews |
+ helpCommand | createFunctionStatement | genericStatement)
def extractConsistency(text: String): Consistency = {
text match {
@@ -171,6 +251,13 @@ class ParagraphParser extends RegexParsers{
}
}
+ def extractUdfStatement(text: String): SimpleStm = {
+ text match {
+ case UDF_PATTERN(statement) => SimpleStm(statement)
+ case _ => throw new InterpreterException(s"Invalid statement '$text' for UDF creation. Did you forget to add ; (semi-colon) at the end of each CQL statement ?")
+ }
+ }
+
def extractPreparedStatement(text: String): PrepareStm = {
text match {
case PREPARE_STATEMENT_PATTERN(name,queryString) => PrepareStm(name.trim,queryString.trim)
@@ -214,6 +301,14 @@ class ParagraphParser extends RegexParsers{
}
}
+ def extractDescribeKeyspaceCmd(text: String): DescribeKeyspaceCmd = {
+ text match {
+ case DESCRIBE_KEYSPACE_PATTERN(keyspace) => new DescribeKeyspaceCmd(keyspace)
+ case _ => throw new InterpreterException(s"Invalid syntax for DESCRIBE KEYSPACE. " +
+ s"""It should comply to the pattern: ${DESCRIBE_KEYSPACE_PATTERN.toString}""")
+ }
+ }
+
def extractDescribeKeyspacesCmd(text: String): DescribeKeyspacesCmd = {
text match {
case DESCRIBE_KEYSPACES_PATTERN() => new DescribeKeyspacesCmd
@@ -222,6 +317,15 @@ class ParagraphParser extends RegexParsers{
}
}
+ def extractDescribeTableCmd(text: String): DescribeTableCmd = {
+ text match {
+ case DESCRIBE_TABLE_WITH_KEYSPACE_PATTERN(keyspace,table) => new DescribeTableCmd(Option(keyspace),table)
+ case DESCRIBE_TABLE_PATTERN(table) => new DescribeTableCmd(Option.empty,table)
+ case _ => throw new InterpreterException(s"Invalid syntax for DESCRIBE TABLE. " +
+ s"""It should comply to the patterns: ${DESCRIBE_TABLE_WITH_KEYSPACE_PATTERN.toString} or ${DESCRIBE_TABLE_PATTERN.toString}""".stripMargin)
+ }
+ }
+
def extractDescribeTablesCmd(text: String): DescribeTablesCmd = {
text match {
case DESCRIBE_TABLES_PATTERN() => new DescribeTablesCmd
@@ -230,29 +334,71 @@ class ParagraphParser extends RegexParsers{
}
}
- def extractDescribeKeyspaceCmd(text: String): DescribeKeyspaceCmd = {
+ def extractDescribeTypeCmd(text: String): DescribeTypeCmd = {
text match {
- case DESCRIBE_KEYSPACE_PATTERN(keyspace) => new DescribeKeyspaceCmd(keyspace)
- case _ => throw new InterpreterException(s"Invalid syntax for DESCRIBE KEYSPACE. " +
- s"""It should comply to the pattern: ${DESCRIBE_KEYSPACE_PATTERN.toString}""")
+ case DESCRIBE_TYPE_WITH_KEYSPACE_PATTERN(keyspace,table) => new DescribeTypeCmd(Option(keyspace),table)
+ case DESCRIBE_TYPE_PATTERN(table) => new DescribeTypeCmd(Option.empty,table)
+ case _ => throw new InterpreterException(s"Invalid syntax for DESCRIBE TYPE. " +
+ s"""It should comply to the patterns: ${DESCRIBE_TYPE_WITH_KEYSPACE_PATTERN.toString} or ${DESCRIBE_TYPE_PATTERN.toString}""".stripMargin)
}
}
- def extractDescribeTableCmd(text: String): DescribeTableCmd = {
+ def extractDescribeTypesCmd(text: String): DescribeTypesCmd = {
text match {
- case DESCRIBE_TABLE_WITH_KEYSPACE_PATTERN(keyspace,table) => new DescribeTableCmd(Option(keyspace),table)
- case DESCRIBE_TABLE_PATTERN(table) => new DescribeTableCmd(Option.empty,table)
- case _ => throw new InterpreterException(s"Invalid syntax for DESCRIBE TABLE. " +
- s"""It should comply to the patterns: ${DESCRIBE_TABLE_WITH_KEYSPACE_PATTERN.toString} or ${DESCRIBE_TABLE_PATTERN.toString}""".stripMargin)
+ case DESCRIBE_TYPES_PATTERN() => new DescribeTypesCmd
+ case _ => throw new InterpreterException(s"Invalid syntax for DESCRIBE TYPES. " +
+ s"""It should comply to the pattern: ${DESCRIBE_TYPES_PATTERN.toString}""")
}
}
- def extractDescribeTypeCmd(text: String): DescribeUDTCmd = {
+ def extractDescribeFunctionCmd(text: String): DescribeFunctionCmd = {
text match {
- case DESCRIBE_TYPE_WITH_KEYSPACE_PATTERN(keyspace,table) => new DescribeUDTCmd(Option(keyspace),table)
- case DESCRIBE_TYPE_PATTERN(table) => new DescribeUDTCmd(Option.empty,table)
- case _ => throw new InterpreterException(s"Invalid syntax for DESCRIBE TYPE. " +
- s"""It should comply to the patterns: ${DESCRIBE_TYPE_WITH_KEYSPACE_PATTERN.toString} or ${DESCRIBE_TYPE_PATTERN.toString}""".stripMargin)
+ case DESCRIBE_FUNCTION_WITH_KEYSPACE_PATTERN(keyspace,function) => new DescribeFunctionCmd(Option(keyspace),function)
+ case DESCRIBE_FUNCTION_PATTERN(function) => new DescribeFunctionCmd(Option.empty,function)
+ case _ => throw new InterpreterException(s"Invalid syntax for DESCRIBE FUNCTION. " +
+ s"""It should comply to the patterns: ${DESCRIBE_FUNCTION_WITH_KEYSPACE_PATTERN.toString} or ${DESCRIBE_FUNCTION_PATTERN.toString}""".stripMargin)
+ }
+ }
+
+ def extractDescribeFunctionsCmd(text: String): DescribeFunctionsCmd = {
+ text match {
+ case DESCRIBE_FUNCTIONS_PATTERN() => new DescribeFunctionsCmd
+ case _ => throw new InterpreterException(s"Invalid syntax for DESCRIBE FUNCTIONS. " +
+ s"""It should comply to the pattern: ${DESCRIBE_FUNCTIONS_PATTERN.toString}""".stripMargin)
+ }
+ }
+
+ def extractDescribeAggregateCmd(text: String): DescribeAggregateCmd = {
+ text match {
+ case DESCRIBE_AGGREGATE_WITH_KEYSPACE_PATTERN(keyspace,aggregate) => new DescribeAggregateCmd(Option(keyspace),aggregate)
+ case DESCRIBE_AGGREGATE_PATTERN(aggregate) => new DescribeAggregateCmd(Option.empty,aggregate)
+ case _ => throw new InterpreterException(s"Invalid syntax for DESCRIBE AGGREGATE. " +
+ s"""It should comply to the patterns: ${DESCRIBE_AGGREGATE_WITH_KEYSPACE_PATTERN.toString} or ${DESCRIBE_AGGREGATE_PATTERN.toString}""".stripMargin)
+ }
+ }
+
+ def extractDescribeAggregatesCmd(text: String): DescribeAggregatesCmd = {
+ text match {
+ case DESCRIBE_AGGREGATES_PATTERN() => new DescribeAggregatesCmd
+ case _ => throw new InterpreterException(s"Invalid syntax for DESCRIBE AGGREGATES. " +
+ s"""It should comply to the pattern: ${DESCRIBE_AGGREGATES_PATTERN.toString}""".stripMargin)
+ }
+ }
+
+ def extractDescribeMaterializedViewCmd(text: String): DescribeMaterializedViewCmd = {
+ text match {
+ case DESCRIBE_MATERIALIZED_VIEW_WITH_KEYSPACE_PATTERN(keyspace,view) => new DescribeMaterializedViewCmd(Option(keyspace),view)
+ case DESCRIBE_MATERIALIZED_VIEW_PATTERN(view) => new DescribeMaterializedViewCmd(Option.empty,view)
+ case _ => throw new InterpreterException(s"Invalid syntax for DESCRIBE MATERIALIZED VIEW. " +
+ s"""It should comply to the patterns: ${DESCRIBE_MATERIALIZED_VIEW_WITH_KEYSPACE_PATTERN.toString} or ${DESCRIBE_MATERIALIZED_VIEW_PATTERN.toString}""".stripMargin)
+ }
+ }
+
+ def extractDescribeMaterializedViewsCmd(text: String): DescribeMaterializedViewsCmd = {
+ text match {
+ case DESCRIBE_MATERIALIZED_VIEWS_PATTERN() => new DescribeMaterializedViewsCmd
+ case _ => throw new InterpreterException(s"Invalid syntax for DESCRIBE MATERIALIZED VIEWS. " +
+ s"""It should comply to the pattern: ${DESCRIBE_MATERIALIZED_VIEWS_PATTERN.toString}""".stripMargin)
}
}
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/main/scala/org/apache/zeppelin/cassandra/TextBlockHierarchy.scala
----------------------------------------------------------------------
diff --git a/cassandra/src/main/scala/org/apache/zeppelin/cassandra/TextBlockHierarchy.scala b/cassandra/src/main/scala/org/apache/zeppelin/cassandra/TextBlockHierarchy.scala
index 70b2ce2..61a2d8d 100644
--- a/cassandra/src/main/scala/org/apache/zeppelin/cassandra/TextBlockHierarchy.scala
+++ b/cassandra/src/main/scala/org/apache/zeppelin/cassandra/TextBlockHierarchy.scala
@@ -77,10 +77,16 @@ object TextBlockHierarchy {
object BatchStatementType extends StatementType
object DescribeClusterStatementType extends StatementType
object DescribeAllKeyspacesStatementType extends StatementType
- object DescribeKeyspaceStatementType extends StatementType
object DescribeAllTablesStatementType extends StatementType
+ object DescribeAllTypesStatementType extends StatementType
+ object DescribeAllFunctionsStatementType extends StatementType
+ object DescribeAllAggregatesStatementType extends StatementType
+ object DescribeKeyspaceStatementType extends StatementType
object DescribeTableStatementType extends StatementType
object DescribeTypeStatementType extends StatementType
+ object DescribeFunctionStatementType extends StatementType
+ object DescribeAggregateStatementType extends StatementType
+ object DescribeMaterializedView extends StatementType
object HelpStatementType extends StatementType
abstract class QueryStatement(val statementType: StatementType) extends AnyBlock(StatementBlock) {
@@ -104,15 +110,27 @@ object TextBlockHierarchy {
val statement: String
}
- class DescribeClusterCmd(override val statement: String = "DESCRIBE CLUSTER;")
+ case class DescribeClusterCmd(override val statement: String = "DESCRIBE CLUSTER;")
extends QueryStatement(DescribeClusterStatementType) with DescribeCommandStatement
- class DescribeKeyspacesCmd(override val statement: String = "DESCRIBE KEYSPACES;")
+ case class DescribeKeyspacesCmd(override val statement: String = "DESCRIBE KEYSPACES;")
extends QueryStatement(DescribeAllKeyspacesStatementType) with DescribeCommandStatement
- class DescribeTablesCmd(override val statement: String = "DESCRIBE TABLES;")
+ case class DescribeTablesCmd(override val statement: String = "DESCRIBE TABLES;")
extends QueryStatement(DescribeAllTablesStatementType) with DescribeCommandStatement
+ case class DescribeTypesCmd(override val statement: String = "DESCRIBE TYPES;")
+ extends QueryStatement(DescribeAllTypesStatementType) with DescribeCommandStatement
+
+ case class DescribeFunctionsCmd(override val statement: String = "DESCRIBE FUNCTIONS;") extends QueryStatement(DescribeAllFunctionsStatementType)
+ with DescribeCommandStatement
+
+ case class DescribeAggregatesCmd(override val statement: String = "DESCRIBE AGGREGATES;") extends QueryStatement(DescribeAllAggregatesStatementType)
+ with DescribeCommandStatement
+
+ case class DescribeMaterializedViewsCmd(override val statement: String = "DESCRIBE MATERIALIZED VIEWS;") extends QueryStatement(DescribeAllAggregatesStatementType)
+ with DescribeCommandStatement
+
case class DescribeKeyspaceCmd(keyspace: String) extends QueryStatement(DescribeKeyspaceStatementType)
with DescribeCommandStatement {
override val statement: String = s"DESCRIBE KEYSPACE $keyspace;"
@@ -126,7 +144,7 @@ object TextBlockHierarchy {
}
}
- case class DescribeUDTCmd(keyspace:Option[String],udtName: String) extends QueryStatement(DescribeTypeStatementType)
+ case class DescribeTypeCmd(keyspace:Option[String], udtName: String) extends QueryStatement(DescribeTypeStatementType)
with DescribeCommandStatement {
override val statement: String = keyspace match {
case Some(ks) => s"DESCRIBE TYPE $ks.$udtName;"
@@ -134,6 +152,30 @@ object TextBlockHierarchy {
}
}
- class HelpCmd extends QueryStatement(HelpStatementType)
+ case class DescribeFunctionCmd(keyspace:Option[String], function: String) extends QueryStatement(DescribeFunctionStatementType)
+ with DescribeCommandStatement {
+ override val statement: String = keyspace match {
+ case Some(ks) => s"DESCRIBE FUNCTION $ks.$function;"
+ case None => s"DESCRIBE FUNCTION $function;"
+ }
+ }
+
+ case class DescribeAggregateCmd(keyspace:Option[String], aggregate: String) extends QueryStatement(DescribeAggregateStatementType)
+ with DescribeCommandStatement {
+ override val statement: String = keyspace match {
+ case Some(ks) => s"DESCRIBE AGGREGATE $ks.$aggregate;"
+ case None => s"DESCRIBE AGGREGATE $aggregate;"
+ }
+ }
+
+ case class DescribeMaterializedViewCmd(keyspace:Option[String], view: String) extends QueryStatement(DescribeMaterializedView)
+ with DescribeCommandStatement {
+ override val statement: String = keyspace match {
+ case Some(ks) => s"DESCRIBE MATERIALIZED VIEW $ks.$view;"
+ case None => s"DESCRIBE MATERIALIZED VIEW $view;"
+ }
+ }
+
+ case class HelpCmd(val statement:String = "HELP;") extends QueryStatement(HelpStatementType)
}
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/test/java/org/apache/zeppelin/cassandra/CassandraInterpreterTest.java
----------------------------------------------------------------------
diff --git a/cassandra/src/test/java/org/apache/zeppelin/cassandra/CassandraInterpreterTest.java b/cassandra/src/test/java/org/apache/zeppelin/cassandra/CassandraInterpreterTest.java
index afca9de..560c57e 100644
--- a/cassandra/src/test/java/org/apache/zeppelin/cassandra/CassandraInterpreterTest.java
+++ b/cassandra/src/test/java/org/apache/zeppelin/cassandra/CassandraInterpreterTest.java
@@ -30,22 +30,20 @@ import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.when;
import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.ProtocolVersion;
import com.datastax.driver.core.Session;
-import info.archinnov.achilles.junit.AchillesResource;
-import info.archinnov.achilles.junit.AchillesResourceBuilder;
+
+import info.archinnov.achilles.embedded.CassandraEmbeddedServerBuilder;
+
+import org.apache.zeppelin.interpreter.Interpreter;
import org.apache.zeppelin.interpreter.InterpreterContext;
import org.apache.zeppelin.interpreter.InterpreterResult;
import org.apache.zeppelin.interpreter.InterpreterResult.Code;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
+import org.junit.*;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
-import scala.io.Source;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
@@ -58,16 +56,14 @@ public class CassandraInterpreterTest {
private static final String ARTISTS_TABLE = "zeppelin.artists";
- @ClassRule
- public static AchillesResource resource = AchillesResourceBuilder
+ public static Session session = CassandraEmbeddedServerBuilder
.noEntityPackages()
.withKeyspaceName("zeppelin")
.withScript("prepare_schema.cql")
.withScript("prepare_data.cql")
- .build();
-
- private static Session session = resource.getNativeSession();
-
+ .withProtocolVersion(ProtocolVersion.V3)
+ .buildNativeSessionOnly();
+// public static Session session = null;
private static CassandraInterpreter interpreter;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
@@ -76,7 +72,8 @@ public class CassandraInterpreterTest {
@BeforeClass
public static void setUp() {
Properties properties = new Properties();
- final Cluster cluster = resource.getNativeSession().getCluster();
+ final Cluster cluster = session.getCluster();
+// final Cluster cluster = null;
properties.setProperty(CASSANDRA_CLUSTER_NAME, cluster.getClusterName());
properties.setProperty(CASSANDRA_COMPRESSION_PROTOCOL, "NONE");
properties.setProperty(CASSANDRA_CREDENTIALS_USERNAME, "none");
@@ -131,7 +128,7 @@ public class CassandraInterpreterTest {
@Test
public void should_create_cluster_and_session_upon_call_to_open() throws Exception {
assertThat(interpreter.cluster).isNotNull();
- assertThat(interpreter.cluster.getClusterName()).isEqualTo(resource.getNativeSession().getCluster().getClusterName());
+ assertThat(interpreter.cluster.getClusterName()).isEqualTo(session.getCluster().getClusterName());
assertThat(interpreter.session).isNotNull();
assertThat(interpreter.helper).isNotNull();
}
@@ -241,7 +238,7 @@ public class CassandraInterpreterTest {
//Then
assertThat(actual.code()).isEqualTo(Code.ERROR);
assertThat(actual.message())
- .contains("Not enough replica available for query at consistency THREE (3 required but only 1 alive)");
+ .contains("Not enough replicas available for query at consistency THREE (3 required but only 1 alive)");
}
@Test
@@ -329,14 +326,14 @@ public class CassandraInterpreterTest {
assertThat(actual.message()).isEqualTo(
"login\taddresses\tage\tdeceased\tfirstname\tlast_update\tlastname\tlocation\n" +
"jdoe\t" +
- "{street_number:3, street_name:'Beverly Hills Bld', zip_code:90209," +
- " country:'USA', extra_info:['Right on the hills', 'Next to the post box'], " +
- "phone_numbers:{'office':2015790847, 'home':2016778524}}\tnull\t" +
+ "{street_number:3,street_name:'Beverly Hills Bld',zip_code:90209," +
+ "country:'USA',extra_info:['Right on the hills','Next to the post box']," +
+ "phone_numbers:{'office':2015790847,'home':2016778524}}\tnull\t" +
"null\t" +
"John\t" +
"null\t" +
"DOE\t" +
- "('USA', 90209, 'Beverly Hills')\n");
+ "('USA',90209,'Beverly Hills')\n");
}
@Test
@@ -554,6 +551,76 @@ public class CassandraInterpreterTest {
}
@Test
+ @Ignore
+ //TODO activate test when using Java 8 and C* 3.x
+ public void should_describe_function() throws Exception {
+ //Given
+ Properties properties = new Properties();
+ properties.setProperty(CASSANDRA_HOSTS, "127.0.0.1");
+ properties.setProperty(CASSANDRA_PORT, "9042");
+ Interpreter interpreter = new CassandraInterpreter(properties);
+ interpreter.open();
+
+ String createFunction = "CREATE FUNCTION zeppelin.maxof(val1 int,val2 int) " +
+ "RETURNS NULL ON NULL INPUT " +
+ "RETURNS int " +
+ "LANGUAGE java " +
+ "AS $$" +
+ " return Math.max(val1, val2);\n" +
+ "$$;";
+ interpreter.interpret(createFunction, intrContext);
+ String query = "DESCRIBE FUNCTION zeppelin.maxOf;";
+
+ //When
+ final InterpreterResult actual = interpreter.interpret(query, intrContext);
+
+ //Then
+ assertThat(actual.code()).isEqualTo(Code.SUCCESS);
+ assertThat(actual.message()).isEqualTo("xxxxx");
+ }
+
+ @Test
+ @Ignore
+ //TODO activate test when using Java 8 and C* 3.x
+ public void should_describe_aggregate() throws Exception {
+ //Given
+ Properties properties = new Properties();
+ properties.setProperty(CASSANDRA_HOSTS, "127.0.0.1");
+ properties.setProperty(CASSANDRA_PORT, "9042");
+ Interpreter interpreter = new CassandraInterpreter(properties);
+ interpreter.open();
+
+ final String query = "DESCRIBE AGGREGATES;";
+
+ //When
+ final InterpreterResult actual = interpreter.interpret(query, intrContext);
+
+ //Then
+ assertThat(actual.code()).isEqualTo(Code.SUCCESS);
+
+ }
+
+ @Test
+ @Ignore
+ //TODO activate test when using Java 8 and C* 3.x
+ public void should_describe_materialized_view() throws Exception {
+ //Given
+ Properties properties = new Properties();
+ properties.setProperty(CASSANDRA_HOSTS, "127.0.0.1");
+ properties.setProperty(CASSANDRA_PORT, "9042");
+ Interpreter interpreter = new CassandraInterpreter(properties);
+ interpreter.open();
+
+ final String query = "DESCRIBE MATERIALIZED VIEWS;";
+
+ //When
+ final InterpreterResult actual = interpreter.interpret(query, intrContext);
+
+ //Then
+ assertThat(actual.code()).isEqualTo(Code.SUCCESS);
+ }
+
+ @Test
public void should_describe_table() throws Exception {
//Given
String query = "DESCRIBE TABLE live_data.complex_table;";
@@ -601,6 +668,7 @@ public class CassandraInterpreterTest {
assertThat(reformatHtml(actual.message())).isEqualTo(expected);
}
+
@Test
public void should_error_describing_non_existing_table() throws Exception {
//Given
@@ -647,8 +715,8 @@ public class CassandraInterpreterTest {
return rawHtml
.replaceAll("\\s*\n\\s*","")
.replaceAll(">\\s+<", "><")
- .replaceAll("(?s)data-target=\"#[a-f0-9-]+(?:_asCQL)?\"", "")
- .replaceAll("(?s)id=\"[a-f0-9-]+(?:_asCQL)?\"", "")
+ .replaceAll("(?s)data-target=\"#[a-f0-9-]+(?:_asCQL|_indices_asCQL)?\"", "")
+ .replaceAll("(?s)id=\"[a-f0-9-]+(?:_asCQL|_indices_asCQL)?\"", "")
.trim();
}
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/test/java/org/apache/zeppelin/cassandra/InterpreterLogicTest.java
----------------------------------------------------------------------
diff --git a/cassandra/src/test/java/org/apache/zeppelin/cassandra/InterpreterLogicTest.java b/cassandra/src/test/java/org/apache/zeppelin/cassandra/InterpreterLogicTest.java
index f7993fb..bf685f1 100644
--- a/cassandra/src/test/java/org/apache/zeppelin/cassandra/InterpreterLogicTest.java
+++ b/cassandra/src/test/java/org/apache/zeppelin/cassandra/InterpreterLogicTest.java
@@ -302,10 +302,10 @@ public class InterpreterLogicTest {
}
private <A> scala.collection.immutable.List<A> toScalaList(java.util.List<A> list) {
- return scala.collection.JavaConverters.asScalaBufferConverter(list).asScala().toList();
+ return scala.collection.JavaConversions.asScalaIterable(list).toList();
}
private <A> java.util.List<A> toJavaList(scala.collection.immutable.List<A> list){
- return scala.collection.JavaConverters.seqAsJavaListConverter(list).asJava();
+ return scala.collection.JavaConversions.asJavaList(list);
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/11a45e2e/cassandra/src/test/resources/scalate/DescribeCluster.html
----------------------------------------------------------------------
diff --git a/cassandra/src/test/resources/scalate/DescribeCluster.html b/cassandra/src/test/resources/scalate/DescribeCluster.html
index 5d32c7d..3a5c001 100644
--- a/cassandra/src/test/resources/scalate/DescribeCluster.html
+++ b/cassandra/src/test/resources/scalate/DescribeCluster.html
@@ -1,98 +1 @@
-<br/>
-<br/>
-<nav class="navbar navbar-default">
- <ul class="nav navbar-nav">
-
- <li>
- <a><strong>DESCRIBE CLUSTER;</strong></a>
- </li>
- </ul>
- <ul class="nav navbar-nav navbar-right">
- <li class="dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
- <strong>Legend</strong>
- <span class="caret"></span>
- </a>
- <ul class="dropdown-menu">
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-dashboard text-muted" /> Cluster
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-folder-open text-danger" /> Keyspace
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-copyright-mark text-warning" /> UDT
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-th-list text-primary" /> Table
- </a>
- </li>
- <li class="bg-info">
- <a role="button">
- <i class="glyphicon glyphicon-fullscreen" /> Partition Key
- </a>
- </li>
- <li class="bg-warning">
- <a role="button">
- <i class="glyphicon glyphicon-pushpin" /> Static Column
- </a>
- </li>
- <li class="bg-success">
- <a role="button">
- <i class="glyphicon glyphicon-sort" /> Clustering Column
- </a>
- </li>
- <li class="bg-success">
- <a role="button">
- <i class="glyphicon glyphicon-sort-by-attributes" /> Clustering Order ASC
- </a>
- </li>
- <li class="bg-success">
- <a role="button">
- <i class="glyphicon glyphicon-sort-by-attributes-alt" /> Clustering Order DESC
- </a>
- </li>
- <li>
- <a role="button">
- <i class="glyphicon glyphicon-info-sign" /> Indexed Column
- </a>
- </li>
- </ul>
- </li>
- <li>
- <a href="#"></a>
- </li>
- </ul>
-</nav>
-<hr/>
-<div class="row">
- <div class="col-md-4"></div>
- <div class="col-md-4 col-offset-md-4">
- <div class="table-responsive table-bordered">
- <table class="table">
- <caption>
- <h4 class="text-muted">
- <i class="glyphicon glyphicon-dashboard"/> Test Cluster
- </h4>
- </caption>
- <thead>
- <tr>
- <th>Partitioner</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>org.apache.cassandra.dht.Murmur3Partitioner</td>
- </tr>
- <tbody>
- </table>
- </div>
- </div>
-</div>
\ No newline at end of file
+<br/><br/><nav class="navbar navbar-default"><ul class="nav navbar-nav"><li><a><strong>DESCRIBE CLUSTER;</strong></a></li></ul><ul class="nav navbar-nav navbar-right"><li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><strong>Legend</strong><span class="caret"></span></a><ul class="dropdown-menu"><li><a role="button"><i class="glyphicon glyphicon-dashboard text-muted" /> Cluster</a></li><li><a role="button"><i class="glyphicon glyphicon-folder-open text-danger" /> Keyspace</a></li><li><a role="button"><i class="glyphicon glyphicon-copyright-mark text-warning" /> UDT</a></li><li><a role="button"><i class="glyphicon glyphicon-th-list text-primary" /> Table</a></li><li><a role="button"><i class="glyphicon glyphicon-eye-open text-primary" /> Materialized View</a></li><li><a role="button"><i class="glyphicon glyphicon-random text-success" /> Function</a
></li><li><a role="button"><i class="glyphicon glyphicon-retweet text-success" /> Aggregate</a></li><li role="separator" class="divider text-muted"></li><li class="dropdown-header"><span class="text-primary">Table icons</span></li><li class="bg-info"><a role="button"><i class="glyphicon glyphicon-fullscreen" /> Partition Key</a></li><li class="bg-warning"><a role="button"><i class="glyphicon glyphicon-pushpin" /> Static Column</a></li><li class="bg-success"><a role="button"><i class="glyphicon glyphicon-sort" /> Clustering Column</a></li><li class="bg-success"><a role="button"><i class="glyphicon glyphicon-sort-by-attributes" /> Clustering Order ASC</a></li><li class="bg-success"><a role="button"><i class="glyphicon glyphicon-sort-by-attributes-alt" /> Clustering Order DESC</a></li></ul></li><li><a href="#"></a></li></ul></nav><hr/><div class="row"><div class="col-md-4"></div><div class="col-md-4 col-offset-md-4"><div
class="table-responsive table-bordered"><table class="table"><caption><h4 class="text-muted"><i class="glyphicon glyphicon-dashboard"/> Test Cluster</h4></caption><thead><tr><th>Partitioner</th></tr></thead><tbody><tr><td>org.apache.cassandra.dht.Murmur3Partitioner</td></tr><tbody></table></div></div></div>
\ No newline at end of file