Skip to content

Commit

Permalink
Deprecate argument factories in favor of DocumentStorePlugin
Browse files Browse the repository at this point in the history
  • Loading branch information
hermannm committed Aug 30, 2024
1 parent 066e720 commit 0e42b1b
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 34 deletions.
57 changes: 34 additions & 23 deletions docs/v2-migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,29 +94,17 @@ fun main() { // Or wherever you set up your repositories
}
```

### 2. `VersionedEntity<EntityT>` renamed to `Versioned<EntityT>`, with new fields

This has been renamed, since `VersionedEntity<EntityT>` was redundant and led to long function
signatures. In addition, we now also include `createdAt` and `modifiedAt` fields on
`Versioned<EntityT>`, since they are always included in the database tables expected by Liflig
Document Store, but we just didn't expose them previously.

It should be sufficient to just replace `VersionedEntity<EntityT>` with `Versioned<EntityT>`, and
IntelliJ should suggest this as an automatic fix.

### 3. `EntityRoot` replaced by `Entity`

`EntityRoot` was a redundant abstraction on top of the `Entity` interface. You should replace
uses of `EntityRoot` with `Entity`, and `AbstractEntityRoot` with `AbstractEntity` (IntelliJ should
suggest this as an automatic fix). All non-deprecated APIs have been updated to work with `Entity`
instead of `EntityRoot`.

### 4. Argument type registration with `DocumentStorePlugin`
### 2. Argument type registration with `DocumentStorePlugin`

If you previously registered argument types from Liflig Document Store manually when setting up
JDBI, you should instead use the new `DocumentStorePlugin`. This makes it easier for us to migrate
JDBI, you must now instead use the new `DocumentStorePlugin`. This makes it easier for us to migrate
argument type registration in the future, and potentially add new argument types to
`DocumentStorePlugin` without all library consumers having to manually add them themselves.
`DocumentStorePlugin` without all library consumers having to manually add them themselves. For
example, `StringEntityId` was recently added to Document Store, but it requires registering the
`StringEntityIdArgumentFactory` to work - without this, queries will fail at runtime with reflection
errors. Since services so far have done manual argument type registration, most will not have this
argument type registered, and so may encounter runtime reflection errors if trying to use
`StringEntityId`. `DocumentStorePlugin` fixes this issue.

- Old argument type registration:

Expand All @@ -126,7 +114,7 @@ Jdbi.create(dataSource)
.registerArgument(UuidEntityIdArgumentFactory())
.registerArgument(UnmappedEntityIdArgumentFactory())
.registerArgument(VersionArgumentFactory())
.registerArrayType(UuidEntityId::class.java, "uuid")
.registerArrayType(EntityId::class.java, "uuid")
```

- New (using `DocumentStorePlugin`):
Expand All @@ -139,6 +127,23 @@ Jdbi.create(dataSource)
.installPlugin(DocumentStorePlugin())
```

### 3. `VersionedEntity<EntityT>` renamed to `Versioned<EntityT>`, with new fields

This has been renamed, since `VersionedEntity<EntityT>` was redundant and led to long function
signatures. In addition, we now also include `createdAt` and `modifiedAt` fields on
`Versioned<EntityT>`, since they are always included in the database tables expected by Liflig
Document Store, but we just didn't expose them previously.

It should be sufficient to just replace `VersionedEntity<EntityT>` with `Versioned<EntityT>`, and
IntelliJ should suggest this as an automatic fix.

### 4. `EntityRoot` replaced by `Entity`

`EntityRoot` was a redundant abstraction on top of the `Entity` interface. You should replace
uses of `EntityRoot` with `Entity`, and `AbstractEntityRoot` with `AbstractEntity` (IntelliJ should
suggest this as an automatic fix). All non-deprecated APIs have been updated to work with `Entity`
instead of `EntityRoot`.

### 5. Changed package locations and renames

As part of the change from `CrudDao`/`SearchDao` to `Repository`, we added a new package
Expand Down Expand Up @@ -193,6 +198,12 @@ removal in v2. If you depend on any of these, give a heads-up to the Liflig deve
- `no.liflig.documentstore.entity.createMapperPairForStringMapper`
- `no.liflig.documentstore.entity.UnmappedEntityId`
- `no.liflig.documentstore.entity.UnmappedEntityIdArgumentFactory`
- See point 4 above
- See point 2 above
- `no.liflig.documentstore.entity.UnmappedEntityIdArgumentFactory`
- See point 2 above
- `no.liflig.documentstore.entity.UnmappedEntityIdArgumentFactory`
- See point 2 above
- `no.liflig.documentstore.entity.UnmappedEntityIdArgumentFactory`
- See point 2 above
- `no.liflig.documentstore.registerLifligArgumentTypes`
- See point 4 above
- See point 2 above
45 changes: 36 additions & 9 deletions src/main/kotlin/no/liflig/documentstore/DocumentStorePlugin.kt
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
package no.liflig.documentstore

import java.sql.Types
import no.liflig.documentstore.entity.StringEntityId
import no.liflig.documentstore.entity.StringEntityIdArgumentFactory
import no.liflig.documentstore.entity.UuidEntityId
import no.liflig.documentstore.entity.UuidEntityIdArgumentFactory
import no.liflig.documentstore.entity.VersionArgumentFactory
import no.liflig.documentstore.entity.Version
import org.jdbi.v3.core.Jdbi
import org.jdbi.v3.core.argument.AbstractArgumentFactory
import org.jdbi.v3.core.argument.Argument
import org.jdbi.v3.core.config.ConfigRegistry
import org.jdbi.v3.core.spi.JdbiPlugin

/**
* JDBI plugin for registering all the argument types used by Liflig Document Store:
* - [UuidEntityIdArgumentFactory]
* - [StringEntityIdArgumentFactory]
* - [VersionArgumentFactory]
*
* Usage:
* JDBI plugin that registers all bind argument types used by Liflig Document Store. In order to use
* Document Store, you must install this when setting up your Jdbi instance:
* ```
* jdbi.installPlugin(DocumentStorePlugin())
* ```
*
* Once this plugin is installed, the following types can be used as JDBI bind arguments:
* - [UuidEntityId]
* - [StringEntityId]
* - [Version]
*/
class DocumentStorePlugin : JdbiPlugin.Singleton() {
override fun customizeJdbi(jdbi: Jdbi) {
Expand All @@ -30,6 +33,30 @@ class DocumentStorePlugin : JdbiPlugin.Singleton() {
}
}

/** JDBI argument factory that lets us use [UuidEntityId] as a bind argument. */
private class UuidEntityIdArgumentFactory : AbstractArgumentFactory<UuidEntityId>(Types.OTHER) {
override fun build(value: UuidEntityId, config: ConfigRegistry?): Argument =
Argument { position, statement, _ ->
statement.setObject(position, value.value)
}
}

/** JDBI argument factory that lets us use [StringEntityId] as a bind argument. */
private class StringEntityIdArgumentFactory : AbstractArgumentFactory<StringEntityId>(Types.OTHER) {
override fun build(value: StringEntityId, config: ConfigRegistry?): Argument =
Argument { position, statement, _ ->
statement.setString(position, value.value)
}
}

/** JDBI argument factory that lets us use [Version] as a bind argument. */
private class VersionArgumentFactory : AbstractArgumentFactory<Version>(Types.OTHER) {
override fun build(value: Version, config: ConfigRegistry?): Argument =
Argument { position, statement, _ ->
statement.setObject(position, value.value)
}
}

/**
* Utility function for registering all the JDBI argument factories needed by Liflig Document Store:
* - [UuidEntityIdArgumentFactory]
Expand Down
10 changes: 9 additions & 1 deletion src/main/kotlin/no/liflig/documentstore/entity/EntityId.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,22 @@ internal fun getEntityIdType(entityId: EntityId): Class<out EntityId> {
}

/** An argument factory for JDBI so that we can use a [UuidEntityId] as a bind argument. */
@Deprecated(
"This will be made internal in an upcoming version. Instead of calling jdbi.registerArgument() with argument factories manually, you should call jdbi.installPlugin(DocumentStorePlugin()) (no.liflig.documentstore.DocumentStorePlugin).",
level = DeprecationLevel.WARNING,
)
class UuidEntityIdArgumentFactory : AbstractArgumentFactory<UuidEntityId>(Types.OTHER) {
override fun build(value: UuidEntityId, config: ConfigRegistry?): Argument =
Argument { position, statement, _ ->
statement.setObject(position, value.value)
}
}

/** An argument factory for JDBI so that we can use a [UuidEntityId] as a bind argument. */
/** An argument factory for JDBI so that we can use a [StringEntityId] as a bind argument. */
@Deprecated(
"This will be made internal in an upcoming version. Instead of calling jdbi.registerArgument() with argument factories manually, you should call jdbi.installPlugin(DocumentStorePlugin()) (no.liflig.documentstore.DocumentStorePlugin).",
level = DeprecationLevel.WARNING,
)
class StringEntityIdArgumentFactory : AbstractArgumentFactory<StringEntityId>(Types.OTHER) {
override fun build(value: StringEntityId, config: ConfigRegistry?): Argument =
Argument { position, statement, _ ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ fun EntityId.toUnmapped(): UnmappedEntityId = UnmappedEntityId.fromString(toStri

/** An argument factory for JDBI so that we can use a [UnmappedEntityId] as a bind argument. */
@Deprecated(
"This is being removed along with UnmappedEntityId in a future version of Liflig Document Store, since we found no users of it.",
"This will be removed in an upcoming version. Instead of calling jdbi.registerArgument() with argument factories manually, you should call jdbi.installPlugin(DocumentStorePlugin()) (no.liflig.documentstore.DocumentStorePlugin).",
level = DeprecationLevel.WARNING,
)
class UnmappedEntityIdArgumentFactory : AbstractArgumentFactory<UnmappedEntityId>(Types.OTHER) {
Expand Down
4 changes: 4 additions & 0 deletions src/main/kotlin/no/liflig/documentstore/entity/Version.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ data class Versioned<out EntityT : Entity<*>>(
)
data class VersionedEntity<out EntityT : Entity<*>>(val item: EntityT, val version: Version)

@Deprecated(
"This will be made internal in an upcoming version. Instead of calling jdbi.registerArgument() with argument factories manually, you should call jdbi.installPlugin(DocumentStorePlugin()) (no.liflig.documentstore.DocumentStorePlugin).",
level = DeprecationLevel.WARNING,
)
/** An argument factory for JDBI so that we can use a [Version] as a bind argument. */
class VersionArgumentFactory : AbstractArgumentFactory<Version>(Types.OTHER) {
override fun build(value: Version, config: ConfigRegistry?): Argument =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ interface Repository<EntityIdT : EntityId, EntityT : Entity<EntityIdT>> {
* data jsonb NOT NULL
* );
* ```
*
* Also, the given [Jdbi] instance must have the
* [DocumentStorePlugin][no.liflig.documentstore.DocumentStorePlugin] installed for the queries in
* this class to work.
*/
open class RepositoryJdbi<EntityIdT : EntityId, EntityT : Entity<EntityIdT>>(
protected val jdbi: Jdbi,
Expand Down

0 comments on commit 0e42b1b

Please sign in to comment.