|
| 1 | +/* |
| 2 | + * Licensed to the Apache Software Foundation (ASF) under one |
| 3 | + * or more contributor license agreements. See the NOTICE file |
| 4 | + * distributed with this work for additional information |
| 5 | + * regarding copyright ownership. The ASF licenses this file |
| 6 | + * to you under the Apache License, Version 2.0 (the |
| 7 | + * "License"); you may not use this file except in compliance |
| 8 | + * with the License. You may obtain a copy of the License at |
| 9 | + * |
| 10 | + * http://www.apache.org/licenses/LICENSE-2.0 |
| 11 | + * |
| 12 | + * Unless required by applicable law or agreed to in writing, software |
| 13 | + * distributed under the License is distributed on an "AS IS" BASIS, |
| 14 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 15 | + * See the License for the specific language governing permissions and |
| 16 | + * limitations under the License. |
| 17 | + */ |
| 18 | +package com.datastax.oss.driver.internal.core.type.codec; |
| 19 | + |
| 20 | +import static org.assertj.core.api.Assertions.assertThat; |
| 21 | +import static org.assertj.core.api.Assertions.assertThatThrownBy; |
| 22 | + |
| 23 | +import com.datastax.oss.driver.api.core.CqlSession; |
| 24 | +import com.datastax.oss.driver.api.core.cql.Row; |
| 25 | +import com.datastax.oss.driver.api.core.data.UdtValue; |
| 26 | +import com.datastax.oss.driver.api.core.type.UserDefinedType; |
| 27 | +import com.datastax.oss.driver.api.core.type.codec.TypeCodec; |
| 28 | +import com.datastax.oss.driver.api.testinfra.ccm.CcmRule; |
| 29 | +import com.datastax.oss.driver.api.testinfra.session.SessionRule; |
| 30 | +import com.datastax.oss.driver.categories.ParallelizableTests; |
| 31 | +import java.util.Objects; |
| 32 | +import org.junit.Rule; |
| 33 | +import org.junit.Test; |
| 34 | +import org.junit.experimental.categories.Category; |
| 35 | +import org.junit.rules.RuleChain; |
| 36 | +import org.junit.rules.TestRule; |
| 37 | + |
| 38 | +@Category(ParallelizableTests.class) |
| 39 | +public class UdtCodecIT { |
| 40 | + |
| 41 | + private CcmRule ccmRule = CcmRule.getInstance(); |
| 42 | + |
| 43 | + private SessionRule<CqlSession> sessionRule = SessionRule.builder(ccmRule).build(); |
| 44 | + |
| 45 | + @Rule public TestRule chain = RuleChain.outerRule(ccmRule).around(sessionRule); |
| 46 | + |
| 47 | + @Test |
| 48 | + public void should_decoding_udt_be_backward_compatible() { |
| 49 | + CqlSession session = sessionRule.session(); |
| 50 | + session.execute("CREATE TYPE test_type_1 (a text, b int)"); |
| 51 | + session.execute("CREATE TABLE test_table_1 (e int primary key, f frozen<test_type_1>)"); |
| 52 | + // insert a row using version 1 of the UDT schema |
| 53 | + session.execute("INSERT INTO test_table_1(e, f) VALUES(1, {a: 'a', b: 1})"); |
| 54 | + UserDefinedType udt = |
| 55 | + session |
| 56 | + .getMetadata() |
| 57 | + .getKeyspace(sessionRule.keyspace()) |
| 58 | + .flatMap(ks -> ks.getUserDefinedType("test_type_1")) |
| 59 | + .orElseThrow(IllegalStateException::new); |
| 60 | + TypeCodec<?> oldCodec = session.getContext().getCodecRegistry().codecFor(udt); |
| 61 | + // update UDT schema |
| 62 | + session.execute("ALTER TYPE test_type_1 add i text"); |
| 63 | + // insert a row using version 2 of the UDT schema |
| 64 | + session.execute("INSERT INTO test_table_1(e, f) VALUES(2, {a: 'b', b: 2, i: 'b'})"); |
| 65 | + Row row = |
| 66 | + Objects.requireNonNull(session.execute("SELECT f FROM test_table_1 WHERE e = ?", 2).one()); |
| 67 | + // Try to read new row with old codec. Using row.getUdtValue() would not cause any issues, |
| 68 | + // because new codec will be automatically registered (using all 3 attributes). |
| 69 | + // If application leverages generic row.get(String, Codec) method, data reading with old codec |
| 70 | + // should |
| 71 | + // be backward-compatible. |
| 72 | + UdtValue value = Objects.requireNonNull((UdtValue) row.get("f", oldCodec)); |
| 73 | + assertThat(value.getString("a")).isEqualTo("b"); |
| 74 | + assertThat(value.getInt("b")).isEqualTo(2); |
| 75 | + assertThatThrownBy(() -> value.getString("i")).hasMessage("i is not a field in this UDT"); |
| 76 | + } |
| 77 | +} |
0 commit comments