package com.example.scanwich import android.content.Context import androidx.room.* import androidx.room.migration.Migration import androidx.sqlite.db.SupportSQLiteDatabase import kotlinx.coroutines.flow.Flow @Entity(tableName = "meals") data class Meal( @PrimaryKey(autoGenerate = true) val id: Int = 0, val date: Long, val name: String = "Repas", val analysisText: String, val totalCalories: Int, val carbs: Int = 0, val protein: Int = 0, val fat: Int = 0, val type: String = "Collation" ) @Entity(tableName = "glycemia") data class Glycemia( @PrimaryKey(autoGenerate = true) val id: Int = 0, val date: Long, val value: Double, val moment: String ) @Entity(tableName = "sports") data class SportActivity( @PrimaryKey val id: Long, val name: String, val type: String, val distance: Float, val movingTime: Int, val calories: Float?, val date: Long // timestamp ) @Entity(tableName = "favorite_meals") data class FavoriteMeal( @PrimaryKey(autoGenerate = true) val id: Int = 0, val name: String, val analysisText: String, val calories: Int, val carbs: Int, val protein: Int, val fat: Int ) @Dao interface AppDao { @Insert suspend fun insertMeal(meal: Meal): Long @Delete suspend fun deleteMeal(meal: Meal) @Query("SELECT * FROM meals ORDER BY date DESC") fun getAllMeals(): Flow> @Query("SELECT * FROM meals WHERE date >= :startOfDay AND date < :endOfDay ORDER BY date DESC") fun getMealsForDay(startOfDay: Long, endOfDay: Long): Flow> @Query("SELECT * FROM meals WHERE date >= :start AND date <= :end ORDER BY date ASC") suspend fun getMealsInRangeSync(start: Long, end: Long): List @Insert suspend fun insertGlycemia(glycemia: Glycemia): Long @Delete suspend fun deleteGlycemia(glycemia: Glycemia) @Query("SELECT * FROM glycemia ORDER BY date DESC") fun getAllGlycemia(): Flow> @Query("SELECT * FROM glycemia WHERE date >= :startOfDay AND date < :endOfDay ORDER BY date DESC") fun getGlycemiaForDay(startOfDay: Long, endOfDay: Long): Flow> @Query("SELECT * FROM glycemia WHERE date >= :start AND date <= :end ORDER BY date ASC") suspend fun getGlycemiaInRangeSync(start: Long, end: Long): List @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertSports(sports: List) @Query("SELECT * FROM sports ORDER BY date DESC") fun getAllSports(): Flow> @Query("SELECT * FROM sports WHERE date >= :startOfDay AND date < :endOfDay ORDER BY date DESC") fun getSportsForDay(startOfDay: Long, endOfDay: Long): Flow> @Query("SELECT * FROM sports WHERE date >= :start AND date <= :end ORDER BY date ASC") suspend fun getSportsInRangeSync(start: Long, end: Long): List @Insert suspend fun insertFavorite(meal: FavoriteMeal) @Delete suspend fun deleteFavorite(meal: FavoriteMeal) @Query("SELECT * FROM favorite_meals ORDER BY name ASC") fun getAllFavorites(): Flow> } @Database(entities = [Meal::class, Glycemia::class, SportActivity::class, FavoriteMeal::class], version = 7) abstract class AppDatabase : RoomDatabase() { abstract fun appDao(): AppDao companion object { @Volatile private var INSTANCE: AppDatabase? = null private val MIGRATION_6_7 = object : Migration(6, 7) { override fun migrate(db: SupportSQLiteDatabase) { db.execSQL("CREATE TABLE IF NOT EXISTS `favorite_meals` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `analysisText` TEXT NOT NULL, `calories` INTEGER NOT NULL, `carbs` INTEGER NOT NULL, `protein` INTEGER NOT NULL, `fat` INTEGER NOT NULL)") } } fun getDatabase(context: Context): AppDatabase = INSTANCE ?: synchronized(this) { Room.databaseBuilder(context.applicationContext, AppDatabase::class.java, "app_db") .addMigrations(MIGRATION_6_7) .fallbackToDestructiveMigration() .build().also { INSTANCE = it } } } }