Compare commits

...

5 Commits

Author SHA1 Message Date
1f9ff73a6d Add git ignore 2025-02-09 18:42:18 +01:00
56e7c53f70 Add migrations 2025-02-09 18:33:04 +01:00
66617923b7 Add multiple languages 2025-02-09 18:31:51 +01:00
47e1b47028 Fix bugs and add direction of translation 2025-02-02 17:00:26 +01:00
52eef8dbd4 Cosmetics 2025-02-02 16:23:58 +01:00
15 changed files with 334 additions and 110 deletions

4
.gitignore vendored
View File

@@ -11,8 +11,8 @@ captures
.externalNativeBuild .externalNativeBuild
.cxx .cxx
*.xcodeproj/* *.xcodeproj/*
data/** data/*
composeApp/data/** composeApp/data/*
composeApp/src/commonMain/resources/media/** composeApp/src/commonMain/resources/media/**
!*.xcodeproj/project.pbxproj !*.xcodeproj/project.pbxproj
!*.xcodeproj/xcshareddata/ !*.xcodeproj/xcshareddata/

View File

@@ -69,6 +69,7 @@ kotlin {
implementation(compose.runtime) implementation(compose.runtime)
implementation(compose.foundation) implementation(compose.foundation)
implementation(compose.material) implementation(compose.material)
implementation(compose.material3)
implementation(compose.ui) implementation(compose.ui)
implementation(compose.components.resources) implementation(compose.components.resources)
implementation(compose.components.uiToolingPreview) implementation(compose.components.uiToolingPreview)
@@ -86,8 +87,7 @@ kotlin {
implementation(libs.composeIcons.tablerIcons) implementation(libs.composeIcons.tablerIcons)
implementation(libs.composeIcons.fontAwesome) implementation(libs.composeIcons.fontAwesome)
implementation(libs.korau) implementation(libs.korau)
implementation(libs.flagkit)
} }
desktopMain.dependencies { desktopMain.dependencies {
implementation(compose.desktop.currentOs) implementation(compose.desktop.currentOs)

View File

@@ -21,6 +21,8 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.filled.Clear import androidx.compose.material.icons.filled.Clear
import androidx.compose.material.icons.filled.Settings import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import kotlinx.coroutines.flow.observeOn import kotlinx.coroutines.flow.observeOn
import org.koin.compose.koinInject import org.koin.compose.koinInject
@@ -34,30 +36,78 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import compose.icons.TablerIcons import compose.icons.TablerIcons
import compose.icons.tablericons.Table import compose.icons.tablericons.Table
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.lazy.itemsIndexed
import compose.icons.FontAwesomeIcons import compose.icons.FontAwesomeIcons
import compose.icons.fontawesomeicons.Solid import compose.icons.fontawesomeicons.Solid
import compose.icons.tablericons.ArrowBigRight import compose.icons.tablericons.ArrowBigRight
import compose.icons.tablericons.FileText
import compose.icons.fontawesomeicons.solid.PlayCircle import compose.icons.fontawesomeicons.solid.PlayCircle
import compose.icons.tablericons.ArrowBigLeft
import models.Term import models.Term
import models.TermFull import models.TermFull
import kotlinx.coroutines.* import kotlinx.coroutines.*
import service.DatabaseFactory.getTranslationForLanguages
import service.DatabaseFactory.getLanguageForCode
import service.DatabaseFactory.getDictionaies
import service.DatabaseFactory.getLanguageForId
import dev.carlsen.flagkit.FlagKit
import dev.carlsen.flagkit.FlagIcons
import models.Dictionary
@Composable @Composable
fun RowScope.TableCell( fun RowScope.TableCell(
text: String, text: String,
weight: Float weight: Float,
color: Color = Color.Gray
) { ) {
Text( Text(
text = text, text = text,
Modifier Modifier
.border(1.dp, Color.Black) .border(1.dp, Color.LightGray)
.weight(weight) .weight(weight)
.padding(4.dp) .padding(4.dp)
) )
} }
@Composable
fun LangugeDropdown(onChangeClick: (dict: Dictionary) -> Unit,dictionary: Dictionary?) {
var expanded by remember { mutableStateOf(false) }
fun groupByString1(terms: List<TermFull>): MutableList<MutableList<TermFull>> { IconButton(onClick = {
expanded = !expanded
}) {
getLanguageForId(dictionary!!.lang1Id)?.let{ l ->
FlagKit.getFlag(countryCode = l.alphaCode!!)?.let {
Image(
imageVector = it,
contentDescription = "English",
)
}
}
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }
) {
for ((id, dict) in getDictionaies()) {
getLanguageForId(dict.lang1Id)?.let { l ->
DropdownMenuItem(
leadingIcon = {
Image(
imageVector = FlagKit.getFlag(countryCode = l.alphaCode!!)!!,
contentDescription = l.name
)
},
text = { Text(l.name) },
onClick = { onChangeClick(dict); expanded = false }
)
}
}
}
}
}
fun groupByString(terms: List<TermFull>, direction: Int): MutableList<MutableList<TermFull>> {
val fullList: MutableList<MutableList<TermFull>> = mutableListOf() val fullList: MutableList<MutableList<TermFull>> = mutableListOf()
var lastTerm: TermFull? = null var lastTerm: TermFull? = null
var termsEq: MutableList<TermFull> = mutableListOf() var termsEq: MutableList<TermFull> = mutableListOf()
@@ -65,7 +115,9 @@ fun groupByString1(terms: List<TermFull>): MutableList<MutableList<TermFull>> {
if (lastTerm == null) { if (lastTerm == null) {
termsEq += t termsEq += t
} else { } else {
if (lastTerm.string1 == t.string1){ val s1 = if (direction == 1) lastTerm.string1 else lastTerm.string2
val s2 = if (direction == 1) t.string1 else t.string2
if (s1 == s2) {
termsEq += t termsEq += t
} else { } else {
fullList += termsEq fullList += termsEq
@@ -83,8 +135,11 @@ fun groupByString1(terms: List<TermFull>): MutableList<MutableList<TermFull>> {
@Composable @Composable
fun SearchBarTextField(viewModel: MainModelView) { fun SearchBarTextField(viewModel: MainModelView) {
val query = remember { mutableStateOf("") } val query = remember { mutableStateOf("") }
val columnViewType = remember { mutableStateOf(false) } var columnViewType = remember { mutableStateOf(false) }
var tDirection = remember { mutableStateOf(1) }
Column { Column {
val dict by viewModel.dictionary.collectAsState()
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
// horizontalArrangement = Arrangement.End, // horizontalArrangement = Arrangement.End,
@@ -95,7 +150,14 @@ fun SearchBarTextField(viewModel: MainModelView) {
value = query.value, value = query.value,
onValueChange = { onValueChange = {
query.value = it query.value = it
viewModel.getTerms(query.value) if (dict == null) return@TextField
val l1 = getLanguageForId(dict!!.lang1Id)
val l2 = getLanguageForId(dict!!.lang2Id)
if (l1 != null && l2 != null) {
val trans = if (tDirection.value == 1) getTranslationForLanguages(l1.shortName,l2.shortName) else getTranslationForLanguages(l2.shortName,l1.shortName)
if (trans == null) return@TextField
viewModel.getTerms(query.value, trans)
}
}, },
placeholder = { Text("Prelož...") }, placeholder = { Text("Prelož...") },
singleLine = true, singleLine = true,
@@ -112,13 +174,51 @@ fun SearchBarTextField(viewModel: MainModelView) {
}, },
modifier = Modifier.weight(3f) modifier = Modifier.weight(3f)
) )
Row (Modifier.width(155.dp).border(width = 2.dp, Color.Black)) { Row(Modifier.width(200.dp).border(width = 2.dp, Color.Black)) {
Spacer(modifier = Modifier.padding(2.dp)) Spacer(modifier = Modifier.padding(2.dp))
Icon(TablerIcons.Table, contentDescription = "Table View", modifier = Modifier.size(width = 50.dp, height = 50.dp)) IconButton(onClick = {
columnViewType.value = !columnViewType.value
}) {
if (columnViewType.value)
Icon(
TablerIcons.Table,
contentDescription = "Table View",
modifier = Modifier.size(width = 50.dp, height = 50.dp)
)
else
Icon(
TablerIcons.FileText,
contentDescription = "List View",
modifier = Modifier.size(width = 50.dp, height = 50.dp)
)
}
Spacer(modifier = Modifier.padding(2.dp)) Spacer(modifier = Modifier.padding(2.dp))
Icon(TablerIcons.ArrowBigRight, contentDescription = "Table View", modifier = Modifier.size(width = 50.dp, height = 50.dp)) IconButton(onClick = {
tDirection.value = if (tDirection.value == 1) 2 else 1
}) {
if (tDirection.value == 1)
Icon(
TablerIcons.ArrowBigRight,
contentDescription = "Forward",
modifier = Modifier.size(width = 50.dp, height = 50.dp)
)
else
Icon(
TablerIcons.ArrowBigLeft,
contentDescription = "Resverse",
modifier = Modifier.size(width = 50.dp, height = 50.dp)
)
}
LangugeDropdown(
onChangeClick = viewModel::changeDictionary,
dictionary = dict
)
Spacer(modifier = Modifier.padding(2.dp)) Spacer(modifier = Modifier.padding(2.dp))
Icon(Icons.Filled.Settings, contentDescription = "Table View", modifier = Modifier.size(width = 50.dp, height = 50.dp)) Icon(
Icons.Filled.Settings,
contentDescription = "Table View",
modifier = Modifier.size(width = 50.dp, height = 50.dp)
)
//Spacer(modifier = Modifier.fillMaxWidth()) //Spacer(modifier = Modifier.fillMaxWidth())
} }
} }
@@ -131,20 +231,30 @@ fun SearchBarTextField(viewModel: MainModelView) {
Column { Column {
if (columnViewType.value) { if (columnViewType.value) {
Row(Modifier.background(Color.Gray)) { Row(Modifier.background(Color.Gray)) {
TableCell(text = "Anglicky", weight = .5f) TableCell(text = if (tDirection.value == 1) "Anglicky" else "Slovensky", weight = .5f)
TableCell(text = "Slovensky", weight = .5f) TableCell(text = if (tDirection.value == 1) "Slovensky" else "Anglicky", weight = .5f)
} }
val column1Weight = .5f // 50% val column1Weight = .5f // 50%
val column2Weight = .5f // 50% val column2Weight = .5f // 50%
// The LazyColumn will be our table. Notice the use of the weights below // The LazyColumn will be our table. Notice the use of the weights below
LazyColumn(Modifier.fillMaxSize().padding(0.dp)) { LazyColumn(Modifier.fillMaxSize().padding(0.dp)) {
// Here is the header itemsIndexed(items = terms!!, itemContent = { i, t ->
val color = if (i % 2 == 1) Color.hsl(
hue = 168f,
saturation = .77f,
lightness = .68f,
alpha = 1f
) else Color.hsl(hue = 217f, saturation = .77f, lightness = .68f, alpha = 1f)
items(items = terms!!, itemContent = { t -> Row(Modifier.fillMaxWidth().background(color)) {
TableCell(
Row(Modifier.fillMaxWidth()) { text = if (tDirection.value == 1) t.string1 else t.string2,
TableCell(text = t.string1, weight = column1Weight) weight = column1Weight
TableCell(text = t.string2, weight = column2Weight) )
TableCell(
text = if (tDirection.value == 1) t.string2 else t.string1,
weight = column2Weight
)
} }
@@ -152,23 +262,25 @@ fun SearchBarTextField(viewModel: MainModelView) {
} }
} else { } else {
val terms2: MutableList<MutableList<TermFull>> = groupByString1(terms!!) val terms2: MutableList<MutableList<TermFull>> = groupByString(terms!!, tDirection.value)
LazyColumn(Modifier.fillMaxSize().padding(0.dp)) { LazyColumn(Modifier.fillMaxSize().padding(0.dp)) {
var i=0
var rowBackground = Color.LightGray var rowBackground = Color.LightGray
items(items = terms2, itemContent = { t2 -> itemsIndexed(items = terms2, itemContent = { i, t2 ->
var t: TermFull? = null var t: TermFull? = null
if (t2.size > 0) t = t2[0] if (t2.size > 0) t = t2[0]
else return@items else return@itemsIndexed
when ( i++ % 2 ) { when (i % 2) {
0 -> rowBackground = Color.LightGray 0 -> rowBackground = Color.LightGray
1 -> rowBackground = Color.Gray 1 -> rowBackground = Color.Gray
} }
Row(Modifier.fillMaxWidth().background(color = rowBackground)) { Row(Modifier.fillMaxWidth().background(color = rowBackground)) {
Column { Column {
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
Text(t.string1, fontWeight = FontWeight.Bold) Text(
if (tDirection.value == 1) t.string1 else t.string2,
fontWeight = FontWeight.Bold
)
for (p in t.pronunciations!!) { for (p in t.pronunciations!!) {
Spacer(modifier = Modifier.padding(2.dp)) Spacer(modifier = Modifier.padding(2.dp))
if (p.ipa != null) { if (p.ipa != null) {
@@ -186,21 +298,29 @@ fun SearchBarTextField(viewModel: MainModelView) {
onClick = { onClick = {
viewModel.playSound("media/${p.filename}") viewModel.playSound("media/${p.filename}")
}) { }) {
Icon(FontAwesomeIcons.Solid.PlayCircle,contentDescription = "Play sound",Modifier.size(20.dp).padding(start = 2.dp),) Icon(
FontAwesomeIcons.Solid.PlayCircle,
contentDescription = "Play sound",
Modifier.size(20.dp).padding(start = 2.dp),
)
} }
} }
Spacer(modifier = Modifier.padding(2.dp)) Spacer(modifier = Modifier.padding(2.dp))
} }
} }
val str2 = t2.joinToString(separator = ", ") { it.string2 } val str2 =
if (tDirection.value == 1) t2.joinToString(separator = ", ") { it.string2 } else t2.joinToString(
separator = ", "
) { it.string1 }
Text(text = str2, modifier = Modifier.padding(start = 20.dp)) Text(text = str2, modifier = Modifier.padding(start = 20.dp))
Spacer(modifier = Modifier Spacer(
modifier = Modifier
.border(1.dp, Color.Black) .border(1.dp, Color.Black)
.padding(1.dp).fillMaxWidth()) .padding(1.dp).fillMaxWidth()
)
} }
} }
}) })
@@ -216,9 +336,8 @@ fun SearchBarTextField(viewModel: MainModelView) {
} }
@Composable @Composable
fun MainView(viewModel: MainModelView = koinInject<MainModelView>(),) { fun MainView(viewModel: MainModelView = koinInject<MainModelView>()) {
SearchBarTextField(viewModel) SearchBarTextField(viewModel)
} }

View File

@@ -4,6 +4,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import korlibs.audio.sound.* import korlibs.audio.sound.*
import korlibs.io.file.std.resourcesVfs import korlibs.io.file.std.resourcesVfs
import korlibs.io.file.std.ZipVfs
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
@@ -13,21 +14,34 @@ import service.DatabaseFactory.getTranslationForLanguages
import service.SearchType import service.SearchType
import service.TermServiceImpl import service.TermServiceImpl
import korlibs.audio.format.* import korlibs.audio.format.*
import korlibs.io.compression.zip.ZipEntry
import korlibs.io.file.VfsFile
import korlibs.io.file.std.openAsZip
import models.Dictionary
import models.Translation
import service.DatabaseFactory.getDictionaies
class MainModelView(private val repository: TermServiceImpl): ViewModel() { class MainModelView(private val repository: TermServiceImpl): ViewModel() {
val terms : StateFlow<List<TermFull>?> get() = _terms val terms : StateFlow<List<TermFull>?> get() = _terms
private val _terms = MutableStateFlow<List<TermFull>?>(null) private val _terms = MutableStateFlow<List<TermFull>?>(null)
fun getTerms(term: String) { val dictionary: StateFlow<Dictionary?> get() = _dictionary
private val _dictionary = MutableStateFlow<Dictionary?>(getDictionaies()[1])
fun getTerms(term: String, trans: Translation) {
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
var sType = SearchType.START var sType = SearchType.START
sType = if (term.length > 2) SearchType.START else SearchType.EXACT sType = if (term.length > 2) SearchType.START else SearchType.EXACT
val trans = getTranslationForLanguages("an","sl") ?: return@launch
val transTerms = repository.getTranslationForTerm(term,trans,sType) val transTerms = repository.getTranslationForTerm(term,trans,sType)
_terms.value = transTerms _terms.value = transTerms
} }
} }
fun changeDictionary(dict: Dictionary) {
_dictionary.value = dict
}
fun clearSearch() { fun clearSearch() {
_terms.value = listOf() _terms.value = listOf()

View File

@@ -17,6 +17,7 @@ assertjVersion = "3.26.3"
compose-multiplatform = "1.7.0" compose-multiplatform = "1.7.0"
coreKtx = "1.9.0" coreKtx = "1.9.0"
exposedVersion = "0.55.0" exposedVersion = "0.55.0"
flagkit = "1.1.0"
flywayVersion = "10.20.1" flywayVersion = "10.20.1"
h2 = "2.3.232" h2 = "2.3.232"
hikariCpVersion = "5.1.0" hikariCpVersion = "5.1.0"
@@ -67,6 +68,7 @@ lifecycleViewmodelKtx = "2.6.1"
lifecycleViewmodelCompose = "2.8.4" lifecycleViewmodelCompose = "2.8.4"
logback = "1.5.12" logback = "1.5.12"
material = "1.7.6" material = "1.7.6"
okio = "3.10.2"
psqlVersion = "42.7.4" psqlVersion = "42.7.4"
restAssuredVersion = "5.5.0" restAssuredVersion = "5.5.0"
runtimeLivedata = "1.7.6" runtimeLivedata = "1.7.6"
@@ -89,6 +91,7 @@ composeIcons-linea = { module = "br.com.devsrsouza.compose.icons:linea", version
composeIcons-octicons = { module = "br.com.devsrsouza.compose.icons:octicons", version.ref = "composeIcons" } composeIcons-octicons = { module = "br.com.devsrsouza.compose.icons:octicons", version.ref = "composeIcons" }
composeIcons-simpleIcons = { module = "br.com.devsrsouza.compose.icons:simple-icons", version.ref = "composeIcons" } composeIcons-simpleIcons = { module = "br.com.devsrsouza.compose.icons:simple-icons", version.ref = "composeIcons" }
composeIcons-tablerIcons = { module = "br.com.devsrsouza.compose.icons:tabler-icons", version.ref = "composeIcons" } composeIcons-tablerIcons = { module = "br.com.devsrsouza.compose.icons:tabler-icons", version.ref = "composeIcons" }
flagkit = { module = "dev.carlsen.flagkit:flagkit", version.ref = "flagkit" }
korau = { module = "com.soywiz.korlibs.korau:korau", version.ref = "korau" } korau = { module = "com.soywiz.korlibs.korau:korau", version.ref = "korau" }
androidx-core-ktx-v190 = { module = "androidx.core:core-ktx", version.ref = "coreKtx" } androidx-core-ktx-v190 = { module = "androidx.core:core-ktx", version.ref = "coreKtx" }
@@ -182,6 +185,7 @@ ktor-server-core = { module = "io.ktor:ktor-server-core-jvm", version.ref = "kto
ktor-server-netty = { module = "io.ktor:ktor-server-netty-jvm", version.ref = "ktor" } ktor-server-netty = { module = "io.ktor:ktor-server-netty-jvm", version.ref = "ktor" }
ktor-server-tests = { module = "io.ktor:ktor-server-tests-jvm", version.ref = "ktor" } ktor-server-tests = { module = "io.ktor:ktor-server-tests-jvm", version.ref = "ktor" }
material = { module = "androidx.compose.material:material", version.ref = "material" } material = { module = "androidx.compose.material:material", version.ref = "material" }
okio = { module = "com.squareup.okio:okio-bom", version.ref = "okio" }
postgresql = { module = "org.postgresql:postgresql", version.ref = "psqlVersion" } postgresql = { module = "org.postgresql:postgresql", version.ref = "psqlVersion" }
rest-assured = { module = "io.rest-assured:rest-assured", version.ref = "restAssuredVersion" } rest-assured = { module = "io.rest-assured:rest-assured", version.ref = "restAssuredVersion" }
symbol-processing-api = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "symbolProcessingApi" } symbol-processing-api = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "symbolProcessingApi" }

View File

@@ -9,10 +9,12 @@ class LanguageDao(id: EntityID<Int>) : IntEntity(id) {
var name by Languages.name var name by Languages.name
var shortName by Languages.shortName var shortName by Languages.shortName
var alphaCode by Languages.alphaCode
fun toModel() : Language = Language( fun toModel() : Language = Language(
id = id.value, id = id.value,
name = name, name = name,
shortName = shortName shortName = shortName,
alphaCode = alphaCode
) )
} }

View File

@@ -0,0 +1,28 @@
package db.migration
import dao.DictionaryDao
import kotlinx.serialization.decodeFromString
import tables.*
import org.flywaydb.core.api.migration.BaseJavaMigration
import org.flywaydb.core.api.migration.Context
import org.jetbrains.exposed.dao.id.EntityID
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.transactions.transaction
import kotlin.system.exitProcess
class V4__add_lang_code: BaseJavaMigration() {
override fun migrate(context: Context?) {
transaction {
val mapOfCodes = mapOf(1 to "SK",2 to "CZ", 3 to "GB",4 to "NL", 5 to "FR", 6 to "DE", 7 to "IT", 8 to "IT",
9 to "HU", 10 to "PL", 11 to "PT", 12 to "RU", 13 to "ES", 14 to "SE" )
SchemaUtils.createMissingTablesAndColumns(Languages)
for (l in Languages.selectAll()) {
val id = l[Languages.id]
Languages.update({ Languages.id eq id}) {
it[alphaCode] = mapOfCodes[id.value]
}
}
}
}
}

View File

@@ -0,0 +1,24 @@
package db.migration
import dao.DictionaryDao
import kotlinx.serialization.decodeFromString
import tables.*
import org.flywaydb.core.api.migration.BaseJavaMigration
import org.flywaydb.core.api.migration.Context
import org.jetbrains.exposed.dao.id.EntityID
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.transactions.transaction
import kotlin.system.exitProcess
import service.DatabaseFactory
class V5__add_indexes: BaseJavaMigration() {
override fun migrate(context: Context?) {
DatabaseFactory.connectAll()
// for ((id,dict) in DatabaseFactory.getDictionaies()) {
transaction (1) {
SchemaUtils.createMissingTablesAndColumns(Terms)
}
//}
}
}

View File

@@ -9,7 +9,8 @@ import org.jetbrains.exposed.sql.Table
data class Language( data class Language(
val id: Int, val id: Int,
val name: String, val name: String,
val shortName: String val shortName: String,
val alphaCode: String?
) )

View File

@@ -13,6 +13,8 @@ import javax.sql.DataSource
import tables.* import tables.*
import dao.* import dao.*
import com.typesafe.config.ConfigFactory import com.typesafe.config.ConfigFactory
import models.Dictionary
import models.Language
import models.Translation import models.Translation
object DatabaseFactory { object DatabaseFactory {
@@ -21,7 +23,9 @@ object DatabaseFactory {
private val dbs : MutableMap<Int,Database> = mutableMapOf() private val dbs : MutableMap<Int,Database> = mutableMapOf()
private val hdb : MutableMap<String,Database> = mutableMapOf() private val hdb : MutableMap<String,Database> = mutableMapOf()
private val htrans: MutableMap<String,Translation> = mutableMapOf() private val htrans: MutableMap<String,Translation> = mutableMapOf()
private val halpha: MutableMap<String,Language> = mutableMapOf()
private val dictById: MutableMap<Int,Dictionary> = mutableMapOf()
private val hLang1: MutableMap<Int,Language> = mutableMapOf()
fun connectAndMigrate() { fun connectAndMigrate() {
log.info("Initialising database") log.info("Initialising database")
val pool = hikari() val pool = hikari()
@@ -43,10 +47,17 @@ object DatabaseFactory {
return HikariDataSource(config) return HikariDataSource(config)
} }
fun getTranslationForLanguages(l1: String, l2: String): Translation? = htrans["${l1}${l2}"]?: null fun getTranslationForLanguages(l1: String, l2: String): Translation? = htrans["${l1.lowercase()}${l2.lowercase()}"]?: null
fun getLanguageForCode(l: String): Language? = halpha[l.uppercase()]?: null
fun getLanguageForId(id: Int): Language? = hLang1[id]?: null
fun getDictionaies(): Map<Int,Dictionary> = dictById
fun getAllLanguages(): List<Language> {
return halpha.values.toList()
}
fun connectAll() {
if (getDictionaies().any()) return
fun connectAll(): Map<Int,Database> {
val hMap : MutableMap<Int, Database> = mutableMapOf()
transaction { transaction {
for (trans in TranslationDao.all()) { for (trans in TranslationDao.all()) {
val l1 = trans.lang1.shortName.lowercase() val l1 = trans.lang1.shortName.lowercase()
@@ -55,6 +66,11 @@ object DatabaseFactory {
htrans["${l1}${l2}"] = trans.toModel() htrans["${l1}${l2}"] = trans.toModel()
} }
for (lang in LanguageDao.all()) {
halpha[lang.shortName] = lang.toModel()
hLang1[lang.id.value] = lang.toModel()
}
for (dict in DictionaryDao.all()) { for (dict in DictionaryDao.all()) {
val cfg = ConfigFactory.load().getConfig("h2") val cfg = ConfigFactory.load().getConfig("h2")
val config = HikariConfig().apply { val config = HikariConfig().apply {
@@ -68,10 +84,14 @@ object DatabaseFactory {
val db = HikariDataSource(config) val db = HikariDataSource(config)
val dbc = Database.connect(db) val dbc = Database.connect(db)
dbs[dict.id.value] = dbc dbs[dict.id.value] = dbc
dictById[dict.id.value] = dict.toModel()
hdb["${dict.lang1.shortName.lowercase()}${dict.lang2.shortName.lowercase()}"] = dbc hdb["${dict.lang1.shortName.lowercase()}${dict.lang2.shortName.lowercase()}"] = dbc
} }
} }
return hMap println("DBS PRINT")
println(dbs)
} }
private fun runFlyway(datasource: DataSource) { private fun runFlyway(datasource: DataSource) {

View File

@@ -6,4 +6,7 @@ import models.Language
interface LanguageService { interface LanguageService {
fun getLanguage(id: Int): Language? fun getLanguage(id: Int): Language?
fun getAllLanguages(): List<Language> fun getAllLanguages(): List<Language>
fun getAlphaCode4String(code: String): Language?
fun getAlphaCode4Lang(lang: Language): Language?
} }

View File

@@ -3,6 +3,7 @@ package service
import dao.LanguageDao import dao.LanguageDao
import org.jetbrains.exposed.sql.transactions.transaction import org.jetbrains.exposed.sql.transactions.transaction
import service.DatabaseFactory.dbExecId import service.DatabaseFactory.dbExecId
import service.DatabaseFactory.getLanguageForCode
import models.Language import models.Language
class LanguageServiceImpl : LanguageService { class LanguageServiceImpl : LanguageService {
@@ -14,4 +15,12 @@ class LanguageServiceImpl : LanguageService {
LanguageDao.all().map { it.toModel() } LanguageDao.all().map { it.toModel() }
} }
override fun getAlphaCode4String(code: String): Language? {
return getLanguageForCode(code)
}
override fun getAlphaCode4Lang(lang: Language): Language? {
return getLanguageForCode(lang.shortName)
}
} }

View File

@@ -47,7 +47,7 @@ class TermServiceImpl : TermService {
if (type == SearchType.EXACT) if (type == SearchType.EXACT)
TermDao.find { Terms.string2 eq s }.map { it.toFullModel() } TermDao.find { Terms.string2 eq s }.map { it.toFullModel() }
else else
TermDao.find { Terms.string1 like s }.map { it.toFullModel() } TermDao.find { Terms.string2 like s }.map { it.toFullModel() }
} }
} }

View File

@@ -8,5 +8,5 @@ object Languages : IntIdTable() {
val name = varchar("name", 255) val name = varchar("name", 255)
val shortName = varchar("short_name", 255) val shortName = varchar("short_name", 255)
val alphaCode = char("alpha_code",2).nullable()
} }

View File

@@ -6,8 +6,8 @@ import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObject
import tables.Suffixes import tables.Suffixes
object Terms : IntIdTable() { object Terms : IntIdTable() {
val string1 = varchar("string1", 255) val string1 = varchar("string1", 255).index()
val string2 = varchar("string2", 255) val string2 = varchar("string2", 255).index()
val suffix1 = reference("suffix1_id",Suffixes).nullable() val suffix1 = reference("suffix1_id",Suffixes).nullable()
val suffix2 = reference("suffix2_id",Suffixes).nullable() val suffix2 = reference("suffix2_id",Suffixes).nullable()
val type = reference("type_id",DictTypes).nullable() val type = reference("type_id",DictTypes).nullable()