Skip to content

Commit b8b276f

Browse files
authored
fix: Migrate database non-destructively (#11)
2 parents 62e46fe + e1c4cc3 commit b8b276f

File tree

12 files changed

+141
-17
lines changed

12 files changed

+141
-17
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
{
2+
"formatVersion": 1,
3+
"database": {
4+
"version": 3,
5+
"identityHash": "6517669d413b15b9fd2c38215b1fe3be",
6+
"entities": [
7+
{
8+
"tableName": "rules",
9+
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`action` TEXT NOT NULL, `enabled` INTEGER NOT NULL, `executions` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
10+
"fields": [
11+
{
12+
"fieldPath": "action",
13+
"columnName": "action",
14+
"affinity": "TEXT",
15+
"notNull": true
16+
},
17+
{
18+
"fieldPath": "enabled",
19+
"columnName": "enabled",
20+
"affinity": "INTEGER",
21+
"notNull": true
22+
},
23+
{
24+
"fieldPath": "executions",
25+
"columnName": "executions",
26+
"affinity": "INTEGER",
27+
"notNull": true
28+
},
29+
{
30+
"fieldPath": "id",
31+
"columnName": "id",
32+
"affinity": "INTEGER",
33+
"notNull": true
34+
}
35+
],
36+
"primaryKey": {
37+
"autoGenerate": true,
38+
"columnNames": [
39+
"id"
40+
]
41+
}
42+
},
43+
{
44+
"tableName": "executions",
45+
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`fileName` TEXT NOT NULL, `verb` TEXT NOT NULL DEFAULT 'MOVE', `timestamp` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
46+
"fields": [
47+
{
48+
"fieldPath": "fileName",
49+
"columnName": "fileName",
50+
"affinity": "TEXT",
51+
"notNull": true
52+
},
53+
{
54+
"fieldPath": "verb",
55+
"columnName": "verb",
56+
"affinity": "TEXT",
57+
"notNull": true,
58+
"defaultValue": "'MOVE'"
59+
},
60+
{
61+
"fieldPath": "timestamp",
62+
"columnName": "timestamp",
63+
"affinity": "INTEGER",
64+
"notNull": true
65+
},
66+
{
67+
"fieldPath": "id",
68+
"columnName": "id",
69+
"affinity": "INTEGER",
70+
"notNull": true
71+
}
72+
],
73+
"primaryKey": {
74+
"autoGenerate": true,
75+
"columnNames": [
76+
"id"
77+
]
78+
}
79+
}
80+
],
81+
"setupQueries": [
82+
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
83+
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '6517669d413b15b9fd2c38215b1fe3be')"
84+
]
85+
}
86+
}

app/src/main/java/co/adityarajput/fileflow/data/AppContainer.kt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package co.adityarajput.fileflow.data
22

33
import android.content.Context
4-
import co.adityarajput.fileflow.R
54
import co.adityarajput.fileflow.data.models.Action
65
import co.adityarajput.fileflow.data.models.Execution
76
import co.adityarajput.fileflow.data.models.Rule
@@ -56,27 +55,27 @@ class AppContainer(private val context: Context) {
5655
repository.upsert(
5756
Execution(
5857
"TubularData-20251201_113745.zip",
59-
R.string.move,
58+
Verb.MOVE,
6059
System.currentTimeMillis() - 86400000L * 66,
6160
),
6261
Execution(
6362
"TubularData-20260101_141634.zip",
64-
R.string.move,
63+
Verb.MOVE,
6564
System.currentTimeMillis() - 86400000L * 35,
6665
),
6766
Execution(
6867
"TubularData-20260201_160604.zip",
69-
R.string.move,
68+
Verb.MOVE,
7069
System.currentTimeMillis() - 86400000L * 4,
7170
),
7271
Execution(
7372
"AntennaPodBackup-2026-02-02.db",
74-
R.string.copy,
73+
Verb.COPY,
7574
System.currentTimeMillis() - 86400000L * 3,
7675
),
7776
Execution(
7877
"AntennaPodBackup-2026-02-05.db",
79-
R.string.copy,
78+
Verb.COPY,
8079
System.currentTimeMillis() - 60_000L * 5,
8180
),
8281
)

app/src/main/java/co/adityarajput/fileflow/data/Converters.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package co.adityarajput.fileflow.data
33
import androidx.room.TypeConverter
44
import co.adityarajput.fileflow.data.models.Action
55
import kotlinx.serialization.json.Json
6+
import kotlinx.serialization.json.jsonObject
67

78
class Converters {
89
@TypeConverter
@@ -12,6 +13,16 @@ class Converters {
1213
fun toAction(value: String) = try {
1314
Json.decodeFromString<Action>(value)
1415
} catch (_: Exception) {
15-
Action.entries[0]
16+
try {
17+
Json.decodeFromString<Action>(
18+
Json.encodeToString(
19+
Json.parseToJsonElement(value)
20+
.jsonObject.toMap()
21+
.filterKeys { it != "title" },
22+
),
23+
)
24+
} catch (_: Exception) {
25+
Action.entries[0]
26+
}
1627
}
1728
}

app/src/main/java/co/adityarajput/fileflow/data/FileFlowDatabase.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,26 @@ package co.adityarajput.fileflow.data
22

33
import android.content.Context
44
import androidx.room.*
5+
import androidx.room.migration.AutoMigrationSpec
56
import co.adityarajput.fileflow.data.models.Execution
67
import co.adityarajput.fileflow.data.models.Rule
78

8-
@Database([Rule::class, Execution::class], version = 2, autoMigrations = [AutoMigration(1, 2)])
9+
@Database(
10+
[Rule::class, Execution::class],
11+
version = 3,
12+
autoMigrations = [
13+
AutoMigration(1, 2),
14+
AutoMigration(2, 3, FileFlowDatabase.DeleteEColumnAV::class),
15+
],
16+
)
917
@TypeConverters(Converters::class)
1018
abstract class FileFlowDatabase : RoomDatabase() {
1119
abstract fun ruleDao(): RuleDao
1220
abstract fun executionDao(): ExecutionDao
1321

22+
@DeleteColumn("executions", "actionVerb")
23+
class DeleteEColumnAV : AutoMigrationSpec
24+
1425
companion object {
1526
@Volatile
1627
private var instance: FileFlowDatabase? = null
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package co.adityarajput.fileflow.data
2+
3+
import co.adityarajput.fileflow.R
4+
5+
enum class Verb(val resource: Int) {
6+
MOVE(R.string.move),
7+
COPY(R.string.copy),
8+
DELETE_STALE(R.string.delete_stale),
9+
}

app/src/main/java/co/adityarajput/fileflow/data/models/Action.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import androidx.compose.ui.text.SpanStyle
77
import androidx.compose.ui.text.buildAnnotatedString
88
import androidx.compose.ui.text.withStyle
99
import co.adityarajput.fileflow.R
10+
import co.adityarajput.fileflow.data.Verb
1011
import co.adityarajput.fileflow.utils.FileSuperlative
1112
import co.adityarajput.fileflow.utils.getGetDirectoryFromUri
1213
import co.adityarajput.fileflow.utils.toShortHumanReadableTime
@@ -19,7 +20,7 @@ sealed class Action {
1920
abstract val srcFileNamePattern: String
2021
abstract val scanSubdirectories: Boolean
2122

22-
abstract val verb: Int
23+
abstract val verb: Verb
2324
abstract val phrase: Int
2425

2526
@Composable
@@ -45,7 +46,7 @@ sealed class Action {
4546
val superlative: FileSuperlative = FileSuperlative.LATEST,
4647
val preserveStructure: Boolean = scanSubdirectories,
4748
) : Action() {
48-
override val verb get() = if (keepOriginal) R.string.copy else R.string.move
49+
override val verb get() = if (keepOriginal) Verb.COPY else Verb.MOVE
4950

5051
override val phrase = R.string.move_phrase
5152

@@ -73,7 +74,7 @@ sealed class Action {
7374
val retentionDays: Int = 30,
7475
override val scanSubdirectories: Boolean = false,
7576
) : Action() {
76-
override val verb get() = R.string.delete_stale
77+
override val verb get() = Verb.DELETE_STALE
7778

7879
override val phrase = R.string.delete_stale_phrase
7980

app/src/main/java/co/adityarajput/fileflow/data/models/Execution.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
package co.adityarajput.fileflow.data.models
22

3+
import androidx.room.ColumnInfo
34
import androidx.room.Entity
45
import androidx.room.PrimaryKey
6+
import co.adityarajput.fileflow.data.Verb
57

68
@Entity(tableName = "executions")
79
data class Execution(
810
val fileName: String,
911

10-
val actionVerb: Int,
12+
@ColumnInfo(defaultValue = "MOVE")
13+
val verb: Verb,
1114

1215
val timestamp: Long = System.currentTimeMillis(),
1316

app/src/main/java/co/adityarajput/fileflow/views/components/FolderPickerBottomSheet.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ fun FolderPickerBottomSheet(viewModel: UpsertRuleViewModel) {
4949
)
5050
HorizontalDivider()
5151
LazyColumn(
52-
Modifier.padding(dimensionResource(R.dimen.padding_medium)),
52+
Modifier
53+
.weight(1f)
54+
.padding(dimensionResource(R.dimen.padding_medium)),
5355
verticalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.padding_medium)),
5456
) {
5557
if (currentDir.parentFile?.canRead() ?: false) {

app/src/main/java/co/adityarajput/fileflow/views/components/ImproperRulesetDialog.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ fun ImproperRulesetDialog(
5151
rulesToBeMigrated.forEach {
5252
Tile(
5353
it.action.srcFileNamePattern,
54-
stringResource(it.action.verb),
54+
stringResource(it.action.verb.resource),
5555
if (!it.enabled) stringResource(R.string.disabled)
5656
else pluralStringResource(
5757
R.plurals.execution,

app/src/main/java/co/adityarajput/fileflow/views/screens/ExecutionsScreen.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ fun ExecutionsScreen(
6363
items(state.value.executions!!, { it.id }) {
6464
Tile(
6565
it.fileName,
66-
stringResource(it.actionVerb),
66+
stringResource(it.verb.resource),
6767
stringResource(
6868
R.string.ago,
6969
(System.currentTimeMillis() - it.timestamp).toShortHumanReadableTime(),

0 commit comments

Comments
 (0)