Skip to content

Commit

Permalink
Changed decode to align with mysql connector/j
Browse files Browse the repository at this point in the history
  • Loading branch information
svats0001 committed Nov 18, 2024
1 parent c091335 commit a0a0820
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package io.asyncer.r2dbc.mysql.codec;

import java.math.BigInteger;

import io.asyncer.r2dbc.mysql.MySqlParameter;
import io.asyncer.r2dbc.mysql.ParameterWriter;
import io.asyncer.r2dbc.mysql.api.MySqlReadableMetadata;
Expand All @@ -38,18 +40,27 @@ private BooleanCodec() {
@Override
public Boolean decode(ByteBuf value, MySqlReadableMetadata metadata, Class<?> target, boolean binary,
CodecContext context) {
MySqlType dataType = metadata.getType();
if (dataType == MySqlType.VARCHAR) {
if (value.isReadable()) {
String stringVal = value.toString(metadata.getCharCollation(context).getCharset());
if (stringVal.equalsIgnoreCase("true") || stringVal.equals("1")) {
return true;
} else if (stringVal.equalsIgnoreCase("false") || stringVal.equals("0")) {
return false;
}
if (!value.isReadable()) {
return createFromLong(0);
}

String s = value.toString(metadata.getCharCollation(context).getCharset());

if (s.equalsIgnoreCase("Y") || s.equalsIgnoreCase("yes") ||
s.equalsIgnoreCase("T") || s.equalsIgnoreCase("true")) {
return createFromLong(1);
} else if (s.equalsIgnoreCase("N") || s.equalsIgnoreCase("no") ||
s.equalsIgnoreCase("F") || s.equalsIgnoreCase("false")) {
return createFromLong(0);
} else if (s.contains("e") || s.contains("E") || s.matches("-?\\d*\\.\\d*")) {
return createFromDouble(Double.parseDouble(s));
} else if (s.matches("-?\\d+")) {
if (!CodecUtils.isGreaterThanLongMax(s)) {
return createFromLong(CodecUtils.parseLong(value));
}
return createFromBigInteger(new BigInteger(s));
}
return binary || dataType == MySqlType.BIT ? value.readBoolean() : value.readByte() != '0';
throw new IllegalArgumentException("Unable to interpret string: " + s);
}

@Override
Expand All @@ -65,8 +76,19 @@ public MySqlParameter encode(Object value, CodecContext context) {
@Override
public boolean doCanDecode(MySqlReadableMetadata metadata) {
MySqlType type = metadata.getType();
return ((type == MySqlType.BIT || type == MySqlType.TINYINT) &&
Integer.valueOf(1).equals(metadata.getPrecision())) || type == MySqlType.VARCHAR;
return type == MySqlType.BIT || type == MySqlType.VARCHAR || type.isNumeric();
}

public Boolean createFromLong(long l) {
return (l == -1 || l > 0);
}

public Boolean createFromDouble(double d) {
return (d == -1.0d || d > 0);
}

public Boolean createFromBigInteger(BigInteger b) {
return b.compareTo(BigInteger.valueOf(0)) > 0 || b.compareTo(BigInteger.valueOf(-1)) == 0;
}

private static final class BooleanMySqlParameter extends AbstractMySqlParameter {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import io.netty.buffer.Unpooled;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import java.nio.charset.Charset;
import java.util.Arrays;
Expand Down Expand Up @@ -70,6 +71,14 @@ void decodeString() {
Decoding d2 = new Decoding(Unpooled.copiedBuffer("false", c), "false", MySqlType.VARCHAR);
Decoding d3 = new Decoding(Unpooled.copiedBuffer("1", c), "1", MySqlType.VARCHAR);
Decoding d4 = new Decoding(Unpooled.copiedBuffer("0", c), "0", MySqlType.VARCHAR);
Decoding d5 = new Decoding(Unpooled.copiedBuffer("Y", c), "Y", MySqlType.VARCHAR);
Decoding d6 = new Decoding(Unpooled.copiedBuffer("no", c), "no", MySqlType.VARCHAR);
Decoding d7 = new Decoding(Unpooled.copyDouble(26.57d), 26.57d, MySqlType.DOUBLE);
Decoding d8 = new Decoding(Unpooled.copyLong(-57L), -57L, MySqlType.TINYINT);
Decoding d9 = new Decoding(Unpooled.copyLong(100000L), 100000L, MySqlType.BIGINT);
Decoding d10 = new Decoding(Unpooled.copiedBuffer("-12345678901234567890", c),
"-12345678901234567890", MySqlType.VARCHAR);
Decoding d11 = new Decoding(Unpooled.copiedBuffer("Banana", c), "Banana", MySqlType.VARCHAR);

assertThat(codec.decode(d1.content(), d1.metadata(), Boolean.class, false, ConnectionContextTest.mock()))
.as("Decode failed, %s", d1)
Expand All @@ -86,5 +95,32 @@ void decodeString() {
assertThat(codec.decode(d4.content(), d4.metadata(), Boolean.class, false, ConnectionContextTest.mock()))
.as("Decode failed, %s", d4)
.isEqualTo(false);

assertThat(codec.decode(d5.content(), d5.metadata(), Boolean.class, false, ConnectionContextTest.mock()))
.as("Decode failed, %s", d5)
.isEqualTo(true);

assertThat(codec.decode(d6.content(), d6.metadata(), Boolean.class, false, ConnectionContextTest.mock()))
.as("Decode failed, %s", d6)
.isEqualTo(false);

assertThat(codec.decode(d7.content(), d7.metadata(), Boolean.class, false, ConnectionContextTest.mock()))
.as("Decode failed, %s", d7)
.isEqualTo(true);

assertThat(codec.decode(d8.content(), d8.metadata(), Boolean.class, false, ConnectionContextTest.mock()))
.as("Decode failed, %s", d8)
.isEqualTo(false);

assertThat(codec.decode(d9.content(), d9.metadata(), Boolean.class, false, ConnectionContextTest.mock()))
.as("Decode failed, %s", d9)
.isEqualTo(true);

assertThat(codec.decode(d10.content(), d10.metadata(), Boolean.class, false, ConnectionContextTest.mock()))
.as("Decode failed, %s", d10)
.isEqualTo(false);

assertThatThrownBy(() -> {codec.decode(d11.content(), d11.metadata(), Boolean.class, false, ConnectionContextTest.mock());})
.isInstanceOf(IllegalArgumentException.class);
}
}

0 comments on commit a0a0820

Please sign in to comment.