diff --git a/atomik/build.gradle.kts b/atomik/build.gradle.kts index 9d6b9b73..606c3e12 100644 --- a/atomik/build.gradle.kts +++ b/atomik/build.gradle.kts @@ -36,6 +36,7 @@ kotlin { publishLibraryVariants("debug", "release") } jvm("desktop") + /* listOf( iosX64(), iosArm64(), @@ -44,7 +45,7 @@ kotlin { iosTarget.binaries.framework { baseName = "atomik" } - } + }*/ jvm("desktop") jvmToolchain(15) @@ -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 @@ -85,7 +87,7 @@ kotlin { iosX64Main.dependsOn(this) iosArm64Main.dependsOn(this) iosSimulatorArm64Main.dependsOn(this) - } + }*/ val desktopMain by getting { dependsOn(jvmMain) diff --git a/build.gradle.kts b/build.gradle.kts index c46b66db..3d62306f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -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) } diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index faea6e0e..0c8b4def 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -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 { @@ -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") } } @@ -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") } } /* @@ -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) @@ -123,3 +127,11 @@ multiplatformResources { dependencies { ktlintRuleset("com.twitter.compose.rules:ktlint:0.0.26") } + +sqldelight { + databases { + create("PlaylistDatabase") { + packageName.set("com.kevinschildhorn.fotopresenter") + } + } +} diff --git a/shared/src/androidMain/kotlin/com/kevinschildhorn/fotopresenter/KoinAndroid.kt b/shared/src/androidMain/kotlin/com/kevinschildhorn/fotopresenter/KoinAndroid.kt index 93761c51..f880f59b 100644 --- a/shared/src/androidMain/kotlin/com/kevinschildhorn/fotopresenter/KoinAndroid.kt +++ b/shared/src/androidMain/kotlin/com/kevinschildhorn/fotopresenter/KoinAndroid.kt @@ -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 @@ -41,6 +43,7 @@ internal actual val platformModule: Module = module { single { SMBJHandler } + single { DriverFactory(context = get()).createDriver() } } fun KoinApplication.androidContext(androidContext: Context): KoinApplication { diff --git a/shared/src/androidMain/kotlin/com/kevinschildhorn/fotopresenter/ui/shared/DriverFactory.kt b/shared/src/androidMain/kotlin/com/kevinschildhorn/fotopresenter/ui/shared/DriverFactory.kt new file mode 100644 index 00000000..4392a3c1 --- /dev/null +++ b/shared/src/androidMain/kotlin/com/kevinschildhorn/fotopresenter/ui/shared/DriverFactory.kt @@ -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") + } +} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/Koin.kt b/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/Koin.kt index 63186b53..911d7a0d 100644 --- a/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/Koin.kt +++ b/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/Koin.kt @@ -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 @@ -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 @@ -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")) } @@ -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 diff --git a/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/data/datasources/PlaylistDataSource.kt b/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/data/datasources/PlaylistDataSource.kt new file mode 100644 index 00000000..21cd4929 --- /dev/null +++ b/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/data/datasources/PlaylistDataSource.kt @@ -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 = 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 { + 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 + } + } +} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/data/repositories/PlaylistRepository.kt b/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/data/repositories/PlaylistRepository.kt new file mode 100644 index 00000000..f45f19a1 --- /dev/null +++ b/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/data/repositories/PlaylistRepository.kt @@ -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 = emptyList()): Playlist? = + playlistDataSource.createPlaylist(name, directories) + + fun getAllPlaylists(): List = + 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) +} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/ui/screens/playlist/PlaylistScreen.kt b/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/ui/screens/playlist/PlaylistScreen.kt new file mode 100644 index 00000000..48d439af --- /dev/null +++ b/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/ui/screens/playlist/PlaylistScreen.kt @@ -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) + } + } +} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/ui/screens/playlist/PlaylistScreenState.kt b/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/ui/screens/playlist/PlaylistScreenState.kt new file mode 100644 index 00000000..d5fa1956 --- /dev/null +++ b/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/ui/screens/playlist/PlaylistScreenState.kt @@ -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 = emptyList(), + val selectedId: Long = 0L, + override val state: UiState = UiState.IDLE, +) : ScreenState \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/ui/screens/playlist/PlaylistViewModel.kt b/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/ui/screens/playlist/PlaylistViewModel.kt new file mode 100644 index 00000000..653edbba --- /dev/null +++ b/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/ui/screens/playlist/PlaylistViewModel.kt @@ -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 = _uiState.asStateFlow() + + init { + refreshPlaylists() + } + + fun refreshPlaylists(){ + val allPlaylists = playlistRepository.getAllPlaylists() + _uiState.update { it.copy(playlists = allPlaylists) } + } +} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/ui/shared/DriverFactory.kt b/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/ui/shared/DriverFactory.kt new file mode 100644 index 00000000..7bb208a0 --- /dev/null +++ b/shared/src/commonMain/kotlin/com/kevinschildhorn/fotopresenter/ui/shared/DriverFactory.kt @@ -0,0 +1,7 @@ +package com.kevinschildhorn.fotopresenter.ui.shared + +import app.cash.sqldelight.db.SqlDriver + +expect class DriverFactory { + fun createDriver(): SqlDriver +} \ No newline at end of file diff --git a/shared/src/commonMain/sqldelight/com/kevinschildhorn/fotopresenter/ImageDirectory.sq b/shared/src/commonMain/sqldelight/com/kevinschildhorn/fotopresenter/ImageDirectory.sq new file mode 100644 index 00000000..e00317d5 --- /dev/null +++ b/shared/src/commonMain/sqldelight/com/kevinschildhorn/fotopresenter/ImageDirectory.sq @@ -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 = ?; \ No newline at end of file diff --git a/shared/src/commonMain/sqldelight/com/kevinschildhorn/fotopresenter/Playlist.sq b/shared/src/commonMain/sqldelight/com/kevinschildhorn/fotopresenter/Playlist.sq new file mode 100644 index 00000000..95dac8bc --- /dev/null +++ b/shared/src/commonMain/sqldelight/com/kevinschildhorn/fotopresenter/Playlist.sq @@ -0,0 +1,27 @@ +CREATE TABLE Playlist ( + id INTEGER PRIMARY KEY NOT NULL, + name TEXT UNIQUE NOT NULL +); + +selectAllPlaylists: +SELECT * +FROM Playlist; + +selectPlaylistByName: +SELECT * +FROM Playlist +WHERE name = ?; + +insertPlaylist: +INSERT INTO Playlist(name) +VALUES (?); + +updatePlaylist: +UPDATE Playlist +SET name = ? +WHERE id = :id; + +deletePlaylist: +DELETE +FROM Playlist +WHERE name = ?; \ No newline at end of file diff --git a/shared/src/commonTest/kotlin/com/kevinschildhorn/fotopresenter/data/datasources/PlaylistDataSourceTest.kt b/shared/src/commonTest/kotlin/com/kevinschildhorn/fotopresenter/data/datasources/PlaylistDataSourceTest.kt new file mode 100644 index 00000000..2392b0ad --- /dev/null +++ b/shared/src/commonTest/kotlin/com/kevinschildhorn/fotopresenter/data/datasources/PlaylistDataSourceTest.kt @@ -0,0 +1,186 @@ +package com.kevinschildhorn.fotopresenter.data.datasources + +import app.cash.sqldelight.db.SqlDriver +import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver +import com.kevinschildhorn.fotopresenter.PlaylistDatabase +import com.kevinschildhorn.fotopresenter.data.ImageDirectory +import com.kevinschildhorn.fotopresenter.data.network.MockNetworkDirectoryDetails +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertNotNull +import kotlin.test.assertNull +import kotlin.test.assertTrue +import kotlin.test.fail + +/** +Testing [PlaylistDataSource] + **/ +class PlaylistDataSourceTest { + + private val imageDirectory = ImageDirectory( + MockNetworkDirectoryDetails( + fullPath = "Image1.png", + id = 1, + ) + ) + private val imageDirectoryList: List = listOf( + imageDirectory, + ImageDirectory( + MockNetworkDirectoryDetails( + fullPath = "Photos/Image2.png", + id = 2, + ) + ), + ImageDirectory( + MockNetworkDirectoryDetails( + fullPath = "Image3.png", + id = 3, + ) + ), + ) + + @Test + fun `Create Playlist Success`() { + val dataSource = PlaylistDataSource(createInMemorySqlDriver()) + val playlist = dataSource.createPlaylist("Playlist1") + assertEquals("Playlist1", playlist?.name) + assertEquals(1, playlist?.id) + } + + @Test + fun `Create Playlist Large`() { + val dataSource = PlaylistDataSource(createInMemorySqlDriver()) + val playlist = dataSource.createPlaylist("Playlist1", imageDirectoryList) + assertEquals("Playlist1", playlist?.name) + assertEquals(1, playlist?.id) + imageDirectoryList.forEach { + val image = dataSource.getPlaylistImage(playlist?.id!!, it.details.fullPath) + assertNotNull(image) + } + } + + @Test + fun `Create Playlist Failure`() { + val dataSource = PlaylistDataSource(createInMemorySqlDriver()) + val playlist1 = dataSource.createPlaylist("Playlist1") + val playlist2 = dataSource.createPlaylist("Playlist1") + assertNotNull(playlist1) + assertNull(playlist2) + } + + @Test + fun `Insert Playlist Image Success`() { + val dataSource = PlaylistDataSource(createInMemorySqlDriver()) + dataSource.createPlaylist("Playlist1")?.let { playlist -> + val image = dataSource.insertPlaylistImage(playlist.id, imageDirectory) + assertEquals(playlist.id, image?.playlist_id) + assertEquals(imageDirectory.details.fullPath, image?.directory_path) + } ?: run { + fail("Didn't Create Playlist") + } + } + + @Test + fun `Insert Playlist Image Failure`() { + val dataSource = PlaylistDataSource(createInMemorySqlDriver()) + dataSource.createPlaylist("Playlist1")?.let { playlist -> + val image1 = dataSource.insertPlaylistImage(playlist.id, imageDirectory) + val image2 = dataSource.insertPlaylistImage(playlist.id, imageDirectory) + assertNotNull(image1) + assertNull(image2) + } ?: run { + fail("Didn't Create Playlist") + } + } + + @Test + fun `Get Playlist by Name Success`() { + val dataSource = PlaylistDataSource(createInMemorySqlDriver()) + val playlistName = "Playlist1" + val playlist = dataSource.createPlaylist(playlistName) + val selectedPlaylist = dataSource.getPlaylistByName(playlistName) + assertEquals(playlist?.name, selectedPlaylist?.name) + assertEquals(playlist?.id, selectedPlaylist?.id) + } + + @Test + fun `Select Playlist by Name Failure`() { + val dataSource = PlaylistDataSource(createInMemorySqlDriver()) + val selectedPlaylist = dataSource.getPlaylistByName("NonExistant") + assertNull(selectedPlaylist) + } + + @Test + fun `Get Playlist Image Success`() { + val dataSource = PlaylistDataSource(createInMemorySqlDriver()) + dataSource.createPlaylist("Playlist1")?.let { playlist -> + val image1 = dataSource.insertPlaylistImage(playlist.id, imageDirectory) + val image2 = dataSource.getPlaylistImage(playlist.id, imageDirectory.details.fullPath) + assertNotNull(image1) + assertNotNull(image2) + assertEquals(image1?.playlist_id, image2?.playlist_id) + assertEquals(image1?.id, image2?.id) + assertEquals(image1?.directory_path, image2?.directory_path) + } ?: run { + fail("Didn't Create Playlist") + } + } + + @Test + fun `Get Playlist Image Failure`() { + val dataSource = PlaylistDataSource(createInMemorySqlDriver()) + val image = dataSource.getPlaylistImage(0, imageDirectory.details.fullPath) + assertNull(image) + } + + @Test + fun `Delete Playlist Success`() { + val dataSource = PlaylistDataSource(createInMemorySqlDriver()) + val image = dataSource.getPlaylistImage(0, imageDirectory.details.fullPath) + assertNull(image) + } + + @Test + fun `Delete Playlist Failure`() { + val playlistName = "Playlist1" + val dataSource = PlaylistDataSource(createInMemorySqlDriver()) + val playlist = dataSource.createPlaylist(playlistName, imageDirectoryList) + assertNotNull(playlist) + + val newPlaylist = dataSource.getPlaylistByName(playlistName) + assertNotNull(newPlaylist) + + val image = dataSource.getPlaylistImage(playlist?.id ?: 0L, imageDirectory.details.fullPath) + assertNotNull(image) + + val result = dataSource.deletePlaylistByName(playlistName) + assertTrue(result) + + val deletedPlaylist = dataSource.getPlaylistByName(playlistName) + assertNull(deletedPlaylist) + val deletedImage = dataSource.getPlaylistImage(playlist?.id ?: 0L, imageDirectory.details.fullPath) + assertNull(deletedImage) + } + + @Test + fun `Select All Playlists Success`() { + val dataSource = PlaylistDataSource(createInMemorySqlDriver()) + val playlist = dataSource.createPlaylist("Playlist1", imageDirectoryList) + val playlists = dataSource.getAllPlaylists() + assertEquals(1, playlists.count()) + } + + @Test + fun `Select All Playlists Failure`() { + val dataSource = PlaylistDataSource(createInMemorySqlDriver()) + val playlists = dataSource.getAllPlaylists() + assertEquals(0, playlists.count()) + + } + + private fun createInMemorySqlDriver(): SqlDriver { + val driver: SqlDriver = JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY) + PlaylistDatabase.Schema.create(driver) + return driver + } +} \ No newline at end of file diff --git a/shared/src/desktopMain/kotlin/com/kevinschildhorn/fotopresenter/KoinDesktop.kt b/shared/src/desktopMain/kotlin/com/kevinschildhorn/fotopresenter/KoinDesktop.kt index 20ba23b1..4157ea77 100644 --- a/shared/src/desktopMain/kotlin/com/kevinschildhorn/fotopresenter/KoinDesktop.kt +++ b/shared/src/desktopMain/kotlin/com/kevinschildhorn/fotopresenter/KoinDesktop.kt @@ -1,7 +1,9 @@ package com.kevinschildhorn.fotopresenter +import app.cash.sqldelight.db.SqlDriver 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.PreferencesSettings import com.russhwolf.settings.Settings import org.koin.core.module.Module @@ -21,4 +23,5 @@ internal actual val platformModule: Module = module { single { SMBJHandler } + single { DriverFactory().createDriver() } } diff --git a/shared/src/desktopMain/kotlin/com/kevinschildhorn/fotopresenter/ui/shared/DriverFactory.kt b/shared/src/desktopMain/kotlin/com/kevinschildhorn/fotopresenter/ui/shared/DriverFactory.kt new file mode 100644 index 00000000..93fb9c9c --- /dev/null +++ b/shared/src/desktopMain/kotlin/com/kevinschildhorn/fotopresenter/ui/shared/DriverFactory.kt @@ -0,0 +1,13 @@ +package com.kevinschildhorn.fotopresenter.ui.shared + +import app.cash.sqldelight.db.SqlDriver +import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver +import com.kevinschildhorn.fotopresenter.PlaylistDatabase + +actual class DriverFactory { + actual fun createDriver(): SqlDriver { + val driver: SqlDriver = JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY) + PlaylistDatabase.Schema.create(driver) + return driver + } +} \ No newline at end of file diff --git a/shared/src/iosMain/kotlin/com/kevinschildhorn/fotopresenter/KoiniOS.kt b/shared/src/iosMain/kotlin/com/kevinschildhorn/fotopresenter/KoiniOS.kt index 7e1a3762..4f3e0ae4 100644 --- a/shared/src/iosMain/kotlin/com/kevinschildhorn/fotopresenter/KoiniOS.kt +++ b/shared/src/iosMain/kotlin/com/kevinschildhorn/fotopresenter/KoiniOS.kt @@ -30,4 +30,5 @@ internal actual val platformModule: Module = module { ), ) } + single { DriverFactory().createDriver() } } diff --git a/shared/src/iosMain/kotlin/com/kevinschildhorn/fotopresenter/ui/shared/DriverFactory.kt b/shared/src/iosMain/kotlin/com/kevinschildhorn/fotopresenter/ui/shared/DriverFactory.kt new file mode 100644 index 00000000..9eadbaf0 --- /dev/null +++ b/shared/src/iosMain/kotlin/com/kevinschildhorn/fotopresenter/ui/shared/DriverFactory.kt @@ -0,0 +1,5 @@ +actual class DriverFactory { + actual fun createDriver(): SqlDriver { + return NativeSqliteDriver(Database.Schema, "test.db") + } +} \ No newline at end of file