Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion Keyboards/DataManager/LanguageDBManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ extension LanguageDBManager {
}

/// Returns the next three words in the `autocomplete_lexicon` that follow a given word.
/// Falls back to noun-based alphabetical autocompletions when the lexicon returns no results.
///
/// - Parameters
/// - word: the word that autosuggestions should be returned for.
Expand All @@ -260,9 +261,52 @@ extension LanguageDBManager {
let outputCols = ["word"]
let args = ["\(word.lowercased())%"]

return queryDBRows(
let lexiconResults = queryDBRows(
query: autocompletionsQuery, outputCols: outputCols, args: StatementArguments(args)
)

// If the lexicon has results, return them; otherwise fall back to noun-based completions.
if !lexiconResults.isEmpty, !lexiconResults[0].isEmpty {
return lexiconResults
}

return queryNounAutocompletions(word: word)
}

/// Returns up to three alphabetically-ordered words from the nouns table that start with the given prefix.
/// Searches across all singular (key) columns defined in the language's data contract numbers section.
///
/// - Parameters
/// - word: the prefix to match against noun columns.
func queryNounAutocompletions(word: String) -> [String] {
let language = getControllerLanguageAbbr()
let contract = ContractManager.shared.loadContract(language: language)

guard let numbers = contract.numbers, !numbers.isEmpty else {
return [""]
}

// Use all singular (key) columns from the numbers contract.
let singularColumns = Array(numbers.keys)
let prefix = word.lowercased()

// Build a UNION query across all singular columns so we get a deduplicated,
// alphabetically sorted list of up to 3 matching nouns.
let unionParts = singularColumns.map { col in
"SELECT `\(col)` AS word FROM nouns WHERE LOWER(`\(col)`) LIKE ?"
}
let unionQuery = """
SELECT DISTINCT word
FROM (\(unionParts.joined(separator: " UNION ALL ")))
WHERE word IS NOT NULL AND word != ''
ORDER BY word COLLATE NOCASE ASC
LIMIT 3
"""

// One `prefix%` argument per UNION part.
let args = StatementArguments(Array(repeating: "\(prefix)%", count: singularColumns.count))

return queryDBRows(query: unionQuery, outputCols: ["word"], args: args)
}

/// Query the suggestion of word in `autosuggestions`.
Expand Down
Loading