Skip to content

Commit

Permalink
Merge pull request #15 from tolbertam/drop-cql-requirement
Browse files Browse the repository at this point in the history
Drop cql requirement
  • Loading branch information
tolbertam committed Dec 17, 2015
2 parents 39cd10a + ce28dbf commit 41e9b47
Show file tree
Hide file tree
Showing 7 changed files with 347 additions and 81 deletions.
40 changes: 35 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@ should be much more pleasant to follow.
```
java -jar sstable-tools.jar toJson
usage: toJson <sstable> -c <arg> [-e] [-k <arg>] [-x <arg>]
usage: toJson <sstable> [-c <arg>] [-e] [-k <arg>] [-x <arg>]
Converts SSTable into a JSON formatted document.
-c <arg> file containing "CREATE TABLE..." for the sstable's schema
-e Enumerate keys only
-k <arg> Partition key to be included
-x <arg> Partition key to be excluded
-c <arg> Optional file containing "CREATE TABLE..." for the sstable's schema. Used to determine the partition and
clustering key names. Must not include "keyspace." in create statement. If not included will not print key names.
-e Only print out the keys for the sstable. If enabled other options are ignored.
-k <arg> Partition key to be included. May be used multiple times. If not set will default to all keys.
-x <arg> Partition key to be excluded. May be used multiple times.
```

### Examples
Expand Down Expand Up @@ -123,6 +125,34 @@ series of rows with columns:
]
```

An example demonstrating what output will look like if you do not provide a CQL
schema via `-c`. Partition and Clustering key column names are simply omitted
and only their values are provided:


```json
[
{
"partition" : {
"key" : [ "ZLC", "2003" ]
},
"rows" : [
{
"type" : "row",
"clustering" : [ "12", "31" ],
"cells" : [
{ "name" : "close", "value" : "53.2", "tstamp" : 1449469421557041 },
{ "name" : "high", "value" : "53.48", "tstamp" : 1449469421557041 },
{ "name" : "low", "value" : "52.56", "tstamp" : 1449469421557041 },
{ "name" : "open", "value" : "53.35", "tstamp" : 1449469421557041 },
{ "name" : "volume", "value" : "93600", "tstamp" : 1449469421557041 }
]
}
]
}
]
```


An example showing an SSTable with tombstones at all levels:

Expand Down
141 changes: 141 additions & 0 deletions src/integration/python/sstable2json_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@
);
"""

COMPOSITE_TABLE = """
CREATE TABLE composites (
key1 varchar,
key2 varchar,
ckey1 varchar,
ckey2 varchar,
value bigint,
PRIMARY KEY((key1, key2), ckey1, ckey2)
);
"""

class TestKeysOnly(IntegrationTest):
def __init__(self, methodName='runTest'):
Expand All @@ -38,3 +48,134 @@ def test_single_key(self):
print output
self.assertEqual(json.loads(output), [[{"name": "user_name", "value": "frodo"}]])

def get_partition(name, result):
for p in result:
if p['partition']['key'] == name:
return p
elif isinstance(p['partition']['key'], type({})):
for key in p['partition']['key']:
if key['name'] == name:
return p
return None

class ToJson(IntegrationTest):
def __init__(self, methodName='runTest'):
TestCase.__init__(self, methodName)
self.name = 'ToJson'

def test_composite(self):
self.cluster.populate(1).start()
[node1] = self.cluster.nodelist()
session = self.cql_connection(node1, "test")
session.execute(COMPOSITE_TABLE)
session.execute("INSERT INTO composites (key1, key2, ckey1, ckey2, value) VALUES('a', 'b', 'c', 'd', 1);")
session.execute("INSERT INTO composites (key1, key2, ckey1, ckey2, value) VALUES('e', 'f', 'g', 'h', 2);")

node1.flush()
node1.compact()
sstable = node1.get_sstables("test", "composites")[0]

output = sh(["java", "-jar", self.uberjar_location, "toJson", sstable])
print output
result = json.loads(output)
self.assertEqual(2, len(result))
self.assertEqual(["a","b"], get_partition(["a","b"], result)['partition']['key'])
self.assertEqual(["e","f"], get_partition(["e","f"], result)['partition']['key'])
self.assertEqual(1, len(get_partition(["a","b"], result)['rows']))
self.assertEqual(['c', 'd'], get_partition(["a","b"], result)['rows'][0]['clustering'])
self.assertEqual(['g', 'h'], get_partition(["e","f"], result)['rows'][0]['clustering'])


def test_composite_with_schema(self):
self.cluster.populate(1).start()
[node1] = self.cluster.nodelist()
session = self.cql_connection(node1, "test")
session.execute(COMPOSITE_TABLE)
session.execute("INSERT INTO composites (key1, key2, ckey1, ckey2, value) VALUES('a', 'b', 'c', 'd', 1);")
session.execute("INSERT INTO composites (key1, key2, ckey1, ckey2, value) VALUES('e', 'f', 'g', 'h', 2);")

node1.flush()
node1.compact()
sstable = node1.get_sstables("test", "composites")[0]

tempf = NamedTemporaryFile(delete=False)
tempf.write(COMPOSITE_TABLE)
tempf.flush()
output = sh(["java", "-jar", self.uberjar_location, "toJson", sstable, "-c", tempf.name])
print output
result = json.loads(output)
for p in result:
del p['rows'][0]['liveness_info']

self.assertEqual(result,
[
{
"partition" : {
"key" : [
{ "name" : "key1", "value" : "e" },
{ "name" : "key2", "value" : "f" }
]
},
"rows" : [
{
"type" : "row",
"clustering" : [
{ "name" : "ckey1", "value" : "g" },
{ "name" : "ckey2", "value" : "h" }
],
"cells" : [
{ "name" : "value", "value" : "2" }
]
}
]
},
{
"partition" : {
"key" : [
{ "name" : "key1", "value" : "a" },
{ "name" : "key2", "value" : "b" }
]
},
"rows" : [
{
"type" : "row",
"clustering" : [
{ "name" : "ckey1", "value" : "c" },
{ "name" : "ckey2", "value" : "d" }
],
"cells" : [
{ "name" : "value", "value" : "1" },
]
}
]
}
])

def test_simple_single(self):
self.cluster.populate(1).start()
[node1] = self.cluster.nodelist()
session = self.cql_connection(node1, "test")

session.execute(CREATE_USER_TABLE)
session.execute("INSERT INTO users (user_name, password, gender, state, birth_year) VALUES('frodo', 'pass@', 'male', 'CA', 1985);")

node1.flush()
node1.compact()
sstable = node1.get_sstables("test", "users")[0]

tempf = NamedTemporaryFile(delete=False)
tempf.write(CREATE_USER_TABLE)
tempf.flush()
output = sh(["java", "-jar", self.uberjar_location, "toJson", sstable, "-c", tempf.name])
print output
result = json.loads(output)
del result[0]["rows"][0]['liveness_info']
self.assertEqual({'partition': {'key': [{'name': 'user_name', 'value': 'frodo'}]},
'rows': [{
'type': 'row',
'cells': [
{'name': 'birth_year', 'value': '1985'},
{'name': 'gender', 'value': 'male'},
{'name': 'password', 'value': 'pass@'},
{'name': 'state', 'value': 'CA'}]
}]}, result[0])
3 changes: 2 additions & 1 deletion src/integration/python/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
if __name__ == "__main__":
print "Integration test suite for Cassandra %s" % os.environ['CASSANDRA_VERSION']
suite = unittest.TestLoader().loadTestsFromTestCase(TestKeysOnly)
unittest.TextTestRunner(verbosity=2).run(suite)
suite = unittest.TestLoader().loadTestsFromTestCase(ToJson)
unittest.TextTestRunner(verbosity=2).run(suite)
5 changes: 1 addition & 4 deletions src/main/java/com/csforge/sstable/Driver.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
package com.csforge.sstable;

import ch.qos.logback.classic.LoggerContext;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;

public class Driver {
public static void main(String ... args) {
Logger.getRootLogger().setLevel(Level.OFF);
((LoggerContext) LoggerFactory.getILoggerFactory()).stop();
if (args.length == 0) {
printCommands();
Expand All @@ -26,7 +23,7 @@ public static void main(String ... args) {
break;
}
}

private static void printCommands() {
System.err.println("Available commands: toJson");
}
Expand Down
Loading

0 comments on commit 41e9b47

Please sign in to comment.