Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Postgres resultset metadata and column metadata support #513

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions vertx-pg-client/src/main/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,13 @@ You can fetch generated keys with a 'RETURNING' clause in your query:
{@link examples.PgClientExamples#returning(io.vertx.sqlclient.SqlClient)}
----

You may also want to get the column metadata of the resultset such as the field data type oid or the data type length:

[source,$lang]
----
{@link examples.PgClientExamples#resultsetMetadata(io.vertx.sqlclient.SqlClient)}
----

include::connections.adoc[]

include::transactions.adoc[]
Expand Down
19 changes: 19 additions & 0 deletions vertx-pg-client/src/main/java/examples/PgClientExamples.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import io.vertx.docgen.Source;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collector;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -591,4 +592,22 @@ public void returning(SqlClient client) {
}
});
}

public void resultsetMetadata(SqlClient client) {
client.query("SELECT id, name from users", ar -> {
if (ar.succeeded()) {
RowSet<Row> rows = ar.result();
PgResultSetMetadata pgResultSetMetadata = rows.property(PgClient.RESULTSET_METADATA);
List<PgColumnMetadata> columnMetadataList = pgResultSetMetadata.columnMetadataList();
for (PgColumnMetadata pgColumnMetadata : columnMetadataList) {
System.out.println("Field name: " + pgColumnMetadata.name());
System.out.println("Field data type OID: " + pgColumnMetadata.dataTypeOID());
System.out.println("Field data type length: " + pgColumnMetadata.typeLength());
System.out.println("Field format code: " + pgColumnMetadata.formatCode());
}
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
});
}
}
15 changes: 15 additions & 0 deletions vertx-pg-client/src/main/java/io/vertx/pgclient/PgClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package io.vertx.pgclient;

import io.vertx.codegen.annotations.VertxGen;
import io.vertx.sqlclient.PropertyKind;

/**
* An interface to define Postgres specific constants or behaviors.
*/
@VertxGen
public interface PgClient {
/**
* SqlResult Property for Postgres ResultSet metadata.
*/
PropertyKind<PgResultSetMetadata> RESULTSET_METADATA = () -> PgResultSetMetadata.class;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package io.vertx.pgclient;

import io.vertx.codegen.annotations.VertxGen;

/**
* An object which can be used to describe the metadata of columns in Postgres:
*
* <ul>
* <li>column name</li>
* <li>table OID</li>
* <li>column attribute number</li>
* <li>data type OID</li>
* <li>type length</li>
* <li>type modifier</li>
* <li>format code</li>
* </ul>
*/
@VertxGen
public interface PgColumnMetadata {

/**
* Get the field name.
*
* @return the name
*/
String name();

/**
* If the field can be identified as a column of a specific table, the object ID of the table; otherwise zero.
*
* @return the table OID
*/
int tableOID();

/**
* If the field can be identified as a column of a specific table, the attribute number of the column; otherwise zero.
*
* @return the column attribute number
*/
short columnAttributeNumber();

/**
* Get the object ID (see pg_type.oid) of the field's data type.
*
* @return the OID
*/
int dataTypeOID();

/**
* Get the data type size (see pg_type.typlen). Note that negative values denote variable-width types.
*
* @return the length
*/
short typeLength();

/**
* Get the type modifier (see pg_attribute.atttypmod). The meaning of the modifier is type-specific.
*
* @return the type modifier
*/
int typeModifier();

/**
* The format code being used for the field. Currently will be zero (text) or one (binary).
*
* @return the format code
*/
short formatCode();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.vertx.pgclient;

import io.vertx.codegen.annotations.VertxGen;

import java.util.List;

/**
* An object that can be used to represent metadata of the Postgres ResultSet which includes
* metadata information of all the fields.
*/
@VertxGen
public interface PgResultSetMetadata {

/**
* get all the {@link PgColumnMetadata} in this resultset.
*
* @return the column metadata list
*/
List<PgColumnMetadata> columnMetadataList();
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

package io.vertx.pgclient.impl.codec;

import io.vertx.pgclient.impl.datatype.DataType;

/**
* @author <a href="mailto:emad.albloushi@gmail.com">Emad Alblueshi</a>
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@

package io.vertx.pgclient.impl.codec;

import io.vertx.pgclient.PgColumnMetadata;
import io.vertx.pgclient.impl.datatype.DataType;

/**
* @author <a href="mailto:emad.albloushi@gmail.com">Emad Alblueshi</a>
*/

class PgColumnDesc {
class PgColumnDesc implements PgColumnMetadata {

final String name;
final int relationId;
Expand All @@ -40,4 +43,39 @@ class PgColumnDesc {
this.relationAttributeNo = relationAttributeNo;
this.typeModifier = typeModifier;
}

@Override
public String name() {
return name;
}

@Override
public int tableOID() {
return relationId;
}

@Override
public short columnAttributeNumber() {
return relationAttributeNo;
}

@Override
public int dataTypeOID() {
return dataType.id;
}

@Override
public short typeLength() {
return length;
}

@Override
public int typeModifier() {
return typeModifier;
}

@Override
public short formatCode() {
return (short) dataFormat.id;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import io.netty.buffer.CompositeByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.vertx.pgclient.impl.datatype.DataType;
import io.vertx.sqlclient.impl.Notification;
import io.vertx.pgclient.impl.util.Util;
import io.netty.buffer.ByteBuf;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise;
import io.vertx.pgclient.impl.datatype.DataType;
import io.vertx.pgclient.impl.datatype.DataTypeCodec;
import io.vertx.sqlclient.Tuple;
import io.vertx.pgclient.impl.util.Util;
import io.vertx.sqlclient.impl.ParamDesc;
Expand Down Expand Up @@ -233,7 +235,7 @@ void writeScramClientFinalMessage(ScramClientFinalMessage msg) {
int totalLengthPosition = out.writerIndex();
out.writeInt(0); // message length -> will be set later
out.writeCharSequence(msg.message, UTF_8);

// rewind to set the message length
out.setInt(totalLengthPosition, out.writerIndex() - totalLengthPosition);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,13 @@
*/
package io.vertx.pgclient.impl.codec;

import io.vertx.sqlclient.Tuple;
import io.vertx.pgclient.impl.datatype.DataType;
import io.vertx.pgclient.impl.datatype.DataTypeCodec;
import io.vertx.sqlclient.impl.ErrorMessageFactory;
import io.vertx.sqlclient.impl.ParamDesc;
import io.vertx.pgclient.impl.util.Util;
import io.vertx.sqlclient.impl.TupleInternal;

import java.util.Arrays;
import java.util.stream.Stream;

/**
* @author <a href="mailto:emad.albloushi@gmail.com">Emad Alblueshi</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@
*/
package io.vertx.pgclient.impl.codec;

import io.vertx.pgclient.PgColumnMetadata;
import io.vertx.pgclient.PgResultSetMetadata;
import io.vertx.sqlclient.impl.RowDesc;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

class PgRowDesc extends RowDesc {
class PgRowDesc extends RowDesc implements PgResultSetMetadata {

final PgColumnDesc[] columns;

Expand All @@ -32,4 +36,9 @@ class PgRowDesc extends RowDesc {
.collect(Collectors.toList())));
this.columns = columns;
}

@Override
public List<PgColumnMetadata> columnMetadataList() {
return Arrays.asList(columns);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
*/
package io.vertx.pgclient.impl.codec;

import io.vertx.pgclient.PgClient;
import io.vertx.sqlclient.Row;
import io.vertx.sqlclient.impl.RowDesc;
import io.vertx.sqlclient.impl.command.QueryCommandBase;

import java.util.stream.Collector;
Expand All @@ -36,7 +36,7 @@ public void handleCommandComplete(int updated) {
T result;
Throwable failure;
int size;
RowDesc desc;
PgRowDesc desc;
if (decoder != null) {
failure = decoder.complete();
result = decoder.result();
Expand All @@ -50,6 +50,7 @@ public void handleCommandComplete(int updated) {
desc = null;
}
cmd.resultHandler().handleResult(updated, size, desc, result, failure);
cmd.resultHandler().addProperty(PgClient.RESULTSET_METADATA, desc);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package io.vertx.pgclient.impl.codec;

import io.vertx.pgclient.impl.datatype.DataTypeCodec;
import io.vertx.sqlclient.Row;
import io.vertx.pgclient.impl.RowImpl;
import io.netty.buffer.ByteBuf;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*
*/
package io.vertx.pgclient.impl.codec;
package io.vertx.pgclient.impl.datatype;

import io.netty.util.collection.IntObjectHashMap;
import io.netty.util.collection.IntObjectMap;
Expand All @@ -40,7 +40,7 @@
*
* @author <a href="mailto:emad.albloushi@gmail.com">Emad Alblueshi</a>
*/
enum DataType {
public enum DataType {

BOOL(16, true, Boolean.class),
BOOL_ARRAY(1000, true, Boolean[].class),
Expand Down Expand Up @@ -124,10 +124,10 @@ enum DataType {

private static final Logger logger = LoggerFactory.getLogger(DataType.class);

final int id;
final boolean supportsBinary;
final Class<?> encodingType; // Not really used for now
final Class<?> decodingType;
public final int id;
public final boolean supportsBinary;
public final Class<?> encodingType; // Not really used for now
public final Class<?> decodingType;

DataType(int id, boolean supportsBinary, Class<?> type) {
this.id = id;
Expand All @@ -143,7 +143,7 @@ enum DataType {
this.decodingType = decodingType;
}

static DataType valueOf(int oid) {
public static DataType valueOf(int oid) {
DataType value = oidToDataType.get(oid);
if (value == null) {
logger.debug("Postgres type OID=" + oid + " not handled - using unknown type instead");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*
*/

package io.vertx.pgclient.impl.codec;
package io.vertx.pgclient.impl.datatype;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
Expand Down Expand Up @@ -52,7 +52,7 @@
* @author <a href="mailto:julien@julienviet.com">Julien Viet</a>
* @author <a href="mailto:emad.albloushi@gmail.com">Emad Alblueshi</a>
*/
class DataTypeCodec {
public class DataTypeCodec {

private static final Logger logger = LoggerFactory.getLogger(DataTypeCodec.class);

Expand Down Expand Up @@ -130,7 +130,7 @@ class DataTypeCodec {
.appendOffset("+HH:mm", "00:00")
.toFormatter();

static void encodeText(DataType id, Object value, ByteBuf buff) {
public static void encodeText(DataType id, Object value, ByteBuf buff) {
int index = buff.writerIndex();
buff.writeInt(0);
textEncode(id, value, buff);
Expand Down