Skip to content

Commit

Permalink
[Server]: Add default dictionaries
Browse files Browse the repository at this point in the history
  • Loading branch information
Krushiler committed Dec 19, 2023
1 parent fcdd808 commit 6af0547
Show file tree
Hide file tree
Showing 11 changed files with 353 additions and 30 deletions.
17 changes: 17 additions & 0 deletions api/src/main/java/data/dto/DefaultDictionaryDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package data.dto

import kotlinx.serialization.Serializable

@Serializable
data class DefaultDictionaryDto(
val id: String,
val name: String,
val description: String,
val terms: List<DefaultTermDto>,
)

@Serializable
data class DefaultTermDto(
val name: String,
val description: String,
)
10 changes: 10 additions & 0 deletions api/src/main/java/data/dto/DictionaryCollectionDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package data.dto

import kotlinx.serialization.Serializable

@Serializable
data class DictionaryCollectionDto(
val id: String,
val name: String,
val dictionaryCount: Int,
)
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,14 @@ fun DictionaryNavigation(
rootViewModel.back()
}
) { navController ->
NavHost(navController = navController,
NavHost(
navController = navController,
startDestination = DictionaryRoute.Menu.path,
enterTransition = { fadeIn() },
exitTransition = { fadeOut() }) {
exitTransition = { fadeOut() },
popEnterTransition = { fadeIn() },
popExitTransition = { fadeOut() },
) {
composable(DictionaryRoute.Menu.path) {
DictionariesMenuScreen(
dictionaryScreenSource = dictionaryScreenSource, dictionaryNavigation = viewModel
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
package com.example.aftermathandroid.presentation.navigation.root

import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.animation.slideOutVertically
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
Expand Down Expand Up @@ -52,15 +48,11 @@ fun RootNavigation(
|| navController.currentDestination?.route == RootDestination.Registration.path
if (it == null && !isAuthDestination) {
navController.navigate(RootDestination.Login.path) {
popUpTo(RootDestination.Home.path) {
inclusive = true
}
popUpTo(0)
}
} else if (it != null && isAuthDestination) {
navController.navigate(RootDestination.Home.path) {
popUpTo(RootDestination.Home.path) {
inclusive = true
}
popUpTo(0)
}
}
}
Expand All @@ -69,9 +61,10 @@ fun RootNavigation(
NavHost(
navController = navController,
startDestination = RootDestination.Home.path,
enterTransition = { fadeIn() },
exitTransition = { fadeOut() },
popExitTransition = { fadeOut() },
enterTransition = { slideInHorizontally { it } },
exitTransition = { slideOutHorizontally { -it / 2 } },
popEnterTransition = { slideInHorizontally { -it / 2 } },
popExitTransition = { slideOutHorizontally { it } },
) {
composable(RootDestination.Profile.path) {
ProfileScreen()
Expand All @@ -84,9 +77,6 @@ fun RootNavigation(
}
composable(
RootDestination.Registration.path,
enterTransition = { slideInHorizontally { it } },
popExitTransition = { slideOutHorizontally { it } },
exitTransition = { slideOutHorizontally { it } },
) {
RegisterScreen()
}
Expand All @@ -102,9 +92,6 @@ fun RootNavigation(
}
composable(
RootDestination.SelectDictionary.path,
enterTransition = { slideInVertically(initialOffsetY = { it }) },
exitTransition = { slideOutVertically(targetOffsetY = { it }) },
popExitTransition = { slideOutVertically(targetOffsetY = { it }) },
) {
DictionarySelectScreen()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@ package com.krushiler.data.repository
import com.krushiler.data.storage.dao.DictionaryDao
import com.krushiler.data.storage.dao.UserDao
import com.krushiler.data.storage.dbo.ChangeTermDboAction
import domain.model.DictionarySearchData
import com.krushiler.domain.model.PagingData
import data.dto.DefaultDictionaryDto
import data.dto.DictionaryDto
import data.dto.DictionaryInfoDto
import data.dto.TermDto
import data.dto.UserDto
import data.response.PagedResponse
import domain.model.DictionarySearchData
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.serialization.json.Json
import util.generateUUID
import java.io.BufferedReader
import java.io.InputStreamReader

class DictionaryRepository(private val dictionaryDao: DictionaryDao, private val userDao: UserDao) {
suspend fun getUserDictionaries(user: UserDto, pagingData: PagingData): PagedResponse<DictionaryInfoDto> {
Expand All @@ -27,11 +33,12 @@ class DictionaryRepository(private val dictionaryDao: DictionaryDao, private val
pagingData: PagingData,
searchData: DictionarySearchData,
userId: String?,
collectionId: String?
): PagedResponse<DictionaryInfoDto> {
val dictionaries = dictionaryDao.getDictionaries(pagingData, searchData)
val dictionaries = dictionaryDao.getDictionaries(pagingData, searchData, collectionId)
return PagedResponse(
items = dictionaries.items.map {
val userDbo = userDao.getUserByLogin(it.authorId)
val userDbo = it.authorId?.let { authorId -> userDao.getUserByLogin(authorId) }
val user = userDbo?.let { dbo ->
UserDto(
dbo.login, dbo.name, dbo.avatar
Expand All @@ -49,7 +56,7 @@ class DictionaryRepository(private val dictionaryDao: DictionaryDao, private val
val dictionary = dictionaryDao.getDictionary(id)
val terms = dictionaryDao.getTerms(id)
return dictionary?.let {
val userDbo = userDao.getUserByLogin(it.authorId)
val userDbo = it.authorId?.let { authorId -> userDao.getUserByLogin(authorId) }
val user = userDbo?.let { dbo ->
UserDto(
dbo.login, dbo.name, dbo.avatar
Expand Down Expand Up @@ -96,4 +103,62 @@ class DictionaryRepository(private val dictionaryDao: DictionaryDao, private val
if (this == null || userId == null) return false
return this == userId
}

private val jsonFormat = Json { ignoreUnknownKeys = true }


suspend fun createInitialDictionaries() {
val collectionId = "default"
val collection = dictionaryDao.getDictionaryCollection(collectionId)
if (collection != null) return

dictionaryDao.createDictionaryCollection(
id = collectionId,
name = "Default"
)

try {
val id = createDictionaryFromResource("dictionaries/kotlin.json")
if (id != null) {
dictionaryDao.addDictionaryToCollection(id, collectionId)
}
} catch (_: Exception) {
}
}

private suspend fun createDictionaryFromResource(resourceName: String): String? {
val inputStream = object {}.javaClass.classLoader.getResourceAsStream(resourceName)

if (inputStream != null) {
val reader = BufferedReader(InputStreamReader(inputStream))
val content = reader.readText()
withContext(Dispatchers.IO) {
reader.close()
inputStream.close()
}

val json = jsonFormat.decodeFromString<DefaultDictionaryDto>(content)

if (dictionaryDao.getDictionary(json.id) != null) return null

dictionaryDao.createDictionary(
id = json.id,
authorId = null,
name = json.name,
description = json.description,
)

json.terms.forEach {
dictionaryDao.createTerm(
id = generateUUID(),
dictionaryId = json.id,
term = it.name,
description = it.description
)
}

return json.id
}
return null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,25 @@ import com.krushiler.data.dao.Dao
import com.krushiler.data.storage.database.DatabaseList
import com.krushiler.data.storage.dbo.ChangeTermDboAction
import com.krushiler.data.storage.dbo.Dictionaries
import com.krushiler.data.storage.dbo.DictionaryCollectionDbo
import com.krushiler.data.storage.dbo.DictionaryCollectionDictionaries
import com.krushiler.data.storage.dbo.DictionaryCollections
import com.krushiler.data.storage.dbo.DictionaryDbo
import com.krushiler.data.storage.dbo.TermDbo
import com.krushiler.data.storage.dbo.Terms
import domain.model.DictionarySearchData
import com.krushiler.domain.model.PagingData
import domain.model.DictionarySearchData
import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.and
import org.jetbrains.exposed.sql.andWhere
import org.jetbrains.exposed.sql.deleteWhere
import org.jetbrains.exposed.sql.insert
import org.jetbrains.exposed.sql.or
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.selectAll
import org.jetbrains.exposed.sql.update
import util.generateUUID

class DictionaryDao(database: Database) : Dao(database) {
suspend fun getUserDictionaries(userId: String, pagingData: PagingData): DatabaseList<DictionaryDbo> = dbQuery {
Expand All @@ -32,6 +37,7 @@ class DictionaryDao(database: Database) : Dao(database) {
suspend fun getDictionaries(
pagingData: PagingData,
searchData: DictionarySearchData,
collectionId: String?
): DatabaseList<DictionaryDbo> = dbQuery {
val request = Dictionaries.selectAll()
if (searchData.authors.isNotEmpty()) {
Expand All @@ -51,6 +57,15 @@ class DictionaryDao(database: Database) : Dao(database) {
}
}
}
if (collectionId != null) {
request.andWhere {
Dictionaries.id inList
DictionaryCollectionDictionaries.select { DictionaryCollectionDictionaries.collectionId eq collectionId }
.map {
it[DictionaryCollectionDictionaries.dictionaryId]
}
}
}
DatabaseList(
items = request.copy().limit(
pagingData.limit, pagingData.offset.toLong()
Expand All @@ -67,7 +82,7 @@ class DictionaryDao(database: Database) : Dao(database) {
Terms.select { Terms.dictionaryId eq dictionaryId }.map { Terms.resultRowToTerm(it) }
}

suspend fun createDictionary(id: String, authorId: String, name: String, description: String): Boolean = dbQuery {
suspend fun createDictionary(id: String, authorId: String?, name: String, description: String): Boolean = dbQuery {
Dictionaries.insert {
it[Dictionaries.name] = name
it[Dictionaries.description] = description
Expand Down Expand Up @@ -119,4 +134,62 @@ class DictionaryDao(database: Database) : Dao(database) {
it[Terms.description] = description
} > 0
}

suspend fun createDictionaryCollection(
id: String,
name: String,
) = dbQuery {
DictionaryCollections.insert {
it[DictionaryCollections.id] = id
it[DictionaryCollections.name] = name
}
}

suspend fun addDictionaryToCollection(
dictionaryId: String,
collectionId: String,
) = dbQuery {
DictionaryCollectionDictionaries.insert {
it[DictionaryCollectionDictionaries.id] = generateUUID()
it[DictionaryCollectionDictionaries.dictionaryId] = dictionaryId
it[DictionaryCollectionDictionaries.collectionId] = collectionId
}
}

suspend fun removeDictionaryFromCollection(
dictionaryId: String,
collectionId: String,
) = dbQuery {
DictionaryCollections.deleteWhere {
(DictionaryCollectionDictionaries.dictionaryId eq dictionaryId).and { DictionaryCollectionDictionaries.collectionId eq collectionId }
}
}

suspend fun getDictionaryCollections(
pagingData: PagingData
): DatabaseList<DictionaryCollectionDbo> = dbQuery {
val request = DictionaryCollections.selectAll()
DatabaseList(
items = request.copy().limit(pagingData.limit, pagingData.offset.toLong())
.map { DictionaryCollections.resultRowToDictionaryCollection(it) },
total = request.copy().count().toInt(),
)
}

suspend fun getDictionaryCollection(
id: String
): DictionaryCollectionDbo? = dbQuery {
DictionaryCollections.select { DictionaryCollections.id eq id }
.firstOrNull()?.let { DictionaryCollections.resultRowToDictionaryCollection(it) }
}

suspend fun getDictionaryCollectionDictionaries(
collectionId: String,
): List<DictionaryDbo> = dbQuery {
DictionaryCollectionDictionaries.select { DictionaryCollectionDictionaries.collectionId eq collectionId }.map {
Dictionaries.select {
Dictionaries.id eq it[DictionaryCollectionDictionaries.dictionaryId]
}.map { Dictionaries.resultRowToDictionary(it) }.firstOrNull()
}.mapNotNull { it }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.krushiler.data.storage.dbo

import org.jetbrains.exposed.sql.ResultRow
import org.jetbrains.exposed.sql.Table

data class DictionaryCollectionDbo(
val id: String,
val name: String,
)

object DictionaryCollections : Table() {
val id = varchar("id", 128)
val name = varchar("name", 128)

override val primaryKey = PrimaryKey(id)

fun resultRowToDictionaryCollection(row: ResultRow) = DictionaryCollectionDbo(
id = row[id],
name = row[name],
)
}

object DictionaryCollectionDictionaries : Table() {
val id = varchar("id", 128)
val dictionaryId = varchar("dictionaryId", 128).references(Dictionaries.id)
val collectionId = varchar("collectionId", 128).references(DictionaryCollections.id)

override val primaryKey = PrimaryKey(id)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import org.jetbrains.exposed.sql.Table

data class DictionaryDbo(
val id: String,
val authorId: String,
val authorId: String?,
val name: String,
val description: String,
)

object Dictionaries : Table() {
val id = varchar("id", 128)
val authorId = varchar("authorId", 128)
val authorId = varchar("authorId", 128).nullable()
val name = varchar("name", 128)
val description = varchar("description", 128)

Expand Down
Loading

0 comments on commit 6af0547

Please sign in to comment.