mirror of
https://github.com/pawelorzech/Swoosh.git
synced 2026-03-31 20:15:41 +00:00
feat: add DB migration v3→v4 with new LocalPost columns for email, media, files
This commit is contained in:
parent
0891013df6
commit
8326d06861
4 changed files with 50 additions and 11 deletions
|
|
@ -9,7 +9,7 @@ import androidx.room.migration.Migration
|
|||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import com.swoosh.microblog.data.model.LocalPost
|
||||
|
||||
@Database(entities = [LocalPost::class], version = 3, exportSchema = false)
|
||||
@Database(entities = [LocalPost::class], version = 4, exportSchema = false)
|
||||
@TypeConverters(Converters::class)
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
|
||||
|
|
@ -42,6 +42,25 @@ abstract class AppDatabase : RoomDatabase() {
|
|||
override fun migrate(db: SupportSQLiteDatabase) = addColumnsIfMissing(db)
|
||||
}
|
||||
|
||||
val MIGRATION_3_4 = object : Migration(3, 4) {
|
||||
override fun migrate(db: SupportSQLiteDatabase) {
|
||||
val columns = listOf(
|
||||
"ALTER TABLE local_posts ADD COLUMN emailOnly INTEGER NOT NULL DEFAULT 0",
|
||||
"ALTER TABLE local_posts ADD COLUMN newsletterSlug TEXT DEFAULT NULL",
|
||||
"ALTER TABLE local_posts ADD COLUMN videoUri TEXT DEFAULT NULL",
|
||||
"ALTER TABLE local_posts ADD COLUMN uploadedVideoUrl TEXT DEFAULT NULL",
|
||||
"ALTER TABLE local_posts ADD COLUMN audioUri TEXT DEFAULT NULL",
|
||||
"ALTER TABLE local_posts ADD COLUMN uploadedAudioUrl TEXT DEFAULT NULL",
|
||||
"ALTER TABLE local_posts ADD COLUMN fileUri TEXT DEFAULT NULL",
|
||||
"ALTER TABLE local_posts ADD COLUMN uploadedFileUrl TEXT DEFAULT NULL",
|
||||
"ALTER TABLE local_posts ADD COLUMN fileName TEXT DEFAULT NULL"
|
||||
)
|
||||
for (sql in columns) {
|
||||
try { db.execSQL(sql) } catch (_: Exception) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getInstance(context: Context): AppDatabase {
|
||||
return INSTANCE ?: synchronized(this) {
|
||||
val instance = Room.databaseBuilder(
|
||||
|
|
@ -49,7 +68,7 @@ abstract class AppDatabase : RoomDatabase() {
|
|||
AppDatabase::class.java,
|
||||
"swoosh_database"
|
||||
)
|
||||
.addMigrations(MIGRATION_1_3, MIGRATION_2_3)
|
||||
.addMigrations(MIGRATION_1_3, MIGRATION_2_3, MIGRATION_3_4)
|
||||
.fallbackToDestructiveMigration()
|
||||
.build()
|
||||
INSTANCE = instance
|
||||
|
|
|
|||
|
|
@ -11,13 +11,21 @@ class Converters {
|
|||
fun fromPostStatus(value: PostStatus): String = value.name
|
||||
|
||||
@TypeConverter
|
||||
fun toPostStatus(value: String): PostStatus = PostStatus.valueOf(value)
|
||||
fun toPostStatus(value: String): PostStatus = try {
|
||||
PostStatus.valueOf(value)
|
||||
} catch (_: Exception) {
|
||||
PostStatus.DRAFT
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun fromQueueStatus(value: QueueStatus): String = value.name
|
||||
|
||||
@TypeConverter
|
||||
fun toQueueStatus(value: String): QueueStatus = QueueStatus.valueOf(value)
|
||||
fun toQueueStatus(value: String): QueueStatus = try {
|
||||
QueueStatus.valueOf(value)
|
||||
} catch (_: Exception) {
|
||||
QueueStatus.NONE
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val gson = Gson()
|
||||
|
|
|
|||
|
|
@ -89,7 +89,19 @@ data class LocalPost(
|
|||
val tags: String = "[]",
|
||||
val createdAt: Long = System.currentTimeMillis(),
|
||||
val updatedAt: Long = System.currentTimeMillis(),
|
||||
val queueStatus: QueueStatus = QueueStatus.NONE
|
||||
val queueStatus: QueueStatus = QueueStatus.NONE,
|
||||
// Phase 4b: email-only
|
||||
val emailOnly: Boolean = false,
|
||||
val newsletterSlug: String? = null,
|
||||
// Phase 5: media
|
||||
val videoUri: String? = null,
|
||||
val uploadedVideoUrl: String? = null,
|
||||
val audioUri: String? = null,
|
||||
val uploadedAudioUrl: String? = null,
|
||||
// Phase 6: file
|
||||
val fileUri: String? = null,
|
||||
val uploadedFileUrl: String? = null,
|
||||
val fileName: String? = null
|
||||
)
|
||||
|
||||
enum class PostStatus {
|
||||
|
|
|
|||
|
|
@ -56,9 +56,9 @@ class ConvertersTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
fun `toPostStatus throws on invalid string`() {
|
||||
converters.toPostStatus("INVALID")
|
||||
@Test
|
||||
fun `toPostStatus returns DRAFT fallback on invalid string`() {
|
||||
assertEquals(PostStatus.DRAFT, converters.toPostStatus("INVALID"))
|
||||
}
|
||||
|
||||
// --- QueueStatus conversions ---
|
||||
|
|
@ -112,9 +112,9 @@ class ConvertersTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
fun `toQueueStatus throws on invalid string`() {
|
||||
converters.toQueueStatus("NONEXISTENT")
|
||||
@Test
|
||||
fun `toQueueStatus returns NONE fallback on invalid string`() {
|
||||
assertEquals(QueueStatus.NONE, converters.toQueueStatus("NONEXISTENT"))
|
||||
}
|
||||
|
||||
// --- String list JSON serialization ---
|
||||
|
|
|
|||
Loading…
Reference in a new issue