mirror of
https://github.com/atsunatsu/Look4Sat.git
synced 2026-10-04 19:47:22 +00:00
feat(wavelog): per-record Wavelog upload state (model, migration, dao, repo)
This commit is contained in:
1 parent
cbe3e50f86
commit
733f660d78
7 files changed
+54
-2
No files matched your search
@@ -47,4 +47,7 @@ interface QsoDao {
|
||||
|
||||
@Query("UPDATE qso_records SET lotwUploaded = 1 WHERE id IN (:ids)")
|
||||
suspend fun markUploaded(ids: List<Long>)
|
||||
|
||||
@Query("UPDATE qso_records SET wavelogUploaded = 1 WHERE id IN (:ids)")
|
||||
suspend fun markWavelogUploaded(ids: List<Long>)
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import com.rtbishop.look4sat.core.data.database.entity.QsoEntity
|
||||
* upload receipts). Kept apart from [Look4SatDb] so existing installations
|
||||
* never need a migration of the satellite database.
|
||||
*/
|
||||
@Database(entities = [QsoEntity::class], version = 3, exportSchema = false)
|
||||
@Database(entities = [QsoEntity::class], version = 4, exportSchema = false)
|
||||
abstract class QsoDatabase : RoomDatabase() {
|
||||
abstract fun qsoDao(): QsoDao
|
||||
}
|
||||
@@ -38,3 +38,10 @@ val MIGRATION_QSO_2_3 = object : Migration(2, 3) {
|
||||
db.execSQL("ALTER TABLE qso_records ADD COLUMN theirVuccGrids TEXT NOT NULL DEFAULT ''")
|
||||
}
|
||||
}
|
||||
|
||||
/** v3 → v4: track whether a QSO was uploaded to Wavelog (independent of the LoTW state). */
|
||||
val MIGRATION_QSO_3_4 = object : Migration(3, 4) {
|
||||
override fun migrate(db: SupportSQLiteDatabase) {
|
||||
db.execSQL("ALTER TABLE qso_records ADD COLUMN wavelogUploaded INTEGER NOT NULL DEFAULT 0")
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,7 @@ data class QsoEntity(
|
||||
@ColumnInfo(defaultValue = "''") val propagationMode: String = "",
|
||||
@ColumnInfo(defaultValue = "0") val lotwConfirmed: Boolean = false,
|
||||
@ColumnInfo(defaultValue = "0") val lotwUploaded: Boolean = false,
|
||||
@ColumnInfo(defaultValue = "0") val wavelogUploaded: Boolean = false,
|
||||
@ColumnInfo(defaultValue = "0") val lotwReceived: Boolean = false,
|
||||
@ColumnInfo(defaultValue = "''") val lotwQslDate: String = "",
|
||||
@ColumnInfo(defaultValue = "''") val vuccGrids: String = "",
|
||||
|
||||
+10
-1
@@ -51,12 +51,14 @@ class QsoRepository(
|
||||
// place: that contact already exists on LoTW under the old values. The original row
|
||||
// keeps its upload/confirmation state, and the edited content is saved as a NEW
|
||||
// record (without any LoTW state, so it can be uploaded again).
|
||||
if (previous != null && (previous.lotwUploaded || previous.lotwConfirmed) &&
|
||||
if (previous != null &&
|
||||
(previous.lotwUploaded || previous.lotwConfirmed || previous.wavelogUploaded) &&
|
||||
!record.sameEditableContentAs(previous)
|
||||
) {
|
||||
dao.save(record.copy(
|
||||
id = 0L,
|
||||
lotwUploaded = false, lotwConfirmed = false, lotwReceived = false,
|
||||
wavelogUploaded = false,
|
||||
lotwQslDate = "", vuccGrids = emptyList(), theirVuccGrids = emptyList(),
|
||||
dxcc = null, country = "", cqZone = null, region = ""
|
||||
).toEntity())
|
||||
@@ -93,6 +95,11 @@ class QsoRepository(
|
||||
if (stamped.isNotEmpty()) dao.saveBatch(stamped.map { it.toEntity() })
|
||||
}
|
||||
|
||||
override suspend fun markWavelogUploaded(ids: List<Long>) = withContext(dispatcher) {
|
||||
if (ids.isEmpty()) return@withContext
|
||||
importMutex.withLock { dao.markWavelogUploaded(ids) }
|
||||
}
|
||||
|
||||
override suspend fun exportAdi(ids: Set<Long>?, includeIncomplete: Boolean): String = withContext(dispatcher) {
|
||||
val records = dao.getAll()
|
||||
.asSequence()
|
||||
@@ -286,6 +293,7 @@ private fun QsoEntity.toDomain() = QsoRecord(
|
||||
propagationMode = propagationMode,
|
||||
lotwConfirmed = lotwConfirmed,
|
||||
lotwUploaded = lotwUploaded,
|
||||
wavelogUploaded = wavelogUploaded,
|
||||
lotwReceived = lotwReceived,
|
||||
lotwQslDate = lotwQslDate,
|
||||
vuccGrids = vuccGrids.split(',').filter(String::isNotBlank),
|
||||
@@ -323,6 +331,7 @@ private fun QsoRecord.toEntity() = QsoEntity(
|
||||
propagationMode = propagationMode.ifBlank { if (satelliteName.isNotBlank()) "SAT" else "" },
|
||||
lotwConfirmed = lotwConfirmed,
|
||||
lotwUploaded = lotwUploaded,
|
||||
wavelogUploaded = wavelogUploaded,
|
||||
lotwReceived = lotwReceived,
|
||||
lotwQslDate = lotwQslDate,
|
||||
vuccGrids = vuccGrids.joinToString(","),
|
||||
|
||||
+26
@@ -295,6 +295,27 @@ class QsoRepositoryTest {
|
||||
assertEquals(1, dao.getAll().size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun markWavelogUploaded_setsOnlyTheWavelogFlag() = runBlocking {
|
||||
val id = dao.save(loggedInApp("SO-50", lotwUploaded = false).toEntity())
|
||||
|
||||
repository.markWavelogUploaded(listOf(id))
|
||||
|
||||
val row = dao.getAll().single()
|
||||
assertTrue(row.wavelogUploaded)
|
||||
assertFalse(row.lotwUploaded)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun save_editingAWavelogUploadedRecordCreatesANewRecord() = runBlocking {
|
||||
val id = dao.save(loggedInApp("SO-50", lotwUploaded = false).copy(wavelogUploaded = true).toEntity())
|
||||
|
||||
repository.save(loggedInApp("SO-50", lotwUploaded = false).copy(id = id, theirCallsign = "BG5JVM"))
|
||||
|
||||
assertEquals(2, dao.getAll().size)
|
||||
assertEquals(1, dao.getAll().count { it.wavelogUploaded })
|
||||
}
|
||||
|
||||
/** A record as the log page creates it: tracker name, repeater pair, uplink band. */
|
||||
private fun loggedInApp(satelliteName: String, lotwUploaded: Boolean) = QsoRecord(
|
||||
startUtcMillis = qsoStart,
|
||||
@@ -355,6 +376,7 @@ class QsoRepositoryTest {
|
||||
propagationMode = propagationMode,
|
||||
lotwConfirmed = lotwConfirmed,
|
||||
lotwUploaded = lotwUploaded,
|
||||
wavelogUploaded = wavelogUploaded,
|
||||
lotwReceived = lotwReceived,
|
||||
lotwQslDate = lotwQslDate,
|
||||
vuccGrids = vuccGrids.joinToString(","),
|
||||
@@ -393,5 +415,9 @@ class QsoRepositoryTest {
|
||||
override suspend fun markUploaded(ids: List<Long>) {
|
||||
ids.forEach { id -> rows[id]?.let { rows[id] = it.copy(lotwUploaded = true) } }
|
||||
}
|
||||
|
||||
override suspend fun markWavelogUploaded(ids: List<Long>) {
|
||||
ids.forEach { id -> rows[id]?.let { rows[id] = it.copy(wavelogUploaded = true) } }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,10 @@ interface IQsoRepository {
|
||||
* logbook row can show which grids the QSO went out under.
|
||||
*/
|
||||
suspend fun markUploaded(ids: List<Long>, grids: List<String> = emptyList())
|
||||
|
||||
/** Marks the batch as uploaded to Wavelog (independent of the LoTW upload state). */
|
||||
suspend fun markWavelogUploaded(ids: List<Long>)
|
||||
|
||||
suspend fun exportAdi(ids: Set<Long>? = null, includeIncomplete: Boolean = false): String
|
||||
suspend fun importAdi(content: String): AdifImportResult
|
||||
suspend fun mergeConfirmed(records: List<QsoRecord>): AdifImportResult
|
||||
|
||||
@@ -40,6 +40,8 @@ data class QsoRecord(
|
||||
val propagationMode: String = if (satelliteName.isNotBlank()) "SAT" else "",
|
||||
val lotwConfirmed: Boolean = false,
|
||||
val lotwUploaded: Boolean = false,
|
||||
/** Internal: set after a successful Wavelog upload; keeps the pending filter small. Not shown in any list. */
|
||||
val wavelogUploaded: Boolean = false,
|
||||
val lotwReceived: Boolean = false,
|
||||
val lotwQslDate: String = "",
|
||||
val vuccGrids: List<String> = emptyList(),
|
||||
|
||||
Reference in new issue
Block a user