Skip to content

Commit

Permalink
add support for postgres xml type
Browse files Browse the repository at this point in the history
  • Loading branch information
Meier Roman committed Dec 22, 2021
1 parent 3d45e6d commit fd24b1a
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ public enum DataType {
JSON_ARRAY(199, true, Object[].class, JDBCType.OTHER, Tuple::getArrayOfJsons),
JSONB(3802, true, Object.class, JDBCType.OTHER, Tuple::getJson),
JSONB_ARRAY(3807, true, Object[].class, JDBCType.OTHER, Tuple::getArrayOfJsons),
XML(142, true, Object.class, JDBCType.OTHER),
XML_ARRAY(143, true, Object[].class, JDBCType.OTHER),
XML(142, true, Object.class, JDBCType.SQLXML),
XML_ARRAY(143, true, Object[].class, JDBCType.SQLXML),
POINT(600, true, Point.class, JDBCType.OTHER),
POINT_ARRAY(1017, true, Point[].class, JDBCType.OTHER),
LINE(628, true, Line.class, JDBCType.OTHER),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,10 @@ public static Object decodeText(DataType id, int index, int len, ByteBuf buff) {
return textDecodeMoney(index, len, buff);
case MONEY_ARRAY:
return textDecodeArray(MONEY_ARRAY_FACTORY, DataType.MONEY, index, len, buff);
case XML:
return textDecodePgSQLXML(index, len, buff);
case XML_ARRAY:
return textDecodeArray(PGSQLXML_ARRAY_FACTORY, DataType.XML, index, len, buff);
default:
return defaultDecodeText(index, len, buff);
}
Expand Down Expand Up @@ -1486,14 +1490,19 @@ private static void binaryEncodeTsQuery(String value, ByteBuf buff) {
buff.writeCharSequence(String.valueOf(value), StandardCharsets.UTF_8);
}

private static String binaryDecodePgXMLSQL(int index, int len, ByteBuf buff) {
return buff.getCharSequence(index, len, StandardCharsets.UTF_8).toString();
private static PgSQLXML binaryDecodePgXMLSQL(int index, int len, ByteBuf buff) {
return new PgSQLXML(buff.getCharSequence(index, len, StandardCharsets.UTF_8).toString());
}

private static void binaryEncodePgXMLSQL(PgSQLXML value, ByteBuf buff) {
buff.writeCharSequence(value.toString(), StandardCharsets.UTF_8);
}

private static PgSQLXML textDecodePgSQLXML(int index, int len, ByteBuf buff) {
String s = textDecodeVARCHAR(index, len, buff);
return new PgSQLXML(s);
}

private static String textDecodeTsVector(int index, int len, ByteBuf buff) {
return buff.getCharSequence(index, len, StandardCharsets.UTF_8).toString();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package io.vertx.pgclient.data;

import io.vertx.ext.unit.TestContext;
import io.vertx.pgclient.PgConnection;
import io.vertx.pgclient.PgException;
import io.vertx.sqlclient.*;
import org.junit.Test;

import java.util.function.BiFunction;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

public class PgSQLXMLCodecTest extends DataTypeTestBase {

@Test
public void testBinaryEncodePgSQLXMLAsVarcharOrXML(TestContext ctx) {
PgSQLXML asVarchar = new PgSQLXML("<message><to><be><validated></validated></be></to></message>");
PgSQLXML asXML = new PgSQLXML("<message><to><be><validated><again></again></validated></be></to></message>");

PgConnection.connect(vertx, options, ctx.asyncAssertSuccess(conn -> {
conn.preparedQuery("SELECT ($1::xml)::VARCHAR, ($2::xml)").execute(Tuple.of(asVarchar, asXML),
ctx.asyncAssertSuccess(rows -> {
ctx.assertEquals(1, rows.size());
Row row = rows.iterator().next();
String v1 = row.getString(0);
PgSQLXML v2 = (PgSQLXML)row.getValue(1);
ctx.assertEquals("<message><to><be><validated></validated></be></to></message>", v1);
ctx.assertEquals(asXML, v2);
})
);
}));
}

@Test
public void testBinaryEncodePgSQLXMLMalformed(TestContext ctx) {
PgSQLXML malformedXml = new PgSQLXML("<message><to><be><validated><malformed>>></validated></be></to></message>");

PgConnection.connect(vertx, options, ctx.asyncAssertSuccess(conn -> {
conn.preparedQuery("SELECT ($1::xml)").execute(Tuple.of(malformedXml),
ctx.asyncAssertFailure(err -> {
assertThat(((PgException) err).getCode(), is(equalTo("2200N")));
})
);
}));
}

@Test
public void testTextDecodePgSQLXML(TestContext ctx) {
testDecodePgSQLXML(ctx, SqlClient::query);
}

@Test
public void testBinaryDecodePgSQLXML(TestContext ctx) {
testDecodePgSQLXML(ctx, SqlClient::preparedQuery);
}

private void testDecodePgSQLXML(TestContext ctx, BiFunction<SqlClient, String, Query<RowSet<Row>>> a) {
PgSQLXML first = new PgSQLXML("<message><to><be><validated></validated></be></to></message>");

PgConnection.connect(vertx, options, ctx.asyncAssertSuccess(conn -> {
a.apply(conn, "SELECT '<message><to><be><validated></validated></be></to></message>'::xml")
.execute(ctx.asyncAssertSuccess(rows -> {
ctx.assertEquals(1, rows.size());
Row row = rows.iterator().next();
PgSQLXML v1 = (PgSQLXML) row.getValue(0);
ctx.assertEquals(first, v1);
}));
}));
}

@Test
public void testBinaryDecodePgSQLXMLArray(TestContext ctx) throws Exception {
PgSQLXML first = new PgSQLXML("<message><to><be><validated></validated></be></to></message>");
PgSQLXML second = new PgSQLXML("<message><to><be><validated><again></again></validated></be></to></message>");

PgConnection.connect(vertx, options, ctx.asyncAssertSuccess(conn -> {
conn.preparedQuery("SELECT ARRAY['<message><to><be><validated></validated></be></to></message>'::xml,'<message><to><be><validated><again></again></validated></be></to></message>'::xml]")
.execute(ctx.asyncAssertSuccess(rows -> {
ctx.assertEquals(1, rows.size());
Row row = rows.iterator().next();
PgSQLXML[] array = (PgSQLXML[]) row.getValue(0);
PgSQLXML v1 = array[0];
PgSQLXML v2 = array[1];
ctx.assertEquals(first, v1);
ctx.assertEquals(second, v2);
}));
}));
}

@Test
public void testBinaryEncodePgSQLXMLArray(TestContext ctx) {
PgSQLXML first = new PgSQLXML("<message><to><be><validated></validated></be></to></message>");
PgSQLXML second = new PgSQLXML("<message><to><be><validated><again></again></validated></be></to></message>");


PgConnection.connect(vertx, options, ctx.asyncAssertSuccess(conn -> {
conn.preparedQuery("SELECT ($1::xml[])::VARCHAR[]").execute(Tuple.of(
new PgSQLXML[]{
new PgSQLXML("<message><to><be><validated></validated></be></to></message>"),
new PgSQLXML("<message><to><be><validated><again></again></validated></be></to></message>")}
),
ctx.asyncAssertSuccess(rows -> {
ctx.assertEquals(1, rows.size());
Row row = rows.iterator().next();
String[] array = row.getArrayOfStrings(0);
String v1 = array[0];
String v2 = array[1];
ctx.assertEquals(first.getXmlData(), v1);
ctx.assertEquals(second.getXmlData(), v2);
}));
}));
}
}

0 comments on commit fd24b1a

Please sign in to comment.