mirror of
https://github.com/pawelorzech/Swoosh.git
synced 2026-03-31 11:55:47 +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 androidx.sqlite.db.SupportSQLiteDatabase
|
||||||
import com.swoosh.microblog.data.model.LocalPost
|
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)
|
@TypeConverters(Converters::class)
|
||||||
abstract class AppDatabase : RoomDatabase() {
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
|
|
||||||
|
|
@ -42,6 +42,25 @@ abstract class AppDatabase : RoomDatabase() {
|
||||||
override fun migrate(db: SupportSQLiteDatabase) = addColumnsIfMissing(db)
|
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 {
|
fun getInstance(context: Context): AppDatabase {
|
||||||
return INSTANCE ?: synchronized(this) {
|
return INSTANCE ?: synchronized(this) {
|
||||||
val instance = Room.databaseBuilder(
|
val instance = Room.databaseBuilder(
|
||||||
|
|
@ -49,7 +68,7 @@ abstract class AppDatabase : RoomDatabase() {
|
||||||
AppDatabase::class.java,
|
AppDatabase::class.java,
|
||||||
"swoosh_database"
|
"swoosh_database"
|
||||||
)
|
)
|
||||||
.addMigrations(MIGRATION_1_3, MIGRATION_2_3)
|
.addMigrations(MIGRATION_1_3, MIGRATION_2_3, MIGRATION_3_4)
|
||||||
.fallbackToDestructiveMigration()
|
.fallbackToDestructiveMigration()
|
||||||
.build()
|
.build()
|
||||||
INSTANCE = instance
|
INSTANCE = instance
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,21 @@ class Converters {
|
||||||
fun fromPostStatus(value: PostStatus): String = value.name
|
fun fromPostStatus(value: PostStatus): String = value.name
|
||||||
|
|
||||||
@TypeConverter
|
@TypeConverter
|
||||||
fun toPostStatus(value: String): PostStatus = PostStatus.valueOf(value)
|
fun toPostStatus(value: String): PostStatus = try {
|
||||||
|
PostStatus.valueOf(value)
|
||||||
|
} catch (_: Exception) {
|
||||||
|
PostStatus.DRAFT
|
||||||
|
}
|
||||||
|
|
||||||
@TypeConverter
|
@TypeConverter
|
||||||
fun fromQueueStatus(value: QueueStatus): String = value.name
|
fun fromQueueStatus(value: QueueStatus): String = value.name
|
||||||
|
|
||||||
@TypeConverter
|
@TypeConverter
|
||||||
fun toQueueStatus(value: String): QueueStatus = QueueStatus.valueOf(value)
|
fun toQueueStatus(value: String): QueueStatus = try {
|
||||||
|
QueueStatus.valueOf(value)
|
||||||
|
} catch (_: Exception) {
|
||||||
|
QueueStatus.NONE
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val gson = Gson()
|
private val gson = Gson()
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,19 @@ data class LocalPost(
|
||||||
val tags: String = "[]",
|
val tags: String = "[]",
|
||||||
val createdAt: Long = System.currentTimeMillis(),
|
val createdAt: Long = System.currentTimeMillis(),
|
||||||
val updatedAt: 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 {
|
enum class PostStatus {
|
||||||
|
|
|
||||||
|
|
@ -56,9 +56,9 @@ class ConvertersTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException::class)
|
@Test
|
||||||
fun `toPostStatus throws on invalid string`() {
|
fun `toPostStatus returns DRAFT fallback on invalid string`() {
|
||||||
converters.toPostStatus("INVALID")
|
assertEquals(PostStatus.DRAFT, converters.toPostStatus("INVALID"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- QueueStatus conversions ---
|
// --- QueueStatus conversions ---
|
||||||
|
|
@ -112,9 +112,9 @@ class ConvertersTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException::class)
|
@Test
|
||||||
fun `toQueueStatus throws on invalid string`() {
|
fun `toQueueStatus returns NONE fallback on invalid string`() {
|
||||||
converters.toQueueStatus("NONEXISTENT")
|
assertEquals(QueueStatus.NONE, converters.toQueueStatus("NONEXISTENT"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- String list JSON serialization ---
|
// --- String list JSON serialization ---
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue