diff --git a/app/src/main/java/com/hotdeal/alarm/data/local/db/AppDatabase.kt b/app/src/main/java/com/hotdeal/alarm/data/local/db/AppDatabase.kt index cd7f913..13c958e 100644 --- a/app/src/main/java/com/hotdeal/alarm/data/local/db/AppDatabase.kt +++ b/app/src/main/java/com/hotdeal/alarm/data/local/db/AppDatabase.kt @@ -21,7 +21,7 @@ import com.hotdeal.alarm.data.local.db.entity.SiteConfigEntity SiteConfigEntity::class, KeywordEntity::class ], - version = 3, + version = 4, exportSchema = false ) @TypeConverters(Converters::class) @@ -46,11 +46,19 @@ abstract class AppDatabase : RoomDatabase() { /** * Migration 2 -> 3: 인덱스 추가 */ - val MIGRATION_2_3 = object : Migration(2, 3) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("CREATE INDEX IF NOT EXISTS index_hot_deals_siteName_boardName ON hot_deals(siteName, boardName)") - db.execSQL("CREATE INDEX IF NOT EXISTS index_hot_deals_createdAt ON hot_deals(createdAt)") - } - } + val MIGRATION_2_3 = object : Migration(2, 3) { + override fun migrate(db: SupportSQLiteDatabase) { + db.execSQL("CREATE INDEX IF NOT EXISTS index_hot_deals_siteName_boardName ON hot_deals(siteName, boardName)") + db.execSQL("CREATE INDEX IF NOT EXISTS index_hot_deals_createdAt ON hot_deals(createdAt)") + } + } + + /** + * Migration 3 -> 4: 즐겨찾기 필드 추가 + */ + val MIGRATION_3_4 = object : Migration(3, 4) { + override fun migrate(db: SupportSQLiteDatabase) { + db.execSQL("ALTER TABLE hot_deals ADD COLUMN isFavorite INTEGER NOT NULL DEFAULT 0") + } } } diff --git a/app/src/main/java/com/hotdeal/alarm/data/local/db/dao/HotDealDao.kt b/app/src/main/java/com/hotdeal/alarm/data/local/db/dao/HotDealDao.kt index 2ce4b1d..1020d80 100644 --- a/app/src/main/java/com/hotdeal/alarm/data/local/db/dao/HotDealDao.kt +++ b/app/src/main/java/com/hotdeal/alarm/data/local/db/dao/HotDealDao.kt @@ -97,6 +97,28 @@ interface HotDealDao { /** * 제목으로 검색 */ - @Query("SELECT * FROM hot_deals WHERE title LIKE '%' || :query || '%' ORDER BY createdAt DESC") - fun searchDeals(query: String): Flow> + @Query("SELECT * FROM hot_deals WHERE title LIKE '%' || :query || '%' ORDER BY createdAt DESC") + fun searchDeals(query: String): Flow> + + // ========================= + // 즐겨찾기 관련 메서드 + // ========================= + + /** + * 즐겨찾기 핫딜 조회 + */ + @Query("SELECT * FROM hot_deals WHERE isFavorite = 1 ORDER BY createdAt DESC") + fun observeFavoriteDeals(): Flow> + + /** + * 즐겨찾기 상태 토글 + */ + @Query("UPDATE hot_deals SET isFavorite = NOT isFavorite WHERE id = :id") + suspend fun toggleFavorite(id: String) + + /** + * 즐겨찾기 상태 설정 + */ + @Query("UPDATE hot_deals SET isFavorite = :isFavorite WHERE id = :id") + suspend fun setFavorite(id: String, isFavorite: Boolean) } diff --git a/app/src/main/java/com/hotdeal/alarm/data/local/db/entity/HotDealEntity.kt b/app/src/main/java/com/hotdeal/alarm/data/local/db/entity/HotDealEntity.kt index ce1d9eb..a68a7b3 100644 --- a/app/src/main/java/com/hotdeal/alarm/data/local/db/entity/HotDealEntity.kt +++ b/app/src/main/java/com/hotdeal/alarm/data/local/db/entity/HotDealEntity.kt @@ -23,9 +23,10 @@ data class HotDealEntity( val title: String, val url: String, val mallUrl: String?, - val createdAt: Long, - val isNotified: Boolean = false, - val isKeywordMatch: Boolean = false + val createdAt: Long, + val isNotified: Boolean = false, + val isKeywordMatch: Boolean = false, + val isFavorite: Boolean = false // 즐겨찾기 여부 ) { /** * Domain 모델로 변환 @@ -39,8 +40,9 @@ data class HotDealEntity( url = url, mallUrl = mallUrl, createdAt = createdAt, - isNotified = isNotified, - isKeywordMatch = isKeywordMatch + isNotified = isNotified, + isKeywordMatch = isKeywordMatch, + isFavorite = isFavorite ) } @@ -57,8 +59,9 @@ data class HotDealEntity( url = domain.url, mallUrl = domain.mallUrl, createdAt = domain.createdAt, - isNotified = domain.isNotified, - isKeywordMatch = domain.isKeywordMatch + isNotified = domain.isNotified, + isKeywordMatch = domain.isKeywordMatch, + isFavorite = domain.isFavorite ) } } diff --git a/app/src/main/java/com/hotdeal/alarm/di/DatabaseModule.kt b/app/src/main/java/com/hotdeal/alarm/di/DatabaseModule.kt index e0d01fc..116eccf 100644 --- a/app/src/main/java/com/hotdeal/alarm/di/DatabaseModule.kt +++ b/app/src/main/java/com/hotdeal/alarm/di/DatabaseModule.kt @@ -31,10 +31,11 @@ object DatabaseModule { AppDatabase::class.java, AppDatabase.DATABASE_NAME ) - .addMigrations( - AppDatabase.MIGRATION_1_2, - AppDatabase.MIGRATION_2_3 - ) + .addMigrations( + AppDatabase.MIGRATION_1_2, + AppDatabase.MIGRATION_2_3, + AppDatabase.MIGRATION_3_4 + ) .fallbackToDestructiveMigration() .build() } diff --git a/app/src/main/java/com/hotdeal/alarm/domain/model/HotDeal.kt b/app/src/main/java/com/hotdeal/alarm/domain/model/HotDeal.kt index d33438b..f5385b0 100644 --- a/app/src/main/java/com/hotdeal/alarm/domain/model/HotDeal.kt +++ b/app/src/main/java/com/hotdeal/alarm/domain/model/HotDeal.kt @@ -10,9 +10,10 @@ data class HotDeal( val title: String, // 게시글 제목 val url: String, // 게시글 URL val mallUrl: String? = null, // 쇼핑몰 URL (추출된 경우) - val createdAt: Long, // 수집 시간 (timestamp) - val isNotified: Boolean = false, - val isKeywordMatch: Boolean = false + val createdAt: Long, // 수집 시간 (timestamp) + val isNotified: Boolean = false, + val isKeywordMatch: Boolean = false, + val isFavorite: Boolean = false // 즐겨찾기 여부 ) { /** * 사이트 타입 반환