commit 07/10/2025
This commit is contained in:
15
src/Main.kt
15
src/Main.kt
@@ -1,5 +1,6 @@
|
||||
import audio.AudioPlayer
|
||||
import audio.ContentCache
|
||||
import audio.TCPReceiver
|
||||
import audio.UDPReceiver
|
||||
import barix.BarixConnection
|
||||
import barix.TCP_Barix_Command_Server
|
||||
@@ -27,6 +28,7 @@ lateinit var db: MariaDB
|
||||
lateinit var audioPlayer: AudioPlayer
|
||||
val StreamerOutputs: MutableMap<String, BarixConnection> = HashMap()
|
||||
lateinit var udpreceiver: UDPReceiver
|
||||
lateinit var tcpreceiver: TCPReceiver
|
||||
const val version = "0.0.2 (23/09/2025)"
|
||||
// AAS 64 channels
|
||||
const val max_channel = 64
|
||||
@@ -140,6 +142,15 @@ fun main() {
|
||||
Logger.error { "Failed to start UDP Receiver on port 5002" }
|
||||
}
|
||||
|
||||
tcpreceiver = TCPReceiver()
|
||||
if (tcpreceiver.Start()) {
|
||||
Logger.info { "TCP Receiver started on port 5002" }
|
||||
} else {
|
||||
Logger.error { "Failed to start TCP Receiver on port 5002" }
|
||||
}
|
||||
|
||||
|
||||
|
||||
val androidserver = TCP_Android_Command_Server()
|
||||
androidserver.StartTcpServer(5003){
|
||||
Logger.info { it }
|
||||
@@ -182,14 +193,18 @@ fun main() {
|
||||
}
|
||||
}
|
||||
|
||||
db.Add_Log("AAS"," Application started")
|
||||
|
||||
// shutdown hook
|
||||
Runtime.getRuntime().addShutdownHook(Thread {
|
||||
db.Add_Log("AAS"," Application stopping")
|
||||
Logger.info { "Shutdown hook called, stopping services..." }
|
||||
barixserver.StopTcpCommand()
|
||||
androidserver.StopTcpCommand()
|
||||
onlinechecker.cancel()
|
||||
web.Stop()
|
||||
udpreceiver.Stop()
|
||||
tcpreceiver.Stop()
|
||||
audioPlayer.Close()
|
||||
db.close()
|
||||
Logger.info { "All services stopped, exiting application." }
|
||||
|
||||
@@ -183,7 +183,9 @@ class MainExtension01 {
|
||||
*/
|
||||
fun Get_Soundbank_Data(value: String) : Map<String, String>? {
|
||||
if (ValidString(value)){
|
||||
//println("Parsing soundbank data from value: $value")
|
||||
val values = value.split(" ").map { it.trim() }.filter { ValidString(it) }
|
||||
//println("Split into values: $values")
|
||||
if (values.isNotEmpty()){
|
||||
val result = mutableMapOf<String, String>()
|
||||
values.forEach {
|
||||
@@ -192,6 +194,7 @@ class MainExtension01 {
|
||||
// ada separator
|
||||
val key = it.substring(0, separatorindex).trim().uppercase()
|
||||
val value = it.substring(separatorindex+1).trim().uppercase()
|
||||
//println("Got $key : $value")
|
||||
if (ValidString(key) && ValidString(value)){
|
||||
if (SoundbankKeywords.contains(key)) result[key] = value
|
||||
}
|
||||
@@ -338,11 +341,9 @@ class MainExtension01 {
|
||||
files.add(city.Path)
|
||||
} else {
|
||||
return Result_GetSoundbankFiles(false, "Invalid soundbank file ${city.Path} for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}")
|
||||
|
||||
}
|
||||
} else {
|
||||
return Result_GetSoundbankFiles(false, "No City found for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}")
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -537,7 +538,7 @@ class MainExtension01 {
|
||||
fun Read_Queue_Paging() : Boolean{
|
||||
db.queuepagingDB.Get()
|
||||
val list = db.queuepagingDB.List
|
||||
.filter { it.Source=="PAGING" }
|
||||
.filter { it.Type=="PAGING" }
|
||||
|
||||
list.forEach { qp ->
|
||||
println("Processing $qp")
|
||||
@@ -593,7 +594,7 @@ class MainExtension01 {
|
||||
fun Read_Queue_Shalat() : Boolean{
|
||||
db.queuepagingDB.Get()
|
||||
val list = db.queuepagingDB.List
|
||||
.filter { it.Source=="SHALAT" }
|
||||
.filter { it.Type=="SHALAT" }
|
||||
list.forEach { qp ->
|
||||
println("Processing $qp")
|
||||
if (qp.BroadcastZones.isNotBlank()){
|
||||
@@ -852,13 +853,15 @@ class MainExtension01 {
|
||||
|
||||
if (listafi.isNotEmpty()){
|
||||
db.queuetableDB.DeleteByIndex(qa.index.toInt())
|
||||
|
||||
val targetfile = SoundbankResult_directory.resolve(Make_WAV_FileName("Soundbank","")).toString()
|
||||
println("Writing to target WAV file: $targetfile")
|
||||
// bikin nama file ada postifx nya dari SB_TAGS, tapi spasi diganti underscore
|
||||
// dan titik dua diganti dash
|
||||
val postfix = qa.SB_TAGS.replace(" ","_").replace(":","-")
|
||||
val targetfile = SoundbankResult_directory.resolve(Make_WAV_FileName("${qa.Source}_${qa.Type}",postfix)).toString()
|
||||
//println("Writing to target WAV file: $targetfile")
|
||||
val result = audioPlayer.WavWriter(listafi, targetfile, true)
|
||||
if (result.success){
|
||||
// file siap broadcast
|
||||
println("Successfully wrote WAV file: $targetfile")
|
||||
//println("Successfully wrote WAV file: $targetfile")
|
||||
val targetafi = audioPlayer.LoadAudioFile(targetfile)
|
||||
if (targetafi.isValid()) {
|
||||
ips.forEach { ip -> StreamerOutputs[ip]?.SendData(targetafi.bytes, { db.Add_Log("AAS", it) }, { db.Add_Log("AAS", it) }) }
|
||||
|
||||
@@ -143,8 +143,7 @@ class AudioPlayer (var samplingrate: Int) {
|
||||
mem.write(0, data, 0, data.size)
|
||||
val pushresult = bass.BASS_StreamPutData(streamhandle, mem, data.size)
|
||||
if (pushresult==-1){
|
||||
val errcode = bass.BASS_ErrorGetCode()
|
||||
println("BASS_StreamPutData failed: $errcode")
|
||||
Logger.error { "BASS_StreamPutData failed: ${bass.BASS_ErrorGetCode()}" }
|
||||
}
|
||||
return pushresult != -1
|
||||
}
|
||||
@@ -154,32 +153,27 @@ class AudioPlayer (var samplingrate: Int) {
|
||||
if (withChime){
|
||||
val chup = contentCache.getAudioFile("chimeup")
|
||||
if (chup!=null && chup.isValid()){
|
||||
if (pushData(chup.bytes)){
|
||||
println("Chime up pushed")
|
||||
} else {
|
||||
if (!pushData(chup.bytes)){
|
||||
all_success = false
|
||||
println("Chime up failed")
|
||||
Logger.error { "Failed to push Chime Up" }
|
||||
}
|
||||
} else println("Chime Up not valid")
|
||||
} else Logger.error { "withChime=true, but Chime Up not available" }
|
||||
}
|
||||
|
||||
if (pushData(data)){
|
||||
println("Data pushed")
|
||||
} else {
|
||||
if (!pushData(data)){
|
||||
all_success = false
|
||||
println("Data push failed")
|
||||
Logger.error { "Failed to push Data ByteArray" }
|
||||
}
|
||||
|
||||
|
||||
if (withChime){
|
||||
val chdn = contentCache.getAudioFile("chimedown")
|
||||
if (chdn!=null && chdn.isValid()){
|
||||
if (pushData(chdn.bytes)){
|
||||
println("Chime down pushed")
|
||||
} else {
|
||||
if (!pushData(chdn.bytes)){
|
||||
all_success = false
|
||||
println("Chime down failed")
|
||||
Logger.error { "Failed to push Chime Down" }
|
||||
}
|
||||
} else println("Chime Down not valid")
|
||||
} else Logger.error { "withChime=true, but Chime Down not available" }
|
||||
}
|
||||
|
||||
val readsize: Long = 1024 * 1024 // read 1 MB at a time
|
||||
@@ -191,7 +185,6 @@ class AudioPlayer (var samplingrate: Int) {
|
||||
totalread += read
|
||||
}
|
||||
} while (read > 0)
|
||||
println("Finished reading stream data, total $totalread bytes read")
|
||||
bassenc.BASS_Encode_Stop(encodehandle)
|
||||
bass.BASS_StreamFree(streamhandle)
|
||||
|
||||
@@ -246,8 +239,7 @@ class AudioPlayer (var samplingrate: Int) {
|
||||
mem.write(0, data, 0, data.size)
|
||||
val pushresult = bass.BASS_StreamPutData(streamhandle, mem, data.size)
|
||||
if (pushresult==-1){
|
||||
val errcode = bass.BASS_ErrorGetCode()
|
||||
println("BASS_StreamPutData failed: $errcode")
|
||||
Logger.error { "BASS_StreamPutData failed: ${bass.BASS_ErrorGetCode()}" }
|
||||
}
|
||||
return pushresult != -1
|
||||
}
|
||||
@@ -258,39 +250,34 @@ class AudioPlayer (var samplingrate: Int) {
|
||||
if (withChime){
|
||||
val chup = contentCache.getAudioFile("chimeup")
|
||||
if (chup!=null && chup.isValid()){
|
||||
if (pushData(chup.bytes)){
|
||||
println("Chime up pushed")
|
||||
} else {
|
||||
if (!pushData(chup.bytes)){
|
||||
allsuccess = false
|
||||
println("Chime up failed")
|
||||
Logger.error { "Failed to push Chime Up" }
|
||||
}
|
||||
} else println("Chime Up not valid")
|
||||
} else Logger.error { "withChime=true, but Chime Up not available" }
|
||||
}
|
||||
sources.forEach { source ->
|
||||
if (source.isValid()) {
|
||||
// write the bytes to the stream
|
||||
if (pushData(source.bytes)){
|
||||
println("Source ${source.fileName} pushed")
|
||||
} else {
|
||||
if (!pushData(source.bytes)){
|
||||
allsuccess = false
|
||||
println("Source ${source.fileName} push failed")
|
||||
Logger.error { "Source ${source.fileName} push failed" }
|
||||
}
|
||||
|
||||
} else {
|
||||
allsuccess = false
|
||||
println("Source ${source.fileName} is not valid")
|
||||
Logger.error { "Not pushing Source=${source.fileName} because invalid" }
|
||||
}
|
||||
|
||||
}
|
||||
if (withChime){
|
||||
val chdn = contentCache.getAudioFile("chimedown")
|
||||
if (chdn!=null && chdn.isValid()){
|
||||
if (pushData(chdn.bytes)){
|
||||
println("Chime down pushed")
|
||||
} else {
|
||||
if (!pushData(chdn.bytes)){
|
||||
allsuccess = false
|
||||
println("Chime down failed")
|
||||
Logger.error { "Failed to push Chime Down" }
|
||||
}
|
||||
} else println("Chime Down not valid")
|
||||
} else Logger.error { "withChime=true, but Chime Down not available"}
|
||||
}
|
||||
|
||||
val readsize: Long = 1024 * 1024 // read 1 MB at a time
|
||||
@@ -302,7 +289,6 @@ class AudioPlayer (var samplingrate: Int) {
|
||||
totalread += read
|
||||
}
|
||||
} while (read > 0)
|
||||
println("Finished reading stream data, total $totalread bytes read")
|
||||
|
||||
|
||||
// close the encoding handle
|
||||
|
||||
104
src/audio/TCPReceiver.kt
Normal file
104
src/audio/TCPReceiver.kt
Normal file
@@ -0,0 +1,104 @@
|
||||
package audio
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.tinylog.Logger
|
||||
import java.net.ServerSocket
|
||||
import java.util.function.Consumer
|
||||
|
||||
/**
|
||||
* TCPReceiver is a class that listens for TCP connections on a specified port.
|
||||
* for receiving PCMFILE from Android SAMI
|
||||
*/
|
||||
class TCPReceiver(val portnumber: Int = 5002){
|
||||
private lateinit var server: ServerSocket
|
||||
private var isRunning = false
|
||||
private val dataCallback = mutableMapOf<String, Consumer<ByteArray>>()
|
||||
private val isfinishd = mutableMapOf<String, Boolean>()
|
||||
|
||||
/**
|
||||
* Start listening for TCP connections on the specified port.
|
||||
* @return true if successful, false otherwise
|
||||
*/
|
||||
fun Start() : Boolean{
|
||||
try{
|
||||
server = ServerSocket(portnumber)
|
||||
isRunning = true
|
||||
Logger.info { "Server started at port $portnumber" }
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
while(isRunning){
|
||||
try {
|
||||
val client = server.accept()
|
||||
val clientAddress = client.inetAddress.hostAddress
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
|
||||
isfinishd[clientAddress] = false
|
||||
var totalbytes = 0L
|
||||
try{
|
||||
val din = client.getInputStream()
|
||||
Logger.info{ "Start receiving PCMFILE from Android with IP=${clientAddress}" }
|
||||
|
||||
do {
|
||||
val buffer = ByteArray(16384)
|
||||
val bytesRead = din.read(buffer)
|
||||
if (bytesRead>0){
|
||||
val data = ByteArray(bytesRead)
|
||||
System.arraycopy(buffer, 0, data, 0, bytesRead)
|
||||
//println("Received $bytesRead bytes from $clientAddress")
|
||||
totalbytes+=bytesRead
|
||||
dataCallback[clientAddress].let {
|
||||
it?.accept(data)
|
||||
}
|
||||
}
|
||||
} while (bytesRead > 0)
|
||||
} catch (e : Exception){
|
||||
Logger.error { "Failed receiving data from $clientAddress, Message : ${e.message}" }
|
||||
}
|
||||
Logger.info { "Connection from $clientAddress ended, total bytesRead=$totalbytes" }
|
||||
isfinishd[clientAddress] = true
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Logger.error { "Failed to accept socket, Message : ${e.message}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
} catch (e : Exception){
|
||||
Logger.error { "Failed to Start Server at port $portnumber, Message : ${e.message}" }
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
fun RequestDataFrom(ipaddress: String, cb: Consumer<ByteArray>){
|
||||
dataCallback[ipaddress] = cb
|
||||
}
|
||||
|
||||
fun StopRequestDataFrom(ipaddress: String){
|
||||
if (isfinishd[ipaddress] != null){
|
||||
if (isfinishd[ipaddress]==false){
|
||||
// belum selesai
|
||||
//println("Waiting for receiving from $ipaddress to finish...")
|
||||
runBlocking {
|
||||
while (isfinishd[ipaddress] == false){
|
||||
kotlinx.coroutines.delay(100)
|
||||
}
|
||||
}
|
||||
}
|
||||
//println("Removing callback for $ipaddress")
|
||||
dataCallback.remove(ipaddress)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop listening for TCP connections and close the server socket.
|
||||
*/
|
||||
fun Stop(){
|
||||
if (isRunning){
|
||||
isRunning = false
|
||||
server.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package commandServer
|
||||
|
||||
import codes.Somecodes.Companion.PagingResult_directory
|
||||
import codes.Somecodes.Companion.filenameformat
|
||||
import org.tinylog.Logger
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.nio.file.Path
|
||||
import java.time.LocalDateTime
|
||||
@@ -18,6 +17,11 @@ class PagingJob(val fromIP: String, val broadcastzones: String) {
|
||||
var totalBytesReceived = 0; private set
|
||||
var isRunning = true; private set
|
||||
|
||||
/**
|
||||
* Expected Size from PCMFILE android
|
||||
*/
|
||||
var expectedSize = 0
|
||||
|
||||
|
||||
/**
|
||||
* Adds incoming audio data to the job.
|
||||
|
||||
@@ -3,6 +3,7 @@ package commandServer
|
||||
import audioPlayer
|
||||
import codes.Somecodes.Companion.ValidString
|
||||
import codes.Somecodes.Companion.datetimeformat1
|
||||
import content.Category
|
||||
import content.Language
|
||||
import database.Messagebank
|
||||
import database.QueuePaging
|
||||
@@ -16,6 +17,7 @@ import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.tinylog.Logger
|
||||
import tcpreceiver
|
||||
import udpreceiver
|
||||
import java.net.ServerSocket
|
||||
import java.net.Socket
|
||||
@@ -167,102 +169,158 @@ class TCP_Android_Command_Server {
|
||||
}
|
||||
}
|
||||
|
||||
"PCMFILE_START","STARTPAGINGAND" -> {
|
||||
//TODO Paging IPM1 success, Paging IPMT gagal
|
||||
val zones = parts.getOrElse(1) { "" }.replace(",",";")
|
||||
"PCMFILE_START" ->{
|
||||
// start sending PCM data from Android for paging
|
||||
val size = parts.getOrElse(1) { "0" }.toInt()
|
||||
val filename = parts.getOrElse(2) { "" }
|
||||
val zones = parts.getOrElse(3) { "" }.replace(",",";")
|
||||
if (size>0){
|
||||
if (ValidString(filename)){
|
||||
if (ValidString(zones)){
|
||||
// create paging job
|
||||
val pj = PagingJob(key, zones)
|
||||
// ada expected size
|
||||
pj.expectedSize = size
|
||||
// masukin ke list
|
||||
listOnGoingPaging[key] = pj
|
||||
Logger.info{"PagingJob created for Android $key, zones: $zones, file: ${pj.filePath.absolutePathString()}"}
|
||||
|
||||
// start minta data dari udpreceiver
|
||||
udpreceiver.RequestDataFrom(key){
|
||||
tcpreceiver.RequestDataFrom(key) {
|
||||
// push data ke paging job
|
||||
pj.addData(it, it.size)
|
||||
}
|
||||
logcb.accept("Paging started from Android $key")
|
||||
cb.accept(parts[0]+";OK@")
|
||||
cb.accept("PCMFILE_START;OK@")
|
||||
Logger.info{"Android $key start sending PCM data, expecting $size bytes"}
|
||||
return
|
||||
} else logcb.accept("Paging start from Android $key failed, empty zones")
|
||||
cb.accept(parts[0]+";NG@")
|
||||
}
|
||||
|
||||
"PCMFILE_STOP","STOPPAGINGAND" -> {
|
||||
// TODO Paging IPM1 success, Paging IPMT gagal
|
||||
} else logcb.accept("PCMFILE_START from Android $key failed, empty zones")
|
||||
} else logcb.accept("PCMFILE_START from Android $key failed, empty filename")
|
||||
} else logcb.accept("PCMFILE_START from Android $key failed, invalid size")
|
||||
cb.accept("PCMFILE_START;NG@")
|
||||
}
|
||||
"PCMFILE_STOP" -> {
|
||||
// stop sending PCM data from Android for paging
|
||||
val pj = listOnGoingPaging[key]
|
||||
if (pj!=null) {
|
||||
listOnGoingPaging.remove(key)
|
||||
udpreceiver.StopRequestDataFrom(key)
|
||||
logcb.accept("Paging stopped from Android $key")
|
||||
cb.accept(parts[0]+";OK@")
|
||||
tcpreceiver.StopRequestDataFrom(key)
|
||||
// get remaining data
|
||||
val data = pj.GetData()
|
||||
pj.Close()
|
||||
if (data.size==pj.expectedSize){
|
||||
Logger.info { "Paging job closed from Android $key, total bytes received ${data.size}, writing to file ${pj.filePath.absolutePathString()}" }
|
||||
val result = audioPlayer.WavWriter(data, pj.filePath.absolutePathString(), true)
|
||||
if (result.success) {
|
||||
val qp = QueuePaging(
|
||||
0u,
|
||||
LocalDateTime.now().format(datetimeformat1),
|
||||
"ANDROID",
|
||||
"PAGING",
|
||||
"NORMAL",
|
||||
pj.filePath.absolutePathString(),
|
||||
pj.broadcastzones
|
||||
)
|
||||
if (db.queuepagingDB.Add(qp)) {
|
||||
logcb.accept("Paging audio inserted to queue paging table from Android $key, file ${pj.filePath.absolutePathString()}")
|
||||
cb.accept(parts[0]+";OK@")
|
||||
} else {
|
||||
logcb.accept("Failed to insert paging audio to queue paging table from Android $key, file ${pj.filePath.absolutePathString()}")
|
||||
cb.accept(parts[0]+";NG@")
|
||||
}
|
||||
} else {
|
||||
logcb.accept("Failed to write paging audio to file ${pj.filePath.absolutePathString()}, Message : ${result.message}")
|
||||
cb.accept(parts[0]+";NG@")
|
||||
cb.accept("PCMFILE_STOP;OK@")
|
||||
return
|
||||
} else logcb.accept("Failed to insert paging audio to queue paging table from Android $key, file ${pj.filePath.absolutePathString()}")
|
||||
} else logcb.accept("Failed to write paging audio to file ${pj.filePath.absolutePathString()}, Message : ${result.message}")
|
||||
} else logcb.accept("PCMFILE_STOP from Android $key received size ${data.size} does not match expected ${pj.expectedSize}")
|
||||
} else logcb.accept("PCMFILE_STOP from Android $key failed, no ongoing PCM data receiving")
|
||||
cb.accept("PCMFILE_STOP;NG@")
|
||||
}
|
||||
|
||||
"STARTPAGINGAND" -> {
|
||||
// Start Paging request from IPM
|
||||
val zones = parts.getOrElse(1) { "" }.replace(",",";")
|
||||
if (ValidString(zones)){
|
||||
// create pagingjob
|
||||
val pj = PagingJob(key, zones)
|
||||
// masukin ke list
|
||||
listOnGoingPaging[key] = pj
|
||||
Logger.info{"PagingJob created for IPM $key, zones: $zones, file: ${pj.filePath.absolutePathString()}"}
|
||||
|
||||
} else {
|
||||
logcb.accept("Paging stop from Android $key failed, no ongoing paging")
|
||||
cb.accept(parts[0]+";NG@")
|
||||
// start minta data dari udpreceiver
|
||||
udpreceiver.RequestDataFrom(key){
|
||||
// push data ke paging job
|
||||
pj.addData(it, it.size)
|
||||
}
|
||||
logcb.accept("Paging started from IPM $key")
|
||||
cb.accept("STARTPAGINGAND;OK@")
|
||||
return
|
||||
} else logcb.accept("Paging start from IPM $key failed, empty zones")
|
||||
cb.accept("STARTPAGINGAND;NG@")
|
||||
}
|
||||
|
||||
"STOPPAGINGAND" -> {
|
||||
// stop paging request from IPM
|
||||
val pj = listOnGoingPaging[key]
|
||||
if (pj!=null){
|
||||
listOnGoingPaging.remove(key)
|
||||
udpreceiver.StopRequestDataFrom(key)
|
||||
logcb.accept("Paging stopped from IPM $key")
|
||||
// get remaining data
|
||||
val data = pj.GetData()
|
||||
pj.Close()
|
||||
Logger.info{"Paging job closed from IPM $key, total bytes received ${data.size}, writing to file ${pj.filePath.absolutePathString()}"}
|
||||
val result = audioPlayer.WavWriter(data, pj.filePath.absolutePathString(), true)
|
||||
if (result.success){
|
||||
val qp = QueuePaging(
|
||||
0u,
|
||||
LocalDateTime.now().format(datetimeformat1),
|
||||
"IPM",
|
||||
"PAGING",
|
||||
pj.filePath.absolutePathString(),
|
||||
pj.broadcastzones
|
||||
)
|
||||
if (db.queuepagingDB.Add(qp)){
|
||||
logcb.accept("Paging audio inserted to queue paging table from IPM $key, file ${pj.filePath.absolutePathString()}")
|
||||
cb.accept("STOPPAGINGAND;OK@")
|
||||
return
|
||||
} else logcb.accept("Failed to insert paging audio to queue paging table from IPM $key, file ${pj.filePath.absolutePathString()}")
|
||||
} else logcb.accept("Failed to write paging audio to file ${pj.filePath.absolutePathString()}, Message : ${result.message}")
|
||||
} else logcb.accept("Paging stop from IPM $key failed, no ongoing paging")
|
||||
cb.accept("STOPPAGINGAND;NG@")
|
||||
|
||||
}
|
||||
|
||||
"CANCELPAGINGAND" -> {
|
||||
// TODO Cancel Paging IPM1 success, IPMT gagal
|
||||
// cancel paging request from IPM
|
||||
val pj = listOnGoingPaging[key]
|
||||
if (pj!=null){
|
||||
pj.Close()
|
||||
listOnGoingPaging.remove(key)
|
||||
udpreceiver.StopRequestDataFrom(key)
|
||||
logcb.accept("Paging from Android $key cancelled")
|
||||
logcb.accept("Paging from IPM $key cancelled")
|
||||
cb.accept("CANCELPAGINGAND;OK@")
|
||||
return
|
||||
} else logcb.accept("Paging cancel from Android $key failed, no ongoing paging")
|
||||
} else logcb.accept("Paging cancel from IPM $key failed, no ongoing paging")
|
||||
cb.accept("CANCELPAGINGAND;NG@")
|
||||
|
||||
}
|
||||
|
||||
"STARTINITIALIZE" -> {
|
||||
// TODO STARTINITIALIZE IPM1 success, IPMT gagal
|
||||
val username = parts.getOrElse(1) { "" }
|
||||
if (ValidString(username)){
|
||||
val userlogin = listUserLogin.find { it.username == username }
|
||||
if (userlogin != null){
|
||||
val userdb = db.userDB.List.find { it.username == username }
|
||||
if (userdb != null){
|
||||
println("Sending initialization data to $key with username $username")
|
||||
val result = StringBuilder()
|
||||
// kirim Zone
|
||||
result.append("ZONE")
|
||||
userdb.broadcastzones.split(";").map { it.trim() }.filter { it.isNotBlank() }.forEach {
|
||||
result.append(";")
|
||||
result.append(it)
|
||||
}
|
||||
result.append("@")
|
||||
cb.accept(result.toString())
|
||||
|
||||
// kirim MSGTOTAL
|
||||
result.clear()
|
||||
val VARMESSAGES = mutableListOf<Messagebank>()
|
||||
result.append("MSGTOTAL;")
|
||||
userdb.messagebank_ann_id
|
||||
// messagebank_ann_id adalah rentengan ANN_ID (digit) yang dipisah dengan ;
|
||||
.split(";")
|
||||
@@ -270,112 +328,272 @@ class TCP_Android_Command_Server {
|
||||
.map { it.trim() }
|
||||
// bukan string kosong antar dua tanda ;
|
||||
.filter { it.isNotBlank() }
|
||||
// beneran digit semua
|
||||
.filter { xx -> xx.all{it.isDigit()} }
|
||||
// iterasi setiap ANN_ID
|
||||
.forEach { annid ->
|
||||
// masukin ke VARMESSAGES yang unik secara ANN_ID dan Language
|
||||
val xx = db.messageDB.List
|
||||
.filter{ it.ANN_ID == annid.toUInt() }
|
||||
.distinctBy { it.Language }
|
||||
.distinctBy { it.ANN_ID }
|
||||
VARMESSAGES.addAll(xx)
|
||||
}
|
||||
result.append("MSGTOTAL;").append(VARMESSAGES.size).append("@")
|
||||
// VAR AP TOTAL
|
||||
val VARAPTOTAL = mutableListOf<Soundbank>()
|
||||
val al_split = userdb.airline_tags.split(";").map { it.trim() }.filter { it.isNotBlank() }
|
||||
al_split.forEach {
|
||||
val sb = db.Find_Soundbank_AirplaneName(it).firstOrNull()
|
||||
if (sb != null) VARAPTOTAL.add(sb)
|
||||
}
|
||||
result.append("VARAPTOTAL;").append(VARAPTOTAL.size).append("@")
|
||||
// VAR CITY TOTAL
|
||||
val VARCITYTOTAL = mutableListOf<Soundbank>()
|
||||
val ct_split = userdb.city_tags.split(";").map { it.trim() }.filter { it.isNotBlank() }
|
||||
ct_split.forEach {
|
||||
val sb = db.Find_Soundbank_City(it).firstOrNull()
|
||||
if (sb != null) VARCITYTOTAL.add(sb)
|
||||
}
|
||||
result.append("VARCITYTOTAL;").append(VARCITYTOTAL.size).append("@")
|
||||
// VAR PLACES TOTAL
|
||||
val VARPLACESTOTAL = mutableListOf<Soundbank>()
|
||||
// sb_split.forEach {
|
||||
// val sb = db.Find_Soundbank_Places(it).firstOrNull()
|
||||
// if (sb != null) VARPLACESTOTAL.add(sb)
|
||||
// }
|
||||
result.append("VARPLACESTOTAL;").append(VARPLACESTOTAL.size).append("@")
|
||||
// VAR SHALAT TOTAL
|
||||
val VARSHALATTOTAL = mutableListOf<Soundbank>()
|
||||
// sb_split.forEach {
|
||||
// val sb = db.Find_Soundbank_Shalat(it).firstOrNull()
|
||||
// if (sb != null) VARSHALATTOTAL.add(sb)
|
||||
// }
|
||||
result.append("VARSHALATTOTAL;").append(VARSHALATTOTAL.size).append("@")
|
||||
// VAR SEQUENCE TOTAL
|
||||
val VARSEQUENCETOTAL = mutableListOf<Soundbank>()
|
||||
// sb_split.forEach {
|
||||
// val sb = db.Find_Soundbank_Sequence(it).firstOrNull()
|
||||
// if (sb != null) VARSEQUENCETOTAL.add(sb)
|
||||
// }
|
||||
// VAR REASON TOTAL
|
||||
val VARREASONTOTAL = mutableListOf<Soundbank>()
|
||||
// sb_split.forEach {
|
||||
// val sb = db.Find_Soundbank_Reason(it).firstOrNull()
|
||||
// if (sb != null) VARREASONTOTAL.add(sb)
|
||||
// }
|
||||
result.append("VARREASONTOTAL;").append(VARREASONTOTAL.size).append("@")
|
||||
// VAR PROCEDURE TOTAL
|
||||
val VARPROCEDURETOTAL = mutableListOf<Soundbank>()
|
||||
// sb_split.forEach {
|
||||
// val sb = db.Find_Soundbank_Procedure(it).firstOrNull()
|
||||
// if (sb != null) VARPROCEDURETOTAL.add(sb)
|
||||
// }
|
||||
result.append("VARPROCEDURETOTAL;").append(VARPROCEDURETOTAL.size).append("@")
|
||||
// send to sender
|
||||
result.append(VARMESSAGES.size).append("@")
|
||||
cb.accept(result.toString())
|
||||
|
||||
// kirim VARAPTOTAL
|
||||
result.clear()
|
||||
result.append("VARAPTOTAL;")
|
||||
val VARAPTOTAL = mutableListOf<Soundbank>()
|
||||
userdb.airline_tags
|
||||
.split(";")
|
||||
.map { it.trim() }
|
||||
.filter { it.isNotBlank() }
|
||||
.forEach { al ->
|
||||
val sb = db.soundDB.List
|
||||
.filter { it.Category.equals(Category.Airplane_Name.name, true) }
|
||||
.filter { it.TAG.equals(al, true)}
|
||||
.distinctBy { it.TAG }
|
||||
VARAPTOTAL.addAll(sb)
|
||||
}
|
||||
result.append(VARAPTOTAL.size).append("@")
|
||||
cb.accept(result.toString())
|
||||
|
||||
// kirim VARCITYTOTAL
|
||||
result.clear()
|
||||
result.append("VARCITYTOTAL;")
|
||||
val VARCITYTOTAL = mutableListOf<Soundbank>()
|
||||
userdb.city_tags
|
||||
.split(";")
|
||||
.map { it.trim() }
|
||||
.filter { it.isNotBlank() }
|
||||
.forEach { ct ->
|
||||
val sb = db.soundDB.List
|
||||
.filter { it.Category.equals(Category.City.name, true) }
|
||||
.filter { it.TAG.equals(ct, true)}
|
||||
.distinctBy { it.TAG }
|
||||
VARCITYTOTAL.addAll(sb)
|
||||
}
|
||||
result.append(VARCITYTOTAL.size).append("@")
|
||||
cb.accept(result.toString())
|
||||
|
||||
// kirim VARPLACESTOTAL
|
||||
result.clear()
|
||||
result.append("VARPLACESTOTAL;")
|
||||
val VARPLACESTOTAL = mutableListOf<Soundbank>()
|
||||
db.soundDB.List
|
||||
.filter { it.Category.equals(Category.Places.name, true) }
|
||||
.distinctBy { it.TAG }
|
||||
.forEach {
|
||||
VARPLACESTOTAL.add(it)
|
||||
}
|
||||
result.append(VARPLACESTOTAL.size).append("@")
|
||||
cb.accept(result.toString())
|
||||
|
||||
// kirim VARSHALATTOTAL
|
||||
result.clear()
|
||||
result.append("VARSHALATTOTAL;")
|
||||
val VARSHALATTOTAL = mutableListOf<Soundbank>()
|
||||
db.soundDB.List
|
||||
.filter { it.Category.equals(Category.Shalat.name, true) }
|
||||
.distinctBy { it.TAG }
|
||||
.forEach {
|
||||
VARSHALATTOTAL.add(it)
|
||||
}
|
||||
result.append(VARSHALATTOTAL.size).append("@")
|
||||
cb.accept(result.toString())
|
||||
|
||||
// kirim VARSEQUENCETOTAL
|
||||
result.clear()
|
||||
result.append("VARSEQUENCETOTAL;")
|
||||
val VARSEQUENCETOTAL = mutableListOf<Soundbank>()
|
||||
db.soundDB.List
|
||||
.filter { it.Category.equals(Category.Sequence.name, true) }
|
||||
.distinctBy { it.TAG }
|
||||
.forEach {
|
||||
VARSEQUENCETOTAL.add(it)
|
||||
}
|
||||
result.append(VARSEQUENCETOTAL.size).append("@")
|
||||
cb.accept(result.toString())
|
||||
|
||||
// kirim VARREASONTOTAL
|
||||
result.clear()
|
||||
result.append("VARREASONTOTAL;")
|
||||
val VARREASONTOTAL = mutableListOf<Soundbank>()
|
||||
db.soundDB.List
|
||||
.filter { it.Category.equals(Category.Reason.name, true) }
|
||||
.distinctBy { it.TAG }
|
||||
.forEach {
|
||||
VARREASONTOTAL.add(it)
|
||||
}
|
||||
result.append(VARREASONTOTAL.size).append("@")
|
||||
cb.accept(result.toString())
|
||||
|
||||
// kirim VARPROCEDURETOTAL
|
||||
val VARPROCEDURETOTAL = mutableListOf<Soundbank>()
|
||||
result.clear()
|
||||
result.append("VARPROCEDURETOTAL;")
|
||||
db.soundDB.List
|
||||
.filter { it.Category.equals(Category.Procedure.name, true) }
|
||||
.distinctBy { it.TAG }
|
||||
.forEach {
|
||||
VARPROCEDURETOTAL.add(it)
|
||||
}
|
||||
result.append(VARPROCEDURETOTAL.size).append("@")
|
||||
cb.accept(result.toString())
|
||||
|
||||
// kirim VARGATETOTAL
|
||||
val VARGATETOTAL = mutableListOf<Soundbank>()
|
||||
result.clear()
|
||||
result.append("VARGATETOTAL;")
|
||||
db.soundDB.List
|
||||
.filter { it.Category.equals(Category.Gate.name, true) }
|
||||
.distinctBy { it.TAG }
|
||||
.forEach {
|
||||
VARGATETOTAL.add(it)
|
||||
}
|
||||
result.append(VARGATETOTAL.size).append("@")
|
||||
cb.accept(result.toString())
|
||||
|
||||
// kirim VARCOMPENSATIONTOTAL
|
||||
result.clear()
|
||||
result.append("VARCOMPENSATIONTOTAL;")
|
||||
val VARCOMPENSATIONTOTAL = mutableListOf<Soundbank>()
|
||||
db.soundDB.List
|
||||
.filter { it.Category.equals(Category.Compensation.name, true) }
|
||||
.distinctBy { it.TAG }
|
||||
.forEach {
|
||||
VARCOMPENSATIONTOTAL.add(it)
|
||||
}
|
||||
result.append(VARCOMPENSATIONTOTAL.size).append("@")
|
||||
cb.accept(result.toString())
|
||||
|
||||
// kirim VARGREETINGTOTAL
|
||||
result.clear()
|
||||
result.append("VARGREETINGTOTAL;")
|
||||
val VARGREETINGTOTAL = mutableListOf<Soundbank>()
|
||||
db.soundDB.List
|
||||
.filter { it.Category.equals(Category.Greeting.name, true) }
|
||||
.distinctBy { it.TAG }
|
||||
.forEach {
|
||||
VARGREETINGTOTAL.add(it)
|
||||
}
|
||||
result.append(VARGREETINGTOTAL.size).append("@")
|
||||
cb.accept(result.toString())
|
||||
|
||||
//Append MSG, for Android only Indonesia and English
|
||||
VARMESSAGES.groupBy { it.ANN_ID }.forEach { (ann_id, value) ->
|
||||
result.append("MSG;").append(ann_id)
|
||||
result.append(";")
|
||||
value.find { it.Language.equals(Language.INDONESIA.name, true) }?.let {result.append(it.Message_Detail)} ?: result.append("NA")
|
||||
result.append(";")
|
||||
value.find {it.Language.equals(Language.ENGLISH.name, true) }?.let {result.append(it.Message_Detail)} ?: result.append("NA")
|
||||
result.append("@")
|
||||
if (VARMESSAGES.isNotEmpty()) {
|
||||
result.clear()
|
||||
VARMESSAGES.forEachIndexed { index, msg ->
|
||||
|
||||
val ann_id = msg.ANN_ID
|
||||
val msg_indo = db.messageDB.List.find {
|
||||
it.ANN_ID == ann_id && it.Language.equals(
|
||||
Language.INDONESIA.name,
|
||||
true
|
||||
)
|
||||
}
|
||||
val msg_eng = db.messageDB.List.find {
|
||||
it.ANN_ID == ann_id && it.Language.equals(
|
||||
Language.ENGLISH.name,
|
||||
true
|
||||
)
|
||||
}
|
||||
val description = msg_indo?.Description ?: msg_eng?.Description ?: "UNKNOWN"
|
||||
result.append("MSG;$index;$ann_id;$description;")
|
||||
result.append(msg_indo?.Message_Detail ?:"").append(";")
|
||||
result.append(msg_eng?.Message_Detail ?:"").append("@")
|
||||
}
|
||||
cb.accept(result.toString())
|
||||
}
|
||||
|
||||
// append VARAP
|
||||
VARAPTOTAL.distinctBy { it.Description }.forEachIndexed { index, soundbank ->
|
||||
result.append("VARAP;").append(index).append(";").append(soundbank.TAG).append(";").append(soundbank.Description).append("@")
|
||||
if (VARAPTOTAL.isNotEmpty()) {
|
||||
result.clear()
|
||||
VARAPTOTAL.forEachIndexed { index, sb ->
|
||||
result.append("VARAP;$index;${sb.TAG};${sb.Description}@")
|
||||
}
|
||||
cb.accept(result.toString())
|
||||
}
|
||||
|
||||
// append VARCITY
|
||||
VARCITYTOTAL.distinctBy { it.Description }.forEachIndexed { index, soundbank ->
|
||||
result.append("VARCITY;").append(index).append(";").append(soundbank.TAG).append(";").append(soundbank.Description).append("@")
|
||||
if (VARCITYTOTAL.isNotEmpty()) {
|
||||
result.clear()
|
||||
VARCITYTOTAL.forEachIndexed { index, sb ->
|
||||
result.append("VARCITY;$index;${sb.TAG};${sb.Description}@")
|
||||
}
|
||||
cb.accept(result.toString())
|
||||
}
|
||||
|
||||
// append VARPLACES
|
||||
VARPLACESTOTAL.distinctBy { it.Description }.forEachIndexed { index, soundbank ->
|
||||
result.append("VARPLACES;").append(index).append(";").append(soundbank.TAG).append(";").append(soundbank.Description).append("@")
|
||||
if (VARPLACESTOTAL.isNotEmpty()) {
|
||||
result.clear()
|
||||
VARPLACESTOTAL.forEachIndexed { index, sb ->
|
||||
result.append("VARPLACES;$index;${sb.TAG};${sb.Description}@")
|
||||
}
|
||||
cb.accept(result.toString())
|
||||
}
|
||||
// append VARSHALAT
|
||||
VARSHALATTOTAL.distinctBy { it.Description }.forEachIndexed { index, soundbank ->
|
||||
result.append("VARSHALAT;").append(index).append(";").append(soundbank.TAG).append(";").append(soundbank.Description).append("@")
|
||||
if (VARSHALATTOTAL.isNotEmpty()) {
|
||||
result.clear()
|
||||
VARSHALATTOTAL.forEachIndexed { index, sb ->
|
||||
result.append("VARSHALAT;$index;${sb.TAG};${sb.Description}@")
|
||||
}
|
||||
// append VARSEQUENCE
|
||||
VARSEQUENCETOTAL.distinctBy { it.Description }.forEachIndexed { index, soundbank ->
|
||||
result.append("VARSEQUENCE;").append(index).append(";").append(soundbank.TAG).append(";").append(soundbank.Description).append("@")
|
||||
}
|
||||
// append VARREASON
|
||||
VARREASONTOTAL.distinctBy { it.Description }.forEachIndexed { index, soundbank ->
|
||||
result.append("VARREASON;").append(index).append(";").append(soundbank.TAG).append(";").append(soundbank.Description).append("@")
|
||||
}
|
||||
// append VARPROCEDURE
|
||||
VARPROCEDURETOTAL.distinctBy { it.Description }.forEachIndexed { index, soundbank ->
|
||||
result.append("VARPROCEDURE;").append(index).append(";").append(soundbank.TAG).append(";").append(soundbank.Description).append("@")
|
||||
}
|
||||
// send to sender
|
||||
cb.accept(result.toString())
|
||||
}
|
||||
|
||||
// append VARSEQUENCE
|
||||
if (VARSEQUENCETOTAL.isNotEmpty()) {
|
||||
result.clear()
|
||||
VARSEQUENCETOTAL.forEachIndexed { index, sb ->
|
||||
result.append("VARSEQUENCE;$index;${sb.TAG};${sb.Description}@")
|
||||
}
|
||||
cb.accept(result.toString())
|
||||
}
|
||||
|
||||
// append VARREASON
|
||||
if (VARREASONTOTAL.isNotEmpty()) {
|
||||
result.clear()
|
||||
VARREASONTOTAL.forEachIndexed { index, sb ->
|
||||
result.append("VARREASON;$index;${sb.TAG};${sb.Description}@")
|
||||
}
|
||||
cb.accept(result.toString())
|
||||
}
|
||||
|
||||
// append VARPROCEDURE
|
||||
if (VARPROCEDURETOTAL.isNotEmpty()) {
|
||||
result.clear()
|
||||
VARPROCEDURETOTAL.forEachIndexed { index, sb ->
|
||||
result.append("VARPROCEDURE;$index;${sb.TAG};${sb.Description}@")
|
||||
}
|
||||
cb.accept(result.toString())
|
||||
}
|
||||
|
||||
// append VARGATE
|
||||
if (VARGATETOTAL.isNotEmpty()) {
|
||||
result.clear()
|
||||
VARGATETOTAL.forEachIndexed { index, sb ->
|
||||
result.append("VARGATE;$index;${sb.TAG};${sb.Description}@")
|
||||
}
|
||||
cb.accept(result.toString())
|
||||
}
|
||||
|
||||
// append VARCOMPENSATION
|
||||
if (VARCOMPENSATIONTOTAL.isNotEmpty()) {
|
||||
result.clear()
|
||||
VARCOMPENSATIONTOTAL.forEachIndexed { index, sb ->
|
||||
result.append("VARCOMPENSATION;$index;${sb.TAG};${sb.Description}@")
|
||||
}
|
||||
cb.accept(result.toString())
|
||||
}
|
||||
|
||||
// append VARGREETING
|
||||
if (VARGREETINGTOTAL.isNotEmpty()) {
|
||||
result.clear()
|
||||
VARGREETINGTOTAL.forEachIndexed { index, sb ->
|
||||
result.append("VARGREETING;$index;${sb.TAG};${sb.Description}@")
|
||||
}
|
||||
cb.accept(result.toString())
|
||||
}
|
||||
|
||||
logcb.accept("All variables sent to $key with username $username")
|
||||
return
|
||||
} else logcb.accept("STARTINITIALIZE failed from $key with username $username not found in userDB")
|
||||
@@ -387,8 +605,11 @@ class TCP_Android_Command_Server {
|
||||
"BROADCASTAND" -> {
|
||||
// semi auto dari android, masukin ke queue table
|
||||
val desc = parts.getOrElse(1) { "" }
|
||||
// language bisa lebih dari satu, dipisah dengan koma
|
||||
val lang = parts.getOrElse(2) { "" }.replace(",",";")
|
||||
// tags bisa lebih dari satu, dipisah dengan spasi
|
||||
val tags = parts.getOrElse(3) { "" }.replace(",",";")
|
||||
// zone bisa lebih dari satu, dipisah dengan koma
|
||||
val zone = parts.getOrElse(4) { "" }.replace(",",";")
|
||||
if (ValidString(desc)){
|
||||
if (ValidString(lang)){
|
||||
@@ -414,7 +635,7 @@ class TCP_Android_Command_Server {
|
||||
} else logcb.accept("Broadcsast request from Android $key username=${listUserLogin.find { it.ip==key }?.username ?: "UNKNOWN"} failed, empty tags")
|
||||
} else logcb.accept("Broadcast request from Android $key username=${listUserLogin.find { it.ip==key }?.username ?: "UNKNOWN"} failed, empty language")
|
||||
} else logcb.accept("Broadcast request from Android $key username=${listUserLogin.find { it.ip==key }?.username ?: "UNKNOWN"} failed, empty description")
|
||||
cb.accept("NG@")
|
||||
cb.accept("BROADCASTAND;NG@")
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -14,5 +14,8 @@ enum class Category(name: String) {
|
||||
Birthday("Birthday"),
|
||||
Reason("Reason"),
|
||||
Sequence("Sequence"),
|
||||
Procedure("Procedure");
|
||||
Procedure("Procedure"),
|
||||
Gate("Gate"),
|
||||
Greeting("Greeting"),
|
||||
Compensation("Compensation");
|
||||
}
|
||||
@@ -1179,7 +1179,7 @@ class MariaDB(
|
||||
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 (?, ?, ?, ?, ?, ?, ?, ?)"
|
||||
"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)
|
||||
@@ -1191,7 +1191,7 @@ class MariaDB(
|
||||
statement?.setString(8, data.Language)
|
||||
val rowsAffected = statement?.executeUpdate()
|
||||
if (rowsAffected != null && rowsAffected > 0) {
|
||||
Logger.info("QueueTable added: ${data.Message}" as Any)
|
||||
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)
|
||||
@@ -1206,7 +1206,7 @@ class MariaDB(
|
||||
try {
|
||||
connection.autoCommit = false
|
||||
val sql =
|
||||
"INSERT INTO ${super.dbName} (Date_Time, Source, Type, Message, SB_TAGS, BroadcastZones, Repeat, Language) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
|
||||
"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)
|
||||
|
||||
Reference in New Issue
Block a user