퀴즈 어플에 사용할 기출 문제를 데이터베이스를 통해 활용하기 위해 "어떤 데이터베이스를 사용할지" 결정해야 했다. PostgreSQL 등 다른 선택지도 있었지만, 안드로이드 환경에서 가장 편리하고 구현이 간단한 SQLite를 사용하기로 했다.
총 5개*100=500개의 문제를 입력해야 하는데, 데이터베이스를 작성하는 데에만 시간이 다소 걸릴 것 같다. 단순히 문제를 복사/붙여넣기 하는게 아니라, 문제 채점 이후 보여줄 view에서 문제 및 보기 해설 정보를 담을 값을 찾아서 입력해야 했기 때문이다.
일단, 테스트 케이스로 한 회차의 문제(즉 100문제)만을 다루기로 해보자(내일의 내가 모든 문제를 다 입력했으리라고 믿는다...). 즉 db 파일을 어플을 최초로 실행할 때 내부 데이터베이스로 로드한 뒤 사용할 것이다. 외부 데이터베이스 등을 활용할 수도 있지만, 구현하려는 어플 기능 상 간단한 기출 문제만 SELECT하는 게 기능의 대부분인지라 로컬 데이터베이스를 활용하는 게 편할 것 같았다.
업로드 시 로컬 데이터베이스를 활용하는 방법은 다음과 같다.
init {
val dbExist = checkDatabase()
if (dbExist) {
Log.d("dbCheck", "Database exist")
} else {
Log.d("dbCheck", "Database doesn't exist")
createDatabase()
}
}
createDatebase() 함수는 File 입출력과 마찬가지로 inputStream과 outputStream을 사용해 붙여넣기 한다. 결과적으로 SQLiteDatabase가 관리하는 데이터베이스 폴더 내에는 assets에 초기값으로 로드한 데이터베이스 복사본이 자리 잡게 된다!
db로 업로드된 데이터베이스 활용은 일반적인 SQLite 함수 사용과 동일하다. 본 어플에서는 test_num(몇 회 차 문제인가?), type(어떤 유형인가?)에 따라 퀴즈 문제를 SELECT하고 이를 각 question1, question2 클래스의 리스트에 담아내 return하는 게 주요 기능이다.
fun get_question1(test_num:Int, type:Int): MutableList<question1>{
openDatabase()
val query:String = "SELECT * FROM question1 WHERE question1.test_num = ${test_num} AND question1.type = ${type};"
val cursor = dataBase?.rawQuery(query,null)
cursor?.moveToFirst()
val list = mutableListOf<question1>()
do {
val test_num = cursor?.getInt(0)
val number = cursor?.getInt(1)
val type = cursor?.getInt(2)
val question = cursor?.getString(3)
val question_detail = cursor?.getString(4)
val answer = cursor?.getInt(5)
val choice1 = cursor?.getString(6)
val choice1_detail = cursor?.getString(7)
val choice2 = cursor?.getString(8)
val choice2_detail = cursor?.getString(9)
val choice3 = cursor?.getString(10)
val choice3_detail = cursor?.getString(11)
val choice4 = cursor?.getString(12)
val choice4_detail = cursor?.getString(13)
list.add(question1(test_num, number, type, question, question_detail, answer, choice1, choice1_detail, choice2, choice2_detail,
choice3, choice3_detail, choice4, choice4_detail))
} while (cursor?.moveToNext() == true)
cursor?.close()
close()
return list
}
question1은 간단한 유형의 문제로 각 튜플이 문제와 문제 정보, 보기와 보기 정보를 모두 가지고 있기 때문에 한꺼번에 리스트로 만들어 return한다. rawQuery를 통해 편하게 SELECT할 수 있는데, 이후 유형별/기출별 문제 등 필요에 따른 다른 조회가 생길 때에는 함수 조건을 변경해 다양하게 사용할 예정이다. 위 코드는 가장 기본적인 형태의 문제를 반환하는 경우이다.
그럼... 나중에 만나요!