package io.vertx.sqlclient.impl;
import io.vertx.sqlclient.SqlConnection;
import io.vertx.sqlclient.impl.command.CommandResponse;
import io.vertx.sqlclient.impl.command.CommandBase;
import io.vertx.sqlclient.Transaction;
import io.vertx.core.*;
public abstract class SqlConnectionImpl<C extends SqlConnectionImpl> extends SqlConnectionBase<C> implements SqlConnection, Connection.Holder {
private volatile Handler<Throwable> exceptionHandler;
private volatile Handler<Void> closeHandler;
private TransactionImpl tx;
public SqlConnectionImpl(Context context, Connection conn) {
super(context, conn);
}
@Override
public void handleClosed() {
Handler<Void> handler = closeHandler;
if (handler != null) {
context.runOnContext(handler);
}
}
@Override
public <R> void schedule(CommandBase<R> cmd, Handler<? super CommandResponse<R>> handler) {
cmd.handler = cr -> {
cr.scheduler = this;
handler.handle(cr);
};
schedule(cmd);
}
protected void schedule(CommandBase<?> cmd) {
if (context == Vertx.currentContext()) {
if (tx != null) {
tx.schedule(cmd);
} else {
conn.schedule(cmd);
}
} else {
context.runOnContext(v -> {
schedule(cmd);
});
}
}
@Override
public void handleException(Throwable err) {
Handler<Throwable> handler = exceptionHandler;
if (handler != null) {
context.runOnContext(v -> {
handler.handle(err);
});
} else {
err.printStackTrace();
}
}
@Override
public boolean isSSL() {
return conn.isSsl();
}
@Override
public C closeHandler(Handler<Void> handler) {
closeHandler = handler;
return (C) this;
}
@Override
public C exceptionHandler(Handler<Throwable> handler) {
exceptionHandler = handler;
return (C) this;
}
@Override
public Transaction begin() {
return begin(false);
}
public Transaction begin(boolean closeOnEnd) {
if (tx != null) {
throw new IllegalStateException();
}
tx = new TransactionImpl(context, conn, v -> {
tx = null;
if (closeOnEnd) {
close();
}
});
return tx;
}
public abstract void handleNotification(int processId, String channel, String payload);
@Override
public void close() {
if (context == Vertx.currentContext()) {
if (tx != null) {
tx.rollback(ar -> conn.close(this));
tx = null;
} else {
conn.close(this);
}
} else {
context.runOnContext(v -> close());
}
}
}