Skip to content

Commit 8d4f030

Browse files
committed
Fix #76: add codec TINYINT <-> Short
1 parent d04c917 commit 8d4f030

File tree

8 files changed

+178
-2
lines changed

8 files changed

+178
-2
lines changed

Diff for: CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
1111
- `COPY <tableName>[(<colums>)] TO|FROM <target>[ WITH <options>[ AND <options>...]]`
1212
- Add a method `CassandraConnection.setOptionSet(OptionSet)` to programmatically define a custom compliance mode option
1313
set on a pre-existing connection.
14+
### Fixed
15+
- Add codec for conversion between `Short` and CQL type `tinyint` (see issue
16+
[#76](https://github.com/ing-bank/cassandra-jdbc-wrapper/issues/76)).
1417

1518
## [4.14.0] - 2024-12-24
1619
### Added

Diff for: src/main/java/com/ing/data/cassandra/jdbc/CassandraConnection.java

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.ing.data.cassandra.jdbc.codec.SmallintToIntCodec;
3232
import com.ing.data.cassandra.jdbc.codec.TimestampToLongCodec;
3333
import com.ing.data.cassandra.jdbc.codec.TinyintToIntCodec;
34+
import com.ing.data.cassandra.jdbc.codec.TinyintToShortCodec;
3435
import com.ing.data.cassandra.jdbc.codec.VarintToIntCodec;
3536
import com.ing.data.cassandra.jdbc.optionset.Default;
3637
import com.ing.data.cassandra.jdbc.optionset.OptionSet;
@@ -254,6 +255,7 @@ public CassandraConnection(final Session cSession, final String currentKeyspace,
254255
codecs.add(new VarintToIntCodec());
255256
codecs.add(new SmallintToIntCodec());
256257
codecs.add(new TinyintToIntCodec());
258+
codecs.add(new TinyintToShortCodec());
257259
safelyRegisterCodecs(cSession, codecs);
258260
}
259261

Diff for: src/main/java/com/ing/data/cassandra/jdbc/SessionHolder.java

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import com.ing.data.cassandra.jdbc.codec.SmallintToIntCodec;
4040
import com.ing.data.cassandra.jdbc.codec.TimestampToLongCodec;
4141
import com.ing.data.cassandra.jdbc.codec.TinyintToIntCodec;
42+
import com.ing.data.cassandra.jdbc.codec.TinyintToShortCodec;
4243
import com.ing.data.cassandra.jdbc.codec.VarintToIntCodec;
4344
import com.ing.data.cassandra.jdbc.utils.AwsUtil;
4445
import com.ing.data.cassandra.jdbc.utils.ContactPoint;
@@ -379,6 +380,7 @@ private Session createSession(final Properties properties) throws SQLException {
379380
codecs.add(new VarintToIntCodec());
380381
codecs.add(new SmallintToIntCodec());
381382
codecs.add(new TinyintToIntCodec());
383+
codecs.add(new TinyintToShortCodec());
382384
builder.addTypeCodecs(codecs.toArray(new TypeCodec[]{}));
383385

384386
builder.withKeyspace(keyspace);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
package com.ing.data.cassandra.jdbc.codec;
17+
18+
import com.datastax.oss.driver.api.core.ProtocolVersion;
19+
import com.datastax.oss.driver.api.core.type.DataType;
20+
import com.datastax.oss.driver.api.core.type.DataTypes;
21+
import com.datastax.oss.driver.api.core.type.codec.TypeCodec;
22+
import com.datastax.oss.driver.api.core.type.reflect.GenericType;
23+
import com.ing.data.cassandra.jdbc.utils.ByteBufferUtil;
24+
25+
import javax.annotation.Nonnull;
26+
import java.nio.ByteBuffer;
27+
28+
/**
29+
* Manages the two-way conversion between the CQL type {@link DataTypes#TINYINT} and the Java type {@link Short}.
30+
*/
31+
public class TinyintToShortCodec extends AbstractCodec<Short> implements TypeCodec<Short> {
32+
33+
/**
34+
* Constructor for {@code TinyintToShortCodec}.
35+
*/
36+
public TinyintToShortCodec() {
37+
}
38+
39+
@Nonnull
40+
@Override
41+
public GenericType<Short> getJavaType() {
42+
return GenericType.SHORT;
43+
}
44+
45+
@Nonnull
46+
@Override
47+
public DataType getCqlType() {
48+
return DataTypes.TINYINT;
49+
}
50+
51+
@Override
52+
public ByteBuffer encode(final Short value, @Nonnull final ProtocolVersion protocolVersion) {
53+
if (value == null) {
54+
return null;
55+
}
56+
return ByteBufferUtil.bytes(value);
57+
}
58+
59+
@Override
60+
public Short decode(final ByteBuffer bytes, @Nonnull final ProtocolVersion protocolVersion) {
61+
if (bytes == null) {
62+
return null;
63+
}
64+
// always duplicate the ByteBuffer instance before consuming it!
65+
final byte value = bytes.duplicate().get();
66+
return (short) value;
67+
}
68+
69+
@Override
70+
Short parseNonNull(@Nonnull final String value) {
71+
return Short.valueOf(value);
72+
}
73+
74+
@Override
75+
String formatNonNull(@Nonnull final Short value) {
76+
return String.valueOf(value);
77+
}
78+
79+
}

Diff for: src/test/java/com/ing/data/cassandra/jdbc/ConnectionUnitTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ void givenSessionToConnect_andLiquibaseCompliance() throws SQLException {
513513
@Test
514514
void givenSession_whenCreateConnection_registerCodecsOnlyOnce() {
515515
// The number of custom codecs defined in the package com.ing.data.cassandra.jdbc.codec.
516-
final int numberOfCustomCodecs = 9;
516+
final int numberOfCustomCodecs = 10;
517517

518518
final CqlSession mockSession = mock(CqlSession.class);
519519
final DriverContext mockContext = mock(DriverContext.class);

Diff for: src/test/java/com/ing/data/cassandra/jdbc/JdbcRegressionUnitTest.java

+1
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,7 @@ void testIssue80() throws Exception {
531531
assertEquals(new Time(now).toString(), result.getTime("time_col").toString());
532532
assertEquals(1, result.getShort("smallint_col"));
533533
assertEquals(1, result.getByte("tinyint_col"));
534+
assertEquals(1, result.getShort("tinyint_col")); // TINYINT could also be retrieved as short.
534535
assertEquals(testDuration1, ((CassandraResultSet) result).getDuration("duration_col"));
535536
assertEquals(testUrl, result.getURL("url_col"));
536537

Diff for: src/test/java/com/ing/data/cassandra/jdbc/codec/TinyintToIntCodecTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ void givenCodec_whenGetJavaType_returnInt() {
3636
}
3737

3838
@Test
39-
void givenCodec_whenGetCqlType_returnVarint() {
39+
void givenCodec_whenGetCqlType_returnTinyint() {
4040
assertEquals(DataTypes.TINYINT, sut.getCqlType());
4141
}
4242

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package com.ing.data.cassandra.jdbc.codec;
15+
16+
import com.datastax.oss.driver.api.core.ProtocolVersion;
17+
import com.datastax.oss.driver.api.core.type.DataTypes;
18+
import com.datastax.oss.driver.api.core.type.reflect.GenericType;
19+
import org.apache.commons.lang3.StringUtils;
20+
import org.junit.jupiter.api.Test;
21+
22+
import java.nio.ByteBuffer;
23+
24+
import static com.ing.data.cassandra.jdbc.utils.DriverUtil.NULL_KEYWORD;
25+
import static org.junit.jupiter.api.Assertions.assertEquals;
26+
import static org.junit.jupiter.api.Assertions.assertNotNull;
27+
import static org.junit.jupiter.api.Assertions.assertNull;
28+
29+
public class TinyintToShortCodecTest {
30+
31+
private final TinyintToShortCodec sut = new TinyintToShortCodec();
32+
33+
@Test
34+
void givenCodec_whenGetJavaType_returnShort() {
35+
assertEquals(GenericType.SHORT, sut.getJavaType());
36+
}
37+
38+
@Test
39+
void givenCodec_whenGetCqlType_returnTinyint() {
40+
assertEquals(DataTypes.TINYINT, sut.getCqlType());
41+
}
42+
43+
@Test
44+
void givenNullValue_whenEncode_returnNull() {
45+
assertNull(sut.encode(null, ProtocolVersion.DEFAULT));
46+
}
47+
48+
@Test
49+
void givenValue_whenEncode_returnByteBuffer() {
50+
ByteBuffer bytes = sut.encode((short) 64, ProtocolVersion.DEFAULT);
51+
assertNotNull(bytes);
52+
assertEquals(64, bytes.getShort());
53+
}
54+
55+
@Test
56+
void givenNullValue_whenDecode_returnNull() {
57+
assertNull(sut.decode(null, ProtocolVersion.DEFAULT));
58+
}
59+
60+
@Test
61+
void givenValue_whenDecode_returnShort() {
62+
ByteBuffer bytes = ByteBuffer.allocate(1).put((byte) 64);
63+
bytes.position(0);
64+
assertEquals((short) 64, sut.decode(bytes, ProtocolVersion.DEFAULT));
65+
}
66+
67+
@Test
68+
void givenNullOrEmptyValue_whenParse_returnNull() {
69+
assertNull(sut.parse(null));
70+
assertNull(sut.parse(NULL_KEYWORD));
71+
assertNull(sut.parse(StringUtils.EMPTY));
72+
assertNull(sut.parse(StringUtils.SPACE));
73+
}
74+
75+
@Test
76+
void givenNonNullValue_whenParse_returnExpectedValue() {
77+
assertEquals((short) 64, sut.parse("64"));
78+
}
79+
80+
@Test
81+
void givenNullValue_whenFormat_returnNull() {
82+
assertEquals(NULL_KEYWORD, sut.format(null));
83+
}
84+
85+
@Test
86+
void givenNonNullValue_whenFormat_returnExpectedValue() {
87+
assertEquals("64", sut.format((short) 64));
88+
}
89+
}

0 commit comments

Comments
 (0)