commit 23/01/2026
This commit is contained in:
1
.idea/inspectionProfiles/Project_Default.xml
generated
1
.idea/inspectionProfiles/Project_Default.xml
generated
@@ -21,6 +21,7 @@
|
|||||||
<option name="processLiterals" value="true" />
|
<option name="processLiterals" value="true" />
|
||||||
<option name="processComments" value="true" />
|
<option name="processComments" value="true" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
|
<inspection_tool class="SqlNoDataSourceInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="TestFunctionName" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
<inspection_tool class="TestFunctionName" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||||
</profile>
|
</profile>
|
||||||
</component>
|
</component>
|
||||||
@@ -16,10 +16,10 @@ import java.util.function.Consumer
|
|||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
class ActiveMQClient {
|
class ActiveMQClient {
|
||||||
private lateinit var connection: Connection
|
private var connection: Connection? = null
|
||||||
private lateinit var session: Session
|
private var session: Session? = null
|
||||||
private lateinit var destination : Queue
|
private var destination : Queue? = null
|
||||||
private lateinit var consumer: MessageConsumer
|
private var consumer: MessageConsumer? = null
|
||||||
var MessageConsumer : Consumer<Message>?= null
|
var MessageConsumer : Consumer<Message>?= null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,11 +28,11 @@ class ActiveMQClient {
|
|||||||
fun Start(){
|
fun Start(){
|
||||||
try{
|
try{
|
||||||
connection = ActiveMQConnectionFactory(config.ActiveMQ_BrokerURL, config.ActiveMQ_Username, config.ActiveMQ_Password).createConnection()
|
connection = ActiveMQConnectionFactory(config.ActiveMQ_BrokerURL, config.ActiveMQ_Username, config.ActiveMQ_Password).createConnection()
|
||||||
connection.start()
|
connection?.start()
|
||||||
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)
|
session = connection?.createSession(false, Session.AUTO_ACKNOWLEDGE)
|
||||||
destination = session.createQueue(config.ActiveMQ_QueueName)
|
destination = session?.createQueue(config.ActiveMQ_QueueName)
|
||||||
consumer = session.createConsumer(destination)
|
consumer = session?.createConsumer(destination)
|
||||||
consumer.messageListener = MessageListener { message ->
|
consumer?.messageListener = MessageListener { message ->
|
||||||
MessageConsumer?.accept(message)
|
MessageConsumer?.accept(message)
|
||||||
when (message) {
|
when (message) {
|
||||||
is TextMessage -> Logger.info { "Received Text Message : ${message.text}" }
|
is TextMessage -> Logger.info { "Received Text Message : ${message.text}" }
|
||||||
@@ -69,9 +69,12 @@ class ActiveMQClient {
|
|||||||
*/
|
*/
|
||||||
fun Stop(){
|
fun Stop(){
|
||||||
try{
|
try{
|
||||||
consumer.close()
|
if (consumer==null) throw Exception("Consumer is null")
|
||||||
session.close()
|
if (session==null) throw Exception("Session is null")
|
||||||
connection.close()
|
if (connection==null) throw Exception("Connection is null")
|
||||||
|
consumer?.close()
|
||||||
|
session?.close()
|
||||||
|
connection?.close()
|
||||||
Logger.info { "Connection closed to Broker" }
|
Logger.info { "Connection closed to Broker" }
|
||||||
} catch (e : Exception){
|
} catch (e : Exception){
|
||||||
Logger.error { "Failed to close connection, Message : ${e.message}" }
|
Logger.error { "Failed to close connection, Message : ${e.message}" }
|
||||||
|
|||||||
59
src/Main.kt
59
src/Main.kt
@@ -2,19 +2,69 @@ import ActiveMQ.ActiveMQClient
|
|||||||
import Other.Config
|
import Other.Config
|
||||||
import Web.WebUI
|
import Web.WebUI
|
||||||
import database.MySQLAdapter
|
import database.MySQLAdapter
|
||||||
|
import org.tinylog.Logger
|
||||||
import org.tinylog.provider.ProviderRegistry
|
import org.tinylog.provider.ProviderRegistry
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
|
|
||||||
lateinit var config : Config
|
lateinit var config : Config
|
||||||
|
var aas1 : MySQLAdapter? = null
|
||||||
|
var aas2 : MySQLAdapter? = null
|
||||||
|
var aas3 : MySQLAdapter? = null
|
||||||
fun main() {
|
fun main() {
|
||||||
config = Config()
|
config = Config()
|
||||||
config.Load()
|
config.Load()
|
||||||
val webUI = WebUI()
|
val webUI = WebUI()
|
||||||
webUI.Start()
|
webUI.Start()
|
||||||
val activeclient = ActiveMQClient()
|
val activeclient = ActiveMQClient()
|
||||||
//activeclient.Start()
|
activeclient.Start()
|
||||||
val mysql = MySQLAdapter()
|
|
||||||
mysql.Start()
|
aas1 = MySQLAdapter(1)
|
||||||
|
aas1!!.VerifyConnection { success ->
|
||||||
|
if (success) {
|
||||||
|
Logger.info {"Database 1 connection verified."}
|
||||||
|
aas1!!.CreateFlightFilterTable { success ->
|
||||||
|
if (success) {
|
||||||
|
Logger.info {"Flight Filter Table ensured in Database 1."}
|
||||||
|
} else {
|
||||||
|
Logger.error {"Failed to ensure Flight Filter Table in Database 1."}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Logger.error {"Failed to verify Database 1 connection." }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aas2 = MySQLAdapter(2)
|
||||||
|
aas2!!.VerifyConnection { success ->
|
||||||
|
if (success) {
|
||||||
|
Logger.info { "Database 2 connection verified." }
|
||||||
|
aas2!!.CreateFlightFilterTable { success ->
|
||||||
|
if (success) {
|
||||||
|
Logger.info { "Flight Filter Table ensured in Database 2." }
|
||||||
|
} else {
|
||||||
|
Logger.error { "Failed to ensure Flight Filter Table in Database 2." }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Logger.error { "Failed to verify Database 2 connection." }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aas3 = MySQLAdapter(3)
|
||||||
|
aas3!!.VerifyConnection { success ->
|
||||||
|
if (success) {
|
||||||
|
Logger.info {"Database 3 connection verified."}
|
||||||
|
aas3!!.CreateFlightFilterTable { success ->
|
||||||
|
if (success) {
|
||||||
|
Logger.info { "Flight Filter Table ensured in Database 3." }
|
||||||
|
} else {
|
||||||
|
Logger.error { "Failed to ensure Flight Filter Table in Database 3." }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Logger.error { "Failed to verify Database 3 connection." }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
activeclient.MessageConsumer = Consumer{ message ->
|
activeclient.MessageConsumer = Consumer{ message ->
|
||||||
|
|
||||||
@@ -23,8 +73,7 @@ fun main() {
|
|||||||
Runtime.getRuntime().addShutdownHook(Thread {
|
Runtime.getRuntime().addShutdownHook(Thread {
|
||||||
webUI.Stop()
|
webUI.Stop()
|
||||||
activeclient.Stop()
|
activeclient.Stop()
|
||||||
mysql.Stop()
|
|
||||||
// shutdown tinylog properly
|
// shutdown tinylog properly
|
||||||
ProviderRegistry.getLoggingProvider().shutdown();
|
ProviderRegistry.getLoggingProvider().shutdown()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
140
src/Web/WebUI.kt
140
src/Web/WebUI.kt
@@ -1,7 +1,13 @@
|
|||||||
package Web
|
package Web
|
||||||
|
|
||||||
import Log.LogGetter
|
import Log.LogGetter
|
||||||
|
import aas1
|
||||||
|
import aas2
|
||||||
|
import aas3
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
|
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
|
||||||
import config
|
import config
|
||||||
|
import database.FlightFilter
|
||||||
import io.javalin.Javalin
|
import io.javalin.Javalin
|
||||||
import io.javalin.apibuilder.ApiBuilder.before
|
import io.javalin.apibuilder.ApiBuilder.before
|
||||||
import io.javalin.apibuilder.ApiBuilder.get
|
import io.javalin.apibuilder.ApiBuilder.get
|
||||||
@@ -15,7 +21,7 @@ import org.tinylog.Logger
|
|||||||
class WebUI {
|
class WebUI {
|
||||||
// regex untuk date dengan format YYYY-MM-DD
|
// regex untuk date dengan format YYYY-MM-DD
|
||||||
private val dateRegex1 = """\d{4}-\d{2}-\d{2}""".toRegex()
|
private val dateRegex1 = """\d{4}-\d{2}-\d{2}""".toRegex()
|
||||||
|
private val mapper = ObjectMapper().registerKotlinModule()
|
||||||
private var app: Javalin = Javalin.create { cfg ->
|
private var app: Javalin = Javalin.create { cfg ->
|
||||||
cfg.staticFiles.add("/")
|
cfg.staticFiles.add("/")
|
||||||
cfg.router.apiBuilder {
|
cfg.router.apiBuilder {
|
||||||
@@ -54,9 +60,9 @@ class WebUI{
|
|||||||
val logs = LogGetter().getLog(date)
|
val logs = LogGetter().getLog(date)
|
||||||
if (logs.isNotEmpty()) {
|
if (logs.isNotEmpty()) {
|
||||||
it.json(logs)
|
it.json(logs)
|
||||||
} else it.status(404).json(webReply("No logs found for the specified date"))
|
} else it.status(404).json(webReply(message = "No logs found for the specified date"))
|
||||||
} else it.status(400).json(webReply("Date parameter is empty"))
|
} else it.status(400).json(webReply(message = "Date parameter is empty"))
|
||||||
} else it.status(400).json(webReply("Please provide a date"))
|
} else it.status(400).json(webReply(message = "Please provide a date"))
|
||||||
}
|
}
|
||||||
|
|
||||||
get("logout") {
|
get("logout") {
|
||||||
@@ -66,7 +72,12 @@ class WebUI{
|
|||||||
}
|
}
|
||||||
|
|
||||||
get("getSetting") {
|
get("getSetting") {
|
||||||
val fd = farmData(config.ActiveMQ_BrokerURL, config.ActiveMQ_Username, config.ActiveMQ_Password, config.ActiveMQ_QueueName)
|
val fd = farmData(
|
||||||
|
config.ActiveMQ_BrokerURL,
|
||||||
|
config.ActiveMQ_Username,
|
||||||
|
config.ActiveMQ_Password,
|
||||||
|
config.ActiveMQ_QueueName
|
||||||
|
)
|
||||||
val aas1 = aasData(config.MySQL_AAS1, config.MySQL_AAS1_Username, config.MySQL_AAS1_Password)
|
val aas1 = aasData(config.MySQL_AAS1, config.MySQL_AAS1_Username, config.MySQL_AAS1_Password)
|
||||||
val aas2 = aasData(config.MySQL_AAS2, config.MySQL_AAS2_Username, config.MySQL_AAS2_Password)
|
val aas2 = aasData(config.MySQL_AAS2, config.MySQL_AAS2_Username, config.MySQL_AAS2_Password)
|
||||||
val aas3 = aasData(config.MySQL_AAS3, config.MySQL_AAS3_Username, config.MySQL_AAS3_Password)
|
val aas3 = aasData(config.MySQL_AAS3, config.MySQL_AAS3_Username, config.MySQL_AAS3_Password)
|
||||||
@@ -82,11 +93,11 @@ class WebUI{
|
|||||||
config.ActiveMQ_Password = fd.farm.password
|
config.ActiveMQ_Password = fd.farm.password
|
||||||
config.ActiveMQ_QueueName = fd.farm.queue
|
config.ActiveMQ_QueueName = fd.farm.queue
|
||||||
config.Save()
|
config.Save()
|
||||||
it.json(webReply("success"))
|
it.json(webReply(message = "success"))
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
val str = "Error saving FARM settings: ${e.message}"
|
val str = "Error saving FARM settings: ${e.message}"
|
||||||
Logger.error { str }
|
Logger.error { str }
|
||||||
it.status(500).json(webReply(str))
|
it.status(500).json(webReply(message = str))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
post("saveAAS") {
|
post("saveAAS") {
|
||||||
@@ -103,12 +114,119 @@ class WebUI{
|
|||||||
config.MySQL_AAS3_Username = ax.aas3.username
|
config.MySQL_AAS3_Username = ax.aas3.username
|
||||||
config.MySQL_AAS3_Password = ax.aas3.password
|
config.MySQL_AAS3_Password = ax.aas3.password
|
||||||
config.Save()
|
config.Save()
|
||||||
it.json(webReply("success"))
|
it.json(webReply(message = "success"))
|
||||||
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
val str = "Error saving AAS settings: ${e.message}"
|
val str = "Error saving AAS settings: ${e.message}"
|
||||||
Logger.error { str }
|
Logger.error { str }
|
||||||
it.status(500).json(webReply(str))
|
it.status(500).json(webReply(message = str))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get("getBroadcastZones") {
|
||||||
|
val id = it.queryParam("id")?.toIntOrNull() ?: 0
|
||||||
|
val aas = when (id) {
|
||||||
|
1 -> aas1
|
||||||
|
2 -> aas2
|
||||||
|
3 -> aas3
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
if (aas != null) {
|
||||||
|
aas.GetBroadcastZones { success, zones ->
|
||||||
|
if (success) {
|
||||||
|
it.json(zones)
|
||||||
|
} else {
|
||||||
|
it.status(500).json(webReply(message = "Failed to retrieve broadcast zones"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else it.status(400).json(webReply(message = "Invalid AAS id"))
|
||||||
|
}
|
||||||
|
|
||||||
|
get("getAirlineCodes") {
|
||||||
|
val id = it.queryParam("id")?.toIntOrNull() ?: 0
|
||||||
|
val aas = when (id) {
|
||||||
|
1 -> aas1
|
||||||
|
2 -> aas2
|
||||||
|
3 -> aas3
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
if (aas != null) {
|
||||||
|
aas.GetAirlineCode { success, codes ->
|
||||||
|
if (success) {
|
||||||
|
it.json(codes)
|
||||||
|
} else {
|
||||||
|
it.status(500).json(webReply(message = "Failed to retrieve airline codes"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else it.status(400).json(webReply(message = "Invalid AAS id"))
|
||||||
|
}
|
||||||
|
|
||||||
|
post("FlightFilter") {
|
||||||
|
try {
|
||||||
|
val req = it.bodyAsClass(webRequest::class.java)
|
||||||
|
val aas_id = req.aas_id.toIntOrNull() ?: 0
|
||||||
|
val aas = when (aas_id) {
|
||||||
|
1 -> aas1
|
||||||
|
2 -> aas2
|
||||||
|
3 -> aas3
|
||||||
|
else -> throw Exception("Invalid AAS id")
|
||||||
|
}
|
||||||
|
when (req.command) {
|
||||||
|
"get" -> {
|
||||||
|
if (aas != null) {
|
||||||
|
aas.GetFlightFilterTable { success, filters ->
|
||||||
|
if (success) {
|
||||||
|
it.json(webReply(command = req.command, message = "success"))
|
||||||
|
} else throw Exception("Failed to retrieve Flight Filter data")
|
||||||
|
}
|
||||||
|
} else throw Exception("Invalid AAS id")
|
||||||
|
}
|
||||||
|
"clear" ->{
|
||||||
|
if (aas != null) {
|
||||||
|
aas.ClearFlightFilterTable { success ->
|
||||||
|
if (success) {
|
||||||
|
it.json(webReply(command = req.command, message = "success"))
|
||||||
|
} else throw Exception("Failed to clear Flight Filter data")
|
||||||
|
}
|
||||||
|
} else throw Exception("Invalid AAS id")
|
||||||
|
}
|
||||||
|
"add" ->{
|
||||||
|
val data = mapper.readValue(req.data, FlightFilter::class.java)
|
||||||
|
if (aas != null) {
|
||||||
|
aas.InsertFlightFilter(data) { success ->
|
||||||
|
if (success) {
|
||||||
|
it.json(webReply(command = req.command, data=req.data, message = "success"))
|
||||||
|
} else throw Exception("Failed to add Flight Filter data")
|
||||||
|
}
|
||||||
|
} else throw Exception("Invalid AAS id")
|
||||||
|
}
|
||||||
|
"delete"->{
|
||||||
|
// data is index of flight filter to delete
|
||||||
|
val data = req.data.toIntOrNull() ?: 0
|
||||||
|
if (aas != null) {
|
||||||
|
aas.DeleteFlightFilter(data) { success ->
|
||||||
|
if (success) {
|
||||||
|
it.json(webReply(command = req.command, data=req.data, message = "success"))
|
||||||
|
} else throw Exception("Failed to delete Flight Filter data")
|
||||||
|
}
|
||||||
|
} else throw Exception("Invalid AAS id")
|
||||||
|
}
|
||||||
|
"patch"->{
|
||||||
|
val data = mapper.readValue(req.data, FlightFilter::class.java)
|
||||||
|
if (aas != null) {
|
||||||
|
aas.PatchFlightFilter(data.id, data) { success ->
|
||||||
|
if (success) {
|
||||||
|
it.json(webReply(command = req.command, data=req.data, message = "success"))
|
||||||
|
} else throw Exception("Failed to patch Flight Filter data")
|
||||||
|
}
|
||||||
|
} else throw Exception("Invalid AAS id")
|
||||||
|
}
|
||||||
|
else -> throw Exception("Invalid FlightFilter command")
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
val str = "Error parsing FlightFilter request: ${e.message}"
|
||||||
|
Logger.error { str }
|
||||||
|
it.status(500).json(webReply(message = str))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,21 +234,18 @@ class WebUI{
|
|||||||
if (config.WebUsername != it.cookie("username")) {
|
if (config.WebUsername != it.cookie("username")) {
|
||||||
Logger.info { "${it.ip()} Have not logged in, forward to login.html" }
|
Logger.info { "${it.ip()} Have not logged in, forward to login.html" }
|
||||||
it.redirect("login.html")
|
it.redirect("login.html")
|
||||||
return@before
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
before("log.html") {
|
before("log.html") {
|
||||||
if (config.WebUsername != it.cookie("username")) {
|
if (config.WebUsername != it.cookie("username")) {
|
||||||
Logger.info { "${it.ip()} Have not logged in, forward to login.html" }
|
Logger.info { "${it.ip()} Have not logged in, forward to login.html" }
|
||||||
it.redirect("login.html")
|
it.redirect("login.html")
|
||||||
return@before
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
before("setting.html") {
|
before("setting.html") {
|
||||||
if (config.WebUsername != it.cookie("username")) {
|
if (config.WebUsername != it.cookie("username")) {
|
||||||
Logger.info { "${it.ip()} Have not logged in, forward to login.html" }
|
Logger.info { "${it.ip()} Have not logged in, forward to login.html" }
|
||||||
it.redirect("login.html")
|
it.redirect("login.html")
|
||||||
return@before
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,6 +258,7 @@ class WebUI{
|
|||||||
fun Start() {
|
fun Start() {
|
||||||
app.start(config.WebPort)
|
app.start(config.WebPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop WebUI Server
|
* Stop WebUI Server
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
package Web
|
package Web
|
||||||
|
|
||||||
class webReply(val message: String) {
|
class webReply(var command: String?=null, val message: String, val data: String?=null)
|
||||||
}
|
|
||||||
3
src/Web/webRequest.kt
Normal file
3
src/Web/webRequest.kt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
package Web
|
||||||
|
|
||||||
|
data class webRequest(val command: String, val aas_id: String, val data: String)
|
||||||
3
src/database/FlightFilter.kt
Normal file
3
src/database/FlightFilter.kt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
package database
|
||||||
|
|
||||||
|
data class FlightFilter(val id: Int,val Description: String, val AirlineCode: String, val FlightNumber: String, val DepartureZone: String, val ArrivalZone: String)
|
||||||
@@ -5,6 +5,7 @@ import java.sql.DriverManager
|
|||||||
import config
|
import config
|
||||||
import org.tinylog.Logger
|
import org.tinylog.Logger
|
||||||
import java.util.function.BiConsumer
|
import java.util.function.BiConsumer
|
||||||
|
import java.util.function.Consumer
|
||||||
|
|
||||||
@Suppress("UNUSED")
|
@Suppress("UNUSED")
|
||||||
/**
|
/**
|
||||||
@@ -12,6 +13,30 @@ import java.util.function.BiConsumer
|
|||||||
* @param aas_id The AAS ID (1, 2, or 3)
|
* @param aas_id The AAS ID (1, 2, or 3)
|
||||||
*/
|
*/
|
||||||
class MySQLAdapter(val aas_id: Int) {
|
class MySQLAdapter(val aas_id: Int) {
|
||||||
|
private var _verified = false
|
||||||
|
private var _successcount = 0
|
||||||
|
private var _failcount = 0
|
||||||
|
private val _broadcastzones = ArrayList<String>()
|
||||||
|
private val _airlinecodes = ArrayList<String>()
|
||||||
|
private val _queueTableData = ArrayList<QueueTableData>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connection Verified
|
||||||
|
*/
|
||||||
|
val ConnectionVerified : Boolean
|
||||||
|
get() = _verified
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Successful transactions count
|
||||||
|
*/
|
||||||
|
val SuccessCount: Int
|
||||||
|
get() = _successcount
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Failed transactions count
|
||||||
|
*/
|
||||||
|
val FailCount: Int
|
||||||
|
get() = _failcount
|
||||||
|
|
||||||
init{
|
init{
|
||||||
require(aas_id in 1..3){
|
require(aas_id in 1..3){
|
||||||
@@ -19,6 +44,24 @@ class MySQLAdapter(val aas_id: Int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Last Result of Get Broadcast Zones
|
||||||
|
*/
|
||||||
|
val BroadcastZones : ArrayList<String>
|
||||||
|
get() = _broadcastzones
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Last Result of Get Airline Codes
|
||||||
|
*/
|
||||||
|
val AirlineCodes : ArrayList<String>
|
||||||
|
get() = _airlinecodes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Last Result of Get Queue Table
|
||||||
|
*/
|
||||||
|
val QueueTable: ArrayList<QueueTableData>
|
||||||
|
get() = _queueTableData
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to connect to MySQL Database
|
* Try to connect to MySQL Database
|
||||||
* @param cb Callback function with parameters (success: Boolean, connection: Connection)
|
* @param cb Callback function with parameters (success: Boolean, connection: Connection)
|
||||||
@@ -33,18 +76,73 @@ class MySQLAdapter(val aas_id: Int) {
|
|||||||
}
|
}
|
||||||
if (conn != null){
|
if (conn != null){
|
||||||
cb.accept(true, conn)
|
cb.accept(true, conn)
|
||||||
|
_verified = true
|
||||||
} else throw Exception("Connection is null")
|
} else throw Exception("Connection is null")
|
||||||
} catch (e : Exception){
|
} catch (e : Exception){
|
||||||
Logger.error { "Failed to connect MySQL Adapter for AAS$aas_id: ${e.message}" }
|
Logger.error { "Failed to connect MySQL Adapter for AAS$aas_id: ${e.message}" }
|
||||||
|
_verified = false
|
||||||
cb.accept(false, null)
|
cb.accept(false, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Airline Codes
|
* Verify Connection to MySQL Database
|
||||||
* @param cb Callback function with parameters (success: Boolean, codes: ArrayList<String>)
|
* @param cb Callback function with parameter (success: Boolean)
|
||||||
*/
|
*/
|
||||||
fun GetAirlineCode(cb: BiConsumer<Boolean, ArrayList<String>>){
|
fun VerifyConnection(cb: Consumer<Boolean>){
|
||||||
|
Connect { success, connection ->
|
||||||
|
if (success){
|
||||||
|
connection!!.close()
|
||||||
|
_verified = true
|
||||||
|
cb.accept(true)
|
||||||
|
} else {
|
||||||
|
_verified = false
|
||||||
|
cb.accept(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Broadcast Zones
|
||||||
|
* @param cb Callback function (optional) with parameters (success: Boolean, zones: ArrayList<String
|
||||||
|
*/
|
||||||
|
fun GetBroadcastZones(cb: BiConsumer<Boolean, ArrayList<String>>? = null){
|
||||||
|
Connect { success, connection ->
|
||||||
|
if (success){
|
||||||
|
try {
|
||||||
|
connection!!.prepareStatement("SELECT DISTINCT description from aas.broadcastzones").use { statement ->
|
||||||
|
val result = ArrayList<String>()
|
||||||
|
statement.executeQuery().use { rs ->
|
||||||
|
while (rs.next()){
|
||||||
|
result.add(rs.getString("ZONE"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
connection.close()
|
||||||
|
Logger.info { "GetBroadcastZones succeeded, found ${result.size} zones" }
|
||||||
|
cb?.accept(true, result)
|
||||||
|
_successcount++
|
||||||
|
_broadcastzones.clear()
|
||||||
|
_broadcastzones.addAll(result)
|
||||||
|
}
|
||||||
|
} catch (e: Exception){
|
||||||
|
Logger.error { "GetBroadcastZones failed, exception: ${e.message}" }
|
||||||
|
cb?.accept(false, arrayListOf())
|
||||||
|
_failcount++
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Logger.error { "GetBroadcastZones failed, no Connection" }
|
||||||
|
cb?.accept(false, arrayListOf())
|
||||||
|
_failcount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Airline Codes
|
||||||
|
* @param cb Callback function (optional) with parameters (success: Boolean, codes: ArrayList<String>)
|
||||||
|
*/
|
||||||
|
fun GetAirlineCode(cb: BiConsumer<Boolean, ArrayList<String>>? = null){
|
||||||
Connect { success, connection ->
|
Connect { success, connection ->
|
||||||
if (success){
|
if (success){
|
||||||
try {
|
try {
|
||||||
@@ -57,16 +155,133 @@ class MySQLAdapter(val aas_id: Int) {
|
|||||||
}
|
}
|
||||||
connection.close()
|
connection.close()
|
||||||
Logger.info { "GetAirlineCode succeeded, found ${result.size} codes" }
|
Logger.info { "GetAirlineCode succeeded, found ${result.size} codes" }
|
||||||
cb.accept(true, result)
|
cb?.accept(true, result)
|
||||||
|
_successcount++
|
||||||
|
_airlinecodes.clear()
|
||||||
|
_airlinecodes.addAll(result)
|
||||||
}
|
}
|
||||||
} catch (e: Exception){
|
} catch (e: Exception){
|
||||||
Logger.error { "GetAirlineCode failed, exception: ${e.message}" }
|
Logger.error { "GetAirlineCode failed, exception: ${e.message}" }
|
||||||
cb.accept(false, arrayListOf())
|
cb?.accept(false, arrayListOf())
|
||||||
|
_failcount++
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Logger.error { "GetAirlineCode failed, no Connection" }
|
Logger.error { "GetAirlineCode failed, no Connection" }
|
||||||
cb.accept(false, arrayListOf())
|
cb?.accept(false, arrayListOf())
|
||||||
|
_failcount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Queue Table records
|
||||||
|
* @param cb Callback function (optional) with parameters (success: Boolean, records: ArrayList<QueueTableData>)
|
||||||
|
*/
|
||||||
|
fun GetQueueTable(cb: BiConsumer<Boolean, ArrayList<QueueTableData>>? = null){
|
||||||
|
Connect { success, connection ->
|
||||||
|
if (success){
|
||||||
|
try {
|
||||||
|
connection!!.prepareStatement("SELECT * from aas.queue_table").use { statement ->
|
||||||
|
val result = ArrayList<QueueTableData>()
|
||||||
|
statement.executeQuery().use { rs ->
|
||||||
|
while (rs.next()){
|
||||||
|
result.add(
|
||||||
|
QueueTableData(
|
||||||
|
Date_Time = rs.getString("Date_Time"),
|
||||||
|
Source = rs.getString("Source"),
|
||||||
|
Tipe = rs.getString("Type"),
|
||||||
|
Message = rs.getString("Message"),
|
||||||
|
SB_Tags = rs.getString("SB_TAGS"),
|
||||||
|
BroadcastZones = rs.getString("BroadcastZones"),
|
||||||
|
Language = rs.getString("Language")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
connection.close()
|
||||||
|
Logger.info { "GetQueueTable succeeded, found ${result.size} records" }
|
||||||
|
cb?.accept(true, result)
|
||||||
|
_successcount++
|
||||||
|
_queueTableData.clear()
|
||||||
|
_queueTableData.addAll(result)
|
||||||
|
}
|
||||||
|
} catch (e: Exception){
|
||||||
|
Logger.error { "GetQueueTable failed, exception: ${e.message}" }
|
||||||
|
cb?.accept(false, arrayListOf())
|
||||||
|
_failcount++
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Logger.error { "GetQueueTable failed, no Connection" }
|
||||||
|
cb?.accept(false, arrayListOf())
|
||||||
|
_failcount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear Queue Table
|
||||||
|
* @param cb Callback function with parameter (success: Boolean)
|
||||||
|
*/
|
||||||
|
fun ClearQueueTable(cb: Consumer<Boolean>){
|
||||||
|
Connect { success, connection ->
|
||||||
|
if (success){
|
||||||
|
try {
|
||||||
|
connection!!.prepareStatement("TRUNCATE TABLE aas.queue_table").use { statement ->
|
||||||
|
val rowsAffected = statement.executeUpdate()
|
||||||
|
connection.close()
|
||||||
|
Logger.info { "ClearQueueTable succeeded, deleted $rowsAffected records" }
|
||||||
|
cb.accept(true)
|
||||||
|
_successcount++
|
||||||
|
}
|
||||||
|
} catch (e: Exception){
|
||||||
|
Logger.error { "ClearQueueTable failed, exception: ${e.message}" }
|
||||||
|
cb.accept(false)
|
||||||
|
_failcount++
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Logger.error { "ClearQueueTable failed, no Connection" }
|
||||||
|
cb.accept(false)
|
||||||
|
_failcount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete records from Queue Table by index
|
||||||
|
* @param index Vararg of record IDs to delete
|
||||||
|
* @param cb Callback function with parameter (success: Boolean)
|
||||||
|
*/
|
||||||
|
fun DeleteQueueTable(vararg index: Int, cb: Consumer<Boolean>){
|
||||||
|
Connect { success, connection ->
|
||||||
|
if (success){
|
||||||
|
try{
|
||||||
|
var updatecount : IntArray
|
||||||
|
connection!!.prepareStatement("DELETE FROM aas.queue_table WHERE id = ?").use { ps ->
|
||||||
|
index.forEach { id ->
|
||||||
|
ps.setInt(1, id)
|
||||||
|
ps.addBatch()
|
||||||
|
}
|
||||||
|
updatecount = ps.executeBatch()
|
||||||
|
ps.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
connection.close()
|
||||||
|
Logger.info { "Deleted ${index.size} records from AAS$aas_id Queue Table, update counts: ${updatecount.joinToString()}" }
|
||||||
|
cb.accept(true)
|
||||||
|
_successcount++
|
||||||
|
} catch (e : Exception){
|
||||||
|
Logger.error { "Failed to delete MySQL Adapter for AAS$aas_id: ${e.message}" }
|
||||||
|
cb.accept(false)
|
||||||
|
_failcount++
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Logger.error { "DeleteQueueTable failed , no Connection" }
|
||||||
|
cb.accept(false)
|
||||||
|
_failcount++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,8 +289,9 @@ class MySQLAdapter(val aas_id: Int) {
|
|||||||
/**
|
/**
|
||||||
* Insert records to Queue Table
|
* Insert records to Queue Table
|
||||||
* @param queue Vararg of QueueTableData to insert
|
* @param queue Vararg of QueueTableData to insert
|
||||||
|
* @param cb Callback function with parameter (success: Boolean)
|
||||||
*/
|
*/
|
||||||
fun InsertToQueueTable(vararg queue: QueueTableData){
|
fun InsertToQueueTable(vararg queue: QueueTableData, cb: Consumer<Boolean>){
|
||||||
Connect { success, connection ->
|
Connect { success, connection ->
|
||||||
if (success){
|
if (success){
|
||||||
var updatecount : IntArray
|
var updatecount : IntArray
|
||||||
@@ -98,13 +314,250 @@ class MySQLAdapter(val aas_id: Int) {
|
|||||||
|
|
||||||
connection.close()
|
connection.close()
|
||||||
Logger.info { "Inserted ${queue.size} records to AAS$aas_id Queue Table, update counts: ${updatecount.joinToString()}" }
|
Logger.info { "Inserted ${queue.size} records to AAS$aas_id Queue Table, update counts: ${updatecount.joinToString()}" }
|
||||||
|
cb.accept(true)
|
||||||
|
_successcount++
|
||||||
} catch (e : Exception){
|
} catch (e : Exception){
|
||||||
Logger.error { "Failed to insert MySQL Adapter for AAS$aas_id: ${e.message}" }
|
Logger.error { "Failed to insert MySQL Adapter for AAS$aas_id: ${e.message}" }
|
||||||
|
cb.accept(false)
|
||||||
|
_failcount++
|
||||||
}
|
}
|
||||||
|
|
||||||
} else Logger.error { "InsertToQueueTable failed , no Connection" }
|
} else {
|
||||||
|
Logger.error { "InsertToQueueTable failed , no Connection" }
|
||||||
|
cb.accept(false)
|
||||||
|
_failcount++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Flight Filter Table if not exists
|
||||||
|
* @param cb Callback function with parameter (success: Boolean)
|
||||||
|
*/
|
||||||
|
fun CreateFlightFilterTable(cb: Consumer<Boolean>){
|
||||||
|
Connect { success, connection ->
|
||||||
|
if (success){
|
||||||
|
try {
|
||||||
|
connection!!.prepareStatement(
|
||||||
|
"""
|
||||||
|
CREATE TABLE IF NOT EXISTS aas.tblFlightFilter (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
description VARCHAR(35) NOT NULL,
|
||||||
|
airlineCode VARCHAR(4) NOT NULL,
|
||||||
|
flightNumber VARCHAR(4) NOT NULL,
|
||||||
|
departureZone VARCHAR(512) NOT NULL,
|
||||||
|
arrivalZone VARCHAR(512) NOT NULL
|
||||||
|
);
|
||||||
|
""".trimIndent()
|
||||||
|
).use { statement ->
|
||||||
|
statement.executeUpdate()
|
||||||
|
connection.close()
|
||||||
|
Logger.info { "CreateFlightFilterTable succeeded or already exists" }
|
||||||
|
cb.accept(true)
|
||||||
|
_successcount++
|
||||||
|
}
|
||||||
|
} catch (e: Exception){
|
||||||
|
Logger.error { "CreateFlightFilterTable failed, exception: ${e.message}" }
|
||||||
|
cb.accept(false)
|
||||||
|
_failcount++
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Logger.error { "CreateFlightFilterTable failed, no Connection" }
|
||||||
|
cb.accept(false)
|
||||||
|
_failcount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear Flight Filter Table
|
||||||
|
* @param cb Callback function with parameter (success: Boolean)
|
||||||
|
*/
|
||||||
|
fun ClearFlightFilterTable(cb: Consumer<Boolean>){
|
||||||
|
Connect { success, connection ->
|
||||||
|
if (success){
|
||||||
|
try {
|
||||||
|
connection!!.prepareStatement("TRUNCATE TABLE aas.tblFlightFilter").use { statement ->
|
||||||
|
val rowsAffected = statement.executeUpdate()
|
||||||
|
connection.close()
|
||||||
|
Logger.info { "ClearFlightFilterTable succeeded, deleted $rowsAffected records" }
|
||||||
|
cb.accept(true)
|
||||||
|
_successcount++
|
||||||
|
}
|
||||||
|
} catch (e: Exception){
|
||||||
|
Logger.error { "ClearFlightFilterTable failed, exception: ${e.message}" }
|
||||||
|
cb.accept(false)
|
||||||
|
_failcount++
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Logger.error { "ClearFlightFilterTable failed, no Connection" }
|
||||||
|
cb.accept(false)
|
||||||
|
_failcount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Flight Filter Table records
|
||||||
|
* @param cb Callback function with parameters (success: Boolean, records: ArrayList<FlightFilter>)
|
||||||
|
*/
|
||||||
|
fun GetFlightFilterTable(cb: BiConsumer<Boolean, ArrayList<FlightFilter>>){
|
||||||
|
Connect { success, connection ->
|
||||||
|
if (success){
|
||||||
|
try{
|
||||||
|
connection!!.prepareStatement("SELECT * FROM aas.tblFlightFilter").use { statement ->
|
||||||
|
statement.executeQuery().use { rs ->
|
||||||
|
val result = ArrayList<FlightFilter>()
|
||||||
|
while (rs.next()){
|
||||||
|
result.add(
|
||||||
|
FlightFilter(
|
||||||
|
id = rs.getInt("id"),
|
||||||
|
Description = rs.getString("description"),
|
||||||
|
AirlineCode = rs.getString("airlineCode"),
|
||||||
|
FlightNumber = rs.getString("flightNumber"),
|
||||||
|
DepartureZone = rs.getString("departureZone"),
|
||||||
|
ArrivalZone = rs.getString("arrivalZone")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
connection.close()
|
||||||
|
Logger.info { "GetFlightFilterTable succeeded, found ${result.size} records" }
|
||||||
|
cb.accept(true, result)
|
||||||
|
_successcount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e : Exception){
|
||||||
|
Logger.error { "GetFlightFilterTable failed, exception: ${e.message}" }
|
||||||
|
cb.accept(false, arrayListOf())
|
||||||
|
_failcount++
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Logger.error { "GetFlightFilterTable failed, no Connection" }
|
||||||
|
cb.accept(false, arrayListOf())
|
||||||
|
_failcount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patch record in Flight Filter Table by index
|
||||||
|
* @param index Record ID to patch
|
||||||
|
* @param flight FlightFilter data to update
|
||||||
|
* @param cb Callback function with parameter (success: Boolean)
|
||||||
|
*/
|
||||||
|
fun PatchFlightFilter(index: Int, flight : FlightFilter, cb: Consumer<Boolean>){
|
||||||
|
Connect { success, connection ->
|
||||||
|
if (success){
|
||||||
|
try{
|
||||||
|
connection!!.prepareStatement("UPDATE aas.tblFlightFilter SET description = ?, airlineCode = ?, flightNumber = ?, departureZone = ?, arrivalZone = ? WHERE id = ?").use { ps ->
|
||||||
|
ps.setString(1, flight.Description)
|
||||||
|
ps.setString(2, flight.AirlineCode)
|
||||||
|
ps.setString(3, flight.FlightNumber)
|
||||||
|
ps.setString(4, flight.DepartureZone)
|
||||||
|
ps.setString(5, flight.ArrivalZone)
|
||||||
|
ps.setInt(6, index)
|
||||||
|
val updatecount = ps.executeUpdate()
|
||||||
|
ps.close()
|
||||||
|
|
||||||
|
connection.close()
|
||||||
|
Logger.info { "Patched record $index in AAS$aas_id Flight Filter Table, update count: $updatecount" }
|
||||||
|
cb.accept(true)
|
||||||
|
_successcount++
|
||||||
|
}
|
||||||
|
} catch (e : Exception){
|
||||||
|
Logger.error { "Failed to patch MySQL Adapter for AAS$aas_id Flight Filter: ${e.message}" }
|
||||||
|
cb.accept(false)
|
||||||
|
_failcount++
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Logger.error { "PatchFlightFilter failed , no Connection" }
|
||||||
|
cb.accept(false)
|
||||||
|
_failcount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete records from Flight Filter Table by index
|
||||||
|
* @param index Vararg of record IDs to delete
|
||||||
|
* @param cb Callback function with parameter (success: Boolean)
|
||||||
|
*/
|
||||||
|
fun DeleteFlightFilter(vararg index: Int, cb: Consumer<Boolean>){
|
||||||
|
Connect { success, connection ->
|
||||||
|
if (success){
|
||||||
|
try{
|
||||||
|
var updatecount : IntArray
|
||||||
|
connection!!.prepareStatement("DELETE FROM aas.tblFlightFilter WHERE id = ?").use { ps ->
|
||||||
|
index.forEach { id ->
|
||||||
|
ps.setInt(1, id)
|
||||||
|
ps.addBatch()
|
||||||
|
}
|
||||||
|
updatecount = ps.executeBatch()
|
||||||
|
ps.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
connection.close()
|
||||||
|
Logger.info { "Deleted ${index.size} records from AAS$aas_id Flight Filter Table, update counts: ${updatecount.joinToString()}" }
|
||||||
|
cb.accept(true)
|
||||||
|
_successcount++
|
||||||
|
} catch (e : Exception){
|
||||||
|
Logger.error { "Failed to delete MySQL Adapter for AAS$aas_id Flight Filter: ${e.message}" }
|
||||||
|
cb.accept(false)
|
||||||
|
_failcount++
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Logger.error { "DeleteFlightFilter failed , no Connection" }
|
||||||
|
cb.accept(false)
|
||||||
|
_failcount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert records to Flight Filter Table
|
||||||
|
* @param ff Vararg of FlightFilter to insert
|
||||||
|
* @param cb Callback function with parameter (success: Boolean)
|
||||||
|
*/
|
||||||
|
fun InsertFlightFilter(vararg ff: FlightFilter, cb: Consumer<Boolean>){
|
||||||
|
Connect { success, connection ->
|
||||||
|
if (success){
|
||||||
|
try{
|
||||||
|
var updatecount : IntArray
|
||||||
|
connection!!.prepareStatement("INSERT INTO aas.tblFlightFilter (description, airlineCode, flightNumber, departureZone, arrivalZone) VALUES (?,?,?,?,?)").use { ps ->
|
||||||
|
ff.forEach { data ->
|
||||||
|
ps.setString(1, data.Description)
|
||||||
|
ps.setString(2, data.AirlineCode)
|
||||||
|
ps.setString(3, data.FlightNumber)
|
||||||
|
ps.setString(4, data.DepartureZone)
|
||||||
|
ps.setString(5, data.ArrivalZone)
|
||||||
|
ps.addBatch()
|
||||||
|
}
|
||||||
|
updatecount = ps.executeBatch()
|
||||||
|
ps.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
connection.close()
|
||||||
|
Logger.info { "Inserted ${ff.size} records to AAS$aas_id Flight Filter Table, update counts: ${updatecount.joinToString()}" }
|
||||||
|
cb.accept(true)
|
||||||
|
_successcount++
|
||||||
|
} catch (e : Exception){
|
||||||
|
Logger.error { "Failed to insert MySQL Adapter for AAS$aas_id Flight Filter: ${e.message}" }
|
||||||
|
cb.accept(false)
|
||||||
|
_failcount++
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Logger.error { "InsertFlightFilter failed , no Connection" }
|
||||||
|
cb.accept(false)
|
||||||
|
_failcount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
|
|
||||||
data class QueueTableData(val Date_Time: String, val Source: String, val Tipe: String, val Message: String, val SB_Tags: String, val BroadcastZones: String, val Language: String)
|
data class QueueTableData(val Date_Time: String, val Source: String, val Tipe: String, val Message: String, val SB_Tags: String, val BroadcastZones: String, val Language: String)
|
||||||
|
|||||||
Reference in New Issue
Block a user