package io.vertx.pgclient.impl;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.DecoderException;
import io.vertx.pgclient.impl.codec.PgCodec;
import io.vertx.sqlclient.impl.Connection;
import io.vertx.sqlclient.impl.SocketConnectionBase;
import io.vertx.sqlclient.impl.command.CommandResponse;
import io.vertx.sqlclient.impl.command.InitCommand;
import io.vertx.core.*;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.impl.NetSocketInternal;
import java.util.Map;
public class PgSocketConnection extends SocketConnectionBase {
private PgCodec codec;
public int processId;
public int secretKey;
public PgSocketConnection(NetSocketInternal socket,
boolean cachePreparedStatements,
int preparedStatementCacheSize,
int preparedStatementCacheSqlLimit,
int pipeliningLimit,
Context context) {
super(socket, cachePreparedStatements, preparedStatementCacheSize, preparedStatementCacheSqlLimit, pipeliningLimit, context);
}
@Override
public void init() {
codec = new PgCodec();
ChannelPipeline pipeline = socket.channelHandlerContext().pipeline();
pipeline.addBefore("handler", "codec", codec);
super.init();
}
public void sendStartupMessage(String username, String password, String database, Map<String, String> properties, Handler<? super CommandResponse<Connection>> completionHandler) {
InitCommand cmd = new InitCommand(this, username, password, database, properties);
cmd.handler = completionHandler;
schedule(cmd);
}
void sendCancelRequestMessage(int processId, int secretKey, Handler<AsyncResult<Void>> handler) {
Buffer buffer = Buffer.buffer(16);
buffer.appendInt(16);
buffer.appendInt(80877102);
buffer.appendInt(processId);
buffer.appendInt(secretKey);
socket.write(buffer, ar -> {
if (ar.succeeded()) {
if (status == Status.CONNECTED) {
status = Status.CLOSING;
socket.close();
}
handler.handle(Future.succeededFuture());
} else {
handler.handle(Future.failedFuture(ar.cause()));
}
});
}
@Override
public int getProcessId() {
return processId;
}
@Override
public int getSecretKey() {
return secretKey;
}
void upgradeToSSLConnection(Handler<AsyncResult<Void>> completionHandler) {
ChannelPipeline pipeline = socket.channelHandlerContext().pipeline();
Promise<Void> upgradePromise = Promise.promise();
upgradePromise.future().setHandler(ar->{
if (ar.succeeded()) {
completionHandler.handle(Future.succeededFuture());
} else {
Throwable cause = ar.cause();
if (cause instanceof DecoderException) {
DecoderException err = (DecoderException) cause;
cause = err.getCause();
}
completionHandler.handle(Future.failedFuture(cause));
}
});
pipeline.addBefore("handler", "initiate-ssl-handler", new InitiateSslHandler(this, upgradePromise));
}
}