Disclaimer: I'm a complete beginner to Android development in Kotlin and just started some weeks ago.
My goal is to create an Quiz App which gets it's Questions and Answers from a local, prepopulated Room database.
SQLITE:
The sqlite database has the following schema:
sqlite> .schema
CREATE TABLE quiz_questions(ID INTEGER PRIMARY KEY, question TEXT, quest_result INTEGER NOT NULL DEFAULT 0);
CREATE TABLE quiz_answers(ID INTEGER PRIMARY KEY, quest_id INTEGER, answer TEXT, is_true INTEGER NOT NULL);
=> The quest_id is the foreign key which reflects the ID of the related question
=> One question has many answers (specifically 4 in my case)
Links:
I used the following guides to create my app and add the relationship:
General App: https://www.youtube.com/watch?v=8YPXv7xKh2w
Relationship: https://developer.android.com/training/data-storage/room/relationships#one-to-many
Entities:
Question.kt:
@Entity(tableName = "quiz_questions")
data class Question(
@PrimaryKey val ID: Int,
val question: String?,
var quest_result: Boolean
)
Answer.kt:
@Entity(tableName = "quiz_answers")
data class Answer(
@PrimaryKey val ID: Int,
@ColumnInfo(index = true) val quest_id: Int,
val answer: String,
val is_true: Boolean
)
QuestionWithAnswers.kt:
data class QuestionWithAnswers(
@Embedded val question: Question,
@Relation(
entity = Answer::class,
parentColumn = "ID",
entityColumn = "quest_id"
)
val answer: List<Answer>
)
Repository:
interface Rep_QuestionWithAnswers {
fun getQuestionAndAnswers(id: Int): List<QuestionWithAnswers>
}
UseCase:
class UC_GetQuestionWithAnswers (
private val repository: Rep_QuestionWithAnswers
) {
operator fun invoke(id: Int): List<QuestionWithAnswers> {
return repository.getQuestionAndAnswers(id)
}
}
Implementation:
class Impl_Rep_QuestionWithAnswers (
private val dao: Dao_QuestionWithAnswers
) : Rep_QuestionWithAnswers {
override fun getQuestionAndAnswers(id: Int): List<QuestionWithAnswers> {
return dao.getQuestionAndAnswers(id)
}
}
Dao:
@Dao
interface Dao_QuestionWithAnswers {
@Transaction
@Query("SELECT * FROM quiz_questions WHERE ID = :id")
fun getQuestionAndAnswers(id: Int): List<QuestionWithAnswers>
}
QuizDatabase:
@Database(
entities = [
Question::class,
Answer::class,
QuestionWithAnswers::class
],
version = 1
)
abstract class QuizDatabase : RoomDatabase () {
abstract val Dao_Question : Dao_Question
abstract val Dao_Answer : Dao_Answer
abstract val Dao_QuestionWithAnswers : Dao_QuestionWithAnswers
companion object {
const val DATABASE_NAME = "quiz_db"
}
}
=> I created the Rep_, Impl_ and Dao_ for Answer and Question as well but didn't upload them here
Expectations:
- I was expecting it to compile first of all
- I want to get all questions and answers so that I can put them in a for loop and show them on the screen
- When a answer is chosen I need to check whether the ID of the answer has value is_true = true
- When a question was answered correctly, I need to update the result to value = true of the question with ID
What I already tried:
- Define the foreign key in the Answer.kt file without changing anything else
@Entity(
tableName = "quiz_answers",
foreignKeys = [
ForeignKey(
entity = Question::class,
parentColumns = ["ID"],
childColumns = ["quest_id"]
)
]
)
data class Answer(
@PrimaryKey val ID: Int,
@ColumnInfo(index = true) val quest_id: Int,
val answer: String,
val is_true: Boolean
)
Errors:
- error: Entity class must be annotated with @Entity
- error: Entities cannot have relations
- error: An entity must have at least 1 field annotated with @PrimaryKey
Questions:
- Is it correct to create an individual Dao_, Rep_ and Impl_ file for the relationship?
- Why does the compiler assume that the data class QuestionWithAnswers should be an entity?
- Is collection the correct datatype for the result of the query?
Thank's for all answers :)