Repository: cassandra Updated Branches: refs/heads/cassandra-2.2 b77e11cfd -> cb6fad3ef refs/heads/cassandra-3.0 e51c85f2e -> 97fb4d102 refs/heads/cassandra-3.11 b5df3b4c3 -> 48ffad89c refs/heads/trunk 10b397e2a -> 4d6af1752
Fix toJSONString for the UDT, tuple and collection types patch by ZhaoYang; reviewed by Benjamin Lerer for CASSANDRA-13592 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/cb6fad3e Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/cb6fad3e Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/cb6fad3e Branch: refs/heads/cassandra-2.2 Commit: cb6fad3efcd7cd3dc87d02ca7e8e97eb277a66ab Parents: b77e11c Author: ZhaoYang <zhaoyangsingap...@gmail.com> Authored: Fri Jul 7 16:09:15 2017 +0200 Committer: Benjamin Lerer <b.le...@gmail.com> Committed: Fri Jul 7 16:12:27 2017 +0200 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../cassandra/db/marshal/AbstractType.java | 11 +- .../apache/cassandra/db/marshal/EmptyType.java | 6 + .../apache/cassandra/db/marshal/ListType.java | 5 +- .../apache/cassandra/db/marshal/MapType.java | 7 +- .../apache/cassandra/db/marshal/TupleType.java | 3 +- .../org/apache/cassandra/cql3/CQLTester.java | 19 +- .../cql3/validation/entities/JsonTest.java | 167 +++++++++- .../db/marshal/JsonConversionTest.java | 320 +++++++++++++++++++ 9 files changed, 518 insertions(+), 21 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/cb6fad3e/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 08c6e48..6740c9e 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 2.2.11 + * Fix toJSONString for the UDT, tuple and collection types (CASSANDRA-13592) * Fix nested Tuples/UDTs validation (CASSANDRA-13646) * Remove unused max_value_size_in_mb config setting from yaml (CASSANDRA-13625 http://git-wip-us.apache.org/repos/asf/cassandra/blob/cb6fad3e/src/java/org/apache/cassandra/db/marshal/AbstractType.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/marshal/AbstractType.java b/src/java/org/apache/cassandra/db/marshal/AbstractType.java index b90e127..799d636 100644 --- a/src/java/org/apache/cassandra/db/marshal/AbstractType.java +++ b/src/java/org/apache/cassandra/db/marshal/AbstractType.java @@ -101,7 +101,16 @@ public abstract class AbstractType<T> implements Comparator<ByteBuffer> **/ public abstract Term fromJSONObject(Object parsed) throws MarshalException; - /** Converts a value to a JSON string. */ + /** + * Converts the specified value into its JSON representation. + * <p> + * The buffer position will stay the same. + * </p> + * + * @param buffer the value to convert + * @param protocolVersion the protocol version to use for the conversion + * @return a JSON string representing the specified value + */ public String toJSONString(ByteBuffer buffer, int protocolVersion) { return '"' + getSerializer().deserialize(buffer).toString() + '"'; http://git-wip-us.apache.org/repos/asf/cassandra/blob/cb6fad3e/src/java/org/apache/cassandra/db/marshal/EmptyType.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/marshal/EmptyType.java b/src/java/org/apache/cassandra/db/marshal/EmptyType.java index f82d767..e5abe5b 100644 --- a/src/java/org/apache/cassandra/db/marshal/EmptyType.java +++ b/src/java/org/apache/cassandra/db/marshal/EmptyType.java @@ -65,6 +65,12 @@ public class EmptyType extends AbstractType<Void> return new Constants.Value(ByteBufferUtil.EMPTY_BYTE_BUFFER); } + @Override + public String toJSONString(ByteBuffer buffer, int protocolVersion) + { + return "\"\""; + } + public TypeSerializer<Void> getSerializer() { return EmptySerializer.instance; http://git-wip-us.apache.org/repos/asf/cassandra/blob/cb6fad3e/src/java/org/apache/cassandra/db/marshal/ListType.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/marshal/ListType.java b/src/java/org/apache/cassandra/db/marshal/ListType.java index 9334ad0..ed44616 100644 --- a/src/java/org/apache/cassandra/db/marshal/ListType.java +++ b/src/java/org/apache/cassandra/db/marshal/ListType.java @@ -208,13 +208,14 @@ public class ListType<T> extends CollectionType<List<T>> public static String setOrListToJsonString(ByteBuffer buffer, AbstractType elementsType, int protocolVersion) { + ByteBuffer value = buffer.duplicate(); StringBuilder sb = new StringBuilder("["); - int size = CollectionSerializer.readCollectionSize(buffer, protocolVersion); + int size = CollectionSerializer.readCollectionSize(value, protocolVersion); for (int i = 0; i < size; i++) { if (i > 0) sb.append(", "); - sb.append(elementsType.toJSONString(CollectionSerializer.readValue(buffer, protocolVersion), protocolVersion)); + sb.append(elementsType.toJSONString(CollectionSerializer.readValue(value, protocolVersion), protocolVersion)); } return sb.append("]").toString(); } http://git-wip-us.apache.org/repos/asf/cassandra/blob/cb6fad3e/src/java/org/apache/cassandra/db/marshal/MapType.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/marshal/MapType.java b/src/java/org/apache/cassandra/db/marshal/MapType.java index 434702a..c7267cf 100644 --- a/src/java/org/apache/cassandra/db/marshal/MapType.java +++ b/src/java/org/apache/cassandra/db/marshal/MapType.java @@ -232,22 +232,23 @@ public class MapType<K, V> extends CollectionType<Map<K, V>> @Override public String toJSONString(ByteBuffer buffer, int protocolVersion) { + ByteBuffer value = buffer.duplicate(); StringBuilder sb = new StringBuilder("{"); - int size = CollectionSerializer.readCollectionSize(buffer, protocolVersion); + int size = CollectionSerializer.readCollectionSize(value, protocolVersion); for (int i = 0; i < size; i++) { if (i > 0) sb.append(", "); // map keys must be JSON strings, so convert non-string keys to strings - String key = keys.toJSONString(CollectionSerializer.readValue(buffer, protocolVersion), protocolVersion); + String key = keys.toJSONString(CollectionSerializer.readValue(value, protocolVersion), protocolVersion); if (key.startsWith("\"")) sb.append(key); else sb.append('"').append(Json.quoteAsJsonString(key)).append('"'); sb.append(": "); - sb.append(values.toJSONString(CollectionSerializer.readValue(buffer, protocolVersion), protocolVersion)); + sb.append(values.toJSONString(CollectionSerializer.readValue(value, protocolVersion), protocolVersion)); } return sb.append("}").toString(); } http://git-wip-us.apache.org/repos/asf/cassandra/blob/cb6fad3e/src/java/org/apache/cassandra/db/marshal/TupleType.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/marshal/TupleType.java b/src/java/org/apache/cassandra/db/marshal/TupleType.java index bf7eae4..f3600ef 100644 --- a/src/java/org/apache/cassandra/db/marshal/TupleType.java +++ b/src/java/org/apache/cassandra/db/marshal/TupleType.java @@ -261,13 +261,14 @@ public class TupleType extends AbstractType<ByteBuffer> @Override public String toJSONString(ByteBuffer buffer, int protocolVersion) { + ByteBuffer duplicated = buffer.duplicate(); StringBuilder sb = new StringBuilder("["); for (int i = 0; i < types.size(); i++) { if (i > 0) sb.append(", "); - ByteBuffer value = CollectionSerializer.readValue(buffer, protocolVersion); + ByteBuffer value = CollectionSerializer.readValue(duplicated, protocolVersion); if (value == null) sb.append("null"); else http://git-wip-us.apache.org/repos/asf/cassandra/blob/cb6fad3e/test/unit/org/apache/cassandra/cql3/CQLTester.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/cql3/CQLTester.java b/test/unit/org/apache/cassandra/cql3/CQLTester.java index 98b8e23..416a4b2 100644 --- a/test/unit/org/apache/cassandra/cql3/CQLTester.java +++ b/test/unit/org/apache/cassandra/cql3/CQLTester.java @@ -36,13 +36,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import static junit.framework.Assert.assertNotNull; -import com.datastax.driver.core.Cluster; -import com.datastax.driver.core.ColumnDefinitions; -import com.datastax.driver.core.DataType; -import com.datastax.driver.core.ProtocolVersion; + +import com.datastax.driver.core.*; import com.datastax.driver.core.ResultSet; -import com.datastax.driver.core.Row; -import com.datastax.driver.core.Session; + import org.apache.cassandra.SchemaLoader; import org.apache.cassandra.concurrent.ScheduledExecutors; import org.apache.cassandra.config.CFMetaData; @@ -557,6 +554,11 @@ public abstract class CQLTester return session[protocolVersion-1].execute(formatQuery(query), values); } + protected com.datastax.driver.core.ResultSet executeNetWithPaging(String query, int pageSize) throws Throwable + { + return sessionNet(maxProtocolVersion).execute(new SimpleStatement(formatQuery(query)).setFetchSize(pageSize)); + } + protected Session sessionNet(int protocolVersion) { requireNetwork(); @@ -663,6 +665,11 @@ public abstract class CQLTester rows.length>i ? "less" : "more", rows.length, i, protocolVersion), i == rows.length); } + protected void assertRowsNet(ResultSet result, Object[]... rows) + { + assertRowsNet(maxProtocolVersion, result, rows); + } + protected void assertRows(UntypedResultSet result, Object[]... rows) { if (result == null) http://git-wip-us.apache.org/repos/asf/cassandra/blob/cb6fad3e/test/unit/org/apache/cassandra/cql3/validation/entities/JsonTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/JsonTest.java b/test/unit/org/apache/cassandra/cql3/validation/entities/JsonTest.java index 6892e79..0f29928 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/entities/JsonTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/entities/JsonTest.java @@ -17,10 +17,11 @@ */ package org.apache.cassandra.cql3.validation.entities; -import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.cql3.Json; -import org.apache.cassandra.cql3.CQLTester; import org.apache.cassandra.dht.ByteOrderedPartitioner; +import org.apache.cassandra.config.DatabaseDescriptor; +import org.apache.cassandra.cql3.CQLTester; + import org.apache.cassandra.serializers.SimpleDateSerializer; import org.apache.cassandra.serializers.TimeSerializer; import org.apache.cassandra.utils.ByteBufferUtil; @@ -34,11 +35,7 @@ import java.math.BigInteger; import java.net.InetAddress; import java.text.SimpleDateFormat; import java.util.*; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - +import java.util.concurrent.*; import static org.junit.Assert.fail; public class JsonTest extends CQLTester @@ -50,6 +47,157 @@ public class JsonTest extends CQLTester } @Test + public void testSelectJsonWithPagingWithFrozenTuple() throws Throwable + { + final UUID uuid = UUID.fromString("2dd2cd62-6af3-4cf6-96fc-91b9ab62eedc"); + final Object partitionKey = tuple(uuid, 2); + + createTable("CREATE TABLE %s (k1 FROZEN<TUPLE<uuid, int>>, c1 frozen<tuple<uuid, int>>, value int, PRIMARY KEY (k1, c1))"); + + // prepare data + for (int i = 1; i < 5; i++) + execute("INSERT INTO %s (k1, c1, value) VALUES (?, ?, ?)", partitionKey, tuple(uuid, i), i); + + for (int pageSize = 1; pageSize < 6; pageSize++) + { + // SELECT JSON + assertRowsNet(executeNetWithPaging("SELECT JSON * FROM %s", pageSize), + row("{\"k1\": [\"" + uuid + "\", 2], \"c1\": [\"" + uuid + "\", 1], \"value\": 1}"), + row("{\"k1\": [\"" + uuid + "\", 2], \"c1\": [\"" + uuid + "\", 2], \"value\": 2}"), + row("{\"k1\": [\"" + uuid + "\", 2], \"c1\": [\"" + uuid + "\", 3], \"value\": 3}"), + row("{\"k1\": [\"" + uuid + "\", 2], \"c1\": [\"" + uuid + "\", 4], \"value\": 4}")); + + // SELECT toJson(column) + assertRowsNet(executeNetWithPaging("SELECT toJson(k1), toJson(c1), toJson(value) FROM %s", pageSize), + row("[\"" + uuid + "\", 2]", "[\"" + uuid + "\", 1]", "1"), + row("[\"" + uuid + "\", 2]", "[\"" + uuid + "\", 2]", "2"), + row("[\"" + uuid + "\", 2]", "[\"" + uuid + "\", 3]", "3"), + row("[\"" + uuid + "\", 2]", "[\"" + uuid + "\", 4]", "4")); + } + } + + @Test + public void testSelectJsonWithPagingWithFrozenMap() throws Throwable + { + final UUID uuid = UUID.fromString("2dd2cd62-6af3-4cf6-96fc-91b9ab62eedc"); + final Object partitionKey = map(1, tuple(uuid, 1), 2, tuple(uuid, 2)); + + createTable("CREATE TABLE %s (k1 FROZEN<map<int, tuple<uuid, int>>>, c1 frozen<tuple<uuid, int>>, value int, PRIMARY KEY (k1, c1))"); + + // prepare data + for (int i = 1; i < 5; i++) + execute("INSERT INTO %s (k1, c1, value) VALUES (?, ?, ?)", partitionKey, tuple(uuid, i), i); + + for (int pageSize = 1; pageSize < 6; pageSize++) + { + // SELECT JSON + assertRowsNet(executeNetWithPaging("SELECT JSON * FROM %s", pageSize), + row("{\"k1\": {\"1\": [\"" + uuid + "\", 1], \"2\": [\"" + uuid + "\", 2]}, \"c1\": [\"" + uuid + "\", 1], \"value\": 1}"), + row("{\"k1\": {\"1\": [\"" + uuid + "\", 1], \"2\": [\"" + uuid + "\", 2]}, \"c1\": [\"" + uuid + "\", 2], \"value\": 2}"), + row("{\"k1\": {\"1\": [\"" + uuid + "\", 1], \"2\": [\"" + uuid + "\", 2]}, \"c1\": [\"" + uuid + "\", 3], \"value\": 3}"), + row("{\"k1\": {\"1\": [\"" + uuid + "\", 1], \"2\": [\"" + uuid + "\", 2]}, \"c1\": [\"" + uuid + "\", 4], \"value\": 4}")); + + // SELECT toJson(column) + assertRowsNet(executeNetWithPaging("SELECT toJson(k1), toJson(c1), toJson(value) FROM %s", pageSize), + row("{\"1\": [\"" + uuid + "\", 1], \"2\": [\"" + uuid + "\", 2]}", "[\"" + uuid + "\", 1]", "1"), + row("{\"1\": [\"" + uuid + "\", 1], \"2\": [\"" + uuid + "\", 2]}", "[\"" + uuid + "\", 2]", "2"), + row("{\"1\": [\"" + uuid + "\", 1], \"2\": [\"" + uuid + "\", 2]}", "[\"" + uuid + "\", 3]", "3"), + row("{\"1\": [\"" + uuid + "\", 1], \"2\": [\"" + uuid + "\", 2]}", "[\"" + uuid + "\", 4]", "4")); + } + } + + @Test + public void testSelectJsonWithPagingWithFrozenSet() throws Throwable + { + final UUID uuid = UUID.fromString("2dd2cd62-6af3-4cf6-96fc-91b9ab62eedc"); + final Object partitionKey = set(tuple(list(1, 2), 1), tuple(list(2, 3), 2)); + + createTable("CREATE TABLE %s (k1 frozen<set<tuple<list<int>, int>>>, c1 frozen<tuple<uuid, int>>, value int, PRIMARY KEY (k1, c1))"); + + // prepare data + for (int i = 1; i < 5; i++) + execute("INSERT INTO %s (k1, c1, value) VALUES (?, ?, ?)", partitionKey, tuple(uuid, i), i); + + for (int pageSize = 1; pageSize < 6; pageSize++) + { + // SELECT JSON + assertRowsNet(executeNetWithPaging("SELECT JSON * FROM %s", pageSize), + row("{\"k1\": [[[1, 2], 1], [[2, 3], 2]], \"c1\": [\"" + uuid + "\", 1], \"value\": 1}"), + row("{\"k1\": [[[1, 2], 1], [[2, 3], 2]], \"c1\": [\"" + uuid + "\", 2], \"value\": 2}"), + row("{\"k1\": [[[1, 2], 1], [[2, 3], 2]], \"c1\": [\"" + uuid + "\", 3], \"value\": 3}"), + row("{\"k1\": [[[1, 2], 1], [[2, 3], 2]], \"c1\": [\"" + uuid + "\", 4], \"value\": 4}")); + + // SELECT toJson(column) + assertRowsNet(executeNetWithPaging("SELECT toJson(k1), toJson(c1), toJson(value) FROM %s", pageSize), + row("[[[1, 2], 1], [[2, 3], 2]]", "[\"" + uuid + "\", 1]", "1"), + row("[[[1, 2], 1], [[2, 3], 2]]", "[\"" + uuid + "\", 2]", "2"), + row("[[[1, 2], 1], [[2, 3], 2]]", "[\"" + uuid + "\", 3]", "3"), + row("[[[1, 2], 1], [[2, 3], 2]]", "[\"" + uuid + "\", 4]", "4")); + } + } + + @Test + public void testSelectJsonWithPagingWithFrozenList() throws Throwable + { + final UUID uuid = UUID.fromString("2dd2cd62-6af3-4cf6-96fc-91b9ab62eedc"); + final Object partitionKey = list(tuple(uuid, 2), tuple(uuid, 3)); + + createTable("CREATE TABLE %s (k1 frozen<list<tuple<uuid, int>>>, c1 frozen<tuple<uuid, int>>, value int, PRIMARY KEY (k1, c1))"); + + // prepare data + for (int i = 1; i < 5; i++) + execute("INSERT INTO %s (k1, c1, value) VALUES (?, ?, ?)", partitionKey, tuple(uuid, i), i); + + for (int pageSize = 1; pageSize < 6; pageSize++) + { + // SELECT JSON + assertRowsNet(executeNetWithPaging("SELECT JSON * FROM %s", pageSize), + row("{\"k1\": [[\"" + uuid + "\", 2], [\"" + uuid + "\", 3]], \"c1\": [\"" + uuid + "\", 1], \"value\": 1}"), + row("{\"k1\": [[\"" + uuid + "\", 2], [\"" + uuid + "\", 3]], \"c1\": [\"" + uuid + "\", 2], \"value\": 2}"), + row("{\"k1\": [[\"" + uuid + "\", 2], [\"" + uuid + "\", 3]], \"c1\": [\"" + uuid + "\", 3], \"value\": 3}"), + row("{\"k1\": [[\"" + uuid + "\", 2], [\"" + uuid + "\", 3]], \"c1\": [\"" + uuid + "\", 4], \"value\": 4}")); + + // SELECT toJson(column) + assertRowsNet(executeNetWithPaging("SELECT toJson(k1), toJson(c1), toJson(value) FROM %s", pageSize), + row("[[\"" + uuid + "\", 2], [\"" + uuid + "\", 3]]", "[\"" + uuid + "\", 1]", "1"), + row("[[\"" + uuid + "\", 2], [\"" + uuid + "\", 3]]", "[\"" + uuid + "\", 2]", "2"), + row("[[\"" + uuid + "\", 2], [\"" + uuid + "\", 3]]", "[\"" + uuid + "\", 3]", "3"), + row("[[\"" + uuid + "\", 2], [\"" + uuid + "\", 3]]", "[\"" + uuid + "\", 4]", "4")); + } + } + + @Test + public void testSelectJsonWithPagingWithFrozenUDT() throws Throwable + { + final UUID uuid = UUID.fromString("2dd2cd62-6af3-4cf6-96fc-91b9ab62eedc"); + final Object partitionKey = userType(1, 2, list("1", "2")); + + String typeName = createType("CREATE TYPE %s (a int, b int, c list<text>)"); + createTable("CREATE TABLE %s (k1 frozen<" + typeName + ">, c1 frozen<tuple<uuid, int>>, value int, PRIMARY KEY (k1, c1))"); + + // prepare data + for (int i = 1; i < 5; i++) + execute("INSERT INTO %s (k1, c1, value) VALUES (?, ?, ?)", partitionKey, tuple(uuid, i), i); + + for (int pageSize = 1; pageSize < 6; pageSize++) + { + // SELECT JSON + assertRowsNet(executeNetWithPaging("SELECT JSON * FROM %s", pageSize), + row("{\"k1\": {\"a\": 1, \"b\": 2, \"c\": [\"1\", \"2\"]}, \"c1\": [\"" + uuid + "\", 1], \"value\": 1}"), + row("{\"k1\": {\"a\": 1, \"b\": 2, \"c\": [\"1\", \"2\"]}, \"c1\": [\"" + uuid + "\", 2], \"value\": 2}"), + row("{\"k1\": {\"a\": 1, \"b\": 2, \"c\": [\"1\", \"2\"]}, \"c1\": [\"" + uuid + "\", 3], \"value\": 3}"), + row("{\"k1\": {\"a\": 1, \"b\": 2, \"c\": [\"1\", \"2\"]}, \"c1\": [\"" + uuid + "\", 4], \"value\": 4}")); + + // SELECT toJson(column) + assertRowsNet(executeNetWithPaging("SELECT toJson(k1), toJson(c1), toJson(value) FROM %s", pageSize), + row("{\"a\": 1, \"b\": 2, \"c\": [\"1\", \"2\"]}", "[\"" + uuid + "\", 1]", "1"), + row("{\"a\": 1, \"b\": 2, \"c\": [\"1\", \"2\"]}", "[\"" + uuid + "\", 2]", "2"), + row("{\"a\": 1, \"b\": 2, \"c\": [\"1\", \"2\"]}", "[\"" + uuid + "\", 3]", "3"), + row("{\"a\": 1, \"b\": 2, \"c\": [\"1\", \"2\"]}", "[\"" + uuid + "\", 4]", "4")); + } + } + + @Test public void testFromJsonFct() throws Throwable { String typeName = createType("CREATE TYPE %s (a int, b uuid, c set<text>)"); @@ -679,10 +827,13 @@ public class JsonTest extends CQLTester execute("INSERT INTO %s (k, textval) VALUES (?, ?)", 0, "\u0000"); assertRows(execute("SELECT k, toJson(textval) FROM %s WHERE k = ?", 0), row(0, "\"\\u0000\"")); - // ================ timestamp ================ + // ================ time ================ execute("INSERT INTO %s (k, timeval) VALUES (?, ?)", 0, 123L); assertRows(execute("SELECT k, toJson(timeval) FROM %s WHERE k = ?", 0), row(0, "\"00:00:00.000000123\"")); + execute("INSERT INTO %s (k, timeval) VALUES (?, fromJson(?))", 0, "\"07:35:07.000111222\""); + assertRows(execute("SELECT k, toJson(timeval) FROM %s WHERE k = ?", 0), row(0, "\"07:35:07.000111222\"")); + // ================ timestamp ================ SimpleDateFormat sdf = new SimpleDateFormat("y-M-d"); sdf.setTimeZone(TimeZone.getTimeZone("UDT")); http://git-wip-us.apache.org/repos/asf/cassandra/blob/cb6fad3e/test/unit/org/apache/cassandra/db/marshal/JsonConversionTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/db/marshal/JsonConversionTest.java b/test/unit/org/apache/cassandra/db/marshal/JsonConversionTest.java new file mode 100644 index 0000000..f7795c7 --- /dev/null +++ b/test/unit/org/apache/cassandra/db/marshal/JsonConversionTest.java @@ -0,0 +1,320 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ +package org.apache.cassandra.db.marshal; + +import static org.junit.Assert.assertEquals; + +import java.nio.ByteBuffer; +import org.apache.cassandra.cql3.QueryOptions; +import org.apache.cassandra.transport.Server; +import org.apache.cassandra.utils.UUIDGen; +import org.codehaus.jackson.map.ObjectMapper; +import org.junit.Test; + +public class JsonConversionTest +{ + private static final ObjectMapper JSON_OBJECT_MAPPER = new ObjectMapper(); + + @Test + public void testMap() throws Exception + { + String type = "FrozenType(MapType(TupleType(ListType(Int32Type), ListType(Int32Type)), ListType(Int32Type)))"; + String json = "{" + + "\"[[1, 2, 3], [1, 2, 3]]\": [1, 2, 3], " + + "\"[[1, 2, 3, 4], [1, 2, 3, 4]]\": [1, 2, 3, 4], " + + "\"[[1, 2, 3, 4, 5], [1, 2, 3, 4, 5]]\": [1, 2, 3, 4, 5]" + + "}"; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testUDT() throws Exception + { + // 6161-> aa + // 78 -> x + String type = "UserType(ks,6161,78:TupleType(ListType(Int32Type), ListType(Int32Type)))"; + String json = "{" + + "\"x\": [[1, 2, 3], [1, 2, 3]]" + + "}"; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testSimpleDate() throws Exception + { + String type = "SimpleDateType"; + String json = "\"1991-06-20\""; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testDate() throws Exception + { + String type = "DateType"; + String json = "\"1991-06-20 18:00:00.000Z\""; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testCounterColumn() throws Exception + { + Long value = 1L; + String json = "1"; + assertBytebufferPositionAndOutput(json, value, CounterColumnType.instance); + } + + @Test + public void testTimestamp() throws Exception + { + String type = "TimestampType"; + String json = "\"1991-06-20 18:00:00.000Z\""; + assertBytebufferPositionAndOutput(json, type); + } + + @Test(expected = UnsupportedOperationException.class) + public void testDynamicCompositeType() throws Exception + { + String type = "DynamicCompositeType(a=>Int32Type, b=>Int32Type)"; + // not supported + String json = "{" + + "\"a\":1," + + "\"b\":2" + + "}"; + assertBytebufferPositionAndOutput(json, type); + } + + @Test(expected = UnsupportedOperationException.class) + public void testCompositeType() throws Exception + { + String type = "CompositeType(Int32Type, Int32Type)"; + // not supported + String json = "{" + + "\"a\":1," + + "\"b\":2" + + "}"; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testList() throws Exception + { + String type = "FrozenType(ListType(TupleType(ListType(Int32Type), ListType(Int32Type))))"; + String json = "[" + + "[[1, 2, 3], [1, 2, 3]], " + + "[[1, 2, 3, 4], [1, 2, 3, 4]], " + + "[[1, 2, 3, 4, 5], [1, 2, 3, 4, 5]]" + + "]"; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testSet() throws Exception + { + String type = "FrozenType(SetType(TupleType(Int32Type, Int32Type)))"; + String json = "[[1, 2], [1, 3], [2, 3]]"; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testTuple() throws Exception + { + String type = "FrozenType(TupleType(TupleType(ListType(Int32Type), ListType(Int32Type))))"; + String json = "[" + + "[[1, 2, 3], [1, 2, 3]]" + + "]"; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testInt32() throws Exception + { + String type = "Int32Type"; + String json = "10000000"; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testReversed() throws Exception + { + String type = "ReversedType(Int32Type)"; + String json = "10000000"; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testInteger() throws Exception + { + String type = "IntegerType"; + String json = "10000000"; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testDecimal() throws Exception + { + String type = "DecimalType"; + String json = "100000.01"; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testEmpty() throws Exception + { + String type = "EmptyType"; + String json = "\"\""; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testDouble() throws Exception + { + String type = "DoubleType"; + String json = "100000.01"; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testFloat() throws Exception + { + String type = "FloatType"; + String json = "100000.01"; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testShort() throws Exception + { + String type = "ShortType"; + String json = "100"; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testByte() throws Exception + { + String type = "ByteType"; + String json = "0"; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testTime() throws Exception + { + String type = "TimeType"; + String json = "\"00:00:00.000001991\""; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testInetAddress() throws Exception + { + String type = "InetAddressType"; + String json = "\"127.0.0.1\""; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testBoolean() throws Exception + { + String type = "BooleanType"; + String json = "false"; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testLong() throws Exception + { + String type = "LongType"; + String json = "10000000000"; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testAscii() throws Exception + { + String type = "AsciiType"; + String json = "\"aaa\""; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testBytes() throws Exception + { + String type = "BytesType"; + String json = "\"0x00000001\""; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testUUID() throws Exception + { + String type = "UUIDType"; + String json = "\"6bddc89a-5644-11e4-97fc-56847afe9799\""; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testLexicalUUID() throws Exception + { + String type = "LexicalUUIDType"; + String json = "\"6bddc89a-5644-11e4-97fc-56847afe9799\""; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testTimeUUID() throws Exception + { + String type = "TimeUUIDType"; + String json = "\"" + UUIDGen.getTimeUUID() + "\""; + assertBytebufferPositionAndOutput(json, type); + } + + @Test + public void testUtf8() throws Exception + { + String type = "UTF8Type"; + String json = "\"abc\""; + assertBytebufferPositionAndOutput(json, type); + } + + // for those only supports toJson, eg. Counter + private static <T> void assertBytebufferPositionAndOutput(String json, T value, AbstractType<T> type) + throws Exception + { + ByteBuffer bb = type.getSerializer().serialize(value); + int position = bb.position(); + + String output = type.toJSONString(bb, Server.CURRENT_VERSION); + assertEquals(position, bb.position()); + assertEquals(json, output); + } + + // test fromJSONObject and toJSONString + private static void assertBytebufferPositionAndOutput(String json, String typeString) throws Exception + { + AbstractType<?> type = TypeParser.parse(typeString); + Object jsonObject = JSON_OBJECT_MAPPER.readValue(json, Object.class); + ByteBuffer bb = type.fromJSONObject(jsonObject).bindAndGet(QueryOptions.DEFAULT); + int position = bb.position(); + + String output = type.toJSONString(bb, Server.CURRENT_VERSION); + assertEquals(position, bb.position()); + assertEquals(json, output); + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org