diff --git a/modules/database/src/main/kotlin/com/flipperdevices/ifrmvp/backend/db/signal/dao/TableDaoImpl.kt b/modules/database/src/main/kotlin/com/flipperdevices/ifrmvp/backend/db/signal/dao/TableDaoImpl.kt index 7dc3663..8bcfbc7 100644 --- a/modules/database/src/main/kotlin/com/flipperdevices/ifrmvp/backend/db/signal/dao/TableDaoImpl.kt +++ b/modules/database/src/main/kotlin/com/flipperdevices/ifrmvp/backend/db/signal/dao/TableDaoImpl.kt @@ -71,7 +71,8 @@ internal class TableDaoImpl(private val database: Database) : TableDao { id = it[InfraredFileTable.id].value, brandId = it[InfraredFileTable.brandId].value, fileName = it[InfraredFileTable.fileName], - folderName = it[InfraredFileTable.folderName] + folderName = it[InfraredFileTable.folderName], + signalCount = it[InfraredFileTable.signalCount] ) }.firstOrNull() ?: throw TableDaoException.IrFileNotFound(irFileId) } diff --git a/modules/database/src/main/kotlin/com/flipperdevices/ifrmvp/backend/db/signal/table/InfraredFileTable.kt b/modules/database/src/main/kotlin/com/flipperdevices/ifrmvp/backend/db/signal/table/InfraredFileTable.kt index 0c5c8ed..d947d50 100644 --- a/modules/database/src/main/kotlin/com/flipperdevices/ifrmvp/backend/db/signal/table/InfraredFileTable.kt +++ b/modules/database/src/main/kotlin/com/flipperdevices/ifrmvp/backend/db/signal/table/InfraredFileTable.kt @@ -20,4 +20,6 @@ object InfraredFileTable : LongIdTable("INFRARED_FILE") { * The name of .IR file folder */ val folderName = text("folder_name") + + val signalCount = integer("signal_count") } diff --git a/modules/kenerator/sql/src/main/kotlin/com/flipperdevices/ifrmvp/parser/presentation/FillerController.kt b/modules/kenerator/sql/src/main/kotlin/com/flipperdevices/ifrmvp/parser/presentation/FillerController.kt index b2d6385..5e367b2 100644 --- a/modules/kenerator/sql/src/main/kotlin/com/flipperdevices/ifrmvp/parser/presentation/FillerController.kt +++ b/modules/kenerator/sql/src/main/kotlin/com/flipperdevices/ifrmvp/parser/presentation/FillerController.kt @@ -14,6 +14,7 @@ import com.flipperdevices.ifrmvp.model.IfrKeyIdentifier import com.flipperdevices.ifrmvp.parser.util.ParserPathResolver import com.flipperdevices.infrared.editor.encoding.InfraredRemoteEncoder.identifier import com.flipperdevices.infrared.editor.model.InfraredRemote +import com.flipperdevices.infrared.editor.util.InfraredMapper import com.flipperdevices.infrared.editor.viewmodel.InfraredKeyParser import java.io.File import kotlinx.coroutines.CoroutineScope @@ -78,6 +79,7 @@ internal class FillerController(private val database: Database) : CoroutineScope this[InfraredFileTable.brandId] = brandId this[InfraredFileTable.fileName] = it.name this[InfraredFileTable.folderName] = it.parentFile.name + this[InfraredFileTable.signalCount] = InfraredMapper.parseRemotes(it).size } // Presets val uiFiles = irFiles.mapNotNull { irFile -> diff --git a/modules/model/src/commonMain/kotlin/com/flipperdevices/ifrmvp/backend/model/IfrFileModel.kt b/modules/model/src/commonMain/kotlin/com/flipperdevices/ifrmvp/backend/model/IfrFileModel.kt index 80210c5..eb15e8d 100644 --- a/modules/model/src/commonMain/kotlin/com/flipperdevices/ifrmvp/backend/model/IfrFileModel.kt +++ b/modules/model/src/commonMain/kotlin/com/flipperdevices/ifrmvp/backend/model/IfrFileModel.kt @@ -12,5 +12,7 @@ data class IfrFileModel( @SerialName("file_name") val fileName: String, @SerialName("folder_name") - val folderName: String + val folderName: String, + @SerialName("signal_count") + val signalCount: Int ) diff --git a/modules/model/src/commonMain/kotlin/com/flipperdevices/ifrmvp/backend/model/SignalRequestModel.kt b/modules/model/src/commonMain/kotlin/com/flipperdevices/ifrmvp/backend/model/SignalRequestModel.kt index f41c5ce..63c9c76 100644 --- a/modules/model/src/commonMain/kotlin/com/flipperdevices/ifrmvp/backend/model/SignalRequestModel.kt +++ b/modules/model/src/commonMain/kotlin/com/flipperdevices/ifrmvp/backend/model/SignalRequestModel.kt @@ -9,6 +9,8 @@ data class SignalRequestModel( val successResults: List = emptyList(), @SerialName("failed_results") val failedResults: List = emptyList(), + @SerialName("skipped_results") + val skippedResults: List = emptyList(), @SerialName("brand_id") val brandId: Long ) { diff --git a/web-api/src/main/kotlin/com/flipperdevices/ifrmvp/backend/route/infrareds/data/InfraredsRepository.kt b/web-api/src/main/kotlin/com/flipperdevices/ifrmvp/backend/route/infrareds/data/InfraredsRepository.kt index df7663e..cab5091 100644 --- a/web-api/src/main/kotlin/com/flipperdevices/ifrmvp/backend/route/infrareds/data/InfraredsRepository.kt +++ b/web-api/src/main/kotlin/com/flipperdevices/ifrmvp/backend/route/infrareds/data/InfraredsRepository.kt @@ -22,6 +22,7 @@ internal class InfraredsRepository( brandId = it[InfraredFileTable.brandId].value, fileName = it[InfraredFileTable.fileName], folderName = it[InfraredFileTable.folderName], + signalCount = it[InfraredFileTable.signalCount] ) } } diff --git a/web-api/src/main/kotlin/com/flipperdevices/ifrmvp/backend/route/signal/presentation/SignalRouteRegistry.kt b/web-api/src/main/kotlin/com/flipperdevices/ifrmvp/backend/route/signal/presentation/SignalRouteRegistry.kt index ec92b79..b82a4e9 100644 --- a/web-api/src/main/kotlin/com/flipperdevices/ifrmvp/backend/route/signal/presentation/SignalRouteRegistry.kt +++ b/web-api/src/main/kotlin/com/flipperdevices/ifrmvp/backend/route/signal/presentation/SignalRouteRegistry.kt @@ -17,6 +17,9 @@ import com.flipperdevices.ifrmvp.backend.model.SignalResponse import com.flipperdevices.ifrmvp.backend.model.SignalResponseModel import com.flipperdevices.ifrmvp.backend.route.signal.data.CategoryConfigRepository import com.flipperdevices.ifrmvp.backend.route.signal.data.IRDBCategoryConfigRepository +import com.flipperdevices.ifrmvp.generator.config.device.api.DeviceKeyNamesProvider +import com.flipperdevices.ifrmvp.generator.config.device.api.DeviceKeyNamesProvider.Companion.getKey +import com.flipperdevices.ifrmvp.generator.config.device.api.any.AnyDeviceKeyNamesProvider import com.flipperdevices.ifrmvp.model.IfrKeyIdentifier import com.flipperdevices.ifrmvp.model.buttondata.SingleKeyButtonData import io.github.smiley4.ktorswaggerui.dsl.routing.post @@ -42,18 +45,33 @@ internal class SignalRouteRegistry( private val categoryConfigRepository: CategoryConfigRepository = IRDBCategoryConfigRepository, ) : RouteRegistry { - // Keep only those files, in which signals have been successfully passed - private fun getIncludedFileIds(signalRequestModel: SignalRequestModel): Query { + /** + * Keep only those files, in which signals have been successfully passed + * + * SELECT INFRARED_FILE."id", INFRARED_FILE."signal_count" + * FROM INFRARED_FILE JOIN INFRARED_FILE_TO_SIGNAL on INFRARED_FILE_TO_SIGNAL."infrared_file_id" = INFRARED_FILE."id" + * group by INFRARED_FILE."id" + * order by INFRARED_FILE."signal_count" desc + */ + private fun getIncludedFileIds(signalRequestModel: SignalRequestModel, brandId: Long): Query { return transaction(database) { - InfraredFileToSignalTable - .select(InfraredFileToSignalTable.infraredFileId) - .groupBy(InfraredFileToSignalTable.infraredFileId) + InfraredFileTable + .join( + otherTable = InfraredFileToSignalTable, + onColumn = InfraredFileTable.id, + otherColumn = InfraredFileToSignalTable.infraredFileId, + joinType = JoinType.INNER + ) + .select(InfraredFileTable.id, InfraredFileTable.signalCount) + .groupBy(InfraredFileTable.id) + .orderBy(InfraredFileTable.signalCount to SortOrder.DESC) + .where { InfraredFileTable.brandId eq brandId } .apply { val successSignalIds = signalRequestModel .successResults .map(SignalRequestModel.SignalResultData::signalId) if (successSignalIds.isNotEmpty()) { - where { + andWhere { InfraredFileToSignalTable .signalId .inList(successSignalIds) @@ -170,7 +188,7 @@ internal class SignalRouteRegistry( includedFileIds: Query, brand: BrandModel, // Index of successful results - index: Int = signalRequestModel.successResults.size, + index: Int = signalRequestModel.successResults.size + signalRequestModel.skippedResults.size, categoryType: CategoryType, category: DeviceCategory ): SignalResponseModel { @@ -183,7 +201,7 @@ internal class SignalRouteRegistry( if (order == null) { val infraredFileId = transaction(database) { includedFileIds - .map { it[InfraredFileToSignalTable.infraredFileId] } + .map { it[InfraredFileTable.id] } .first() .value } @@ -191,12 +209,23 @@ internal class SignalRouteRegistry( return response } + val skippedKeys = transaction(database) { + SignalTable + .selectAll() + .where { SignalTable.id inList signalRequestModel.skippedResults.map(SignalRequestModel.SignalResultData::signalId) } + .mapNotNull { + val keyName = it[SignalTable.name] + AnyDeviceKeyNamesProvider.getKey(keyName) + } + } + val signalModel = getSignalModel( signalRequestModel = signalRequestModel, order = order, brand = brand ) - if (signalModel == null) { + + if (signalModel == null || skippedKeys.contains(order.key)) { return findSignal( signalRequestModel = signalRequestModel, includedFileIds = includedFileIds, @@ -234,8 +263,9 @@ internal class SignalRouteRegistry( .firstOrNull { it.folderName == category.folderName } ?: throw TableDaoException.CategoryNotFound(category.id) - val includedFileIds = getIncludedFileIds(signalRequestModel) + val includedFileIds = getIncludedFileIds(signalRequestModel, brand.id) val includedInfraredFilesCount = transaction(database) { includedFileIds.count() } + println("#root includedInfraredFilesCount=$includedInfraredFilesCount") when (includedInfraredFilesCount) { 0L -> { context.respond(HttpStatusCode.NoContent) @@ -245,7 +275,7 @@ internal class SignalRouteRegistry( 1L -> { val infraredFileId = transaction(database) { includedFileIds - .map { it[InfraredFileToSignalTable.infraredFileId] } + .map { it[InfraredFileTable.id] } .first() .value }