261 lines
12 KiB
Kotlin
261 lines
12 KiB
Kotlin
package database.table
|
|
|
|
import database.data.Messagebank
|
|
import database.dbFunctions
|
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook
|
|
import org.tinylog.Logger
|
|
import java.sql.Connection
|
|
import java.util.function.Consumer
|
|
|
|
class Table_Messagebank(connection: Connection) : dbFunctions<Messagebank>("messagebank", connection, listOf("index", "Description", "Language", "ANN_ID", "Voice_Type", "Message_Detail", "Message_TAGS")) {
|
|
override fun Create() {
|
|
val tabledefinition = "CREATE TABLE IF NOT EXISTS ${super.dbName} (" +
|
|
"`index` INT AUTO_INCREMENT PRIMARY KEY," +
|
|
"Description VARCHAR(512) NOT NULL," + // Description of the message
|
|
"Language VARCHAR(45) NOT NULL," + // Language of the message
|
|
"ANN_ID INT NOT NULL," + // ANN ID of the message
|
|
"Voice_Type VARCHAR(45) NOT NULL," + // Voice type of the message
|
|
"Message_Detail VARCHAR(1024) NOT NULL," + // Full message text
|
|
"Message_TAGS VARCHAR(1024)" + // Comma-separated tags for the message
|
|
")"
|
|
super.Create(tabledefinition)
|
|
}
|
|
|
|
override fun Get(cbOK: Consumer<Unit>?, cbFail: Consumer<String>?) {
|
|
List.clear()
|
|
try {
|
|
val statement = connection.createStatement()
|
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
|
while (resultSet?.next() == true) {
|
|
val messagebank = Messagebank(
|
|
resultSet.getLong("index").toUInt(),
|
|
resultSet.getString("Description"),
|
|
resultSet.getString("Language"),
|
|
resultSet.getInt("ANN_ID").toUInt(),
|
|
resultSet.getString("Voice_Type"),
|
|
resultSet.getString("Message_Detail"),
|
|
resultSet.getString("Message_TAGS")
|
|
)
|
|
|
|
List.add(messagebank)
|
|
}
|
|
cbOK?.accept(Unit)
|
|
} catch (e: Exception) {
|
|
Logger.error("Error fetching ${super.dbName} : ${e.message}" as Any)
|
|
cbFail?.accept("Error fetching ${super.dbName} : ${e.message}")
|
|
}
|
|
}
|
|
|
|
override fun Add(data: Messagebank): Boolean {
|
|
try {
|
|
val statement =
|
|
connection.prepareStatement("INSERT INTO ${super.dbName} (Description, Language, ANN_ID, Voice_Type, Message_Detail, Message_TAGS) VALUES (?, ?, ?, ?, ?, ?)")
|
|
statement?.setString(1, data.Description)
|
|
statement?.setString(2, data.Language)
|
|
statement?.setInt(3, data.ANN_ID.toInt())
|
|
statement?.setString(4, data.Voice_Type)
|
|
statement?.setString(5, data.Message_Detail)
|
|
statement?.setString(6, data.Message_TAGS)
|
|
val rowsAffected = statement?.executeUpdate()
|
|
if (rowsAffected != null && rowsAffected > 0) {
|
|
Logger.info("Messagebank added: ${data.Description}" as Any)
|
|
return true
|
|
} else {
|
|
Logger.warn("No messagebank entry added for: ${data.Description}" as Any)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error adding messagebank entry: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun AddAll(data: ArrayList<Messagebank>): Boolean {
|
|
try {
|
|
connection.autoCommit = false
|
|
val sql =
|
|
"INSERT INTO ${super.dbName} (Description, Language, ANN_ID, Voice_Type, Message_Detail, Message_TAGS) VALUES (?, ?, ?, ?, ?, ?)"
|
|
val statement = connection.prepareStatement(sql)
|
|
for (mb in data) {
|
|
statement.setString(1, mb.Description)
|
|
statement.setString(2, mb.Language)
|
|
statement.setInt(3, mb.ANN_ID.toInt())
|
|
statement.setString(4, mb.Voice_Type)
|
|
statement.setString(5, mb.Message_Detail)
|
|
statement.setString(6, mb.Message_TAGS)
|
|
statement.addBatch()
|
|
}
|
|
statement.executeBatch()
|
|
connection.commit()
|
|
Logger.info("Bulk messagebank insert successful: ${data.size} entries" as Any)
|
|
connection.autoCommit = true
|
|
return true
|
|
} catch (e: Exception) {
|
|
Logger.error("Error adding messagebank entries: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun UpdateByIndex(index: Int, data: Messagebank): Boolean {
|
|
try {
|
|
val statement =
|
|
connection.prepareStatement("UPDATE ${super.dbName} SET Description = ?, Language = ?, ANN_ID = ?, Voice_Type = ?, Message_Detail = ?, Message_TAGS = ? WHERE `index` = ?")
|
|
statement?.setString(1, data.Description)
|
|
statement?.setString(2, data.Language)
|
|
statement?.setInt(3, data.ANN_ID.toInt())
|
|
statement?.setString(4, data.Voice_Type)
|
|
statement?.setString(5, data.Message_Detail)
|
|
statement?.setString(6, data.Message_TAGS)
|
|
statement?.setLong(7, index.toLong())
|
|
val rowsAffected = statement?.executeUpdate()
|
|
if (rowsAffected != null && rowsAffected > 0) {
|
|
Logger.info("Messagebank updated at index $index: ${data.Description}" as Any)
|
|
return true
|
|
} else {
|
|
Logger.warn("No messagebank entry updated at index $index for: ${data.Description}" as Any)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error updating messagebank entry at index $index: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun Resort(): Boolean {
|
|
try {
|
|
val statement = connection.createStatement()
|
|
val tempdb_name = "temp_${super.dbName}"
|
|
// use a temporary table to reorder the index
|
|
statement?.executeUpdate("CREATE TABLE IF NOT EXISTS $tempdb_name LIKE ${super.dbName}")
|
|
statement?.executeUpdate("TRUNCATE TABLE $tempdb_name")
|
|
statement?.executeUpdate("INSERT INTO $tempdb_name (Description, Language, ANN_ID, Voice_Type, Message_Detail, Message_TAGS) SELECT Description, Language, ANN_ID, Voice_Type, Message_Detail, Message_TAGS FROM ${super.dbName} ORDER BY ANN_ID ")
|
|
statement?.executeUpdate("TRUNCATE TABLE ${super.dbName}")
|
|
statement?.executeUpdate("INSERT INTO ${super.dbName} (Description, Language, ANN_ID, Voice_Type, Message_Detail, Message_TAGS) SELECT Description, Language, ANN_ID, Voice_Type, Message_Detail, Message_TAGS FROM $tempdb_name")
|
|
statement?.executeUpdate("DROP TABLE $tempdb_name")
|
|
Logger.info("${super.dbName} table resorted by Description" as Any)
|
|
// reload the local list
|
|
Get()
|
|
return true
|
|
} catch (e: Exception) {
|
|
Logger.error("Error resorting ${super.dbName} table by Description: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun Import_XLSX(workbook: XSSFWorkbook): Boolean {
|
|
try {
|
|
// check if there is sheet named "Messagebank"
|
|
val sheet =
|
|
workbook.getSheet("Messagebank") ?: throw Exception("No sheet named 'Messagebank' found")
|
|
// check if the sheet contains header named "Index", "Description", "Language", "ANN_ID", "Voice_Type", "Message_Detail", "Message_TAGS"
|
|
val headerRow = sheet.getRow(0) ?: throw Exception("No header row found")
|
|
val headers =
|
|
arrayOf(
|
|
"Index",
|
|
"Description",
|
|
"Language",
|
|
"ANN_ID",
|
|
"Voice_Type",
|
|
"Message_Detail",
|
|
"Message_TAGS"
|
|
)
|
|
for ((colIndex, header) in headers.withIndex()) {
|
|
val cell = headerRow.getCell(colIndex) ?: throw Exception("Header '$header' not found")
|
|
if (cell.stringCellValue != header) throw Exception("Header '$header' not found")
|
|
}
|
|
// clear existing messagebank
|
|
Clear()
|
|
// read each row and insert into database
|
|
val _messagebankList = ArrayList<Messagebank>()
|
|
for (rowIndex in 1..sheet.lastRowNum) {
|
|
val row = sheet.getRow(rowIndex) ?: continue
|
|
val description = row.getCell(1)?.stringCellValue ?: continue
|
|
val language = row.getCell(2)?.stringCellValue ?: continue
|
|
val annId = row.getCell(3)?.stringCellValue?.toUIntOrNull() ?: continue
|
|
val voiceType = row.getCell(4)?.stringCellValue ?: continue
|
|
val messageDetail = row.getCell(5)?.stringCellValue ?: continue
|
|
val messageTags = row.getCell(6)?.stringCellValue ?: continue
|
|
val messagebank =
|
|
Messagebank(0u, description, language, annId, voiceType, messageDetail, messageTags)
|
|
_messagebankList.add(messagebank)
|
|
}
|
|
return AddAll(_messagebankList)
|
|
} catch (e: Exception) {
|
|
Logger.error { "Error importing Messagebank, Msg: ${e.message}" }
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun Export_XLSX(): XSSFWorkbook? {
|
|
try {
|
|
val statement = connection.createStatement()
|
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
|
val workbook = XSSFWorkbook()
|
|
val sheet = workbook.createSheet("Messagebank")
|
|
val headerRow = sheet.createRow(0)
|
|
val headers =
|
|
arrayOf(
|
|
"Index",
|
|
"Description",
|
|
"Language",
|
|
"ANN_ID",
|
|
"Voice_Type",
|
|
"Message_Detail",
|
|
"Message_TAGS"
|
|
)
|
|
for ((colIndex, header) in headers.withIndex()) {
|
|
val cell = headerRow.createCell(colIndex)
|
|
cell.setCellValue(header)
|
|
}
|
|
var rowIndex = 1
|
|
while (resultSet?.next() == true) {
|
|
val row = sheet.createRow(rowIndex++)
|
|
row.createCell(0).setCellValue(resultSet.getString("index"))
|
|
row.createCell(1).setCellValue(resultSet.getString("Description"))
|
|
row.createCell(2).setCellValue(resultSet.getString("Language"))
|
|
row.createCell(3).setCellValue(resultSet.getString("ANN_ID"))
|
|
row.createCell(4).setCellValue(resultSet.getString("Voice_Type"))
|
|
row.createCell(5).setCellValue(resultSet.getString("Message_Detail"))
|
|
row.createCell(6).setCellValue(resultSet.getString("Message_TAGS"))
|
|
}
|
|
for (i in headers.indices) {
|
|
sheet.autoSizeColumn(i)
|
|
}
|
|
return workbook
|
|
} catch (e: Exception) {
|
|
Logger.error { "Error exporting Messagebank, Msg: ${e.message}" }
|
|
}
|
|
return null
|
|
}
|
|
|
|
/**
|
|
* Get all distinct message ID from messagebank
|
|
* @return a list of distinct ANN_ID sorted numerically
|
|
*/
|
|
fun Get_MessageID_List(): List<UInt> {
|
|
return List
|
|
.distinctBy { it.ANN_ID }
|
|
.map { it.ANN_ID }
|
|
.sorted()
|
|
}
|
|
|
|
// valid messagedetail is message_name [ann_id]
|
|
// so we need regex to check if messagedetail matches that format
|
|
private val messageDetailRegex = """^(.*?)\s*\[(\d+)]$""".toRegex()
|
|
|
|
/**
|
|
* Check if a messagebank entry exists based on messagedetail and languages
|
|
* @param messagedetail the messagedetail in format "message_name [ann_id]"
|
|
* @param languages a comma or semicolon separated string of languages to check
|
|
* @return true if the messagebank entry exists for all specified languages, false otherwise
|
|
*/
|
|
fun Messagebank_Exists(messagedetail: String, languages: String) : Boolean{
|
|
val match = messageDetailRegex.find(messagedetail)
|
|
val ll = languages.split(",",";").map { it.trim() }
|
|
if (match != null){
|
|
val msg = match.groupValues[1].trim()
|
|
val annid = match.groupValues[2].toUIntOrNull() ?: return false // kalau bukan number, return false
|
|
val ff = List.filter{ it.ANN_ID == annid && it.Description == msg }
|
|
return ll.all{ lang -> ff.any{ it.Language.equals(lang, ignoreCase = true) } }
|
|
}
|
|
return false
|
|
}
|
|
} |