/* * Copyright (C) 2012-2015 DataStax Inc. * * Licensed 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.extras.codecs.arrays; import com.datastax.driver.core.*; import com.datastax.driver.mapping.Mapper; import com.datastax.driver.mapping.MappingManager; import com.datastax.driver.mapping.annotations.Column; import com.datastax.driver.mapping.annotations.PartitionKey; import com.datastax.driver.mapping.annotations.Table; import com.google.common.primitives.Primitives; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; public class ArrayCodecsTest extends CCMTestsSupport { private static final ObjectArrayCodec<String> stringArrayCodec = new ObjectArrayCodec<String>( DataType.list(DataType.varchar()), String[].class, TypeCodec.varchar()); @Override public void onTestContextInitialized() { execute( "CREATE TABLE lists (" + "pk int PRIMARY KEY, " + "l_int list<int>, " + "l_bigint list<bigint>, " + "l_float list<float>, " + "l_double list<double>, " + "l_string list<text> " + ")", "INSERT INTO lists (pk, l_int, l_bigint, l_float, l_double, l_string) VALUES (1, " + "[1, 2, 3], " + "[4, 5, 6], " + "[1.0, 2.0, 3.0], " + "[4.0, 5.0, 6.0], " + "['a', 'b', 'c'] " + ")" ); } @Override public Cluster.Builder createClusterBuilder() { return Cluster.builder().withCodecRegistry( new CodecRegistry() .register(IntArrayCodec.instance) .register(LongArrayCodec.instance) .register(FloatArrayCodec.instance) .register(DoubleArrayCodec.instance) .register(stringArrayCodec) ); } @DataProvider(name = "ArrayCodecsTest-serializing") public static Object[][] parametersForSerializationTests() { return new Object[][]{ {"l_int", int[].class, new int[]{1, 2, 3}}, {"l_bigint", long[].class, new long[]{4, 5, 6}}, {"l_float", float[].class, new float[]{1, 2, 3}}, {"l_double", double[].class, new double[]{4, 5, 6}}, {"l_string", String[].class, new String[]{"a", "b", "c"}} }; } @DataProvider(name = "ArrayCodecsTest-formatting") public static Object[][] parametersForFormattingTests() { return new Object[][]{ {new IntArrayCodec(), new int[]{1, 2, 3}, new int[0], "[1,2,3]"}, {new LongArrayCodec(), new long[]{4, 5, 6}, new long[0], "[4,5,6]"}, {new FloatArrayCodec(), new float[]{1, 2, 3}, new float[0], "[1.0,2.0,3.0]"}, {new DoubleArrayCodec(), new double[]{4, 5, 6}, new double[0], "[4.0,5.0,6.0]"}, {stringArrayCodec, new String[]{"a", "b", "c"}, new String[0], "['a','b','c']"} }; } @Test(groups = "short", dataProvider = "ArrayCodecsTest-serializing") public <A> void should_read_list_column_as_array(String columnName, Class<A> arrayClass, A expected) { Row row = session().execute(String.format("SELECT %s FROM lists WHERE pk = 1", columnName)).one(); A actual = row.get(columnName, arrayClass); assertThat(actual).isEqualTo(expected); } @Test(groups = "short", dataProvider = "ArrayCodecsTest-serializing") public <A> void should_set_list_column_with_array(String columnName, Class<A> arrayClass, A expected) { PreparedStatement ps = session().prepare(String.format("INSERT INTO lists (pk, %s) VALUES (?, ?)", columnName)); BoundStatement bs = ps.bind() .setInt(0, 2) .set(columnName, expected, arrayClass); session().execute(bs); Row row = session().execute(String.format("SELECT %s FROM lists WHERE pk = 2", columnName)).one(); List<?> list = row.getList(columnName, Primitives.wrap(arrayClass.getComponentType())); assertThat(list.toArray()).isEqualTo(expected); } @Test(groups = "unit", dataProvider = "ArrayCodecsTest-formatting") public <A> void should_format_array_as_cql_literal(TypeCodec<A> codec, A array, A emptyArray, String cql) { assertThat(codec.format(array)).isEqualTo(cql); assertThat(codec.format(emptyArray)).isEqualTo("[]"); assertThat(codec.format(null)).isEqualToIgnoringCase("NULL"); } @Test(groups = "unit", dataProvider = "ArrayCodecsTest-formatting") public <A> void should_parse_array_from_cql_literal(TypeCodec<A> codec, A array, A emptyArray, String cql) { assertThat(codec.parse(cql)).isEqualTo(array); assertThat(codec.parse("[]")).isEqualTo(emptyArray); assertThat(codec.parse("NULL")).isNull(); assertThat(codec.parse("")).isNull(); assertThat(codec.parse(null)).isNull(); } @Test(groups = "short") public void should_use_mapper_to_store_and_retrieve_values_with_custom_joda_codecs() { // given MappingManager manager = new MappingManager(session()); Mapper<Mapped> mapper = manager.mapper(Mapped.class); // when Mapped pojo = new Mapped(); mapper.save(pojo); Mapped actual = mapper.get(42); // then assertThat(actual).isEqualToComparingFieldByField(pojo); } @SuppressWarnings("unused") @Table(name = "lists") public static class Mapped { @PartitionKey private int pk; @Column(name = "l_string") private String[] strings; @Column(name = "l_int") private int[] ints; @Column(name = "l_bigint") private long[] longs; @Column(name = "l_float") private float[] floats; @Column(name = "l_double") private double[] doubles; public Mapped() { pk = 42; strings = new String[]{"a", "b", "c"}; ints = new int[]{1, 2, 3}; longs = new long[]{4, 5, 6}; floats = new float[]{1, 2, 3}; doubles = new double[]{4, 5, 6}; } public int getPk() { return pk; } public void setPk(int pk) { this.pk = pk; } public String[] getStrings() { return strings; } public void setStrings(String[] strings) { this.strings = strings; } public int[] getInts() { return ints; } public void setInts(int[] ints) { this.ints = ints; } public long[] getLongs() { return longs; } public void setLongs(long[] longs) { this.longs = longs; } public float[] getFloats() { return floats; } public void setFloats(float[] floats) { this.floats = floats; } public double[] getDoubles() { return doubles; } public void setDoubles(double[] doubles) { this.doubles = doubles; } } }