Skip to content

Commit

Permalink
Introduce ObjectCodec to support bindNull(Object.class)
Browse files Browse the repository at this point in the history
[resolves #664]
  • Loading branch information
mp911de committed Oct 2, 2024
1 parent 8cc55a3 commit a8830e7
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 1 deletion.
6 changes: 5 additions & 1 deletion src/main/java/io/r2dbc/postgresql/codec/DefaultCodecs.java
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ EncodedParameter encodeParameterValue(Object value, @Nullable PostgresTypeIdenti
if (dataType == null) {

if (parameterValue == null) {
throw new IllegalArgumentException(String.format("Cannot encode null value %s using type inference", value));
return ObjectCodec.INSTANCE.encodeNull();
}

Codec<?> codec = this.codecLookup.findEncodeCodec(parameterValue);
Expand All @@ -294,6 +294,10 @@ EncodedParameter encodeParameterValue(Object value, @Nullable PostgresTypeIdenti
public EncodedParameter encodeNull(Class<?> type) {
Assert.requireNonNull(type, "type must not be null");

if (type == Object.class) {
return ObjectCodec.INSTANCE.encodeNull();
}

Codec<?> codec = this.codecLookup.findEncodeNullCodec(type);
if (codec != null) {
return codec.encodeNull();
Expand Down
72 changes: 72 additions & 0 deletions src/main/java/io/r2dbc/postgresql/codec/ObjectCodec.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright 2024 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.ByteBuf;
import io.r2dbc.postgresql.client.EncodedParameter;
import io.r2dbc.postgresql.message.Format;

import static io.r2dbc.postgresql.codec.PostgresqlObjectId.UNSPECIFIED;
import static io.r2dbc.postgresql.message.Format.FORMAT_TEXT;

final class ObjectCodec implements Codec<Object> {

static final ObjectCodec INSTANCE = new ObjectCodec();

private ObjectCodec() {
}

@Override
public EncodedParameter encodeNull() {
return AbstractCodec.createNull(FORMAT_TEXT, UNSPECIFIED);
}

public EncodedParameter encodeNull(int dataType) {
return new EncodedParameter(FORMAT_TEXT, dataType, EncodedParameter.NULL_VALUE);
}

@Override
public boolean canDecode(int dataType, Format format, Class<?> type) {
return false;
}

@Override
public boolean canEncode(Object value) {
return false;
}

@Override
public boolean canEncodeNull(Class<?> type) {
return Object.class.equals(type);
}

@Override
public Object decode(ByteBuf buffer, int dataType, Format format, Class<?> type) {
throw new UnsupportedOperationException();
}

@Override
public EncodedParameter encode(Object value) {
throw new UnsupportedOperationException();
}

@Override
public EncodedParameter encode(Object value, int dataType) {
throw new UnsupportedOperationException();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright 2024 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.r2dbc.postgresql.AbstractIntegrationTests;
import org.junit.jupiter.api.Test;
import reactor.test.StepVerifier;

/**
* Integration tests for {@link ObjectCodec} usage.
*/
class ObjectCodecIntegrationTests extends AbstractIntegrationTests {

@Test
void shouldEncodeNull() {

SERVER.getJdbcOperations().execute("DROP TABLE IF EXISTS test");
SERVER.getJdbcOperations().execute("CREATE TABLE test (ci INT4, cs VARCHAR)");

this.connection.createStatement("INSERT INTO test VALUES($1, $2)")
.bindNull("$1", Object.class)
.bindNull("$2", Object.class)
.execute()
.flatMap(it -> it.getRowsUpdated())
.as(StepVerifier::create)
.expectNext(1L)
.verifyComplete();

SERVER.getJdbcOperations().execute("DROP TABLE test");
}

}

0 comments on commit a8830e7

Please sign in to comment.