2387 lines
127 KiB
Kotlin
2387 lines
127 KiB
Kotlin
package database
|
|
|
|
import codes.Somecodes.Companion.ValiDateForLogHtml
|
|
import codes.Somecodes.Companion.toJsonString
|
|
import content.Category
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.runBlocking
|
|
import kotlinx.coroutines.withContext
|
|
import max_channel
|
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook
|
|
import org.tinylog.Logger
|
|
import java.sql.Connection
|
|
import java.sql.DriverManager
|
|
import java.util.function.Consumer
|
|
|
|
/**
|
|
* A class to manage a connection to a MariaDB database.
|
|
*
|
|
* @property address The address of the MariaDB server.
|
|
* @property port The port number of the MariaDB server.
|
|
* @property dbName The name of the database to connect to.
|
|
* @property username The username for the database connection.
|
|
* @property password The password for the database connection.
|
|
*/
|
|
@Suppress("unused", "SqlSourceToSinkFlow")
|
|
class MariaDB(
|
|
address: String = "localhost",
|
|
port: Int = 3306,
|
|
dbName: String = "aas",
|
|
username: String = "admin",
|
|
password: String = "admin"
|
|
) {
|
|
var connected: Boolean = false
|
|
|
|
|
|
lateinit var connection: Connection
|
|
lateinit var soundDB: dbFunctions<Soundbank>
|
|
lateinit var messageDB: dbFunctions<Messagebank>
|
|
lateinit var languageDB: dbFunctions<LanguageLink>
|
|
lateinit var scheduleDB: dbFunctions<ScheduleBank>
|
|
lateinit var broadcastDB: dbFunctions<BroadcastZones>
|
|
lateinit var queuetableDB: dbFunctions<QueueTable>
|
|
lateinit var queuepagingDB: dbFunctions<QueuePaging>
|
|
lateinit var soundchannelDB: dbFunctions<SoundChannel>
|
|
lateinit var logDB: dbFunctions<Log>
|
|
lateinit var userDB: dbFunctions<UserDB>
|
|
|
|
companion object {
|
|
fun ValidDate(date: String): Boolean {
|
|
// Check if the date is in the format DD/MM/YYYY
|
|
val regex = Regex("""^\d{2}/\d{2}/\d{4}$""")
|
|
return regex.matches(date)
|
|
}
|
|
|
|
fun ValidTime(time: String): Boolean {
|
|
// Check if the time is in the format HH:MM:SS
|
|
val regex = Regex("""^\d{2}:\d{2}:\d{2}$""")
|
|
return regex.matches(time)
|
|
}
|
|
|
|
|
|
/**
|
|
* Convert SoundbankList, MessagebankList, LanguageLinkList, or SchedulebankList to a JSON String.
|
|
* @param list The ArrayList to convert to a String.
|
|
* @return A JSON String representation of the ArrayList.
|
|
*/
|
|
fun <T> ArrayListtoString(list: ArrayList<T>): String {
|
|
return try {
|
|
toJsonString(list)
|
|
} catch (e: Exception) {
|
|
Logger.error("Error converting list to JSON: ${e.message}" as Any)
|
|
"[]"
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
init {
|
|
try {
|
|
connection =
|
|
DriverManager.getConnection(
|
|
"jdbc:mysql://$address:$port/$dbName?sslMode=REQUIRED",
|
|
username,
|
|
password
|
|
) as Connection
|
|
Logger.info("Connected to MySQL" as Any)
|
|
connected = true
|
|
|
|
soundDB = object : dbFunctions<Soundbank>("soundbank", connection) {
|
|
override fun Create() {
|
|
val tabledefinition = "CREATE TABLE IF NOT EXISTS ${super.dbName} (" +
|
|
"`index` INT AUTO_INCREMENT PRIMARY KEY," +
|
|
"Description VARCHAR(1024) NOT NULL," + // Description of the soundbank
|
|
"TAG VARCHAR(45) NOT NULL," + // TAG of the soundbank
|
|
"Category VARCHAR(45) NOT NULL," + // Category of the soundbank
|
|
"Language VARCHAR(45) NOT NULL," + // Language of the soundbank
|
|
"VoiceType VARCHAR(45) NOT NULL," + // VoiceType of the soundbank
|
|
"Path VARCHAR(1024) NOT NULL" + // Path to the sound file
|
|
")"
|
|
super.Create(tabledefinition)
|
|
}
|
|
|
|
override fun Get() {
|
|
List.clear()
|
|
try {
|
|
val statement = connection.createStatement()
|
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName} ORDER BY Category, Language, VoiceType, TAG")
|
|
while (resultSet?.next() == true) {
|
|
val soundbank = Soundbank(
|
|
resultSet.getLong("index").toUInt(),
|
|
resultSet.getString("Description"),
|
|
resultSet.getString("TAG"),
|
|
resultSet.getString("Category"),
|
|
resultSet.getString("Language"),
|
|
resultSet.getString("VoiceType"),
|
|
resultSet.getString("Path")
|
|
)
|
|
List.add(soundbank)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error fetching soundbanks: ${e.message}" as Any)
|
|
}
|
|
}
|
|
|
|
fun Get_By_Index(index: Int): Soundbank? {
|
|
try {
|
|
val statement = connection.createStatement()
|
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName} WHERE `index` = $index")
|
|
if (resultSet?.next() == true) {
|
|
return Soundbank(
|
|
resultSet.getLong("index").toUInt(),
|
|
resultSet.getString("Description"),
|
|
resultSet.getString("TAG"),
|
|
resultSet.getString("Category"),
|
|
resultSet.getString("Language"),
|
|
resultSet.getString("VoiceType"),
|
|
resultSet.getString("Path")
|
|
)
|
|
}
|
|
} catch (_: Exception) {
|
|
Logger.error("Error finding ${super.dbName} with index $index" as Any)
|
|
}
|
|
return null
|
|
}
|
|
|
|
override fun Add(data: Soundbank): Boolean {
|
|
try {
|
|
val statement =
|
|
connection.prepareStatement("INSERT INTO ${super.dbName} (Description, TAG, Category, Language, VoiceType, Path) VALUES (?, ?, ?, ?, ?, ?)")
|
|
statement?.setString(1, data.Description)
|
|
statement?.setString(2, data.TAG)
|
|
statement?.setString(3, data.Category)
|
|
statement?.setString(4, data.Language)
|
|
statement?.setString(5, data.VoiceType)
|
|
statement?.setString(6, data.Path)
|
|
val rowsAffected = statement?.executeUpdate()
|
|
if (rowsAffected != null && rowsAffected > 0) {
|
|
Logger.info("Soundbank added: ${data.Description}" as Any)
|
|
return true
|
|
} else {
|
|
Logger.warn("No soundbank entry added for: ${data.Description}" as Any)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error adding soundbank entry: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun AddAll(data: ArrayList<Soundbank>): Boolean {
|
|
// use mysql bulk insert
|
|
try {
|
|
connection.autoCommit = false
|
|
val sql =
|
|
"INSERT INTO ${super.dbName} (Description, TAG, Category, Language, VoiceType, Path) VALUES (?, ?, ?, ?, ?, ?)"
|
|
val statement = connection.prepareStatement(sql)
|
|
for (sb in data) {
|
|
statement.setString(1, sb.Description)
|
|
statement.setString(2, sb.TAG)
|
|
statement.setString(3, sb.Category)
|
|
statement.setString(4, sb.Language)
|
|
statement.setString(5, sb.VoiceType)
|
|
statement.setString(6, sb.Path)
|
|
statement.addBatch()
|
|
}
|
|
statement.executeBatch()
|
|
connection.commit()
|
|
Logger.info("Bulk soundbank insert successful: ${data.size} entries" as Any)
|
|
connection.autoCommit = true
|
|
return true
|
|
} catch (e: Exception) {
|
|
Logger.error("Error adding soundbank entries: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun UpdateByIndex(index: Int, data: Soundbank): Boolean {
|
|
try {
|
|
val statement =
|
|
connection.prepareStatement("UPDATE ${super.dbName} SET Description = ?, TAG = ?, Category = ?, Language = ?, VoiceType = ?, Path = ? WHERE `index` = ?")
|
|
statement?.setString(1, data.Description)
|
|
statement?.setString(2, data.TAG)
|
|
statement?.setString(3, data.Category)
|
|
statement?.setString(4, data.Language)
|
|
statement?.setString(5, data.VoiceType)
|
|
statement?.setString(6, data.Path)
|
|
statement?.setLong(7, index.toLong())
|
|
val rowsAffected = statement?.executeUpdate()
|
|
if (rowsAffected != null && rowsAffected > 0) {
|
|
Logger.info("Soundbank updated at index $index: ${data.Description}" as Any)
|
|
return true
|
|
} else {
|
|
Logger.warn("No soundbank entry updated at index $index for: ${data.Description}" as Any)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error updating soundbank 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, TAG, Category, Language, VoiceType, Path) SELECT Description, TAG, Category, Language, VoiceType, Path FROM ${super.dbName} ORDER BY Category, Language, VoiceType, TAG ")
|
|
statement?.executeUpdate("TRUNCATE TABLE ${super.dbName}")
|
|
statement?.executeUpdate("INSERT INTO ${super.dbName} (Description, TAG, Category, Language, VoiceType, Path) SELECT Description, TAG, Category, Language, VoiceType, Path 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 "Soundbank"
|
|
val sheet =
|
|
workbook.getSheet("Soundbank") ?: throw Exception("No sheet named 'Soundbank' found")
|
|
// check if the sheet contains header named "index", "Description", "TAG", "Category", "Language", "VoiceType", "Path"
|
|
val headerRow = sheet.getRow(0) ?: throw Exception("No header row found")
|
|
val headers =
|
|
arrayOf("Index", "Description", "TAG", "Category", "Language", "VoiceType", "Path")
|
|
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 soundbank
|
|
Clear()
|
|
// read each row and insert into database
|
|
val _soundbankList = ArrayList<Soundbank>()
|
|
for (rowIndex in 1..sheet.lastRowNum) {
|
|
val row = sheet.getRow(rowIndex) ?: continue
|
|
val description = row.getCell(1)?.stringCellValue ?: continue
|
|
val tag = row.getCell(2)?.stringCellValue ?: continue
|
|
val category = row.getCell(3)?.stringCellValue ?: continue
|
|
val language = row.getCell(4)?.stringCellValue ?: continue
|
|
val voiceType = row.getCell(5)?.stringCellValue ?: continue
|
|
val path = row.getCell(6)?.stringCellValue ?: continue
|
|
val soundbank = Soundbank(0u, description, tag, category, language, voiceType, path)
|
|
_soundbankList.add(soundbank)
|
|
}
|
|
return AddAll(_soundbankList)
|
|
} catch (e: Exception) {
|
|
Logger.error { "Error importing Soundbank, 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("Soundbank")
|
|
val headerRow = sheet.createRow(0)
|
|
val headers =
|
|
arrayOf("Index", "Description", "TAG", "Category", "Language", "VoiceType", "Path")
|
|
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("TAG"))
|
|
row.createCell(3).setCellValue(resultSet.getString("Category"))
|
|
row.createCell(4).setCellValue(resultSet.getString("Language"))
|
|
row.createCell(5).setCellValue(resultSet.getString("VoiceType"))
|
|
row.createCell(6).setCellValue(resultSet.getString("Path"))
|
|
}
|
|
for (i in 0 until headers.size) {
|
|
sheet.autoSizeColumn(i)
|
|
}
|
|
return workbook
|
|
} catch (e: Exception) {
|
|
Logger.error { "Error exporting Soundbank, Msg: ${e.message}" }
|
|
}
|
|
return null
|
|
}
|
|
}
|
|
|
|
messageDB = object : dbFunctions<Messagebank>("messagebank", connection) {
|
|
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() {
|
|
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)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error fetching ${super.dbName} : ${e.message}" as Any)
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
}
|
|
|
|
languageDB = object : dbFunctions<LanguageLink>("languagelinking", connection) {
|
|
override fun Create() {
|
|
val tabledefinition = "CREATE TABLE IF NOT EXISTS ${super.dbName} (" +
|
|
"`index` INT AUTO_INCREMENT PRIMARY KEY," +
|
|
"TAG VARCHAR(45) NOT NULL," + // Language tag (e.g., EN, FR)
|
|
"Language VARCHAR(128) NOT NULL" + // Full language name (e.g., English, French)
|
|
")"
|
|
|
|
super.Create(tabledefinition)
|
|
}
|
|
|
|
override fun Get() {
|
|
List.clear()
|
|
try {
|
|
val statement = connection.createStatement()
|
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
|
while (resultSet?.next() == true) {
|
|
val languageLink = LanguageLink(
|
|
resultSet.getLong("index").toUInt(),
|
|
resultSet.getString("TAG"),
|
|
resultSet.getString("Language")
|
|
)
|
|
List.add(languageLink)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error fetching ${super.dbName} : ${e.message}" as Any)
|
|
}
|
|
}
|
|
|
|
override fun Add(data: LanguageLink): Boolean {
|
|
try {
|
|
val statement = connection.prepareStatement("INSERT INTO ${super.dbName} (TAG, Language) VALUES (?, ?)")
|
|
statement.setString(1, data.TAG)
|
|
statement.setString(2, data.Language)
|
|
val rowsAffected = statement.executeUpdate()
|
|
if (rowsAffected > 0) {
|
|
Logger.info("Language link added: ${data.TAG} -> ${data.Language}" as Any)
|
|
return true
|
|
} else {
|
|
Logger.warn("No language link entry added for: ${data.TAG} -> ${data.Language}" as Any)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error adding language link entry: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun AddAll(data: ArrayList<LanguageLink>): Boolean {
|
|
try {
|
|
connection.autoCommit = false
|
|
val sql = "INSERT INTO ${super.dbName} (TAG, Language) VALUES (?, ?)"
|
|
val statement = connection.prepareStatement(sql)
|
|
for (ll in List) {
|
|
statement.setString(1, ll.TAG)
|
|
statement.setString(2, ll.Language)
|
|
statement.addBatch()
|
|
}
|
|
statement.executeBatch()
|
|
connection.commit()
|
|
Logger.info("Bulk languagelinking insert successful: ${List.size} entries" as Any)
|
|
connection.autoCommit = true
|
|
return true
|
|
} catch (e: Exception) {
|
|
Logger.error("Error adding languagelinking entries: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun UpdateByIndex(index: Int, data: LanguageLink): Boolean {
|
|
try {
|
|
val statement =
|
|
connection.prepareStatement("UPDATE ${super.dbName} SET TAG = ?, Language = ? WHERE `index` = ?")
|
|
statement?.setString(1, data.TAG)
|
|
statement?.setString(2, data.Language)
|
|
statement?.setLong(3, index.toLong())
|
|
val rowsAffected = statement?.executeUpdate()
|
|
if (rowsAffected != null && rowsAffected > 0) {
|
|
Logger.info("Language link updated at index $index: ${data.TAG} -> ${data.Language}" as Any)
|
|
return true
|
|
} else {
|
|
Logger.warn("No language link entry updated at index $index for: ${data.TAG} -> ${data.Language}" as Any)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error updating language link 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 (TAG, Language) SELECT TAG, Language FROM ${super.dbName} ORDER BY TAG")
|
|
statement?.executeUpdate("TRUNCATE TABLE ${super.dbName}")
|
|
statement?.executeUpdate("INSERT INTO ${super.dbName} (TAG, Language) SELECT TAG, Language FROM $tempdb_name")
|
|
statement?.executeUpdate("DROP TABLE $tempdb_name")
|
|
Logger.info("${super.dbName} table resorted by TAG" as Any)
|
|
// reload the local list
|
|
Get()
|
|
return true
|
|
} catch (e: Exception) {
|
|
Logger.error("Error resorting ${super.dbName} table by TAG: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun Import_XLSX(workbook: XSSFWorkbook): Boolean {
|
|
try {
|
|
val sheet =
|
|
workbook.getSheet("LanguageLink") ?: throw Exception("No sheet named 'LanguageLink' found")
|
|
val headerRow = sheet.getRow(0) ?: throw Exception("No header row found")
|
|
val headers = arrayOf("Index", "TAG", "Language")
|
|
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 languagelink
|
|
Clear()
|
|
// read each row and insert into database
|
|
val _languageLinkList = ArrayList<LanguageLink>()
|
|
for (rowIndex in 1..sheet.lastRowNum) {
|
|
val row = sheet.getRow(rowIndex) ?: continue
|
|
val tag = row.getCell(1)?.stringCellValue ?: continue
|
|
val language = row.getCell(2)?.stringCellValue ?: continue
|
|
val languageLink = LanguageLink(0u, tag, language)
|
|
_languageLinkList.add(languageLink)
|
|
}
|
|
return AddAll(_languageLinkList)
|
|
} catch (e: Exception) {
|
|
Logger.error { "Error importing LanguageLink, 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("LanguageLink")
|
|
val headerRow = sheet.createRow(0)
|
|
val headers = arrayOf("Index", "TAG", "Language")
|
|
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("TAG"))
|
|
row.createCell(2).setCellValue(resultSet.getString("Language"))
|
|
}
|
|
for (i in headers.indices) {
|
|
sheet.autoSizeColumn(i)
|
|
}
|
|
return workbook
|
|
} catch (e: Exception) {
|
|
Logger.error { "Error exporting languagelinking, Msg: ${e.message}" }
|
|
}
|
|
return null
|
|
}
|
|
|
|
}
|
|
|
|
scheduleDB = object : dbFunctions<ScheduleBank>("schedulebank", connection) {
|
|
override fun Create() {
|
|
val tabledefinition = "CREATE TABLE IF NOT EXISTS ${super.dbName} (" +
|
|
"`index` INT AUTO_INCREMENT PRIMARY KEY," +
|
|
"Description VARCHAR(128) NOT NULL," + // Description of the schedule
|
|
"Day VARCHAR(255) NOT NULL," + // Day in format DD/MM/YYYY
|
|
"Time VARCHAR(20) NOT NULL," + // Time in format HH:MM:SS
|
|
"Soundpath VARCHAR(512) NOT NULL," + // Path to the sound file
|
|
"`Repeat` TINYINT UNSIGNED NOT NULL," + // Repeat type (0=Once, 1=Daily, 2=Weekly, 3=Monthly, 4=Yearly)
|
|
"Enable BOOLEAN NOT NULL," + // Enable or disable the schedule
|
|
"BroadcastZones TEXT NOT NULL," + // Comma-separated list of broadcast zones
|
|
"Language VARCHAR(45) NOT NULL" + // Language code (e.g., EN, FR)
|
|
")"
|
|
super.Create(tabledefinition)
|
|
}
|
|
|
|
override fun Get() {
|
|
List.clear()
|
|
try {
|
|
val statement = connection.createStatement()
|
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
|
while (resultSet?.next() == true) {
|
|
val schedulebank = ScheduleBank(
|
|
resultSet.getLong("index").toUInt(),
|
|
resultSet.getString("Description"),
|
|
resultSet.getString("Day"),
|
|
resultSet.getString("Time"),
|
|
resultSet.getString("Soundpath"),
|
|
resultSet.getInt("Repeat").toUByte(),
|
|
resultSet.getBoolean("Enable"),
|
|
resultSet.getString("BroadcastZones"),
|
|
resultSet.getString("Language")
|
|
)
|
|
List.add(schedulebank)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error fetching ${super.dbName}: ${e.message}" as Any)
|
|
}
|
|
}
|
|
|
|
override fun Add(data: ScheduleBank): Boolean {
|
|
if (!ValidDate(data.Day)) {
|
|
Logger.error("Error adding schedulebank entry: Invalid date format ${data.Day}" as Any)
|
|
return false
|
|
}
|
|
if (!ValidTime(data.Time)) {
|
|
Logger.error("Error adding schedulebank entry: Invalid time format ${data.Time}" as Any)
|
|
return false
|
|
}
|
|
try {
|
|
val statement =
|
|
connection.prepareStatement("INSERT INTO ${super.dbName} (Description, Day, Time, Soundpath, Repeat, Enable, BroadcastZones, Language) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")
|
|
statement?.setString(1, data.Description)
|
|
statement?.setString(2, data.Day)
|
|
statement?.setString(3, data.Time)
|
|
statement?.setString(4, data.Soundpath)
|
|
statement?.setInt(5, data.Repeat.toInt())
|
|
statement?.setBoolean(6, data.Enable)
|
|
statement?.setString(7, data.BroadcastZones)
|
|
statement?.setString(8, data.Language)
|
|
val rowsAffected = statement?.executeUpdate()
|
|
if (rowsAffected != null && rowsAffected > 0) {
|
|
Logger.info("Schedulebank added: ${data.Description}" as Any)
|
|
return true
|
|
} else {
|
|
Logger.warn("No schedulebank entry added for: ${data.Description}" as Any)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error adding schedulebank entry: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun AddAll(data: ArrayList<ScheduleBank>): Boolean {
|
|
try {
|
|
connection.autoCommit = false
|
|
val sql =
|
|
"INSERT INTO ${super.dbName} (Description, Day, Time, Soundpath, Repeat, Enable, BroadcastZones, Language) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
|
|
val statement = connection.prepareStatement(sql)
|
|
for (sb in data) {
|
|
if (!ValidDate(sb.Day) || !ValidTime(sb.Time)) {
|
|
Logger.error("Invalid date or time format for schedulebank: ${sb.Description}" as Any)
|
|
continue
|
|
}
|
|
statement.setString(1, sb.Description)
|
|
statement.setString(2, sb.Day)
|
|
statement.setString(3, sb.Time)
|
|
statement.setString(4, sb.Soundpath)
|
|
statement.setInt(5, sb.Repeat.toInt())
|
|
statement.setBoolean(6, sb.Enable)
|
|
statement.setString(7, sb.BroadcastZones)
|
|
statement.setString(8, sb.Language)
|
|
statement.addBatch()
|
|
}
|
|
statement.executeBatch()
|
|
connection.commit()
|
|
Logger.info("Bulk schedulebank insert successful: ${data.size} entries" as Any)
|
|
connection.autoCommit = true
|
|
return true
|
|
} catch (e: Exception) {
|
|
Logger.error("Error adding schedulebank entries: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
|
|
override fun UpdateByIndex(index: Int, data: ScheduleBank): Boolean {
|
|
if (!ValidDate(data.Day)) {
|
|
Logger.error("Error updating schedulebank entry: Invalid date format ${data.Day}" as Any)
|
|
return false
|
|
}
|
|
if (!ValidTime(data.Time)) {
|
|
Logger.error("Error updating schedulebank entry: Invalid time format ${data.Time}" as Any)
|
|
return false
|
|
}
|
|
try {
|
|
val statement =
|
|
connection.prepareStatement("UPDATE ${super.dbName} SET Description = ?, Day = ?, Time = ?, Soundpath = ?, Repeat = ?, Enable = ?, BroadcastZones = ?, Language = ? WHERE `index` = ?")
|
|
statement?.setString(1, data.Description)
|
|
statement?.setString(2, data.Day)
|
|
statement?.setString(3, data.Time)
|
|
statement?.setString(4, data.Soundpath)
|
|
statement?.setInt(5, data.Repeat.toInt())
|
|
statement?.setBoolean(6, data.Enable)
|
|
statement?.setString(7, data.BroadcastZones)
|
|
statement?.setString(8, data.Language)
|
|
statement?.setLong(9, index.toLong())
|
|
val rowsAffected = statement?.executeUpdate()
|
|
if (rowsAffected != null && rowsAffected > 0) {
|
|
Logger.info("Schedulebank updated at index $index: ${data.Description}" as Any)
|
|
return true
|
|
} else {
|
|
Logger.warn("No schedulebank entry updated at index $index for: ${data.Description}" as Any)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error updating schedulebank 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, Day, Time, Soundpath, Repeat, Enable, BroadcastZones, Language) SELECT Description, Day, Time, Soundpath, Repeat, Enable, BroadcastZones, Language FROM ${super.dbName} ORDER BY Day , Time ")
|
|
statement?.executeUpdate("TRUNCATE TABLE ${super.dbName}")
|
|
statement?.executeUpdate("INSERT INTO ${super.dbName} (Description, Day, Time, Soundpath, Repeat, Enable, BroadcastZones, Language) SELECT Description, Day, Time, Soundpath, Repeat, Enable, BroadcastZones, Language FROM $tempdb_name")
|
|
statement?.executeUpdate("DROP TABLE $tempdb_name")
|
|
Logger.info("${super.dbName} table resorted by Day and Time" as Any)
|
|
// reload the local list
|
|
Get()
|
|
return true
|
|
} catch (e: Exception) {
|
|
Logger.error("Error resorting ${super.dbName} table by Day and Time: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun Import_XLSX(workbook: XSSFWorkbook): Boolean {
|
|
try {
|
|
val sheet =
|
|
workbook.getSheet("Schedulebank") ?: throw Exception("No sheet named 'Schedulebank' found")
|
|
val headerRow = sheet.getRow(0) ?: throw Exception("No header row found")
|
|
val headers = arrayOf(
|
|
"Index",
|
|
"Description",
|
|
"Day",
|
|
"Time",
|
|
"Soundpath",
|
|
"Repeat",
|
|
"Enable",
|
|
"BroadcastZones",
|
|
"Language"
|
|
)
|
|
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 schedulebank
|
|
Clear()
|
|
// read each row and insert into database
|
|
val _schedulebankList = ArrayList<ScheduleBank>()
|
|
for (rowIndex in 1..sheet.lastRowNum) {
|
|
val row = sheet.getRow(rowIndex) ?: continue
|
|
val description = row.getCell(1)?.stringCellValue ?: continue
|
|
val day = row.getCell(2)?.stringCellValue ?: continue
|
|
val time = row.getCell(3)?.stringCellValue ?: continue
|
|
val soundpath = row.getCell(4)?.stringCellValue ?: continue
|
|
val repeat = row.getCell(5)?.stringCellValue?.toUByteOrNull() ?: continue
|
|
val enable = row.getCell(6)?.stringCellValue?.toBooleanStrictOrNull() ?: continue
|
|
val broadcastZones = row.getCell(7)?.stringCellValue ?: continue
|
|
val language = row.getCell(8)?.stringCellValue ?: continue
|
|
val schedulebank =
|
|
ScheduleBank(
|
|
0u,
|
|
description,
|
|
day,
|
|
time,
|
|
soundpath,
|
|
repeat,
|
|
enable,
|
|
broadcastZones,
|
|
language
|
|
)
|
|
_schedulebankList.add(schedulebank)
|
|
}
|
|
|
|
return scheduleDB.AddAll(_schedulebankList)
|
|
} catch (e: Exception) {
|
|
Logger.error { "Error importing Schedulebank, 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("Schedulebank")
|
|
val headerRow = sheet.createRow(0)
|
|
val headers = arrayOf(
|
|
"Index",
|
|
"Description",
|
|
"Day",
|
|
"Time",
|
|
"Soundpath",
|
|
"Repeat",
|
|
"Enable",
|
|
"BroadcastZones",
|
|
"Language"
|
|
)
|
|
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("Day"))
|
|
row.createCell(3).setCellValue(resultSet.getString("Time"))
|
|
row.createCell(4).setCellValue(resultSet.getString("Soundpath"))
|
|
row.createCell(5).setCellValue(resultSet.getString("Repeat"))
|
|
row.createCell(6).setCellValue(resultSet.getString("Enable"))
|
|
row.createCell(7).setCellValue(resultSet.getString("BroadcastZones"))
|
|
row.createCell(8).setCellValue(resultSet.getString("Language"))
|
|
}
|
|
for (i in headers.indices) {
|
|
sheet.autoSizeColumn(i)
|
|
}
|
|
return workbook
|
|
} catch (e: Exception) {
|
|
Logger.error { "Error exporting Schedulebank, Msg: ${e.message}" }
|
|
}
|
|
return null
|
|
}
|
|
|
|
}
|
|
|
|
broadcastDB = object : dbFunctions<BroadcastZones>("broadcastzones", connection) {
|
|
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 broadcast zone
|
|
"SoundChannel VARCHAR(45) NOT NULL," + // Sound channel of the broadcast zone
|
|
"id VARCHAR(45) NOT NULL," + // Box of the broadcast zone
|
|
"bp VARCHAR(45) NOT NULL" + // Relay of the broadcast zone
|
|
")"
|
|
super.Create(tabledefinition)
|
|
}
|
|
|
|
override fun Get() {
|
|
List.clear()
|
|
try {
|
|
val statement = connection.createStatement()
|
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
|
while (resultSet?.next() == true) {
|
|
val zone = BroadcastZones(
|
|
resultSet.getLong("index").toUInt(),
|
|
resultSet.getString("description"),
|
|
resultSet.getString("SoundChannel"),
|
|
resultSet.getString("id"),
|
|
resultSet.getString("bp")
|
|
)
|
|
List.add(zone)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error fetching ${super.dbName} : ${e.message}" as Any)
|
|
}
|
|
}
|
|
|
|
override fun Add(data: BroadcastZones): Boolean {
|
|
try {
|
|
val statement =
|
|
connection.prepareStatement("INSERT INTO ${super.dbName} (description, SoundChannel, id, bp) VALUES (?, ?, ?, ?)")
|
|
statement?.setString(1, data.description)
|
|
statement?.setString(2, data.SoundChannel)
|
|
statement?.setString(3, data.id)
|
|
statement?.setString(4, data.bp)
|
|
val rowsAffected = statement?.executeUpdate()
|
|
if (rowsAffected != null && rowsAffected > 0) {
|
|
Logger.info("Broadcast zone added: ${data.description}" as Any)
|
|
return true
|
|
} else {
|
|
Logger.warn("No broadcast zone entry added for: ${data.description}" as Any)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error adding broadcast zone entry: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun AddAll(data: ArrayList<BroadcastZones>): Boolean {
|
|
try {
|
|
connection.autoCommit = false
|
|
val sql =
|
|
"INSERT INTO ${super.dbName} (description, SoundChannel, id, bp) VALUES (?, ?, ?, ?)"
|
|
val statement = connection.prepareStatement(sql)
|
|
for (bz in data) {
|
|
statement.setString(1, bz.description)
|
|
statement.setString(2, bz.SoundChannel)
|
|
statement.setString(3, bz.id)
|
|
statement.setString(4, bz.bp)
|
|
statement.addBatch()
|
|
}
|
|
statement.executeBatch()
|
|
connection.commit()
|
|
Logger.info("Bulk ${super.dbName} insert successful: ${data.size} entries" as Any)
|
|
connection.autoCommit = true
|
|
return true
|
|
} catch (e: Exception) {
|
|
Logger.error("Error adding ${super.dbName} entries: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun UpdateByIndex(index: Int, data: BroadcastZones): Boolean {
|
|
try {
|
|
val statement =
|
|
connection.prepareStatement("UPDATE ${super.dbName} SET description = ?, SoundChannel = ?, id = ?, bp = ? WHERE `index` = ?")
|
|
statement?.setString(1, data.description)
|
|
statement?.setString(2, data.SoundChannel)
|
|
statement?.setString(3, data.id)
|
|
statement?.setString(4, data.bp)
|
|
statement?.setLong(5, index.toLong())
|
|
val rowsAffected = statement?.executeUpdate()
|
|
if (rowsAffected != null && rowsAffected > 0) {
|
|
Logger.info("Broadcast zone updated at index $index: ${data.description}" as Any)
|
|
return true
|
|
} else {
|
|
Logger.warn("No broadcast zone entry updated at index $index for: ${data.description}" as Any)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error updating broadcast zone 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, SoundChannel, id, bp) SELECT description, SoundChannel, id, bp FROM ${super.dbName} ORDER BY description ")
|
|
statement?.executeUpdate("TRUNCATE TABLE ${super.dbName}")
|
|
statement?.executeUpdate("INSERT INTO ${super.dbName} (description, SoundChannel, id, bp) SELECT description, SoundChannel, id, bp 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 {
|
|
val sheet = workbook.getSheet("BroadcastZones")
|
|
?: throw Exception("No sheet named 'BroadcastZones' found")
|
|
val headerRow = sheet.getRow(0) ?: throw Exception("No header row found")
|
|
val headers = arrayOf("Index", "description", "SoundChannel", "id", "bp")
|
|
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 broadcast_zones
|
|
Clear()
|
|
// read each row and insert into database
|
|
val _broadcastZonesList = ArrayList<BroadcastZones>()
|
|
for (rowIndex in 1..sheet.lastRowNum) {
|
|
val row = sheet.getRow(rowIndex) ?: continue
|
|
val description = row.getCell(1)?.stringCellValue ?: continue
|
|
val soundChannel = row.getCell(2)?.stringCellValue ?: continue
|
|
val id = row.getCell(3)?.stringCellValue ?: continue
|
|
val bp = row.getCell(4)?.stringCellValue ?: continue
|
|
val broadcastZone = BroadcastZones(0u, description, soundChannel, id, bp)
|
|
_broadcastZonesList.add(broadcastZone)
|
|
}
|
|
return AddAll(_broadcastZonesList)
|
|
} catch (e: Exception) {
|
|
Logger.error { "Error importing BroadcastZones, 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("BroadcastZones")
|
|
val headerRow = sheet.createRow(0)
|
|
val headers = arrayOf("Index", "description", "SoundChannel", "id", "bp")
|
|
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("SoundChannel"))
|
|
row.createCell(3).setCellValue(resultSet.getString("id"))
|
|
row.createCell(4).setCellValue(resultSet.getString("bp"))
|
|
}
|
|
for (i in headers.indices) {
|
|
sheet.autoSizeColumn(i)
|
|
}
|
|
return workbook
|
|
} catch (e: Exception) {
|
|
Logger.error { "Error exporting BroadcastZones, Msg: ${e.message}" }
|
|
}
|
|
return null
|
|
}
|
|
|
|
}
|
|
|
|
queuetableDB = object : dbFunctions<QueueTable>("queue_table", connection) {
|
|
override fun Create() {
|
|
val tabledefinition = "CREATE TABLE IF NOT EXISTS ${super.dbName} (" +
|
|
"`index` INT AUTO_INCREMENT PRIMARY KEY," +
|
|
"Date_Time VARCHAR(45) NOT NULL," + // Date and time of the entry
|
|
"Source VARCHAR(45) NOT NULL," + // Source of the entry
|
|
"Type VARCHAR(45) NOT NULL," + // Type of the entry
|
|
"Message VARCHAR(1024) NOT NULL," + // Message content
|
|
"SB_TAGS VARCHAR(1024)," + // Comma-separated soundbank tags
|
|
"BroadcastZones VARCHAR(1024) NOT NULL," + // Comma-separated broadcast zones
|
|
"`Repeat` INT NOT NULL," + // Number of repeats
|
|
"Language VARCHAR(100) NOT NULL" + // Language of the message
|
|
")"
|
|
super.Create(tabledefinition)
|
|
}
|
|
|
|
override fun Get() {
|
|
List.clear()
|
|
val queueList = ArrayList<QueueTable>()
|
|
try {
|
|
val statement = connection.createStatement()
|
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
|
while (resultSet?.next() == true) {
|
|
val queueTable = QueueTable(
|
|
resultSet.getLong("index").toUInt(),
|
|
resultSet.getString("Date_Time"),
|
|
resultSet.getString("Source"),
|
|
resultSet.getString("Type"),
|
|
resultSet.getString("Message"),
|
|
resultSet.getString("SB_TAGS"),
|
|
resultSet.getString("BroadcastZones"),
|
|
resultSet.getInt("Repeat").toUInt(),
|
|
resultSet.getString("Language")
|
|
)
|
|
queueList.add(queueTable)
|
|
List.add(queueTable)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error fetching ${super.dbName} : ${e.message}" as Any)
|
|
}
|
|
}
|
|
|
|
override fun Add(data: QueueTable): Boolean {
|
|
try {
|
|
val statement = connection.prepareStatement(
|
|
"INSERT INTO ${super.dbName} (`Date_Time`, `Source`, `Type`, `Message`, `SB_TAGS`, `BroadcastZones`, `Repeat`, `Language`) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
|
|
)
|
|
statement?.setString(1, data.Date_Time)
|
|
statement?.setString(2, data.Source)
|
|
statement?.setString(3, data.Type)
|
|
statement?.setString(4, data.Message)
|
|
statement?.setString(5, data.SB_TAGS)
|
|
statement?.setString(6, data.BroadcastZones)
|
|
statement?.setInt(7, data.Repeat.toInt())
|
|
statement?.setString(8, data.Language)
|
|
val rowsAffected = statement?.executeUpdate()
|
|
if (rowsAffected != null && rowsAffected > 0) {
|
|
Logger.info("QueueTable added Source=${data.Source} Type=${data.Type} Message=${data.Message}, Languages=${data.Language} Variables=${data.SB_TAGS}, BroadcastZones=${data.BroadcastZones}" as Any)
|
|
return true
|
|
} else {
|
|
Logger.warn("No QueueTable entry added for: ${data.Message}" as Any)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error adding QueueTable entry: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun AddAll(data: ArrayList<QueueTable>): Boolean {
|
|
try {
|
|
connection.autoCommit = false
|
|
val sql =
|
|
"INSERT INTO ${super.dbName} (`Date_Time`, `Source`, `Type`, `Message`, `SB_TAGS`, `BroadcastZones`, `Repeat`, `Language`) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
|
|
val statement = connection.prepareStatement(sql)
|
|
for (qt in data) {
|
|
statement.setString(1, qt.Date_Time)
|
|
statement.setString(2, qt.Source)
|
|
statement.setString(3, qt.Type)
|
|
statement.setString(4, qt.Message)
|
|
statement.setString(5, qt.SB_TAGS)
|
|
statement.setString(6, qt.BroadcastZones)
|
|
statement.setInt(7, qt.Repeat.toInt())
|
|
statement.setString(8, qt.Language)
|
|
statement.addBatch()
|
|
}
|
|
statement.executeBatch()
|
|
connection.commit()
|
|
Logger.info("Bulk QueueTable insert successful: ${data.size} entries" as Any)
|
|
connection.autoCommit = true
|
|
return true
|
|
} catch (e: Exception) {
|
|
Logger.error("Error adding QueueTable entries: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun UpdateByIndex(index: Int, data: QueueTable): Boolean {
|
|
throw Exception("Update not supported")
|
|
}
|
|
|
|
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 (Date_Time, Source, Type, Message, SB_TAGS, BroadcastZones, `Repeat`, Language) SELECT Date_Time, Source, Type, Message, SB_TAGS, BroadcastZones, `Repeat`, Language FROM ${super.dbName} ORDER BY `index` ")
|
|
statement?.executeUpdate("TRUNCATE TABLE ${super.dbName}")
|
|
statement?.executeUpdate("INSERT INTO ${super.dbName} (Date_Time, Source, Type, Message, SB_TAGS, BroadcastZones, `Repeat`, Language) SELECT Date_Time, Source, Type, Message, SB_TAGS, BroadcastZones, `Repeat`, Language FROM $tempdb_name")
|
|
statement?.executeUpdate("DROP TABLE $tempdb_name")
|
|
Logger.info("${super.dbName} table resorted by index" as Any)
|
|
// reload the local list
|
|
Get()
|
|
return true
|
|
} catch (e: Exception) {
|
|
Logger.error("Error resorting ${super.dbName} table by index: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun Import_XLSX(workbook: XSSFWorkbook): Boolean {
|
|
throw Exception("Import XLSX not supported for QueueTable")
|
|
}
|
|
|
|
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("QueueTable")
|
|
val headerRow = sheet.createRow(0)
|
|
val headers = arrayOf(
|
|
"Index",
|
|
"Date_Time",
|
|
"Source",
|
|
"Type",
|
|
"Message",
|
|
"SB_TAGS",
|
|
"BroadcastZones",
|
|
"Repeat",
|
|
"Language"
|
|
)
|
|
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("Date_Time"))
|
|
row.createCell(2).setCellValue(resultSet.getString("Source"))
|
|
row.createCell(3).setCellValue(resultSet.getString("Type"))
|
|
row.createCell(4).setCellValue(resultSet.getString("Message"))
|
|
row.createCell(5).setCellValue(resultSet.getString("SB_TAGS"))
|
|
row.createCell(6).setCellValue(resultSet.getString("BroadcastZones"))
|
|
row.createCell(7).setCellValue(resultSet.getString("Repeat"))
|
|
row.createCell(8).setCellValue(resultSet.getString("Language"))
|
|
}
|
|
for (i in headers.indices) {
|
|
sheet.autoSizeColumn(i)
|
|
}
|
|
return workbook
|
|
} catch (e: Exception) {
|
|
Logger.error { "Error exporting QueueTable, Msg: ${e.message}" }
|
|
}
|
|
return null
|
|
}
|
|
|
|
}
|
|
|
|
queuepagingDB = object : dbFunctions<QueuePaging>("queue_paging", connection) {
|
|
override fun Create() {
|
|
val tabledefinition ="CREATE TABLE IF NOT EXISTS ${super.dbName} (" +
|
|
"`index` INT AUTO_INCREMENT PRIMARY KEY," +
|
|
"Date_Time VARCHAR(45) NOT NULL," + // Date and time of the entry
|
|
"Source VARCHAR(45) NOT NULL," + // Source of the entry
|
|
"Type VARCHAR(45) NOT NULL," + // Type of the entry
|
|
"Message VARCHAR(1024) NOT NULL," + // Message content
|
|
"BroadcastZones VARCHAR(1024)" + // Comma-separated soundbank tags
|
|
")"
|
|
super.Create(tabledefinition)
|
|
}
|
|
|
|
override fun Get() {
|
|
List.clear()
|
|
val queueList = ArrayList<QueuePaging>()
|
|
try {
|
|
val statement = connection.createStatement()
|
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
|
while (resultSet?.next() == true) {
|
|
val queuePaging = QueuePaging(
|
|
resultSet.getLong("index").toUInt(),
|
|
resultSet.getString("Date_Time"),
|
|
resultSet.getString("Source"),
|
|
resultSet.getString("Type"),
|
|
resultSet.getString("Message"),
|
|
resultSet.getString("BroadcastZones"),
|
|
)
|
|
queueList.add(queuePaging)
|
|
List.add(queuePaging)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error fetching ${super.dbName} : ${e.message}" as Any)
|
|
}
|
|
}
|
|
|
|
override fun Add(data: QueuePaging): Boolean {
|
|
try {
|
|
val statement = connection.prepareStatement(
|
|
"INSERT INTO ${super.dbName} (Date_Time, Source, Type, Message, BroadcastZones) VALUES (?, ?, ?, ?, ?)"
|
|
)
|
|
statement?.setString(1, data.Date_Time)
|
|
statement?.setString(2, data.Source)
|
|
statement?.setString(3, data.Type)
|
|
statement?.setString(4, data.Message)
|
|
|
|
statement?.setString(5, data.BroadcastZones)
|
|
val rowsAffected = statement?.executeUpdate()
|
|
if (rowsAffected != null && rowsAffected > 0) {
|
|
Logger.info("QueuePaging added: ${data.Message}" as Any)
|
|
return true
|
|
} else {
|
|
Logger.warn("No QueuePaging entry added for: ${data.Message}" as Any)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error adding QueuePaging entry: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun AddAll(data: ArrayList<QueuePaging>): Boolean {
|
|
return try {
|
|
connection.autoCommit = false
|
|
val sql =
|
|
"INSERT INTO ${super.dbName} (Date_Time, Source, Type, Message, BroadcastZones) VALUES (?, ?, ?, ?, ?)"
|
|
val statement = connection.prepareStatement(sql)
|
|
for (qp in data) {
|
|
statement.setString(1, qp.Date_Time)
|
|
statement.setString(2, qp.Source)
|
|
statement.setString(3, qp.Type)
|
|
statement.setString(4, qp.Message)
|
|
statement.setString(5, qp.BroadcastZones)
|
|
statement.addBatch()
|
|
}
|
|
statement.executeBatch()
|
|
connection.commit()
|
|
Logger.info("Bulk QueuePaging insert successful: ${data.size} entries" as Any)
|
|
connection.autoCommit = true
|
|
true
|
|
} catch (e: Exception) {
|
|
Logger.error("Error adding QueuePaging entries: ${e.message}" as Any)
|
|
false
|
|
}
|
|
}
|
|
|
|
override fun UpdateByIndex(index: Int, data: QueuePaging): Boolean {
|
|
throw Exception("Update not supported")
|
|
}
|
|
|
|
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 (Date_Time, Source, Type, Message, BroadcastZones) SELECT Date_Time, Source, Type, Message, BroadcastZones FROM ${super.dbName} ")
|
|
statement?.executeUpdate("TRUNCATE TABLE ${super.dbName}")
|
|
statement?.executeUpdate("INSERT INTO ${super.dbName} (Date_Time, Source, Type, Message, BroadcastZones) SELECT Date_Time, Source, Type, Message, BroadcastZones FROM $tempdb_name")
|
|
statement?.executeUpdate("DROP TABLE $tempdb_name")
|
|
Logger.info("${super.dbName} table resorted by index" as Any)
|
|
// reload the local list
|
|
Get()
|
|
return true
|
|
} catch (e: Exception) {
|
|
Logger.error("Error resorting ${super.dbName} table by index: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun Import_XLSX(workbook: XSSFWorkbook): Boolean {
|
|
throw Exception("Importing QueuePaging from XLSX is not supported")
|
|
}
|
|
|
|
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("QueuePaging")
|
|
val headerRow = sheet.createRow(0)
|
|
val headers = arrayOf("Index", "Date_Time", "Source", "Type", "Message", "BroadcastZones")
|
|
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("Date_Time"))
|
|
row.createCell(2).setCellValue(resultSet.getString("Source"))
|
|
row.createCell(3).setCellValue(resultSet.getString("Type"))
|
|
row.createCell(4).setCellValue(resultSet.getString("Message"))
|
|
row.createCell(5).setCellValue(resultSet.getString("BroadcastZones"))
|
|
}
|
|
for (i in headers.indices) {
|
|
sheet.autoSizeColumn(i)
|
|
}
|
|
return workbook
|
|
} catch (e: Exception) {
|
|
Logger.error { "Error exporting QueuePaging, Msg: ${e.message}" }
|
|
}
|
|
return null
|
|
}
|
|
|
|
}
|
|
|
|
soundchannelDB = object : dbFunctions<SoundChannel>("soundchannel", connection) {
|
|
override fun Create() {
|
|
val tableDefinition = "CREATE TABLE IF NOT EXISTS ${super.dbName} (" +
|
|
"`index` INT AUTO_INCREMENT PRIMARY KEY," +
|
|
"channel VARCHAR(45) NOT NULL," + // Channel 01 to Channel 64
|
|
"ip VARCHAR(45) NOT NULL" + // IP address or empty string
|
|
")"
|
|
|
|
super.Create(tableDefinition)
|
|
|
|
// Check if table is empty, if so, populate with 64 channels
|
|
try {
|
|
val statement = connection.createStatement()
|
|
val countResult = statement?.executeQuery("SELECT COUNT(*) AS count FROM ${super.dbName}")
|
|
if (countResult?.next() == true) {
|
|
val count = countResult.getInt("count")
|
|
if (count < max_channel) {
|
|
Logger.info("SoundChannel table is empty, populating with default channels" as Any)
|
|
Clear()
|
|
}
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error creating SoundChannel table: ${e.message}" as Any)
|
|
}
|
|
}
|
|
|
|
override fun Get() {
|
|
List.clear()
|
|
try {
|
|
val statement = connection.createStatement()
|
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName} ORDER BY `index` ")
|
|
while (resultSet?.next() == true) {
|
|
val channel = SoundChannel(
|
|
resultSet.getLong("index").toUInt(),
|
|
resultSet.getString("channel"),
|
|
resultSet.getString("ip")
|
|
)
|
|
List.add(channel)
|
|
}
|
|
|
|
} catch (e: Exception) {
|
|
Logger.error("Error fetching sound channels: ${e.message}" as Any)
|
|
}
|
|
}
|
|
|
|
override fun Add(data: SoundChannel): Boolean {
|
|
try {
|
|
val statement = connection.prepareStatement("UPDATE ${super.dbName} SET ip = ? WHERE channel = ?")
|
|
statement?.setString(1, data.ip)
|
|
statement?.setString(2, data.channel)
|
|
val rowsAffected = statement?.executeUpdate()
|
|
if (rowsAffected != null && rowsAffected > 0) {
|
|
Logger.info("SoundChannel updated: ${data.channel} -> ${data.ip}" as Any)
|
|
return true
|
|
} else {
|
|
Logger.warn("No SoundChannel entry updated for: ${data.channel} -> ${data.ip}" as Any)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error updating SoundChannel entry: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun AddAll(data: ArrayList<SoundChannel>): Boolean {
|
|
return try {
|
|
connection.autoCommit = false
|
|
val sql = "UPDATE ${super.dbName} SET ip = ? WHERE channel = ?"
|
|
val statement = connection.prepareStatement(sql)
|
|
for (sc in data) {
|
|
statement.setString(1, sc.ip)
|
|
statement.setString(2, sc.channel)
|
|
statement.addBatch()
|
|
}
|
|
statement.executeBatch()
|
|
connection.commit()
|
|
Logger.info("Bulk SoundChannel update successful: ${data.size} entries" as Any)
|
|
connection.autoCommit = true
|
|
true
|
|
} catch (e: Exception) {
|
|
Logger.error("Error updating SoundChannel entries: ${e.message}" as Any)
|
|
false
|
|
}
|
|
}
|
|
|
|
override fun UpdateByIndex(index: Int, data: SoundChannel): Boolean {
|
|
try {
|
|
val statement =
|
|
connection.prepareStatement("UPDATE ${super.dbName} SET channel = ?, ip = ? WHERE `index` = ?")
|
|
statement?.setString(1, data.channel)
|
|
statement?.setString(2, data.ip)
|
|
statement?.setLong(3, index.toLong())
|
|
val rowsAffected = statement?.executeUpdate()
|
|
if (rowsAffected != null && rowsAffected > 0) {
|
|
Logger.info("SoundChannel updated at index $index: ${data.channel} -> ${data.ip}" as Any)
|
|
return true
|
|
} else {
|
|
Logger.warn("No SoundChannel entry updated at index $index for: ${data.channel} -> ${data.ip}" as Any)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error updating SoundChannel 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 (channel, ip) SELECT channel, ip FROM ${super.dbName} ORDER BY `index` ")
|
|
statement?.executeUpdate("TRUNCATE TABLE ${super.dbName}")
|
|
statement?.executeUpdate("INSERT INTO ${super.dbName} (channel, ip) SELECT channel, ip FROM $tempdb_name")
|
|
statement?.executeUpdate("DROP TABLE $tempdb_name")
|
|
Logger.info("${super.dbName} table resorted by index" as Any)
|
|
// reload the local list
|
|
Get()
|
|
return true
|
|
} catch (e: Exception) {
|
|
Logger.error("Error resorting ${super.dbName} table by index: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun Clear(): Boolean {
|
|
try {
|
|
val statement = connection.createStatement()
|
|
// use TRUNCATE to reset auto increment index
|
|
statement?.executeUpdate("TRUNCATE TABLE ${super.dbName}")
|
|
Logger.info("${super.dbName} table cleared" as Any)
|
|
List.clear()
|
|
// create new rows from 1 to 64 with description "Channel 1" to "Channel 64" and empty ip
|
|
for (i in 1..max_channel) {
|
|
val channel = String.format("Channel %d", i)
|
|
val insertStatement =
|
|
connection.prepareStatement("INSERT INTO ${super.dbName} (channel, ip) VALUES (?, ?)")
|
|
insertStatement?.setString(1, channel)
|
|
insertStatement?.setString(2, "")
|
|
insertStatement?.executeUpdate()
|
|
}
|
|
return true
|
|
} catch (e: Exception) {
|
|
Logger.error("Error clearing soundchannel table: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun Import_XLSX(workbook: XSSFWorkbook): Boolean {
|
|
try {
|
|
val sheet =
|
|
workbook.getSheet("SoundChannel") ?: throw Exception("No sheet named 'SoundChannel' found")
|
|
val headerRow = sheet.getRow(0) ?: throw Exception("No header row found")
|
|
val headers = arrayOf("Index", "channel", "ip")
|
|
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 soundchannel
|
|
Clear()
|
|
// read each row and insert into database
|
|
val _soundChannelList = ArrayList<SoundChannel>()
|
|
for (rowIndex in 1..sheet.lastRowNum) {
|
|
val row = sheet.getRow(rowIndex) ?: continue
|
|
val channel = row.getCell(1)?.stringCellValue ?: continue
|
|
val ip = row.getCell(2)?.stringCellValue ?: continue
|
|
val soundChannel = SoundChannel(0u, channel, ip)
|
|
_soundChannelList.add(soundChannel)
|
|
}
|
|
// Bulk update IPs for channels
|
|
var success = true
|
|
for (sc in _soundChannelList) {
|
|
if (!soundchannelDB.Add(sc)) {
|
|
success = false
|
|
}
|
|
}
|
|
return success
|
|
} catch (e: Exception) {
|
|
Logger.error { "Error importing SoundChannel, 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("SoundChannel")
|
|
val headerRow = sheet.createRow(0)
|
|
val headers = arrayOf("Index", "channel", "ip")
|
|
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("channel"))
|
|
row.createCell(2).setCellValue(resultSet.getString("ip"))
|
|
}
|
|
for (i in headers.indices) {
|
|
sheet.autoSizeColumn(i)
|
|
}
|
|
return workbook
|
|
} catch (e: Exception) {
|
|
Logger.error { "Error exporting SoundChannel, Msg: ${e.message}" }
|
|
}
|
|
return null
|
|
}
|
|
|
|
/**
|
|
* Delete entry by index, but only clear the IP field
|
|
* @param index The index of the entry to delete
|
|
* @return true if successful, false otherwise
|
|
*/
|
|
override fun DeleteByIndex(index: Int): Boolean {
|
|
try {
|
|
val statement = connection.prepareStatement("UPDATE ${super.dbName} SET ip = '' WHERE `index` = ?")
|
|
statement?.setLong(1, index.toLong())
|
|
val rowsAffected = statement?.executeUpdate()
|
|
if (rowsAffected != null && rowsAffected > 0) {
|
|
Logger.info("${super.dbName} IP cleared for index $index" as Any)
|
|
return true
|
|
} else {
|
|
Logger.warn("No ${super.dbName} entry cleared for index $index" as Any)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error clearing ${super.dbName} entry for index $index: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
}
|
|
|
|
logDB = object : dbFunctions<Log>("logs", connection) {
|
|
override fun Create() {
|
|
val tabledefinition = "CREATE TABLE IF NOT EXISTS ${super.dbName} (" +
|
|
"`index` INT AUTO_INCREMENT PRIMARY KEY," +
|
|
"datenya VARCHAR(20) NOT NULL," + // format DD/MM/YYYY
|
|
"timenya VARCHAR(20) NOT NULL," + // format HH:MM:SS
|
|
"machine VARCHAR(45) NOT NULL," +
|
|
"description TEXT NOT NULL" +
|
|
")"
|
|
|
|
super.Create(tabledefinition)
|
|
|
|
}
|
|
|
|
override fun Get() {
|
|
List.clear()
|
|
try {
|
|
val statement = connection.createStatement()
|
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
|
while (resultSet?.next() == true) {
|
|
val log = Log(
|
|
resultSet.getLong("index").toULong(),
|
|
resultSet.getString("datenya"),
|
|
resultSet.getString("timenya"),
|
|
resultSet.getString("machine"),
|
|
resultSet.getString("description")
|
|
)
|
|
List.add(log)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error fetching ${super.dbName}: ${e.message}" as Any)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
override fun Add(data: Log): Boolean {
|
|
try {
|
|
val statement =
|
|
connection.prepareStatement("INSERT INTO logs (datenya, timenya, machine, description) VALUES (?, ?, ?, ?)")
|
|
statement?.setString(1, data.datenya)
|
|
statement?.setString(2, data.timenya)
|
|
statement?.setString(3, data.machine)
|
|
statement?.setString(4, data.description)
|
|
val rowsAffected = statement?.executeUpdate()
|
|
if (rowsAffected != null && rowsAffected > 0) {
|
|
return true
|
|
} else {
|
|
Logger.warn{"Failed to add log entry : $data"}
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error{"Error adding log entry: ${e.message}"}
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun AddAll(data: ArrayList<Log>): Boolean {
|
|
return try {
|
|
connection.autoCommit = false
|
|
val sql = "INSERT INTO logs (datenya, timenya, machine, description) VALUES (?, ?, ?, ?)"
|
|
val statement = connection.prepareStatement(sql)
|
|
for (log in data) {
|
|
statement.setString(1, log.datenya)
|
|
statement.setString(2, log.timenya)
|
|
statement.setString(3, log.machine)
|
|
statement.setString(4, log.description)
|
|
statement.addBatch()
|
|
}
|
|
statement.executeBatch()
|
|
connection.commit()
|
|
Logger.info("Bulk log insert successful: ${data.size} entries" as Any)
|
|
connection.autoCommit = true
|
|
true
|
|
} catch (e: Exception) {
|
|
Logger.error("Error adding log entries: ${e.message}" as Any)
|
|
false
|
|
}
|
|
}
|
|
|
|
override fun UpdateByIndex(index: Int, data: Log): Boolean {
|
|
throw Exception("Update not supported")
|
|
}
|
|
|
|
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 (datenya, timenya, machine, description) " +
|
|
"SELECT datenya, timenya, machine, description FROM ${super.dbName} " +
|
|
"ORDER BY datenya , timenya , machine "
|
|
)
|
|
statement?.executeUpdate("TRUNCATE TABLE ${super.dbName}")
|
|
statement?.executeUpdate(
|
|
"INSERT INTO ${super.dbName} (datenya, timenya, machine, description) " +
|
|
"SELECT datenya, timenya, machine, description FROM $tempdb_name"
|
|
)
|
|
statement?.executeUpdate("DROP TABLE $tempdb_name")
|
|
Logger.info("${super.dbName} table resorted by datenya, timenya, machine" as Any)
|
|
// reload the local list
|
|
Get()
|
|
return true
|
|
} catch (e: Exception) {
|
|
Logger.error("Error resorting ${super.dbName} table by datenya, timenya, machine: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun Import_XLSX(workbook: XSSFWorkbook): Boolean {
|
|
throw Exception("Importing Logs from XLSX is not supported")
|
|
}
|
|
|
|
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("Log")
|
|
val headerRow = sheet.createRow(0)
|
|
val headers = arrayOf("Index", "datenya", "timenya", "machine", "description")
|
|
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("datenya"))
|
|
row.createCell(2).setCellValue(resultSet.getString("timenya"))
|
|
row.createCell(3).setCellValue(resultSet.getString("machine"))
|
|
row.createCell(4).setCellValue(resultSet.getString("description"))
|
|
}
|
|
for (i in headers.indices) {
|
|
sheet.autoSizeColumn(i)
|
|
}
|
|
return workbook
|
|
} catch (e: Exception) {
|
|
Logger.error { "Error exporting Log, Msg: ${e.message}" }
|
|
}
|
|
return null
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
userDB = object : dbFunctions<UserDB>("newuser", connection){
|
|
override fun Create() {
|
|
val tableDefinition = "CREATE TABLE IF NOT EXISTS ${super.dbName} (" +
|
|
"`index` INT AUTO_INCREMENT PRIMARY KEY," +
|
|
"username VARCHAR(100) NOT NULL," +
|
|
"password VARCHAR(100) NOT NULL," +
|
|
"location VARCHAR(100) NOT NULL," +
|
|
"airline_tags TEXT NOT NULL,"+ // Comma-separated soundbank tags
|
|
"city_tags TEXT NOT NULL,"+ // Comma-separated soundbank tags
|
|
"messagebank_ann_id TEXT NOT NULL,"+ // Comma-separated messagebank announcement index
|
|
"broadcastzones TEXT NOT NULL"+ // Comma-separated broadcast zones
|
|
")"
|
|
super.Create(tableDefinition)
|
|
}
|
|
|
|
override fun Get() {
|
|
List.clear()
|
|
try {
|
|
val statement = connection.createStatement()
|
|
val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}")
|
|
while (resultSet?.next() == true) {
|
|
val user = UserDB(
|
|
resultSet.getLong("index").toUInt(),
|
|
resultSet.getString("username"),
|
|
resultSet.getString("password"),
|
|
resultSet.getString("location"),
|
|
resultSet.getString("airline_tags"),
|
|
resultSet.getString("city_tags"),
|
|
resultSet.getString("messagebank_ann_id"),
|
|
resultSet.getString("broadcastzones")
|
|
)
|
|
List.add(user)
|
|
}
|
|
|
|
} catch (e: Exception) {
|
|
Logger.error("Error fetching users: ${e.message}" as Any)
|
|
}
|
|
}
|
|
|
|
override fun Add(data: UserDB): Boolean {
|
|
try {
|
|
val statement = connection.prepareStatement("INSERT INTO ${super.dbName} (username, password, location, airline_tags, city_tags, messagebank_ann_id, broadcastzones) VALUES (?, ?, ?, ?,?, ?, ?)")
|
|
statement?.setString(1, data.username)
|
|
statement?.setString(2, data.password)
|
|
statement?.setString(3, data.location)
|
|
statement?.setString(4, data.airline_tags)
|
|
statement?.setString(5, data.city_tags)
|
|
statement?.setString(6, data.messagebank_ann_id)
|
|
statement?.setString(7, data.broadcastzones)
|
|
val rowsAffected = statement?.executeUpdate()
|
|
if (rowsAffected != null && rowsAffected > 0) {
|
|
Logger.info("User added: ${data.username}" as Any)
|
|
return true
|
|
} else {
|
|
Logger.warn("No user entry added for: ${data.username}" as Any)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error adding user entry: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun AddAll(data: ArrayList<UserDB>): Boolean {
|
|
return try {
|
|
connection.autoCommit = false
|
|
val sql = "INSERT INTO ${super.dbName} (username, password, location,airline_tags,city_tags, messagebank_ann_id, broadcastzones) VALUES (?, ?, ?,?, ?, ?, ?)"
|
|
val statement = connection.prepareStatement(sql)
|
|
for (user in data) {
|
|
statement.setString(1, user.username)
|
|
statement.setString(2, user.password)
|
|
statement.setString(3, user.location)
|
|
statement.setString(4, user.airline_tags)
|
|
statement.setString(5, user.city_tags)
|
|
statement.setString(6, user.messagebank_ann_id)
|
|
statement.setString(7, user.broadcastzones)
|
|
statement.addBatch()
|
|
}
|
|
statement.executeBatch()
|
|
connection.commit()
|
|
Logger.info("Bulk user insert successful: ${data.size} entries" as Any)
|
|
connection.autoCommit = true
|
|
true
|
|
} catch (e: Exception) {
|
|
Logger.error("Error adding user entries: ${e.message}" as Any)
|
|
false
|
|
}
|
|
}
|
|
|
|
override fun UpdateByIndex(index: Int, data: UserDB): Boolean {
|
|
try {
|
|
val statement = connection.prepareStatement("UPDATE ${super.dbName} SET username = ?, password = ?, location = ?, airline_tags = ?,city_tags=?, messagebank_ann_id = ?, broadcastzones = ? WHERE `index` = ?")
|
|
statement?.setString(1, data.username)
|
|
statement?.setString(2, data.password)
|
|
statement?.setString(3, data.location)
|
|
statement?.setString(4, data.airline_tags)
|
|
statement?.setString(5, data.city_tags)
|
|
statement?.setString(6, data.messagebank_ann_id)
|
|
statement?.setString(7, data.broadcastzones)
|
|
statement?.setLong(8, index.toLong())
|
|
val rowsAffected = statement?.executeUpdate()
|
|
if (rowsAffected != null && rowsAffected > 0) {
|
|
Logger.info("User updated at index $index: ${data.username}" as Any)
|
|
return true
|
|
} else {
|
|
Logger.warn("No user entry updated at index $index for: ${data.username}" as Any)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error updating user 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 (username, password, location, airline_tags, city_tags, messagebank_ann_id, broadcastzones) SELECT username, password, location, airline_tags, city_tags, messagebank_ann_id, broadcastzones FROM ${super.dbName} ORDER BY username ")
|
|
statement?.executeUpdate("TRUNCATE TABLE ${super.dbName}")
|
|
statement?.executeUpdate("INSERT INTO ${super.dbName} (username, password, location, airline_tags, city_tags, messagebank_ann_id, broadcastzones) SELECT username, password, location, airline_tags, city_tags, messagebank_ann_id, broadcastzones FROM $tempdb_name")
|
|
statement?.executeUpdate("DROP TABLE $tempdb_name")
|
|
Logger.info("${super.dbName} table resorted by index" as Any)
|
|
// reload the local list
|
|
Get()
|
|
return true
|
|
} catch (e: Exception) {
|
|
Logger.error("Error resorting ${super.dbName} table by index: ${e.message}" as Any)
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun Import_XLSX(workbook: XSSFWorkbook): Boolean {
|
|
try {
|
|
val sheet = workbook.getSheet("User") ?: throw Exception("No sheet named 'User' found")
|
|
val headerRow = sheet.getRow(0) ?: throw Exception("No header row found")
|
|
val headers = arrayOf("Index", "username", "password", "location", "airline_tags", "city_tags", "messagebank_ann_id", "broadcastzones")
|
|
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 users
|
|
Clear()
|
|
// read each row and insert into database
|
|
val _userList = ArrayList<UserDB>()
|
|
for (rowIndex in 1..sheet.lastRowNum) {
|
|
val row = sheet.getRow(rowIndex) ?: continue
|
|
val username = row.getCell(1)?.stringCellValue ?: continue
|
|
val password = row.getCell(2)?.stringCellValue ?: continue
|
|
val location = row.getCell(3)?.stringCellValue ?: continue
|
|
val airline_tags = row.getCell(4)?.stringCellValue ?: continue
|
|
val city_tags = row.getCell(5)?.stringCellValue ?: continue
|
|
val messagebank_ann_id = row.getCell(6)?.stringCellValue ?: continue
|
|
val broadcastzones = row.getCell(7)?.stringCellValue ?: continue
|
|
val user = UserDB(0u, username, password, location, airline_tags,city_tags, messagebank_ann_id, broadcastzones)
|
|
_userList.add(user)
|
|
}
|
|
return AddAll(_userList)
|
|
} catch (e: Exception) {
|
|
Logger.error { "Error importing User, 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("User")
|
|
val headerRow = sheet.createRow(0)
|
|
val headers = arrayOf("Index", "username", "password", "location", "airline_tags","city_tags", "messagebank_ann_id", "broadcastzones")
|
|
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("username"))
|
|
row.createCell(2).setCellValue(resultSet.getString("password"))
|
|
row.createCell(3).setCellValue(resultSet.getString("location"))
|
|
row.createCell(4).setCellValue(resultSet.getString("airline_tags"))
|
|
row.createCell(5).setCellValue(resultSet.getString("city_tags"))
|
|
row.createCell(6).setCellValue(resultSet.getString("messagebank_ann_id"))
|
|
row.createCell(7).setCellValue(resultSet.getString("broadcastzones"))
|
|
}
|
|
for (i in headers.indices) {
|
|
sheet.autoSizeColumn(i)
|
|
}
|
|
return workbook
|
|
} catch (e: Exception) {
|
|
Logger.error { "Error exporting User, Msg: ${e.message}" }
|
|
}
|
|
return null
|
|
}
|
|
|
|
}
|
|
|
|
runBlocking {
|
|
withContext(Dispatchers.IO) {
|
|
logDB.Create()
|
|
soundchannelDB.Create()
|
|
scheduleDB.Create()
|
|
broadcastDB.Create()
|
|
messageDB.Create()
|
|
soundDB.Create()
|
|
languageDB.Create()
|
|
queuetableDB.Create()
|
|
queuepagingDB.Create()
|
|
userDB.Create()
|
|
|
|
messageDB.Get()
|
|
soundDB.Get()
|
|
languageDB.Get()
|
|
scheduleDB.Get()
|
|
broadcastDB.Get()
|
|
soundchannelDB.Get()
|
|
userDB.Get()
|
|
}
|
|
}
|
|
|
|
|
|
|
|
Logger.info { "Loading MariaDB completed" }
|
|
Logger.info { "Soundbank count: ${soundDB.List.size}" }
|
|
Logger.info { "Messagebank count: ${messageDB.List.size}" }
|
|
Logger.info { "LanguageLink count: ${languageDB.List.size}" }
|
|
Logger.info { "Schedulebank count: ${scheduleDB.List.size}" }
|
|
Logger.info { "BroadcastZones count: ${broadcastDB.List.size}" }
|
|
Logger.info { "SoundChannel count: ${soundchannelDB.List.size}" }
|
|
Logger.info { "User count: ${userDB.List.size}" }
|
|
|
|
|
|
} catch (e: Exception) {
|
|
Logger.error("Failed to connect to MariaDB: ${e.message}" as Any)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Closes the MariaDB connection.
|
|
*/
|
|
fun close() {
|
|
try {
|
|
connection.close()
|
|
|
|
Logger.info("Connection to MariaDB closed" as Any)
|
|
} catch (e: Exception) {
|
|
Logger.error("Error closing MariaDB connection: ${e.message}" as Any)
|
|
}
|
|
connected = false
|
|
}
|
|
|
|
|
|
/**
|
|
* Adds a new log entry to the database with the current date and time.
|
|
* @param machine The machine name or identifier.
|
|
* @param description The log description.
|
|
* @return true if the log was added successfully, false otherwise.
|
|
*/
|
|
fun Add_Log(machine: String, description: String): Boolean {
|
|
val current = java.time.LocalDateTime.now()
|
|
val date = current.toLocalDate().toString() // format YYYY-MM-DD
|
|
val time = current.toLocalTime().withNano(0).toString() // format HH:MM:SS
|
|
val datenya = date.split("-").reversed().joinToString("/") // convert to DD/MM/YYYY
|
|
val log = Log(0u, datenya, time, machine, description)
|
|
return logDB.Add(log)
|
|
}
|
|
|
|
/**
|
|
* Get All Log from database
|
|
* @param consumer A Consumer that will receive the list of logs
|
|
*/
|
|
fun GetLog(consumer: Consumer<ArrayList<Log>>) {
|
|
val logList = ArrayList<Log>()
|
|
try {
|
|
val statement = connection.createStatement()
|
|
val resultSet = statement?.executeQuery("SELECT * FROM logs")
|
|
while (resultSet?.next() == true) {
|
|
val log = Log(
|
|
resultSet.getLong("index").toULong(),
|
|
resultSet.getString("datenya"),
|
|
resultSet.getString("timenya"),
|
|
resultSet.getString("machine"),
|
|
resultSet.getString("description")
|
|
)
|
|
logList.add(log)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error fetching logs table: ${e.message}" as Any)
|
|
}
|
|
consumer.accept(logList)
|
|
}
|
|
|
|
/**
|
|
* Get Log from database by date for HTML usage
|
|
* @param date The date to filter logs by (format: DD-MM-YYYY)
|
|
* @param consumer A Consumer that will receive the list of logs for the specified date
|
|
*/
|
|
fun GetLogForHtml(date: String, consumer: Consumer<ArrayList<Log>>) {
|
|
val logList = ArrayList<Log>()
|
|
//println("GetLogForHtml Date: $date" )
|
|
if (ValiDateForLogHtml(date)) {
|
|
try {
|
|
// must convert from DD-MM-YYYY to DD/MM/YYYY, because in database we use DD/MM/YYYY
|
|
val adjusteddate = date.replace("-", "/")
|
|
val statement = connection.prepareStatement("SELECT * FROM logs WHERE datenya = ?")
|
|
statement?.setString(1, adjusteddate)
|
|
//println("GetLogForHtml Date: $adjusteddate" )
|
|
// println("GetLogForHtml SQL: " +statement?.toString())
|
|
val resultSet = statement?.executeQuery()
|
|
while (resultSet?.next() == true) {
|
|
val log = Log(
|
|
resultSet.getLong("index").toULong(),
|
|
resultSet.getString("datenya"),
|
|
resultSet.getString("timenya"),
|
|
resultSet.getString("machine"),
|
|
resultSet.getString("description")
|
|
)
|
|
logList.add(log)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error fetching logs table for date $date: ${e.message}" as Any)
|
|
}
|
|
}
|
|
|
|
consumer.accept(logList)
|
|
}
|
|
|
|
/**
|
|
* Get Log from database by date and filter for HTML usage
|
|
* @param date The date to filter logs by (format: DD-MM-YYYY)
|
|
* @param filter The filter string to search in description or machine
|
|
* @param consumer A Consumer that will receive the list of logs for the specified date and filter
|
|
*/
|
|
fun GetLogForHtml(date: String, filter: String, consumer: Consumer<ArrayList<Log>>) {
|
|
val logList = ArrayList<Log>()
|
|
//println("GetLogForHtml Date: $date Filter: $filter" )
|
|
|
|
if (ValiDateForLogHtml(date)) {
|
|
try {
|
|
// must convert from DD-MM-YYYY to DD/MM/YYYY, because in database we use DD/MM/YYYY
|
|
val adjusteddate = date.replace("-", "/")
|
|
val statement =
|
|
connection.prepareStatement("SELECT * FROM logs WHERE datenya = ? AND description LIKE ?")
|
|
statement?.setString(1, adjusteddate)
|
|
statement?.setString(2, "%$filter%")
|
|
//println("GetLogForHtml Date: $adjusteddate , Filter=$filter" )
|
|
//println("GetLogForHtml SQL: " +statement?.toString())
|
|
val resultSet = statement?.executeQuery()
|
|
while (resultSet?.next() == true) {
|
|
val log = Log(
|
|
resultSet.getLong("index").toULong(),
|
|
resultSet.getString("datenya"),
|
|
resultSet.getString("timenya"),
|
|
resultSet.getString("machine"),
|
|
resultSet.getString("description")
|
|
)
|
|
logList.add(log)
|
|
}
|
|
} catch (e: Exception) {
|
|
Logger.error("Error fetching logs for date $date with filter $filter: ${e.message}" as Any)
|
|
}
|
|
}
|
|
|
|
consumer.accept(logList)
|
|
}
|
|
|
|
/**
|
|
* Exports the log table to an XLSX workbook for a specific date and optional filter.
|
|
* @param logDate The date string in format "dd/MM/yyyy".
|
|
* @param logFilter The filter string for the description or machine. If empty, exports all logs for the date.
|
|
* @return An XSSFWorkbook containing the filtered log data, or null if an error occurred.
|
|
*/
|
|
fun Export_Log_XLSX(logDate: String, logFilter: String): XSSFWorkbook? {
|
|
try {
|
|
val statement = connection.prepareStatement(
|
|
if (logFilter.isBlank()) {
|
|
"SELECT * FROM logs WHERE datenya = ?"
|
|
} else {
|
|
"SELECT * FROM logs WHERE datenya = ? AND (description LIKE ?)"
|
|
}
|
|
)
|
|
statement?.setString(1, logDate)
|
|
if (!logFilter.isBlank()) {
|
|
val filter = "%$logFilter%"
|
|
statement?.setString(2, filter)
|
|
}
|
|
val resultSet = statement?.executeQuery()
|
|
val workbook = XSSFWorkbook()
|
|
val sheet = workbook.createSheet("Log")
|
|
val headerRow = sheet.createRow(0)
|
|
val headers = arrayOf("Index", "datenya", "timenya", "machine", "description")
|
|
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("datenya"))
|
|
row.createCell(2).setCellValue(resultSet.getString("timenya"))
|
|
row.createCell(3).setCellValue(resultSet.getString("machine"))
|
|
row.createCell(4).setCellValue(resultSet.getString("description"))
|
|
}
|
|
for (i in headers.indices) {
|
|
sheet.autoSizeColumn(i)
|
|
}
|
|
return workbook
|
|
} catch (e: Exception) {
|
|
Logger.error { "Error exporting Log, Msg: ${e.message}" }
|
|
}
|
|
return null
|
|
}
|
|
|
|
/**
|
|
* Find all city soundbank by tag
|
|
* @param tag The tags to search for
|
|
* @return a list of Soundbank with Category City and matching tag
|
|
*/
|
|
fun Find_Soundbank_City(tag: String) : List<Soundbank>{
|
|
return soundDB.List
|
|
.filter{ it.Category== Category.City.name }
|
|
.filter { it.TAG.equals(tag,true)}
|
|
}
|
|
|
|
fun Find_Soundbank_AirplaneName(tag: String) : List<Soundbank>{
|
|
return soundDB.List
|
|
.filter{ it.Category== Category.Airplane_Name.name }
|
|
.filter { it.TAG.equals(tag,true)}
|
|
}
|
|
|
|
fun Find_Soundbank_Places(tag: String) : List<Soundbank>{
|
|
return soundDB.List
|
|
.filter{ it.Category== Category.Places.name }
|
|
.filter { it.TAG.equals(tag,true)}
|
|
}
|
|
|
|
fun Find_Soundbank_Shalat(tag: String) : List<Soundbank>{
|
|
val lowerTag = tag.lowercase()
|
|
return soundDB.List
|
|
.filter{ it.Category== Category.Shalat.name }
|
|
.filter { it.TAG.lowercase()==lowerTag}
|
|
}
|
|
|
|
fun Find_Soundbank_Sequence(tag: String) : List<Soundbank>{
|
|
return soundDB.List
|
|
.filter{ it.Category== Category.Sequence.name }
|
|
.filter { it.TAG.equals(tag,true)}
|
|
}
|
|
|
|
fun Find_Soundbank_Reason(tag: String) : List<Soundbank>{
|
|
return soundDB.List
|
|
.filter{ it.Category== Category.Reason.name }
|
|
.filter { it.TAG.equals(tag,true)}
|
|
}
|
|
|
|
fun Find_Soundbank_Procedure(tag: String) : List<Soundbank> {
|
|
return soundDB.List
|
|
.filter { it.Category == Category.Procedure.name }
|
|
.filter { it.TAG.equals(tag,true) }
|
|
}
|
|
|
|
/**
|
|
* Get all distinct airline code tags from soundbank
|
|
* @return a list of distinct airline code tags sorted alphabetically
|
|
*/
|
|
fun Get_AirlineCode_Tags(): List<String> {
|
|
return soundDB.List
|
|
.filter { it.Category == Category.Airline_Code.name }
|
|
.map { it.TAG }
|
|
.distinct()
|
|
.sorted()
|
|
}
|
|
|
|
/**
|
|
* Get all distinct city tags from soundbank
|
|
* @return a list of distinct city tags sorted alphabetically
|
|
*/
|
|
fun Get_City_Tags(): List<String> {
|
|
return soundDB.List
|
|
.filter { it.Category == Category.City.name }
|
|
.map { it.TAG }
|
|
.distinct()
|
|
.sorted()
|
|
}
|
|
|
|
/**
|
|
* Get all distinct message ID from messagebank
|
|
* @return a list of distinct ANN_ID sorted numerically
|
|
*/
|
|
fun Get_MessageID_List(): List<UInt> {
|
|
return messageDB.List
|
|
.distinctBy { it.ANN_ID }
|
|
.map { it.ANN_ID }
|
|
.sorted()
|
|
}
|
|
|
|
/**
|
|
* Get all distinct broadcast zone descriptions from broadcastDB
|
|
* @return a list of distinct broadcast zone descriptions sorted alphabetically
|
|
*/
|
|
fun Get_BroadcastZone_List(): List<String> {
|
|
return broadcastDB.List
|
|
.distinctBy { it.description }
|
|
.map { it.description }
|
|
.sorted()
|
|
}
|
|
|
|
/**
|
|
* Get all distinct sound channel from soundchannelDB
|
|
* @return a list of distinct sound channel sorted alphabetically
|
|
*/
|
|
fun Get_SoundChannel_List(): List<String> {
|
|
return soundchannelDB.List
|
|
.distinctBy { it.channel }
|
|
.map { it.channel }
|
|
.sorted()
|
|
}
|
|
|
|
/**
|
|
* Check if a username already exists in the userDB (case-insensitive)
|
|
*/
|
|
fun Username_exists(username: String): Boolean {
|
|
return userDB.List.any { it.username.equals(username, ignoreCase = true) }
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |