Skip to content

Commit

Permalink
Merge pull request #28 from oracle/18-spi-0-9-0-update
Browse files Browse the repository at this point in the history
18 spi 0 9 0 update
  • Loading branch information
jeandelavarene authored Jun 10, 2021
2 parents 527b7e1 + e0426a9 commit 662ceab
Show file tree
Hide file tree
Showing 32 changed files with 4,108 additions and 1,936 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/target/
.DS_Store
*.iml
/src/test/resources/config.properties
/sample/.gradle/
/sample/build/
Expand Down
60 changes: 54 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,37 @@ The Oracle R2DBC Driver is a Java library that supports reactive programming wit

Oracle R2DBC implements the R2DBC Service Provider Interface (SPI) as specified by the Reactive Relational Database Connectivity (R2DBC) project. The R2DBC SPI exposes Reactive Streams as an abstraction for remote database operations. Reactive Streams is a well defined standard for asynchronous, non-blocking, and back-pressured communication. This standard allows an R2DBC driver to interoperate with other reactive libraries and frameworks, such as Spring, Project Reactor, RxJava, and Akka Streams.

Oracle R2DBC 0.1.0 is the initial release of this driver. Release numbers follow the [Semantic Versioning](https://semver.org) specification. As indicated by the major version number of 0, this is a development release in which the behavior implemented for any API may change.

### Learn More About R2DBC:
[R2DBC Project Home Page](https://r2dbc.io)

[R2DBC Javadocs v0.8.2](https://r2dbc.io/spec/0.8.2.RELEASE/api/)
[R2DBC Javadocs v0.9.0.M1](https://r2dbc.io/spec/0.9.0.M1/api/)

[R2DBC Specification v0.8.2](https://r2dbc.io/spec/0.8.2.RELEASE/spec/html/)
[R2DBC Specification v0.9.0.M1](https://r2dbc.io/spec/0.9.0.M1/spec/html/)

### Learn More About Reactive Streams:
[Reactive Streams Project Home Page](http://www.reactive-streams.org)

[Reactive Streams Javadocs v1.0.3](http://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/org/reactivestreams/package-summary.html)

[Reactive Streams Specification v1.0.3](https://github.com/reactive-streams/reactive-streams-jvm/blob/v1.0.3/README.md)
# About This Version
Oracle R2DBC 0.2.0 updates the implemented SPI version to 0.9.0.M1. With the
0.9.0.M1 SPI update, Oracle R2DBC 0.2.0 introduces support for procedural
calls (PL/SQL), the ```Statement.bind(...)``` methods are enhanced to accept
```io.r2dbc.spi.Parameter``` objects, and the
```Connection.beginTransaction(TransactionDefintion)``` method is
implemented to support named and read-only/read-write transactions.

# Performance Goals
The primary goal of these early releases of Oracle R2DBC is to support the R2DBC
SPI on Oracle Database. The only performance goal is to enable concurrent
database calls to be executed by a single thread.

The R2DBC SPI and Oracle's implementation are both pre-production. As these
projects mature we will shift our development focus from implementing
the SPI to optimizing the implementation.


# Installation
Oracle R2DBC can be built from source using Maven:
Expand All @@ -37,7 +53,7 @@ Artifacts can also be found on Maven Central.
```

Oracle R2DBC is compatible with JDK 11 (or newer), and has the following runtime dependencies:
- R2DBC SPI 0.8.2
- R2DBC SPI 0.9.0.M1
- Reactive Streams 1.0.3
- Project Reactor 3.0.0
- Oracle JDBC 21.1.0.0 for JDK 11 (ojdbc11.jar)
Expand Down Expand Up @@ -112,8 +128,8 @@ This document specifies the behavior of the R2DBC SPI implemented for the
Oracle Database. This SPI implementation is referred to as the "Oracle R2DBC
Driver" or "Oracle R2DBC" throughout the remainder of this document.

The Oracle R2DBC Driver implements behavior specified by the R2DBC 0.8.2
[Specification](https://r2dbc.io/spec/0.8.2.RELEASE/spec/html/)
The Oracle R2DBC Driver implements behavior specified by the R2DBC 0.9.0.M1
[Specification](https://r2dbc.io/spec/0.9.0.M1/spec/html/)
and [Javadoc](https://r2dbc.io/spec/0.8.3.RELEASE/api/)

Publisher objects created by Oracle R2DBC implement behavior specified by
Expand Down Expand Up @@ -190,6 +206,8 @@ or Oracle JDBC Driver error message](https://docs.oracle.com/en/database/oracle/
- READ COMMITTED is the default transaction isolation level, and is the
only level supported in this release.
- Transaction savepoints are not supported in this release.
- TransactionDefinition.LOCK_WAIT_TIMEOUT is not supported in this release.
- Oracle Database does not support a lock wait timeout that applies to all statements within a transaction.

### Statements
- Batch execution is only supported for DML type SQL commands (INSERT/UPDATE/DELETE).
Expand Down Expand Up @@ -220,6 +238,36 @@ values for a non-empty set of column names.
- INSERT: https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/INSERT.html#GUID-903F8043-0254-4EE9-ACC1-CB8AC0AF3423
- UPDATE: https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/UPDATE.html#GUID-027A462D-379D-4E35-8611-410F3AC8FDA5

### Procedural Calls
- Use ```Connection.createStatement(String)``` to create a
```Statement``` that executes a PL/SQL call:
```java
connection.createStatement("BEGIN sayHello(:name_in, :greeting_out); END;")
```
- Register out parameters by invoking ```Statement.bind(int/String, Object)```
with an instance of ```io.r2dbc.spi.Parameter``` implementing the
```io.r2dbc.spi.Parameter.Out``` marker interface:
```java
statement.bind("greeting_out", Parameters.out(R2dbcType.VARCHAR))
```
- Register in out parameters by invoking
```Statement.bind(int/String, Object)``` with an instance of
```io.r2dbc.spi.Parameter``` implementing both the
```io.r2dbc.spi.Parameter.Out``` and
```io.r2dbc.spi.Parameter.In``` marker interfaces.
- Consume out parameters by invoking
```Result.map(BiFunction<Row, RowMetadata>)```:
```java
result.map((row,metadata) -> row.get("greeting_out", String.class))
```
- ```Statement.execute()``` returns a ```Publisher<Result>``` that emits one
```Result``` for each cursor returned by ```DBMS_SQL.RETURN_RESULT```
- The order in which a ```Result``` is emitted for a cursor
corresponds to the order in which the procedure returns each cursor.
- If a procedure returns cursors and also has out parameters, then the
```Result``` for out parameters is emitted last, after the
```Result``` for each returned cursor.

### Type Mappings
- Blob and Clob objects are the default mapping implemented by Row.get(...) for
BLOB and CLOB columns. ByteBuffer and String mappings are not supported for BLOB
Expand Down
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@

<groupId>com.oracle.database.r2dbc</groupId>
<artifactId>oracle-r2dbc</artifactId>
<version>0.1.0</version>
<version>0.2.0</version>
<name>oracle-r2dbc</name>
<description>
Oracle R2DBC Driver implementing version 0.8.2 of the R2DBC SPI for Oracle Database.
Oracle R2DBC Driver implementing version 0.9.0.M1 of the R2DBC SPI for Oracle Database.
</description>
<url>
https://github.com/oracle/oracle-r2dbc
Expand Down Expand Up @@ -66,7 +66,7 @@
<properties>
<java.version>11</java.version>
<ojdbc.version>21.1.0.0</ojdbc.version>
<r2dbc.version>0.8.2.RELEASE</r2dbc.version>
<r2dbc.version>0.9.0.M1</r2dbc.version>
<reactor.version>3.3.0.RELEASE</reactor.version>
<reactive-streams.version>1.0.3</reactive-streams.version>
<junit.version>5.7.0</junit.version>
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@
with oracle.r2dbc.impl.OracleConnectionFactoryProviderImpl;

requires java.sql;

requires ojdbc11;
requires org.reactivestreams;
requires reactor.core;
requires r2dbc.spi;
requires transitive org.reactivestreams;
requires transitive r2dbc.spi;

exports oracle.r2dbc;
}
185 changes: 185 additions & 0 deletions src/main/java/oracle/r2dbc/OracleR2dbcTypes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
/*
Copyright (c) 2020, 2021, Oracle and/or its affiliates.
This software is dual-licensed to you under the Universal Permissive License
(UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License
2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
either license.
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
https://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 oracle.r2dbc;

import io.r2dbc.spi.Type;
import oracle.sql.json.OracleJsonObject;

import java.nio.ByteBuffer;
import java.sql.RowId;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.Period;

/**
* SQL types supported by Oracle Database that are not defined as standard types
* by {@link io.r2dbc.spi.R2dbcType}.
*/
public final class OracleR2dbcTypes {

private OracleR2dbcTypes() {}

/**
* A 64-bit, double-precision floating-point number data type.
*/
public static final Type BINARY_DOUBLE =
new TypeImpl(Double.class, "BINARY_DOUBLE");

/**
* A 32-bit, single-precision floating-point number data type.
*/
public static final Type BINARY_FLOAT =
new TypeImpl(Float.class, "BINARY_FLOAT");

/**
* A Binary Large Object (BLOB) as implemented by Oracle Database. The default
* Java type mapping is {@link io.r2dbc.spi.Blob} rather than
* {@link java.nio.ByteBuffer}, which is the mapping of the standard
* {@link io.r2dbc.spi.R2dbcType#BLOB}.
*/
public static final Type BLOB =
new TypeImpl(io.r2dbc.spi.Blob.class, "BLOB");

/**
* A Character Large Object (BLOB) as implemented by Oracle Database. The
* default Java type mapping is {@link io.r2dbc.spi.Clob} rather than
* {@link String}, which is the mapping of the standard
* {@link io.r2dbc.spi.R2dbcType#CLOB}.
*/
public static final Type CLOB =
new TypeImpl(io.r2dbc.spi.Clob.class, "CLOB");

/**
* Stores a period of time in days, hours, minutes, and seconds.
*/
public static final Type INTERVAL_DAY_TO_SECOND =
new TypeImpl(Duration.class, "INTERVAL DAY TO SECOND");

/**
* Stores a period of time in years and months.
*/
public static final Type INTERVAL_YEAR_TO_MONTH =
new TypeImpl(Period.class, "INTERVAL YEAR TO MONTH");

public static final Type JSON =
new TypeImpl(OracleJsonObject.class, "JSON");

/**
* Character data of variable length up to 2 gigabytes.
*/
public static final Type LONG =
new TypeImpl(String.class, "LONG");

/**
* Raw binary data of variable length up to 2 gigabytes.
*/
public static final Type LONG_RAW =
new TypeImpl(ByteBuffer.class, "LONG RAW");

/**
* A National Character Large Object (NCLOB) as implemented by Oracle
* Database. The default Java type mapping is {@link io.r2dbc.spi.Clob}
* rather than {@link String}, which is the mapping of the standard
* {@link io.r2dbc.spi.R2dbcType#NCLOB}.
*/
public static final Type NCLOB =
new TypeImpl(io.r2dbc.spi.Clob.class, "NCLOB");

/**
* Base 64 string representing the unique address of a row in its table.
*/
public static final Type ROWID =
new TypeImpl(RowId.class, "ROWID");

/**
* Timestamp that is converted to the database's timezone when stored, and
* converted to the local timezone (the session timezone) when retrieved.
*/
public static final Type TIMESTAMP_WITH_LOCAL_TIME_ZONE =
new TypeImpl(LocalDateTime.class, "TIMESTAMP WITH LOCAL TIME ZONE");

/**
* Implementation of the {@link Type} SPI.
*/
private static final class TypeImpl implements Type {

/**
* The Java Language mapping of this SQL type.
*/
private final Class<?> javaType;

/**
* The name of this SQL type, as it would appear in a DDL expression.
*/
private final String sqlName;

/**
* Constructs a {@code Type} having a {@code javaType} mapping and
* {@code sqlName}.
* @param javaType Java type
* @param sqlName SQL type name
*/
TypeImpl(Class<?> javaType, String sqlName) {
this.javaType = javaType;
this.sqlName = sqlName;
}

/**
* {@inheritDoc}
* <p>
* Implements the R2DBC SPI method by returning the default Java type
* mapping for values of this SQL type. The Java type returned by this
* method is the type of {@code Object} returned by {@code Row.get
* (String/int)} when accessing a value of this SQL type.
* </p>
*/
@Override
public Class<?> getJavaType() {
return javaType;
}

/**
* {@inheritDoc}
* <p>
* Implements the R2DBC SPI method by returning the name of this SQL type.
* The name returned by this method is recognized in expressions of a SQL
* command, for instance: A column definition of a {@code CREATE TABLE}
* command.
* </p>
*
* @return
*/
@Override
public String getName() {
return sqlName;
}

/**
* Returns the name of this type.
* @return Type name
*/
@Override
public String toString() {
return getName();
}
}

}
Loading

0 comments on commit 662ceab

Please sign in to comment.