= Reactive DB2 Client
:PREPARED_PARAMS: `?`

The Reactive DB2 Client is a client for DB2 with a straightforward API focusing on
scalability and low overhead.

The client is reactive and non-blocking, allowing to handle many database connections with a single thread.

*Features*

* Support for DB2 on Linux, Unix, and Windows
* Limited support for DB2 on z/OS
* Event driven
* Lightweight
* Built-in connection pooling
* Prepared queries caching
* Batch and cursor
* Row streaming
* RxJava API
* Direct memory to object without unnecessary copies
* Java 8 Date and Time
* SSL/TLS
* HTTP/1.x CONNECT, SOCKS4a or SOCKS5 proxy support

*Current limitations*

* No stored procedures support
* Some column types (e.g. BLOB and CLOB) are not supported

== Usage

To use the Reactive DB2 Client add the following dependency to the _dependencies_ section of your build descriptor:

* Maven (in your `pom.xml`):

[source,xml]
----
<dependency>
  <groupId>${maven.groupId}</groupId>
  <artifactId>${maven.artifactId}</artifactId>
  <version>${maven.version}</version>
</dependency>
----
* Gradle (in your `build.gradle` file):

[source,groovy]
----
dependencies {
  compile '${maven.groupId}:${maven.artifactId}:${maven.version}'
}
----

== Getting started

Here is the simplest way to connect, query and disconnect

[source,$lang]
----
{@link examples.DB2ClientExamples#gettingStarted()}
----

== Connecting to DB2

Most of the time you will use a pool to connect to DB2:

[source,$lang]
----
{@link examples.DB2ClientExamples#connecting01}
----

The pooled client uses a connection pool and any operation will borrow a connection from the pool
to execute the operation and release it to the pool.

If you are running with Vert.x you can pass it your Vertx instance:

[source,$lang]
----
{@link examples.DB2ClientExamples#connecting02}
----

You need to release the client when you don't need it anymore:

[source,$lang]
----
{@link examples.DB2ClientExamples#connecting03}
----

When you need to execute several operations on the same connection, you need to acquire a
{@link io.vertx.db2client.DB2Connection connection} from a pool

You can easily get one from the pool:

[source,$lang]
----
{@link examples.DB2ClientExamples#connecting04}
----

Once you are done with the connection you must close it to release it to the pool, so it can be reused.

== Pool versus pooled client

The {@link io.vertx.db2client.DB2Pool} allows you to create a pool or a pooled client

[source,$lang]
----
{@link examples.DB2ClientExamples#poolVersusPooledClient}
----

- pool operations are not pipelined, only connections acquired from the pool are pipelined
- pooled client operations are pipelined, you cannot acquire a connection from a pooled client

== Pool sharing

include::pool_sharing.adoc[]

== Configuration

There are several alternatives for you to configure the client.

=== data object

A simple way to configure the client is to specify a `DB2ConnectOptions` data object.

[source,$lang]
----
{@link examples.DB2ClientExamples#configureFromDataObject(io.vertx.core.Vertx)}
----

You can also configure the generic properties with the `setProperties` or `addProperty` methods. Note `setProperties` will override the default client properties.

=== Connection URI

Apart from configuring with a `DB2ConnectOptions` data object, We also provide you an alternative way to connect when you want to configure with a connection URI:

[source,$lang]
----
{@link examples.DB2ClientExamples#configureFromUri(io.vertx.core.Vertx)}
----

The URI format for a connection string is:

----
db2://[user[:[password]]@]host[:port][/database][?<key1>=<value1>[&<key2>=<value2>]]
----

Currently, the client supports the following parameter keys:

* `host`
* `port`
* `user`
* `password`
* `database`

NOTE: Configuring parameters in connection URI will override the default properties.

== Connect retries

You can configure the client to retry when a connection fails to be established.

[source,$lang]
----
{@link examples.DB2ClientExamples#reconnectAttempts}
----

include::queries.adoc[leveloffset=1]

You can fetch generated keys by wrapping your query in `SELECT <COLUMNS> FROM FINAL TABLE ( <SQL> )`, for example:

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

include::connections.adoc[]

include::transactions.adoc[]

include::cursor.adoc[]

== Tracing queries

include::tracing.adoc[]

== DB2 type mapping

Currently the client supports the following DB2 types

* BOOLEAN (`java.lang.Boolean`) (DB2 LUW only)
* SMALLINT (`java.lang.Short`)
* INTEGER (`java.lang.Integer`)
* BIGINT (`java.lang.Long`)
* REAL (`java.lang.Float`)
* DOUBLE (`java.lang.Double`)
* DECIMAL (`io.vertx.sqlclient.data.Numeric`)
* CHAR (`java.lang.String`)
* VARCHAR (`java.lang.String`)
* ENUM (`java.lang.String`)
* DATE (`java.time.LocalDate`)
* TIME (`java.time.LocalTime`)
* TIMESTAMP (`java.time.LocalDateTime`)
* BINARY (`byte[]`)
* VARBINARY (`byte[]`)
* ROWID (`io.vertx.db2client.impl.drda.DB2RowId` or `java.sql.RowId`) (DB2 z/OS only)

Some types that are currently NOT supported are:

* XML
* BLOB
* CLOB
* DBCLOB
* GRAPHIC / VARGRAPHIC

For a further documentation on DB2 data types, see the following resources:

* https://www.ibm.com/support/knowledgecenter/SSEPGG_11.5.0/com.ibm.db2.luw.sql.ref.doc/doc/r0008483.html[DB2 for LUW 11.5 data types]
* https://www.ibm.com/support/knowledgecenter/SSEPEK_12.0.0/sqlref/src/tpc/db2z_datatypesintro.html[DB2 for z/OS 12.0 data types]

Tuple decoding uses the above types when storing values, it also performs on the fly conversion of the actual value when possible:

[source,$lang]
----
{@link examples.DB2ClientExamples#typeMapping01}
----

== Using Java enum types

You can map Java https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html[enum types] to these column
types:

- Strings (VARCHAR, TEXT)
- Numbers (SMALLINT, INTEGER, BIGINT)

[source,$lang]
----
{@link examples.DB2ClientExamples#enumStringValues}
{@link examples.DB2ClientExamples#enumIntValues}
----

The String type is matched with the Java enum's name returned by the `name()` method.

Number types are matched with the Java enum's ordinal returned by the `ordinal()` method and the row.get() method returns the corresponding enum's `name()` value at the ordinal position of the integer value retrieved.

== Collector queries

You can use Java collectors with the query API:

[source,$lang]
----
{@link examples.DB2ClientExamples#collector01Example}
----

The collector processing must not keep a reference on the {@link io.vertx.sqlclient.Row} as
there is a single row used for processing the entire set.

The Java `Collectors` provides many interesting predefined collectors, for example you can
create easily create a string directly from the row set:

[source,$lang]
----
{@link examples.DB2ClientExamples#collector02Example}
----

== Using SSL/TLS

To configure the client to use SSL connection, you can configure the {@link io.vertx.db2client.DB2ConnectOptions}
like a Vert.x `NetClient`.

[source,$lang]
----
{@link examples.DB2ClientExamples#connectSsl}
----

More information can be found in the http://vertx.io/docs/vertx-core/java/#ssl[Vert.x documentation].


== Using a proxy

You can also configure the client to use an HTTP/1.x CONNECT, SOCKS4a or SOCKS5 proxy.

More information can be found in the http://vertx.io/docs/vertx-core/java/#_using_a_proxy_for_client_connections[Vert.x documentation].

== Advanced pool configuration

include::pool_config.adoc[]

ifeval::["$lang" == "java"]
include::override/rxjava3.adoc[]
endif::[]
