@@ -14,9 +14,136 @@ for convenient database access.
1414
1515This 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
0 commit comments