Room Database Setup

This commit is contained in:
202310715297 RAIHAN ARIQ MUZAKKI 2025-11-12 21:10:17 +07:00
parent 18926eb3e2
commit b3022237a3
9 changed files with 217 additions and 1 deletions

26
.idea/appInsightsSettings.xml generated Normal file
View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AppInsightsSettings">
<option name="tabSettings">
<map>
<entry key="Firebase Crashlytics">
<value>
<InsightsFilterSettings>
<option name="connection">
<ConnectionSetting>
<option name="appId" value="PLACEHOLDER" />
<option name="mobileSdkAppId" value="" />
<option name="projectId" value="" />
<option name="projectNumber" value="" />
</ConnectionSetting>
</option>
<option name="signal" value="SIGNAL_UNSPECIFIED" />
<option name="timeIntervalDays" value="THIRTY_DAYS" />
<option name="visibilityType" value="ALL" />
</InsightsFilterSettings>
</value>
</entry>
</map>
</option>
</component>
</project>

View File

@ -1,6 +1,7 @@
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
id("com.google.devtools.ksp") version "1.9.22-1.0.16"
}
android {
@ -66,4 +67,17 @@ dependencies {
androidTestImplementation(libs.ui.test.junit4)
debugImplementation(libs.ui.tooling)
debugImplementation(libs.ui.test.manifest)
// Room Database - TAMBAHKAN INI SEMUA
val roomVersion = "2.6.1"
implementation("androidx.room:room-runtime:$roomVersion")
implementation("androidx.room:room-ktx:$roomVersion")
ksp("androidx.room:room-compiler:$roomVersion")
// Coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0")
// ViewModel & Lifecycle
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0")
implementation("androidx.lifecycle:lifecycle-runtime-compose:2.7.0")
}

View File

@ -33,6 +33,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import com.example.notebook.data.DatabaseTest
import com.example.notebook.ui.theme.NotebookTheme
class MainActivity : ComponentActivity() {

View File

@ -0,0 +1,44 @@
package com.example.notebook.data
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
/**
* Database utama aplikasi
* Version 1 = versi pertama database kamu
*/
@Database(
entities = [
NotebookEntity::class,
SourceEntity::class,
ChatMessageEntity::class
],
version = 1,
exportSchema = false
)
abstract class AppDatabase : RoomDatabase() {
abstract fun notebookDao(): NotebookDao
companion object {
@Volatile
private var INSTANCE: AppDatabase? = null
/**
* Singleton pattern - hanya ada 1 instance database
*/
fun getDatabase(context: Context): AppDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"notebook_database"
).build()
INSTANCE = instance
instance
}
}
}
}

View File

@ -0,0 +1,31 @@
package com.example.notebook.data
import android.content.Context
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
/**
* Helper untuk test database
* Panggil fungsi ini dari MainActivity untuk test
*/
class DatabaseTest(private val context: Context) {
private val database = AppDatabase.getDatabase(context)
private val dao = database.notebookDao()
fun testInsertNotebook() {
CoroutineScope(Dispatchers.IO).launch {
val testNotebook = NotebookEntity(
title = "Notebook Test",
description = "Ini adalah test database",
createdAt = System.currentTimeMillis(),
updatedAt = System.currentTimeMillis(),
sourceCount = 0
)
val id = dao.insertNotebook(testNotebook)
println("✅ Database Test: Notebook berhasil disimpan dengan ID: $id")
}
}
}

View File

@ -0,0 +1,51 @@
package com.example.notebook.data
import androidx.room.*
import kotlinx.coroutines.flow.Flow
/**
* DAO (Data Access Object) untuk mengakses database
* Semua fungsi ini otomatis dihandle Room
*/
@Dao
interface NotebookDao {
// === NOTEBOOK OPERATIONS ===
@Insert
suspend fun insertNotebook(notebook: NotebookEntity): Long
@Update
suspend fun updateNotebook(notebook: NotebookEntity)
@Delete
suspend fun deleteNotebook(notebook: NotebookEntity)
@Query("SELECT * FROM notebooks ORDER BY updatedAt DESC")
fun getAllNotebooks(): Flow<List<NotebookEntity>>
@Query("SELECT * FROM notebooks WHERE id = :notebookId")
fun getNotebookById(notebookId: Int): Flow<NotebookEntity?>
// === SOURCE OPERATIONS ===
@Insert
suspend fun insertSource(source: SourceEntity)
@Query("SELECT * FROM sources WHERE notebookId = :notebookId")
fun getSourcesByNotebook(notebookId: Int): Flow<List<SourceEntity>>
@Delete
suspend fun deleteSource(source: SourceEntity)
// === CHAT OPERATIONS ===
@Insert
suspend fun insertChatMessage(message: ChatMessageEntity)
@Query("SELECT * FROM chat_messages WHERE notebookId = :notebookId ORDER BY timestamp ASC")
fun getChatHistory(notebookId: Int): Flow<List<ChatMessageEntity>>
@Query("DELETE FROM chat_messages WHERE notebookId = :notebookId")
suspend fun clearChatHistory(notebookId: Int)
}

View File

@ -0,0 +1,48 @@
package com.example.notebook.data
import androidx.room.Entity
import androidx.room.PrimaryKey
/**
* Entity untuk menyimpan data Notebook di database
*/
@Entity(tableName = "notebooks")
data class NotebookEntity(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
val title: String, // Judul notebook
val description: String, // Deskripsi singkat
val createdAt: Long, // Timestamp pembuatan
val updatedAt: Long, // Timestamp update terakhir
val sourceCount: Int = 0 // Jumlah sumber yang diupload
)
/**
* Entity untuk menyimpan sumber/dokumen yang diupload
*/
@Entity(tableName = "sources")
data class SourceEntity(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
val notebookId: Int, // Foreign key ke notebook
val fileName: String, // Nama file
val fileType: String, // Tipe: PDF, Image, Text, dll
val filePath: String, // Path file di storage
val uploadedAt: Long // Timestamp upload
)
/**
* Entity untuk menyimpan chat history dengan AI
*/
@Entity(tableName = "chat_messages")
data class ChatMessageEntity(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
val notebookId: Int, // Foreign key ke notebook
val message: String, // Isi pesan
val isUserMessage: Boolean, // true = user, false = AI
val timestamp: Long // Kapan pesan dikirim
)

View File

@ -2,4 +2,5 @@
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.jetbrains.kotlin.android) apply false
id("com.google.devtools.ksp") version "1.9.22-1.0.16" apply false
}

View File

@ -1,5 +1,5 @@
[versions]
agp = "8.2.2"
agp = "8.13.1"
kotlin = "1.9.22"
coreKtx = "1.12.0"
junit = "4.13.2"