Skip to content

Commit 4094a57

Browse files
committed
Add DatabaseConfiguration.downgrade
This allows clients to implement custom downgrade behavior (such as destructive migrations, etc).
1 parent a37bbe7 commit 4094a57

File tree

4 files changed

+47
-14
lines changed

4 files changed

+47
-14
lines changed

sqliter-driver/src/nativeCommonMain/kotlin/co/touchlab/sqliter/DatabaseConfiguration.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ data class DatabaseConfiguration(
3535
val version: Int,
3636
val create: (DatabaseConnection) -> Unit,
3737
val upgrade: (DatabaseConnection, Int, Int) -> Unit = { _, _, _ -> },
38+
val downgrade: (DatabaseConnection, Int, Int) -> Unit = { _, initialVersion, version ->
39+
error("Database version $initialVersion newer than config version $version")
40+
},
3841
val inMemory: Boolean = false,
3942
val journalMode: JournalMode = JournalMode.WAL,
4043
val extendedConfig:Extended = Extended(),

sqliter-driver/src/nativeCommonMain/kotlin/co/touchlab/sqliter/native/NativeDatabaseConnection.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ class NativeDatabaseConnection internal constructor(
9292
fun migrateIfNeeded(
9393
create: (DatabaseConnection) -> Unit,
9494
upgrade: (DatabaseConnection, Int, Int) -> Unit,
95+
downgrade: (DatabaseConnection, Int, Int) -> Unit,
9596
version: Int
9697
) {
9798
this.withTransaction {
@@ -100,10 +101,11 @@ class NativeDatabaseConnection internal constructor(
100101
create(this)
101102
setVersion(version)
102103
} else if (initialVersion != version) {
103-
if (initialVersion > version)
104-
throw IllegalStateException("Database version $initialVersion newer than config version $version")
105-
106-
upgrade(this, initialVersion, version)
104+
if (initialVersion > version) {
105+
downgrade(this, initialVersion, version)
106+
} else {
107+
upgrade(this, initialVersion, version)
108+
}
107109
setVersion(version)
108110
}
109111
}

sqliter-driver/src/nativeCommonMain/kotlin/co/touchlab/sqliter/native/NativeDatabaseManager.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class NativeDatabaseManager(private val path:String,
8989
try {
9090
val version = configuration.version
9191
if(version != NO_VERSION_CHECK)
92-
conn.migrateIfNeeded(configuration.create, configuration.upgrade, version)
92+
conn.migrateIfNeeded(configuration.create, configuration.upgrade, configuration.downgrade, version)
9393
} catch (e: Exception) {
9494

9595
// If this failed, we have to close the connection or we will end up leaking it.

sqliter-driver/src/nativeCommonTest/kotlin/co/touchlab/sqliter/DatabaseManagerTest.kt

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,7 @@ class DatabaseManagerTest : BaseDatabaseTest(){
149149
}
150150

151151
@Test
152-
fun downgradeNotAllowed(){
153-
val upgradeCalled = AtomicInt(0)
152+
fun downgradeNotAllowedByDefault() {
154153
val config1 = DatabaseConfiguration(
155154
name = TEST_DB_NAME,
156155
version = 1,
@@ -159,16 +158,11 @@ class DatabaseManagerTest : BaseDatabaseTest(){
159158
execute()
160159
}
161160
},
162-
upgrade = { _, _, _ ->
163-
upgradeCalled.increment()
164-
},
165161
loggingConfig = DatabaseConfiguration.Logging(logger = NoneLogger),
166162
)
167163

168-
createDatabaseManager(config1).withConnection { }
169-
assertEquals(0, upgradeCalled.value)
170-
createDatabaseManager(config1.copy(version = 2)).withConnection { }
171-
assertEquals(1, upgradeCalled.value)
164+
createDatabaseManager(config1).withConnection { }
165+
createDatabaseManager(config1.copy(version = 2)).withConnection { }
172166

173167
var conn: DatabaseConnection? = null
174168
assertFails {
@@ -178,6 +172,40 @@ class DatabaseManagerTest : BaseDatabaseTest(){
178172
conn?.close()
179173
}
180174

175+
@Test
176+
fun downgradeCalled() {
177+
val upgradeCalled = AtomicInt(0)
178+
val downgradeCalled = AtomicInt(0)
179+
val config1 = DatabaseConfiguration(
180+
name = TEST_DB_NAME,
181+
version = 1,
182+
create = { db ->
183+
db.withStatement(TWO_COL) {
184+
execute()
185+
}
186+
},
187+
upgrade = { _, _, _ ->
188+
upgradeCalled.increment()
189+
},
190+
downgrade = { _, _, _ ->
191+
downgradeCalled.increment()
192+
},
193+
loggingConfig = DatabaseConfiguration.Logging(logger = NoneLogger),
194+
)
195+
196+
createDatabaseManager(config1).withConnection { }
197+
assertEquals(0, upgradeCalled.value)
198+
assertEquals(0, downgradeCalled.value)
199+
200+
createDatabaseManager(config1.copy(version = 2)).withConnection { }
201+
assertEquals(1, upgradeCalled.value)
202+
assertEquals(0, downgradeCalled.value)
203+
204+
createDatabaseManager(config1.copy(version = 1)).withConnection { }
205+
assertEquals(1, upgradeCalled.value)
206+
assertEquals(1, downgradeCalled.value)
207+
}
208+
181209
@Test
182210
fun failedCreateRollsBack(){
183211
val configFail = DatabaseConfiguration(

0 commit comments

Comments
 (0)