Conversation
There was a problem hiding this comment.
Within this PR the main approach was in taking tests from jdbc's EntityTests and adopting them to r2dbc with implementing minimal functionality to cover these tests. Not so many tests are moved, but they cover many key features like relationships, entity cache, lifecycle interceptor and so on
There was a problem hiding this comment.
It's the main difference in relationships comparing to jdbc. It allows to make non-suspend set(), and suspend get() (via invoke())
SuspendAccessor - is in the code, but actually not used, but OptionalSuspendAccessor is present in the tests
There was a problem hiding this comment.
It was copied from jdbc dao for now
c6f3b4d to
da5a2fe
Compare
bog-walk
left a comment
There was a problem hiding this comment.
It's great how much can be successfully accomplished & its a promising step towards providing DAO + R2DBC support.
My main thought overall is the huge amount of duplication that enters into the public API. With DSL there was of course a lot duplicated, but a huge amount was also kept in the core, so the end API for new R2DBC users remained almost the same unless you were customizing classes. For Entity versus R2dbcEntity for example, it seems to so far only be refresh(), flush(), and lookup() that differs.
I thought that 1 of the possible goals of R2DBC + DAO was to redesign the jdbc-dao so that it could be used common to both approaches. In the same way that a Table and most DSL non-executables can be shared by both, I hoped it might be possible to use the same Entity across both. With the executable methods (like save, refresh, update etc) extracted to interface implementations. So that a project could use both drivers together, even temporarily as they migrate or test r2dbc in parts of code.
With this approach, they'd instead have to either change their existing entities (just 1 change is nice though) or copy-paste new entities that implement R2dbcEntity. In the end, it's not really a problem, I'm just surprised that it's not possible to share code given how much similarity this semi-final product has.
Would it not at all be possible to have an exposed-dao-core module that is depended on by both? I suppose it would technically be a breaking change even if change wasn't felt in final API, but I don't think that should be a deterrent from trying a POC like that.
There was a problem hiding this comment.
Another question: What is wrong/incompatible with the existing EntityTypeChange implementation that jdbc-dao uses?
There was a problem hiding this comment.
I hope to bring it in the next PR with subscribtions if it's ok, this PR was getting bigger and bigger already
e5l
left a comment
There was a problem hiding this comment.
the new api looks nice for the further implementation. Please check the package name
1e4ab80 to
55e0a07
Compare
55e0a07 to
f0e3044
Compare
Description
Summary of the change: Implements R2DBC DAO layer - a functional, suspending equivalent of Exposed's JDBC DAO API, enabling entity-based reactive database access with change tracking and relationships.
What:
R2dbcEntity,R2dbcEntityClassR2dbcEntityCacheandR2dbcEntityLifecycleInterceptorreferencedOnSuspend/optionalReferencedOnSuspend,referrersOnSuspend/optionalReferrersOnSuspend,backReferencedOnSuspend/optionalBackReferencedOnSuspendHow:
Architecture mirrors JDBC DAO but adapted for suspending operations:
val city = person.city(blocking property access)val city = person.city()(suspend function call via invoke operator)person.city set newCity(non suspend)Lifecycle interceptor (
GlobalSuspendStatementInterceptor) automatically flushes pending entity changes before queries, sorted by foreign key dependencies usingSchemaUtils.sortTablesByReferences()Key Differences from JDBC DAO:
suspendfunctionsinvoke():entity.relationship()Similarities with JDBC DAO:
by EntityClass referencedOnSuspend Column)Type of Change
Affected databases: