diff --git a/pom.xml b/pom.xml index 28f04de4cf..2499abce48 100644 --- a/pom.xml +++ b/pom.xml @@ -65,6 +65,13 @@ pom import + + + + io.vertx + vertx-sql-client-codec + ${project.version} + @@ -184,6 +191,7 @@ vertx-sql-client + vertx-sql-client-codec vertx-pg-client vertx-mysql-client vertx-mssql-client @@ -199,6 +207,7 @@ vertx-sql-client + vertx-sql-client-codec vertx-pg-client @@ -209,6 +218,7 @@ vertx-sql-client + vertx-sql-client-codec vertx-pg-client @@ -219,6 +229,7 @@ vertx-sql-client + vertx-sql-client-codec vertx-pg-client @@ -230,6 +241,7 @@ vertx-sql-client + vertx-sql-client-codec vertx-mysql-client @@ -241,6 +253,7 @@ vertx-sql-client + vertx-sql-client-codec vertx-mysql-client @@ -252,6 +265,7 @@ vertx-sql-client + vertx-sql-client-codec vertx-mysql-client @@ -263,6 +277,7 @@ vertx-sql-client + vertx-sql-client-codec vertx-mysql-client @@ -273,6 +288,7 @@ vertx-sql-client + vertx-sql-client-codec vertx-mssql-client @@ -283,6 +299,7 @@ vertx-sql-client + vertx-sql-client-codec vertx-mssql-client @@ -290,6 +307,7 @@ DB2-11.5 vertx-sql-client + vertx-sql-client-codec vertx-db2-client @@ -297,6 +315,7 @@ SQL-templates vertx-sql-client + vertx-sql-client-codec vertx-pg-client vertx-mysql-client vertx-sql-client-templates @@ -309,9 +328,10 @@ vertx-sql-client + vertx-sql-client-codec vertx-oracle-client - \ No newline at end of file + diff --git a/vertx-db2-client/pom.xml b/vertx-db2-client/pom.xml index b33bf5cb2a..3486c5d962 100644 --- a/vertx-db2-client/pom.xml +++ b/vertx-db2-client/pom.xml @@ -47,6 +47,10 @@ io.vertx vertx-sql-client + + io.vertx + vertx-sql-client-codec + diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2ConnectionFactory.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2ConnectionFactory.java index 6ca28d8803..ea2b52ea82 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2ConnectionFactory.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2ConnectionFactory.java @@ -26,8 +26,7 @@ import io.vertx.core.spi.metrics.ClientMetrics; import io.vertx.core.spi.metrics.VertxMetrics; import io.vertx.db2client.DB2ConnectOptions; -import io.vertx.sqlclient.SqlConnection; -import io.vertx.sqlclient.internal.Connection; +import io.vertx.sqlclient.spi.connection.Connection; import io.vertx.sqlclient.impl.ConnectionFactoryBase; import java.util.Map; @@ -65,15 +64,10 @@ protected Future doConnectInternal(DB2ConnectOptions options, Contex } @Override - public Future connect(Context context, DB2ConnectOptions options) { + public Future connect(Context context, DB2ConnectOptions options) { ContextInternal contextInternal = (ContextInternal) context; - Promise promise = contextInternal.promise(); - connect(asEventLoopContext(contextInternal), options) - .map(conn -> { - DB2ConnectionImpl db2Connection = new DB2ConnectionImpl(contextInternal, this, conn); - conn.init(db2Connection); - return (SqlConnection)db2Connection; - }).onComplete(promise); + Promise promise = contextInternal.promise(); + connect(asEventLoopContext(contextInternal), options).onComplete(promise); return promise.future(); } } diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2ConnectionImpl.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2ConnectionImpl.java index 8bdb1280ee..57d1de0a95 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2ConnectionImpl.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2ConnectionImpl.java @@ -23,9 +23,9 @@ import io.vertx.db2client.DB2Connection; import io.vertx.db2client.impl.command.PingCommand; import io.vertx.db2client.spi.DB2Driver; -import io.vertx.sqlclient.internal.Connection; +import io.vertx.sqlclient.spi.connection.Connection; import io.vertx.sqlclient.internal.SqlConnectionBase; -import io.vertx.sqlclient.spi.ConnectionFactory; +import io.vertx.sqlclient.spi.connection.ConnectionFactory; public class DB2ConnectionImpl extends SqlConnectionBase implements DB2Connection { @@ -37,7 +37,12 @@ public static Future connect(Vertx vertx, DB2ConnectOptions optio } catch (Exception e) { return ctx.failedFuture(e); } - return prepareForClose(ctx, client.connect((Context)ctx, options)).map(DB2Connection::cast); + return client.connect((Context)ctx, options).map(conn -> { + DB2ConnectionImpl impl = new DB2ConnectionImpl(ctx, client, conn); + conn.init(impl); + prepareForClose(ctx, impl); + return impl; + }); } public DB2ConnectionImpl(ContextInternal context, ConnectionFactory factory, Connection conn) { diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2RowImpl.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2Row.java similarity index 89% rename from vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2RowImpl.java rename to vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2Row.java index a575ed1a58..1fe95c3b79 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2RowImpl.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2Row.java @@ -23,22 +23,18 @@ import java.time.OffsetDateTime; import java.time.OffsetTime; import java.time.temporal.Temporal; -import java.util.List; import java.util.UUID; import io.vertx.core.buffer.Buffer; import io.vertx.db2client.impl.drda.DB2RowId; import io.vertx.sqlclient.data.Numeric; import io.vertx.sqlclient.impl.RowBase; -import io.vertx.sqlclient.internal.RowDesc; +import io.vertx.sqlclient.internal.RowDescriptorBase; -public class DB2RowImpl extends RowBase { +public class DB2Row extends RowBase { - private final RowDesc rowDesc; - - public DB2RowImpl(RowDesc rowDesc) { - super(rowDesc.columnNames().size()); - this.rowDesc = rowDesc; + public DB2Row(RowDescriptorBase rowDescriptor) { + super(rowDescriptor); } @Override @@ -82,23 +78,14 @@ public T get(Class type, int position) { } } - @Override - public String getColumnName(int pos) { - List columnNames = rowDesc.columnNames(); - return pos < 0 || columnNames.size() - 1 < pos ? null : columnNames.get(pos); - } - @Override public int getColumnIndex(String name) { - if (name == null) { - throw new NullPointerException(); - } - int idx = rowDesc.columnIndex(name); + int idx = super.getColumnIndex(name); if (idx >= 0) { return idx; } // Unless the column is renamed in the SQL query, the column name will be uppercase - return rowDesc.columnIndex(name.toUpperCase()); + return super.getColumnIndex(name.toUpperCase()); } @Override diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2SocketConnection.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2SocketConnection.java index b79c3a0e0b..3b47291838 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2SocketConnection.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/DB2SocketConnection.java @@ -16,7 +16,6 @@ package io.vertx.db2client.impl; import io.netty.channel.ChannelPipeline; -import io.vertx.core.AsyncResult; import io.vertx.core.Completable; import io.vertx.core.Handler; import io.vertx.core.Promise; @@ -24,15 +23,24 @@ import io.vertx.core.internal.net.NetSocketInternal; import io.vertx.core.spi.metrics.ClientMetrics; import io.vertx.db2client.DB2ConnectOptions; +import io.vertx.db2client.impl.codec.CommandCodec; import io.vertx.db2client.impl.codec.DB2Codec; +import io.vertx.db2client.impl.codec.DB2PreparedStatement; +import io.vertx.db2client.impl.codec.ExtendedBatchQueryCommandCodec; +import io.vertx.db2client.impl.codec.ExtendedQueryCommandCodec; import io.vertx.db2client.impl.command.InitialHandshakeCommand; import io.vertx.db2client.impl.drda.ConnectionMetaData; import io.vertx.sqlclient.SqlConnectOptions; -import io.vertx.sqlclient.internal.Connection; +import io.vertx.sqlclient.codec.CommandMessage; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.internal.PreparedStatement; import io.vertx.sqlclient.internal.QueryResultHandler; -import io.vertx.sqlclient.impl.SocketConnectionBase; -import io.vertx.sqlclient.internal.command.*; +import io.vertx.sqlclient.codec.SocketConnectionBase; import io.vertx.sqlclient.spi.DatabaseMetadata; +import io.vertx.sqlclient.spi.protocol.CommandBase; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; +import io.vertx.sqlclient.spi.protocol.SimpleQueryCommand; +import io.vertx.sqlclient.spi.protocol.TxCommand; import java.util.Map; import java.util.function.Predicate; @@ -79,19 +87,32 @@ public void init() { super.init(); } + @Override + protected CommandMessage toMessage(ExtendedQueryCommand command, PreparedStatement preparedStatement) { + if (command.isBatch()) { + return new ExtendedBatchQueryCommandCodec<>(command, (DB2PreparedStatement) preparedStatement); + } else { + return new ExtendedQueryCommandCodec(command, (DB2PreparedStatement) preparedStatement); + } + } + + @Override + protected CommandMessage toMessage(CommandBase command) { + return CommandCodec.wrap(command); + } + @Override protected void doSchedule(CommandBase cmd, Completable handler) { if (cmd instanceof TxCommand) { TxCommand txCmd = (TxCommand) cmd; - if (txCmd.kind == TxCommand.Kind.BEGIN) { + if (txCmd.kind() == TxCommand.Kind.BEGIN) { // DB2 always implicitly starts a transaction with each query, and does // not support the 'BEGIN' keyword. Instead we can no-op BEGIN commands - cmd.handler = handler; - cmd.complete(CommandResponse.success(txCmd.result).toAsyncResult()); + handler.succeed(txCmd.result()); } else { - SimpleQueryCommand cmd2 = new SimpleQueryCommand<>(txCmd.kind.sql, false, false, - QueryCommandBase.NULL_COLLECTOR, QueryResultHandler.NOOP_HANDLER); - super.doSchedule(cmd2, (res, err) -> handler.complete(txCmd.result, err)); + SimpleQueryCommand cmd2 = new SimpleQueryCommand<>(txCmd.kind().sql(), false, false, + SocketConnectionBase.NULL_COLLECTOR, QueryResultHandler.NOOP_HANDLER); + super.doSchedule(cmd2, (res, err) -> handler.complete(txCmd.result(), err)); } } else { @@ -111,7 +132,7 @@ public String system() { } @Override - public DatabaseMetadata getDatabaseMetaData() { + public DatabaseMetadata databaseMetadata() { return connMetadata.getDbMetadata(); } diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/CloseConnectionCommandCodec.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/CloseConnectionCommandCodec.java index cf2d04d7fc..11bef520da 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/CloseConnectionCommandCodec.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/CloseConnectionCommandCodec.java @@ -18,7 +18,7 @@ import io.netty.buffer.ByteBuf; import io.vertx.db2client.impl.drda.DRDAQueryRequest; import io.vertx.db2client.impl.drda.DRDAQueryResponse; -import io.vertx.sqlclient.internal.command.CloseConnectionCommand; +import io.vertx.sqlclient.spi.protocol.CloseConnectionCommand; class CloseConnectionCommandCodec extends CommandCodec { diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/CloseCursorCommandCodec.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/CloseCursorCommandCodec.java index fedb4a2055..184d859362 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/CloseCursorCommandCodec.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/CloseCursorCommandCodec.java @@ -21,8 +21,8 @@ import io.vertx.db2client.impl.codec.DB2PreparedStatement.QueryInstance; import io.vertx.db2client.impl.drda.DRDAQueryRequest; import io.vertx.db2client.impl.drda.DRDAQueryResponse; -import io.vertx.sqlclient.internal.command.CloseCursorCommand; -import io.vertx.sqlclient.internal.command.CommandResponse; +import io.vertx.sqlclient.spi.protocol.CloseCursorCommand; +import io.vertx.sqlclient.codec.CommandResponse; class CloseCursorCommandCodec extends CommandCodec { diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/CloseStatementCommandCodec.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/CloseStatementCommandCodec.java index f7934c96e3..199dd7bde8 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/CloseStatementCommandCodec.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/CloseStatementCommandCodec.java @@ -16,8 +16,8 @@ package io.vertx.db2client.impl.codec; import io.netty.buffer.ByteBuf; -import io.vertx.sqlclient.internal.command.CloseStatementCommand; -import io.vertx.sqlclient.internal.command.CommandResponse; +import io.vertx.sqlclient.spi.protocol.CloseStatementCommand; +import io.vertx.sqlclient.codec.CommandResponse; class CloseStatementCommandCodec extends CommandCodec { diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/CommandCodec.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/CommandCodec.java index 343a0a08ae..b966a6115d 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/CommandCodec.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/CommandCodec.java @@ -17,19 +17,65 @@ import io.netty.buffer.ByteBuf; import io.vertx.core.Handler; -import io.vertx.sqlclient.internal.command.CommandBase; -import io.vertx.sqlclient.internal.command.CommandResponse; +import io.vertx.db2client.impl.command.InitialHandshakeCommand; +import io.vertx.db2client.impl.command.PingCommand; +import io.vertx.sqlclient.codec.CommandMessage; +import io.vertx.sqlclient.spi.protocol.CloseConnectionCommand; +import io.vertx.sqlclient.spi.protocol.CloseCursorCommand; +import io.vertx.sqlclient.spi.protocol.CloseStatementCommand; +import io.vertx.sqlclient.spi.protocol.CommandBase; +import io.vertx.sqlclient.codec.CommandResponse; +import io.vertx.sqlclient.spi.protocol.PrepareStatementCommand; +import io.vertx.sqlclient.spi.protocol.SimpleQueryCommand; -abstract class CommandCodec> { +public abstract class CommandCodec> extends CommandMessage { Handler> completionHandler; public Throwable failure; public R result; - final C cmd; DB2Encoder encoder; CommandCodec(C cmd) { - this.cmd = cmd; + super(cmd); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static CommandCodec wrap(CommandBase cmd) { + CommandCodec codec = null; + if (cmd instanceof InitialHandshakeCommand) { + codec = new InitialHandshakeCommandCodec((InitialHandshakeCommand) cmd); + } else if (cmd instanceof SimpleQueryCommand) { + codec = new SimpleQueryCommandCodec((SimpleQueryCommand) cmd); + } else if (cmd instanceof CloseConnectionCommand) { + codec = new CloseConnectionCommandCodec((CloseConnectionCommand) cmd); + } else if (cmd instanceof PrepareStatementCommand) { + codec = new PrepareStatementCodec((PrepareStatementCommand) cmd); + } else if (cmd instanceof CloseStatementCommand) { + codec = new CloseStatementCommandCodec((CloseStatementCommand) cmd); + } else if (cmd instanceof CloseCursorCommand) { + codec = new CloseCursorCommandCodec((CloseCursorCommand) cmd); + } else if (cmd instanceof PingCommand) { + codec = new PingCommandCodec((PingCommand) cmd); +// } else if (cmd instanceof InitDbCommand) { +// codec = new InitDbCommandCodec((InitDbCommand) cmd); + // } else if (cmd instanceof StatisticsCommand) { + // codec = new StatisticsCommandCodec((StatisticsCommand) cmd); + // } else if (cmd instanceof SetOptionCommand) { + // codec = new SetOptionCommandCodec((SetOptionCommand) cmd); + // } else if (cmd instanceof ResetConnectionCommand) { + // codec = new ResetConnectionCommandCodec((ResetConnectionCommand) cmd); + // } else if (cmd instanceof DebugCommand) { + // codec = new DebugCommandCodec((DebugCommand) cmd); + // } else if (cmd instanceof ChangeUserCommand) { + // codec = new ChangeUserCommandCodec((ChangeUserCommand) cmd); + } else { + UnsupportedOperationException uoe = new UnsupportedOperationException("Unsupported command type: " + cmd); + DB2Encoder.LOG.error(uoe); + throw uoe; + } + if (DB2Encoder.LOG.isDebugEnabled()) + DB2Encoder.LOG.debug(">>> ENCODE " + codec); + return codec; } abstract void decodePayload(ByteBuf payload, int payloadLength); diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2Codec.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2Codec.java index 29d592226b..6891d21143 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2Codec.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2Codec.java @@ -43,7 +43,7 @@ public void channelInactive(ChannelHandlerContext ctx) throws Exception { private void clearInflightCommands(Throwable failure) { for (CommandCodec commandCodec : inflight) { - commandCodec.cmd.fail(failure); + commandCodec.fail(failure); } } } diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2Decoder.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2Decoder.java index 1266e65c8e..39c81a9f16 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2Decoder.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2Decoder.java @@ -25,7 +25,7 @@ import io.vertx.core.internal.logging.Logger; import io.vertx.core.internal.logging.LoggerFactory; import io.vertx.db2client.DB2Exception; -import io.vertx.sqlclient.internal.command.CommandResponse; +import io.vertx.sqlclient.codec.CommandResponse; class DB2Decoder extends ByteToMessageDecoder { diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2Encoder.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2Encoder.java index 6ebd0a00c1..0778f926dd 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2Encoder.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2Encoder.java @@ -20,23 +20,15 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelPromise; +import io.vertx.core.Completable; import io.vertx.core.internal.logging.Logger; import io.vertx.core.internal.logging.LoggerFactory; import io.vertx.db2client.impl.DB2SocketConnection; -import io.vertx.db2client.impl.command.InitialHandshakeCommand; -import io.vertx.db2client.impl.command.PingCommand; -import io.vertx.sqlclient.internal.command.CloseConnectionCommand; -import io.vertx.sqlclient.internal.command.CloseCursorCommand; -import io.vertx.sqlclient.internal.command.CloseStatementCommand; -import io.vertx.sqlclient.internal.command.CommandBase; -import io.vertx.sqlclient.internal.command.CommandResponse; -import io.vertx.sqlclient.internal.command.ExtendedQueryCommand; -import io.vertx.sqlclient.internal.command.PrepareStatementCommand; -import io.vertx.sqlclient.internal.command.SimpleQueryCommand; +import io.vertx.sqlclient.codec.CommandResponse; class DB2Encoder extends ChannelOutboundHandlerAdapter { - private static final Logger LOG = LoggerFactory.getLogger(DB2Encoder.class); + public static final Logger LOG = LoggerFactory.getLogger(DB2Encoder.class); private final ArrayDeque> inflight; ChannelHandlerContext chctx; @@ -55,8 +47,8 @@ public void handlerAdded(ChannelHandlerContext ctx) { @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - if (msg instanceof CommandBase) { - CommandBase cmd = (CommandBase) msg; + if (msg instanceof CommandCodec) { + CommandCodec cmd = (CommandCodec) msg; write(cmd); } else { super.write(ctx, msg, promise); @@ -64,66 +56,18 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) } @SuppressWarnings({ "unchecked", "rawtypes" }) - void write(CommandBase cmd) { - CommandCodec codec = wrap(cmd); - codec.completionHandler = resp -> { + void write(CommandCodec msg) { + msg.completionHandler = resp -> { CommandCodec c = inflight.poll(); - resp.cmd = (CommandBase) c.cmd; + resp.handler = (Completable) c.handler; chctx.fireChannelRead(resp); }; - inflight.add(codec); + inflight.add(msg); try { - codec.encode(this); + msg.encode(this); } catch (Throwable e) { - LOG.error("FATAL: Unable to encode command: " + cmd, e); - codec.completionHandler.handle(CommandResponse.failure(e)); + LOG.error("FATAL: Unable to encode command: " + msg, e); + msg.completionHandler.handle(CommandResponse.failure(e)); } } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private CommandCodec wrap(CommandBase cmd) { - CommandCodec codec = null; - if (cmd instanceof InitialHandshakeCommand) { - codec = new InitialHandshakeCommandCodec((InitialHandshakeCommand) cmd); - } else if (cmd instanceof SimpleQueryCommand) { - codec = new SimpleQueryCommandCodec((SimpleQueryCommand) cmd); - } else if (cmd instanceof ExtendedQueryCommand) { - ExtendedQueryCommand queryCmd = (ExtendedQueryCommand) cmd; - if (queryCmd.isBatch()) { - codec = new ExtendedBatchQueryCommandCodec<>(queryCmd); - } else { - codec = new ExtendedQueryCommandCodec(queryCmd); - } - } else if (cmd instanceof CloseConnectionCommand) { - codec = new CloseConnectionCommandCodec((CloseConnectionCommand) cmd); - } else if (cmd instanceof PrepareStatementCommand) { - codec = new PrepareStatementCodec((PrepareStatementCommand) cmd); - } else if (cmd instanceof CloseStatementCommand) { - codec = new CloseStatementCommandCodec((CloseStatementCommand) cmd); - } else if (cmd instanceof CloseCursorCommand) { - codec = new CloseCursorCommandCodec((CloseCursorCommand) cmd); - } else if (cmd instanceof PingCommand) { - codec = new PingCommandCodec((PingCommand) cmd); -// } else if (cmd instanceof InitDbCommand) { -// codec = new InitDbCommandCodec((InitDbCommand) cmd); - // } else if (cmd instanceof StatisticsCommand) { - // codec = new StatisticsCommandCodec((StatisticsCommand) cmd); - // } else if (cmd instanceof SetOptionCommand) { - // codec = new SetOptionCommandCodec((SetOptionCommand) cmd); - // } else if (cmd instanceof ResetConnectionCommand) { - // codec = new ResetConnectionCommandCodec((ResetConnectionCommand) cmd); - // } else if (cmd instanceof DebugCommand) { - // codec = new DebugCommandCodec((DebugCommand) cmd); - // } else if (cmd instanceof ChangeUserCommand) { - // codec = new ChangeUserCommandCodec((ChangeUserCommand) cmd); - } else { - UnsupportedOperationException uoe = new UnsupportedOperationException("Unsupported command type: " + cmd); - LOG.error(uoe); - throw uoe; - } - if (LOG.isDebugEnabled()) - LOG.debug(">>> ENCODE " + codec); - return codec; - } - } diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2ParamDesc.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2ParamDesc.java index 06269430e9..9d558ce2c3 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2ParamDesc.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2ParamDesc.java @@ -21,10 +21,9 @@ import io.vertx.db2client.impl.drda.ColumnMetaData; import io.vertx.sqlclient.data.Numeric; import io.vertx.sqlclient.impl.ErrorMessageFactory; -import io.vertx.sqlclient.internal.ParamDesc; -import io.vertx.sqlclient.internal.TupleInternal; +import io.vertx.sqlclient.internal.TupleBase; -class DB2ParamDesc extends ParamDesc { +class DB2ParamDesc { private final ColumnMetaData paramDefinitions; @@ -36,7 +35,7 @@ ColumnMetaData paramDefinitions() { return paramDefinitions; } - public TupleInternal prepare(TupleInternal values) { + public TupleBase prepare(TupleBase values) { if (values.size() != paramDefinitions.columns_) { throw new VertxException(ErrorMessageFactory.buildWhenArgumentsLengthNotMatched(paramDefinitions.columns_, values.size()), true); } diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2PreparedStatement.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2PreparedStatement.java index f70ba58e4a..86854c9614 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2PreparedStatement.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2PreparedStatement.java @@ -23,18 +23,17 @@ import io.vertx.core.internal.logging.LoggerFactory; import io.vertx.db2client.impl.drda.Cursor; import io.vertx.db2client.impl.drda.Section; -import io.vertx.sqlclient.internal.ParamDesc; import io.vertx.sqlclient.internal.PreparedStatement; -import io.vertx.sqlclient.internal.RowDesc; -import io.vertx.sqlclient.internal.TupleInternal; +import io.vertx.sqlclient.internal.RowDescriptorBase; +import io.vertx.sqlclient.internal.TupleBase; -class DB2PreparedStatement implements PreparedStatement { +public class DB2PreparedStatement implements PreparedStatement { private static final Logger LOG = LoggerFactory.getLogger(DB2PreparedStatement.class); final String sql; final DB2ParamDesc paramDesc; - final DB2RowDesc rowDesc; + final DB2RowDescriptor rowDesc; final Section section; private final Map activeQueries = new ConcurrentHashMap<>(4); @@ -51,7 +50,7 @@ public static class QueryInstance { } } - DB2PreparedStatement(String sql, DB2ParamDesc paramDesc, DB2RowDesc rowDesc, Section section) { + DB2PreparedStatement(String sql, DB2ParamDesc paramDesc, DB2RowDescriptor rowDesc, Section section) { this.paramDesc = paramDesc; this.rowDesc = rowDesc; this.sql = sql; @@ -59,12 +58,7 @@ public static class QueryInstance { } @Override - public ParamDesc paramDesc() { - return paramDesc; - } - - @Override - public RowDesc rowDesc() { + public RowDescriptorBase rowDesc() { return rowDesc; } @@ -74,7 +68,7 @@ public String sql() { } @Override - public TupleInternal prepare(TupleInternal values) { + public TupleBase prepare(TupleBase values) { return paramDesc.prepare(values); } diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2RowDesc.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2RowDescriptor.java similarity index 80% rename from vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2RowDesc.java rename to vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2RowDescriptor.java index f29947bdd8..12d3fa2385 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2RowDesc.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2RowDescriptor.java @@ -16,16 +16,16 @@ package io.vertx.db2client.impl.codec; import io.vertx.db2client.impl.drda.ColumnMetaData; -import io.vertx.sqlclient.internal.RowDesc; +import io.vertx.sqlclient.internal.RowDescriptorBase; import java.sql.JDBCType; import java.util.List; -class DB2RowDesc extends RowDesc { +class DB2RowDescriptor extends RowDescriptorBase { private final ColumnMetaData columnMetaData; - private DB2RowDesc(DB2ColumnDesc[] columnDescs, ColumnMetaData columnMetaData) { + private DB2RowDescriptor(DB2ColumnDesc[] columnDescs, ColumnMetaData columnMetaData) { super(columnDescs); this.columnMetaData = columnMetaData; } @@ -34,13 +34,13 @@ ColumnMetaData columnDefinitions() { return columnMetaData; } - static DB2RowDesc create(ColumnMetaData md) { + static DB2RowDescriptor create(ColumnMetaData md) { List names = md.getColumnNames(); List types = md.getJdbcTypes(); DB2ColumnDesc[] columns = new DB2ColumnDesc[names.size()]; for (int i = 0; i < columns.length; i++) { columns[i] = new DB2ColumnDesc(names.get(i), types.get(i)); } - return new DB2RowDesc(columns, md); + return new DB2RowDescriptor(columns, md); } } diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/ExtendedBatchQueryCommandCodec.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/ExtendedBatchQueryCommandCodec.java index f6cd00391b..e396a76523 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/ExtendedBatchQueryCommandCodec.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/ExtendedBatchQueryCommandCodec.java @@ -27,20 +27,20 @@ import io.vertx.db2client.impl.drda.DRDAQueryRequest; import io.vertx.db2client.impl.drda.DRDAQueryResponse; import io.vertx.sqlclient.Tuple; -import io.vertx.sqlclient.internal.TupleInternal; -import io.vertx.sqlclient.internal.command.CommandResponse; -import io.vertx.sqlclient.internal.command.ExtendedQueryCommand; +import io.vertx.sqlclient.internal.TupleBase; +import io.vertx.sqlclient.codec.CommandResponse; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; -class ExtendedBatchQueryCommandCodec extends ExtendedQueryCommandBaseCodec> { +public class ExtendedBatchQueryCommandCodec extends ExtendedQueryCommandBaseCodec> { private static final Logger LOG = LoggerFactory.getLogger(ExtendedBatchQueryCommandCodec.class); - private final List params; + private final List params; private final List queryInstances; private final String baseCursorId; - ExtendedBatchQueryCommandCodec(ExtendedQueryCommand cmd) { - super(cmd); + public ExtendedBatchQueryCommandCodec(ExtendedQueryCommand cmd, DB2PreparedStatement statement) { + super(cmd, statement); params = cmd.paramsList(); queryInstances = new ArrayList<>(params.size()); baseCursorId = (cmd.cursorId() == null ? UUID.randomUUID().toString() : cmd.cursorId()) + "-"; diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/ExtendedQueryCommandBaseCodec.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/ExtendedQueryCommandBaseCodec.java index 24ee7f9898..8630d3b685 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/ExtendedQueryCommandBaseCodec.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/ExtendedQueryCommandBaseCodec.java @@ -27,18 +27,18 @@ import io.vertx.sqlclient.Row; import io.vertx.sqlclient.Tuple; import io.vertx.sqlclient.data.Numeric; -import io.vertx.sqlclient.internal.command.CommandResponse; -import io.vertx.sqlclient.internal.command.ExtendedQueryCommand; +import io.vertx.sqlclient.codec.CommandResponse; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; abstract class ExtendedQueryCommandBaseCodec> extends QueryCommandBaseCodec { final DB2PreparedStatement statement; - ExtendedQueryCommandBaseCodec(C cmd) { + ExtendedQueryCommandBaseCodec(C cmd, DB2PreparedStatement statement) { super(cmd); - statement = (DB2PreparedStatement) cmd.preparedStatement(); - columnDefinitions = statement.rowDesc.columnDefinitions(); + this.statement = statement; + this.columnDefinitions = statement.rowDesc.columnDefinitions(); } void encodePreparedQuery(DRDAQueryRequest queryRequest, QueryInstance queryInstance, Tuple params) { @@ -72,7 +72,7 @@ RowResultDecoder decodePreparedQuery(ByteBuf payload, DRDAQueryResponse re if (queryInstance.cursor == null) { resp.setOutputColumnMetaData(columnDefinitions); resp.readBeginOpenQuery(); - decoder = new RowResultDecoder<>(cmd.collector(), DB2RowDesc.create(columnDefinitions), resp.getCursor(), resp); + decoder = new RowResultDecoder<>(cmd.collector(), DB2RowDescriptor.create(columnDefinitions), resp.getCursor(), resp); queryInstance.cursor = resp.getCursor(); queryInstance.queryInstanceId = resp.getQueryInstanceId(); } else { diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/ExtendedQueryCommandCodec.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/ExtendedQueryCommandCodec.java index ea6f3be905..d49bf773bd 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/ExtendedQueryCommandCodec.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/ExtendedQueryCommandCodec.java @@ -19,15 +19,15 @@ import io.vertx.db2client.impl.codec.DB2PreparedStatement.QueryInstance; import io.vertx.db2client.impl.drda.DRDAQueryRequest; import io.vertx.db2client.impl.drda.DRDAQueryResponse; -import io.vertx.sqlclient.internal.command.CommandResponse; -import io.vertx.sqlclient.internal.command.ExtendedQueryCommand; +import io.vertx.sqlclient.codec.CommandResponse; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; -class ExtendedQueryCommandCodec extends ExtendedQueryCommandBaseCodec> { +public class ExtendedQueryCommandCodec extends ExtendedQueryCommandBaseCodec> { final QueryInstance queryInstance; - ExtendedQueryCommandCodec(ExtendedQueryCommand cmd) { - super(cmd); + public ExtendedQueryCommandCodec(ExtendedQueryCommand cmd, DB2PreparedStatement statement) { + super(cmd, statement); queryInstance = statement.getQueryInstance(cmd.cursorId()); } diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/InitialHandshakeCommandCodec.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/InitialHandshakeCommandCodec.java index 8b1fee817e..7b7882c4bc 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/InitialHandshakeCommandCodec.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/InitialHandshakeCommandCodec.java @@ -25,8 +25,8 @@ import io.vertx.db2client.impl.drda.DRDAConstants; import io.vertx.db2client.impl.drda.SQLState; import io.vertx.db2client.impl.drda.SqlCode; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.internal.command.CommandResponse; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.codec.CommandResponse; /** * InitialHandshakeCommandCodec encodes the packets to get a connection from the database. @@ -59,7 +59,7 @@ void encode(DB2Encoder encoder) { // -4499 = A fatal error occurred that resulted in a disconnect from the data // source. // 08001 = "The connection was unable to be established" - cmd.fail(new DB2Exception("The connection was closed by the database server.", SqlCode.CONNECTION_REFUSED, + fail(new DB2Exception("The connection was closed by the database server.", SqlCode.CONNECTION_REFUSED, SQLState.AUTH_DATABASE_CONNECTION_REFUSED)); } }); @@ -130,7 +130,7 @@ void decodePayload(ByteBuf payload, int payloadLength) { break; default: - cmd.fail(new DB2Exception("The connection was unable to be established. Invalid connection state.", SqlCode.CONNECTION_REFUSED, + fail(new DB2Exception("The connection was unable to be established. Invalid connection state.", SqlCode.CONNECTION_REFUSED, SQLState.AUTH_DATABASE_CONNECTION_REFUSED)); break; diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/PingCommandCodec.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/PingCommandCodec.java index 3866a75539..ad9da6cba9 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/PingCommandCodec.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/PingCommandCodec.java @@ -22,7 +22,7 @@ import io.vertx.db2client.impl.drda.DRDAConnectResponse; import io.vertx.db2client.impl.drda.DRDAConstants; import io.vertx.db2client.impl.drda.ConnectionMetaData; -import io.vertx.sqlclient.internal.command.CommandResponse; +import io.vertx.sqlclient.codec.CommandResponse; class PingCommandCodec extends CommandCodec { diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/PrepareStatementCodec.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/PrepareStatementCodec.java index 18fe425e9c..d5282ecca0 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/PrepareStatementCodec.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/PrepareStatementCodec.java @@ -23,8 +23,8 @@ import io.vertx.db2client.impl.drda.DRDAQueryResponse; import io.vertx.db2client.impl.drda.Section; import io.vertx.sqlclient.internal.PreparedStatement; -import io.vertx.sqlclient.internal.command.CommandResponse; -import io.vertx.sqlclient.internal.command.PrepareStatementCommand; +import io.vertx.sqlclient.codec.CommandResponse; +import io.vertx.sqlclient.spi.protocol.PrepareStatementCommand; class PrepareStatementCodec extends CommandCodec { @@ -89,7 +89,7 @@ void decodePayload(ByteBuf payload, int payloadLength) { private void handleReadyForQuery() { completionHandler.handle(CommandResponse.success(new DB2PreparedStatement(cmd.sql(), new DB2ParamDesc(paramDesc), - DB2RowDesc.create(rowDesc), section))); + DB2RowDescriptor.create(rowDesc), section))); } private void resetIntermediaryResult() { diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/QueryCommandBaseCodec.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/QueryCommandBaseCodec.java index 859b43b349..a640b175c6 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/QueryCommandBaseCodec.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/QueryCommandBaseCodec.java @@ -18,8 +18,8 @@ import io.netty.buffer.ByteBuf; import io.vertx.db2client.impl.drda.ColumnMetaData; import io.vertx.db2client.impl.drda.DRDAQueryRequest; -import io.vertx.sqlclient.internal.RowDesc; -import io.vertx.sqlclient.internal.command.QueryCommandBase; +import io.vertx.sqlclient.internal.RowDescriptorBase; +import io.vertx.sqlclient.spi.protocol.QueryCommandBase; abstract class QueryCommandBaseCodec> extends CommandCodec { @@ -79,11 +79,11 @@ void decodePayload(ByteBuf payload, int payloadLength) { void handleQueryResult(RowResultDecoder decoder) { Throwable failure = decoder.complete(); T result = decoder.result(); - RowDesc rowDesc = decoder.rowDesc; + RowDescriptorBase rowDescriptor = decoder.rowDesc; int size = decoder.size(); int updatedCount = decoder.size(); decoder.reset(); - cmd.resultHandler().handleResult(updatedCount, size, rowDesc, result, failure); + cmd.resultHandler().handleResult(updatedCount, size, rowDescriptor, result, failure); } } diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/RowResultDecoder.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/RowResultDecoder.java index bcb4658d1e..3c2ece6442 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/RowResultDecoder.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/RowResultDecoder.java @@ -21,7 +21,7 @@ import io.netty.buffer.ByteBuf; import io.vertx.core.internal.logging.Logger; import io.vertx.core.internal.logging.LoggerFactory; -import io.vertx.db2client.impl.DB2RowImpl; +import io.vertx.db2client.impl.DB2Row; import io.vertx.db2client.impl.drda.Cursor; import io.vertx.db2client.impl.drda.DRDAQueryResponse; import io.vertx.sqlclient.Row; @@ -33,11 +33,11 @@ class RowResultDecoder extends RowDecoder { private static final Logger LOG = LoggerFactory.getLogger(RowResultDecoder.class); - final DB2RowDesc rowDesc; + final DB2RowDescriptor rowDesc; final Cursor cursor; final DRDAQueryResponse response; - RowResultDecoder(Collector collector, DB2RowDesc rowDesc, Cursor cursor, DRDAQueryResponse resp) { + RowResultDecoder(Collector collector, DB2RowDescriptor rowDesc, Cursor cursor, DRDAQueryResponse resp) { super(collector); this.rowDesc = rowDesc; this.cursor = cursor; @@ -55,7 +55,7 @@ public boolean next() { @Override protected RowInternal row() { - return new DB2RowImpl(rowDesc); + return new DB2Row(rowDesc); } @Override diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/SimpleQueryCommandCodec.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/SimpleQueryCommandCodec.java index 3a1e8cc083..305ffa20f3 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/SimpleQueryCommandCodec.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/SimpleQueryCommandCodec.java @@ -23,8 +23,8 @@ import io.vertx.db2client.impl.drda.DRDAQueryResponse; import io.vertx.db2client.impl.drda.Section; import io.vertx.sqlclient.Row; -import io.vertx.sqlclient.internal.command.CommandResponse; -import io.vertx.sqlclient.internal.command.SimpleQueryCommand; +import io.vertx.sqlclient.codec.CommandResponse; +import io.vertx.sqlclient.spi.protocol.SimpleQueryCommand; class SimpleQueryCommandCodec extends QueryCommandBaseCodec> { @@ -75,7 +75,7 @@ void decodeQuery(ByteBuf payload) { resp.readPrepareDescribeOutput(); resp.readBeginOpenQuery(); columnDefinitions = resp.getOutputColumnMetaData(); - RowResultDecoder decoder = new RowResultDecoder<>(cmd.collector(), DB2RowDesc.create(columnDefinitions), resp.getCursor(), resp); + RowResultDecoder decoder = new RowResultDecoder<>(cmd.collector(), DB2RowDescriptor.create(columnDefinitions), resp.getCursor(), resp); while (decoder.next()) { decoder.handleRow(columnDefinitions.columns_, payload); diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/command/AuthenticationCommandBase.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/command/AuthenticationCommandBase.java index b87668fd3d..4f3eec4af9 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/command/AuthenticationCommandBase.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/command/AuthenticationCommandBase.java @@ -17,7 +17,7 @@ import java.util.Map; -import io.vertx.sqlclient.internal.command.CommandBase; +import io.vertx.sqlclient.spi.protocol.CommandBase; public class AuthenticationCommandBase extends CommandBase { diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/command/InitialHandshakeCommand.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/command/InitialHandshakeCommand.java index f6ce353aa4..23196d6768 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/command/InitialHandshakeCommand.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/command/InitialHandshakeCommand.java @@ -17,8 +17,8 @@ import java.util.Map; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.impl.SocketConnectionBase; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.codec.SocketConnectionBase; public class InitialHandshakeCommand extends AuthenticationCommandBase { diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/command/PingCommand.java b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/command/PingCommand.java index e9193113e0..c3895e48f2 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/impl/command/PingCommand.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/impl/command/PingCommand.java @@ -15,7 +15,7 @@ */ package io.vertx.db2client.impl.command; -import io.vertx.sqlclient.internal.command.CommandBase; +import io.vertx.sqlclient.spi.protocol.CommandBase; public class PingCommand extends CommandBase { } diff --git a/vertx-db2-client/src/main/java/io/vertx/db2client/spi/DB2Driver.java b/vertx-db2-client/src/main/java/io/vertx/db2client/spi/DB2Driver.java index d5a64f18a3..466b5547dc 100644 --- a/vertx-db2-client/src/main/java/io/vertx/db2client/spi/DB2Driver.java +++ b/vertx-db2-client/src/main/java/io/vertx/db2client/spi/DB2Driver.java @@ -29,42 +29,35 @@ import io.vertx.sqlclient.PoolOptions; import io.vertx.sqlclient.SqlConnectOptions; import io.vertx.sqlclient.SqlConnection; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.internal.pool.CloseablePool; -import io.vertx.sqlclient.internal.pool.PoolImpl; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.impl.pool.PoolImpl; import io.vertx.sqlclient.internal.SqlConnectionInternal; -import io.vertx.sqlclient.spi.ConnectionFactory; -import io.vertx.sqlclient.spi.Driver; +import io.vertx.sqlclient.spi.connection.ConnectionFactory; +import io.vertx.sqlclient.spi.DriverBase; import java.util.function.Supplier; -public class DB2Driver implements Driver { +public class DB2Driver extends DriverBase { - private static final String SHARED_CLIENT_KEY = "__vertx.shared.db2client"; + private static final String DISCRIMINANT = "db2client"; public static final DB2Driver INSTANCE = new DB2Driver(); + public DB2Driver() { + super(DISCRIMINANT); + } + @Override public DB2ConnectOptions downcast(SqlConnectOptions connectOptions) { return connectOptions instanceof DB2ConnectOptions ? (DB2ConnectOptions) connectOptions : new DB2ConnectOptions(connectOptions); } @Override - public Pool newPool(Vertx vertx, Supplier> databases, PoolOptions poolOptions, NetClientOptions transportOptions, Handler connectHandler, CloseFuture closeFuture) { - VertxInternal vx = (VertxInternal) vertx; - PoolImpl pool; - if (poolOptions.isShared()) { - pool = vx.createSharedResource(SHARED_CLIENT_KEY, poolOptions.getName(), closeFuture, cf -> newPoolImpl(vx, connectHandler, databases, poolOptions, transportOptions, cf)); - } else { - pool = newPoolImpl(vx, connectHandler, databases, poolOptions, transportOptions, closeFuture); - } - return new CloseablePool(vx, closeFuture, pool); - } - - private PoolImpl newPoolImpl(VertxInternal vertx, Handler connectHandler, Supplier> databases, PoolOptions options, NetClientOptions transportOptions, CloseFuture closeFuture) { - boolean pipelinedPool = options instanceof Db2PoolOptions && ((Db2PoolOptions) options).isPipelined(); + protected Pool newPool(VertxInternal vertx, Handler connectHandler, Supplier> databases, PoolOptions poolOptions, NetClientOptions transportOptions, CloseFuture closeFuture) { + boolean pipelinedPool = poolOptions instanceof Db2PoolOptions && ((Db2PoolOptions) poolOptions).isPipelined(); ConnectionFactory factory = createConnectionFactory(vertx, transportOptions); - PoolImpl pool = new PoolImpl(vertx, this, pipelinedPool, options, null, null, context -> factory.connect(context, databases.get()), connectHandler, closeFuture); + PoolImpl pool = new PoolImpl(vertx, this, pipelinedPool, poolOptions, null, null, + factory, databases, connectHandler, this::wrapConnection, closeFuture); pool.init(); closeFuture.add(factory); return pool; @@ -87,7 +80,7 @@ public ConnectionFactory createConnectionFactory(Vertx vertx, } @Override - public SqlConnectionInternal wrapConnection(ContextInternal context, ConnectionFactory factory, Connection conn) { - return new DB2ConnectionImpl(context, factory, conn); + public SqlConnectionInternal wrapConnection(ContextInternal context, ConnectionFactory factory, Connection connection) { + return new DB2ConnectionImpl(context, factory, connection); } } diff --git a/vertx-db2-client/src/main/java/module-info.java b/vertx-db2-client/src/main/java/module-info.java index 8a111b09d9..bac0a77fe2 100644 --- a/vertx-db2-client/src/main/java/module-info.java +++ b/vertx-db2-client/src/main/java/module-info.java @@ -6,6 +6,7 @@ requires io.netty.handler; requires io.netty.transport; requires io.vertx.sql.client; + requires io.vertx.sql.client.codec; requires io.vertx.core; requires io.vertx.core.logging; requires java.sql; diff --git a/vertx-db2-client/src/test/java/io/vertx/tests/db2client/DB2RowImplTest.java b/vertx-db2-client/src/test/java/io/vertx/tests/db2client/DB2RowTest.java similarity index 82% rename from vertx-db2-client/src/test/java/io/vertx/tests/db2client/DB2RowImplTest.java rename to vertx-db2-client/src/test/java/io/vertx/tests/db2client/DB2RowTest.java index 511a6a16c6..048ee82c3f 100644 --- a/vertx-db2-client/src/test/java/io/vertx/tests/db2client/DB2RowImplTest.java +++ b/vertx-db2-client/src/test/java/io/vertx/tests/db2client/DB2RowTest.java @@ -11,8 +11,8 @@ package io.vertx.tests.db2client; -import io.vertx.db2client.impl.DB2RowImpl; -import io.vertx.tests.sqlclient.TestRowDesc; +import io.vertx.db2client.impl.DB2Row; +import io.vertx.tests.sqlclient.TestRowDescriptor; import org.junit.Test; import java.time.LocalDate; @@ -20,14 +20,14 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; -public class DB2RowImplTest { +public class DB2RowTest { enum EnumValue { SOME, NONE } @Test public void testGetNullEnum() { - DB2RowImpl row = new DB2RowImpl(TestRowDesc.create("enum")); + DB2Row row = new DB2Row(TestRowDescriptor.create("enum")); row.addValue(null); assertNull(row.get(EnumValue.class, 0)); diff --git a/vertx-mssql-client/pom.xml b/vertx-mssql-client/pom.xml index 2d4b3940d6..058564dfe6 100644 --- a/vertx-mssql-client/pom.xml +++ b/vertx-mssql-client/pom.xml @@ -30,7 +30,10 @@ io.vertx vertx-sql-client - ${project.version} + + + io.vertx + vertx-sql-client-codec diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLConnectionFactory.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLConnectionFactory.java index 515370e3c8..1d6f856de4 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLConnectionFactory.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLConnectionFactory.java @@ -24,8 +24,7 @@ import io.vertx.core.spi.metrics.ClientMetrics; import io.vertx.core.spi.metrics.VertxMetrics; import io.vertx.mssqlclient.MSSQLConnectOptions; -import io.vertx.sqlclient.SqlConnection; -import io.vertx.sqlclient.internal.Connection; +import io.vertx.sqlclient.spi.connection.Connection; import io.vertx.sqlclient.impl.ConnectionFactoryBase; import java.util.Map; @@ -106,16 +105,10 @@ private Future login(MSSQLSocketConnection conn, MSSQLConnectOptions } @Override - public Future connect(Context context, MSSQLConnectOptions options) { + public Future connect(Context context, MSSQLConnectOptions options) { ContextInternal ctx = (ContextInternal) context; - Promise promise = ctx.promise(); - connect(asEventLoopContext(ctx), options) - .map(conn -> { - MSSQLConnectionImpl msConn = new MSSQLConnectionImpl(ctx, this, conn); - conn.init(msConn); - return (SqlConnection)msConn; - }) - .onComplete(promise); + Promise promise = ctx.promise(); + connect(asEventLoopContext(ctx), options).onComplete(promise); return promise.future(); } } diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLConnectionImpl.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLConnectionImpl.java index eb96a51330..a255e3dba8 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLConnectionImpl.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLConnectionImpl.java @@ -20,10 +20,10 @@ import io.vertx.mssqlclient.MSSQLConnection; import io.vertx.mssqlclient.MSSQLInfo; import io.vertx.mssqlclient.spi.MSSQLDriver; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.impl.SocketConnectionBase; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.codec.SocketConnectionBase; import io.vertx.sqlclient.internal.SqlConnectionBase; -import io.vertx.sqlclient.spi.ConnectionFactory; +import io.vertx.sqlclient.spi.connection.ConnectionFactory; public class MSSQLConnectionImpl extends SqlConnectionBase implements MSSQLConnection { @@ -36,7 +36,12 @@ public MSSQLConnectionImpl(ContextInternal context, ConnectionFactory factory, C public static Future connect(Vertx vertx, MSSQLConnectOptions options) { ContextInternal ctx = (ContextInternal) vertx.getOrCreateContext(); MSSQLConnectionFactory client = new MSSQLConnectionFactory(ctx.owner()); - return prepareForClose(ctx, client.connect((Context)ctx, options)).map(MSSQLConnection::cast); + return client.connect((Context)ctx, options).map(conn -> { + MSSQLConnectionImpl impl = new MSSQLConnectionImpl(ctx, client, conn); + conn.init(impl); + prepareForClose(ctx, impl); + return impl; + }); } @Override diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLRowImpl.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLRow.java similarity index 85% rename from vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLRowImpl.java rename to vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLRow.java index cf46c0d9aa..a8b96aa47d 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLRowImpl.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLRow.java @@ -13,7 +13,7 @@ import io.vertx.core.buffer.Buffer; import io.vertx.sqlclient.impl.RowBase; -import io.vertx.sqlclient.internal.RowDesc; +import io.vertx.sqlclient.internal.RowDescriptorBase; import java.math.BigDecimal; import java.time.LocalDate; @@ -21,29 +21,12 @@ import java.time.LocalTime; import java.time.OffsetDateTime; import java.time.temporal.Temporal; -import java.util.List; import java.util.UUID; -public class MSSQLRowImpl extends RowBase { - private final RowDesc rowDesc; +public class MSSQLRow extends RowBase { - public MSSQLRowImpl(RowDesc rowDesc) { - super(rowDesc.columnNames().size()); - this.rowDesc = rowDesc; - } - - @Override - public String getColumnName(int pos) { - List columnNames = rowDesc.columnNames(); - return pos < 0 || columnNames.size() - 1 < pos ? null : columnNames.get(pos); - } - - @Override - public int getColumnIndex(String column) { - if (column == null) { - throw new IllegalArgumentException("Column name can not be null"); - } - return rowDesc.columnNames().indexOf(column); + public MSSQLRow(RowDescriptorBase rowDescriptor) { + super(rowDescriptor); } @Override diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLSocketConnection.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLSocketConnection.java index 579b6dd5d2..4294805a61 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLSocketConnection.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/MSSQLSocketConnection.java @@ -14,10 +14,8 @@ import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPromise; import io.netty.handler.ssl.SslHandler; -import io.vertx.core.AsyncResult; import io.vertx.core.Completable; import io.vertx.core.Future; -import io.vertx.core.Handler; import io.vertx.core.internal.ContextInternal; import io.vertx.core.internal.PromiseInternal; import io.vertx.core.internal.tls.SslContextManager; @@ -29,22 +27,31 @@ import io.vertx.core.spi.metrics.ClientMetrics; import io.vertx.mssqlclient.MSSQLConnectOptions; import io.vertx.mssqlclient.MSSQLInfo; +import io.vertx.mssqlclient.impl.codec.ExtendedQueryCommandBaseCodec; +import io.vertx.mssqlclient.impl.codec.MSSQLCommandCodec; +import io.vertx.mssqlclient.impl.codec.MSSQLPreparedStatement; import io.vertx.mssqlclient.impl.codec.TdsLoginSentCompletionHandler; import io.vertx.mssqlclient.impl.codec.TdsMessageCodec; import io.vertx.mssqlclient.impl.codec.TdsPacketDecoder; import io.vertx.mssqlclient.impl.codec.TdsSslHandshakeCodec; import io.vertx.mssqlclient.impl.command.PreLoginCommand; import io.vertx.sqlclient.SqlConnectOptions; -import io.vertx.sqlclient.internal.Connection; +import io.vertx.sqlclient.codec.CommandMessage; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.internal.PreparedStatement; import io.vertx.sqlclient.internal.QueryResultHandler; -import io.vertx.sqlclient.impl.SocketConnectionBase; -import io.vertx.sqlclient.internal.command.*; +import io.vertx.sqlclient.codec.SocketConnectionBase; import io.vertx.sqlclient.spi.DatabaseMetadata; +import io.vertx.sqlclient.spi.protocol.CommandBase; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; +import io.vertx.sqlclient.spi.protocol.InitCommand; +import io.vertx.sqlclient.spi.protocol.SimpleQueryCommand; +import io.vertx.sqlclient.spi.protocol.TxCommand; import java.util.Map; import java.util.function.Predicate; -import static io.vertx.sqlclient.internal.command.TxCommand.Kind.BEGIN; +import static io.vertx.sqlclient.spi.protocol.TxCommand.Kind.BEGIN; public class MSSQLSocketConnection extends SocketConnectionBase { @@ -147,18 +154,28 @@ public void init() { super.init(); } + @Override + protected CommandMessage toMessage(ExtendedQueryCommand command, PreparedStatement preparedStatement) { + return ExtendedQueryCommandBaseCodec.create(command, (MSSQLPreparedStatement)preparedStatement); + } + + @Override + protected CommandMessage toMessage(CommandBase command) { + return MSSQLCommandCodec.wrap(command); + } + @Override protected void doSchedule(CommandBase cmd, Completable handler) { if (cmd instanceof TxCommand) { TxCommand tx = (TxCommand) cmd; - String sql = tx.kind == BEGIN ? "BEGIN TRANSACTION":tx.kind.sql; + String sql = tx.kind() == BEGIN ? "BEGIN TRANSACTION" : tx.kind().sql(); SimpleQueryCommand cmd2 = new SimpleQueryCommand<>( sql, false, false, - QueryCommandBase.NULL_COLLECTOR, + SocketConnectionBase.NULL_COLLECTOR, QueryResultHandler.NOOP_HANDLER); - super.doSchedule(cmd2, (res, err) -> handler.complete(tx.result, err)); + super.doSchedule(cmd2, (res, err) -> handler.complete(tx.result(), err)); } else { super.doSchedule(cmd, handler); } @@ -179,7 +196,7 @@ public String system() { } @Override - public DatabaseMetadata getDatabaseMetaData() { + public DatabaseMetadata databaseMetadata() { return databaseMetadata; } diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/CloseConnectionCommandCodec.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/CloseConnectionCommandCodec.java index 7dc4a45534..dedad18d8c 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/CloseConnectionCommandCodec.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/CloseConnectionCommandCodec.java @@ -11,11 +11,11 @@ package io.vertx.mssqlclient.impl.codec; -import io.vertx.sqlclient.internal.command.CloseConnectionCommand; +import io.vertx.sqlclient.spi.protocol.CloseConnectionCommand; class CloseConnectionCommandCodec extends MSSQLCommandCodec { - CloseConnectionCommandCodec(TdsMessageCodec tdsMessageCodec, CloseConnectionCommand cmd) { - super(tdsMessageCodec, cmd); + CloseConnectionCommandCodec(CloseConnectionCommand cmd) { + super(cmd); } @Override diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/CloseCursorCommandCodec.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/CloseCursorCommandCodec.java index fa6071e185..4e23a13234 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/CloseCursorCommandCodec.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/CloseCursorCommandCodec.java @@ -12,24 +12,24 @@ package io.vertx.mssqlclient.impl.codec; import io.netty.buffer.ByteBuf; -import io.vertx.sqlclient.internal.command.CloseCursorCommand; -import io.vertx.sqlclient.internal.command.CommandResponse; +import io.vertx.sqlclient.spi.protocol.CloseCursorCommand; +import io.vertx.sqlclient.codec.CommandResponse; import static io.vertx.mssqlclient.impl.codec.DataType.INTN; import static io.vertx.mssqlclient.impl.codec.MessageType.RPC; public class CloseCursorCommandCodec extends MSSQLCommandCodec { - private final CursorData cursorData; + private CursorData cursorData; private boolean cursorClosed; - public CloseCursorCommandCodec(TdsMessageCodec tdsMessageCodec, CloseCursorCommand cmd) { - super(tdsMessageCodec, cmd); - cursorData = tdsMessageCodec.removeCursorData(cmd.id()); + public CloseCursorCommandCodec(CloseCursorCommand cmd) { + super(cmd); } @Override void encode() { + cursorData = tdsMessageCodec.removeCursorData(cmd.id()); if (cursorData != null && cursorData.serverCursorId > 0) { sendCursorClose(); } else { diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/CloseStatementCommandCodec.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/CloseStatementCommandCodec.java index 020c07b282..63a28bdf14 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/CloseStatementCommandCodec.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/CloseStatementCommandCodec.java @@ -12,16 +12,16 @@ package io.vertx.mssqlclient.impl.codec; import io.netty.buffer.ByteBuf; -import io.vertx.sqlclient.internal.command.CloseStatementCommand; -import io.vertx.sqlclient.internal.command.CommandResponse; +import io.vertx.sqlclient.spi.protocol.CloseStatementCommand; +import io.vertx.sqlclient.codec.CommandResponse; import static io.vertx.mssqlclient.impl.codec.DataType.INTN; import static io.vertx.mssqlclient.impl.codec.MessageType.RPC; class CloseStatementCommandCodec extends MSSQLCommandCodec { - CloseStatementCommandCodec(TdsMessageCodec tdsMessageCodec, CloseStatementCommand cmd) { - super(tdsMessageCodec, cmd); + CloseStatementCommandCodec(CloseStatementCommand cmd) { + super(cmd); } @Override diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/CursorData.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/CursorData.java index 8e7d034595..1256e4fe6a 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/CursorData.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/CursorData.java @@ -22,7 +22,7 @@ class CursorData { int serverCursorId; // When invoking CursorPrepExec, the database server returns column metadata. // We store it so that we can tell the server not to return column metadata again when invoking CursorFetch - MSSQLRowDesc mssqlRowDesc; + MSSQLRowDescriptor mssqlRowDesc; boolean fetchSent; int rowsTotal; int rowsFetched; diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/ExtendedBatchQueryCommandCodec.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/ExtendedBatchQueryCommandCodec.java index 9f26d6ac18..abeb8b444a 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/ExtendedBatchQueryCommandCodec.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/ExtendedBatchQueryCommandCodec.java @@ -12,21 +12,21 @@ package io.vertx.mssqlclient.impl.codec; import io.netty.buffer.ByteBuf; -import io.vertx.sqlclient.internal.TupleInternal; -import io.vertx.sqlclient.internal.command.CommandResponse; -import io.vertx.sqlclient.internal.command.ExtendedQueryCommand; +import io.vertx.sqlclient.internal.TupleBase; +import io.vertx.sqlclient.codec.CommandResponse; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; import java.util.List; class ExtendedBatchQueryCommandCodec extends ExtendedQueryCommandBaseCodec { - private final List paramsList; + private final List paramsList; private int paramsIdx; private int messageDecoded; - ExtendedBatchQueryCommandCodec(TdsMessageCodec tdsMessageCodec, ExtendedQueryCommand cmd) { - super(tdsMessageCodec, cmd); + ExtendedBatchQueryCommandCodec(ExtendedQueryCommand cmd, MSSQLPreparedStatement ps) { + super(cmd, ps); paramsList = cmd.paramsList(); } @@ -49,7 +49,7 @@ protected void handleDecodingComplete() { } @Override - protected TupleInternal prepexecRequestParams() { + protected TupleBase prepexecRequestParams() { paramsIdx = 1; return paramsList.get(0); } @@ -65,7 +65,7 @@ protected void writeRpcRequestBatch(ByteBuf packet) { } @Override - protected TupleInternal execRequestParams() { + protected TupleBase execRequestParams() { return paramsList.get(paramsIdx); } } diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/ExtendedCursorQueryCommandCodec.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/ExtendedCursorQueryCommandCodec.java index da1b680236..236be34d43 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/ExtendedCursorQueryCommandCodec.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/ExtendedCursorQueryCommandCodec.java @@ -12,8 +12,8 @@ package io.vertx.mssqlclient.impl.codec; import io.netty.buffer.ByteBuf; -import io.vertx.sqlclient.internal.TupleInternal; -import io.vertx.sqlclient.internal.command.ExtendedQueryCommand; +import io.vertx.sqlclient.internal.TupleBase; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; import static io.vertx.mssqlclient.impl.codec.DataType.INTN; import static io.vertx.mssqlclient.impl.codec.DataType.NVARCHAR; @@ -21,15 +21,15 @@ class ExtendedCursorQueryCommandCodec extends ExtendedQueryCommandBaseCodec { - private final CursorData cursorData; + private CursorData cursorData; - ExtendedCursorQueryCommandCodec(TdsMessageCodec tdsMessageCodec, ExtendedQueryCommand cmd) { - super(tdsMessageCodec, cmd); - cursorData = tdsMessageCodec.getOrCreateCursorData(cmd.cursorId()); + ExtendedCursorQueryCommandCodec(ExtendedQueryCommand cmd, MSSQLPreparedStatement ps) { + super(cmd, ps); } @Override void encode() { + cursorData = tdsMessageCodec.getOrCreateCursorData(cmd.cursorId()); if (cursorData.preparedHandle == 0) { sendCursorPrepExec(); } else { @@ -68,7 +68,7 @@ private void sendCursorPrepExec() { INTN.encodeParam(content, null, true, 0); // prepared handle INTN.encodeParam(content, null, true, 0); // cursor - TupleInternal params = prepexecRequestParams(); + TupleBase params = prepexecRequestParams(); // Param definitions String paramDefinitions = parseParamDefinitions(params); @@ -112,9 +112,9 @@ protected void handleDecodingComplete() { } @Override - protected MSSQLRowDesc createRowDesc(ColumnData[] columnData) { + protected MSSQLRowDescriptor createRowDesc(ColumnData[] columnData) { boolean hasRowStat = columnData.length > 0 && "ROWSTAT".equals(columnData[columnData.length - 1].name()); - return (cursorData.mssqlRowDesc = MSSQLRowDesc.create(columnData, hasRowStat)); + return (cursorData.mssqlRowDesc = MSSQLRowDescriptor.create(columnData, hasRowStat)); } private void sendCursorFetch() { @@ -174,12 +174,12 @@ protected void handleNbcRow(ByteBuf payload) { } @Override - protected TupleInternal prepexecRequestParams() { + protected TupleBase prepexecRequestParams() { return cmd.params(); } @Override - protected TupleInternal execRequestParams() { + protected TupleBase execRequestParams() { throw new UnsupportedOperationException(); } } diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/ExtendedQueryCommandBaseCodec.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/ExtendedQueryCommandBaseCodec.java index c4cb2b8499..dd1d902cb9 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/ExtendedQueryCommandBaseCodec.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/ExtendedQueryCommandBaseCodec.java @@ -13,28 +13,28 @@ import io.netty.buffer.ByteBuf; import io.vertx.sqlclient.data.NullValue; -import io.vertx.sqlclient.internal.TupleInternal; -import io.vertx.sqlclient.internal.command.ExtendedQueryCommand; +import io.vertx.sqlclient.internal.TupleBase; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; import static io.vertx.mssqlclient.impl.codec.DataType.*; import static io.vertx.mssqlclient.impl.codec.MessageType.RPC; -abstract class ExtendedQueryCommandBaseCodec extends QueryCommandBaseCodec> { +public abstract class ExtendedQueryCommandBaseCodec extends QueryCommandBaseCodec> { final MSSQLPreparedStatement ps; - ExtendedQueryCommandBaseCodec(TdsMessageCodec tdsMessageCodec, ExtendedQueryCommand cmd) { - super(tdsMessageCodec, cmd); - ps = (MSSQLPreparedStatement) this.cmd.preparedStatement(); + public ExtendedQueryCommandBaseCodec(ExtendedQueryCommand cmd, MSSQLPreparedStatement ps) { + super(cmd); + this.ps = ps; } - public static MSSQLCommandCodec create(TdsMessageCodec tdsMessageCodec, ExtendedQueryCommand queryCmd) { + public static MSSQLCommandCodec create(ExtendedQueryCommand queryCmd, MSSQLPreparedStatement ps) { if (queryCmd.isBatch()) { - return new ExtendedBatchQueryCommandCodec<>(tdsMessageCodec, queryCmd); + return new ExtendedBatchQueryCommandCodec<>(queryCmd, ps); } else if (queryCmd.cursorId() != null) { - return new ExtendedCursorQueryCommandCodec<>(tdsMessageCodec, queryCmd); + return new ExtendedCursorQueryCommandCodec<>(queryCmd, ps); } else { - return new ExtendedQueryCommandCodec<>(tdsMessageCodec, queryCmd); + return new ExtendedQueryCommandCodec<>(queryCmd, ps); } } @@ -87,7 +87,7 @@ private void sendPrepexecRequest() { // OUT Parameter INTN.encodeParam(content, null, true, ps.handle); - TupleInternal params = prepexecRequestParams(); + TupleBase params = prepexecRequestParams(); // Param definitions String paramDefinitions = parseParamDefinitions(params); @@ -102,7 +102,7 @@ private void sendPrepexecRequest() { tdsMessageCodec.encoder().writeTdsMessage(RPC, content); } - protected abstract TupleInternal prepexecRequestParams(); + protected abstract TupleBase prepexecRequestParams(); void sendExecRequest() { ByteBuf content = tdsMessageCodec.alloc().ioBuffer(); @@ -131,9 +131,9 @@ protected void writeRpcRequestBatch(ByteBuf packet) { encodeParams(packet, execRequestParams()); } - protected abstract TupleInternal execRequestParams(); + protected abstract TupleBase execRequestParams(); - protected String parseParamDefinitions(TupleInternal params) { + protected String parseParamDefinitions(TupleBase params) { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < params.size(); i++) { if (i > 0) { @@ -156,7 +156,7 @@ protected String parseParamDefinitions(TupleInternal params) { return stringBuilder.toString(); } - protected void encodeParams(ByteBuf buffer, TupleInternal params) { + protected void encodeParams(ByteBuf buffer, TupleBase params) { for (int i = 0; i < params.size(); i++) { String name = "@P" + (i + 1); Object value = params.getValue(i); diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/ExtendedQueryCommandCodec.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/ExtendedQueryCommandCodec.java index 002ad57dde..bb1986f683 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/ExtendedQueryCommandCodec.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/ExtendedQueryCommandCodec.java @@ -11,22 +11,22 @@ package io.vertx.mssqlclient.impl.codec; -import io.vertx.sqlclient.internal.TupleInternal; -import io.vertx.sqlclient.internal.command.ExtendedQueryCommand; +import io.vertx.sqlclient.internal.TupleBase; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; class ExtendedQueryCommandCodec extends ExtendedQueryCommandBaseCodec { - ExtendedQueryCommandCodec(TdsMessageCodec tdsMessageCodec, ExtendedQueryCommand cmd) { - super(tdsMessageCodec, cmd); + ExtendedQueryCommandCodec(ExtendedQueryCommand cmd, MSSQLPreparedStatement ps) { + super(cmd, ps); } @Override - protected TupleInternal prepexecRequestParams() { + protected TupleBase prepexecRequestParams() { return cmd.params(); } @Override - protected TupleInternal execRequestParams() { + protected TupleBase execRequestParams() { return cmd.params(); } } diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/InitCommandCodec.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/InitCommandCodec.java index 454a185c5a..6cdda99e5f 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/InitCommandCodec.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/InitCommandCodec.java @@ -17,8 +17,8 @@ import io.vertx.mssqlclient.impl.MSSQLSocketConnection; import io.vertx.mssqlclient.impl.protocol.client.login.LoginPacket; import io.vertx.mssqlclient.impl.utils.Utils; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.internal.command.InitCommand; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.spi.protocol.InitCommand; import java.util.Map; @@ -31,8 +31,8 @@ class InitCommandCodec extends MSSQLCommandCodec { static final Object LOGIN_SENT = new Object(); - InitCommandCodec(TdsMessageCodec tdsMessageCodec, InitCommand cmd) { - super(tdsMessageCodec, cmd); + InitCommandCodec(InitCommand cmd) { + super(cmd); } @Override diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/MSSQLCommandCodec.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/MSSQLCommandCodec.java index b195e4d110..d17c03bc45 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/MSSQLCommandCodec.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/MSSQLCommandCodec.java @@ -16,25 +16,51 @@ import io.netty.handler.ssl.SslHandler; import io.vertx.mssqlclient.MSSQLException; import io.vertx.mssqlclient.MSSQLInfo; -import io.vertx.sqlclient.internal.command.CommandBase; -import io.vertx.sqlclient.internal.command.CommandResponse; +import io.vertx.mssqlclient.impl.command.PreLoginCommand; +import io.vertx.sqlclient.codec.CommandMessage; +import io.vertx.sqlclient.spi.protocol.CloseConnectionCommand; +import io.vertx.sqlclient.spi.protocol.CloseCursorCommand; +import io.vertx.sqlclient.spi.protocol.CloseStatementCommand; +import io.vertx.sqlclient.spi.protocol.CommandBase; +import io.vertx.sqlclient.codec.CommandResponse; +import io.vertx.sqlclient.spi.protocol.InitCommand; +import io.vertx.sqlclient.spi.protocol.PrepareStatementCommand; +import io.vertx.sqlclient.spi.protocol.SimpleQueryCommand; import static io.vertx.mssqlclient.impl.codec.EnvChange.*; import static io.vertx.mssqlclient.impl.codec.TokenType.*; import static io.vertx.mssqlclient.impl.utils.ByteBufUtils.readUnsignedByteLengthString; import static io.vertx.mssqlclient.impl.utils.ByteBufUtils.readUnsignedShortLengthString; -abstract class MSSQLCommandCodec> { +public abstract class MSSQLCommandCodec> extends CommandMessage { - protected final TdsMessageCodec tdsMessageCodec; + public TdsMessageCodec tdsMessageCodec; - final C cmd; public MSSQLException failure; public R result; - MSSQLCommandCodec(TdsMessageCodec tdsMessageCodec, C cmd) { - this.tdsMessageCodec = tdsMessageCodec; - this.cmd = cmd; + MSSQLCommandCodec(C cmd) { + super(cmd); + } + + public static MSSQLCommandCodec wrap(CommandBase cmd) { + if (cmd instanceof PreLoginCommand) { + return new PreLoginCommandCodec((PreLoginCommand) cmd); + } else if (cmd instanceof InitCommand) { + return new InitCommandCodec((InitCommand) cmd); + } else if (cmd instanceof SimpleQueryCommand) { + return new SQLBatchCommandCodec<>((SimpleQueryCommand) cmd); + } else if (cmd instanceof PrepareStatementCommand) { + return new PrepareStatementCodec((PrepareStatementCommand) cmd); + } else if (cmd instanceof CloseStatementCommand) { + return new CloseStatementCommandCodec((CloseStatementCommand) cmd); + } else if (cmd == CloseConnectionCommand.INSTANCE) { + return new CloseConnectionCommandCodec((CloseConnectionCommand) cmd); + } else if (cmd instanceof CloseCursorCommand) { + return new CloseCursorCommandCodec((CloseCursorCommand) cmd); + } else { + throw new UnsupportedOperationException(); + } } abstract void encode(); @@ -125,11 +151,11 @@ private void handleColumnMetadata(ByteBuf payload) { handleRowDesc(createRowDesc(columnDatas)); } - protected MSSQLRowDesc createRowDesc(ColumnData[] columnData) { - return MSSQLRowDesc.create(columnData, false); + protected MSSQLRowDescriptor createRowDesc(ColumnData[] columnData) { + return MSSQLRowDescriptor.create(columnData, false); } - protected void handleRowDesc(MSSQLRowDesc mssqlRowDesc) { + protected void handleRowDesc(MSSQLRowDescriptor mssqlRowDesc) { } protected void handleRow(ByteBuf payload) { diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/MSSQLParamDesc.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/MSSQLParamDesc.java deleted file mode 100644 index c7b62223e2..0000000000 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/MSSQLParamDesc.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2011-2019 Contributors to the Eclipse Foundation - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 - * which is available at https://www.apache.org/licenses/LICENSE-2.0. - * - * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 - */ - -package io.vertx.mssqlclient.impl.codec; - -import io.vertx.sqlclient.impl.ErrorMessageFactory; -import io.vertx.sqlclient.internal.ParamDesc; -import io.vertx.sqlclient.internal.TupleInternal; - -class MSSQLParamDesc extends ParamDesc { - private final ColumnData[] paramDescriptions; - - public MSSQLParamDesc(ColumnData[] paramDescriptions) { - this.paramDescriptions = paramDescriptions; - } - - public ColumnData[] paramDescriptions() { - return paramDescriptions; - } - - public String prepare(TupleInternal values) { - int numberOfParameters = values.size(); - int paramDescLength = paramDescriptions.length; - if (numberOfParameters != paramDescLength){ - return ErrorMessageFactory.buildWhenArgumentsLengthNotMatched(paramDescLength, numberOfParameters); - } - return null; - } -} diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/MSSQLPreparedStatement.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/MSSQLPreparedStatement.java index ff282d3734..f9ee313de5 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/MSSQLPreparedStatement.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/MSSQLPreparedStatement.java @@ -11,10 +11,8 @@ package io.vertx.mssqlclient.impl.codec; -import io.vertx.sqlclient.internal.ParamDesc; import io.vertx.sqlclient.internal.PreparedStatement; -import io.vertx.sqlclient.internal.RowDesc; -import io.vertx.sqlclient.internal.TupleInternal; +import io.vertx.sqlclient.internal.RowDescriptorBase; public class MSSQLPreparedStatement implements PreparedStatement { @@ -26,12 +24,7 @@ public MSSQLPreparedStatement(String sql) { } @Override - public ParamDesc paramDesc() { - throw new UnsupportedOperationException(); - } - - @Override - public RowDesc rowDesc() { + public RowDescriptorBase rowDesc() { throw new UnsupportedOperationException(); } diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/MSSQLRowDesc.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/MSSQLRowDescriptor.java similarity index 69% rename from vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/MSSQLRowDesc.java rename to vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/MSSQLRowDescriptor.java index e8485e16cc..f51fe36547 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/MSSQLRowDesc.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/MSSQLRowDescriptor.java @@ -11,29 +11,29 @@ package io.vertx.mssqlclient.impl.codec; -import io.vertx.sqlclient.internal.RowDesc; +import io.vertx.sqlclient.internal.RowDescriptorBase; import java.util.Arrays; /** - * An implementation of {@link RowDesc} for MSSQL. + * An implementation of {@link RowDescriptorBase} for MSSQL. *

* When reading rows with a cursor, an extra column named {@code ROWSTAT} is returned by the server. * This column should not be conveyed to the user so this class filters it out. */ -public class MSSQLRowDesc extends RowDesc { +public class MSSQLRowDescriptor extends RowDescriptorBase { private final ColumnData[] columnDatas; private final boolean rowStat; - private MSSQLRowDesc(ColumnData[] columnDatas, boolean hasRowStat) { + private MSSQLRowDescriptor(ColumnData[] columnDatas, boolean hasRowStat) { super(columnDatas); this.columnDatas = columnDatas; this.rowStat = hasRowStat; } - public static MSSQLRowDesc create(ColumnData[] columnDatas, boolean hasRowStat) { - return new MSSQLRowDesc(hasRowStat ? Arrays.copyOf(columnDatas, columnDatas.length - 1) : columnDatas, hasRowStat); + public static MSSQLRowDescriptor create(ColumnData[] columnDatas, boolean hasRowStat) { + return new MSSQLRowDescriptor(hasRowStat ? Arrays.copyOf(columnDatas, columnDatas.length - 1) : columnDatas, hasRowStat); } public int size() { diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/PreLoginCommandCodec.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/PreLoginCommandCodec.java index 485657ef44..00158f50d1 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/PreLoginCommandCodec.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/PreLoginCommandCodec.java @@ -15,7 +15,7 @@ import io.vertx.mssqlclient.impl.MSSQLDatabaseMetadata; import io.vertx.mssqlclient.impl.command.PreLoginCommand; import io.vertx.mssqlclient.impl.command.PreLoginResponse; -import io.vertx.sqlclient.internal.command.CommandResponse; +import io.vertx.sqlclient.codec.CommandResponse; import static io.vertx.mssqlclient.impl.codec.EncryptionLevel.ENCRYPT_OFF; import static io.vertx.mssqlclient.impl.codec.EncryptionLevel.ENCRYPT_ON; @@ -27,8 +27,8 @@ class PreLoginCommandCodec extends MSSQLCommandCodec { - PrepareStatementCodec(TdsMessageCodec tdsMessageCodec, PrepareStatementCommand cmd) { - super(tdsMessageCodec, cmd); + PrepareStatementCodec(PrepareStatementCommand cmd) { + super(cmd); } @Override diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/QueryCommandBaseCodec.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/QueryCommandBaseCodec.java index 6d83b241c5..50f03bd093 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/QueryCommandBaseCodec.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/QueryCommandBaseCodec.java @@ -13,8 +13,8 @@ import io.netty.buffer.ByteBuf; import io.vertx.sqlclient.Row; -import io.vertx.sqlclient.internal.RowDesc; -import io.vertx.sqlclient.internal.command.QueryCommandBase; +import io.vertx.sqlclient.internal.RowDescriptorBase; +import io.vertx.sqlclient.spi.protocol.QueryCommandBase; import java.util.stream.Collector; @@ -23,8 +23,8 @@ abstract class QueryCommandBaseCodec> extends M protected int rowCount; protected RowResultDecoder rowResultDecoder; - QueryCommandBaseCodec(TdsMessageCodec tdsMessageCodec, C cmd) { - super(tdsMessageCodec, cmd); + QueryCommandBaseCodec(C cmd) { + super(cmd); } private static T emptyResult(Collector collector) { @@ -32,7 +32,7 @@ private static T emptyResult(Collector collector) { } @Override - protected void handleRowDesc(MSSQLRowDesc mssqlRowDesc) { + protected void handleRowDesc(MSSQLRowDescriptor mssqlRowDesc) { rowResultDecoder = new RowResultDecoder<>(cmd.collector(), mssqlRowDesc); } @@ -58,20 +58,20 @@ protected void handleResultSetDone() { T result; Throwable failure; int size; - RowDesc rowDesc; + RowDescriptorBase rowDescriptor; if (rowResultDecoder != null) { failure = rowResultDecoder.complete(); result = rowResultDecoder.result(); - rowDesc = rowResultDecoder.desc(); + rowDescriptor = rowResultDecoder.desc(); size = rowResultDecoder.size(); rowResultDecoder.reset(); } else { result = emptyResult(cmd.collector()); failure = null; size = 0; - rowDesc = null; + rowDescriptor = null; } - cmd.resultHandler().handleResult(rowCount, size, rowDesc, result, failure); + cmd.resultHandler().handleResult(rowCount, size, rowDescriptor, result, failure); } } diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/RowResultDecoder.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/RowResultDecoder.java index 6673433d33..21809de191 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/RowResultDecoder.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/RowResultDecoder.java @@ -12,7 +12,7 @@ package io.vertx.mssqlclient.impl.codec; import io.netty.buffer.ByteBuf; -import io.vertx.mssqlclient.impl.MSSQLRowImpl; +import io.vertx.mssqlclient.impl.MSSQLRow; import io.vertx.sqlclient.Row; import io.vertx.sqlclient.impl.RowDecoder; import io.vertx.sqlclient.internal.RowInternal; @@ -23,21 +23,21 @@ public class RowResultDecoder extends RowDecoder { private static final int FETCH_MISSING = 0x0002; - private final MSSQLRowDesc desc; + private final MSSQLRowDescriptor desc; public boolean nbc; - public RowResultDecoder(Collector collector, MSSQLRowDesc desc) { + public RowResultDecoder(Collector collector, MSSQLRowDescriptor desc) { super(collector); this.desc = desc; } - public MSSQLRowDesc desc() { + public MSSQLRowDescriptor desc() { return desc; } @Override protected RowInternal row() { - return new MSSQLRowImpl(desc); + return new MSSQLRow(desc); } @Override diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/SQLBatchCommandCodec.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/SQLBatchCommandCodec.java index 9a8039b2c1..fb3aa56d10 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/SQLBatchCommandCodec.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/SQLBatchCommandCodec.java @@ -12,15 +12,15 @@ package io.vertx.mssqlclient.impl.codec; import io.netty.buffer.ByteBuf; -import io.vertx.sqlclient.internal.command.SimpleQueryCommand; +import io.vertx.sqlclient.spi.protocol.SimpleQueryCommand; import java.nio.charset.StandardCharsets; import static io.vertx.mssqlclient.impl.codec.MessageType.SQL_BATCH; class SQLBatchCommandCodec extends QueryCommandBaseCodec> { - SQLBatchCommandCodec(TdsMessageCodec tdsMessageCodec, SimpleQueryCommand cmd) { - super(tdsMessageCodec, cmd); + SQLBatchCommandCodec(SimpleQueryCommand cmd) { + super(cmd); } @Override diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/TdsMessageCodec.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/TdsMessageCodec.java index a25fd6dee4..10c217cd49 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/TdsMessageCodec.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/TdsMessageCodec.java @@ -65,10 +65,7 @@ private void fail(Throwable cause) { } private void fail(MSSQLCommandCodec codec, Throwable cause) { - Completable handler = codec.cmd.handler; - if (handler != null) { - handler.complete(null, cause); - } + codec.fail(cause); } @Override diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/TdsMessageDecoder.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/TdsMessageDecoder.java index 8283a3047c..b34eb02f58 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/TdsMessageDecoder.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/TdsMessageDecoder.java @@ -14,8 +14,8 @@ import io.netty.buffer.ByteBufAllocator; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; -import io.vertx.sqlclient.internal.command.CommandBase; -import io.vertx.sqlclient.internal.command.CommandResponse; +import io.vertx.core.Completable; +import io.vertx.sqlclient.codec.CommandResponse; public class TdsMessageDecoder extends ChannelInboundHandlerAdapter { @@ -55,7 +55,7 @@ public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { void fireCommandResponse(CommandResponse commandResponse) { MSSQLCommandCodec c = tdsMessageCodec.poll(); - commandResponse.cmd = (CommandBase) c.cmd; + commandResponse.handler = (Completable) c.handler; chctx.fireChannelRead(commandResponse); } diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/TdsMessageEncoder.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/TdsMessageEncoder.java index 7f7385cc19..87eb805aa3 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/TdsMessageEncoder.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/codec/TdsMessageEncoder.java @@ -15,8 +15,6 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelPromise; -import io.vertx.mssqlclient.impl.command.PreLoginCommand; -import io.vertx.sqlclient.internal.command.*; import static io.vertx.mssqlclient.MSSQLConnectOptions.MIN_PACKET_SIZE; import static io.vertx.mssqlclient.impl.codec.MessageStatus.END_OF_MESSAGE; @@ -42,40 +40,18 @@ public void handlerAdded(ChannelHandlerContext ctx) throws Exception { @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - if (msg instanceof CommandBase) { - CommandBase cmd = (CommandBase) msg; + if (msg instanceof MSSQLCommandCodec) { + MSSQLCommandCodec cmd = (MSSQLCommandCodec) msg; + cmd.tdsMessageCodec = tdsMessageCodec; write(cmd); } else { super.write(ctx, msg, promise); } } - void write(CommandBase cmd) { - MSSQLCommandCodec codec = wrap(cmd); - if (tdsMessageCodec.add(codec)) { - codec.encode(); - } - } - - private MSSQLCommandCodec wrap(CommandBase cmd) { - if (cmd instanceof PreLoginCommand) { - return new PreLoginCommandCodec(tdsMessageCodec, (PreLoginCommand) cmd); - } else if (cmd instanceof InitCommand) { - return new InitCommandCodec(tdsMessageCodec, (InitCommand) cmd); - } else if (cmd instanceof SimpleQueryCommand) { - return new SQLBatchCommandCodec<>(tdsMessageCodec, (SimpleQueryCommand) cmd); - } else if (cmd instanceof PrepareStatementCommand) { - return new PrepareStatementCodec(tdsMessageCodec, (PrepareStatementCommand) cmd); - } else if (cmd instanceof ExtendedQueryCommand) { - return ExtendedQueryCommandBaseCodec.create(tdsMessageCodec, (ExtendedQueryCommand) cmd); - } else if (cmd instanceof CloseStatementCommand) { - return new CloseStatementCommandCodec(tdsMessageCodec, (CloseStatementCommand) cmd); - } else if (cmd == CloseConnectionCommand.INSTANCE) { - return new CloseConnectionCommandCodec(tdsMessageCodec, (CloseConnectionCommand) cmd); - } else if (cmd instanceof CloseCursorCommand) { - return new CloseCursorCommandCodec(tdsMessageCodec, (CloseCursorCommand) cmd); - } else { - throw new UnsupportedOperationException(); + void write(MSSQLCommandCodec cmd) { + if (tdsMessageCodec.add(cmd)) { + cmd.encode(); } } diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/command/PreLoginCommand.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/command/PreLoginCommand.java index 78d67ff713..2995a17b41 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/command/PreLoginCommand.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/impl/command/PreLoginCommand.java @@ -11,7 +11,7 @@ package io.vertx.mssqlclient.impl.command; -import io.vertx.sqlclient.internal.command.CommandBase; +import io.vertx.sqlclient.spi.protocol.CommandBase; public class PreLoginCommand extends CommandBase { diff --git a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/spi/MSSQLDriver.java b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/spi/MSSQLDriver.java index 0c01516def..9a7bbd70b6 100644 --- a/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/spi/MSSQLDriver.java +++ b/vertx-mssql-client/src/main/java/io/vertx/mssqlclient/spi/MSSQLDriver.java @@ -15,10 +15,7 @@ */ package io.vertx.mssqlclient.spi; -import io.vertx.core.Future; -import io.vertx.core.Handler; import io.vertx.core.Vertx; -import io.vertx.core.internal.CloseFuture; import io.vertx.core.internal.ContextInternal; import io.vertx.core.internal.VertxInternal; import io.vertx.core.json.JsonObject; @@ -27,48 +24,25 @@ import io.vertx.mssqlclient.impl.MSSQLConnectionFactory; import io.vertx.mssqlclient.impl.MSSQLConnectionImpl; import io.vertx.mssqlclient.impl.MSSQLConnectionUriParser; -import io.vertx.sqlclient.Pool; -import io.vertx.sqlclient.PoolOptions; import io.vertx.sqlclient.SqlConnectOptions; -import io.vertx.sqlclient.SqlConnection; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.internal.pool.CloseablePool; -import io.vertx.sqlclient.internal.pool.PoolImpl; +import io.vertx.sqlclient.spi.connection.Connection; import io.vertx.sqlclient.internal.SqlConnectionInternal; -import io.vertx.sqlclient.spi.ConnectionFactory; -import io.vertx.sqlclient.spi.Driver; +import io.vertx.sqlclient.spi.connection.ConnectionFactory; +import io.vertx.sqlclient.spi.DriverBase; -import java.util.function.Supplier; +public class MSSQLDriver extends DriverBase { -public class MSSQLDriver implements Driver { - - private static final String SHARED_CLIENT_KEY = "__vertx.shared.mssqlclient"; + private static final String DISCRIMINANT = "mssqlclient"; public static final MSSQLDriver INSTANCE = new MSSQLDriver(); - @Override - public MSSQLConnectOptions downcast(SqlConnectOptions connectOptions) { - return connectOptions instanceof MSSQLConnectOptions ? (MSSQLConnectOptions) connectOptions : new MSSQLConnectOptions(connectOptions); + public MSSQLDriver() { + super(DISCRIMINANT); } @Override - public Pool newPool(Vertx vertx, Supplier> databases, PoolOptions options, NetClientOptions transportOptions, Handler connectHandler, CloseFuture closeFuture) { - VertxInternal vx = (VertxInternal) vertx; - PoolImpl pool; - if (options.isShared()) { - pool = vx.createSharedResource(SHARED_CLIENT_KEY, options.getName(), closeFuture, cf -> newPoolImpl(vx, connectHandler, databases, options, transportOptions, cf)); - } else { - pool = newPoolImpl(vx, connectHandler, databases, options, transportOptions, closeFuture); - } - return new CloseablePool(vx, closeFuture, pool); - } - - private PoolImpl newPoolImpl(VertxInternal vertx, Handler connectHandler, Supplier> databases, PoolOptions poolOptions, NetClientOptions transportOptions, CloseFuture closeFuture) { - ConnectionFactory factory = createConnectionFactory(vertx, transportOptions); - PoolImpl pool = new PoolImpl(vertx, this, false, poolOptions, null, null, context -> factory.connect(context, databases.get()), connectHandler, closeFuture); - pool.init(); - closeFuture.add(factory); - return pool; + public MSSQLConnectOptions downcast(SqlConnectOptions connectOptions) { + return connectOptions instanceof MSSQLConnectOptions ? (MSSQLConnectOptions) connectOptions : new MSSQLConnectOptions(connectOptions); } @Override @@ -94,7 +68,7 @@ public int appendQueryPlaceholder(StringBuilder queryBuilder, int index, int cur } @Override - public SqlConnectionInternal wrapConnection(ContextInternal context, ConnectionFactory factory, Connection conn) { - return new MSSQLConnectionImpl(context, factory, conn); + public SqlConnectionInternal wrapConnection(ContextInternal context, ConnectionFactory factory, Connection connection) { + return new MSSQLConnectionImpl(context, factory, connection); } } diff --git a/vertx-mssql-client/src/main/java/module-info.java b/vertx-mssql-client/src/main/java/module-info.java index 1e9f6e193a..6fa20b5591 100644 --- a/vertx-mssql-client/src/main/java/module-info.java +++ b/vertx-mssql-client/src/main/java/module-info.java @@ -6,6 +6,7 @@ requires io.netty.handler; requires io.netty.transport; requires io.vertx.sql.client; + requires io.vertx.sql.client.codec; requires io.vertx.core; requires io.vertx.core.logging; requires java.sql; diff --git a/vertx-mssql-client/src/test/java/io/vertx/tests/mssqlclient/impl/MSSQLRowImplTest.java b/vertx-mssql-client/src/test/java/io/vertx/tests/mssqlclient/impl/MSSQLRowTest.java similarity index 81% rename from vertx-mssql-client/src/test/java/io/vertx/tests/mssqlclient/impl/MSSQLRowImplTest.java rename to vertx-mssql-client/src/test/java/io/vertx/tests/mssqlclient/impl/MSSQLRowTest.java index e49b1cc452..53384ae3b3 100644 --- a/vertx-mssql-client/src/test/java/io/vertx/tests/mssqlclient/impl/MSSQLRowImplTest.java +++ b/vertx-mssql-client/src/test/java/io/vertx/tests/mssqlclient/impl/MSSQLRowTest.java @@ -11,8 +11,8 @@ package io.vertx.tests.mssqlclient.impl; -import io.vertx.mssqlclient.impl.MSSQLRowImpl; -import io.vertx.tests.sqlclient.TestRowDesc; +import io.vertx.mssqlclient.impl.MSSQLRow; +import io.vertx.tests.sqlclient.TestRowDescriptor; import org.junit.Test; import java.time.LocalDate; @@ -20,14 +20,14 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; -public class MSSQLRowImplTest { +public class MSSQLRowTest { enum EnumValue { SOME, NONE } @Test public void testGetNullEnum() { - MSSQLRowImpl row = new MSSQLRowImpl(TestRowDesc.create("enum")); + MSSQLRow row = new MSSQLRow(TestRowDescriptor.create("enum")); row.addValue(null); assertNull(row.get(EnumValue.class, 0)); diff --git a/vertx-mssql-client/src/test/java/module-info.java b/vertx-mssql-client/src/test/java/module-info.java index dc697fade9..b625c61bfc 100644 --- a/vertx-mssql-client/src/test/java/module-info.java +++ b/vertx-mssql-client/src/test/java/module-info.java @@ -8,5 +8,6 @@ requires io.vertx.testing.unit; requires junit; requires testcontainers; + requires hamcrest.core; } diff --git a/vertx-mysql-client/pom.xml b/vertx-mysql-client/pom.xml index 0bf587ac0e..6fda3f33ab 100644 --- a/vertx-mysql-client/pom.xml +++ b/vertx-mysql-client/pom.xml @@ -46,6 +46,10 @@ io.vertx vertx-sql-client + + io.vertx + vertx-sql-client-codec + diff --git a/vertx-mysql-client/src/main/asciidoc/index.adoc b/vertx-mysql-client/src/main/asciidoc/index.adoc index 4c577040c9..401b3a9f59 100644 --- a/vertx-mysql-client/src/main/asciidoc/index.adoc +++ b/vertx-mysql-client/src/main/asciidoc/index.adoc @@ -244,7 +244,7 @@ Currently, the client supports the following parameter keys (case-insensitive): * `user` * `password` * `schema` -* `socket` +* `connection` * `useAffectedRows` NOTE: Configuring parameters in connection URI will override the default properties. diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLConnectionFactory.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLConnectionFactory.java index 30aa1d410e..7a0178ba18 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLConnectionFactory.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLConnectionFactory.java @@ -28,8 +28,7 @@ import io.vertx.mysqlclient.MySQLAuthenticationPlugin; import io.vertx.mysqlclient.MySQLConnectOptions; import io.vertx.mysqlclient.SslMode; -import io.vertx.sqlclient.SqlConnection; -import io.vertx.sqlclient.internal.Connection; +import io.vertx.sqlclient.spi.connection.Connection; import io.vertx.sqlclient.impl.ConnectionFactoryBase; import java.nio.charset.Charset; @@ -142,15 +141,15 @@ private Future doConnect(MySQLConnectOptions options, SslMode sslMod } @Override - public Future connect(Context context, MySQLConnectOptions options) { + public Future connect(Context context, MySQLConnectOptions options) { ContextInternal contextInternal = (ContextInternal) context; - Promise promise = contextInternal.promise(); + Promise promise = contextInternal.promise(); connect(asEventLoopContext(contextInternal), options) - .map(conn -> { + /*.map(conn -> { MySQLConnectionImpl mySQLConnection = new MySQLConnectionImpl(contextInternal, this, conn); conn.init(mySQLConnection); return (SqlConnection)mySQLConnection; - }) + })*/ .onComplete(promise); return promise.future(); } diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLConnectionImpl.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLConnectionImpl.java index 3b0b311571..89a7938f1c 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLConnectionImpl.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLConnectionImpl.java @@ -21,9 +21,9 @@ import io.vertx.mysqlclient.MySQLSetOption; import io.vertx.mysqlclient.impl.command.*; import io.vertx.mysqlclient.spi.MySQLDriver; -import io.vertx.sqlclient.internal.Connection; +import io.vertx.sqlclient.spi.connection.Connection; import io.vertx.sqlclient.internal.SqlConnectionBase; -import io.vertx.sqlclient.spi.ConnectionFactory; +import io.vertx.sqlclient.spi.connection.ConnectionFactory; public class MySQLConnectionImpl extends SqlConnectionBase implements MySQLConnection { @@ -37,7 +37,12 @@ public static Future connect(ContextInternal ctx, MySQLConnectO } catch (Exception e) { return ctx.failedFuture(e); } - return prepareForClose(ctx, client.connect((Context)ctx, options)).map(MySQLConnection::cast); + return client.connect((Context)ctx, options).map(conn -> { + MySQLConnectionImpl impl = new MySQLConnectionImpl(ctx, client, conn); + conn.init(impl); + prepareForClose(ctx, impl); + return impl; + }); } public MySQLConnectionImpl(ContextInternal context, ConnectionFactory factory, Connection conn) { diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLParamDesc.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLParamDesc.java index 6bd8277aae..7c2f689860 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLParamDesc.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLParamDesc.java @@ -12,9 +12,8 @@ package io.vertx.mysqlclient.impl; import io.vertx.mysqlclient.impl.protocol.ColumnDefinition; -import io.vertx.sqlclient.internal.ParamDesc; -public class MySQLParamDesc extends ParamDesc { +public class MySQLParamDesc { private final ColumnDefinition[] paramDefinitions; public MySQLParamDesc(ColumnDefinition[] paramDefinitions) { diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLRowImpl.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLRow.java similarity index 92% rename from vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLRowImpl.java rename to vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLRow.java index 693472b1c8..d92ffd33f7 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLRowImpl.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLRow.java @@ -23,16 +23,12 @@ import java.math.BigDecimal; import java.time.*; import java.time.temporal.Temporal; -import java.util.List; import java.util.UUID; -public class MySQLRowImpl extends RowBase { +public class MySQLRow extends RowBase { - private final MySQLRowDesc rowDesc; - - public MySQLRowImpl(MySQLRowDesc rowDesc) { - super(rowDesc.columnNames().size()); - this.rowDesc = rowDesc; + public MySQLRow(MySQLRowDescriptor rowDesc) { + super(rowDesc); } @Override @@ -92,20 +88,6 @@ public T get(Class type, int position) { } } - @Override - public String getColumnName(int pos) { - List columnNames = rowDesc.columnNames(); - return pos < 0 || columnNames.size() - 1 < pos ? null : columnNames.get(pos); - } - - @Override - public int getColumnIndex(String name) { - if (name == null) { - throw new NullPointerException(); - } - return rowDesc.columnNames().indexOf(name); - } - @Override public Temporal getTemporal(int pos) { throw new UnsupportedOperationException(buildIllegalAccessMessage(getValue(pos), getColumnName(pos), Temporal.class)); @@ -241,7 +223,7 @@ private GeometryCollection getGeometryCollection(int pos) { @Override public LocalTime getLocalTime(int pos) { - ColumnDefinition columnDefinition = rowDesc.get(pos); + ColumnDefinition columnDefinition = ((MySQLRowDescriptor)desc).get(pos); Object val = getValue(pos); if (columnDefinition.type() == DataType.TIME && val instanceof Duration) { // map MySQL TIME data type to java.time.LocalTime diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLRowDesc.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLRowDescriptor.java similarity index 76% rename from vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLRowDesc.java rename to vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLRowDescriptor.java index c7906c7dc4..fe09341172 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLRowDesc.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLRowDescriptor.java @@ -18,21 +18,21 @@ import io.vertx.mysqlclient.impl.datatype.DataFormat; import io.vertx.mysqlclient.impl.protocol.ColumnDefinition; -import io.vertx.sqlclient.internal.RowDesc; +import io.vertx.sqlclient.internal.RowDescriptorBase; -public class MySQLRowDesc extends RowDesc { +public class MySQLRowDescriptor extends RowDescriptorBase { private final ColumnDefinition[] columnDefinitions; private final DataFormat dataFormat; - private MySQLRowDesc(ColumnDefinition[] columnDefinitions, DataFormat dataFormat) { + private MySQLRowDescriptor(ColumnDefinition[] columnDefinitions, DataFormat dataFormat) { super(columnDefinitions); this.columnDefinitions = columnDefinitions; this.dataFormat = dataFormat; } - public static MySQLRowDesc create(ColumnDefinition[] columnDefinitions, DataFormat dataFormat) { - return new MySQLRowDesc(columnDefinitions, dataFormat); + public static MySQLRowDescriptor create(ColumnDefinition[] columnDefinitions, DataFormat dataFormat) { + return new MySQLRowDescriptor(columnDefinitions, dataFormat); } public ColumnDefinition[] columnDefinitions() { diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLSocketConnection.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLSocketConnection.java index 560c1614c4..3d96849aed 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLSocketConnection.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/MySQLSocketConnection.java @@ -28,17 +28,23 @@ import io.vertx.mysqlclient.MySQLConnectOptions; import io.vertx.mysqlclient.SslMode; import io.vertx.mysqlclient.impl.codec.ClearCachedStatementsEvent; +import io.vertx.mysqlclient.impl.codec.CommandCodec; +import io.vertx.mysqlclient.impl.codec.ExtendedBatchQueryCommandCodec; +import io.vertx.mysqlclient.impl.codec.ExtendedQueryCommandCodec; import io.vertx.mysqlclient.impl.codec.MySQLCodec; import io.vertx.mysqlclient.impl.codec.MySQLPacketDecoder; +import io.vertx.mysqlclient.impl.codec.MySQLPreparedStatement; import io.vertx.mysqlclient.impl.command.InitialHandshakeCommand; import io.vertx.sqlclient.SqlConnectOptions; -import io.vertx.sqlclient.internal.Connection; +import io.vertx.sqlclient.codec.CommandMessage; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.internal.PreparedStatement; import io.vertx.sqlclient.internal.QueryResultHandler; -import io.vertx.sqlclient.impl.SocketConnectionBase; -import io.vertx.sqlclient.internal.command.CommandBase; -import io.vertx.sqlclient.internal.command.QueryCommandBase; -import io.vertx.sqlclient.internal.command.SimpleQueryCommand; -import io.vertx.sqlclient.internal.command.TxCommand; +import io.vertx.sqlclient.codec.SocketConnectionBase; +import io.vertx.sqlclient.spi.protocol.CommandBase; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; +import io.vertx.sqlclient.spi.protocol.SimpleQueryCommand; +import io.vertx.sqlclient.spi.protocol.TxCommand; import io.vertx.sqlclient.spi.DatabaseMetadata; import java.nio.charset.Charset; @@ -96,17 +102,31 @@ public void init() { super.init(); } + @Override + protected CommandMessage toMessage(ExtendedQueryCommand command, PreparedStatement preparedStatement) { + if (command.isBatch()) { + return new ExtendedBatchQueryCommandCodec<>(command, (MySQLPreparedStatement) preparedStatement); + } else { + return new ExtendedQueryCommandCodec<>(command, (MySQLPreparedStatement) preparedStatement); + } + } + + @Override + protected CommandMessage toMessage(CommandBase command) { + return CommandCodec.wrap(command); + } + @Override protected void doSchedule(CommandBase cmd, Completable handler) { if (cmd instanceof TxCommand) { TxCommand tx = (TxCommand) cmd; SimpleQueryCommand cmd2 = new SimpleQueryCommand<>( - tx.kind.sql, + tx.kind().sql(), false, false, - QueryCommandBase.NULL_COLLECTOR, + SocketConnectionBase.NULL_COLLECTOR, QueryResultHandler.NOOP_HANDLER); - super.doSchedule(cmd2, (res, err) -> handler.complete(tx.result, err)); + super.doSchedule(cmd2, (res, err) -> handler.complete(tx.result(), err)); } else { super.doSchedule(cmd, handler); } @@ -121,12 +141,6 @@ protected void handleMessage(Object msg) { } } - private void clearCachedStatements() { - if (this.psCache != null) { - this.psCache.clear(); - } - } - public Future upgradeToSsl(ClientSSLOptions sslOptions) { return socket.upgradeToSsl(sslOptions); } @@ -137,7 +151,7 @@ public String system() { } @Override - public DatabaseMetadata getDatabaseMetaData() { + public DatabaseMetadata databaseMetadata() { return metaData; } } diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/AuthenticationCommandBaseCodec.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/AuthenticationCommandBaseCodec.java index 84c96299b4..2fa894a492 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/AuthenticationCommandBaseCodec.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/AuthenticationCommandBaseCodec.java @@ -16,7 +16,7 @@ import io.vertx.mysqlclient.impl.command.AuthenticationCommandBase; import io.vertx.mysqlclient.impl.util.BufferUtils; import io.vertx.mysqlclient.impl.util.RsaPublicKeyEncryptor; -import io.vertx.sqlclient.internal.command.CommandResponse; +import io.vertx.sqlclient.codec.CommandResponse; import java.nio.charset.StandardCharsets; import java.util.Arrays; diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/ChangeUserCommandCodec.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/ChangeUserCommandCodec.java index ea00cb4d25..60015a65ce 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/ChangeUserCommandCodec.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/ChangeUserCommandCodec.java @@ -18,7 +18,7 @@ import io.vertx.mysqlclient.impl.util.BufferUtils; import io.vertx.mysqlclient.impl.util.CachingSha2Authenticator; import io.vertx.mysqlclient.impl.util.Native41Authenticator; -import io.vertx.sqlclient.internal.command.CommandResponse; +import io.vertx.sqlclient.codec.CommandResponse; import java.nio.charset.StandardCharsets; import java.util.Map; diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/CloseConnectionCommandCodec.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/CloseConnectionCommandCodec.java index f62ea556ac..c26b618b05 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/CloseConnectionCommandCodec.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/CloseConnectionCommandCodec.java @@ -13,7 +13,7 @@ import io.netty.buffer.ByteBuf; import io.vertx.mysqlclient.impl.protocol.CommandType; -import io.vertx.sqlclient.internal.command.CloseConnectionCommand; +import io.vertx.sqlclient.spi.protocol.CloseConnectionCommand; class CloseConnectionCommandCodec extends CommandCodec { private static final int PAYLOAD_LENGTH = 1; diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/CloseStatementCommandCodec.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/CloseStatementCommandCodec.java index 9641622123..2801b19159 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/CloseStatementCommandCodec.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/CloseStatementCommandCodec.java @@ -13,8 +13,8 @@ import io.netty.buffer.ByteBuf; import io.vertx.mysqlclient.impl.protocol.CommandType; -import io.vertx.sqlclient.internal.command.CloseStatementCommand; -import io.vertx.sqlclient.internal.command.CommandResponse; +import io.vertx.sqlclient.spi.protocol.CloseStatementCommand; +import io.vertx.sqlclient.codec.CommandResponse; class CloseStatementCommandCodec extends CommandCodec { private static final int PAYLOAD_LENGTH = 5; diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/CommandCodec.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/CommandCodec.java index 00eb148623..0449c71938 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/CommandCodec.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/CommandCodec.java @@ -18,28 +18,74 @@ import io.netty.buffer.ByteBuf; import io.vertx.mysqlclient.MySQLException; +import io.vertx.mysqlclient.impl.command.ChangeUserCommand; +import io.vertx.mysqlclient.impl.command.DebugCommand; +import io.vertx.mysqlclient.impl.command.InitDbCommand; +import io.vertx.mysqlclient.impl.command.InitialHandshakeCommand; +import io.vertx.mysqlclient.impl.command.PingCommand; +import io.vertx.mysqlclient.impl.command.ResetConnectionCommand; +import io.vertx.mysqlclient.impl.command.SetOptionCommand; +import io.vertx.mysqlclient.impl.command.StatisticsCommand; import io.vertx.mysqlclient.impl.datatype.DataType; import io.vertx.mysqlclient.impl.protocol.CapabilitiesFlag; import io.vertx.mysqlclient.impl.protocol.ColumnDefinition; import io.vertx.mysqlclient.impl.util.BufferUtils; -import io.vertx.sqlclient.internal.command.CommandBase; -import io.vertx.sqlclient.internal.command.CommandResponse; +import io.vertx.sqlclient.codec.CommandMessage; +import io.vertx.sqlclient.spi.protocol.CloseConnectionCommand; +import io.vertx.sqlclient.spi.protocol.CloseCursorCommand; +import io.vertx.sqlclient.spi.protocol.CloseStatementCommand; +import io.vertx.sqlclient.spi.protocol.CommandBase; +import io.vertx.sqlclient.codec.CommandResponse; +import io.vertx.sqlclient.spi.protocol.PrepareStatementCommand; +import io.vertx.sqlclient.spi.protocol.SimpleQueryCommand; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import static io.vertx.mysqlclient.impl.protocol.Packets.*; -abstract class CommandCodec> { +public abstract class CommandCodec> extends CommandMessage { public Throwable failure; public R result; - final C cmd; MySQLEncoder encoder; int sequenceId; CommandCodec(C cmd) { - this.cmd = cmd; + super(cmd); + } + + public static CommandCodec wrap(CommandBase cmd) { + if (cmd instanceof InitialHandshakeCommand) { + return new InitialHandshakeCommandCodec((InitialHandshakeCommand) cmd); + } else if (cmd instanceof SimpleQueryCommand) { + return new SimpleQueryCommandCodec<>((SimpleQueryCommand) cmd); + } else if (cmd instanceof CloseConnectionCommand) { + return new CloseConnectionCommandCodec((CloseConnectionCommand) cmd); + } else if (cmd instanceof PrepareStatementCommand) { + return new PrepareStatementCodec((PrepareStatementCommand) cmd); + } else if (cmd instanceof CloseStatementCommand) { + return new CloseStatementCommandCodec((CloseStatementCommand) cmd); + } else if (cmd instanceof CloseCursorCommand) { + return new ResetStatementCommandCodec((CloseCursorCommand) cmd); + } else if (cmd instanceof PingCommand) { + return new PingCommandCodec((PingCommand) cmd); + } else if (cmd instanceof InitDbCommand) { + return new InitDbCommandCodec((InitDbCommand) cmd); + } else if (cmd instanceof StatisticsCommand) { + return new StatisticsCommandCodec((StatisticsCommand) cmd); + } else if (cmd instanceof SetOptionCommand) { + return new SetOptionCommandCodec((SetOptionCommand) cmd); + } else if (cmd instanceof ResetConnectionCommand) { + return new ResetConnectionCommandCodec((ResetConnectionCommand) cmd); + } else if (cmd instanceof DebugCommand) { + return new DebugCommandCodec((DebugCommand) cmd); + } else if (cmd instanceof ChangeUserCommand) { + return new ChangeUserCommandCodec((ChangeUserCommand) cmd); + } else { + System.out.println("Unsupported command " + cmd); + throw new UnsupportedOperationException("Todo"); + } } abstract void decodePayload(ByteBuf payload, int payloadLength); diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/ExtendedBatchQueryCommandCodec.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/ExtendedBatchQueryCommandCodec.java index 8f72f10a67..f7a17fb8f2 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/ExtendedBatchQueryCommandCodec.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/ExtendedBatchQueryCommandCodec.java @@ -16,25 +16,25 @@ import io.vertx.mysqlclient.MySQLBatchException; import io.vertx.mysqlclient.MySQLException; import io.vertx.sqlclient.Tuple; -import io.vertx.sqlclient.internal.TupleInternal; -import io.vertx.sqlclient.internal.command.CommandResponse; -import io.vertx.sqlclient.internal.command.ExtendedQueryCommand; +import io.vertx.sqlclient.internal.TupleBase; +import io.vertx.sqlclient.codec.CommandResponse; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; import java.util.BitSet; import java.util.List; import static io.vertx.mysqlclient.impl.protocol.Packets.EnumCursorType.*; -class ExtendedBatchQueryCommandCodec extends ExtendedQueryCommandBaseCodec> { +public class ExtendedBatchQueryCommandCodec extends ExtendedQueryCommandBaseCodec> { - private final List params; + private final List params; private final BitSet bindingFailures; private boolean pipeliningEnabled; private int sent; private int received; - ExtendedBatchQueryCommandCodec(ExtendedQueryCommand cmd) { - super(cmd); + public ExtendedBatchQueryCommandCodec(ExtendedQueryCommand cmd, MySQLPreparedStatement statement) { + super(cmd, statement); params = cmd.paramsList(); bindingFailures = new BitSet(params.size()); } diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/ExtendedQueryCommandBaseCodec.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/ExtendedQueryCommandBaseCodec.java index 71b4c51b85..27677e206b 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/ExtendedQueryCommandBaseCodec.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/ExtendedQueryCommandBaseCodec.java @@ -17,7 +17,7 @@ import io.vertx.mysqlclient.impl.datatype.DataTypeCodec; import io.vertx.mysqlclient.impl.protocol.CommandType; import io.vertx.sqlclient.Tuple; -import io.vertx.sqlclient.internal.command.ExtendedQueryCommand; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; import static io.vertx.mysqlclient.impl.protocol.Packets.*; @@ -25,9 +25,9 @@ abstract class ExtendedQueryCommandBaseCodec extends ExtendedQueryCommandBaseCodec> { - ExtendedQueryCommandCodec(ExtendedQueryCommand cmd) { - super(cmd); +public class ExtendedQueryCommandCodec extends ExtendedQueryCommandBaseCodec> { + public ExtendedQueryCommandCodec(ExtendedQueryCommand cmd, MySQLPreparedStatement statement) { + super(cmd, statement); if (cmd.fetch() > 0 && statement.isCursorOpen) { // restore the state we need for decoding fetch response based on the prepared statement columnDefinitions = statement.rowDesc.columnDefinitions(); diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/InitialHandshakeCommandCodec.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/InitialHandshakeCommandCodec.java index e623b2c455..fd6ad21524 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/InitialHandshakeCommandCodec.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/InitialHandshakeCommandCodec.java @@ -27,8 +27,8 @@ import io.vertx.mysqlclient.impl.util.BufferUtils; import io.vertx.mysqlclient.impl.util.CachingSha2Authenticator; import io.vertx.mysqlclient.impl.util.Native41Authenticator; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.internal.command.CommandResponse; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.codec.CommandResponse; import java.nio.charset.StandardCharsets; import java.util.Map; diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/MySQLCodec.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/MySQLCodec.java index bc1bb7c3df..f50e15d82b 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/MySQLCodec.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/MySQLCodec.java @@ -18,11 +18,8 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.CombinedChannelDuplexHandler; -import io.vertx.core.Completable; import io.vertx.mysqlclient.impl.MySQLSocketConnection; import io.vertx.sqlclient.ClosedConnectionException; -import io.vertx.sqlclient.internal.command.CommandBase; -import io.vertx.sqlclient.internal.command.CommandResponse; import java.util.ArrayDeque; import java.util.Iterator; @@ -81,10 +78,7 @@ private void clearInflightCommands(Throwable cause) { private void fail(CommandCodec codec, Throwable cause) { if (failure == null) { failure = cause; - Completable handler = codec.cmd.handler; - if (handler != null) { - handler.complete(null, cause); - } + codec.fail(cause); } } diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/MySQLEncoder.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/MySQLEncoder.java index 70d984bf7f..02ca755adb 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/MySQLEncoder.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/MySQLEncoder.java @@ -14,9 +14,9 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelPromise; +import io.vertx.core.Completable; import io.vertx.mysqlclient.impl.MySQLSocketConnection; -import io.vertx.mysqlclient.impl.command.*; -import io.vertx.sqlclient.internal.command.*; +import io.vertx.sqlclient.codec.CommandResponse; import java.nio.charset.Charset; @@ -41,8 +41,8 @@ public void handlerAdded(ChannelHandlerContext ctx) { @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - if (msg instanceof CommandBase) { - CommandBase cmd = (CommandBase) msg; + if (msg instanceof CommandCodec) { + CommandCodec cmd = (CommandCodec) msg; write(cmd); codec.checkFireAndForgetCommands(); } else { @@ -50,57 +50,15 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) } } - void write(CommandBase cmd) { - CommandCodec cmdCodec = wrap(cmd); - if (codec.add(cmdCodec)) { - cmdCodec.encode(this); + void write(CommandCodec cmd) { + if (codec.add(cmd)) { + cmd.encode(this); } } final void fireCommandResponse(CommandResponse commandResponse) { CommandCodec c = codec.poll(); - commandResponse.cmd = (CommandBase) c.cmd; + commandResponse.handler = (Completable) c.handler; chctx.fireChannelRead(commandResponse); } - - private CommandCodec wrap(CommandBase cmd) { - if (cmd instanceof InitialHandshakeCommand) { - return new InitialHandshakeCommandCodec((InitialHandshakeCommand) cmd); - } else if (cmd instanceof SimpleQueryCommand) { - return new SimpleQueryCommandCodec<>((SimpleQueryCommand) cmd); - } else if (cmd instanceof ExtendedQueryCommand) { - ExtendedQueryCommand queryCmd = (ExtendedQueryCommand) cmd; - if (queryCmd.isBatch()) { - return new ExtendedBatchQueryCommandCodec<>(queryCmd); - } else { - return new ExtendedQueryCommandCodec<>(queryCmd); - } - } else if (cmd instanceof CloseConnectionCommand) { - return new CloseConnectionCommandCodec((CloseConnectionCommand) cmd); - } else if (cmd instanceof PrepareStatementCommand) { - return new PrepareStatementCodec((PrepareStatementCommand) cmd); - } else if (cmd instanceof CloseStatementCommand) { - return new CloseStatementCommandCodec((CloseStatementCommand) cmd); - } else if (cmd instanceof CloseCursorCommand) { - return new ResetStatementCommandCodec((CloseCursorCommand) cmd); - } else if (cmd instanceof PingCommand) { - return new PingCommandCodec((PingCommand) cmd); - } else if (cmd instanceof InitDbCommand) { - return new InitDbCommandCodec((InitDbCommand) cmd); - } else if (cmd instanceof StatisticsCommand) { - return new StatisticsCommandCodec((StatisticsCommand) cmd); - } else if (cmd instanceof SetOptionCommand) { - return new SetOptionCommandCodec((SetOptionCommand) cmd); - } else if (cmd instanceof ResetConnectionCommand) { - return new ResetConnectionCommandCodec((ResetConnectionCommand) cmd); - } else if (cmd instanceof DebugCommand) { - return new DebugCommandCodec((DebugCommand) cmd); - } else if (cmd instanceof ChangeUserCommand) { - return new ChangeUserCommandCodec((ChangeUserCommand) cmd); - } else { - System.out.println("Unsupported command " + cmd); - throw new UnsupportedOperationException("Todo"); - } - } - } diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/MySQLPreparedStatement.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/MySQLPreparedStatement.java index ae5526856f..f637a6543c 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/MySQLPreparedStatement.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/MySQLPreparedStatement.java @@ -19,24 +19,23 @@ import io.vertx.core.VertxException; import io.vertx.mysqlclient.impl.MySQLParamDesc; -import io.vertx.mysqlclient.impl.MySQLRowDesc; +import io.vertx.mysqlclient.impl.MySQLRowDescriptor; import io.vertx.mysqlclient.impl.datatype.DataType; import io.vertx.mysqlclient.impl.datatype.DataTypeCodec; import io.vertx.sqlclient.Tuple; import io.vertx.sqlclient.impl.*; -import io.vertx.sqlclient.internal.ParamDesc; import io.vertx.sqlclient.internal.PreparedStatement; -import io.vertx.sqlclient.internal.RowDesc; -import io.vertx.sqlclient.internal.TupleInternal; +import io.vertx.sqlclient.internal.RowDescriptorBase; +import io.vertx.sqlclient.internal.TupleBase; import java.util.Arrays; -class MySQLPreparedStatement implements PreparedStatement { +public class MySQLPreparedStatement implements PreparedStatement { final long statementId; final String sql; final MySQLParamDesc paramDesc; - final MySQLRowDesc rowDesc; + final MySQLRowDescriptor rowDesc; final boolean closeAfterUsage; private boolean sendTypesToServer; @@ -44,7 +43,7 @@ class MySQLPreparedStatement implements PreparedStatement { boolean isCursorOpen; - MySQLPreparedStatement(String sql, long statementId, MySQLParamDesc paramDesc, MySQLRowDesc rowDesc, boolean closeAfterUsage) { + MySQLPreparedStatement(String sql, long statementId, MySQLParamDesc paramDesc, MySQLRowDescriptor rowDesc, boolean closeAfterUsage) { this.statementId = statementId; this.paramDesc = paramDesc; this.rowDesc = rowDesc; @@ -57,12 +56,7 @@ class MySQLPreparedStatement implements PreparedStatement { } @Override - public ParamDesc paramDesc() { - return paramDesc; - } - - @Override - public RowDesc rowDesc() { + public RowDescriptorBase rowDesc() { return rowDesc; } @@ -72,7 +66,7 @@ public String sql() { } @Override - public TupleInternal prepare(TupleInternal values) { + public TupleBase prepare(TupleBase values) { int numberOfParameters = values.size(); int paramDescLength = paramDesc.paramDefinitions().length; if (numberOfParameters != paramDescLength) { diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/PingCommandCodec.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/PingCommandCodec.java index 2a26448ddd..ee096ea30e 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/PingCommandCodec.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/PingCommandCodec.java @@ -14,7 +14,7 @@ import io.netty.buffer.ByteBuf; import io.vertx.mysqlclient.impl.command.PingCommand; import io.vertx.mysqlclient.impl.protocol.CommandType; -import io.vertx.sqlclient.internal.command.CommandResponse; +import io.vertx.sqlclient.codec.CommandResponse; class PingCommandCodec extends CommandCodec { private static final int PAYLOAD_LENGTH = 1; diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/PrepareStatementCodec.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/PrepareStatementCodec.java index 24bb73ea36..1303050053 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/PrepareStatementCodec.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/PrepareStatementCodec.java @@ -18,13 +18,13 @@ import io.netty.buffer.ByteBuf; import io.vertx.mysqlclient.impl.MySQLParamDesc; -import io.vertx.mysqlclient.impl.MySQLRowDesc; +import io.vertx.mysqlclient.impl.MySQLRowDescriptor; import io.vertx.mysqlclient.impl.datatype.DataFormat; import io.vertx.mysqlclient.impl.protocol.ColumnDefinition; import io.vertx.mysqlclient.impl.protocol.CommandType; import io.vertx.sqlclient.internal.PreparedStatement; -import io.vertx.sqlclient.internal.command.CommandResponse; -import io.vertx.sqlclient.internal.command.PrepareStatementCommand; +import io.vertx.sqlclient.codec.CommandResponse; +import io.vertx.sqlclient.spi.protocol.PrepareStatementCommand; import static io.vertx.mysqlclient.impl.protocol.Packets.ERROR_PACKET_HEADER; @@ -135,7 +135,7 @@ private void handleReadyForQuery() { cmd.sql(), this.statementId, new MySQLParamDesc(paramDescs), - MySQLRowDesc.create(columnDescs, DataFormat.BINARY), + MySQLRowDescriptor.create(columnDescs, DataFormat.BINARY), !cmd.isManaged()))); } diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/QueryCommandBaseCodec.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/QueryCommandBaseCodec.java index 37c6aa3296..a410528f85 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/QueryCommandBaseCodec.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/QueryCommandBaseCodec.java @@ -18,14 +18,14 @@ import io.netty.buffer.ByteBuf; import io.vertx.mysqlclient.MySQLClient; -import io.vertx.mysqlclient.impl.MySQLRowDesc; +import io.vertx.mysqlclient.impl.MySQLRowDescriptor; import io.vertx.mysqlclient.impl.datatype.DataFormat; import io.vertx.mysqlclient.impl.protocol.ColumnDefinition; import io.vertx.mysqlclient.impl.util.BufferUtils; import io.vertx.sqlclient.Row; -import io.vertx.sqlclient.internal.RowDesc; -import io.vertx.sqlclient.internal.command.CommandResponse; -import io.vertx.sqlclient.internal.command.QueryCommandBase; +import io.vertx.sqlclient.internal.RowDescriptorBase; +import io.vertx.sqlclient.codec.CommandResponse; +import io.vertx.sqlclient.spi.protocol.QueryCommandBase; import java.util.stream.Collector; @@ -93,7 +93,7 @@ protected void handleResultsetColumnDefinitions(ByteBuf payload) { protected void handleResultsetColumnDefinitionsDecodingCompleted() { commandHandlerState = CommandHandlerState.HANDLING_ROW_DATA_OR_END_PACKET; - MySQLRowDesc mySQLRowDesc = MySQLRowDesc.create(columnDefinitions, format); // use the column definitions if provided by execute or fetch response instead of prepare response + MySQLRowDescriptor mySQLRowDesc = MySQLRowDescriptor.create(columnDefinitions, format); // use the column definitions if provided by execute or fetch response instead of prepare response decoder = new RowResultDecoder<>(cmd.collector(), mySQLRowDesc); } @@ -146,20 +146,20 @@ private void handleSingleResultsetEndPacket(int serverStatusFlags, int affectedR T result; Throwable failure; int size; - RowDesc rowDesc; + RowDescriptorBase rowDescriptor; if (decoder != null) { failure = decoder.complete(); result = decoder.result(); - rowDesc = decoder.rowDesc; + rowDescriptor = decoder.rowDesc; size = decoder.size(); decoder.reset(); } else { result = emptyResult(cmd.collector()); failure = null; size = 0; - rowDesc = null; + rowDescriptor = null; } - cmd.resultHandler().handleResult(affectedRows, size, rowDesc, result, failure); + cmd.resultHandler().handleResult(affectedRows, size, rowDescriptor, result, failure); if (lastInsertId > 0) { cmd.resultHandler().addProperty(MySQLClient.LAST_INSERTED_ID, lastInsertId); } diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/ResetStatementCommandCodec.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/ResetStatementCommandCodec.java index 0ddc12aa08..1e3ed6b5ec 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/ResetStatementCommandCodec.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/ResetStatementCommandCodec.java @@ -13,7 +13,7 @@ import io.netty.buffer.ByteBuf; import io.vertx.mysqlclient.impl.protocol.CommandType; -import io.vertx.sqlclient.internal.command.CloseCursorCommand; +import io.vertx.sqlclient.spi.protocol.CloseCursorCommand; class ResetStatementCommandCodec extends CommandCodec { private static final int PAYLOAD_LENGTH = 5; diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/RowResultDecoder.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/RowResultDecoder.java index 4005403c14..a91dd3b227 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/RowResultDecoder.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/RowResultDecoder.java @@ -12,8 +12,8 @@ package io.vertx.mysqlclient.impl.codec; import io.netty.buffer.ByteBuf; -import io.vertx.mysqlclient.impl.MySQLRowDesc; -import io.vertx.mysqlclient.impl.MySQLRowImpl; +import io.vertx.mysqlclient.impl.MySQLRowDescriptor; +import io.vertx.mysqlclient.impl.MySQLRow; import io.vertx.mysqlclient.impl.datatype.DataFormat; import io.vertx.mysqlclient.impl.datatype.DataType; import io.vertx.mysqlclient.impl.datatype.DataTypeCodec; @@ -27,16 +27,16 @@ class RowResultDecoder extends RowDecoder { private static final int NULL = 0xFB; - MySQLRowDesc rowDesc; + MySQLRowDescriptor rowDesc; - RowResultDecoder(Collector collector, MySQLRowDesc rowDesc) { + RowResultDecoder(Collector collector, MySQLRowDescriptor rowDesc) { super(collector); this.rowDesc = rowDesc; } @Override protected RowInternal row() { - return new MySQLRowImpl(rowDesc); + return new MySQLRow(rowDesc); } @Override diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/SimpleQueryCommandCodec.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/SimpleQueryCommandCodec.java index 9d7d8d8658..b6a1779878 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/SimpleQueryCommandCodec.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/SimpleQueryCommandCodec.java @@ -20,7 +20,7 @@ import io.vertx.core.Future; import io.vertx.mysqlclient.impl.datatype.DataFormat; import io.vertx.mysqlclient.impl.protocol.CommandType; -import io.vertx.sqlclient.internal.command.SimpleQueryCommand; +import io.vertx.sqlclient.spi.protocol.SimpleQueryCommand; import java.io.File; import java.nio.charset.StandardCharsets; diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/StatisticsCommandCodec.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/StatisticsCommandCodec.java index 2ee782f2f4..64d3cf554c 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/StatisticsCommandCodec.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/codec/StatisticsCommandCodec.java @@ -14,7 +14,7 @@ import io.netty.buffer.ByteBuf; import io.vertx.mysqlclient.impl.command.StatisticsCommand; import io.vertx.mysqlclient.impl.protocol.CommandType; -import io.vertx.sqlclient.internal.command.CommandResponse; +import io.vertx.sqlclient.codec.CommandResponse; class StatisticsCommandCodec extends CommandCodec { private static final int PAYLOAD_LENGTH = 1; diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/AuthenticationCommandBase.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/AuthenticationCommandBase.java index 85545736e4..1ecc22c92c 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/AuthenticationCommandBase.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/AuthenticationCommandBase.java @@ -13,7 +13,7 @@ import io.vertx.core.buffer.Buffer; import io.vertx.mysqlclient.impl.MySQLCollation; -import io.vertx.sqlclient.internal.command.CommandBase; +import io.vertx.sqlclient.spi.protocol.CommandBase; import java.util.Map; diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/DebugCommand.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/DebugCommand.java index 027038b40b..b4fb62277f 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/DebugCommand.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/DebugCommand.java @@ -11,7 +11,7 @@ package io.vertx.mysqlclient.impl.command; -import io.vertx.sqlclient.internal.command.CommandBase; +import io.vertx.sqlclient.spi.protocol.CommandBase; public class DebugCommand extends CommandBase { } diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/InitDbCommand.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/InitDbCommand.java index e9715f1a61..9bec20e314 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/InitDbCommand.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/InitDbCommand.java @@ -11,7 +11,7 @@ package io.vertx.mysqlclient.impl.command; -import io.vertx.sqlclient.internal.command.CommandBase; +import io.vertx.sqlclient.spi.protocol.CommandBase; public class InitDbCommand extends CommandBase { private final String schemaName; diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/InitialHandshakeCommand.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/InitialHandshakeCommand.java index 4cb001e2f4..7cb3817fa1 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/InitialHandshakeCommand.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/InitialHandshakeCommand.java @@ -16,8 +16,8 @@ import io.vertx.mysqlclient.MySQLAuthenticationPlugin; import io.vertx.mysqlclient.SslMode; import io.vertx.mysqlclient.impl.MySQLCollation; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.impl.SocketConnectionBase; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.codec.SocketConnectionBase; import java.nio.charset.Charset; import java.util.Map; diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/PingCommand.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/PingCommand.java index cf2a8045e9..8117661052 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/PingCommand.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/PingCommand.java @@ -11,7 +11,7 @@ package io.vertx.mysqlclient.impl.command; -import io.vertx.sqlclient.internal.command.CommandBase; +import io.vertx.sqlclient.spi.protocol.CommandBase; public class PingCommand extends CommandBase { } diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/ResetConnectionCommand.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/ResetConnectionCommand.java index ba699a6608..a7633a5bdf 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/ResetConnectionCommand.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/ResetConnectionCommand.java @@ -11,7 +11,7 @@ package io.vertx.mysqlclient.impl.command; -import io.vertx.sqlclient.internal.command.CommandBase; +import io.vertx.sqlclient.spi.protocol.CommandBase; public class ResetConnectionCommand extends CommandBase { } diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/SetOptionCommand.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/SetOptionCommand.java index 0f8ca98fa4..0ed138460e 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/SetOptionCommand.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/SetOptionCommand.java @@ -12,7 +12,7 @@ package io.vertx.mysqlclient.impl.command; import io.vertx.mysqlclient.MySQLSetOption; -import io.vertx.sqlclient.internal.command.CommandBase; +import io.vertx.sqlclient.spi.protocol.CommandBase; public class SetOptionCommand extends CommandBase { private final MySQLSetOption mySQLSetOption; diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/StatisticsCommand.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/StatisticsCommand.java index dfe537e140..30f5fc19ba 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/StatisticsCommand.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/command/StatisticsCommand.java @@ -11,7 +11,7 @@ package io.vertx.mysqlclient.impl.command; -import io.vertx.sqlclient.internal.command.CommandBase; +import io.vertx.sqlclient.spi.protocol.CommandBase; public class StatisticsCommand extends CommandBase { } diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/datatype/DataTypeCodec.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/datatype/DataTypeCodec.java index 9789f1a6f2..19d73fb864 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/datatype/DataTypeCodec.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/impl/datatype/DataTypeCodec.java @@ -24,7 +24,7 @@ import io.vertx.core.buffer.Buffer; import io.vertx.sqlclient.Tuple; import io.vertx.sqlclient.data.Numeric; -import io.vertx.sqlclient.impl.codec.CommonCodec; +import io.vertx.sqlclient.impl.Utils; import java.math.BigInteger; import java.nio.charset.Charset; @@ -637,23 +637,23 @@ private static Object binaryDecodeJson(int collationId, ByteBuf buffer) { } private static Byte textDecodeInt8(ByteBuf buffer, int index, int length) { - return (byte) CommonCodec.decodeDecStringToLong(index, length, buffer); + return (byte) Utils.decodeDecStringToLong(index, length, buffer); } private static Short textDecodeInt16(ByteBuf buffer, int index, int length) { - return (short) CommonCodec.decodeDecStringToLong(index, length, buffer); + return (short) Utils.decodeDecStringToLong(index, length, buffer); } private static Integer textDecodeInt24(ByteBuf buffer, int index, int length) { - return (int) CommonCodec.decodeDecStringToLong(index, length, buffer); + return (int) Utils.decodeDecStringToLong(index, length, buffer); } private static Integer textDecodeInt32(ByteBuf buffer, int index, int length) { - return (int) CommonCodec.decodeDecStringToLong(index, length, buffer); + return (int) Utils.decodeDecStringToLong(index, length, buffer); } private static Long textDecodeInt64(ByteBuf buffer, int index, int length) { - return CommonCodec.decodeDecStringToLong(index, length, buffer); + return Utils.decodeDecStringToLong(index, length, buffer); } private static Float textDecodeFloat(int collationId, ByteBuf buffer, int index, int length) { diff --git a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/spi/MySQLDriver.java b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/spi/MySQLDriver.java index 76c8422f78..391954c3a2 100644 --- a/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/spi/MySQLDriver.java +++ b/vertx-mysql-client/src/main/java/io/vertx/mysqlclient/spi/MySQLDriver.java @@ -29,42 +29,35 @@ import io.vertx.sqlclient.PoolOptions; import io.vertx.sqlclient.SqlConnectOptions; import io.vertx.sqlclient.SqlConnection; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.internal.pool.CloseablePool; -import io.vertx.sqlclient.internal.pool.PoolImpl; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.impl.pool.PoolImpl; import io.vertx.sqlclient.internal.SqlConnectionInternal; -import io.vertx.sqlclient.spi.ConnectionFactory; -import io.vertx.sqlclient.spi.Driver; +import io.vertx.sqlclient.spi.connection.ConnectionFactory; +import io.vertx.sqlclient.spi.DriverBase; import java.util.function.Supplier; -public class MySQLDriver implements Driver { +public class MySQLDriver extends DriverBase { - private static final String SHARED_CLIENT_KEY = "__vertx.shared.mysqlclient"; + private static final String DISCRIMINANT = "mysqlclient"; public static final MySQLDriver INSTANCE = new MySQLDriver(); + public MySQLDriver() { + super(DISCRIMINANT); + } + @Override public MySQLConnectOptions downcast(SqlConnectOptions connectOptions) { return connectOptions instanceof MySQLConnectOptions ? (MySQLConnectOptions) connectOptions : new MySQLConnectOptions(connectOptions); } @Override - public Pool newPool(Vertx vertx, Supplier> databases, PoolOptions options, NetClientOptions transportOptions, Handler connectHandler, CloseFuture closeFuture) { - VertxInternal vx = (VertxInternal) vertx; - PoolImpl pool; - if (options.isShared()) { - pool = vx.createSharedResource(SHARED_CLIENT_KEY, options.getName(), closeFuture, cf -> newPoolImpl(vx, connectHandler, databases, options, transportOptions, cf)); - } else { - pool = newPoolImpl(vx, connectHandler, databases, options, transportOptions, closeFuture); - } - return new CloseablePool(vx, closeFuture, pool); - } - - private PoolImpl newPoolImpl(VertxInternal vertx, Handler connectHandler, Supplier> databases, PoolOptions poolOptions, NetClientOptions transportOptions, CloseFuture closeFuture) { + protected Pool newPool(VertxInternal vertx, Handler connectHandler, Supplier> databases, PoolOptions poolOptions, NetClientOptions transportOptions, CloseFuture closeFuture) { boolean pipelinedPool = poolOptions instanceof MySQLPoolOptions && ((MySQLPoolOptions) poolOptions).isPipelined(); ConnectionFactory factory = createConnectionFactory(vertx, transportOptions); - PoolImpl pool = new PoolImpl(vertx, this, pipelinedPool, poolOptions, null, null, context -> factory.connect(context, databases.get()), connectHandler, closeFuture); + PoolImpl pool = new PoolImpl(vertx, this, pipelinedPool, poolOptions, null, null, factory, + databases, connectHandler, this::wrapConnection, closeFuture); pool.init(); closeFuture.add(factory); return pool; @@ -87,7 +80,7 @@ public ConnectionFactory createConnectionFactory(Vertx vert } @Override - public SqlConnectionInternal wrapConnection(ContextInternal context, ConnectionFactory factory, Connection conn) { - return new MySQLConnectionImpl(context, factory, conn); + public SqlConnectionInternal wrapConnection(ContextInternal context, ConnectionFactory factory, Connection connection) { + return new MySQLConnectionImpl(context, factory, connection); } } diff --git a/vertx-mysql-client/src/main/java/module-info.java b/vertx-mysql-client/src/main/java/module-info.java index bf2627e566..c75ee9b32f 100644 --- a/vertx-mysql-client/src/main/java/module-info.java +++ b/vertx-mysql-client/src/main/java/module-info.java @@ -6,6 +6,7 @@ requires io.netty.handler; requires io.netty.transport; requires io.vertx.sql.client; + requires io.vertx.sql.client.codec; requires io.vertx.core; requires io.vertx.core.logging; requires java.sql; diff --git a/vertx-mysql-client/src/test/java/io/vertx/tests/mysqlclient/impl/MySQLRowImplTest.java b/vertx-mysql-client/src/test/java/io/vertx/tests/mysqlclient/impl/MySQLRowTest.java similarity index 80% rename from vertx-mysql-client/src/test/java/io/vertx/tests/mysqlclient/impl/MySQLRowImplTest.java rename to vertx-mysql-client/src/test/java/io/vertx/tests/mysqlclient/impl/MySQLRowTest.java index de6a3f8507..cda56e8774 100644 --- a/vertx-mysql-client/src/test/java/io/vertx/tests/mysqlclient/impl/MySQLRowImplTest.java +++ b/vertx-mysql-client/src/test/java/io/vertx/tests/mysqlclient/impl/MySQLRowTest.java @@ -11,8 +11,8 @@ package io.vertx.tests.mysqlclient.impl; -import io.vertx.mysqlclient.impl.MySQLRowDesc; -import io.vertx.mysqlclient.impl.MySQLRowImpl; +import io.vertx.mysqlclient.impl.MySQLRowDescriptor; +import io.vertx.mysqlclient.impl.MySQLRow; import io.vertx.mysqlclient.impl.protocol.ColumnDefinition; import org.junit.Test; @@ -21,14 +21,14 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; -public class MySQLRowImplTest { +public class MySQLRowTest { enum EnumValue { SOME, NONE } @Test public void testGetNullEnum() { - MySQLRowImpl row = new MySQLRowImpl(MySQLRowDesc.create(new ColumnDefinition[0], null)); + MySQLRow row = new MySQLRow(MySQLRowDescriptor.create(new ColumnDefinition[0], null)); row.addValue(null); assertNull(row.get(EnumValue.class, 0)); diff --git a/vertx-mysql-client/src/test/java/module-info.java b/vertx-mysql-client/src/test/java/module-info.java index 2cfcc843eb..db15736219 100644 --- a/vertx-mysql-client/src/test/java/module-info.java +++ b/vertx-mysql-client/src/test/java/module-info.java @@ -10,5 +10,6 @@ requires io.vertx.testing.unit; requires junit; requires testcontainers; + requires com.github.dockerjava.api; } diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleConnectionFactory.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleConnectionFactory.java index f19fdfc1cf..cf19c3199c 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleConnectionFactory.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleConnectionFactory.java @@ -13,7 +13,6 @@ import io.vertx.core.Completable; import io.vertx.core.Context; import io.vertx.core.Future; -import io.vertx.core.Promise; import io.vertx.core.internal.ContextInternal; import io.vertx.core.internal.VertxInternal; import io.vertx.core.json.JsonObject; @@ -21,8 +20,8 @@ import io.vertx.core.spi.metrics.VertxMetrics; import io.vertx.oracleclient.OracleConnectOptions; import io.vertx.sqlclient.SqlConnectOptions; -import io.vertx.sqlclient.SqlConnection; -import io.vertx.sqlclient.spi.ConnectionFactory; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.spi.connection.ConnectionFactory; import oracle.jdbc.OracleConnection; import oracle.jdbc.datasource.OracleDataSource; @@ -59,7 +58,7 @@ private OracleDataSource getDatasource(SqlConnectOptions options) { } @Override - public Future connect(Context context, OracleConnectOptions options) { + public Future connect(Context context, OracleConnectOptions options) { OracleDataSource datasource = getDatasource(options); VertxMetrics vertxMetrics = ((VertxInternal)context.owner()).metrics(); ClientMetrics metrics = vertxMetrics != null ? vertxMetrics.createClientMetrics(options.getSocketAddress(), "sql", options.getMetricsName()) : null; @@ -68,9 +67,7 @@ public Future connect(Context context, OracleConnectOptions optio OracleConnection orac = datasource.createConnectionBuilder().build(); OracleMetadata metadata = new OracleMetadata(orac.getMetaData()); OracleJdbcConnection conn = new OracleJdbcConnection(ctx, metrics, options, orac, metadata); - OracleConnectionImpl msConn = new OracleConnectionImpl(ctx, this, conn); - conn.init(msConn); - return msConn; + return conn; }); } } diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleConnectionImpl.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleConnectionImpl.java index 6c428c0b3a..c0f8cd799e 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleConnectionImpl.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleConnectionImpl.java @@ -17,9 +17,9 @@ import io.vertx.oracleclient.OracleConnectOptions; import io.vertx.oracleclient.OracleConnection; import io.vertx.oracleclient.spi.OracleDriver; -import io.vertx.sqlclient.internal.Connection; +import io.vertx.sqlclient.spi.connection.Connection; import io.vertx.sqlclient.internal.SqlConnectionBase; -import io.vertx.sqlclient.spi.ConnectionFactory; +import io.vertx.sqlclient.spi.connection.ConnectionFactory; public class OracleConnectionImpl extends SqlConnectionBase implements OracleConnection { @@ -30,6 +30,11 @@ public OracleConnectionImpl(ContextInternal context, ConnectionFactory factory, public static Future connect(Vertx vertx, OracleConnectOptions options) { ContextInternal ctx = (ContextInternal) vertx.getOrCreateContext(); OracleConnectionFactory client = new OracleConnectionFactory(ctx.owner()); - return prepareForClose(ctx, client.connect(ctx, options)).map(OracleConnection::cast); + return client.connect(ctx, options).map(conn -> { + OracleConnectionImpl impl = new OracleConnectionImpl(ctx, client, conn); + conn.init(impl); + prepareForClose(ctx, impl); + return impl; + }); } } diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleJdbcConnection.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleJdbcConnection.java index 8ed768d37a..6971788725 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleJdbcConnection.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleJdbcConnection.java @@ -20,9 +20,17 @@ import io.vertx.core.tracing.TracingPolicy; import io.vertx.oracleclient.OracleConnectOptions; import io.vertx.oracleclient.impl.commands.*; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.internal.command.*; +import io.vertx.sqlclient.spi.connection.Connection; import io.vertx.sqlclient.spi.DatabaseMetadata; +import io.vertx.sqlclient.spi.connection.ConnectionContext; +import io.vertx.sqlclient.spi.protocol.CloseConnectionCommand; +import io.vertx.sqlclient.spi.protocol.CloseCursorCommand; +import io.vertx.sqlclient.spi.protocol.CloseStatementCommand; +import io.vertx.sqlclient.spi.protocol.CommandBase; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; +import io.vertx.sqlclient.spi.protocol.PrepareStatementCommand; +import io.vertx.sqlclient.spi.protocol.SimpleQueryCommand; +import io.vertx.sqlclient.spi.protocol.TxCommand; import oracle.jdbc.OracleConnection; import java.sql.SQLException; @@ -35,6 +43,8 @@ public class OracleJdbcConnection implements Connection { + private static final Completable NULL_HANDLER = (res, err) -> {}; + private static final Logger log = LoggerFactory.getLogger(OracleJdbcConnection.class); private final ClientMetrics metrics; @@ -44,11 +54,12 @@ public class OracleJdbcConnection implements Connection { private final OracleConnectOptions options; @SuppressWarnings("rawtypes") private final ConcurrentMap cursors = new ConcurrentHashMap<>(); - private Holder holder; + private ConnectionContext holder; // Command pipeline state @SuppressWarnings("rawtypes") private final Deque pending = new ArrayDeque<>(); + private final Deque> completables = new ArrayDeque<>(); private Promise closePromise; private boolean inflight, executing; @@ -65,11 +76,6 @@ public ClientMetrics metrics() { return metrics; } - @Override - public int pipeliningLimit() { - return 1; - } - @Override public TracingPolicy tracingPolicy() { return options.getTracingPolicy(); @@ -96,8 +102,8 @@ public SocketAddress server() { } @Override - public void init(Holder holder) { - this.holder = holder; + public void init(ConnectionContext context) { + this.holder = context; } @Override @@ -116,18 +122,19 @@ public boolean isValid() { } @Override - public DatabaseMetadata getDatabaseMetaData() { + public DatabaseMetadata databaseMetadata() { return metadata; } @Override - public void close(Holder holder, Completable promise) { + public void close(ConnectionContext holder, Completable promise) { if (Vertx.currentContext() == context) { Future future; if (closePromise == null) { closePromise = context.promise(); future = closePromise.future().andThen(ar -> holder.handleClosed()); pending.add(CloseConnectionCommand.INSTANCE); + completables.add(NULL_HANDLER); checkPending(); } else { future = closePromise.future(); @@ -138,16 +145,6 @@ public void close(Holder holder, Completable promise) { } } - @Override - public int getProcessId() { - throw new UnsupportedOperationException(); - } - - @Override - public int getSecretKey() { - throw new UnsupportedOperationException(); - } - public Future afterAcquire() { PromiseInternal promise = context.owner().promise(); context.executeBlocking(() -> { @@ -172,12 +169,12 @@ public void schedule(CommandBase cmd, Completable handler) { } private void doSchedule(CommandBase cmd, Completable handler) { - cmd.handler = handler; if (closePromise == null) { pending.add(cmd); + completables.add(handler); checkPending(); } else { - cmd.fail(VertxException.noStackTrace("Connection is no longer active")); + handler.fail(VertxException.noStackTrace("Connection is no longer active")); } } @@ -190,14 +187,15 @@ private void checkPending() { executing = true; CommandBase cmd; while (!inflight && (cmd = pending.poll()) != null) { + Completable handler = completables.poll(); inflight = true; if (metrics != null && cmd instanceof CloseConnectionCommand) { metrics.close(); } OracleCommand action = wrap(cmd); - Future future = action.processCommand(cmd); + Future future = action.processCommand(handler); CommandBase capture = cmd; - future.onComplete(ar -> actionComplete(capture, action, ar)); + future.onComplete(ar -> actionComplete(action, ar)); } } finally { executing = false; @@ -248,7 +246,7 @@ private OracleCommand forExtendedQuery(ExtendedQueryCommand cmd) { return action; } - private void actionComplete(CommandBase cmd, OracleCommand action, AsyncResult ar) { + private void actionComplete(OracleCommand action, AsyncResult ar) { inflight = false; Future future = Future.succeededFuture(); if (ar.failed()) { diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleRow.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleRow.java index e8868543c2..55f4c1ec7f 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleRow.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleRow.java @@ -15,30 +15,19 @@ import io.vertx.core.json.JsonObject; import io.vertx.sqlclient.data.Numeric; import io.vertx.sqlclient.impl.RowBase; -import io.vertx.sqlclient.internal.RowDesc; +import io.vertx.sqlclient.internal.RowDescriptorBase; import java.time.*; -import java.util.List; import java.util.UUID; public class OracleRow extends RowBase { - private final RowDesc desc; - - public OracleRow(RowDesc desc) { - super(desc.columnNames().size()); - this.desc = desc; + public OracleRow(RowDescriptorBase desc) { + super(desc); } public OracleRow(OracleRow row) { - super(row); - this.desc = row.desc; - } - - @Override - public String getColumnName(int pos) { - List columnNames = desc.columnNames(); - return pos < 0 || columnNames.size() - 1 < pos ? null : columnNames.get(pos); + super(row.desc, row); } @Override @@ -46,7 +35,7 @@ public int getColumnIndex(String name) { if (name == null) { throw new NullPointerException(); } - return desc.columnNames().indexOf(name.toUpperCase()); + return super.getColumnIndex(name.toUpperCase()); } @Override diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleRowDesc.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleRowDescriptor.java similarity index 66% rename from vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleRowDesc.java rename to vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleRowDescriptor.java index 36faba690c..0e32f43010 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleRowDesc.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/OracleRowDescriptor.java @@ -11,20 +11,20 @@ package io.vertx.oracleclient.impl; -import io.vertx.sqlclient.internal.RowDesc; +import io.vertx.sqlclient.internal.RowDescriptorBase; import java.sql.ResultSetMetaData; import java.sql.SQLException; -public class OracleRowDesc extends RowDesc { +public class OracleRowDescriptor extends RowDescriptorBase { - public static final OracleRowDesc EMPTY = new OracleRowDesc(new OracleColumnDesc[0]); + public static final OracleRowDescriptor EMPTY = new OracleRowDescriptor(new OracleColumnDesc[0]); - private OracleRowDesc(OracleColumnDesc[] columnDescriptors) { + private OracleRowDescriptor(OracleColumnDesc[] columnDescriptors) { super(columnDescriptors); } - public static OracleRowDesc create(ResultSetMetaData metaData) throws SQLException { + public static OracleRowDescriptor create(ResultSetMetaData metaData) throws SQLException { if (metaData == null) { return EMPTY; } @@ -33,6 +33,6 @@ public static OracleRowDesc create(ResultSetMetaData metaData) throws SQLExcepti for (int i = 0; i < cols; i++) { columnDescriptors[i] = new OracleColumnDesc(metaData, i + 1); } - return new OracleRowDesc(columnDescriptors); + return new OracleRowDescriptor(columnDescriptors); } } diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/RowReader.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/RowReader.java index 4348047fdf..f54e55ce2c 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/RowReader.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/RowReader.java @@ -18,7 +18,7 @@ import io.vertx.oracleclient.OracleException; import io.vertx.oracleclient.impl.commands.OracleResponse; import io.vertx.sqlclient.Row; -import io.vertx.sqlclient.internal.RowDesc; +import io.vertx.sqlclient.internal.RowDescriptorBase; import oracle.jdbc.OracleResultSet; import java.sql.ResultSetMetaData; @@ -40,7 +40,7 @@ public class RowReader implements Flow.Subscriber, Function> classes; - private final RowDesc description; + private final RowDescriptorBase description; private final Statement resultSetStatement; // The following fields must be read/updated on the RowReader context @@ -67,7 +67,7 @@ public RowReader(ContextInternal context, Collector collector, Oracle classes.add(getType(metaData.getColumnClassName(i))); } Flow.Publisher publisher = ors.publisherOracle(this); - description = OracleRowDesc.create(metaData); + description = OracleRowDescriptor.create(metaData); publisher.subscribe(this); } @@ -175,7 +175,7 @@ public Row apply(oracle.jdbc.OracleRow oracleRow) { } } - private static Row transform(List> classes, RowDesc desc, oracle.jdbc.OracleRow or) throws SQLException { + private static Row transform(List> classes, RowDescriptorBase desc, oracle.jdbc.OracleRow or) throws SQLException { Row row = new OracleRow(desc); for (int i = 1; i <= desc.columnNames().size(); i++) { Object res = convertSqlValue(or.getObject(i, classes.get(i - 1))); diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleCommand.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleCommand.java index 9524b2e124..72ec84fca3 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleCommand.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleCommand.java @@ -10,12 +10,12 @@ */ package io.vertx.oracleclient.impl.commands; +import io.vertx.core.AsyncResult; +import io.vertx.core.Completable; import io.vertx.core.Future; import io.vertx.core.Promise; import io.vertx.core.internal.ContextInternal; import io.vertx.oracleclient.impl.Helper.SQLBlockingCodeHandler; -import io.vertx.sqlclient.internal.command.CommandBase; -import io.vertx.sqlclient.internal.command.CommandResponse; import oracle.jdbc.OracleConnection; import java.util.concurrent.Flow; @@ -27,22 +27,19 @@ public abstract class OracleCommand { protected final OracleConnection oracleConnection; protected final ContextInternal connectionContext; - private CommandResponse response; + private Completable handler; + private AsyncResult result; protected OracleCommand(OracleConnection oracleConnection, ContextInternal connectionContext) { this.oracleConnection = oracleConnection; this.connectionContext = connectionContext; } - public final Future processCommand(CommandBase cmd) { + public final Future processCommand(Completable handler) { + this.handler = handler; return execute().andThen(ar -> { - if (ar.succeeded()) { - response = CommandResponse.success(ar.result()); - } else { - response = CommandResponse.failure(ar.cause()); - } - response.cmd = cmd; - }).mapEmpty(); + this.result = ar; + }); } protected abstract Future execute(); @@ -87,6 +84,6 @@ public void onComplete() { } public final void fireResponse() { - response.fire(); + handler.complete(result.result(), result.cause()); } } diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleCursorFetchCommand.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleCursorFetchCommand.java index 744c0a5636..8180553d6d 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleCursorFetchCommand.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleCursorFetchCommand.java @@ -15,7 +15,7 @@ import io.vertx.core.internal.ContextInternal; import io.vertx.oracleclient.impl.RowReader; import io.vertx.sqlclient.internal.QueryResultHandler; -import io.vertx.sqlclient.internal.command.ExtendedQueryCommand; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; import oracle.jdbc.OracleConnection; public class OracleCursorFetchCommand extends OracleCommand { diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleCursorQueryCommand.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleCursorQueryCommand.java index 7cb756e67c..07f8b84fd5 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleCursorQueryCommand.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleCursorQueryCommand.java @@ -18,7 +18,7 @@ import io.vertx.sqlclient.Row; import io.vertx.sqlclient.Tuple; import io.vertx.sqlclient.internal.QueryResultHandler; -import io.vertx.sqlclient.internal.command.ExtendedQueryCommand; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; import oracle.jdbc.OracleConnection; import oracle.jdbc.OraclePreparedStatement; diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePrepareStatementCommand.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePrepareStatementCommand.java index 026df67f2a..2242c3e22b 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePrepareStatementCommand.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePrepareStatementCommand.java @@ -15,7 +15,7 @@ import io.vertx.core.json.JsonArray; import io.vertx.oracleclient.OraclePrepareOptions; import io.vertx.sqlclient.internal.PreparedStatement; -import io.vertx.sqlclient.internal.command.PrepareStatementCommand; +import io.vertx.sqlclient.spi.protocol.PrepareStatementCommand; import oracle.jdbc.OracleConnection; import java.sql.SQLException; diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedBatchQuery.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedBatchQuery.java index 7162b57570..6a32dc94e1 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedBatchQuery.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedBatchQuery.java @@ -17,8 +17,8 @@ import io.vertx.sqlclient.Row; import io.vertx.sqlclient.Tuple; import io.vertx.sqlclient.internal.QueryResultHandler; -import io.vertx.sqlclient.internal.TupleInternal; -import io.vertx.sqlclient.internal.command.ExtendedQueryCommand; +import io.vertx.sqlclient.internal.TupleBase; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; import oracle.jdbc.OracleConnection; import oracle.jdbc.OraclePreparedStatement; @@ -36,7 +36,7 @@ public class OraclePreparedBatchQuery extends OracleQueryCommand { private final String sql; - private final List listParams; + private final List listParams; private final QueryResultHandler resultHandler; public OraclePreparedBatchQuery(OracleConnection oracleConnection, ContextInternal connectionContext, ExtendedQueryCommand cmd, Collector collector) { diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedQueryCommand.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedQueryCommand.java index 4858c03ed3..0b4d92b8fe 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedQueryCommand.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedQueryCommand.java @@ -17,7 +17,7 @@ import io.vertx.sqlclient.Row; import io.vertx.sqlclient.Tuple; import io.vertx.sqlclient.internal.QueryResultHandler; -import io.vertx.sqlclient.internal.command.ExtendedQueryCommand; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; import oracle.jdbc.OracleConnection; import oracle.jdbc.OraclePreparedStatement; diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedStatement.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedStatement.java index fc01fecea2..b0d7324492 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedStatement.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OraclePreparedStatement.java @@ -10,10 +10,8 @@ */ package io.vertx.oracleclient.impl.commands; -import io.vertx.oracleclient.impl.OracleRowDesc; -import io.vertx.sqlclient.internal.ParamDesc; -import io.vertx.sqlclient.internal.RowDesc; -import io.vertx.sqlclient.internal.TupleInternal; +import io.vertx.oracleclient.impl.OracleRowDescriptor; +import io.vertx.sqlclient.internal.RowDescriptorBase; import io.vertx.sqlclient.internal.PreparedStatement; import java.sql.ResultSetMetaData; @@ -22,28 +20,23 @@ public class OraclePreparedStatement implements PreparedStatement { private final String sql; - private final RowDesc rowDesc; + private final RowDescriptorBase rowDescriptor; public OraclePreparedStatement(String sql, java.sql.PreparedStatement preparedStatement) throws SQLException { ResultSetMetaData metaData = preparedStatement.getMetaData(); - RowDesc rowDesc; + RowDescriptorBase rowDescriptor; if (metaData != null) { - rowDesc = OracleRowDesc.create(metaData); + rowDescriptor = OracleRowDescriptor.create(metaData); } else { - rowDesc = OracleRowDesc.EMPTY; + rowDescriptor = OracleRowDescriptor.EMPTY; } this.sql = sql; - this.rowDesc = rowDesc; + this.rowDescriptor = rowDescriptor; } @Override - public ParamDesc paramDesc() { - throw new UnsupportedOperationException(); - } - - @Override - public RowDesc rowDesc() { - return rowDesc; + public RowDescriptorBase rowDesc() { + return rowDescriptor; } @Override diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleQueryCommand.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleQueryCommand.java index ca87f4d63d..d30ed317b9 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleQueryCommand.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleQueryCommand.java @@ -20,10 +20,10 @@ import io.vertx.oracleclient.data.Blob; import io.vertx.oracleclient.impl.Helper; import io.vertx.oracleclient.impl.OracleRow; -import io.vertx.oracleclient.impl.OracleRowDesc; +import io.vertx.oracleclient.impl.OracleRowDescriptor; import io.vertx.sqlclient.Row; import io.vertx.sqlclient.desc.ColumnDescriptor; -import io.vertx.sqlclient.internal.RowDesc; +import io.vertx.sqlclient.internal.RowDescriptorBase; import oracle.jdbc.OracleConnection; import oracle.jdbc.OraclePreparedStatement; import oracle.sql.TIMESTAMPTZ; @@ -209,7 +209,7 @@ protected OracleResponse decode(Statement statement, int[] returnedBatchResul BiConsumer accumulator = collector.accumulator(); - RowDesc desc = OracleRowDesc.EMPTY; + RowDescriptorBase desc = OracleRowDescriptor.EMPTY; C container = collector.supplier().get(); for (int result : returnedBatchResult) { Row row = new OracleRow(desc); @@ -233,7 +233,7 @@ private void decodeResultSet(ResultSet rs, OracleResponse response) throws SQ C container = collector.supplier().get(); int size = 0; ResultSetMetaData metaData = rs.getMetaData(); - RowDesc desc = OracleRowDesc.create(metaData); + RowDescriptorBase desc = OracleRowDescriptor.create(metaData); while (rs.next()) { size++; Row row = new OracleRow(desc); @@ -255,10 +255,10 @@ private void decodeReturnedKeys(Statement statement, OracleResponse response) if (metaData != null) { int cols = metaData.getColumnCount(); if (cols > 0) { - RowDesc keysDesc = OracleRowDesc.create(metaData); + RowDescriptorBase keysDesc = OracleRowDescriptor.create(metaData); OracleRow keys = new OracleRow(keysDesc); for (int i = 1; i <= cols; i++) { - ColumnDescriptor columnDesc = keysDesc.columnDescriptor().get(i - 1); + ColumnDescriptor columnDesc = keysDesc.columnDescriptors().get(i - 1); Object res; switch (columnDesc.jdbcType()) { case TIMESTAMP: diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleResponse.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleResponse.java index 79bf72aa52..26394aa9ee 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleResponse.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleResponse.java @@ -13,7 +13,7 @@ import io.vertx.oracleclient.OracleClient; import io.vertx.sqlclient.Row; import io.vertx.sqlclient.internal.QueryResultHandler; -import io.vertx.sqlclient.internal.RowDesc; +import io.vertx.sqlclient.internal.RowDescriptorBase; import java.util.ArrayList; import java.util.List; @@ -23,9 +23,9 @@ public class OracleResponse { static class RS { R holder; int size; - RowDesc desc; + RowDescriptorBase desc; - RS(R holder, RowDesc desc, int size) { + RS(R holder, RowDescriptorBase desc, int size) { this.holder = holder; this.desc = desc; this.size = size; @@ -42,7 +42,7 @@ public OracleResponse(int updateCount) { this.update = updateCount; } - public void push(R decodeResultSet, RowDesc desc, int size) { + public void push(R decodeResultSet, RowDescriptorBase desc, int size) { if (rs == null) { rs = new ArrayList<>(); } @@ -57,7 +57,7 @@ public void empty(R apply) { this.empty = apply; } - public void outputs(R decodeResultSet, RowDesc desc, int size) { + public void outputs(R decodeResultSet, RowDescriptorBase desc, int size) { if (output == null) { output = new ArrayList<>(); } diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleSimpleQueryCommand.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleSimpleQueryCommand.java index ead98af8db..9c2e06b29d 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleSimpleQueryCommand.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleSimpleQueryCommand.java @@ -15,7 +15,7 @@ import io.vertx.oracleclient.OraclePrepareOptions; import io.vertx.sqlclient.Row; import io.vertx.sqlclient.internal.QueryResultHandler; -import io.vertx.sqlclient.internal.command.SimpleQueryCommand; +import io.vertx.sqlclient.spi.protocol.SimpleQueryCommand; import oracle.jdbc.OracleConnection; import oracle.jdbc.OraclePreparedStatement; diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleTransactionCommand.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleTransactionCommand.java index 56ce2b9198..cf6b205cbf 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleTransactionCommand.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/impl/commands/OracleTransactionCommand.java @@ -13,11 +13,11 @@ import io.vertx.core.Future; import io.vertx.core.internal.ContextInternal; import io.vertx.oracleclient.impl.Helper.SQLFutureMapper; -import io.vertx.sqlclient.internal.command.TxCommand; +import io.vertx.sqlclient.spi.protocol.TxCommand; import oracle.jdbc.OracleConnection; -import static io.vertx.sqlclient.internal.command.TxCommand.Kind.BEGIN; -import static io.vertx.sqlclient.internal.command.TxCommand.Kind.COMMIT; +import static io.vertx.sqlclient.spi.protocol.TxCommand.Kind.BEGIN; +import static io.vertx.sqlclient.spi.protocol.TxCommand.Kind.COMMIT; public class OracleTransactionCommand extends OracleCommand { @@ -35,14 +35,14 @@ public static OracleTransactionCommand create(OracleConnection oracleConn @Override protected Future execute() { Future result; - if (op.kind == BEGIN) { + if (op.kind() == BEGIN) { result = begin(); - } else if (op.kind == COMMIT) { + } else if (op.kind() == COMMIT) { result = commit(); } else { result = rollback(); } - return result.map(op.result); + return result.map(op.result()); } private Future begin() { diff --git a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/spi/OracleDriver.java b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/spi/OracleDriver.java index d7f7083bcb..4f3ee4faa5 100644 --- a/vertx-oracle-client/src/main/java/io/vertx/oracleclient/spi/OracleDriver.java +++ b/vertx-oracle-client/src/main/java/io/vertx/oracleclient/spi/OracleDriver.java @@ -11,60 +11,37 @@ package io.vertx.oracleclient.spi; import io.vertx.core.Future; -import io.vertx.core.Handler; import io.vertx.core.Vertx; -import io.vertx.core.internal.CloseFuture; import io.vertx.core.internal.ContextInternal; import io.vertx.core.internal.VertxInternal; import io.vertx.core.json.JsonObject; import io.vertx.core.net.NetClientOptions; import io.vertx.oracleclient.OracleConnectOptions; import io.vertx.oracleclient.impl.*; -import io.vertx.sqlclient.Pool; -import io.vertx.sqlclient.PoolOptions; import io.vertx.sqlclient.SqlConnectOptions; -import io.vertx.sqlclient.SqlConnection; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.internal.pool.CloseablePool; -import io.vertx.sqlclient.internal.pool.PoolImpl; +import io.vertx.sqlclient.spi.connection.Connection; import io.vertx.sqlclient.internal.SqlConnectionInternal; -import io.vertx.sqlclient.spi.ConnectionFactory; -import io.vertx.sqlclient.spi.Driver; +import io.vertx.sqlclient.spi.connection.ConnectionFactory; +import io.vertx.sqlclient.spi.DriverBase; import java.util.function.Function; -import java.util.function.Supplier; -public class OracleDriver implements Driver { +public class OracleDriver extends DriverBase { - private static final String SHARED_CLIENT_KEY = "__vertx.shared.oracleclient"; + private static final String DISCRIMINANT = "oracleclient"; + + private static final Function> AFTER_ACQUIRE = conn -> ((OracleJdbcConnection) conn).afterAcquire(); + private static final Function> BEFORE_RECYCLE = conn -> ((OracleJdbcConnection) conn).beforeRecycle(); public static final OracleDriver INSTANCE = new OracleDriver(); - @Override - public OracleConnectOptions downcast(SqlConnectOptions connectOptions) { - return connectOptions instanceof OracleConnectOptions ? (OracleConnectOptions) connectOptions : new OracleConnectOptions(connectOptions); + public OracleDriver() { + super(DISCRIMINANT, AFTER_ACQUIRE, BEFORE_RECYCLE); } @Override - public Pool newPool(Vertx vertx, Supplier> databases, PoolOptions options, NetClientOptions transportOptions, Handler connectHandler, CloseFuture closeFuture) { - VertxInternal vx = (VertxInternal) vertx; - PoolImpl pool; - if (options.isShared()) { - pool = vx.createSharedResource(SHARED_CLIENT_KEY, options.getName(), closeFuture, cf -> newPoolImpl(vx, connectHandler, databases, options, cf)); - } else { - pool = newPoolImpl(vx, connectHandler, databases, options, closeFuture); - } - return new CloseablePool(vx, closeFuture, pool); - } - - private PoolImpl newPoolImpl(VertxInternal vertx, Handler connectHandler, Supplier> databases, PoolOptions options, CloseFuture closeFuture) { - Function> afterAcquire = conn -> ((OracleJdbcConnection) conn).afterAcquire(); - Function> beforeRecycle = conn -> ((OracleJdbcConnection) conn).beforeRecycle(); - ConnectionFactory factory = createConnectionFactory(vertx, null); - PoolImpl pool = new PoolImpl(vertx, this, false, options, afterAcquire, beforeRecycle, context -> factory.connect(context, databases.get()), connectHandler, closeFuture); - pool.init(); - closeFuture.add(factory); - return pool; + public OracleConnectOptions downcast(SqlConnectOptions connectOptions) { + return connectOptions instanceof OracleConnectOptions ? (OracleConnectOptions) connectOptions : new OracleConnectOptions(connectOptions); } @Override @@ -84,7 +61,7 @@ public ConnectionFactory createConnectionFactory(Vertx ver } @Override - public SqlConnectionInternal wrapConnection(ContextInternal context, ConnectionFactory factory, Connection conn) { - return new OracleConnectionImpl(context, factory, conn); + public SqlConnectionInternal wrapConnection(ContextInternal context, ConnectionFactory factory, Connection connection) { + return new OracleConnectionImpl(context, factory, connection); } } diff --git a/vertx-pg-client/pom.xml b/vertx-pg-client/pom.xml index 251242b4ac..85e42e6baf 100644 --- a/vertx-pg-client/pom.xml +++ b/vertx-pg-client/pom.xml @@ -48,6 +48,10 @@ io.vertx vertx-sql-client + + io.vertx + vertx-sql-client-codec + diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/InitiateSslHandler.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/InitiateSslHandler.java index 1f67953398..402c3d2d86 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/InitiateSslHandler.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/InitiateSslHandler.java @@ -25,7 +25,7 @@ import io.vertx.core.Promise; import io.vertx.core.net.ClientSSLOptions; import io.vertx.pgclient.impl.codec.PgProtocolConstants; -import io.vertx.sqlclient.impl.SocketConnectionBase; +import io.vertx.sqlclient.codec.SocketConnectionBase; import io.vertx.core.VertxException; public class InitiateSslHandler extends ChannelInboundHandlerAdapter { diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/Notification.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/Notification.java similarity index 98% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/Notification.java rename to vertx-pg-client/src/main/java/io/vertx/pgclient/impl/Notification.java index 845e6775f2..c92bdebf7e 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/Notification.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/Notification.java @@ -15,7 +15,7 @@ * */ -package io.vertx.sqlclient.impl; +package io.vertx.pgclient.impl; import java.util.Objects; diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgConnectionFactory.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgConnectionFactory.java index 289b847867..a13770b4ab 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgConnectionFactory.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgConnectionFactory.java @@ -28,8 +28,7 @@ import io.vertx.core.internal.net.NetSocketInternal; import io.vertx.pgclient.PgConnectOptions; import io.vertx.pgclient.SslMode; -import io.vertx.sqlclient.SqlConnection; -import io.vertx.sqlclient.internal.Connection; +import io.vertx.sqlclient.spi.connection.Connection; import io.vertx.sqlclient.impl.ConnectionFactoryBase; import java.util.Collections; @@ -153,19 +152,13 @@ private Future doConnect(ConnectOptions connectOptions, ContextInter } @Override - public Future connect(Context context, PgConnectOptions options) { + public Future connect(Context context, PgConnectOptions options) { ContextInternal contextInternal = (ContextInternal) context; if (options.isUsingDomainSocket() && !vertx.isNativeTransportEnabled()) { return contextInternal.failedFuture(new IllegalArgumentException(NATIVE_TRANSPORT_REQUIRED)); } - PromiseInternal promise = contextInternal.promise(); - connect(asEventLoopContext(contextInternal), options) - .map(conn -> { - PgConnectionImpl pgConn = new PgConnectionImpl(this, contextInternal, conn); - conn.init(pgConn); - return (SqlConnection)pgConn; - }) - .onComplete(promise); + PromiseInternal promise = contextInternal.promise(); + connect(asEventLoopContext(contextInternal), options).onComplete(promise); return promise.future(); } diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgConnectionImpl.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgConnectionImpl.java index ed7433fa03..4ce2cc2e04 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgConnectionImpl.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgConnectionImpl.java @@ -28,9 +28,8 @@ import io.vertx.pgclient.impl.codec.NoticeResponse; import io.vertx.pgclient.impl.codec.TxFailedEvent; import io.vertx.pgclient.spi.PgDriver; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.impl.Notification; -import io.vertx.sqlclient.impl.SocketConnectionBase; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.codec.SocketConnectionBase; import io.vertx.sqlclient.internal.SqlConnectionBase; public class PgConnectionImpl extends SqlConnectionBase implements PgConnection { @@ -42,7 +41,12 @@ public static Future connect(ContextInternal context, PgConnectOpt } catch (Exception e) { return context.failedFuture(e); } - return prepareForClose(context, client.connect((Context)context, options)).map(PgConnection::cast); + return client.connect((Context)context, options).map(conn -> { + PgConnectionImpl impl = new PgConnectionImpl(client, context, conn); + conn.init(impl); + prepareForClose(context, impl); + return impl; + }); } private volatile Handler notificationHandler; @@ -110,12 +114,14 @@ public PgConnection noticeHandler(Handler handler) { @Override public int processId() { - return conn.getProcessId(); + PgSocketConnection actual = (PgSocketConnection) conn.unwrap(); + return actual.getProcessId(); } @Override public int secretKey() { - return conn.getSecretKey(); + PgSocketConnection actual = (PgSocketConnection) conn.unwrap(); + return actual.getSecretKey(); } @Override diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/RowImpl.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgRow.java similarity index 93% rename from vertx-pg-client/src/main/java/io/vertx/pgclient/impl/RowImpl.java rename to vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgRow.java index 9a5c7f01d7..06633e1a99 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/RowImpl.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgRow.java @@ -23,40 +23,21 @@ import io.vertx.pgclient.data.*; import io.vertx.sqlclient.data.Numeric; import io.vertx.sqlclient.impl.RowBase; -import io.vertx.sqlclient.internal.RowDesc; +import io.vertx.sqlclient.internal.RowDescriptorBase; import java.lang.reflect.Array; import java.math.BigDecimal; import java.time.*; -import java.util.List; import java.util.UUID; -public class RowImpl extends RowBase { +public class PgRow extends RowBase { - private final RowDesc desc; - - public RowImpl(RowDesc desc) { - super(desc.columnNames().size()); - this.desc = desc; - } - - public RowImpl(RowImpl row) { - super(row); - this.desc = row.desc; - } - - @Override - public String getColumnName(int pos) { - List columnNames = desc.columnNames(); - return pos < 0 || columnNames.size() - 1 < pos ? null : columnNames.get(pos); + public PgRow(RowDescriptorBase desc) { + super(desc); } - @Override - public int getColumnIndex(String name) { - if (name == null) { - throw new NullPointerException(); - } - return desc.columnNames().indexOf(name); + public PgRow(PgRow row) { + super(row.desc, row); } @Override diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgSocketConnection.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgSocketConnection.java index 880bd65535..263cdb4dc2 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgSocketConnection.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/PgSocketConnection.java @@ -27,15 +27,22 @@ import io.vertx.core.internal.net.NetSocketInternal; import io.vertx.pgclient.PgConnectOptions; import io.vertx.pgclient.PgException; +import io.vertx.pgclient.impl.codec.ExtendedQueryCommandCodec; import io.vertx.pgclient.impl.codec.NoticeResponse; import io.vertx.pgclient.impl.codec.PgCodec; +import io.vertx.pgclient.impl.codec.PgCommandCodec; import io.vertx.pgclient.impl.codec.TxFailedEvent; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.impl.Notification; +import io.vertx.sqlclient.codec.CommandMessage; +import io.vertx.sqlclient.codec.SocketConnectionBase; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.internal.PreparedStatement; import io.vertx.sqlclient.internal.QueryResultHandler; -import io.vertx.sqlclient.impl.SocketConnectionBase; -import io.vertx.sqlclient.internal.command.*; import io.vertx.sqlclient.spi.DatabaseMetadata; +import io.vertx.sqlclient.spi.protocol.CommandBase; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; +import io.vertx.sqlclient.spi.protocol.InitCommand; +import io.vertx.sqlclient.spi.protocol.SimpleQueryCommand; +import io.vertx.sqlclient.spi.protocol.TxCommand; import java.util.Map; import java.util.function.Predicate; @@ -123,18 +130,16 @@ protected void handleException(Throwable t) { } } - @Override public int getProcessId() { return processId; } - @Override public int getSecretKey() { return secretKey; } @Override - public DatabaseMetadata getDatabaseMetaData() { + public DatabaseMetadata databaseMetadata() { return dbMetaData; } @@ -161,17 +166,27 @@ protected void doSchedule(CommandBase cmd, Completable handler) { if (cmd instanceof TxCommand) { TxCommand tx = (TxCommand) cmd; SimpleQueryCommand cmd2 = new SimpleQueryCommand<>( - tx.kind.sql, + tx.kind().sql(), false, false, - QueryCommandBase.NULL_COLLECTOR, + SocketConnectionBase.NULL_COLLECTOR, QueryResultHandler.NOOP_HANDLER); - super.doSchedule(cmd2, (res, err) -> handler.complete(tx.result, err)); + super.doSchedule(cmd2, (res, err) -> handler.complete(tx.result(), err)); } else { super.doSchedule(cmd, handler); } } + @Override + protected CommandMessage toMessage(ExtendedQueryCommand command, PreparedStatement preparedStatement) { + return new ExtendedQueryCommandCodec<>((ExtendedQueryCommand) command, preparedStatement); + } + + @Override + protected CommandMessage toMessage(CommandBase command) { + return PgCommandCodec.wrap(command); + } + @Override public boolean isIndeterminatePreparedStatementError(Throwable error) { if (error instanceof PgException) { diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/CloseConnectionCommandCodec.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/CloseConnectionCommandCodec.java index 06dfe7ce92..fdec716081 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/CloseConnectionCommandCodec.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/CloseConnectionCommandCodec.java @@ -16,7 +16,7 @@ */ package io.vertx.pgclient.impl.codec; -import io.vertx.sqlclient.internal.command.CloseConnectionCommand; +import io.vertx.sqlclient.spi.protocol.CloseConnectionCommand; class CloseConnectionCommandCodec extends PgCommandCodec { diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/ClosePortalCommandCodec.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/ClosePortalCommandCodec.java index 267cc6103d..6584c89394 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/ClosePortalCommandCodec.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/ClosePortalCommandCodec.java @@ -16,7 +16,7 @@ */ package io.vertx.pgclient.impl.codec; -import io.vertx.sqlclient.internal.command.CloseCursorCommand; +import io.vertx.sqlclient.spi.protocol.CloseCursorCommand; class ClosePortalCommandCodec extends PgCommandCodec { diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/CloseStatementCommandCodec.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/CloseStatementCommandCodec.java index 92dd14df01..f9aefe8a65 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/CloseStatementCommandCodec.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/CloseStatementCommandCodec.java @@ -16,7 +16,7 @@ */ package io.vertx.pgclient.impl.codec; -import io.vertx.sqlclient.internal.command.CloseStatementCommand; +import io.vertx.sqlclient.spi.protocol.CloseStatementCommand; class CloseStatementCommandCodec extends PgCommandCodec { diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/DataType.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/DataType.java index a637387425..220a0415a3 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/DataType.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/DataType.java @@ -27,7 +27,7 @@ import io.vertx.pgclient.data.*; import io.vertx.sqlclient.Tuple; import io.vertx.sqlclient.data.Numeric; -import io.vertx.sqlclient.internal.TupleInternal; +import io.vertx.sqlclient.internal.TupleBase; import java.sql.JDBCType; import java.time.*; @@ -243,7 +243,7 @@ private static class DefaultParamExtractor implements ParamExtractor { } @Override - public T get(TupleInternal tuple, int idx) { + public T get(TupleBase tuple, int idx) { Object value = tuple.getValue(idx); if (value == null) { return null; diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/DataTypeCodec.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/DataTypeCodec.java index 1b0a0aecdc..2b065abb32 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/DataTypeCodec.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/DataTypeCodec.java @@ -32,7 +32,7 @@ import io.vertx.pgclient.impl.util.UTF8StringEndDetector; import io.vertx.sqlclient.Tuple; import io.vertx.sqlclient.data.Numeric; -import io.vertx.sqlclient.impl.codec.CommonCodec; +import io.vertx.sqlclient.impl.Utils; import java.math.BigDecimal; import java.net.Inet4Address; @@ -688,7 +688,7 @@ private static Boolean textDecodeBOOL(int index, int len, ByteBuf buff) { } private static Short textDecodeINT2(int index, int len, ByteBuf buff) { - return (short) CommonCodec.decodeDecStringToLong(index, len, buff); + return (short) Utils.decodeDecStringToLong(index, len, buff); } private static Short binaryDecodeINT2(int index, int len, ByteBuf buff) { @@ -700,7 +700,7 @@ private static void binaryEncodeINT2(Number value, ByteBuf buff) { } private static Integer textDecodeINT4(int index, int len, ByteBuf buff) { - return (int) CommonCodec.decodeDecStringToLong(index, len, buff); + return (int) Utils.decodeDecStringToLong(index, len, buff); } private static Integer binaryDecodeINT4(int index, int len, ByteBuf buff) { @@ -712,7 +712,7 @@ private static void binaryEncodeINT4(Number value, ByteBuf buff) { } private static Long textDecodeINT8(int index, int len, ByteBuf buff) { - return CommonCodec.decodeDecStringToLong(index, len, buff); + return Utils.decodeDecStringToLong(index, len, buff); } private static Long binaryDecodeINT8(int index, int len, ByteBuf buff) { diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/ExtendedQueryCommandCodec.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/ExtendedQueryCommandCodec.java index ce0cf91bd2..2713cb2d9a 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/ExtendedQueryCommandCodec.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/ExtendedQueryCommandCodec.java @@ -16,21 +16,25 @@ */ package io.vertx.pgclient.impl.codec; -import io.vertx.sqlclient.internal.TupleInternal; -import io.vertx.sqlclient.impl.codec.InvalidCachedStatementEvent; -import io.vertx.sqlclient.internal.RowDesc; -import io.vertx.sqlclient.internal.command.CommandResponse; -import io.vertx.sqlclient.internal.command.ExtendedQueryCommand; +import io.vertx.sqlclient.internal.PreparedStatement; +import io.vertx.sqlclient.internal.TupleBase; +import io.vertx.sqlclient.codec.InvalidCachedStatementEvent; +import io.vertx.sqlclient.internal.RowDescriptorBase; +import io.vertx.sqlclient.codec.CommandResponse; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; -class ExtendedQueryCommandCodec> extends QueryCommandBaseCodec { +public class ExtendedQueryCommandCodec> extends QueryCommandBaseCodec { private PgEncoder encoder; private static final String TABLE_SCHEMA_CHANGE_ERROR_MESSAGE_PATTERN = "bind message has \\d result formats but query has \\d columns"; - ExtendedQueryCommandCodec(C cmd) { + private PgPreparedStatement ps; + + public ExtendedQueryCommandCodec(C cmd, PreparedStatement ps) { super(cmd); - rowDecoder = new RowResultDecoder<>(cmd.collector(), ((PgPreparedStatement)cmd.preparedStatement()).rowDesc()); + this.rowDecoder = new RowResultDecoder<>(cmd.collector(), ((PgPreparedStatement)ps).rowDesc()); + this.ps = (PgPreparedStatement) ps; } @Override @@ -40,7 +44,6 @@ void encode(PgEncoder encoder) { encoder.writeExecute(cmd.cursorId(), cmd.fetch()); encoder.writeSync(); } else { - PgPreparedStatement ps = (PgPreparedStatement) cmd.preparedStatement(); if (cmd.isBatch()) { if (cmd.paramsList().isEmpty()) { // We set suspended to false as we won't get a command complete command back from Postgres @@ -51,7 +54,7 @@ void encode(PgEncoder encoder) { if (encoder.useLayer7Proxy) { encoder.writeParse(ps.sql, ps.bind.statement, new DataType[0]); } - for (TupleInternal param : cmd.paramsList()) { + for (TupleBase param : cmd.paramsList()) { encoder.writeBind(ps.bind, cmd.cursorId(), param); encoder.writeExecute(cmd.cursorId(), cmd.fetch()); } @@ -76,7 +79,7 @@ void handleParseComplete() { void handlePortalSuspended() { Throwable failure = rowDecoder.complete(); R result = rowDecoder.result(); - RowDesc desc = rowDecoder.desc; + RowDescriptorBase desc = rowDecoder.desc; int size = rowDecoder.size(); rowDecoder.reset(); this.result = true; @@ -90,8 +93,8 @@ void handleBindComplete() { @Override public void handleErrorResponse(ErrorResponse errorResponse) { - if (((PgPreparedStatement)cmd.preparedStatement()).isCached() && isTableSchemaErrorMessage(errorResponse)) { - encoder.channelHandlerContext().fireChannelRead(new InvalidCachedStatementEvent(cmd.preparedStatement().sql())); + if (ps.isCached() && isTableSchemaErrorMessage(errorResponse)) { + encoder.channelHandlerContext().fireChannelRead(new InvalidCachedStatementEvent(ps.sql())); } super.handleErrorResponse(errorResponse); } diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/InitCommandCodec.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/InitCommandCodec.java index a92505d1cb..9bcb563818 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/InitCommandCodec.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/InitCommandCodec.java @@ -25,9 +25,9 @@ import io.vertx.pgclient.impl.PgSocketConnection; import io.vertx.pgclient.impl.auth.scram.ScramAuthentication; import io.vertx.pgclient.impl.auth.scram.ScramSession; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.internal.command.CommandResponse; -import io.vertx.sqlclient.internal.command.InitCommand; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.codec.CommandResponse; +import io.vertx.sqlclient.spi.protocol.InitCommand; class InitCommandCodec extends PgCommandCodec { diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/ParamExtractor.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/ParamExtractor.java index 92f4de9a93..50ed2a6400 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/ParamExtractor.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/ParamExtractor.java @@ -12,14 +12,14 @@ import io.vertx.core.json.Json; import io.vertx.sqlclient.Tuple; -import io.vertx.sqlclient.internal.TupleInternal; +import io.vertx.sqlclient.internal.TupleBase; import java.util.Arrays; import java.util.stream.Collectors; interface ParamExtractor { - static String extractUnknownType(TupleInternal tuple, int pos) { + static String extractUnknownType(TupleBase tuple, int pos) { Object value = tuple.getValue(pos); if (value instanceof Object[]) { String[] strings = tuple.getArrayOfStrings(pos); @@ -29,7 +29,7 @@ static String extractUnknownType(TupleInternal tuple, int pos) { } } - T get(TupleInternal tuple, int idx); + T get(TupleBase tuple, int idx); private static String encodeJsonToString(Object value) { if (value == Tuple.JSON_NULL) { diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgCodec.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgCodec.java index ec58b604e6..e33f27fa85 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgCodec.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgCodec.java @@ -18,10 +18,7 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.CombinedChannelDuplexHandler; -import io.vertx.core.Completable; import io.vertx.sqlclient.ClosedConnectionException; -import io.vertx.sqlclient.internal.command.CommandBase; -import io.vertx.sqlclient.internal.command.CommandResponse; import java.util.ArrayDeque; import java.util.Iterator; @@ -83,10 +80,7 @@ private void fail(Throwable cause) { } private void fail(PgCommandCodec codec, Throwable cause) { - Completable handler = codec.cmd.handler; - if (handler != null) { - handler.complete(null, cause); - } + codec.fail(cause); } @Override diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgCommandCodec.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgCommandCodec.java index e39b38256c..7bb1849bd9 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgCommandCodec.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgCommandCodec.java @@ -20,22 +20,45 @@ import io.vertx.core.internal.logging.Logger; import io.vertx.core.internal.logging.LoggerFactory; import io.vertx.pgclient.PgException; -import io.vertx.sqlclient.internal.command.CommandBase; -import io.vertx.sqlclient.internal.command.CommandResponse; +import io.vertx.sqlclient.codec.CommandMessage; +import io.vertx.sqlclient.codec.CommandResponse; +import io.vertx.sqlclient.spi.protocol.CloseConnectionCommand; +import io.vertx.sqlclient.spi.protocol.CloseCursorCommand; +import io.vertx.sqlclient.spi.protocol.CloseStatementCommand; +import io.vertx.sqlclient.spi.protocol.CommandBase; +import io.vertx.sqlclient.spi.protocol.InitCommand; +import io.vertx.sqlclient.spi.protocol.PrepareStatementCommand; +import io.vertx.sqlclient.spi.protocol.SimpleQueryCommand; import java.util.Arrays; -abstract class PgCommandCodec> { +public abstract class PgCommandCodec> extends CommandMessage { private static final Logger logger = LoggerFactory.getLogger(PgCommandCodec.class); PgDecoder decoder; PgException failure; R result; - final C cmd; PgCommandCodec(C cmd) { - this.cmd = cmd; + super(cmd); + } + + public static PgCommandCodec wrap(CommandBase cmd) { + if (cmd instanceof InitCommand) { + return new InitCommandCodec((InitCommand) cmd); + } else if (cmd instanceof SimpleQueryCommand) { + return new SimpleQueryCodec<>((SimpleQueryCommand) cmd); + } else if (cmd instanceof PrepareStatementCommand) { + return new PrepareStatementCommandCodec((PrepareStatementCommand) cmd); + } else if (cmd instanceof CloseConnectionCommand) { + return CloseConnectionCommandCodec.INSTANCE; + } else if (cmd instanceof CloseCursorCommand) { + return new ClosePortalCommandCodec((CloseCursorCommand) cmd); + } else if (cmd instanceof CloseStatementCommand) { + return new CloseStatementCommandCodec((CloseStatementCommand) cmd); + } + throw new AssertionError("Invalid command " + cmd); } abstract void encode(PgEncoder encoder); diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgDecoder.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgDecoder.java index 122c804181..aca5fcb116 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgDecoder.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgDecoder.java @@ -23,10 +23,10 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.util.ByteProcessor; +import io.vertx.core.Completable; import io.vertx.pgclient.impl.util.Util; -import io.vertx.sqlclient.impl.Notification; -import io.vertx.sqlclient.internal.command.CommandBase; -import io.vertx.sqlclient.internal.command.CommandResponse; +import io.vertx.pgclient.impl.Notification; +import io.vertx.sqlclient.codec.CommandResponse; /** * @@ -48,7 +48,7 @@ class PgDecoder extends ChannelInboundHandlerAdapter { void fireCommandResponse(CommandResponse commandResponse) { PgCommandCodec c = codec.poll(); - commandResponse.cmd = (CommandBase) c.cmd; + commandResponse.handler = (Completable) c.handler; chctx.fireChannelRead(commandResponse); } diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgEncoder.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgEncoder.java index e4e9723498..fdd08e9a60 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgEncoder.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgEncoder.java @@ -26,9 +26,8 @@ import io.vertx.sqlclient.Tuple; import io.vertx.pgclient.impl.util.Util; import io.vertx.sqlclient.impl.HexSequence; -import io.vertx.sqlclient.internal.ParamDesc; -import io.vertx.sqlclient.internal.RowDesc; -import io.vertx.sqlclient.internal.command.*; +import io.vertx.sqlclient.internal.RowDescriptorBase; +import io.vertx.sqlclient.spi.protocol.CloseConnectionCommand; import java.util.*; @@ -97,7 +96,7 @@ private void enqueueMessage(Object msg, Object p1, Object p2, Object p3, int est public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { if (!closeSent) { CloseConnectionCommand cmd = CloseConnectionCommand.INSTANCE; - PgCommandCodec codec = wrap(cmd); + PgCommandCodec codec = PgCommandCodec.wrap(cmd); codec.encode(this); } } @@ -108,32 +107,12 @@ public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { capacityEstimate = 0; } - void write(CommandBase cmd) { - PgCommandCodec cmdCodec = wrap(cmd); - if (codec.add(cmdCodec)) { - cmdCodec.encode(this); + void write(PgCommandCodec cmd) { + if (codec.add(cmd)) { + cmd.encode(this); } } - private PgCommandCodec wrap(CommandBase cmd) { - if (cmd instanceof InitCommand) { - return new InitCommandCodec((InitCommand) cmd); - } else if (cmd instanceof SimpleQueryCommand) { - return new SimpleQueryCodec<>((SimpleQueryCommand) cmd); - } else if (cmd instanceof ExtendedQueryCommand) { - return new ExtendedQueryCommandCodec<>((ExtendedQueryCommand) cmd); - } else if (cmd instanceof PrepareStatementCommand) { - return new PrepareStatementCommandCodec((PrepareStatementCommand) cmd); - } else if (cmd instanceof CloseConnectionCommand) { - return CloseConnectionCommandCodec.INSTANCE; - } else if (cmd instanceof CloseCursorCommand) { - return new ClosePortalCommandCodec((CloseCursorCommand) cmd); - } else if (cmd instanceof CloseStatementCommand) { - return new CloseStatementCommandCodec((CloseStatementCommand) cmd); - } - throw new AssertionError(); - } - @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { this.ctx = ctx; @@ -141,9 +120,8 @@ public void handlerAdded(ChannelHandlerContext ctx) throws Exception { @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - if (msg instanceof CommandBase) { - CommandBase cmd = (CommandBase) msg; - write(cmd); + if (msg instanceof PgCommandCodec) { + write((PgCommandCodec) msg); } else { super.write(ctx, msg, promise); } @@ -599,7 +577,7 @@ void writeScramClientFinalMessage(ScramClientFinalMessage msg) { * This message includes an SQL command (or commands) expressed as a text string. *

* The possible response messages from the backend are - * {@link CommandComplete}, {@link RowDesc}, {@link DataRow}, {@link EmptyQueryResponse}, {@link ErrorResponse}, + * {@link CommandComplete}, {@link RowDescriptorBase}, {@link DataRow}, {@link EmptyQueryResponse}, {@link ErrorResponse}, * {@link ReadyForQuery} and {@link NoticeResponse} */ void writeQuery(Query query) { @@ -611,16 +589,16 @@ void writeQuery(Query query) { * The message that using "statement" variant specifies the name of an existing prepared statement. *

* The response is a {@link ParamDesc} message describing the parameters needed by the statement, - * followed by a {@link RowDesc} message describing the rows that will be returned when the statement is eventually + * followed by a {@link RowDescriptorBase} message describing the rows that will be returned when the statement is eventually * executed or a {@link NoData} message if the statement will not return rows. * {@link ErrorResponse} is issued if there is no such prepared statement. *

* Note that since {@link Bind} has not yet been issued, the formats to be used for returned columns are not yet known to - * the backend; the format code fields in the {@link RowDesc} message will be zeroes in this case. + * the backend; the format code fields in the {@link RowDescriptorBase} message will be zeroes in this case. *

* The message that using "portal" variant specifies the name of an existing portal. *

- * The response is a {@link RowDesc} message describing the rows that will be returned by executing the portal; + * The response is a {@link RowDescriptorBase} message describing the rows that will be returned by executing the portal; * or a {@link NoData} message if the portal does not contain a query that will return rows; or {@link ErrorResponse} * if there is no such portal. */ @@ -639,7 +617,7 @@ void writeParse(String sql, byte[] statement, DataType[] parameterTypes) { * in other cases the command is always executed to completion, and the row count of the result is ignored. *

* The possible responses to this message are the same as {@link Query} message, except that - * it doesn't cause {@link ReadyForQuery} or {@link RowDesc} to be issued. + * it doesn't cause {@link ReadyForQuery} or {@link RowDescriptorBase} to be issued. *

* If Execute terminates before completing the execution of a portal, it will send a {@link PortalSuspended} message; * the appearance of this message tells the frontend that another Execute should be issued against the same portal to diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgParamDesc.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgParamDesc.java index 9f4fd9e98c..5e43152c63 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgParamDesc.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgParamDesc.java @@ -19,8 +19,7 @@ import io.vertx.core.VertxException; import io.vertx.sqlclient.impl.ErrorMessageFactory; import io.vertx.sqlclient.internal.ArrayTuple; -import io.vertx.sqlclient.internal.ParamDesc; -import io.vertx.sqlclient.internal.TupleInternal; +import io.vertx.sqlclient.internal.TupleBase; import java.util.Arrays; import java.util.function.Function; @@ -28,7 +27,7 @@ /** * @author Emad Alblueshi */ -class PgParamDesc extends ParamDesc { +class PgParamDesc { // OIDs private final DataType[] paramDataTypes; @@ -41,7 +40,7 @@ DataType[] paramDataTypes() { return paramDataTypes; } - public TupleInternal prepare(TupleInternal values) { + public TupleBase prepare(TupleBase values) { int numberOfParams = values.size(); if (numberOfParams > 65535) { throw new VertxException("The number of parameters (" + numberOfParams + ") exceeds the maximum of 65535. Use arrays or split the query.", true); @@ -50,7 +49,7 @@ public TupleInternal prepare(TupleInternal values) { if (numberOfParams != paramDescLength) { throw new VertxException(ErrorMessageFactory.buildWhenArgumentsLengthNotMatched(paramDescLength, numberOfParams), true); } - TupleInternal prepared = values; + TupleBase prepared = values; for (int i = 0; i < paramDescLength; i++) { DataType paramDataType = paramDataTypes[i]; ParamExtractor extractor = paramDataType.paramExtractor; diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgPreparedStatement.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgPreparedStatement.java index 1f078cb558..98580843cd 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgPreparedStatement.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgPreparedStatement.java @@ -18,18 +18,17 @@ package io.vertx.pgclient.impl.codec; import io.vertx.sqlclient.internal.PreparedStatement; -import io.vertx.sqlclient.internal.ParamDesc; -import io.vertx.sqlclient.internal.TupleInternal; +import io.vertx.sqlclient.internal.TupleBase; class PgPreparedStatement implements PreparedStatement { final String sql; final Bind bind; final PgParamDesc paramDesc; - final PgRowDesc rowDesc; + final PgRowDescriptor rowDesc; final boolean cached; - PgPreparedStatement(String sql, byte[] statement, PgParamDesc paramDesc, PgRowDesc rowDesc, boolean cached) { + PgPreparedStatement(String sql, byte[] statement, PgParamDesc paramDesc, PgRowDescriptor rowDesc, boolean cached) { this.paramDesc = paramDesc; this.rowDesc = rowDesc; this.sql = sql; @@ -38,12 +37,7 @@ class PgPreparedStatement implements PreparedStatement { } @Override - public ParamDesc paramDesc() { - return paramDesc; - } - - @Override - public PgRowDesc rowDesc() { + public PgRowDescriptor rowDesc() { return rowDesc; } @@ -53,7 +47,7 @@ public String sql() { } @Override - public TupleInternal prepare(TupleInternal values) { + public TupleBase prepare(TupleBase values) { return paramDesc.prepare(values); } diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgRowDesc.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgRowDescriptor.java similarity index 73% rename from vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgRowDesc.java rename to vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgRowDescriptor.java index 557cc630b8..d70192fd84 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgRowDesc.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgRowDescriptor.java @@ -16,11 +16,11 @@ */ package io.vertx.pgclient.impl.codec; -import io.vertx.sqlclient.internal.RowDesc; +import io.vertx.sqlclient.internal.RowDescriptorBase; -class PgRowDesc extends RowDesc { +class PgRowDescriptor extends RowDescriptorBase { - static PgRowDesc createBinary(PgColumnDesc[] columns) { + static PgRowDescriptor createBinary(PgColumnDesc[] columns) { // Fix to use binary when possible for (int i = 0; i < columns.length; i++) { PgColumnDesc columnDesc = columns[i]; @@ -28,16 +28,16 @@ static PgRowDesc createBinary(PgColumnDesc[] columns) { columns[i] = columnDesc.toBinaryDataFormat(); } } - return new PgRowDesc(columns); + return new PgRowDescriptor(columns); } - static PgRowDesc create(PgColumnDesc[] columns) { - return new PgRowDesc(columns); + static PgRowDescriptor create(PgColumnDesc[] columns) { + return new PgRowDescriptor(columns); } final PgColumnDesc[] columns; - private PgRowDesc(PgColumnDesc[] columns) { + private PgRowDescriptor(PgColumnDesc[] columns) { super(columns); this.columns = columns; } diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PrepareStatementCommandCodec.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PrepareStatementCommandCodec.java index 57a620a254..afa648d890 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PrepareStatementCommandCodec.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PrepareStatementCommandCodec.java @@ -16,7 +16,7 @@ */ package io.vertx.pgclient.impl.codec; -import io.vertx.sqlclient.internal.command.PrepareStatementCommand; +import io.vertx.sqlclient.spi.protocol.PrepareStatementCommand; import io.vertx.sqlclient.internal.PreparedStatement; import java.util.List; @@ -26,7 +26,7 @@ class PrepareStatementCommandCodec extends PgCommandCodec extends RowDecoder { +public class RowResultDecoder extends RowDecoder { - final PgRowDesc desc; + final PgRowDescriptor desc; - RowResultDecoder(Collector collector, PgRowDesc desc) { + public RowResultDecoder(Collector collector, PgRowDescriptor desc) { super(collector); this.desc = desc; } @Override protected RowInternal row() { - return new RowImpl(desc); + return new PgRow(desc); } @Override diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/SimpleQueryCodec.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/SimpleQueryCodec.java index 22cfab9810..902ca43f8e 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/SimpleQueryCodec.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/SimpleQueryCodec.java @@ -18,7 +18,7 @@ import io.vertx.core.internal.logging.Logger; import io.vertx.core.internal.logging.LoggerFactory; -import io.vertx.sqlclient.internal.command.SimpleQueryCommand; +import io.vertx.sqlclient.spi.protocol.SimpleQueryCommand; class SimpleQueryCodec extends QueryCommandBaseCodec> { @@ -35,6 +35,6 @@ void encode(PgEncoder encoder) { @Override void handleRowDescription(PgColumnDesc[] columnDescs) { - rowDecoder = new RowResultDecoder<>(cmd.collector(), PgRowDesc.create(columnDescs)); + rowDecoder = new RowResultDecoder<>(cmd.collector(), PgRowDescriptor.create(columnDescs)); } } diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/spi/PgDriver.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/spi/PgDriver.java index 80f899ef5f..a0343a53b4 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/spi/PgDriver.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/spi/PgDriver.java @@ -17,37 +17,30 @@ import io.vertx.sqlclient.PoolOptions; import io.vertx.sqlclient.SqlConnectOptions; import io.vertx.sqlclient.SqlConnection; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.internal.pool.CloseablePool; -import io.vertx.sqlclient.internal.pool.PoolImpl; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.impl.pool.PoolImpl; import io.vertx.sqlclient.internal.SqlConnectionInternal; -import io.vertx.sqlclient.spi.ConnectionFactory; -import io.vertx.sqlclient.spi.Driver; +import io.vertx.sqlclient.spi.connection.ConnectionFactory; +import io.vertx.sqlclient.spi.DriverBase; import java.util.function.Supplier; -public class PgDriver implements Driver { +public class PgDriver extends DriverBase { - private static final String SHARED_CLIENT_KEY = "__vertx.shared.pgclient"; + private static final String DISCRIMINANT = "pgclient"; public static final PgDriver INSTANCE = new PgDriver(); - @Override - public Pool newPool(Vertx vertx, Supplier> databases, PoolOptions poolOptions, NetClientOptions transportOptions, Handler connectHandler, CloseFuture closeFuture) { - VertxInternal vx = (VertxInternal) vertx; - PoolImpl pool; - if (poolOptions.isShared()) { - pool = vx.createSharedResource(SHARED_CLIENT_KEY, poolOptions.getName(), closeFuture, cf -> newPoolImpl(vx, connectHandler, databases, poolOptions, transportOptions, cf)); - } else { - pool = newPoolImpl(vx, connectHandler, databases, poolOptions, transportOptions, closeFuture); - } - return new CloseablePool(vx, closeFuture, pool); + public PgDriver() { + super(DISCRIMINANT); } - private PoolImpl newPoolImpl(VertxInternal vertx, Handler connectHandler, Supplier> databases, PoolOptions poolOptions, NetClientOptions transportOptions, CloseFuture closeFuture) { + @Override + protected Pool newPool(VertxInternal vertx, Handler connectHandler, Supplier> databases, PoolOptions poolOptions, NetClientOptions transportOptions, CloseFuture closeFuture) { boolean pipelinedPool = poolOptions instanceof PgPoolOptions && ((PgPoolOptions) poolOptions).isPipelined(); ConnectionFactory factory = createConnectionFactory(vertx, transportOptions); - PoolImpl pool = new PoolImpl(vertx, this, pipelinedPool, poolOptions, null, null, context -> factory.connect(context, databases.get()), connectHandler, closeFuture); + PoolImpl pool = new PoolImpl(vertx, this, pipelinedPool, poolOptions, null, null, + factory, databases, connectHandler, this::wrapConnection, closeFuture); pool.init(); closeFuture.add(factory); return pool; @@ -81,7 +74,7 @@ public int appendQueryPlaceholder(StringBuilder queryBuilder, int index, int cur } @Override - public SqlConnectionInternal wrapConnection(ContextInternal context, ConnectionFactory factory, Connection conn) { - return new PgConnectionImpl((PgConnectionFactory) factory, context, conn); + public SqlConnectionInternal wrapConnection(ContextInternal context, ConnectionFactory factory, Connection connection) { + return new PgConnectionImpl((PgConnectionFactory) factory, context, connection); } } diff --git a/vertx-pg-client/src/main/java/module-info.java b/vertx-pg-client/src/main/java/module-info.java index c2094eeb05..ec6b47ed9e 100644 --- a/vertx-pg-client/src/main/java/module-info.java +++ b/vertx-pg-client/src/main/java/module-info.java @@ -6,6 +6,7 @@ requires io.netty.handler; requires io.netty.transport; requires io.vertx.sql.client; + requires io.vertx.sql.client.codec; requires io.vertx.core; requires io.vertx.core.logging; requires java.sql; diff --git a/vertx-pg-client/src/test/java/io/vertx/tests/pgclient/impl/RowImplTest.java b/vertx-pg-client/src/test/java/io/vertx/tests/pgclient/impl/PgRowTest.java similarity index 83% rename from vertx-pg-client/src/test/java/io/vertx/tests/pgclient/impl/RowImplTest.java rename to vertx-pg-client/src/test/java/io/vertx/tests/pgclient/impl/PgRowTest.java index db1bdfad2d..e71e6307fe 100644 --- a/vertx-pg-client/src/test/java/io/vertx/tests/pgclient/impl/RowImplTest.java +++ b/vertx-pg-client/src/test/java/io/vertx/tests/pgclient/impl/PgRowTest.java @@ -11,8 +11,8 @@ package io.vertx.tests.pgclient.impl; -import io.vertx.pgclient.impl.RowImpl; -import io.vertx.tests.sqlclient.TestRowDesc; +import io.vertx.pgclient.impl.PgRow; +import io.vertx.tests.sqlclient.TestRowDescriptor; import org.junit.Test; import java.time.LocalDate; @@ -20,13 +20,13 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; -public class RowImplTest { +public class PgRowTest { enum EnumValue { SOME, NONE } @Test public void testGetNullEnum() { - RowImpl row = new RowImpl(TestRowDesc.create("enum")); + PgRow row = new PgRow(TestRowDescriptor.create("enum")); row.addValue(null); assertNull(row.get(EnumValue.class, 0)); diff --git a/vertx-sql-client-codec/pom.xml b/vertx-sql-client-codec/pom.xml new file mode 100644 index 0000000000..6e459e61de --- /dev/null +++ b/vertx-sql-client-codec/pom.xml @@ -0,0 +1,49 @@ + + + + + 4.0.0 + + + io.vertx + vertx-sql-client-parent + 5.1.0-SNAPSHOT + + + vertx-sql-client-codec + + Vertx SQL Client Codec + https://github.com/eclipse-vertx/vertx-sql-client + Vert.x SQL Client Codec + + + + + + io.vertx + vertx-sql-client + + + + + + + + + + diff --git a/vertx-sql-client-codec/src/main/asciidoc/index.adoc b/vertx-sql-client-codec/src/main/asciidoc/index.adoc new file mode 100644 index 0000000000..e69de29bb2 diff --git a/vertx-sql-client-codec/src/main/java/io/vertx/sqlclient/codec/CommandMessage.java b/vertx-sql-client-codec/src/main/java/io/vertx/sqlclient/codec/CommandMessage.java new file mode 100644 index 0000000000..99ae87b6f5 --- /dev/null +++ b/vertx-sql-client-codec/src/main/java/io/vertx/sqlclient/codec/CommandMessage.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2011-2025 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 + */ +package io.vertx.sqlclient.codec; + +import io.vertx.core.AsyncResult; +import io.vertx.core.Completable; +import io.vertx.core.Future; +import io.vertx.sqlclient.spi.protocol.CommandBase; + +public class CommandMessage> { + + public Completable handler; + public final C cmd; + + public CommandMessage(C cmd) { + this.cmd = cmd; + } + + public final void fail(Throwable err) { + complete(Future.failedFuture(err)); + } + + public final void fail(String failureMsg) { + complete(Future.failedFuture(failureMsg)); + } + + public final void complete(AsyncResult resp) { + if (handler != null) { + handler.complete(resp.result(), resp.cause()); + } + } +} diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/CommandResponse.java b/vertx-sql-client-codec/src/main/java/io/vertx/sqlclient/codec/CommandResponse.java similarity index 82% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/CommandResponse.java rename to vertx-sql-client-codec/src/main/java/io/vertx/sqlclient/codec/CommandResponse.java index bf94c8ab36..83634185ca 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/CommandResponse.java +++ b/vertx-sql-client-codec/src/main/java/io/vertx/sqlclient/codec/CommandResponse.java @@ -9,11 +9,13 @@ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 */ -package io.vertx.sqlclient.internal.command; +package io.vertx.sqlclient.codec; +import io.vertx.core.Completable; import io.vertx.core.Future; import io.vertx.core.AsyncResult; import io.vertx.core.VertxException; +import io.vertx.sqlclient.spi.protocol.CommandBase; public class CommandResponse { @@ -31,6 +33,7 @@ public static CommandResponse success(R result) { // The connection that executed the command public CommandBase cmd; + public Completable handler; private final AsyncResult res; public CommandResponse(AsyncResult res) { @@ -41,9 +44,9 @@ public AsyncResult toAsyncResult() { return res; } - public void fire() { - if (cmd.handler != null) { - cmd.handler.complete(res.result(), res.cause()); + public final void fire() { + if (handler != null) { + handler.complete(res.result(), res.cause()); } } } diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/codec/InvalidCachedStatementEvent.java b/vertx-sql-client-codec/src/main/java/io/vertx/sqlclient/codec/InvalidCachedStatementEvent.java similarity index 88% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/codec/InvalidCachedStatementEvent.java rename to vertx-sql-client-codec/src/main/java/io/vertx/sqlclient/codec/InvalidCachedStatementEvent.java index 711476d7da..1dae303dd1 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/codec/InvalidCachedStatementEvent.java +++ b/vertx-sql-client-codec/src/main/java/io/vertx/sqlclient/codec/InvalidCachedStatementEvent.java @@ -1,9 +1,10 @@ -package io.vertx.sqlclient.impl.codec; +package io.vertx.sqlclient.codec; /** * An event signals when a cached prepared statement is invalid and needs to be evicted from the cache. */ public class InvalidCachedStatementEvent { + private final String sql; public InvalidCachedStatementEvent(String sql) { diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/SocketConnectionBase.java b/vertx-sql-client-codec/src/main/java/io/vertx/sqlclient/codec/SocketConnectionBase.java similarity index 71% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/SocketConnectionBase.java rename to vertx-sql-client-codec/src/main/java/io/vertx/sqlclient/codec/SocketConnectionBase.java index 8853f8595a..65ecb151a4 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/SocketConnectionBase.java +++ b/vertx-sql-client-codec/src/main/java/io/vertx/sqlclient/codec/SocketConnectionBase.java @@ -15,7 +15,7 @@ * */ -package io.vertx.sqlclient.impl; +package io.vertx.sqlclient.codec; import io.netty.channel.Channel; import io.netty.channel.ChannelFutureListener; @@ -29,23 +29,34 @@ import io.vertx.core.tracing.TracingPolicy; import io.vertx.core.internal.ContextInternal; import io.vertx.core.internal.net.NetSocketInternal; +import io.vertx.sqlclient.Row; import io.vertx.sqlclient.SqlConnectOptions; -import io.vertx.sqlclient.impl.cache.PreparedStatementCache; -import io.vertx.sqlclient.impl.codec.InvalidCachedStatementEvent; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.internal.command.*; +import io.vertx.sqlclient.codec.impl.PreparedStatementCache; +import io.vertx.sqlclient.spi.connection.Connection; import io.vertx.sqlclient.internal.PreparedStatement; import io.vertx.sqlclient.spi.DatabaseMetadata; +import io.vertx.sqlclient.spi.connection.ConnectionContext; +import io.vertx.sqlclient.spi.protocol.CloseConnectionCommand; +import io.vertx.sqlclient.spi.protocol.CloseStatementCommand; +import io.vertx.sqlclient.spi.protocol.CommandBase; +import io.vertx.sqlclient.spi.protocol.CompositeCommand; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; +import io.vertx.sqlclient.spi.protocol.PrepareStatementCommand; import java.util.ArrayDeque; import java.util.List; +import java.util.function.Function; import java.util.function.Predicate; +import java.util.stream.Collector; /** * @author Julien Viet */ public abstract class SocketConnectionBase implements Connection { + public static final Collector NULL_COLLECTOR = Collector.of(() -> null, (v, row) -> {}, (v1, v2) -> null, Function.identity()); + private static final Completable NULL_HANDLER = (res, err) -> {}; + public static final Logger logger = LoggerFactory.getLogger(SocketConnectionBase.class); public enum Status { @@ -60,11 +71,12 @@ public enum Status { protected final PreparedStatementCache psCache; protected final ContextInternal context; private final Predicate preparedStatementCacheSqlFilter; - private Holder holder; + private ConnectionContext holder; private final int pipeliningLimit; // Command pipeline state private final ArrayDeque> pending = new ArrayDeque<>(); + private final ArrayDeque> handlers = new ArrayDeque<>(); private boolean executing; private int inflight; private boolean paused; @@ -116,11 +128,11 @@ public String user() { } @Override - public DatabaseMetadata getDatabaseMetaData() { + public DatabaseMetadata databaseMetadata() { return null; } - public Context context() { + public io.vertx.core.Context context() { return context; } @@ -156,7 +168,7 @@ public boolean isValid() { } @Override - public void init(Holder holder) { + public void init(ConnectionContext holder) { ContextInternal context = (ContextInternal) Vertx.currentContext(); if (context == null || context.nettyEventLoop() != this.context.nettyEventLoop()) { throw new IllegalStateException(); @@ -168,23 +180,14 @@ public void init(Holder holder) { } @Override - public int getProcessId() { - throw new UnsupportedOperationException(); - } - - @Override - public int getSecretKey() { - throw new UnsupportedOperationException(); - } - - @Override - public void close(Holder holder, Completable promise) { + public void close(ConnectionContext holder, Completable promise) { if (Vertx.currentContext() == context) { Channel ch = socket.channelHandlerContext().channel(); if (status == Status.CONNECTED) { status = Status.CLOSING; // Append directly since schedule checks the status and won't enqueue the command pending.add(CloseConnectionCommand.INSTANCE); + handlers.add(NULL_HANDLER); checkPending(); } ch.closeFuture() @@ -203,23 +206,24 @@ protected void doSchedule(CommandBase cmd, Completable handler) { if (handler == null) { throw new IllegalArgumentException(); } - Context context = Vertx.currentContext(); + io.vertx.core.Context context = Vertx.currentContext(); if (context != this.context) { throw new IllegalStateException(); } - cmd.handler = handler; +// cmd.handler = handler; if (status == Status.CONNECTED) { if (cmd instanceof CompositeCommand) { CompositeCommand composite = (CompositeCommand) cmd; - List> commands = composite.commands(); - pending.addAll(commands); - composite.handler.succeed(); + pending.addAll(composite.commands()); + handlers.addAll(composite.handlers()); + handler.succeed(); } else { pending.add(cmd); + handlers.add(handler); } checkPending(); } else { - cmd.fail(VertxException.noStackTrace("Connection is not active now, current status: " + status)); + handler.fail(VertxException.noStackTrace("Connection is not active now, current status: " + status)); } } @@ -234,39 +238,46 @@ private void checkPending() { CommandBase cmd; while (!paused && inflight < pipeliningLimit && (cmd = pending.poll()) != null) { inflight++; + Completable handler = handlers.poll(); + CommandMessage toSend; if (cmd instanceof ExtendedQueryCommand) { ExtendedQueryCommand queryCmd = (ExtendedQueryCommand) cmd; - if (queryCmd.ps == null) { + PreparedStatement ps = queryCmd.preparedStatement(); + if (ps == null) { if (psCache != null) { - queryCmd.ps = psCache.get(queryCmd.sql()); + ps = psCache.get(queryCmd.sql()); } } - if (queryCmd.ps == null) { + if (ps == null) { // Execute prepare boolean cache = psCache != null && preparedStatementCacheSqlFilter.test(queryCmd.sql()); if (cache) { - CloseStatementCommand closeCmd = evictStatementIfNecessary(); + CommandMessage closeCmd = evictStatementIfNecessary(); if (closeCmd != null) { inflight++; written++; ctx.write(closeCmd, ctx.voidPromise()); } } - PrepareStatementCommand prepareCmd = prepareCommand(queryCmd, cache, false); + CommandMessage prepareCmd = prepareCommand(queryCmd, handler, cache, false); paused = true; inflight++; - cmd = prepareCmd; + toSend = prepareCmd; } else { - String msg = queryCmd.prepare(); + String msg = queryCmd.prepare(ps); if (msg != null) { inflight--; - queryCmd.fail(VertxException.noStackTrace(msg)); + handler.fail(VertxException.noStackTrace(msg)); continue; + } else { + toSend = createMessage(queryCmd, ps, handler); } } + } else { + toSend = createMessage(cmd, handler); } written++; - ctx.write(cmd, ctx.voidPromise()); + ctx.write(toSend, ctx.voidPromise()); } if (written > 0) { ctx.flush(); @@ -276,37 +287,58 @@ private void checkPending() { } } - private PrepareStatementCommand prepareCommand(ExtendedQueryCommand queryCmd, boolean cache, boolean sendParameterTypes) { + private CommandMessage createMessage(ExtendedQueryCommand command, PreparedStatement preparedStatement, Completable handler) { + CommandMessage msg = toMessage(command, preparedStatement); + msg.handler = (Completable) handler; + return msg; + } + + private CommandMessage createMessage(CommandBase command, Completable handler) { + CommandMessage msg = toMessage(command); + msg.handler = (Completable) handler; + return msg; + } + + protected CommandMessage toMessage(ExtendedQueryCommand command, PreparedStatement preparedStatement) { + throw new UnsupportedOperationException(); + } + + protected CommandMessage toMessage(CommandBase command) { + throw new UnsupportedOperationException(); + } + + private CommandMessage prepareCommand(ExtendedQueryCommand queryCmd, Completable handler, boolean cache, boolean sendParameterTypes) { PrepareStatementCommand prepareCmd = new PrepareStatementCommand(queryCmd.sql(), null, cache, sendParameterTypes ? queryCmd.parameterTypes() : null); - prepareCmd.handler = (ps, cause) -> { + CommandMessage prepareMsg = (CommandMessage) toMessage(prepareCmd); + prepareMsg.handler = (ps, cause) -> { paused = false; if (cause == null) { if (cache) { cacheStatement(ps); } - queryCmd.ps = ps; - String msg = queryCmd.prepare(); +// queryCmd.ps = ps; + String msg = queryCmd.prepare(ps); if (msg != null) { inflight--; - queryCmd.fail(VertxException.noStackTrace(msg)); + handler.fail(VertxException.noStackTrace(msg)); } else { ChannelHandlerContext ctx = socket.channelHandlerContext(); - ctx.write(queryCmd, ctx.voidPromise()); + ctx.write(createMessage(queryCmd, ps, handler), ctx.voidPromise()); ctx.flush(); } } else { if (isIndeterminatePreparedStatementError(cause) && !sendParameterTypes) { ChannelHandlerContext ctx = socket.channelHandlerContext(); // We cannot cache this prepared statement because it might be executed with another type - ctx.write(prepareCommand(queryCmd, false, true), ctx.voidPromise()); + ctx.write(prepareCommand(queryCmd, handler, false, true), ctx.voidPromise()); ctx.flush(); } else { inflight--; - queryCmd.fail(cause); + handler.fail(cause); } } }; - return prepareCmd; + return prepareMsg; } protected void handleMessage(Object msg) { @@ -330,16 +362,17 @@ protected void handleEvent(Object event) { } } - private CloseStatementCommand evictStatementIfNecessary() { + private CommandMessage evictStatementIfNecessary() { if (psCache != null && psCache.isFull()) { PreparedStatement evicted = psCache.evict(); CloseStatementCommand closeCmd = new CloseStatementCommand(evicted); - closeCmd.handler = (res, err) -> { + CommandMessage msg = toMessage(closeCmd); + msg.handler = (res, err) -> { if (err != null) { logger.error("Error when closing cached prepared statement", err); } }; - return closeCmd; + return msg; } else { return null; } @@ -391,7 +424,8 @@ protected void handleClose(Throwable t) { CommandBase cmd; while ((cmd = pending.poll()) != null) { CommandBase c = cmd; - context.runOnContext(v -> c.fail(cause)); + Completable handler = handlers.poll(); + context.runOnContext(v -> handler.fail(cause)); } if (holder != null) { holder.handleClosed(); @@ -410,4 +444,10 @@ public void suspendPipeline() { public void resumePipeline() { this.paused = false; } + + protected void clearCachedStatements() { + if (this.psCache != null) { + this.psCache.clear(); + } + } } diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/cache/LruCache.java b/vertx-sql-client-codec/src/main/java/io/vertx/sqlclient/codec/impl/LruCache.java similarity index 97% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/cache/LruCache.java rename to vertx-sql-client-codec/src/main/java/io/vertx/sqlclient/codec/impl/LruCache.java index a8183ccd98..0c093bdf3f 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/cache/LruCache.java +++ b/vertx-sql-client-codec/src/main/java/io/vertx/sqlclient/codec/impl/LruCache.java @@ -9,7 +9,7 @@ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 */ -package io.vertx.sqlclient.impl.cache; +package io.vertx.sqlclient.codec.impl; import java.util.*; diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/cache/PreparedStatementCache.java b/vertx-sql-client-codec/src/main/java/io/vertx/sqlclient/codec/impl/PreparedStatementCache.java similarity index 98% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/cache/PreparedStatementCache.java rename to vertx-sql-client-codec/src/main/java/io/vertx/sqlclient/codec/impl/PreparedStatementCache.java index 445b224b17..694801563f 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/cache/PreparedStatementCache.java +++ b/vertx-sql-client-codec/src/main/java/io/vertx/sqlclient/codec/impl/PreparedStatementCache.java @@ -9,7 +9,7 @@ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 */ -package io.vertx.sqlclient.impl.cache; +package io.vertx.sqlclient.codec.impl; import io.vertx.sqlclient.internal.PreparedStatement; diff --git a/vertx-sql-client-codec/src/main/java/module-info.java b/vertx-sql-client-codec/src/main/java/module-info.java new file mode 100644 index 0000000000..6937aed229 --- /dev/null +++ b/vertx-sql-client-codec/src/main/java/module-info.java @@ -0,0 +1,16 @@ +module io.vertx.sql.client.codec { + + requires io.netty.common; + requires io.netty.buffer; + requires io.netty.codec; + requires io.netty.transport; + + requires io.vertx.core; + requires io.vertx.core.logging; + + requires io.vertx.sql.client; + + exports io.vertx.sqlclient.codec; + exports io.vertx.sqlclient.codec.impl to io.vertx.tests.sql.client.codec; + +} diff --git a/vertx-sql-client/src/test/java/io/vertx/tests/sqlclient/LruCacheTest.java b/vertx-sql-client-codec/src/test/java/io/vertx/tests/sqlclient/codec/LruCacheTest.java similarity index 93% rename from vertx-sql-client/src/test/java/io/vertx/tests/sqlclient/LruCacheTest.java rename to vertx-sql-client-codec/src/test/java/io/vertx/tests/sqlclient/codec/LruCacheTest.java index 314dc37b68..5b3e620d1f 100644 --- a/vertx-sql-client/src/test/java/io/vertx/tests/sqlclient/LruCacheTest.java +++ b/vertx-sql-client-codec/src/test/java/io/vertx/tests/sqlclient/codec/LruCacheTest.java @@ -1,6 +1,6 @@ -package io.vertx.tests.sqlclient; +package io.vertx.tests.sqlclient.codec; -import io.vertx.sqlclient.impl.cache.LruCache; +import io.vertx.sqlclient.codec.impl.LruCache; import org.junit.Test; import java.util.List; diff --git a/vertx-sql-client-codec/src/test/java/module-info.java b/vertx-sql-client-codec/src/test/java/module-info.java new file mode 100644 index 0000000000..923b8fdaff --- /dev/null +++ b/vertx-sql-client-codec/src/test/java/module-info.java @@ -0,0 +1,11 @@ +open module io.vertx.tests.sql.client.codec { + + requires io.vertx.core; + requires io.vertx.core.logging; + requires io.vertx.sql.client; + requires io.vertx.sql.client.codec; + requires io.vertx.testing.unit; + requires java.sql; + requires junit; + +} diff --git a/vertx-sql-client-templates/src/main/java/io/vertx/sqlclient/templates/impl/JsonTuple.java b/vertx-sql-client-templates/src/main/java/io/vertx/sqlclient/templates/impl/JsonTuple.java index d868690cd5..f5254c25f6 100644 --- a/vertx-sql-client-templates/src/main/java/io/vertx/sqlclient/templates/impl/JsonTuple.java +++ b/vertx-sql-client-templates/src/main/java/io/vertx/sqlclient/templates/impl/JsonTuple.java @@ -12,11 +12,11 @@ import io.vertx.core.json.JsonObject; import io.vertx.sqlclient.Tuple; -import io.vertx.sqlclient.internal.TupleInternal; +import io.vertx.sqlclient.internal.TupleBase; import java.util.function.Function; -public class JsonTuple extends TupleInternal { +public class JsonTuple extends TupleBase { private final int size; private final Function columnMapping; diff --git a/vertx-sql-client-templates/src/test/java/io/vertx/tests/sqlclient/templates/TemplateBuilderTest.java b/vertx-sql-client-templates/src/test/java/io/vertx/tests/sqlclient/templates/TemplateBuilderTest.java index cce82a6099..69f04306e4 100644 --- a/vertx-sql-client-templates/src/test/java/io/vertx/tests/sqlclient/templates/TemplateBuilderTest.java +++ b/vertx-sql-client-templates/src/test/java/io/vertx/tests/sqlclient/templates/TemplateBuilderTest.java @@ -7,7 +7,6 @@ import io.vertx.core.net.NetClientOptions; import io.vertx.sqlclient.*; import io.vertx.sqlclient.impl.SqlClientInternal; -import io.vertx.sqlclient.spi.ConnectionFactory; import io.vertx.sqlclient.spi.Driver; import io.vertx.sqlclient.templates.impl.SqlTemplate; import org.junit.Assert; @@ -42,10 +41,6 @@ public Pool newPool(Vertx vertx, Supplier> databases, throw new UnsupportedOperationException(); } @Override - public ConnectionFactory createConnectionFactory(Vertx vertx, NetClientOptions transportOptions) { - throw new UnsupportedOperationException(); - } - @Override public boolean acceptsOptions(SqlConnectOptions connectOptions) { throw new UnsupportedOperationException(); } diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/Pool.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/Pool.java index 8d8be09733..9adb88b8e4 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/Pool.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/Pool.java @@ -34,7 +34,7 @@ import java.util.function.Function; -import static io.vertx.sqlclient.internal.pool.PoolImpl.startPropagatableConnection; +import static io.vertx.sqlclient.impl.pool.PoolImpl.startPropagatableConnection; /** * A connection pool which reuses a number of SQL connections. diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/SqlResult.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/SqlResult.java index 90fcafac40..7a975d3bca 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/SqlResult.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/SqlResult.java @@ -19,6 +19,7 @@ import io.vertx.codegen.annotations.VertxGen; import io.vertx.sqlclient.desc.ColumnDescriptor; +import io.vertx.sqlclient.desc.RowDescriptor; import java.util.List; @@ -37,6 +38,8 @@ public interface SqlResult { */ int rowCount(); + RowDescriptor rowDescriptor(); + /** * Get the names of columns in the SqlResult. * diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/desc/RowDescriptor.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/desc/RowDescriptor.java new file mode 100644 index 0000000000..e6677f0971 --- /dev/null +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/desc/RowDescriptor.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2011-2025 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 + */ +package io.vertx.sqlclient.desc; + +import io.vertx.codegen.annotations.VertxGen; + +import java.util.List; + +/** + * Describe a database row. + */ +@VertxGen +public interface RowDescriptor { + + /** + * Get the index of the named column or {@literal -1} when not found + * @param columnName the column to lookup + * @return the index of the column + */ + int columnIndex(String columnName); + + /** + * @return the list of the column names + */ + List columnNames(); + + /** + * @return the list of column descriptors + */ + List columnDescriptors(); + +} diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/ConnectionFactoryBase.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/ConnectionFactoryBase.java index bb9bd120e5..e3bb92d32c 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/ConnectionFactoryBase.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/ConnectionFactoryBase.java @@ -12,7 +12,6 @@ import io.vertx.core.Completable; import io.vertx.core.Future; -import io.vertx.core.Promise; import io.vertx.core.net.NetClient; import io.vertx.core.net.NetClientOptions; import io.vertx.core.internal.CloseSequence; @@ -20,8 +19,8 @@ import io.vertx.core.internal.PromiseInternal; import io.vertx.core.internal.VertxInternal; import io.vertx.sqlclient.SqlConnectOptions; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.spi.ConnectionFactory; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.spi.connection.ConnectionFactory; /** * An base connection factory for creating database connections diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/CursorImpl.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/CursorImpl.java index c525e6dbab..027da9a375 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/CursorImpl.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/CursorImpl.java @@ -24,9 +24,8 @@ import io.vertx.sqlclient.Cursor; import io.vertx.sqlclient.Row; import io.vertx.sqlclient.RowSet; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.internal.PreparedStatement; -import io.vertx.sqlclient.internal.TupleInternal; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.internal.TupleBase; import java.util.UUID; @@ -39,13 +38,13 @@ public class CursorImpl implements Cursor { private final PreparedStatementBase ps; private final ContextInternal context; private final boolean autoCommit; - private final TupleInternal params; + private final TupleBase params; private String id; private boolean closed; QueryResultBuilder, RowSetImpl, RowSet> result; - CursorImpl(PreparedStatementBase ps, Connection conn, ContextInternal context, boolean autoCommit, TupleInternal params) { + CursorImpl(PreparedStatementBase ps, Connection conn, ContextInternal context, boolean autoCommit, TupleBase params) { this.ps = ps; this.conn = conn; this.context = context; diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/ListTuple.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/ListTuple.java index a38e1e3cae..f294608253 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/ListTuple.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/ListTuple.java @@ -18,11 +18,11 @@ package io.vertx.sqlclient.impl; import io.vertx.sqlclient.Tuple; -import io.vertx.sqlclient.internal.TupleInternal; +import io.vertx.sqlclient.internal.TupleBase; import java.util.List; -public class ListTuple extends TupleInternal { +public class ListTuple extends TupleBase { private final List list; diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/PreparedStatementBase.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/PreparedStatementBase.java index 585c0d6f8f..793b501180 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/PreparedStatementBase.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/PreparedStatementBase.java @@ -22,9 +22,9 @@ import io.vertx.sqlclient.PrepareOptions; import io.vertx.sqlclient.PreparedQuery; import io.vertx.sqlclient.internal.ArrayTuple; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.internal.command.CloseCursorCommand; -import io.vertx.sqlclient.internal.command.CloseStatementCommand; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.spi.protocol.CloseCursorCommand; +import io.vertx.sqlclient.spi.protocol.CloseStatementCommand; import io.vertx.sqlclient.Cursor; import io.vertx.sqlclient.PreparedStatement; import io.vertx.sqlclient.SqlResult; @@ -33,8 +33,8 @@ import io.vertx.sqlclient.Row; import io.vertx.sqlclient.Tuple; import io.vertx.core.*; -import io.vertx.sqlclient.internal.command.PrepareStatementCommand; -import io.vertx.sqlclient.internal.TupleInternal; +import io.vertx.sqlclient.spi.protocol.PrepareStatementCommand; +import io.vertx.sqlclient.internal.TupleBase; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; @@ -69,7 +69,7 @@ protected void closeCursor(String cursorId, Promise promise) { conn.schedule(cmd, promise); } @Override - protected void readCursor(CursorImpl cursor, String id, boolean suspended, TupleInternal params, int count, PromiseInternal> promise) { + protected void readCursor(CursorImpl cursor, String id, boolean suspended, TupleBase params, int count, PromiseInternal> promise) { QueryExecutor, RowSetImpl, RowSet> builder = new QueryExecutor<>(RowSetImpl.FACTORY, RowSetImpl.COLLECTOR); cursor.result = builder.executeExtendedQuery(conn, preparedStatement, null, autoCommit, params, count, id, suspended, promise); } @@ -113,7 +113,7 @@ protected > void execute(Tuple args, int fetch, String }); } @Override - protected void readCursor(CursorImpl cursor, String id, boolean suspended, TupleInternal params, int count, PromiseInternal> promise) { + protected void readCursor(CursorImpl cursor, String id, boolean suspended, TupleBase params, int count, PromiseInternal> promise) { withPreparedStatement(options, params, ar -> { if (ar.succeeded()) { QueryExecutor, RowSetImpl, RowSet> builder = new QueryExecutor<>(RowSetImpl.FACTORY, RowSetImpl.COLLECTOR); @@ -170,7 +170,7 @@ private PreparedStatementBase(Connection conn, ContextInternal context, boolean protected abstract > void executeBatch(List argsList, QueryExecutor builder, PromiseInternal p); protected abstract void close(Promise promise); protected abstract void closeCursor(String cursorId, Promise promise); - protected abstract void readCursor(CursorImpl cursor, String id, boolean suspended, TupleInternal params, int count, PromiseInternal> promise); + protected abstract void readCursor(CursorImpl cursor, String id, boolean suspended, TupleBase params, int count, PromiseInternal> promise); @Override public final PreparedQuery> query() { @@ -179,7 +179,7 @@ public final PreparedQuery> query() { @Override public final Cursor cursor(Tuple args) { - return new CursorImpl(this, conn, context, autoCommit, (TupleInternal) args); + return new CursorImpl(this, conn, context, autoCommit, (TupleBase) args); } @Override diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/QueryExecutor.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/QueryExecutor.java index b60c1f2970..5ed6be09c6 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/QueryExecutor.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/QueryExecutor.java @@ -23,13 +23,12 @@ import io.vertx.sqlclient.Row; import io.vertx.sqlclient.SqlResult; import io.vertx.sqlclient.Tuple; -import io.vertx.sqlclient.internal.command.CommandScheduler; -import io.vertx.sqlclient.internal.command.ExtendedQueryCommand; -import io.vertx.sqlclient.internal.command.SimpleQueryCommand; +import io.vertx.sqlclient.spi.protocol.CommandScheduler; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; +import io.vertx.sqlclient.spi.protocol.SimpleQueryCommand; import io.vertx.sqlclient.internal.PreparedStatement; -import io.vertx.sqlclient.internal.TupleInternal; +import io.vertx.sqlclient.internal.TupleBase; -import java.util.ArrayList; import java.util.List; import java.util.function.Function; import java.util.stream.Collector; @@ -74,7 +73,7 @@ QueryResultBuilder executeExtendedQuery(CommandScheduler scheduler, ContextInternal context = promise.context(); QueryResultBuilder handler = createHandler(promise); try { - values = preparedStatement.prepare((TupleInternal) values); + values = preparedStatement.prepare((TupleBase) values); } catch (Exception e) { handler.fail(e); return null; diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/QueryResultBuilder.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/QueryResultBuilder.java index 04ef6a3fb0..ab6f2c263c 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/QueryResultBuilder.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/QueryResultBuilder.java @@ -18,13 +18,12 @@ package io.vertx.sqlclient.impl; import io.vertx.core.Completable; -import io.vertx.core.Future; import io.vertx.core.Promise; import io.vertx.core.internal.PromiseInternal; import io.vertx.sqlclient.PropertyKind; import io.vertx.sqlclient.SqlResult; import io.vertx.sqlclient.internal.QueryResultHandler; -import io.vertx.sqlclient.internal.RowDesc; +import io.vertx.sqlclient.internal.RowDescriptorBase; import java.util.function.Function; @@ -46,15 +45,14 @@ public class QueryResultBuilder, L extends SqlResu } @Override - public void handleResult(int updatedCount, int size, RowDesc desc, T result, Throwable failure) { + public void handleResult(int updatedCount, int size, RowDescriptorBase desc, T result, Throwable failure) { if (failure != null) { this.failure = failure; } else { R r = factory.apply(result); r.updated = updatedCount; r.size = size; - r.columnNames = desc != null ? desc.columnNames() : null; - r.columnDescriptors = desc != null ? desc.columnDescriptor() : null; + r.rowDescriptor = desc; handleResult(r); } } diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/RowBase.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/RowBase.java index cb21b48f23..38fdd3c331 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/RowBase.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/RowBase.java @@ -2,27 +2,50 @@ import io.vertx.sqlclient.Tuple; import io.vertx.sqlclient.internal.ArrayTuple; +import io.vertx.sqlclient.internal.RowDescriptorBase; import io.vertx.sqlclient.internal.RowInternal; import java.util.Collection; +import java.util.List; /** * Base class for rows. */ -public abstract class RowBase extends ArrayTuple implements RowInternal { +public class RowBase extends ArrayTuple implements RowInternal { private boolean released; + protected final RowDescriptorBase desc; - public RowBase(int len) { - super(len); + public RowBase(RowDescriptorBase desc) { + super(desc.columnNames().size()); + + this.desc = desc; } - public RowBase(Collection c) { + public RowBase(RowDescriptorBase desc, Collection c) { super(c); + + this.desc = desc; } - public RowBase(Tuple tuple) { + public RowBase(RowDescriptorBase desc, Tuple tuple) { super(tuple); + + this.desc = desc; + } + + @Override + public String getColumnName(int pos) { + List columnNames = desc.columnNames(); + return pos < 0 || columnNames.size() - 1 < pos ? null : columnNames.get(pos); + } + + @Override + public int getColumnIndex(String name) { + if (name == null) { + throw new NullPointerException(); + } + return desc.columnIndex(name); } @Override diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/SqlResultBase.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/SqlResultBase.java index 19cf81b760..5a934ff237 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/SqlResultBase.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/SqlResultBase.java @@ -20,26 +20,34 @@ import io.vertx.sqlclient.PropertyKind; import io.vertx.sqlclient.SqlResult; import io.vertx.sqlclient.desc.ColumnDescriptor; +import io.vertx.sqlclient.desc.RowDescriptor; +import io.vertx.sqlclient.internal.RowDescriptorBase; import java.util.List; public abstract class SqlResultBase implements SqlResult { int updated; - List columnNames; - List columnDescriptors; + RowDescriptorBase rowDescriptor; int size; SqlResult next; protected PropertyKindMap properties; @Override public List columnsNames() { - return columnNames; + RowDescriptorBase desc = rowDescriptor; + return desc != null ? desc.columnNames() : null; + } + + @Override + public RowDescriptor rowDescriptor() { + return rowDescriptor; } @Override public List columnDescriptors() { - return columnDescriptors; + RowDescriptorBase desc = rowDescriptor; + return desc != null ? desc.columnDescriptors() : null; } @Override diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/TransactionImpl.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/TransactionImpl.java index a52bdda20a..154155ac23 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/TransactionImpl.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/TransactionImpl.java @@ -21,9 +21,9 @@ import io.vertx.core.internal.PromiseInternal; import io.vertx.sqlclient.Transaction; import io.vertx.sqlclient.TransactionRollbackException; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.internal.command.CommandBase; -import io.vertx.sqlclient.internal.command.TxCommand; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.spi.protocol.CommandBase; +import io.vertx.sqlclient.spi.protocol.TxCommand; public class TransactionImpl implements Transaction { @@ -46,8 +46,7 @@ public TransactionImpl(ContextInternal context, Handler endHandler, Connec public Future begin() { PromiseInternal promise = context.promise(); TxCommand begin = new TxCommand<>(TxCommand.Kind.BEGIN, this); - begin.handler = wrap(begin, promise); - schedule(begin); + scheduleInternal(begin, wrap(begin, promise)); return promise.future(); } @@ -55,8 +54,7 @@ public void fail() { failed = true; } - private void execute(CommandBase cmd) { - Completable handler = cmd.handler; + private void execute(CommandBase cmd, Completable handler) { connection.schedule(cmd, handler); } @@ -71,35 +69,42 @@ private Completable wrap(CommandBase cmd, Completable handler) { } public void schedule(CommandBase cmd, Completable handler) { - cmd.handler = wrap(cmd, handler); - if (!schedule(cmd)) { + if (!scheduleInternal(cmd, wrap(cmd, handler))) { handler.fail("Transaction already completed"); } } - public boolean schedule(CommandBase b) { + public boolean scheduleInternal(CommandBase b, Completable handler) { synchronized (this) { if (ended) { return false; } pendingQueries++; } - execute(b); + execute(b, handler); return true; } private void checkEnd() { - TxCommand cmd; + TxCommand cmd; + Completable handler; synchronized (this) { if (pendingQueries > 0 || !ended || endCommand != null) { return; } TxCommand.Kind kind = failed ? TxCommand.Kind.ROLLBACK : TxCommand.Kind.COMMIT; - endCommand = txCommand(kind); - cmd = endCommand; + cmd = new TxCommand<>(kind, null); + handler = (res, err) -> { + if (err == null) { + completion.complete(kind); + } else { + completion.fail(err); + } + }; + endCommand = cmd; } endHandler.handle(null); - execute(cmd); + execute(cmd, handler); } private Future end(boolean rollback) { @@ -144,18 +149,6 @@ public void rollback(Handler> handler) { } } - private TxCommand txCommand(TxCommand.Kind kind) { - TxCommand cmd = new TxCommand<>(kind, null); - cmd.handler = (res, err) -> { - if (err == null) { - completion.complete(kind); - } else { - completion.fail(err); - } - }; - return cmd; - } - @Override public Future completion() { return completion.future().flatMap(k -> { diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/Utils.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/Utils.java index 0d4b28a393..dac3eaf65d 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/Utils.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/Utils.java @@ -1,5 +1,6 @@ package io.vertx.sqlclient.impl; +import io.netty.buffer.ByteBuf; import io.vertx.core.Future; import io.vertx.core.buffer.Buffer; import io.vertx.core.json.JsonArray; @@ -69,4 +70,34 @@ public Future get() { public static Supplier> singletonSupplier(T factory) { return () -> Future.succeededFuture(factory); } + + /** + * Decode the specified {@code buff} formatted as a decimal string starting at the readable index + * with the specified {@code length} to a long. + * + * @param index the hex string index + * @param len the hex string length + * @param buff the byte buff to read from + * @return the decoded value as a long + */ + public static long decodeDecStringToLong(int index, int len, ByteBuf buff) { + long value = 0; + if (len > 0) { + int to = index + len; + boolean neg = false; + if (buff.getByte(index) == '-') { + neg = true; + index++; + } + while (index < to) { + byte ch = buff.getByte(index++); + byte nibble = (byte) (ch - '0'); + value = value * 10 + nibble; + } + if (neg) { + value = -value; + } + } + return value; + } } diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/codec/CommonCodec.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/codec/CommonCodec.java deleted file mode 100644 index b325c79e41..0000000000 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/codec/CommonCodec.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2011-2020 Contributors to the Eclipse Foundation - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 - * which is available at https://www.apache.org/licenses/LICENSE-2.0. - * - * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 - */ - -package io.vertx.sqlclient.impl.codec; - -import io.netty.buffer.ByteBuf; - -public class CommonCodec { - /** - * Decode the specified {@code buff} formatted as a decimal string starting at the readable index - * with the specified {@code length} to a long. - * - * @param index the hex string index - * @param len the hex string length - * @param buff the byte buff to read from - * @return the decoded value as a long - */ - public static long decodeDecStringToLong(int index, int len, ByteBuf buff) { - long value = 0; - if (len > 0) { - int to = index + len; - boolean neg = false; - if (buff.getByte(index) == '-') { - neg = true; - index++; - } - while (index < to) { - byte ch = buff.getByte(index++); - byte nibble = (byte) (ch - '0'); - value = value * 10 + nibble; - } - if (neg) { - value = -value; - } - } - return value; - } -} diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/pool/CloseablePool.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/pool/CloseablePool.java similarity index 98% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/pool/CloseablePool.java rename to vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/pool/CloseablePool.java index a3b049b5ac..a250f6e53a 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/pool/CloseablePool.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/pool/CloseablePool.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.vertx.sqlclient.internal.pool; +package io.vertx.sqlclient.impl.pool; import io.vertx.codegen.annotations.Nullable; import io.vertx.core.Future; diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/pool/ConnectionWrapper.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/pool/ConnectionWrapper.java new file mode 100644 index 0000000000..1abc8b4021 --- /dev/null +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/pool/ConnectionWrapper.java @@ -0,0 +1,12 @@ +package io.vertx.sqlclient.impl.pool; + +import io.vertx.core.internal.ContextInternal; +import io.vertx.sqlclient.SqlConnectOptions; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.internal.SqlConnectionInternal; +import io.vertx.sqlclient.spi.connection.ConnectionFactory; + +public interface ConnectionWrapper { + + SqlConnectionInternal wrap(ContextInternal context, ConnectionFactory factory, Connection conn); +} diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/pool/PoolImpl.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/pool/PoolImpl.java similarity index 84% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/pool/PoolImpl.java rename to vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/pool/PoolImpl.java index 1a82ba721e..803e2b8af3 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/pool/PoolImpl.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/pool/PoolImpl.java @@ -15,7 +15,7 @@ * */ -package io.vertx.sqlclient.internal.pool; +package io.vertx.sqlclient.impl.pool; import io.vertx.codegen.annotations.Nullable; import io.vertx.core.*; @@ -27,14 +27,16 @@ import io.vertx.core.spi.metrics.VertxMetrics; import io.vertx.sqlclient.*; import io.vertx.sqlclient.impl.TransactionPropagationLocal; -import io.vertx.sqlclient.impl.pool.SqlConnectionPool; -import io.vertx.sqlclient.internal.Connection; +import io.vertx.sqlclient.spi.connection.Connection; import io.vertx.sqlclient.internal.SqlClientBase; import io.vertx.sqlclient.internal.SqlConnectionInternal; -import io.vertx.sqlclient.internal.command.CommandBase; +import io.vertx.sqlclient.spi.connection.ConnectionContext; +import io.vertx.sqlclient.spi.protocol.CommandBase; +import io.vertx.sqlclient.spi.connection.ConnectionFactory; import io.vertx.sqlclient.spi.Driver; import java.util.function.Function; +import java.util.function.Supplier; import static java.util.concurrent.TimeUnit.MILLISECONDS; @@ -53,16 +55,19 @@ public class PoolImpl extends SqlClientBase implements Pool, Closeable { private final long cleanerPeriod; private final boolean pipelined; private final Handler connectionInitializer; + private final ConnectionWrapper connectionWrapper; private long timerID; - public PoolImpl(VertxInternal vertx, + public PoolImpl(VertxInternal vertx, Driver driver, boolean pipelined, PoolOptions poolOptions, Function> afterAcquire, Function> beforeRecycle, - Function> connectionProvider, + ConnectionFactory connectionFactory, + Supplier> connectionProvider, Handler connectionInitializer, + ConnectionWrapper connectionWrapper, CloseFuture closeFuture) { super(driver); @@ -76,6 +81,7 @@ public PoolImpl(VertxInternal vertx, poolMetrics = null; } + this.connectionWrapper = connectionWrapper; this.idleTimeout = MILLISECONDS.convert(poolOptions.getIdleTimeout(), poolOptions.getIdleTimeoutUnit()); this.connectionTimeout = MILLISECONDS.convert(poolOptions.getConnectionTimeout(), poolOptions.getConnectionTimeoutUnit()); this.maxLifetime = MILLISECONDS.convert(poolOptions.getMaxLifetime(), poolOptions.getMaxLifetimeUnit()); @@ -83,7 +89,9 @@ public PoolImpl(VertxInternal vertx, this.timerID = -1L; this.pipelined = pipelined; this.vertx = vertx; - this.pool = new SqlConnectionPool(connectionProvider, poolMetrics, hook, afterAcquire, beforeRecycle, vertx, idleTimeout, maxLifetime, poolOptions.getMaxSize(), pipelined, poolOptions.getMaxWaitQueueSize(), poolOptions.getEventLoopSize()); + this.pool = new SqlConnectionPool(connectionProvider, connectionFactory, poolMetrics, hook, afterAcquire, + beforeRecycle, vertx, idleTimeout, maxLifetime, poolOptions.getMaxSize(), pipelined, + poolOptions.getMaxWaitQueueSize(), poolOptions.getEventLoopSize()); this.closeFuture = closeFuture; this.connectionInitializer = connectionInitializer; } @@ -91,8 +99,8 @@ public PoolImpl(VertxInternal vertx, private void initializeConnection(SqlConnectionPool.PooledConnection conn) { if (connectionInitializer != null) { ContextInternal current = vertx.getContext(); - SqlConnectionInternal wrapper = driver.wrapConnection(current, conn.factory(), conn); - conn.init((Connection.Holder) wrapper); + SqlConnectionInternal wrapper = connectionWrapper.wrap(current, conn.factory(), conn); + conn.init((ConnectionContext) wrapper); current.dispatch(wrapper, connectionInitializer); } } @@ -140,8 +148,8 @@ public Future getConnection() { Promise promise = current.promise(); acquire(current, connectionTimeout, promise); return promise.future().map(conn -> { - SqlConnectionInternal wrapper = driver.wrapConnection(current, conn.factory(), conn); - conn.init((Connection.Holder) wrapper); + SqlConnectionInternal wrapper = connectionWrapper.wrap(current, conn.factory(), conn); + conn.init((ConnectionContext) wrapper); return wrapper; }); } diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/pool/SqlConnectionPool.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/pool/SqlConnectionPool.java index b74c78732c..1f46c3c330 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/pool/SqlConnectionPool.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/pool/SqlConnectionPool.java @@ -23,17 +23,18 @@ import io.vertx.core.internal.pool.*; import io.vertx.core.internal.ContextInternal; import io.vertx.core.internal.VertxInternal; -import io.vertx.sqlclient.SqlConnection; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.internal.SqlConnectionBase; -import io.vertx.sqlclient.internal.command.CommandBase; -import io.vertx.sqlclient.internal.command.QueryCommandBase; +import io.vertx.sqlclient.SqlConnectOptions; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.spi.connection.ConnectionContext; +import io.vertx.sqlclient.spi.protocol.CommandBase; +import io.vertx.sqlclient.spi.protocol.QueryCommandBase; import io.vertx.sqlclient.impl.tracing.QueryReporter; -import io.vertx.sqlclient.spi.ConnectionFactory; +import io.vertx.sqlclient.spi.connection.ConnectionFactory; import io.vertx.sqlclient.spi.DatabaseMetadata; import java.util.List; import java.util.function.Function; +import java.util.function.Supplier; import java.util.stream.Collectors; /** @@ -47,7 +48,8 @@ public class SqlConnectionPool { private static final Object NO_METRICS = new Object(); - private final Function> connectionProvider; + private final Function> connectionProvider; + private final ConnectionFactory connectionFactory; private final VertxInternal vertx; private final PoolMetrics metrics; private final ConnectionPool pool; @@ -59,7 +61,9 @@ public class SqlConnectionPool { private final long maxLifetime; private final int maxSize; - public SqlConnectionPool(Function> connectionProvider, + // TODO : use connection provider with Connection instead of SqlConnection + public SqlConnectionPool(Supplier> optionsProvider, + ConnectionFactory connectionFactory, PoolMetrics metrics, Handler hook, Function> afterAcquire, @@ -78,6 +82,7 @@ public SqlConnectionPool(Function> connectionProv throw new IllegalArgumentException("afterAcquire and beforeRecycle hooks must be both not null"); } this.pool = ConnectionPool.pool(connector, new int[]{maxSize}, maxWaitQueueSize); + this.connectionFactory = connectionFactory; this.metrics = metrics; this.vertx = vertx; this.pipelined = pipelined; @@ -85,7 +90,7 @@ public SqlConnectionPool(Function> connectionProv this.maxLifetime = maxLifetime; this.maxSize = maxSize; this.hook = hook; - this.connectionProvider = connectionProvider; + this.connectionProvider = context -> connectionFactory.connect(context, optionsProvider.get()); this.afterAcquire = afterAcquire; this.beforeRecycle = beforeRecycle; @@ -114,12 +119,10 @@ public ContextInternal apply(ContextInternal contextInternal) { private final PoolConnector connector = new PoolConnector<>() { @Override public Future> connect(ContextInternal context, Listener listener) { - Future future = connectionProvider.apply(context); - return future.compose(res -> { - SqlConnectionBase connBase = (SqlConnectionBase) res; - Connection conn = connBase.unwrap(); + Future future = connectionProvider.apply(context); + return future.compose(conn -> { if (conn.isValid()) { - PooledConnection pooled = new PooledConnection(connBase.factory(), conn, listener); + PooledConnection pooled = new PooledConnection(connectionFactory, conn, listener); conn.init(pooled); if (hook != null) { Promise> p = Promise.promise(); @@ -295,12 +298,12 @@ public Future close() { return promise.future(); } - public class PooledConnection implements Connection, Connection.Holder { + public class PooledConnection implements Connection, ConnectionContext { private final ConnectionFactory factory; private final Connection conn; private final PoolConnector.Listener listener; - private Holder holder; + private ConnectionContext holder; private Promise> poolCallback; private Lease lease; public long idleEvictionTimestamp; @@ -364,8 +367,8 @@ public int pipeliningLimit() { } @Override - public DatabaseMetadata getDatabaseMetaData() { - return conn.getDatabaseMetaData(); + public DatabaseMetadata databaseMetadata() { + return conn.databaseMetadata(); } @Override @@ -403,19 +406,19 @@ private void refresh() { } @Override - public void init(Holder holder) { + public void init(ConnectionContext context) { if (this.holder != null) { throw new IllegalStateException(); } - this.holder = holder; + this.holder = context; } @Override - public void close(Holder holder, Completable promise) { + public void close(ConnectionContext holder, Completable promise) { doClose(holder, promise); } - private void doClose(Holder holder, Completable promise) { + private void doClose(ConnectionContext holder, Completable promise) { if (holder != this.holder) { String msg; if (this.holder == null) { @@ -471,22 +474,12 @@ public void handleEvent(Object event) { } @Override - public void handleException(Throwable err) { + public void handleException(Throwable failure) { if (holder != null) { - holder.handleException(err); + holder.handleException(failure); } } - @Override - public int getProcessId() { - return conn.getProcessId(); - } - - @Override - public int getSecretKey() { - return conn.getSecretKey(); - } - @Override public Connection unwrap() { return conn; diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/tracing/QueryReporter.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/tracing/QueryReporter.java index 88ffe02c81..e47dbbd93a 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/tracing/QueryReporter.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/tracing/QueryReporter.java @@ -1,6 +1,5 @@ package io.vertx.sqlclient.impl.tracing; -import io.vertx.core.AsyncResult; import io.vertx.core.internal.ContextInternal; import io.vertx.core.spi.metrics.ClientMetrics; import io.vertx.core.spi.tracing.SpanKind; @@ -9,10 +8,10 @@ import io.vertx.core.tracing.TracingPolicy; import io.vertx.sqlclient.Tuple; import io.vertx.sqlclient.impl.QueryResultBuilder; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.internal.command.ExtendedQueryCommand; -import io.vertx.sqlclient.internal.command.QueryCommandBase; -import io.vertx.sqlclient.internal.command.SimpleQueryCommand; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.spi.protocol.ExtendedQueryCommand; +import io.vertx.sqlclient.spi.protocol.QueryCommandBase; +import io.vertx.sqlclient.spi.protocol.SimpleQueryCommand; import java.util.Collections; import java.util.List; diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/ArrayTuple.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/ArrayTuple.java index 49301095e7..7c7de12aff 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/ArrayTuple.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/ArrayTuple.java @@ -22,7 +22,7 @@ import java.util.Arrays; import java.util.Collection; -public class ArrayTuple extends TupleInternal { +public class ArrayTuple extends TupleBase { private static final Object[] EMPTY_ARRAY = new Object[0]; public static Tuple EMPTY = new ArrayTuple(0); diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/PreparedStatement.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/PreparedStatement.java index 55591917f6..aada5b1e65 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/PreparedStatement.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/PreparedStatement.java @@ -17,25 +17,21 @@ package io.vertx.sqlclient.internal; -import io.vertx.sqlclient.Tuple; - import java.util.ArrayList; import java.util.List; public interface PreparedStatement { - ParamDesc paramDesc(); - - RowDesc rowDesc(); + RowDescriptorBase rowDesc(); String sql(); - default List prepare(List batch) throws Exception { - List actual = batch; + default List prepare(List batch) throws Exception { + List actual = batch; int size = actual.size(); for (int idx = 0;idx < size;idx++) { - TupleInternal values = batch.get(idx); - TupleInternal prepared = prepare(values); + TupleBase values = batch.get(idx); + TupleBase prepared = prepare(values); if (prepared != values) { if (batch == actual) { actual = new ArrayList<>(actual); @@ -46,7 +42,7 @@ default List prepare(List batch) throws Exception return actual; } - default TupleInternal prepare(TupleInternal values) throws Exception { + default TupleBase prepare(TupleBase values) throws Exception { return values; } } diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/QueryResultHandler.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/QueryResultHandler.java index ddaae23475..ca83358579 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/QueryResultHandler.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/QueryResultHandler.java @@ -29,12 +29,12 @@ public interface QueryResultHandler { public void addProperty(PropertyKind property, V value) { } @Override - public void handleResult(int updatedCount, int size, RowDesc desc, Void result, Throwable failure) { + public void handleResult(int updatedCount, int size, RowDescriptorBase desc, Void result, Throwable failure) { } }; void addProperty(PropertyKind property, V value); - void handleResult(int updatedCount, int size, RowDesc desc, T result, Throwable failure); + void handleResult(int updatedCount, int size, RowDescriptorBase desc, T result, Throwable failure); } diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/RowDesc.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/RowDescriptorBase.java similarity index 88% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/RowDesc.java rename to vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/RowDescriptorBase.java index a71f3feee3..40e58a1c0a 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/RowDesc.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/RowDescriptorBase.java @@ -18,6 +18,7 @@ package io.vertx.sqlclient.internal; import io.vertx.sqlclient.desc.ColumnDescriptor; +import io.vertx.sqlclient.desc.RowDescriptor; import java.util.AbstractList; import java.util.List; @@ -26,12 +27,12 @@ /** * @author Emad Alblueshi */ -public abstract class RowDesc { +public class RowDescriptorBase implements RowDescriptor { private final ColumnNames columnNames; private final ColumnDescriptors columnDescriptors; - protected RowDesc(ColumnDescriptor[] columnDescriptors) { + public RowDescriptorBase(ColumnDescriptor[] columnDescriptors) { this.columnNames = new ColumnNames(columnDescriptors); this.columnDescriptors = new ColumnDescriptors(columnDescriptors); } @@ -47,7 +48,7 @@ public List columnNames() { return columnNames; } - public List columnDescriptor() { + public List columnDescriptors() { return columnDescriptors; } @@ -59,7 +60,8 @@ public String toString() { } private static class ColumnNames extends AbstractList implements RandomAccess { - final ColumnDescriptor[] elements; + + private final ColumnDescriptor[] elements; ColumnNames(ColumnDescriptor[] elements) { this.elements = elements; @@ -90,7 +92,8 @@ public int indexOf(Object o) { } private static class ColumnDescriptors extends AbstractList implements RandomAccess { - final ColumnDescriptor[] elements; + + private final ColumnDescriptor[] elements; ColumnDescriptors(ColumnDescriptor[] elements) { this.elements = elements; diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/SqlClientBase.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/SqlClientBase.java index b6af378717..89de20a2ae 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/SqlClientBase.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/SqlClientBase.java @@ -27,8 +27,8 @@ import io.vertx.sqlclient.impl.QueryExecutor; import io.vertx.sqlclient.impl.RowSetImpl; import io.vertx.sqlclient.impl.SqlClientInternal; -import io.vertx.sqlclient.internal.command.CommandBase; -import io.vertx.sqlclient.internal.command.CommandScheduler; +import io.vertx.sqlclient.spi.protocol.CommandBase; +import io.vertx.sqlclient.spi.protocol.CommandScheduler; import io.vertx.sqlclient.SqlResult; import io.vertx.sqlclient.RowSet; import io.vertx.sqlclient.Row; @@ -36,7 +36,7 @@ import io.vertx.sqlclient.Tuple; import io.vertx.core.Future; import io.vertx.core.Handler; -import io.vertx.sqlclient.internal.command.CompositeCommand; +import io.vertx.sqlclient.spi.protocol.CompositeCommand; import io.vertx.sqlclient.spi.Driver; import java.util.List; @@ -45,9 +45,9 @@ public abstract class SqlClientBase implements SqlClientInternal, CommandScheduler { - protected final Driver driver; + protected final Driver driver; - public SqlClientBase(Driver driver) { + public SqlClientBase(Driver driver) { this.driver = driver; } @@ -56,7 +56,7 @@ public SqlClientBase(Driver driver) { protected abstract PromiseInternal promise(); @Override - public Driver driver() { + public Driver driver() { return driver; } diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/SqlConnectionBase.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/SqlConnectionBase.java index cb8c798034..6a35f5269c 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/SqlConnectionBase.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/SqlConnectionBase.java @@ -28,19 +28,21 @@ import io.vertx.sqlclient.Transaction; import io.vertx.sqlclient.impl.PreparedStatementBase; import io.vertx.sqlclient.impl.TransactionImpl; -import io.vertx.sqlclient.internal.command.CommandBase; -import io.vertx.sqlclient.internal.command.PrepareStatementCommand; -import io.vertx.sqlclient.internal.command.QueryCommandBase; +import io.vertx.sqlclient.spi.connection.ConnectionContext; +import io.vertx.sqlclient.spi.protocol.CommandBase; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.spi.protocol.PrepareStatementCommand; +import io.vertx.sqlclient.spi.protocol.QueryCommandBase; import io.vertx.sqlclient.impl.pool.SqlConnectionPool; import io.vertx.sqlclient.impl.tracing.QueryReporter; -import io.vertx.sqlclient.spi.ConnectionFactory; +import io.vertx.sqlclient.spi.connection.ConnectionFactory; import io.vertx.sqlclient.spi.DatabaseMetadata; import io.vertx.sqlclient.spi.Driver; /** * @author Julien Viet */ -public class SqlConnectionBase> extends SqlClientBase implements SqlConnectionInternal, Closeable, Connection.Holder { +public class SqlConnectionBase> extends SqlClientBase implements SqlConnectionInternal, Closeable, ConnectionContext { private volatile Handler exceptionHandler; private volatile Handler closeHandler; @@ -138,12 +140,12 @@ public void schedule(CommandBase cmd, Completable handler) { } @Override - public void handleException(Throwable err) { + public void handleException(Throwable failure) { Handler handler = exceptionHandler; if (handler != null) { - context.emit(err, handler); + context.emit(failure, handler); } else { - err.printStackTrace(); + failure.printStackTrace(); } } @@ -154,7 +156,7 @@ public boolean isSSL() { @Override public DatabaseMetadata databaseMetadata() { - return conn.getDatabaseMetaData(); + return conn.databaseMetadata(); } @Override @@ -230,10 +232,13 @@ private void doClose(Completable promise) { protected static Future prepareForClose(ContextInternal ctx, Future future) { return future.andThen(ar -> { if (ar.succeeded()) { - SqlConnectionBase base = (SqlConnectionBase) ar.result(); - base.closeFactoryAfterUsage = true; - ctx.addCloseHook(base); + prepareForClose(ctx, (SqlConnectionBase) ar.result()); } }); } + + protected static void prepareForClose(ContextInternal ctx, SqlConnectionBase base) { + base.closeFactoryAfterUsage = true; + ctx.addCloseHook(base); + } } diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/SqlConnectionInternal.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/SqlConnectionInternal.java index bf2f1a7b49..7d6d48d23c 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/SqlConnectionInternal.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/SqlConnectionInternal.java @@ -11,6 +11,7 @@ package io.vertx.sqlclient.internal; import io.vertx.sqlclient.SqlConnection; +import io.vertx.sqlclient.spi.connection.Connection; public interface SqlConnectionInternal extends SqlConnection { diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/TupleInternal.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/TupleBase.java similarity index 95% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/TupleInternal.java rename to vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/TupleBase.java index 4d9120353f..476bf68b22 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/TupleInternal.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/TupleBase.java @@ -17,7 +17,7 @@ import java.util.ArrayList; import java.util.List; -public abstract class TupleInternal implements Tuple { +public abstract class TupleBase implements Tuple { public abstract void setValue(int pos, Object value); diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/CommandBase.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/CommandBase.java deleted file mode 100644 index c2688cff7a..0000000000 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/CommandBase.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2017 Julien Viet - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package io.vertx.sqlclient.internal.command; - -import io.vertx.core.AsyncResult; -import io.vertx.core.Completable; -import io.vertx.core.Future; -import io.vertx.core.Handler; - -/** - * @author Julien Viet - */ - -public abstract class CommandBase { - - public Completable handler; - - public final void fail(Throwable err) { - complete(Future.failedFuture(err)); - } - - public final void fail(String failureMsg) { - complete(Future.failedFuture(failureMsg)); - } - - public final void complete(AsyncResult resp) { - if (handler != null) { - handler.complete(resp.result(), resp.cause()); - } - } -} diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/Driver.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/Driver.java index 1e6fb98fbf..b01765f16b 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/Driver.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/Driver.java @@ -28,9 +28,6 @@ import io.vertx.sqlclient.PoolOptions; import io.vertx.sqlclient.SqlConnectOptions; import io.vertx.sqlclient.SqlConnection; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.internal.SqlConnectionBase; -import io.vertx.sqlclient.internal.SqlConnectionInternal; import java.util.function.Supplier; @@ -101,15 +98,6 @@ default Pool createPool(Vertx vertx, Supplier> databases, PoolOptions */ Pool newPool(Vertx vertx, Supplier> databases, PoolOptions options, NetClientOptions transportOptions, Handler connectHandler, CloseFuture closeFuture); - /** - * Create a connection factory to the given {@code database}. - * - * @param vertx the Vertx instance - * @param transportOptions the options to configure the TCP client - * @return the connection factory - */ - ConnectionFactory createConnectionFactory(Vertx vertx, NetClientOptions transportOptions); - /** * @return {@code true} if the driver accepts the {@code connectOptions}, {@code false} otherwise */ @@ -149,8 +137,4 @@ default int appendQueryPlaceholder(StringBuilder queryBuilder, int index, int cu queryBuilder.append("?"); return current; } - - default SqlConnectionInternal wrapConnection(ContextInternal context, ConnectionFactory factory, Connection conn) { - return new SqlConnectionBase<>(context, factory, conn, this); - } } diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/DriverBase.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/DriverBase.java new file mode 100644 index 0000000000..09ec1cb367 --- /dev/null +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/DriverBase.java @@ -0,0 +1,91 @@ +package io.vertx.sqlclient.spi; + +import io.vertx.core.Future; +import io.vertx.core.Handler; +import io.vertx.core.Vertx; +import io.vertx.core.internal.CloseFuture; +import io.vertx.core.internal.ContextInternal; +import io.vertx.core.internal.VertxInternal; +import io.vertx.core.net.NetClientOptions; +import io.vertx.sqlclient.Pool; +import io.vertx.sqlclient.PoolOptions; +import io.vertx.sqlclient.SqlConnectOptions; +import io.vertx.sqlclient.SqlConnection; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.impl.pool.CloseablePool; +import io.vertx.sqlclient.impl.pool.PoolImpl; +import io.vertx.sqlclient.internal.SqlConnectionBase; +import io.vertx.sqlclient.internal.SqlConnectionInternal; +import io.vertx.sqlclient.spi.connection.ConnectionFactory; + +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * A generic driver. + * @param + */ +public abstract class DriverBase implements Driver { + + private static final String SHARED_CLIENT_KEY_PREFIX = "__vertx.shared."; + + + private final String discriminant; + private final String sharedClientKey; + private final Function> afterAcquire; + private final Function> beforeRecycle; + + public DriverBase(String discriminant) { + this(discriminant, null, null); + } + + public DriverBase(String discriminant, Function> afterAcquire, Function> beforeRecycle) { + this.afterAcquire = afterAcquire; + this.beforeRecycle = beforeRecycle; + this.discriminant = discriminant; + this.sharedClientKey = SHARED_CLIENT_KEY_PREFIX + "." + discriminant; + } + + /** + * Create a connection factory to the given {@code database}. + * + * @param vertx the Vertx instance + * @param transportOptions the options to configure the TCP client + * @return the connection factory + */ + public abstract ConnectionFactory createConnectionFactory(Vertx vertx, NetClientOptions transportOptions); + + /** + * Wrap a given {@code connection} into a {@link SqlConnectionInternal}. The default implementation + * wraps with a generic {@link SqlConnectionBase}. + * + * @param context the connection context + * @param factory the connection factory + * @param connection the connection to wrap + * @return the wrapped connection + */ + public SqlConnectionInternal wrapConnection(ContextInternal context, ConnectionFactory factory, Connection connection) { + return new SqlConnectionBase<>(context, factory, connection, this); + } + + @Override + public Pool newPool(Vertx vertx, Supplier> databases, PoolOptions options, NetClientOptions transportOptions, Handler connectHandler, CloseFuture closeFuture) { + VertxInternal vx = (VertxInternal) vertx; + Pool pool; + if (options.isShared()) { + pool = vx.createSharedResource(sharedClientKey, options.getName(), closeFuture, cf -> newPool(vx, connectHandler, databases, options, transportOptions, cf)); + } else { + pool = newPool(vx, connectHandler, databases, options, transportOptions, closeFuture); + } + return new CloseablePool(vx, closeFuture, pool); + } + + protected Pool newPool(VertxInternal vertx, Handler connectHandler, Supplier> databases, PoolOptions poolOptions, NetClientOptions transportOptions, CloseFuture closeFuture) { + ConnectionFactory factory = createConnectionFactory(vertx, transportOptions); + PoolImpl pool = new PoolImpl(vertx, this, false, poolOptions, afterAcquire, beforeRecycle, + factory, databases, connectHandler, this::wrapConnection, closeFuture); + pool.init(); + closeFuture.add(factory); + return pool; + } +} diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/Connection.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/connection/Connection.java similarity index 54% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/Connection.java rename to vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/connection/Connection.java index 0983d3b5cd..254f7b67b8 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/Connection.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/connection/Connection.java @@ -15,20 +15,19 @@ * */ -package io.vertx.sqlclient.internal; +package io.vertx.sqlclient.spi.connection; import io.vertx.core.Completable; -import io.vertx.core.Promise; import io.vertx.core.net.SocketAddress; import io.vertx.core.spi.metrics.ClientMetrics; import io.vertx.core.tracing.TracingPolicy; -import io.vertx.sqlclient.internal.command.CommandScheduler; import io.vertx.sqlclient.spi.DatabaseMetadata; +import io.vertx.sqlclient.spi.protocol.CommandScheduler; /** - * A connection capable of scheduling command execution. + * A connection capable of scheduling commands. */ -public interface Connection extends CommandScheduler { +public interface Connection extends CommandScheduler { /** * @return {@code true} when {@code error} is an indeterminate data type reported when preparing a statement @@ -37,49 +36,70 @@ default boolean isIndeterminatePreparedStatementError(Throwable error) { return false; } + /** + * @return The connection tracing policy + */ TracingPolicy tracingPolicy(); + /** + * @return The connection client metrics + */ + ClientMetrics metrics(); + + /** + * @return the known server address + */ SocketAddress server(); + /** + * @return a database specific discriminant / identifier + */ default String system() { return "other_sql"; } + /** + * @return the database name + */ String database(); + /** + * @return the database user + */ String user(); - ClientMetrics metrics(); + /** + * Initialize the connection with the context for its usage. + * + * @param context the context + */ + void init(ConnectionContext context); - void init(Holder holder); + void close(ConnectionContext holder, Completable promise); + /** + * @return whether the underlying transport uses TLS + */ boolean isSsl(); + /** + * @return whether the connection is valid + */ boolean isValid(); - int pipeliningLimit(); - - DatabaseMetadata getDatabaseMetaData(); - - void close(Holder holder, Completable promise); - - int getProcessId(); - - int getSecretKey(); - /** - * The connection holder that handles connection interactions with the outer world, e.g. handling an event. + * @return the connection pipelining limit, that is how many queries can be scheduled on this connection + * @implNote returns {@literal 1}, the connection does not support pipelining */ - interface Holder { - - void handleEvent(Object event); - - void handleClosed(); - - void handleException(Throwable err); - + default int pipeliningLimit() { + return 1; } + /** + * @return the metadata + */ + DatabaseMetadata databaseMetadata(); + /** * @return the most unwrapped connection (e.g. for pooled connections) */ diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/connection/ConnectionContext.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/connection/ConnectionContext.java new file mode 100644 index 0000000000..0aa5cc4dd2 --- /dev/null +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/connection/ConnectionContext.java @@ -0,0 +1,29 @@ +package io.vertx.sqlclient.spi.connection; + +/** + *

The connection context that handles connection interactions with the outer world, e.g. handling an event.

+ * + *

The connection context allows a connection to signal inner changes to its context (the client state machine).

+ */ +public interface ConnectionContext { + + /** + * Signals a generic database event. + * + * @param event the event. + */ + void handleEvent(Object event); + + /** + * Signals the connection is closed. + */ + void handleClosed(); + + /** + * Signals a failure. + * + * @param failure the failure + */ + void handleException(Throwable failure); + +} diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/ConnectionFactory.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/connection/ConnectionFactory.java similarity index 80% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/ConnectionFactory.java rename to vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/connection/ConnectionFactory.java index 2ef4a63c2d..17442c0e51 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/ConnectionFactory.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/connection/ConnectionFactory.java @@ -1,4 +1,4 @@ -package io.vertx.sqlclient.spi; +package io.vertx.sqlclient.spi.connection; import io.vertx.core.Closeable; import io.vertx.core.Context; @@ -6,14 +6,14 @@ import io.vertx.core.*; import io.vertx.core.internal.ContextInternal; import io.vertx.sqlclient.SqlConnectOptions; -import io.vertx.sqlclient.SqlConnection; +import io.vertx.sqlclient.spi.Driver; /** * A connection factory, can be obtained from {@link Driver#createConnectionFactory} */ public interface ConnectionFactory extends Closeable { - default Future connect(Context context, Future fut) { + default Future connect(Context context, Future fut) { // The future might be on any context or context-less // So we need to use a specific context promise Promise promise = ((ContextInternal) context).promise(); @@ -30,6 +30,6 @@ default Future connect(Context context, Future fut) { * @param context the context * @return the future connection */ - Future connect(Context context, C options); + Future connect(Context context, C options); } diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/connection/package-info.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/connection/package-info.java new file mode 100644 index 0000000000..9a72604381 --- /dev/null +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/connection/package-info.java @@ -0,0 +1,18 @@ + +/* + * Copyright (c) 2011-2025 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 + */ + +/** + *

The Connection Service Provider Interface (SPI).

+ * + *

This SPI is the contract between a {@link io.vertx.sqlclient.spi.DriverBase} and a database backend.

+ */ +package io.vertx.sqlclient.spi.connection; diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/CloseConnectionCommand.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/CloseConnectionCommand.java similarity index 94% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/CloseConnectionCommand.java rename to vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/CloseConnectionCommand.java index 9cfa3606fe..0892ba0f4e 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/CloseConnectionCommand.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/CloseConnectionCommand.java @@ -15,7 +15,7 @@ * */ -package io.vertx.sqlclient.internal.command; +package io.vertx.sqlclient.spi.protocol; public class CloseConnectionCommand extends CommandBase { diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/CloseCursorCommand.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/CloseCursorCommand.java similarity index 96% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/CloseCursorCommand.java rename to vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/CloseCursorCommand.java index f1f2bdee7d..eb98b78dff 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/CloseCursorCommand.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/CloseCursorCommand.java @@ -15,7 +15,7 @@ * */ -package io.vertx.sqlclient.internal.command; +package io.vertx.sqlclient.spi.protocol; import io.vertx.sqlclient.internal.PreparedStatement; diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/CloseStatementCommand.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/CloseStatementCommand.java similarity index 95% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/CloseStatementCommand.java rename to vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/CloseStatementCommand.java index 03eb2bcfae..114bb3d074 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/CloseStatementCommand.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/CloseStatementCommand.java @@ -15,7 +15,7 @@ * */ -package io.vertx.sqlclient.internal.command; +package io.vertx.sqlclient.spi.protocol; import io.vertx.sqlclient.internal.PreparedStatement; diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/ParamDesc.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/CommandBase.java similarity index 80% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/ParamDesc.java rename to vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/CommandBase.java index ec6dd3793a..a5e1fd4b46 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/ParamDesc.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/CommandBase.java @@ -15,11 +15,11 @@ * */ -package io.vertx.sqlclient.internal; +package io.vertx.sqlclient.spi.protocol; /** - * @author Emad Alblueshi + * @author Julien Viet */ -public class ParamDesc { +public abstract class CommandBase { } diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/CommandScheduler.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/CommandScheduler.java similarity index 95% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/CommandScheduler.java rename to vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/CommandScheduler.java index 2d6e7a1f06..72b5c7af59 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/CommandScheduler.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/CommandScheduler.java @@ -14,7 +14,7 @@ * limitations under the License. * */ -package io.vertx.sqlclient.internal.command; +package io.vertx.sqlclient.spi.protocol; import io.vertx.core.Completable; import io.vertx.core.Future; diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/CompositeCommand.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/CompositeCommand.java similarity index 65% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/CompositeCommand.java rename to vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/CompositeCommand.java index ed28068a38..ae3ab91aec 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/CompositeCommand.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/CompositeCommand.java @@ -1,9 +1,6 @@ -package io.vertx.sqlclient.internal.command; +package io.vertx.sqlclient.spi.protocol; import io.vertx.core.Completable; -import io.vertx.core.Future; -import io.vertx.core.internal.ContextInternal; -import io.vertx.core.internal.PromiseInternal; import java.util.ArrayList; import java.util.List; @@ -11,13 +8,18 @@ public class CompositeCommand extends CommandBase { private final List> commands = new ArrayList<>(); + private final List> handlers = new ArrayList<>(); public void add(CommandBase cmd, Completable handler) { - cmd.handler = handler; commands.add(cmd); + handlers.add(handler); } public List> commands() { return commands; } + + public List> handlers() { + return handlers; + } } diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/ExtendedQueryCommand.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/ExtendedQueryCommand.java similarity index 82% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/ExtendedQueryCommand.java rename to vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/ExtendedQueryCommand.java index ba3956f95a..4baecbf8a4 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/ExtendedQueryCommand.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/ExtendedQueryCommand.java @@ -15,14 +15,14 @@ * */ -package io.vertx.sqlclient.internal.command; +package io.vertx.sqlclient.spi.protocol; import io.vertx.sqlclient.PrepareOptions; import io.vertx.sqlclient.Row; import io.vertx.sqlclient.Tuple; import io.vertx.sqlclient.internal.PreparedStatement; import io.vertx.sqlclient.internal.QueryResultHandler; -import io.vertx.sqlclient.internal.TupleInternal; +import io.vertx.sqlclient.internal.TupleBase; import java.util.List; import java.util.stream.Collector; @@ -68,19 +68,19 @@ public static ExtendedQueryCommand createBatch( return new ExtendedQueryCommand<>(sql, options, ps, true, tuples, 0, null, false, autoCommit, collector, resultHandler); } - protected final String sql; - protected final PrepareOptions options; - public PreparedStatement ps; - protected final boolean batch; + private final String sql; + private final PrepareOptions options; + private final PreparedStatement preparedStatement; + private final boolean batch; + private final int fetch; + private final String cursorId; + private final boolean suspended; private Object tuples; - protected final int fetch; - protected final String cursorId; - protected final boolean suspended; private boolean prepared; private ExtendedQueryCommand(String sql, PrepareOptions options, - PreparedStatement ps, + PreparedStatement preparedStatement, boolean batch, Object tuples, int fetch, @@ -92,13 +92,13 @@ private ExtendedQueryCommand(String sql, super(autoCommit, collector, resultHandler); this.sql = sql; this.options = options; - this.ps = ps; + this.preparedStatement = preparedStatement; this.batch = batch; this.tuples = tuples; this.fetch = fetch; this.cursorId = cursorId; this.suspended = suspended; - this.prepared = ps != null; + this.prepared = preparedStatement != null; } public PrepareOptions options() { @@ -110,15 +110,15 @@ public PrepareOptions options() { * * @return {@code null} if the tuple preparation was successfull otherwise the validation error */ - public String prepare() { + public String prepare(PreparedStatement ps) { if (ps != null && !prepared) { prepared = true; // TODO : fix this try { if (batch) { - tuples = ps.prepare((List) tuples); + tuples = ps.prepare((List) tuples); return null; } else { - tuples = ps.prepare((TupleInternal) tuples); + tuples = ps.prepare((TupleBase) tuples); } } catch (Exception e) { return e.getMessage(); @@ -134,8 +134,8 @@ public boolean isBatch() { /** * @return the list of parameters for batch execution */ - public List paramsList() { - return batch ? (List) tuples : null; + public List paramsList() { + return batch ? (List) tuples : null; } /** @@ -150,7 +150,7 @@ public List> parameterTypes() { } tuple = list.get(0); } else { - tuple = (TupleInternal) tuples; + tuple = (TupleBase) tuples; } return tuple.types(); } @@ -158,12 +158,12 @@ public List> parameterTypes() { /** * @return the parameters for query execution */ - public TupleInternal params() { - return batch ? null : (TupleInternal) tuples; + public TupleBase params() { + return batch ? null : (TupleBase) tuples; } public PreparedStatement preparedStatement() { - return ps; + return preparedStatement; } public int fetch() { diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/InitCommand.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/InitCommand.java similarity index 91% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/InitCommand.java rename to vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/InitCommand.java index 6f27d4bdd2..71b22bf93f 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/InitCommand.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/InitCommand.java @@ -15,10 +15,9 @@ * */ -package io.vertx.sqlclient.internal.command; +package io.vertx.sqlclient.spi.protocol; -import io.vertx.sqlclient.internal.Connection; -import io.vertx.sqlclient.impl.SocketConnectionBase; +import io.vertx.sqlclient.spi.connection.Connection; import java.util.Map; diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/PrepareStatementCommand.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/PrepareStatementCommand.java similarity index 97% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/PrepareStatementCommand.java rename to vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/PrepareStatementCommand.java index 0b2e8409ed..03faaebab8 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/PrepareStatementCommand.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/PrepareStatementCommand.java @@ -15,7 +15,7 @@ * */ -package io.vertx.sqlclient.internal.command; +package io.vertx.sqlclient.spi.protocol; import io.vertx.sqlclient.PrepareOptions; import io.vertx.sqlclient.internal.PreparedStatement; diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/QueryCommandBase.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/QueryCommandBase.java similarity index 86% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/QueryCommandBase.java rename to vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/QueryCommandBase.java index 90b3604ae8..9a02e47584 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/QueryCommandBase.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/QueryCommandBase.java @@ -15,12 +15,11 @@ * */ -package io.vertx.sqlclient.internal.command; +package io.vertx.sqlclient.spi.protocol; import io.vertx.sqlclient.Row; import io.vertx.sqlclient.internal.QueryResultHandler; -import java.util.function.Function; import java.util.stream.Collector; /** @@ -29,8 +28,6 @@ public abstract class QueryCommandBase extends CommandBase { - public static final Collector NULL_COLLECTOR = Collector.of(() -> null, (v,row) -> {}, (v1, v2) -> null, Function.identity()); - private final QueryResultHandler resultHandler; private final Collector collector; private final boolean autoCommit; diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/SimpleQueryCommand.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/SimpleQueryCommand.java similarity index 96% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/SimpleQueryCommand.java rename to vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/SimpleQueryCommand.java index ff224fbb47..655a9a3d00 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/SimpleQueryCommand.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/SimpleQueryCommand.java @@ -15,7 +15,7 @@ * */ -package io.vertx.sqlclient.internal.command; +package io.vertx.sqlclient.spi.protocol; import io.vertx.sqlclient.Row; import io.vertx.sqlclient.internal.QueryResultHandler; diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/TxCommand.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/TxCommand.java similarity index 71% rename from vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/TxCommand.java rename to vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/TxCommand.java index d2afc75191..e3802058e7 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/internal/command/TxCommand.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/TxCommand.java @@ -9,7 +9,7 @@ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 */ -package io.vertx.sqlclient.internal.command; +package io.vertx.sqlclient.spi.protocol; public class TxCommand extends CommandBase { @@ -17,18 +17,30 @@ public enum Kind { BEGIN(), ROLLBACK(), COMMIT(); - public final String sql; + private final String sql; Kind() { this.sql = name(); } + + public String sql() { + return sql; + } } - public final R result; - public final Kind kind; + private final R result; + private final Kind kind; public TxCommand(Kind kind, R result) { this.kind = kind; this.result = result; } + + public R result() { + return result; + } + + public Kind kind() { + return kind; + } } diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/package-info.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/package-info.java new file mode 100644 index 0000000000..5d255d765e --- /dev/null +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/spi/protocol/package-info.java @@ -0,0 +1,19 @@ + +/* + * Copyright (c) 2011-2025 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 + */ + +/** + *

Defines the interaction protocol between the client and a database backend.

+ * + *

The client interacts with the backend with a set of commands modelling the interactions between a client + * and a database.

+ */ +package io.vertx.sqlclient.spi.protocol; diff --git a/vertx-sql-client/src/main/java/module-info.java b/vertx-sql-client/src/main/java/module-info.java index 34e6e23dcf..53f6bdd11c 100644 --- a/vertx-sql-client/src/main/java/module-info.java +++ b/vertx-sql-client/src/main/java/module-info.java @@ -1,6 +1,3 @@ -import io.vertx.core.spi.VertxServiceProvider; -import io.vertx.sqlclient.impl.TransactionPropagationLocal; - module io.vertx.sql.client { requires io.netty.common; @@ -26,8 +23,6 @@ // Expose enough for implementing a client back-end on top of this API (e.g. vertx-jdbc-client) exports io.vertx.sqlclient.internal; - exports io.vertx.sqlclient.internal.command; - exports io.vertx.sqlclient.internal.pool; // Expose impl to our own implementation, this actually would deserve to be in another module since it is not // related to the API or the internal API @@ -35,9 +30,9 @@ exports io.vertx.sqlclient.impl to io.vertx.tests.sql.client, io.vertx.tests.sql.client.pg, io.vertx.tests.sql.client.mysql, io.vertx.tests.sql.client.templates, io.vertx.sql.client.pg, io.vertx.sql.client.mysql, io.vertx.sql.client.mssql, io.vertx.sql.client.db2, io.vertx.sql.client.oracle, io.vertx.sql.client.templates; - exports io.vertx.sqlclient.impl.codec to io.vertx.sql.client.pg, io.vertx.tests.sql.client.pg, io.vertx.sql.client.mysql, io.vertx.sql.client.mssql, io.vertx.sql.client.db2; - exports io.vertx.sqlclient.impl.cache to io.vertx.tests.sql.client, io.vertx.sql.client.mysql, io.vertx.sql.client.mssql, io.vertx.sql.client.db2; exports io.vertx.sqlclient.impl.tracing to io.vertx.tests.sql.client; exports io.vertx.sqlclient.impl.pool; + exports io.vertx.sqlclient.spi.protocol; + exports io.vertx.sqlclient.spi.connection; } diff --git a/vertx-sql-client/src/test/java/io/vertx/tests/sqlclient/TestRowDesc.java b/vertx-sql-client/src/test/java/io/vertx/tests/sqlclient/TestRowDescriptor.java similarity index 80% rename from vertx-sql-client/src/test/java/io/vertx/tests/sqlclient/TestRowDesc.java rename to vertx-sql-client/src/test/java/io/vertx/tests/sqlclient/TestRowDescriptor.java index 693caf2124..04a881dc62 100644 --- a/vertx-sql-client/src/test/java/io/vertx/tests/sqlclient/TestRowDesc.java +++ b/vertx-sql-client/src/test/java/io/vertx/tests/sqlclient/TestRowDescriptor.java @@ -12,22 +12,22 @@ package io.vertx.tests.sqlclient; import io.vertx.sqlclient.desc.ColumnDescriptor; -import io.vertx.sqlclient.internal.RowDesc; +import io.vertx.sqlclient.internal.RowDescriptorBase; import java.sql.JDBCType; -public class TestRowDesc extends RowDesc { +public class TestRowDescriptor extends RowDescriptorBase { - private TestRowDesc(TestColumnDescriptor[] columnDescriptors) { + private TestRowDescriptor(TestColumnDescriptor[] columnDescriptors) { super(columnDescriptors); } - public static TestRowDesc create(String... names) { + public static TestRowDescriptor create(String... names) { TestColumnDescriptor[] columnDescriptors = new TestColumnDescriptor[names.length]; for (int i = 0; i < names.length; i++) { columnDescriptors[i] = new TestColumnDescriptor(names[i]); } - return new TestRowDesc(columnDescriptors); + return new TestRowDescriptor(columnDescriptors); } public static class TestColumnDescriptor implements ColumnDescriptor { diff --git a/vertx-sql-client/src/test/java/io/vertx/tests/sqlclient/spi/backend/DriverBaseTest.java b/vertx-sql-client/src/test/java/io/vertx/tests/sqlclient/spi/backend/DriverBaseTest.java new file mode 100644 index 0000000000..efa65d8364 --- /dev/null +++ b/vertx-sql-client/src/test/java/io/vertx/tests/sqlclient/spi/backend/DriverBaseTest.java @@ -0,0 +1,180 @@ +package io.vertx.tests.sqlclient.spi.backend; + +import io.vertx.core.Completable; +import io.vertx.core.Context; +import io.vertx.core.Future; +import io.vertx.core.Vertx; +import io.vertx.core.net.NetClientOptions; +import io.vertx.core.net.SocketAddress; +import io.vertx.core.spi.metrics.ClientMetrics; +import io.vertx.core.tracing.TracingPolicy; +import io.vertx.sqlclient.Pool; +import io.vertx.sqlclient.PoolOptions; +import io.vertx.sqlclient.Row; +import io.vertx.sqlclient.RowIterator; +import io.vertx.sqlclient.RowSet; +import io.vertx.sqlclient.SqlConnectOptions; +import io.vertx.sqlclient.desc.ColumnDescriptor; +import io.vertx.sqlclient.impl.RowBase; +import io.vertx.sqlclient.spi.connection.Connection; +import io.vertx.sqlclient.internal.QueryResultHandler; +import io.vertx.sqlclient.internal.RowDescriptorBase; +import io.vertx.sqlclient.spi.connection.ConnectionContext; +import io.vertx.sqlclient.spi.protocol.CommandBase; +import io.vertx.sqlclient.spi.protocol.SimpleQueryCommand; +import io.vertx.sqlclient.spi.connection.ConnectionFactory; +import io.vertx.sqlclient.spi.DatabaseMetadata; +import io.vertx.sqlclient.spi.DriverBase; +import org.junit.Test; + +import java.sql.JDBCType; +import java.util.function.BiConsumer; +import java.util.stream.Collector; + +import static org.junit.Assert.*; + +public class DriverBaseTest { + + private static class VarcharColumnDescriptor implements ColumnDescriptor { + + private final String name; + + public VarcharColumnDescriptor(String name) { + this.name = name; + } + + @Override + public String name() { + return name; + } + @Override + public boolean isArray() { + return false; + } + @Override + public String typeName() { + return "VARCHAR"; + } + @Override + public JDBCType jdbcType() { + return JDBCType.VARCHAR; + } + } + + @Test + public void testSimple() { + + DriverBase driver = new DriverBase("generic") { + @Override + public ConnectionFactory createConnectionFactory(Vertx vertx, NetClientOptions transportOptions) { + return new ConnectionFactory<>() { + @Override + public Future connect(Context context, SqlConnectOptions options) { + return Future.succeededFuture(new Connection() { + @Override + public TracingPolicy tracingPolicy() { + return null; + } + @Override + public SocketAddress server() { + return null; + } + @Override + public String database() { + return ""; + } + @Override + public String user() { + return ""; + } + @Override + public ClientMetrics metrics() { + return null; + } + @Override + public void init(ConnectionContext context) { + } + @Override + public boolean isSsl() { + return false; + } + @Override + public boolean isValid() { + return true; + } + @Override + public int pipeliningLimit() { + return 1; + } + @Override + public DatabaseMetadata databaseMetadata() { + throw new UnsupportedOperationException(); + } + @Override + public void close(ConnectionContext holder, Completable promise) { + promise.succeed(); + } + @Override + public void schedule(CommandBase cmd, Completable handler) { + if (cmd instanceof SimpleQueryCommand) { + SimpleQueryCommand simpleQueryCmd = (SimpleQueryCommand) cmd; + scheduleQueryCommand(simpleQueryCmd, (Completable) handler); + } else { + handler.fail(new UnsupportedOperationException()); + } + } + private void scheduleQueryCommand(SimpleQueryCommand simpleQuery, Completable handler) { + QueryResultHandler qrh = simpleQuery.resultHandler(); + Collector collector = (Collector) simpleQuery.collector(); + A container = collector.supplier().get(); + BiConsumer accumulator = collector.accumulator(); + RowDescriptorBase rowDescriptor = new RowDescriptorBase(new ColumnDescriptor[]{new VarcharColumnDescriptor("value")}); + Row row = new RowBase(rowDescriptor); + row.addValue("Hello " + simpleQuery.sql()); + accumulator.accept(container, row); + T result = collector.finisher().apply(container); + qrh.handleResult(0, 1, rowDescriptor + , result, null); + handler.succeed(true); + } + }); + } + @Override + public void close(Completable completable) { + completable.succeed(); + } + }; + } + @Override + public SqlConnectOptions parseConnectionUri(String uri) { + throw new UnsupportedOperationException(); + } + @Override + public boolean acceptsOptions(SqlConnectOptions connectOptions) { + return true; + } + @Override + public SqlConnectOptions downcast(SqlConnectOptions connectOptions) { + return connectOptions; + } + }; + + Vertx vertx = Vertx.vertx(); + + try { + Pool pool = driver.createPool(vertx, () -> Future.succeededFuture(new SqlConnectOptions()), new PoolOptions(), new NetClientOptions(), null); + + Future> res = pool.withConnection(conn -> conn.query("Julien").execute()); + + RowSet rowset = res.await(); + RowIterator iterator = rowset.iterator(); + assertTrue(iterator.hasNext()); + Row row = iterator.next(); + assertEquals(1, row.size()); + assertEquals("Hello Julien", row.getString(0)); + assertFalse(iterator.hasNext()); + } finally { + vertx.close().await(); + } + } +} diff --git a/vertx-sql-client/src/test/java/io/vertx/tests/sqlclient/tck/ConnectionTestBase.java b/vertx-sql-client/src/test/java/io/vertx/tests/sqlclient/tck/ConnectionTestBase.java index 2f36423d03..bd23fa4fca 100644 --- a/vertx-sql-client/src/test/java/io/vertx/tests/sqlclient/tck/ConnectionTestBase.java +++ b/vertx-sql-client/src/test/java/io/vertx/tests/sqlclient/tck/ConnectionTestBase.java @@ -17,7 +17,7 @@ import io.vertx.sqlclient.SqlConnectOptions; import io.vertx.sqlclient.SqlConnection; import io.vertx.sqlclient.internal.SqlConnectionBase; -import io.vertx.sqlclient.spi.ConnectionFactory; +import io.vertx.sqlclient.spi.connection.ConnectionFactory; import io.vertx.sqlclient.spi.DatabaseMetadata; import org.junit.After; import org.junit.Before;