Skip to content

Commit

Permalink
Adding database
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinSchildhorn committed Dec 12, 2023
1 parent 88c2e77 commit 529a3d3
Show file tree
Hide file tree
Showing 19 changed files with 475 additions and 2 deletions.
6 changes: 4 additions & 2 deletions atomik/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ kotlin {
publishLibraryVariants("debug", "release")
}
jvm("desktop")
/*
listOf(
iosX64(),
iosArm64(),
Expand All @@ -44,7 +45,7 @@ kotlin {
iosTarget.binaries.framework {
baseName = "atomik"
}
}
}*/
jvm("desktop")

jvmToolchain(15)
Expand Down Expand Up @@ -77,6 +78,7 @@ kotlin {
api("androidx.core:core-ktx:1.12.0")
}
}
/*
val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
Expand All @@ -85,7 +87,7 @@ kotlin {
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
}
}*/

val desktopMain by getting {
dependsOn(jvmMain)
Expand Down
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ plugins {
id("org.jetbrains.compose").apply(false)
id("org.jlleitschuh.gradle.ktlint").version("12.0.2").apply(false)
id("dev.icerock.mobile.multiplatform-resources").version("0.23.0").apply(false)
id("app.cash.sqldelight").version("2.0.1").apply(false)
}
12 changes: 12 additions & 0 deletions shared/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ plugins {
id("org.jetbrains.compose")
id("org.jlleitschuh.gradle.ktlint")
id("dev.icerock.mobile.multiplatform-resources")
id("app.cash.sqldelight")
}

kotlin {
Expand Down Expand Up @@ -61,6 +62,7 @@ kotlin {
dependencies {
implementation("com.hierynomus:smbj:0.13.0")
implementation(compose.uiTooling)
implementation("app.cash.sqldelight:sqlite-driver:2.0.1")
}
}

Expand All @@ -72,6 +74,7 @@ kotlin {
api("androidx.appcompat:appcompat:1.6.1")
api("androidx.core:core-ktx:1.12.0")
implementation("io.github.kevinschildhorn:atomik:0.0.6")
implementation("app.cash.sqldelight:android-driver:2.0.1")
}
}
/*
Expand All @@ -84,6 +87,7 @@ kotlin {
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
resources.srcDirs("src/commonMain/resources")
implementation("app.cash.sqldelight:native-driver:2.0.1")
}*/
val desktopMain by getting {
dependsOn(jvmMain)
Expand Down Expand Up @@ -123,3 +127,11 @@ multiplatformResources {
dependencies {
ktlintRuleset("com.twitter.compose.rules:ktlint:0.0.26")
}

sqldelight {
databases {
create("PlaylistDatabase") {
packageName.set("com.kevinschildhorn.fotopresenter")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import android.app.Application
import android.content.Context
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
import app.cash.sqldelight.db.SqlDriver
import com.kevinschildhorn.fotopresenter.data.datasources.CredentialsDataSource
import com.kevinschildhorn.fotopresenter.data.network.NetworkHandler
import com.kevinschildhorn.fotopresenter.data.network.SMBJHandler
import com.kevinschildhorn.fotopresenter.ui.shared.DriverFactory
import com.russhwolf.settings.Settings
import com.russhwolf.settings.SharedPreferencesSettings
import org.koin.core.KoinApplication
Expand Down Expand Up @@ -41,6 +43,7 @@ internal actual val platformModule: Module = module {
single<NetworkHandler> {
SMBJHandler
}
single<SqlDriver> { DriverFactory(context = get()).createDriver() }
}

fun KoinApplication.androidContext(androidContext: Context): KoinApplication {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.kevinschildhorn.fotopresenter.ui.shared

import android.content.Context
import app.cash.sqldelight.db.SqlDriver
import app.cash.sqldelight.driver.android.AndroidSqliteDriver
import com.kevinschildhorn.fotopresenter.PlaylistDatabase

actual class DriverFactory(private val context: Context) {
actual fun createDriver(): SqlDriver {
return AndroidSqliteDriver(PlaylistDatabase.Schema, context, "playlist.db")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import com.kevinschildhorn.fotopresenter.data.datasources.CredentialsDataSource
import com.kevinschildhorn.fotopresenter.data.datasources.DirectoryDataSource
import com.kevinschildhorn.fotopresenter.data.datasources.ImageCacheDataSource
import com.kevinschildhorn.fotopresenter.data.datasources.ImageRemoteDataSource
import com.kevinschildhorn.fotopresenter.data.datasources.PlaylistDataSource
import com.kevinschildhorn.fotopresenter.data.repositories.CredentialsRepository
import com.kevinschildhorn.fotopresenter.data.repositories.DirectoryRepository
import com.kevinschildhorn.fotopresenter.data.repositories.ImageRepository
import com.kevinschildhorn.fotopresenter.data.repositories.PlaylistRepository
import com.kevinschildhorn.fotopresenter.domain.RetrieveDirectoryContentsUseCase
import com.kevinschildhorn.fotopresenter.domain.connection.AutoConnectUseCase
import com.kevinschildhorn.fotopresenter.domain.connection.ConnectToServerUseCase
Expand All @@ -19,6 +21,7 @@ import com.kevinschildhorn.fotopresenter.domain.image.RetrieveImageDirectoriesUs
import com.kevinschildhorn.fotopresenter.domain.image.RetrieveImageUseCase
import com.kevinschildhorn.fotopresenter.ui.screens.directory.DirectoryViewModel
import com.kevinschildhorn.fotopresenter.ui.screens.login.LoginViewModel
import com.kevinschildhorn.fotopresenter.ui.screens.playlist.PlaylistViewModel
import com.kevinschildhorn.fotopresenter.ui.screens.slideshow.SlideshowViewModel
import com.kevinschildhorn.fotopresenter.ui.shared.CacheInterface
import com.kevinschildhorn.fotopresenter.ui.shared.SharedCache
Expand All @@ -38,6 +41,8 @@ val commonModule =
single { ImageRemoteDataSource(get()) }
single { ImageRepository(get()) }
single { ImageCacheDataSource(get()) }
single { PlaylistDataSource(get()) }
single { PlaylistRepository(get()) }

// Domain
factory { ConnectToServerUseCase(get(), baseLogger.withTag("ConnectToServerUseCase")) }
Expand All @@ -59,6 +64,7 @@ val commonModule =
single { LoginViewModel(baseLogger.withTag("LoginViewModel"), get()) }
single { DirectoryViewModel(baseLogger.withTag("DirectoryViewModel")) }
single { SlideshowViewModel(baseLogger.withTag("SlideshowViewModel")) }
single { PlaylistViewModel(get(),baseLogger.withTag("PlaylistViewModel")) }
}

internal expect val platformModule: Module
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.kevinschildhorn.fotopresenter.data.datasources

import app.cash.sqldelight.db.SqlDriver
import com.kevinschildhorn.fotopresenter.Playlist
import com.kevinschildhorn.fotopresenter.PlaylistDatabase
import com.kevinschildhorn.fotopresenter.PlaylistImage
import com.kevinschildhorn.fotopresenter.data.ImageDirectory
import org.koin.core.component.KoinComponent

class PlaylistDataSource(
driver: SqlDriver,
) : KoinComponent {

private val database = PlaylistDatabase(driver)

fun createPlaylist(name: String, directories: List<ImageDirectory> = emptyList()): Playlist? {
return try {
//logger?.i { "Creating Playlist $name with images: ${directories.count()}" }
database.playlistQueries.insertPlaylist(name)
val playlist = database.playlistQueries.selectPlaylistByName(name).executeAsOne()
//logger?.i { "Playlist Created, now adding images" }

directories.forEach {
insertPlaylistImage(playlistId = playlist.id, directory = it)
}
playlist
} catch (e: Exception) {
null
}
}

fun getAllPlaylists(): List<Playlist> {
return try {
database.playlistQueries.selectAllPlaylists().executeAsList()
} catch (e: Exception) {
emptyList()
}

}

fun getPlaylistByName(name: String): Playlist? {
return try {
//logger?.i { "Selecting playlist by name $name" }
val playList: Playlist =
database.playlistQueries.selectPlaylistByName(name).executeAsOne()
//logger?.i { "Retrieved Playlist!" }
playList
} catch (e: Exception) {
null
}
}

fun insertPlaylistImage(playlistId: Long, directory: ImageDirectory): PlaylistImage? {
//logger?.i { "Inserting Playlist Image ${directory.name}" }

database.imageDirectoryQueries.insertPlaylistImage(
playlist_id = playlistId,
directory_path = directory.details.fullPath,
directory_id = directory.id.toLong(),
)
return getPlaylistImage(playlistId, directory.details.fullPath)
}

fun getPlaylistImage(playlistId: Long, directoryPath: String): PlaylistImage? {
return try {
//logger?.i { "Selecting Playlist Image $playlistId" }
val image: PlaylistImage =
database.imageDirectoryQueries.selectPlaylistImage(playlistId, directoryPath)
.executeAsOne()
//logger?.i { "Selecting Playlist Image" }
image
} catch (e: Exception) {
null
}
}

fun deletePlaylistByName(name: String): Boolean {
return try {
val playlist = database.playlistQueries.selectPlaylistByName(name).executeAsOne()
database.playlistQueries.deletePlaylist(playlist.name)
database.imageDirectoryQueries.deletePlaylist(playlist.id)
true
} catch (e: Exception) {
false
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.kevinschildhorn.fotopresenter.data.repositories

import com.kevinschildhorn.fotopresenter.Playlist
import com.kevinschildhorn.fotopresenter.PlaylistImage
import com.kevinschildhorn.fotopresenter.data.ImageDirectory
import com.kevinschildhorn.fotopresenter.data.datasources.PlaylistDataSource

class PlaylistRepository(
private val playlistDataSource: PlaylistDataSource,
) {

fun createPlaylist(name: String, directories: List<ImageDirectory> = emptyList()): Playlist? =
playlistDataSource.createPlaylist(name, directories)

fun getAllPlaylists(): List<Playlist> =
playlistDataSource.getAllPlaylists()

fun getPlaylistByName(name: String): Playlist? =
playlistDataSource.getPlaylistByName(name)

fun insertPlaylistImage(playlistId: Long, directory: ImageDirectory): PlaylistImage? =
playlistDataSource.insertPlaylistImage(playlistId, directory)

fun getPlaylistImage(playlistId: Long, directoryPath: String): PlaylistImage? =
playlistDataSource.getPlaylistImage(playlistId, directoryPath)

fun deletePlaylistByName(name: String): Boolean =
playlistDataSource.deletePlaylistByName(name)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.kevinschildhorn.fotopresenter.ui.screens.playlist


import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue

@Composable
fun PlaylistScreen(
viewModel: PlaylistViewModel,
onLoginSuccess: () -> Unit,
) {
val uiState by viewModel.uiState.collectAsState()
LazyColumn {
items(uiState.playlists) {
Text(it.name)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.kevinschildhorn.fotopresenter.ui.screens.playlist

import com.kevinschildhorn.fotopresenter.Playlist
import com.kevinschildhorn.fotopresenter.ui.UiState
import com.kevinschildhorn.fotopresenter.ui.screens.common.ScreenState

data class PlaylistScreenState(
val playlists: List<Playlist> = emptyList(),
val selectedId: Long = 0L,
override val state: UiState = UiState.IDLE,
) : ScreenState
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.kevinschildhorn.fotopresenter.ui.screens.playlist

import co.touchlab.kermit.Logger
import com.kevinschildhorn.fotopresenter.data.repositories.PlaylistRepository
import com.kevinschildhorn.fotopresenter.ui.shared.ViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import org.koin.core.component.KoinComponent

class PlaylistViewModel(
private val playlistRepository: PlaylistRepository,
private val logger: Logger,
) : ViewModel(), KoinComponent {

private val _uiState = MutableStateFlow(PlaylistScreenState())
val uiState: StateFlow<PlaylistScreenState> = _uiState.asStateFlow()

init {
refreshPlaylists()
}

fun refreshPlaylists(){
val allPlaylists = playlistRepository.getAllPlaylists()
_uiState.update { it.copy(playlists = allPlaylists) }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.kevinschildhorn.fotopresenter.ui.shared

import app.cash.sqldelight.db.SqlDriver

expect class DriverFactory {
fun createDriver(): SqlDriver
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
CREATE TABLE PlaylistImage (
id INTEGER PRIMARY KEY NOT NULL,
playlist_id INTEGER NOT NULL,
directory_path TEXT NOT NULL,
directory_id INTEGER NOT NULL
);

insertPlaylistImage:
INSERT INTO PlaylistImage(playlist_id, directory_path, directory_id)
VALUES (?, ?, ?);

selectPlaylistImage:
SELECT *
FROM PlaylistImage
WHERE playlist_id = ? AND directory_path = ?;

deletePlaylistImage:
DELETE
FROM PlaylistImage
WHERE directory_path = ?;

deletePlaylist:
DELETE
FROM PlaylistImage
WHERE playlist_id = ?;
Loading

0 comments on commit 529a3d3

Please sign in to comment.