Refactir SqliteDictionary
This commit is contained in:
parent
1b5c32c320
commit
a1a7567bd0
@ -3,10 +3,10 @@ package com.marvinelsen.willow.domain
|
|||||||
interface Dictionary {
|
interface Dictionary {
|
||||||
fun search(query: String, searchMode: SearchMode): List<DictionaryEntry>
|
fun search(query: String, searchMode: SearchMode): List<DictionaryEntry>
|
||||||
|
|
||||||
fun findWordsBeginning(entry: DictionaryEntry): List<DictionaryEntry>
|
fun findWordsBeginningWith(entry: DictionaryEntry): List<DictionaryEntry>
|
||||||
fun findWordsContaining(entry: DictionaryEntry): List<DictionaryEntry>
|
fun findWordsContaining(entry: DictionaryEntry): List<DictionaryEntry>
|
||||||
|
|
||||||
fun findCharacters(entry: DictionaryEntry): List<DictionaryEntry>
|
fun findCharactersOf(entry: DictionaryEntry): List<DictionaryEntry>
|
||||||
|
|
||||||
fun findSentencesContaining(entry: DictionaryEntry): List<Sentence>
|
fun findExampleSentencesFor(entry: DictionaryEntry): List<Sentence>
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ class SqliteDictionary(private val connection: Connection) : Dictionary {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val searchSegments = """
|
private val searchSegmentsRawSql = """
|
||||||
WITH cte(id, segment) AS (VALUES ?)
|
WITH cte(id, segment) AS (VALUES ?)
|
||||||
SELECT entry.traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, cedict_definitions, cross_straits_definitions, moe_definitions
|
SELECT entry.traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, cedict_definitions, cross_straits_definitions, moe_definitions
|
||||||
FROM entry INNER JOIN cte
|
FROM entry INNER JOIN cte
|
||||||
@ -66,7 +66,7 @@ class SqliteDictionary(private val connection: Connection) : Dictionary {
|
|||||||
ORDER BY cte.id
|
ORDER BY cte.id
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
||||||
private val findWordsBeginning: PreparedStatement by lazy {
|
private val findWordsBeginningPreparedStatement: PreparedStatement by lazy {
|
||||||
connection.prepareStatement(
|
connection.prepareStatement(
|
||||||
"""
|
"""
|
||||||
SELECT traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, cedict_definitions, cross_straits_definitions, moe_definitions
|
SELECT traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, cedict_definitions, cross_straits_definitions, moe_definitions
|
||||||
@ -77,7 +77,7 @@ class SqliteDictionary(private val connection: Connection) : Dictionary {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val findWordsContaining: PreparedStatement by lazy {
|
private val findWordsContainingPreparedStatement: PreparedStatement by lazy {
|
||||||
connection.prepareStatement(
|
connection.prepareStatement(
|
||||||
"""
|
"""
|
||||||
SELECT traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, cedict_definitions, cross_straits_definitions, moe_definitions
|
SELECT traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, cedict_definitions, cross_straits_definitions, moe_definitions
|
||||||
@ -88,16 +88,16 @@ class SqliteDictionary(private val connection: Connection) : Dictionary {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val findCharacters = """
|
private val findCharactersRawSql = """
|
||||||
WITH cte(id, character, syllable) AS (VALUES ?)
|
WITH cte(id, character, pinyin) AS (VALUES ?)
|
||||||
SELECT traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, cedict_definitions, cross_straits_definitions, moe_definitions
|
SELECT traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, cedict_definitions, cross_straits_definitions, moe_definitions
|
||||||
FROM entry INNER JOIN cte
|
FROM entry INNER JOIN cte
|
||||||
ON cte.character = entry.traditional
|
ON cte.character = entry.traditional
|
||||||
WHERE cte.syllable = entry.pinyin_with_tone_numbers
|
WHERE cte.pinyin = entry.pinyin_with_tone_numbers
|
||||||
ORDER BY cte.id
|
ORDER BY cte.id
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
||||||
private val findSentences: PreparedStatement by lazy {
|
private val findExampleSentencesPreparedStatement: PreparedStatement by lazy {
|
||||||
connection.prepareStatement(
|
connection.prepareStatement(
|
||||||
"""
|
"""
|
||||||
SELECT traditional, simplified
|
SELECT traditional, simplified
|
||||||
@ -112,67 +112,69 @@ class SqliteDictionary(private val connection: Connection) : Dictionary {
|
|||||||
SearchMode.SIMPLIFIED -> searchSimplified(query)
|
SearchMode.SIMPLIFIED -> searchSimplified(query)
|
||||||
SearchMode.TRADITIONAL -> searchTraditional(query)
|
SearchMode.TRADITIONAL -> searchTraditional(query)
|
||||||
SearchMode.PINYIN -> searchPinyin(query)
|
SearchMode.PINYIN -> searchPinyin(query)
|
||||||
SearchMode.SEGMENTS -> searchSegments(query)
|
SearchMode.SEGMENTS -> searchSegmentsOf(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun searchSimplified(query: String): List<DictionaryEntry> {
|
private fun searchSimplified(simplified: String): List<DictionaryEntry> {
|
||||||
searchSimplifiedPreparedStatement.setString(1, "$query*")
|
searchSimplifiedPreparedStatement.setString(1, "$simplified*")
|
||||||
|
|
||||||
val resultSet: ResultSet = searchSimplifiedPreparedStatement.executeQuery()
|
return searchSimplifiedPreparedStatement.executeQuery().use {
|
||||||
|
it.toListOfDictionaryEntries()
|
||||||
return resultSet.toListOfDictionaryEntries()
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun searchTraditional(query: String): List<DictionaryEntry> {
|
private fun searchTraditional(traditional: String): List<DictionaryEntry> {
|
||||||
searchTraditionalPreparedStatement.setString(1, "$query*")
|
searchTraditionalPreparedStatement.setString(1, "$traditional*")
|
||||||
|
|
||||||
val resultSet: ResultSet = searchTraditionalPreparedStatement.executeQuery()
|
return searchTraditionalPreparedStatement.executeQuery().use {
|
||||||
|
it.toListOfDictionaryEntries()
|
||||||
return resultSet.toListOfDictionaryEntries()
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun searchPinyin(query: String): List<DictionaryEntry> {
|
private fun searchPinyin(pinyin: String): List<DictionaryEntry> {
|
||||||
val sanitizedQuery = query.lowercase().replace(whitespaceRegex, "")
|
val sanitizedPinyin = pinyin.lowercase().replace(whitespaceRegex, "")
|
||||||
|
|
||||||
searchPinyinPreparedStatement.setString(1, "$sanitizedQuery*")
|
searchPinyinPreparedStatement.setString(1, "$sanitizedPinyin*")
|
||||||
searchPinyinPreparedStatement.setString(2, "$sanitizedQuery*")
|
searchPinyinPreparedStatement.setString(2, "$sanitizedPinyin*")
|
||||||
|
|
||||||
val resultSet: ResultSet = searchPinyinPreparedStatement.executeQuery()
|
return searchPinyinPreparedStatement.executeQuery().use { resultSet ->
|
||||||
|
resultSet.toListOfDictionaryEntries()
|
||||||
return resultSet.toListOfDictionaryEntries()
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun searchSegments(phrase: String): List<DictionaryEntry> {
|
private fun searchSegmentsOf(phrase: String): List<DictionaryEntry> {
|
||||||
val segments = segmentBs.segment(phrase, SegmentResultHandlers.word())
|
val segments = segmentBs.segment(phrase, SegmentResultHandlers.word())
|
||||||
|
|
||||||
val segmentsListString = segments
|
val segmentsListString = segments
|
||||||
.mapIndexed { index, s -> "($index, '$s')" }
|
.mapIndexed { index, segment -> "($index, '$segment')" }
|
||||||
.joinToString(",")
|
.joinToString(",")
|
||||||
|
|
||||||
val query = searchSegments.replace("?", segmentsListString)
|
val query = searchSegmentsRawSql.replace("?", segmentsListString)
|
||||||
|
|
||||||
val resultSet: ResultSet = connection.createStatement().executeQuery(query)
|
return connection.createStatement().use { statement ->
|
||||||
|
statement.executeQuery(query).use { resultSet ->
|
||||||
return resultSet.toListOfDictionaryEntries()
|
resultSet.toListOfDictionaryEntries()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun findWordsContaining(entry: DictionaryEntry): List<DictionaryEntry> {
|
override fun findWordsContaining(entry: DictionaryEntry): List<DictionaryEntry> {
|
||||||
findWordsContaining.setString(1, "_%${entry.traditional}%")
|
findWordsContainingPreparedStatement.setString(1, "_%${entry.traditional}%")
|
||||||
|
|
||||||
val resultSet: ResultSet = findWordsContaining.executeQuery()
|
return findWordsContainingPreparedStatement.executeQuery().use { resultSet ->
|
||||||
|
resultSet.toListOfDictionaryEntries()
|
||||||
return resultSet.toListOfDictionaryEntries()
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun findWordsBeginning(entry: DictionaryEntry): List<DictionaryEntry> {
|
override fun findWordsBeginningWith(entry: DictionaryEntry): List<DictionaryEntry> {
|
||||||
findWordsBeginning.setString(1, "${entry.traditional}?*")
|
findWordsBeginningPreparedStatement.setString(1, "${entry.traditional}?*")
|
||||||
|
|
||||||
val resultSet: ResultSet = findWordsBeginning.executeQuery()
|
return findWordsBeginningPreparedStatement.executeQuery().use { resultSet ->
|
||||||
|
resultSet.toListOfDictionaryEntries()
|
||||||
return resultSet.toListOfDictionaryEntries()
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun findCharacters(entry: DictionaryEntry): List<DictionaryEntry> {
|
override fun findCharactersOf(entry: DictionaryEntry): List<DictionaryEntry> {
|
||||||
val pinyinSyllablesWithToneNumbers = entry.pinyinWithToneNumbers
|
val pinyinSyllablesWithToneNumbers = entry.pinyinWithToneNumbers
|
||||||
.lowercase()
|
.lowercase()
|
||||||
.split(" ")
|
.split(" ")
|
||||||
@ -190,19 +192,21 @@ class SqliteDictionary(private val connection: Connection) : Dictionary {
|
|||||||
.mapIndexed { index, s -> "($index, '${s.first}', '${s.second}')" }
|
.mapIndexed { index, s -> "($index, '${s.first}', '${s.second}')" }
|
||||||
.joinToString(",")
|
.joinToString(",")
|
||||||
|
|
||||||
val query = findCharacters.replace("?", queryInput)
|
val query = findCharactersRawSql.replace("?", queryInput)
|
||||||
|
|
||||||
val resultSet: ResultSet = connection.createStatement().executeQuery(query)
|
return connection.createStatement().use { statement ->
|
||||||
|
statement.executeQuery(query).use { resultSet ->
|
||||||
return resultSet.toListOfDictionaryEntries()
|
resultSet.toListOfDictionaryEntries()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun findSentencesContaining(entry: DictionaryEntry): List<Sentence> {
|
override fun findExampleSentencesFor(entry: DictionaryEntry): List<Sentence> {
|
||||||
findSentences.setString(1, "_%${entry.traditional}%")
|
findExampleSentencesPreparedStatement.setString(1, "_%${entry.traditional}%")
|
||||||
|
|
||||||
val resultSet: ResultSet = findSentences.executeQuery()
|
return findExampleSentencesPreparedStatement.executeQuery().use { resultSet ->
|
||||||
|
resultSet.toListOfSentences()
|
||||||
return resultSet.toListOfSentences()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,10 +223,8 @@ private fun ResultSet.toDictionaryEntry() = DictionaryEntry(
|
|||||||
)
|
)
|
||||||
|
|
||||||
private fun ResultSet.toListOfDictionaryEntries() = buildList {
|
private fun ResultSet.toListOfDictionaryEntries() = buildList {
|
||||||
this@toListOfDictionaryEntries.use {
|
while (this@toListOfDictionaryEntries.next()) {
|
||||||
while (it.next()) {
|
add(this@toListOfDictionaryEntries.toDictionaryEntry())
|
||||||
add(it.toDictionaryEntry())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,9 +234,7 @@ private fun ResultSet.toSentence() = Sentence(
|
|||||||
)
|
)
|
||||||
|
|
||||||
private fun ResultSet.toListOfSentences() = buildList {
|
private fun ResultSet.toListOfSentences() = buildList {
|
||||||
this@toListOfSentences.use {
|
while (this@toListOfSentences.next()) {
|
||||||
while (it.next()) {
|
add(this@toListOfSentences.toSentence())
|
||||||
add(it.toSentence())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,6 @@ class FindCharacterService(private val dictionary: Dictionary) : Service<Observa
|
|||||||
override fun createTask() = task {
|
override fun createTask() = task {
|
||||||
if (!this::entry.isInitialized) error("Entry is not initialized")
|
if (!this::entry.isInitialized) error("Entry is not initialized")
|
||||||
|
|
||||||
FXCollections.observableList(dictionary.findCharacters(entry.toDomain()).map { it.toFx() })
|
FXCollections.observableList(dictionary.findCharactersOf(entry.toDomain()).map { it.toFx() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,6 @@ class FindSentencesService(private val dictionary: Dictionary) : Service<Observa
|
|||||||
override fun createTask() = task {
|
override fun createTask() = task {
|
||||||
if (!this::entry.isInitialized) error("Entry is not initialized")
|
if (!this::entry.isInitialized) error("Entry is not initialized")
|
||||||
|
|
||||||
FXCollections.observableList(dictionary.findSentencesContaining(entry.toDomain()).map { it.toFx() })
|
FXCollections.observableList(dictionary.findExampleSentencesFor(entry.toDomain()).map { it.toFx() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,6 @@ class FindWordsBeginningService(private val dictionary: Dictionary) : Service<Ob
|
|||||||
override fun createTask() = task {
|
override fun createTask() = task {
|
||||||
if (!this::entry.isInitialized) error("Entry is not initialized")
|
if (!this::entry.isInitialized) error("Entry is not initialized")
|
||||||
|
|
||||||
FXCollections.observableList(dictionary.findWordsBeginning(entry.toDomain()).map { it.toFx() })
|
FXCollections.observableList(dictionary.findWordsBeginningWith(entry.toDomain()).map { it.toFx() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user