Skip to content

Commit e0494be

Browse files
Add database migration handling and image migration use case
Co-authored-by: abdallahmehiz <54363735+abdallahmehiz@users.noreply.github.com>
1 parent 36fe3f8 commit e0494be

File tree

4 files changed

+78
-1
lines changed

4 files changed

+78
-1
lines changed

domain/data/src/androidMain/kotlin/mehiz/abdallah/progres/data/database/DatabaseModule.android.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,26 @@ actual val ProgresDatabaseModule = module {
1919
override fun onOpen(db: SupportSQLiteDatabase) {
2020
db.setForeignKeyConstraintsEnabled(true)
2121
}
22+
23+
override fun onUpgrade(
24+
db: SupportSQLiteDatabase,
25+
oldVersion: Int,
26+
newVersion: Int
27+
) {
28+
// Handle migration from BLOB to file storage
29+
// Clear affected tables to force fresh sync with new schema
30+
if (oldVersion < newVersion) {
31+
try {
32+
db.execSQL("DROP TABLE IF EXISTS IndividualInfoTable")
33+
db.execSQL("DROP TABLE IF EXISTS StudentCardTable")
34+
// Recreate tables with new schema
35+
onCreate(db)
36+
} catch (e: Exception) {
37+
// If migration fails, recreate database
38+
super.onUpgrade(db, oldVersion, newVersion)
39+
}
40+
}
41+
}
2242
}
2343
),
2444
)

domain/data/src/commonMain/sqldelight/mehiz/abdallah/progres/data/db/IndividualInfoTable.sq

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CREATE TABLE IndividualInfoTable(
1+
CREATE TABLE IF NOT EXISTS IndividualInfoTable(
22
id INTEGER NOT NULL PRIMARY KEY,
33
firstNameArabic TEXT NOT NULL,
44
firstNameLatin TEXT NOT NULL,
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package mehiz.abdallah.progres.domain
2+
3+
import mehiz.abdallah.progres.data.daos.IndividualInfoDao
4+
import mehiz.abdallah.progres.data.daos.StudentCardDao
5+
import utils.FileStorageManager
6+
import kotlinx.coroutines.Dispatchers
7+
import kotlinx.coroutines.withContext
8+
9+
/**
10+
* Handles migration of image data from database BLOBs to file storage
11+
* This is used during the transition period to ensure compatibility
12+
*/
13+
class ImageMigrationUseCase(
14+
private val individualInfoDao: IndividualInfoDao,
15+
private val studentCardDao: StudentCardDao,
16+
private val fileStorageManager: FileStorageManager
17+
) {
18+
19+
/**
20+
* Checks if migration is needed and suggests a refresh
21+
* Since this is a significant change, we recommend users refresh their data
22+
* to get images stored in the new file format
23+
*/
24+
suspend fun isMigrationNeeded(): Boolean = withContext(Dispatchers.IO) {
25+
// Check if there are any records that might have old BLOB data
26+
// Since we changed schema, old data will be cleaned during refresh
27+
val individualInfo = individualInfoDao.getIndividualInfo()
28+
val studentCards = studentCardDao.getAllStudentCards()
29+
30+
// If no data exists, no migration needed
31+
if (individualInfo == null && studentCards.isEmpty()) {
32+
return@withContext false
33+
}
34+
35+
// Check if we have photo paths (new format) or if they're missing (needs refresh)
36+
val needsPhotoMigration = individualInfo?.photoPath == null
37+
val needsLogoMigration = studentCards.any { it.establishmentLogoPath == null }
38+
39+
needsPhotoMigration || needsLogoMigration
40+
}
41+
42+
/**
43+
* Clears all data to force a fresh sync with the new file storage format
44+
* This is the safest migration approach for this type of schema change
45+
*/
46+
suspend fun forceFreshSync() = withContext(Dispatchers.IO) {
47+
// Clean up any existing files
48+
fileStorageManager.deleteAllProfilePictures()
49+
fileStorageManager.deleteAllUniversityLogos()
50+
51+
// Clear database to force fresh sync
52+
individualInfoDao.deleteAllIndividualInfo()
53+
studentCardDao.deleteAllCards()
54+
}
55+
}

domain/src/commonMain/kotlin/mehiz/abdallah/progres/domain/di/DomainModule.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import mehiz.abdallah.progres.domain.DischargeUseCase
1111
import mehiz.abdallah.progres.domain.ExamGradeUseCase
1212
import mehiz.abdallah.progres.domain.ExamScheduleUseCase
1313
import mehiz.abdallah.progres.domain.GroupUseCase
14+
import mehiz.abdallah.progres.domain.ImageMigrationUseCase
1415
import mehiz.abdallah.progres.domain.StudentCardUseCase
1516
import mehiz.abdallah.progres.domain.SubjectScheduleUseCase
1617
import mehiz.abdallah.progres.domain.SubjectUseCase
@@ -39,4 +40,5 @@ val DomainModule = module {
3940
singleOf(::UserAuthUseCase)
4041
singleOf(::DischargeUseCase)
4142
singleOf(::AccommodationUseCase)
43+
singleOf(::ImageMigrationUseCase)
4244
}

0 commit comments

Comments
 (0)