Skip to content

Commit

Permalink
adding support for Period data type - pgjdbcgh-591
Browse files Browse the repository at this point in the history
  • Loading branch information
steverigney committed Aug 13, 2023
1 parent da5a689 commit 53f74aa
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/main/java/io/r2dbc/postgresql/codec/DefaultCodecs.java
Expand Up @@ -258,6 +258,7 @@ private static List<Codec<?>> getDefaultCodecs(ByteBufAllocator byteBufAllocator
new MonthDayCodec(byteBufAllocator),
new OffsetDateTimeCodec(byteBufAllocator),
new OffsetTimeCodec(byteBufAllocator),
new PeriodCodec(byteBufAllocator),
new ShortCodec(byteBufAllocator),
new UriCodec(byteBufAllocator),
new UrlCodec(byteBufAllocator),
Expand Down
29 changes: 29 additions & 0 deletions src/main/java/io/r2dbc/postgresql/codec/PeriodCodec.java
@@ -0,0 +1,29 @@
/*
* Copyright 2017 the original author or authors.
*
* 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
*
* https://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 io.r2dbc.postgresql.codec;

import io.netty.buffer.ByteBufAllocator;

import java.time.Period;
import java.time.YearMonth;

final class PeriodCodec extends StringCodecDelegate<Period> {

PeriodCodec(ByteBufAllocator byteBufAllocator) {
super(Period.class, byteBufAllocator, Period::toString, Period::parse);
}
}
129 changes: 129 additions & 0 deletions src/test/java/io/r2dbc/postgresql/codec/PeriodCodecTest.java
@@ -0,0 +1,129 @@
package io.r2dbc.postgresql.codec;

import io.netty.buffer.ByteBuf;
import io.r2dbc.postgresql.client.EncodedParameter;
import io.r2dbc.postgresql.client.ParameterAssert;
import org.junit.jupiter.api.Test;

import java.nio.charset.Charset;
import java.time.Period;
import java.time.format.DateTimeParseException;

import static io.r2dbc.postgresql.client.EncodedParameter.NULL_VALUE;
import static io.r2dbc.postgresql.codec.PostgresqlObjectId.BPCHAR;
import static io.r2dbc.postgresql.codec.PostgresqlObjectId.CHAR;
import static io.r2dbc.postgresql.codec.PostgresqlObjectId.NAME;
import static io.r2dbc.postgresql.codec.PostgresqlObjectId.TEXT;
import static io.r2dbc.postgresql.codec.PostgresqlObjectId.VARCHAR;
import static io.r2dbc.postgresql.message.Format.FORMAT_TEXT;
import static io.r2dbc.postgresql.util.TestByteBufAllocator.TEST;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;

class PeriodCodecTest {

@Test
void constructorNoByteBufAllocator() {
assertThatIllegalArgumentException().isThrownBy(() -> new PeriodCodec(null))
.withMessage("byteBufAllocator must not be null");
}

@Test
void decodeDays() {
final int days = 4;

final Period period = Period.ofDays(days);
assertDecodeOfPeriod(period);
}

@Test
void decodeJunkString() {
final String junkString = "hello world";
final ByteBuf buffer = TEST.buffer();

final int charsWritten = buffer.writeCharSequence(junkString, Charset.defaultCharset());
assertThat(charsWritten).isEqualTo(junkString.length());

assertThatExceptionOfType(DateTimeParseException.class)
.isThrownBy(() -> new PeriodCodec(TEST).decode(buffer, VARCHAR, FORMAT_TEXT, Period.class));
}

@Test
void decodeMonths() {
final int months = 3;

final Period period = Period.ofMonths(months);
assertDecodeOfPeriod(period);
}

@Test
void decodeNoByteBuf() {
assertThat(new PeriodCodec(TEST).decode(null, VARCHAR.getObjectId(), FORMAT_TEXT, Period.class)).isNull();
}

@Test
void decodeWeeks() {
final int weeks = 7;

final Period period = Period.ofWeeks(weeks);
assertDecodeOfPeriod(period);
}

@Test
void decodeYearsMonthsDays() {
final int years = 5;
final int months = 4;
final int days = 7;

final Period period = Period.of(years, months, days);
assertDecodeOfPeriod(period);
}

@Test
void doCanDecode() {
final PeriodCodec codec = new PeriodCodec(TEST);

assertThat(codec.doCanDecode(VARCHAR, FORMAT_TEXT)).isTrue();
assertThat(codec.doCanDecode(CHAR, FORMAT_TEXT)).isTrue();
assertThat(codec.doCanDecode(BPCHAR, FORMAT_TEXT)).isTrue();
assertThat(codec.doCanDecode(NAME, FORMAT_TEXT)).isTrue();
assertThat(codec.doCanDecode(TEXT, FORMAT_TEXT)).isTrue();
}

@Test
void doCanDecodeNoType() {
assertThatIllegalArgumentException().isThrownBy(() -> new PeriodCodec(TEST).doCanDecode(null, FORMAT_TEXT))
.withMessage("type must not be null");
}

@Test
void doEncodeNoValue() {
assertThatIllegalArgumentException().isThrownBy(() -> new PeriodCodec(TEST).doEncode(null))
.withMessage("value must not be null");
}

@Test
void encodeItemNoValue() {
assertThatIllegalArgumentException().isThrownBy(() -> new PeriodCodec(TEST).encode(null))
.withMessage("value must not be null");
}

@Test
void encodeNull() {
ParameterAssert.assertThat(new PeriodCodec(TEST).encodeNull())
.isEqualTo(new EncodedParameter(FORMAT_TEXT, VARCHAR.getObjectId(), NULL_VALUE));
}

private static void assertDecodeOfPeriod(Period period) {
final ByteBuf buffer = TEST.buffer();

final int charsWritten = buffer.writeCharSequence(period.toString(), Charset.defaultCharset());
assertThat(charsWritten).isEqualTo(period.toString().length());

assertThat(new PeriodCodec(TEST)
.decode(buffer, VARCHAR, FORMAT_TEXT, Period.class))
.isEqualTo(period);
}

}

0 comments on commit 53f74aa

Please sign in to comment.