Skip to content

Conversation

@Michael-A-McMahon
Copy link
Member

Changes in this branch update Oracle R2DBC to the 0.9.0.M1 SPI. The SPI update adds support for PL/SQL calls, io.r2dbc.spi.Parameter binds, and io.r2dbc.spi.TransactionDefinition. To signify this new functionality, the Oracle R2DBC's minor version number is updated to 0.2.0 in the pom.xml and README.md.

I'll apologize in advance for the excessive volume of changes in this pull request. In hindsight, these changes should have been delivered over a number of smaller pull requests. During development, I repeatedly misjudged the amount of changes needed to support PL/SQL, and this big change set is the result of that. I'll attempt to summarize the most notable changes in the paragraphs that follow.

OracleConnectionImpl supports beginTransaction(TransactionDefinition) by translating the TransactionDefinition into a SET TRANSACTION command and executing it as a Statement.

A new class is introduced to declare instances of io.r2dbc.spi.Type for SQL types that are specific to Oracle Database. This new class is OracleR2dbcTypes. This class is public and exported to other modules so that programmers can reference the Oracle specific types when creating instances of io.r2dbc.spi.Parameter.

OracleStatementImpl now supports procedural calls having out parameters and/or returned cursors. When an instance of Parameter.Out is passed to a bind method, the statement is executed by creating a CallableStatement with Oracle JDBC, and invoking CallableStatement.registerOutParameter(int, SQLType). Out parameter values are returned as a single Row emitted by Result.map(BiFunction). Returned cursors are detected by invoking PreparedStatement.getMoreResults(). Each time getMoreResults() returns true, a Result for the returned cursor is emitted which emits the rows of that cursor with Result.map(BiFunction).

With Statement.execute() now capable of emitting multiple Results for multiple cursors, it must ensure that cursors are not consumed in parallel since Oracle R2DBC does not support parallel database calls. A similar problem had previously surfaced with OracleBatchImpl also emitting multiple Results that would fetch from multiple cursors. The solution to both problems is now unified with OracleResultImpl implementing a onConsumed method. The onConsumed method returns a Publisher that emits onComplete when the Result is consumed. The onConsumed Publisher is used by the execute() method of OracleStatementImpl and OracleBatchImpl to emit multiple Results serially with the consumption of the previous result.

OracleStatementImpl is heavily refactored. There was perviously one method that executed the statement for batches, non-batches, and DML returning generated values. With PL/SQL introducing a fourth execution type, it seemed better have distinct methods for each execution type rather than have one method that would do four different things. Additional refactoring makes use of Project Reactor's usingWhen operator as much as possible. This operator is designed for allocating and dealloacting resources, such as JDBC PreparedStatement, Blob or Clob objects.

OracleColumnMetadataImpl's fromJdbc factory method is refactored. Originally this was done to support mapping either ResultSetMetaData or ParameterMetaData JDBC types into R2DBC's ColumnMetaDataType. It turned out that Oracle JDBC doesn't support ParameterMetaData for CallableStatements, so the factory method that would have mapped ParameterMetaData was removed. However, I left the refactored fromJdbc in because the code seemed more readable than what we had previously.

Copy link
Member

@jeandelavarene jeandelavarene left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes look fine.

@jeandelavarene jeandelavarene merged commit 662ceab into main Jun 10, 2021
@jeandelavarene jeandelavarene deleted the 18-spi-0-9-0-update branch June 10, 2021 14:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Can't use Statement.returnGeneratedValues() with INSERT .. SELECT

2 participants