Skip to content

Commit

Permalink
Add tags table in the database (#253)
Browse files Browse the repository at this point in the history
* Add UUID dependency

* Add `Tag` table to the app

* Add local tag model

* Add required tag queries
  • Loading branch information
msasikanth authored Jan 27, 2024
1 parent afbf2e2 commit fc36f8a
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 0 deletions.
1 change: 1 addition & 0 deletions core/model/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ kotlin {
implementation(libs.kotlinx.datetime)
// Require this for `@Immutable` annotation for models
implementation(libs.compose.runtime)
implementation(libs.uuid)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2024 Sasikanth Miriyampalli
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dev.sasikanth.rss.reader.core.model.local

import com.benasher44.uuid.Uuid
import kotlinx.datetime.Instant

data class Tag(
val id: Uuid,
val label: String,
val createdAt: Instant,
val updatedAt: Instant,
)
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ xmlutil = "0.86.3"
ktxml = "0.2.3"
uri = "0.0.16"
webview = "1.8.4"
uuid = "0.8.2"

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

[plugins]
android_application = { id = "com.android.application", version.ref = "android_gradle_plugin" }
Expand Down
1 change: 1 addition & 0 deletions shared/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ kotlin {
implementation(libs.stately.iso.collections)
implementation(libs.bundles.xmlutil)
api(libs.webview)
implementation(libs.uuid)
}
commonTest.dependencies {
implementation(libs.kotlin.test)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright 2024 Sasikanth Miriyampalli
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dev.sasikanth.rss.reader.database

import app.cash.sqldelight.ColumnAdapter
import com.benasher44.uuid.Uuid
import com.benasher44.uuid.uuidFrom

internal object UuidAdapter : ColumnAdapter<Uuid, String> {

override fun decode(databaseValue: String): Uuid {
return uuidFrom(databaseValue)
}

override fun encode(value: Uuid): String {
return value.toString()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import dev.sasikanth.rss.reader.database.DateAdapter
import dev.sasikanth.rss.reader.database.Feed
import dev.sasikanth.rss.reader.database.Post
import dev.sasikanth.rss.reader.database.ReaderDatabase
import dev.sasikanth.rss.reader.database.Tag
import dev.sasikanth.rss.reader.database.UuidAdapter
import dev.sasikanth.rss.reader.di.scopes.AppScope
import me.tatarka.inject.annotations.Provides

Expand All @@ -43,6 +45,12 @@ internal interface DataComponent : SqlDriverPlatformComponent, DataStorePlatform
lastCleanUpAtAdapter = DateAdapter
),
bookmarkAdapter = Bookmark.Adapter(dateAdapter = DateAdapter),
tagAdapter =
Tag.Adapter(
idAdapter = UuidAdapter,
createdAtAdapter = DateAdapter,
updatedAtAdapter = DateAdapter
)
)
}

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

@Provides
fun providesFeedSearchFTSQueries(database: ReaderDatabase) = database.feedSearchFTSQueries

@Provides fun providesTagQueries(database: ReaderDatabase) = database.tagQueries
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright 2024 Sasikanth Miriyampalli
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dev.sasikanth.rss.reader.repository

import app.cash.sqldelight.coroutines.asFlow
import app.cash.sqldelight.coroutines.mapToList
import com.benasher44.uuid.Uuid
import com.benasher44.uuid.uuid4
import dev.sasikanth.rss.reader.core.model.local.Tag
import dev.sasikanth.rss.reader.database.TagQueries
import dev.sasikanth.rss.reader.di.scopes.AppScope
import dev.sasikanth.rss.reader.util.DispatchersProvider
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.withContext
import kotlinx.datetime.Clock
import me.tatarka.inject.annotations.Inject

@Inject
@AppScope
class TagRepository(
private val dispatchersProvider: DispatchersProvider,
private val tagQueries: TagQueries,
) {

suspend fun createTag(label: String) {
withContext(dispatchersProvider.io) {
val currentInstant = Clock.System.now()

tagQueries.saveTag(
id = uuid4(),
label = label,
createdAt = currentInstant,
updatedAt = currentInstant
)
}
}

suspend fun deleteTag(id: Uuid) = withContext(dispatchersProvider.io) { tagQueries.deleteTag(id) }

suspend fun updatedTag(label: String, id: Uuid) {
withContext(dispatchersProvider.io) { tagQueries.updateTag(label = label, id = id) }
}

fun tags(label: String? = null): Flow<List<Tag>> {
return tagQueries.tags(label.orEmpty(), ::Tag).asFlow().mapToList(dispatchersProvider.io)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import com.benasher44.uuid.Uuid;
import kotlinx.datetime.Instant;

CREATE TABLE tag (
id TEXT AS Uuid NOT NULL PRIMARY KEY,
label TEXT NOT NULL,
createdAt INTEGER AS Instant NOT NULL,
updatedAt INTEGER AS Instant NOT NULL
);

tags:
SELECT * FROM tag WHERE label LIKE :label OR label IS NULL OR label = '';

updateTag:
UPDATE tag SET label = :label WHERE id = :id;

deleteTag:
DELETE FROM tag WHERE id = :id;

saveTag:
INSERT OR IGNORE INTO tag(id, label, createdAt, updatedAt)
VALUES (:id, :label, :createdAt, :updatedAt);

0 comments on commit fc36f8a

Please sign in to comment.