Skip to content

Commit fc36f8a

Browse files
authored
Add tags table in the database (#253)
* Add UUID dependency * Add `Tag` table to the app * Add local tag model * Add required tag queries
1 parent afbf2e2 commit fc36f8a

File tree

8 files changed

+156
-0
lines changed

8 files changed

+156
-0
lines changed

core/model/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ kotlin {
2525
implementation(libs.kotlinx.datetime)
2626
// Require this for `@Immutable` annotation for models
2727
implementation(libs.compose.runtime)
28+
implementation(libs.uuid)
2829
}
2930
}
3031
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright 2024 Sasikanth Miriyampalli
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package dev.sasikanth.rss.reader.core.model.local
18+
19+
import com.benasher44.uuid.Uuid
20+
import kotlinx.datetime.Instant
21+
22+
data class Tag(
23+
val id: Uuid,
24+
val label: String,
25+
val createdAt: Instant,
26+
val updatedAt: Instant,
27+
)

gradle/libs.versions.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ xmlutil = "0.86.3"
4747
ktxml = "0.2.3"
4848
uri = "0.0.16"
4949
webview = "1.8.4"
50+
uuid = "0.8.2"
5051

5152
[libraries]
5253
compose_runtime = { module = "org.jetbrains.compose.runtime:runtime", version.ref = "compose" }
@@ -108,6 +109,7 @@ xmlutil-serialization = { module = "io.github.pdvrieze.xmlutil:serialization", v
108109
ktxml = { module = "org.kobjects.ktxml:core", version.ref = "ktxml" }
109110
uri = { module = "com.eygraber:uri-kmp", version.ref = "uri" }
110111
webview = { module = "io.github.kevinnzou:compose-webview-multiplatform", version.ref = "webview" }
112+
uuid = { module = "com.benasher44:uuid", version.ref = "uuid" }
111113

112114
[plugins]
113115
android_application = { id = "com.android.application", version.ref = "android_gradle_plugin" }

shared/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ kotlin {
120120
implementation(libs.stately.iso.collections)
121121
implementation(libs.bundles.xmlutil)
122122
api(libs.webview)
123+
implementation(libs.uuid)
123124
}
124125
commonTest.dependencies {
125126
implementation(libs.kotlin.test)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2024 Sasikanth Miriyampalli
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package dev.sasikanth.rss.reader.database
18+
19+
import app.cash.sqldelight.ColumnAdapter
20+
import com.benasher44.uuid.Uuid
21+
import com.benasher44.uuid.uuidFrom
22+
23+
internal object UuidAdapter : ColumnAdapter<Uuid, String> {
24+
25+
override fun decode(databaseValue: String): Uuid {
26+
return uuidFrom(databaseValue)
27+
}
28+
29+
override fun encode(value: Uuid): String {
30+
return value.toString()
31+
}
32+
}

shared/src/commonMain/kotlin/dev/sasikanth/rss/reader/di/DataComponent.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import dev.sasikanth.rss.reader.database.DateAdapter
2121
import dev.sasikanth.rss.reader.database.Feed
2222
import dev.sasikanth.rss.reader.database.Post
2323
import dev.sasikanth.rss.reader.database.ReaderDatabase
24+
import dev.sasikanth.rss.reader.database.Tag
25+
import dev.sasikanth.rss.reader.database.UuidAdapter
2426
import dev.sasikanth.rss.reader.di.scopes.AppScope
2527
import me.tatarka.inject.annotations.Provides
2628

@@ -43,6 +45,12 @@ internal interface DataComponent : SqlDriverPlatformComponent, DataStorePlatform
4345
lastCleanUpAtAdapter = DateAdapter
4446
),
4547
bookmarkAdapter = Bookmark.Adapter(dateAdapter = DateAdapter),
48+
tagAdapter =
49+
Tag.Adapter(
50+
idAdapter = UuidAdapter,
51+
createdAtAdapter = DateAdapter,
52+
updatedAtAdapter = DateAdapter
53+
)
4654
)
4755
}
4856

@@ -57,4 +65,6 @@ internal interface DataComponent : SqlDriverPlatformComponent, DataStorePlatform
5765

5866
@Provides
5967
fun providesFeedSearchFTSQueries(database: ReaderDatabase) = database.feedSearchFTSQueries
68+
69+
@Provides fun providesTagQueries(database: ReaderDatabase) = database.tagQueries
6070
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2024 Sasikanth Miriyampalli
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package dev.sasikanth.rss.reader.repository
18+
19+
import app.cash.sqldelight.coroutines.asFlow
20+
import app.cash.sqldelight.coroutines.mapToList
21+
import com.benasher44.uuid.Uuid
22+
import com.benasher44.uuid.uuid4
23+
import dev.sasikanth.rss.reader.core.model.local.Tag
24+
import dev.sasikanth.rss.reader.database.TagQueries
25+
import dev.sasikanth.rss.reader.di.scopes.AppScope
26+
import dev.sasikanth.rss.reader.util.DispatchersProvider
27+
import kotlinx.coroutines.flow.Flow
28+
import kotlinx.coroutines.withContext
29+
import kotlinx.datetime.Clock
30+
import me.tatarka.inject.annotations.Inject
31+
32+
@Inject
33+
@AppScope
34+
class TagRepository(
35+
private val dispatchersProvider: DispatchersProvider,
36+
private val tagQueries: TagQueries,
37+
) {
38+
39+
suspend fun createTag(label: String) {
40+
withContext(dispatchersProvider.io) {
41+
val currentInstant = Clock.System.now()
42+
43+
tagQueries.saveTag(
44+
id = uuid4(),
45+
label = label,
46+
createdAt = currentInstant,
47+
updatedAt = currentInstant
48+
)
49+
}
50+
}
51+
52+
suspend fun deleteTag(id: Uuid) = withContext(dispatchersProvider.io) { tagQueries.deleteTag(id) }
53+
54+
suspend fun updatedTag(label: String, id: Uuid) {
55+
withContext(dispatchersProvider.io) { tagQueries.updateTag(label = label, id = id) }
56+
}
57+
58+
fun tags(label: String? = null): Flow<List<Tag>> {
59+
return tagQueries.tags(label.orEmpty(), ::Tag).asFlow().mapToList(dispatchersProvider.io)
60+
}
61+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import com.benasher44.uuid.Uuid;
2+
import kotlinx.datetime.Instant;
3+
4+
CREATE TABLE tag (
5+
id TEXT AS Uuid NOT NULL PRIMARY KEY,
6+
label TEXT NOT NULL,
7+
createdAt INTEGER AS Instant NOT NULL,
8+
updatedAt INTEGER AS Instant NOT NULL
9+
);
10+
11+
tags:
12+
SELECT * FROM tag WHERE label LIKE :label OR label IS NULL OR label = '';
13+
14+
updateTag:
15+
UPDATE tag SET label = :label WHERE id = :id;
16+
17+
deleteTag:
18+
DELETE FROM tag WHERE id = :id;
19+
20+
saveTag:
21+
INSERT OR IGNORE INTO tag(id, label, createdAt, updatedAt)
22+
VALUES (:id, :label, :createdAt, :updatedAt);

0 commit comments

Comments
 (0)