From 23c05b91d5e3e2d5cb578857bc142d5990cf7f27 Mon Sep 17 00:00:00 2001 From: klaus Date: Wed, 22 Oct 2025 19:19:31 +0900 Subject: [PATCH] =?UTF-8?q?build(room):=20KSP=20room.schemaLocation=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EB=B0=8F=20exportSchema=3Dtrue=EB=A1=9C?= =?UTF-8?q?=20=EC=8A=A4=ED=82=A4=EB=A7=88=20export=20=ED=99=9C=EC=84=B1?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 프로젝트가 이미 KSP를 사용하고 있어 KSP 인수 기반으로 Room 스키마 export를 활성화했습니다. - app/build.gradle: ksp { room.schemaLocation 등 } 추가 - Room DB 클래스 3종: exportSchema=true - app/schemas 디렉터리 버전 관리 --- app/build.gradle | 8 ++ app/schemas/.gitkeep | 1 + .../1.json | 76 +++++++++++++++++ .../2.json | 82 +++++++++++++++++++ .../1.json | 58 +++++++++++++ .../db/PlaybackTrackingDatabase.kt | 2 +- .../sodalive/mypage/alarm/db/AlarmDatabase.kt | 6 +- .../mypage/recent/db/RecentContentDatabase.kt | 2 +- build.gradle | 4 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 10 files changed, 233 insertions(+), 8 deletions(-) create mode 100644 app/schemas/.gitkeep create mode 100644 app/schemas/kr.co.vividnext.sodalive.audio_content.db.PlaybackTrackingDatabase/1.json create mode 100644 app/schemas/kr.co.vividnext.sodalive.mypage.alarm.db.AlarmDatabase/2.json create mode 100644 app/schemas/kr.co.vividnext.sodalive.mypage.recent.db.RecentContentDatabase/1.json diff --git a/app/build.gradle b/app/build.gradle index a9ff51d1..a56122c9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -214,3 +214,11 @@ dependencies { testImplementation 'org.mockito.kotlin:mockito-kotlin:5.3.1' testImplementation 'io.mockk:mockk:1.13.10' } + + +// KSP args for Room schema export +ksp { + arg("room.schemaLocation", "$projectDir/schemas") + arg("room.incremental", "true") + arg("room.expandProjection", "true") +} diff --git a/app/schemas/.gitkeep b/app/schemas/.gitkeep new file mode 100644 index 00000000..2a178f6a --- /dev/null +++ b/app/schemas/.gitkeep @@ -0,0 +1 @@ +# Keep schemas directory under version control diff --git a/app/schemas/kr.co.vividnext.sodalive.audio_content.db.PlaybackTrackingDatabase/1.json b/app/schemas/kr.co.vividnext.sodalive.audio_content.db.PlaybackTrackingDatabase/1.json new file mode 100644 index 00000000..0ff8aaa5 --- /dev/null +++ b/app/schemas/kr.co.vividnext.sodalive.audio_content.db.PlaybackTrackingDatabase/1.json @@ -0,0 +1,76 @@ +{ + "formatVersion": 1, + "database": { + "version": 1, + "identityHash": "b9a331035b36b70f8ca7a14962b13fdf", + "entities": [ + { + "tableName": "playback_tracking", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `contentId` INTEGER NOT NULL, `totalDuration` INTEGER NOT NULL, `startPosition` INTEGER NOT NULL, `isFree` INTEGER NOT NULL, `isPreview` INTEGER NOT NULL, `endPosition` INTEGER, `playDateTime` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "contentId", + "columnName": "contentId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "totalDuration", + "columnName": "totalDuration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "startPosition", + "columnName": "startPosition", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isFree", + "columnName": "isFree", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isPreview", + "columnName": "isPreview", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "endPosition", + "columnName": "endPosition", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "playDateTime", + "columnName": "playDateTime", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'b9a331035b36b70f8ca7a14962b13fdf')" + ] + } +} \ No newline at end of file diff --git a/app/schemas/kr.co.vividnext.sodalive.mypage.alarm.db.AlarmDatabase/2.json b/app/schemas/kr.co.vividnext.sodalive.mypage.alarm.db.AlarmDatabase/2.json new file mode 100644 index 00000000..8a66d574 --- /dev/null +++ b/app/schemas/kr.co.vividnext.sodalive.mypage.alarm.db.AlarmDatabase/2.json @@ -0,0 +1,82 @@ +{ + "formatVersion": 1, + "database": { + "version": 2, + "identityHash": "7429c2998f64cb70e5e8b1d2525a4708", + "entities": [ + { + "tableName": "alarms", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT NOT NULL, `time` INTEGER NOT NULL, `days` TEXT NOT NULL, `contentId` INTEGER NOT NULL, `contentTitle` TEXT NOT NULL, `contentCreatorNickname` TEXT NOT NULL, `volume` INTEGER NOT NULL, `isEnabled` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "time", + "columnName": "time", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "days", + "columnName": "days", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "contentId", + "columnName": "contentId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "contentTitle", + "columnName": "contentTitle", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "contentCreatorNickname", + "columnName": "contentCreatorNickname", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "volume", + "columnName": "volume", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isEnabled", + "columnName": "isEnabled", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '7429c2998f64cb70e5e8b1d2525a4708')" + ] + } +} \ No newline at end of file diff --git a/app/schemas/kr.co.vividnext.sodalive.mypage.recent.db.RecentContentDatabase/1.json b/app/schemas/kr.co.vividnext.sodalive.mypage.recent.db.RecentContentDatabase/1.json new file mode 100644 index 00000000..6cc7d181 --- /dev/null +++ b/app/schemas/kr.co.vividnext.sodalive.mypage.recent.db.RecentContentDatabase/1.json @@ -0,0 +1,58 @@ +{ + "formatVersion": 1, + "database": { + "version": 1, + "identityHash": "e46a8b457c3ea6ceefd0db76bb763056", + "entities": [ + { + "tableName": "recent_contents", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`contentId` INTEGER NOT NULL, `coverImageUrl` TEXT NOT NULL, `title` TEXT NOT NULL, `creatorNickname` TEXT NOT NULL, `listenedAt` INTEGER NOT NULL, PRIMARY KEY(`contentId`))", + "fields": [ + { + "fieldPath": "contentId", + "columnName": "contentId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "coverImageUrl", + "columnName": "coverImageUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "creatorNickname", + "columnName": "creatorNickname", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "listenedAt", + "columnName": "listenedAt", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "contentId" + ] + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'e46a8b457c3ea6ceefd0db76bb763056')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/db/PlaybackTrackingDatabase.kt b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/db/PlaybackTrackingDatabase.kt index 4983086d..ef22d3ad 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/audio_content/db/PlaybackTrackingDatabase.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/audio_content/db/PlaybackTrackingDatabase.kt @@ -8,7 +8,7 @@ import androidx.room.TypeConverters import kr.co.vividnext.sodalive.audio_content.PlaybackTracking import kr.co.vividnext.sodalive.common.Converter -@Database(entities = [PlaybackTracking::class], version = 1) +@Database(entities = [PlaybackTracking::class], version = 1, exportSchema = true) @TypeConverters(Converter::class) abstract class PlaybackTrackingDatabase : RoomDatabase() { abstract fun playbackTrackingDao(): PlaybackTrackingDao diff --git a/app/src/main/java/kr/co/vividnext/sodalive/mypage/alarm/db/AlarmDatabase.kt b/app/src/main/java/kr/co/vividnext/sodalive/mypage/alarm/db/AlarmDatabase.kt index 4b1edef2..e97077da 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/mypage/alarm/db/AlarmDatabase.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/mypage/alarm/db/AlarmDatabase.kt @@ -9,7 +9,7 @@ import androidx.room.migration.Migration import androidx.sqlite.db.SupportSQLiteDatabase import kr.co.vividnext.sodalive.common.Converter -@Database(entities = [Alarm::class], version = 2) +@Database(entities = [Alarm::class], version = 2, exportSchema = true) @TypeConverters(Converter::class) abstract class AlarmDatabase : RoomDatabase() { abstract fun alarmDao(): AlarmDao @@ -33,8 +33,8 @@ abstract class AlarmDatabase : RoomDatabase() { } private val MIGRATION_1_2 = object : Migration(1, 2) { - override fun migrate(database: SupportSQLiteDatabase) { - database.execSQL( + override fun migrate(db: SupportSQLiteDatabase) { + db.execSQL( "ALTER TABLE 'alarms' ADD COLUMN 'volume' integer not null default 15" ) } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/mypage/recent/db/RecentContentDatabase.kt b/app/src/main/java/kr/co/vividnext/sodalive/mypage/recent/db/RecentContentDatabase.kt index 28e99d7b..d94e77b6 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/mypage/recent/db/RecentContentDatabase.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/mypage/recent/db/RecentContentDatabase.kt @@ -7,7 +7,7 @@ import androidx.room.RoomDatabase import androidx.room.TypeConverters import kr.co.vividnext.sodalive.common.Converter -@Database(entities = [RecentContent::class], version = 1) +@Database(entities = [RecentContent::class], version = 1, exportSchema = true) @TypeConverters(Converter::class) abstract class RecentContentDatabase : RoomDatabase() { abstract fun recentContentDao(): RecentContentDao diff --git a/build.gradle b/build.gradle index d0dab3d8..f1506730 100644 --- a/build.gradle +++ b/build.gradle @@ -16,8 +16,8 @@ buildscript { } plugins { - id 'com.android.application' version '8.4.2' apply false - id 'com.android.library' version '8.4.2' apply false + id 'com.android.application' version '8.7.2' apply false + id 'com.android.library' version '8.7.2' apply false id 'org.jetbrains.kotlin.android' version '2.0.21' apply false id 'com.google.devtools.ksp' version '2.0.21-1.0.25' apply false diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index cf4648e1..adf24a0c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Sun Jul 23 18:26:44 KST 2023 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists