So I'm creating a GitHub mobile where I can search for users and look at the profile. I'm trying to create a favorite feature where the user can be added to favorites database when clicking the button in the details page. I've already created the DatabaseHandler class and also have set the functions to add in the activity. Here is the code for the database handler:
class DatabaseHandler(context:Context):SQLiteOpenHelper(context,DATABASE_NAME,null,DATABASE_VERSION) {
companion object {
private const val DATABASE_VERSION = 1
private const val DATABASE_NAME = "FavoriteUsersDatabase"
private const val TABLE_NAME = "FavoriteTable"
private const val KEY_ID = "_id" //primary key -> unique for each record
private const val KEY_USERNAME = "username"
}
//onCreate is called once the database is created
override fun onCreate(db: SQLiteDatabase?) {
//creating table with fields -> using SQL command
val CREATE_USER_TABLE = ("CREATE TABLE "+ TABLE_NAME+
"("+ KEY_ID+" INTEGER PRIMARY KEY,"+
KEY_USERNAME+" TEXT"+")")
//execute the SQL command
db?.execSQL(CREATE_USER_TABLE)
}
//onUpgrade is called when we upgrade our table
override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
db!!.execSQL("DROP TABLE IF EXISTS "+ TABLE_NAME)
onCreate(db)
}
/**
* Adds to database: CREATE
*/
fun addUserToFavorite(user: FavoriteModelClass): Long{
//initialize the database that we want to write on
val db = this.writableDatabase
//contentValues carry the data that we want to put in the database
val contentValues = ContentValues()
//id is unecessary as it will automatically increment
contentValues.put(KEY_USERNAME,user.username) //putting the username
//success will return a long value
val success = db.insert(TABLE_NAME,null,contentValues)
db.close()
return success
}
/**
* Reading the data in database. Returns the user object: READ
*/
fun viewUserInFavorite(): ArrayList<FavoriteModelClass>{
val userList: ArrayList<FavoriteModelClass> = ArrayList<FavoriteModelClass>()
//selects ALL data, SQL command. Give me everything in the table!
val selectQuery = "SELECT * FROM $TABLE_NAME"
//initialize the database that we want to read on
val db = this.readableDatabase
//A SQL cursor retrieves data one row at a time
var cursor: Cursor? = null
try {
cursor = db.rawQuery(selectQuery,null)
} catch (e: SQLiteException){
db.execSQL(selectQuery)
return ArrayList()
}
//make variables to store data
var id: Int
var username: String
//cursor moves to each entry one by one and retrieves data
if (cursor.moveToFirst()){
do {
id = cursor.getInt(cursor.getColumnIndex(KEY_ID))
username = cursor.getString(cursor.getColumnIndex(KEY_USERNAME))
val user = FavoriteModelClass(id = id,username = username)
userList.add(user)
} while (cursor.moveToNext())
}
return userList
}
/**
* Deletes a user from favorite: DELETE
*/
fun deleteUserInFavoriteByUsername(username: String): Int{
//initialize the database that we want to delete on
val db = this.writableDatabase
//setup the container to show which user we want to delete
val contentValues = ContentValues()
contentValues.put(KEY_USERNAME,username)
//Deleting Row where user is that
val success = db.delete(TABLE_NAME, "$KEY_USERNAME=$username",null)
db.close()
return success
}
}
Here is the code in the activity:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityDetailUserBinding.inflate(layoutInflater)
setContentView(binding.root)
username = intent.getStringExtra(EXTRA_USERNAME).toString()
binding.usernameSearchDetail.text = username
setDetailData()
val sectionsPagerAdapter = SectionsPagerAdapter(this)
sectionsPagerAdapter.username = username
val viewPager: ViewPager2 = binding.viewPager
viewPager.adapter = sectionsPagerAdapter
val tabs: TabLayout = binding.tabs
TabLayoutMediator(tabs,viewPager){tab,position->
tab.text = resources.getString(TAB_TITLES[position])
}.attach()
var statusFavorite = false
favoriteIcon = binding.toolbar.buttonFavorite
setStatusFavorite(statusFavorite)
favoriteIcon.setOnClickListener{
statusFavorite = !statusFavorite
setStatusFavorite(statusFavorite)
if (statusFavorite == true){
addToFavorite()
} else if (statusFavorite == false){
deleteFromFavorite()
}
}
}
/**
* Adds to favorite database
*/
private fun addToFavorite(){
//initialize the database handler object
val databaseHandler: DatabaseHandler = DatabaseHandler(this)
val status = databaseHandler.addUserToFavorite(FavoriteModelClass(0,username))
if (status>-1){
Toast.makeText(this,"Added $username to favorites!",Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this,"Failed to add $username to favorites!",Toast.LENGTH_SHORT).show()
}
}
/**
* Deletes user from favorite database
*/
private fun deleteFromFavorite(){
val databaseHandler: DatabaseHandler = DatabaseHandler(this)
val status = databaseHandler.deleteUserInFavoriteByUsername(username)
if (status>-1){
Toast.makeText(this,"Removed $username from favorites!",Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this,"Failed to remove $username from favorites!",Toast.LENGTH_SHORT).show()
}
}
private fun setStatusFavorite(statusFavorite: Boolean) {
if (statusFavorite){
favoriteIcon.setImageResource(R.drawable.ic_favorite)
} else {
favoriteIcon.setImageResource(R.drawable.ic_baseline_favorite_border_24)
}
}
I'm stuck in this. Here is my stack trace:
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.dicoding.githubclone, PID: 10878
android.database.sqlite.SQLiteException: no such column: brian (code 1 SQLITE_ERROR): , while compiling: DELETE FROM FavoriteTable WHERE username=brian
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1102)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:667)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:590)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:61)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:33)
at android.database.sqlite.SQLiteDatabase.delete(SQLiteDatabase.java:1727)
at com.dicoding.githubclone.database.DatabaseHandler.deleteUserInFavoriteByUsername(DatabaseHandler.kt:100)
at com.dicoding.githubclone.activity.DetailUserActivity.deleteFromFavorite(DetailUserActivity.kt:93)
at com.dicoding.githubclone.activity.DetailUserActivity.access$deleteFromFavorite(DetailUserActivity.kt:26)
at com.dicoding.githubclone.activity.DetailUserActivity$onCreate$2.onClick(DetailUserActivity.kt:69)
at android.view.View.performClick(View.java:7500)
at android.view.View.performClickInternal(View.java:7472)
at android.view.View.access$3600(View.java:824)
at android.view.View$PerformClick.run(View.java:28657)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:239)
at android.app.ActivityThread.main(ActivityThread.java:8107)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:626)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1015)