Search code examples
r2dbc

Why pass the RowMetadata argument as an additional parameter?


I am writing an R2DBC implementation for YDB.

Interface Result has a map method where two parameters are expected BiFunction(Row, RowMetadata), but why pass RowMetadata here if there is a getMetadata() method for the Row interface.


Solution

  • There's a bit of history attached. R2DBC SPI started with Result.map(BiFunction<Row, RowMetadata>) in its very first release to decouple Row from its metadata.

    As the specification evolved, we eventually added further methods and evolved the readable targets to Stored Procedures, which are OutParameters with their own metadata type. Both OutParameters and Row now are subtypes of Readable and the preferred way to consume results is by using Result.map(Function<Readable>).

    After adding metadata to Row and OutParameters, we didn't want to break existing client implementations because the value of breaking clients (by removing the method accepting BiFunction) would not outweigh by any means the benefit.

    You could well argue that there is a bit of redundancy and you're right. map(BiFunction) represents Result.filter(instanceof Row).flatMap(it -> Mono.just(mapper.apply(row, row.getMetadata()) and Result.map(Function) equals to Result.filter(instanceof Readable).flatMap(it -> mapper.apply(it). However, we found for the different styles of consuming Results, that these methods make quite some sense.