Skip to content

Commit ea4aad0

Browse files
committed
Move usage docs to README
1 parent 3ecf302 commit ea4aad0

File tree

2 files changed

+128
-125
lines changed

2 files changed

+128
-125
lines changed

README.md

Lines changed: 128 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,136 @@ for convenient database access.
1414

1515
This library is currently only distributed in Liflig internal repositories.
1616

17+
**Contents:**
18+
19+
- [Usage](#usage)
20+
- [Implementing `SerializationAdapter`](#implementing-serializationadapter)
21+
- [Contributing](#contributing)
22+
1723
## Usage
1824

19-
See [docs/usage.md](docs/usage.md).
25+
Liflig Document Store works on the assumption that all database tables look alike, using the `jsonb`
26+
column type from Postgres to store data. So you first have to create your table like this:
27+
28+
```sql
29+
CREATE TABLE example
30+
(
31+
-- Can have type `text` if using `StringEntityId`, or `bigint` if using `IntegerEntityId`
32+
id uuid NOT NULL PRIMARY KEY,
33+
created_at timestamptz NOT NULL,
34+
modified_at timestamptz NOT NULL,
35+
version bigint NOT NULL,
36+
data jsonb NOT NULL
37+
)
38+
```
39+
40+
Then, define an entity in your application. If you use `kotlinx-serialization`, the entity must be
41+
`@Serializable`.
42+
43+
```kotlin
44+
import kotlinx.serialization.Serializable
45+
import no.liflig.documentstore.entity.Entity
46+
import no.liflig.documentstore.entity.UuidEntityId
47+
48+
@Serializable
49+
data class ExampleEntity(
50+
override val id: ExampleId,
51+
val name: String,
52+
) : Entity<ExampleId>
53+
54+
@Serializable
55+
@JvmInline
56+
value class ExampleId(override val value: UUID) : UuidEntityId {
57+
override fun toString() = value.toString()
58+
}
59+
```
60+
61+
Next, implement a `Repository` for your entity. See below for the implementation of
62+
[`KotlinSerialization`](#implementing-serializationadapter).
63+
64+
```kotlin
65+
import no.liflig.documentstore.entity.Versioned
66+
import no.liflig.documentstore.repository.RepositoryJdbi
67+
import org.jdbi.v3.core.Jdbi
68+
69+
class ExampleRepository(jdbi: Jdbi) :
70+
RepositoryJdbi<ExampleId, ExampleEntity>(
71+
jdbi,
72+
tableName = "example",
73+
serializationAdapter = KotlinSerialization(ExampleEntity.serializer()),
74+
) {
75+
76+
fun getByName(name: String): Versioned<ExampleEntity>? {
77+
// To implement filtering on the entity's fields, we use the getByPredicate method inherited
78+
// from RepositoryJdbi. It lets us provide our own WHERE clause, and a lambda to bind arguments.
79+
// In the WHERE string, we use JSON operators from Postgres (->>) to query the entity's fields.
80+
return getByPredicate("data->>'name' = :name") {
81+
// Binds to the :name parameter in the query
82+
bind("name", name)
83+
}
84+
.firstOrNull()
85+
}
86+
}
87+
```
88+
89+
This inherits CRUD methods (`create`, `get`, `update` and `delete`) from `RepositoryJdbi`, so we can
90+
use it like this:
91+
92+
```kotlin
93+
val exampleRepo: ExampleRepository
94+
95+
val (entity, version) = exampleRepo.create(
96+
ExampleEntity(
97+
id = ExampleId(UUID.randomUUID()),
98+
name = "test",
99+
)
100+
)
101+
102+
println("Created entity with name '${entity.name}'")
103+
```
104+
105+
Finally, when setting up our `Jdbi` instance to connect to our database, we have to install the
106+
`DocumentStorePlugin` (this registers argument types that `RepositoryJdbi` depends on):
107+
108+
```kotlin
109+
import javax.sql.DataSource
110+
import org.jdbi.v3.core.Jdbi
111+
import org.jdbi.v3.core.kotlin.KotlinPlugin
112+
import org.jdbi.v3.postgres.PostgresPlugin
113+
114+
fun createJdbiInstance(dataSource: DataSource): Jdbi {
115+
return Jdbi.create(dataSource)
116+
.installPlugin(KotlinPlugin())
117+
.installPlugin(DocumentStorePlugin())
118+
}
119+
```
120+
121+
### Implementing `SerializationAdapter`
122+
123+
The `KotlinSerialization` class used in the `ExampleRepository` above is an implementation of the
124+
`SerializationAdapter` interface from Liflig Document Store. This interface allows you to choose
125+
your own JSON serialization library when using Document Store. Here is an example implementation
126+
for `kotlinx-serialization`:
127+
128+
```kotlin
129+
import kotlinx.serialization.KSerializer
130+
import kotlinx.serialization.json.Json
131+
import no.liflig.documentstore.entity.Entity
132+
import no.liflig.documentstore.repository.SerializationAdapter
133+
134+
private val json = Json {
135+
encodeDefaults = true
136+
ignoreUnknownKeys = true
137+
}
138+
139+
class KotlinSerialization<EntityT : Entity<*>>(
140+
private val serializer: KSerializer<EntityT>,
141+
) : SerializationAdapter<EntityT> {
142+
override fun toJson(entity: EntityT): String = json.encodeToString(serializer, entity)
143+
144+
override fun fromJson(value: String): EntityT = json.decodeFromString(serializer, value)
145+
}
146+
```
20147

21148
## Contributing
22149

docs/usage.md

Lines changed: 0 additions & 124 deletions
This file was deleted.

0 commit comments

Comments
 (0)