Room nested query and subquery - android

I use Room in my Android project and want to write a complex query. I search about it and there is some answers witch says use #Embedded like this:
class TripAndListsAndListItems {
#Embedded
var trip: Trip? = null
#Relation(parentColumn = "creatorId", entityColumn = "remoteId", entity = User::class)
var user: List<User>? = null
#Relation(parentColumn = "remoteId", entityColumn = "tripId", entity = PlanitiList::class)
var lists: List<ListAndListItems>? = null
}
Here is complete article.
But then i have to figure it out in my code to extract my result using loops and so on.
I wrote my query in #Query with nested query and match columns with entity fields by using "as" like this:
Here is the ViewModel class:
class ServiceCard(
val id: Int,
val customerInfo: String,
val time: String,
val oilFilter: Boolean,
val airFilter: Boolean,
val gasFilter: Boolean,
val oil: Boolean
)
and #Doa has a #Query method like this:
#Dao
interface ServiceCardDao :ICommonDao<ServiceCard>{
#Query("SELECT s.services_id as id, " +
"s.user_mobile_no as customerInfo, " +
"( " +
"SELECT count(*) " +
"FROM service_detail as sd " +
"WHERE sd.services_id = s.services_id and sd.service_type_id = 1 " +
") as oilFilter, " +
"( " +
"SELECT count(*) " +
"FROM service_detail as sd " +
"WHERE sd.services_id = s.services_id and sd.service_type_id = 2 " +
") as airFilter, " +
"( " +
"SELECT count(*) " +
"FROM service_detail as sd " +
"WHERE sd.services_id = s.services_id and sd.service_type_id = 3 " +
") as gasFilter, " +
"( " +
"SELECT count(*) " +
"FROM service_detail as sd " +
"WHERE sd.services_id = s.services_id and sd.service_type_id = 4 " +
") as oil, " +
"s.service_date as time " +
"FROM services as s ")
fun selectAllServicesWithDetail(): LiveData<List<model.ServiceCard>>
}
Is there any advantage or disadvantage between these 2 ?

Both have advantages over the other.
The coding in the Dao is more complex for one, the other is more complex to code in the Entity but the greater complexity in the Dao is greater than the complexity difference of the Entities. So the simpler Dao may well win favour with some.
One would be more efficient as there is no post data retrieval looping to obtain the counts and additionally that SQLite is compiled C code rather than JVM bytecode which has to be interpreted so SQlite is typically very efficient. However, efficiency may well well be what some are willing to forsake for the sake of simpler coding and perhaps for what one is used to.
Some would perhaps consider alternatives such as DatabaseViews which combines Dao and Class as one.

Related

Kotlin Android studio : SQlite auto increment isn't working

I have a issue where when I enter the first record into my data it goes into slot ID = 1. But if i enter another record it doesnt increment to id = 2 and tries to use ID = 1 even though i stated AUTOINCREMENT in the SQL code.
SQLite class
class SQLiteHelper(context: Context):SQLiteOpenHelper(context, DATABASE_NAME,null, DATABASE_VERSION){
companion object{
private const val DATABASE_VERSION = 1
private const val DATABASE_NAME = "anki.db"
private const val TBL_WORD = "tbl_word"
private const val ID = "id"
private const val DATE = "date"
private const val ENGLISHWORD = "englishWord"
private const val JAPANESEWORD = "jpnWord"
private const val TIME = "time"
private const val ANSWER = "answer"
}
override fun onCreate(db: SQLiteDatabase?) {
val createTblWord = ("CREATE TABLE "+ TBL_WORD + "("
+ ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"+ DATE + " TEXT,"+ ENGLISHWORD + " TEXT,"
+ JAPANESEWORD + " TEXT,"+ TIME + " INTEGER,"+ ANSWER + " INTEGER"+")")
db?.execSQL(createTblWord)
}
override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
db!!.execSQL("DROP TABLE IF EXISTS $TBL_WORD")
onCreate(db)
}
fun insertWord(word: WordModel): Long{
val db = this.writableDatabase
val contentValues = ContentValues()
contentValues.put(ID,word.id)
contentValues.put(DATE,word.date)
contentValues.put(ENGLISHWORD,word.engword)
contentValues.put(JAPANESEWORD,word.jpword)
contentValues.put(TIME,word.time)
contentValues.put(ANSWER,word.answer)
val success = db.insert(TBL_WORD, null , contentValues)
db.close()
return success
}
Main class add word method
private fun addWord(){
val date = etDate.text.toString()
val jpword = etJpWord.text.toString()
val engword = etEngWord.text.toString()
if(date.isEmpty() || jpword.isEmpty() || engword.isEmpty()){//必要な情報が入力してない場合
Toast.makeText(this,"必要な情報を入力してください。",Toast.LENGTH_SHORT).show()
clearEditText()
}else{
val word = WordModel(date=date, jpword = jpword, engword = engword)
val status = sqliteHelper.insertWord(word)
//Check Insert success or not success
if(status > -2){
Toast.makeText(this,"単語を追加しました",Toast.LENGTH_SHORT).show()
}else{
Toast.makeText(this,"データが保存されてないようです。",Toast.LENGTH_SHORT).show()
}
}
}
Shouldnt ID auto increment ?? Tried debug and Id clearly doesnt auto increment and tries to use the same id
Can you please share your WordModel? What do you use for id when create a new word in your addWord() method:
val word = WordModel(date=date, jpword = jpword, engword = engword)
Perhaps you use default id value of your WordModel like here: data class WordModel(id: Long? = 1, ...). And if it's true you can change the default value of id here to be like data class WordModel(id: Long? = null, ...) and it should work to insert auto-generated id values for db rows.
In another case you can use base SQLite BaseColumns._ID for creating your table like
"CREATE TABLE $TBL_WORD (${BaseColumns._ID} INTEGER PRIMARY KEY AUTOINCREMENT, $ENGLISHWORD TEXT, $JAPANESEWORD TEXT, etc)"
and then just don't put id like a value at all in your SQLiteHelper::insertWord(word: WordModel) method. It will be automatically generated like an auto incremented value for any new row in db.
You can see example in docs.
//try to change key_id query like this
public void onCreate(SQLiteDatabase db) {
String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACTS + "("
+ KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
+ KEY_PH_NO + " TEXT" + ")";
db.execSQL(CREATE_CONTACTS_TABLE);
}

Making and using a foreign key for relation in SQLite Android

Suposse that i have an android studio App where i can add companies, and inside those companies i can also add employees. Now, i'm trying to get the employees list showing only the elements of the company I selected before (In an unique activity for showing employees).
I created two classes:
data class Company(val id:Int, val name:String, val telephone:String)
data class Employee (val id:Int, val name:String, val telephone:String, val idCompany:Int)
And in my SQLiteHelper I created the tables for each one, with a foreign key in Employees to make a relation
private val TABLE_COMPANY = "CompanyTable"
private val TABLE_EMPLOYEE = "EmployeeTable"
//Company table
private val COMPANY_ID = "_id"
private val COMPANY_NAME = "name"
private val COMPANY_TL = "telephone"
//Employee table
private val EMPLOYEE_ID = "id"
private val EMPLOYEE_NAME = "name"
private val EMPLOYEE_TL = "telephone"
private val EMPLOYEE_COMPANY_ID = "id"
}
override fun onCreate(db: SQLiteDatabase?) {
val CREATE_COMPANY_TABLE = ("CREATE TABLE " + TABLE_COMPANY + "("
+ COMPANY_ID + " INTEGER PRIMARY KEY,"
+ COMPANY_NAME + " TEXT,"
+ COMPANY_TL + " TEXT" + ")")
val CREATE_EMPLOYEE_TABLE = ("CREATE TABLE " + TABLE_EMPLOYEE + "("
+ EMPLOYEE_ID + " INTEGER PRIMARY KEY,"
+ EMPLOYEE_NAME + " TEXT,"
+ EMPLOYEE_TL + " INTEGER,"
+ EMPLOYEE_COMPANY_ID + " INTEGER,"
+ " FOREIGN KEY ("+ EMPLOYEE_COMPANY_ID+") REFERENCES "+TABLE_COMPANY+"("+ COMPANY_ID+"))")
db?.execSQL(CREATE_EMPLOYEE_TABLE)
db?.execSQL(CREATE_COMPANY_TABLE)
}
So, I made two activities with recyclerviews, one for the Companies and the other for the employees.
When i click a company, the employees activity opens and it shows a list of them.
But it shows all the employees i have, so i'm trying to figure out how to show only the ones that i saved with the same id of the Company that i clicked in the previous activity.
But i don't know how to proceed now
Here is the DAO function that shows the employees:
fun viewEmployee(): ArrayList<Employee> {
val empList: ArrayList<Employee> = ArrayList<Employee>()
// Query to select the records
val selectQuery = "SELECT L.$EMPLOYEE_NAME, L.$EMPLOYEE_TL, L.$EMPLOYEE_ID, L.$EMPLOYEE_COMPANY_ID, C.$COMPANY_ID" +
"FROM $TABLE_EMPLOYEE as L, $TABLE_COMPANY as C" +
"WHERE L.$EMPLOYEE_COMPANY_ID = C.$COMPANY_ID"
val db = this.readableDatabase
var cursor: Cursor? = null
try {
cursor = db.rawQuery(selectQuery, null)
} catch (e: SQLiteException) {
db.execSQL(selectQuery)
return ArrayList()
}
var id: Int
var name: String
var telephone: String
var idCompany: Int
if (cursor.moveToFirst()) {
do {
id = cursor.getInt(cursor.getColumnIndex(EMPLOYEE_ID))
name = cursor.getString(cursor.getColumnIndex(EMPLOYEE_NAME))
telephone = cursor.getString(cursor.getColumnIndex(EMPLOYEE_TL))
idCompany = cursor.getInt(cursor.getColumnIndex(EMPLOYEE_COMPANY_ID))
val employee = Employee(id = id, name = name, telephone = telephone, idCompany = idCompany)
empList.add(employee)
} while (cursor.moveToNext())
}
return empList
}
And here is the activity that shows the employees
class ManagerEmp : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_manager_emp)
setList()
createEmp.setOnClickListener{
val intent = Intent(this, CreateEmp::class.java)
startActivity(intent)
}
}
/**
* Gets DB employee list
*/
private fun getItemsList(): ArrayList<Employee> {
//creating the instance of DatabaseHandler class
val databaseHandler = DataBaseHelper(this)
//calling the viewEmployee method of DatabaseHandler class to read the records
val empList: ArrayList<Employee> = databaseHandler.viewEmployee()
return empList
}
/**
* Generates the list
*/
private fun setList() {
recyclerEmp.layoutManager = LinearLayoutManager(this)
val itemAdapter = empAdapter(this, getItemsList())
recyclerEmp.adapter = itemAdapter
}
}
It sounds simple but it isn't (At least for me)
I thought of getting the id value of the company and pass it to the employee list activity, so i can use to compare it, but idk how, i'm pretty new in kotlin (And programming in general)
If you can give an answer, you would be saving my life.
H E L P
First you have to obtain companyId you want to filter by. It can be done for example by adding onClickListener in RecyclerView.
Then you will need additional query which will be used for filtering by companyId.
For example if companyId is stored in filteredCompanyId variable you can add additional filter condition (WHERE ... AND C.$COMPANY_ID == $filteredCompanyId):
val filteredCompanyId = 5
val query = """
SELECT L.$EMPLOYEE_NAME,
L.$EMPLOYEE_TL,
L.$EMPLOYEE_ID,
L.$EMPLOYEE_COMPANY_ID,
C.$COMPANY_ID
FROM $TABLE_EMPLOYEE AS L,
$TABLE_COMPANY AS C
WHERE L.$EMPLOYEE_COMPANY_ID = C.$COMPANY_ID
AND C.$COMPANY_ID == $filteredCompanyId
"""

Create Temp Table and execute queries on it with Android Room

I'm using android room for my database: I'm looking for a way to execute a sequence of actions as in the subsequent code:
#Query( "CREATE TEMP TABLE IF NOT EXISTS t1 (idx INTEGER, rnd_pos INTEGER)")
fun shuffle_subquery1()
#Query("DELETE FROM t1;")
fun shuffle_subquery2()
#Query("INSERT INTO t1 SELECT song_id, RANDOM() FROM song_table WHERE playlist_id=:playlistID")
fun shuffle_subquery3(playlist_id: Int)
#Query("WITH " +
"i_rnd(idx, rnd_pos) as (SELECT r1.idx, (SELECT COUNT(*) FROM t1 as r2 WHERE r2.rnd_pos<r1.rnd_pos OR " +
" (r2.rnd_pos=r1.rnd_pos and r2.idx<r1.idx)) as rnd_pos FROM t1 as r1) " +
"UPDATE song_table SET rnd_pos=(SELECT rnd_pos FROM i_rnd WHERE song_table.song_id=i_rnd.idx) WHERE playlist_id=:playlistID"
)
fun shuffle_subquery4(playlist_id: Int)
#Transaction
fun shuffle(playlist_id: Int) {
shuffle_subquery1()
shuffle_subquery2()
shuffle_subquery3(playlist_id)
shuffle_subquery4(playlist_id)
}
This gives error error: UNKNOWN query type is not supported yet. You can use:DELETE, INSERT, SELECT, UPDATE
public abstract void shuffle_subquery1()
and
There is a problem with the query: [SQLITE_ERROR] SQL error or missing database (no such table: t1)
public abstract void shuffle_subquery2()
#Transaction
#Query(
"CREATE TEMP TABLE IF NOT EXISTS t1 (idx INTEGER, rnd_pos INTEGER);\n" +
"DELETE FROM t1;\n" +
"\n" +
"INSERT INTO t1 SELECT song_id, RANDOM() FROM song_table WHERE playlist_id=:playlistID;\n" +
"\n" +
"WITH\n" +
"i_rnd(idx, rnd_pos) as (SELECT r1.idx, (SELECT COUNT(*) FROM t1 as r2 WHERE r2.rnd_pos<r1.rnd_pos OR \n" +
" (r2.rnd_pos=r1.rnd_pos and r2.idx<r1.idx)) as rnd_pos FROM t1 as r1)\n" +
"UPDATE song_table SET rnd_pos=(SELECT rnd_pos FROM i_rnd WHERE song_table.song_id=i_rnd.idx) WHERE playlist_id=:playlistID;"
)
fun shuffle(playlist_id: Int)
This version gives error: error: Must have exactly 1 query in the value of #Query or #DatabaseView
public abstract void shuffle(int playlist_id);
Which is the best (and working) way of doing that using Android Room?

SQLLite update doesn't update the table at all (Android Studio with Kotlin)

I'm fairly new to Android, Kotlin, and SQLLite.
I have this table creation.
val create = "CREATE TABLE IF NOT EXISTS $TABLE_NAME (" +
"$COLUMN_ID INTEGER PRIMARY KEY AUTOINCREMENT, " +
"$COLUMN_USERNAME STRING, $COLUMN_PASSWORD STRING, $COLUMN_EMAIL STRING, $COLUMN_LAST_LOGIN DATETIME NULL, " +
"$COLUMN_PRIV_ACCESS_ADMIN_LIST BOOLEAN, $COLUMN_PRIV_CHANGE_ADMIN_LIST BOOLEAN, $COLUMN_PRIV_SEND_EMAIL_REPORT BOOLEAN, " +
"$COLUMN_IS_ACTIVE BOOLEAN" +
")"
db.execSQL(create)
I can successfully add new data with this:
val values = ContentValues()
values.put(COLUMN_USERNAME, "admin")
values.put(COLUMN_PASSWORD, "password")
values.put(COLUMN_EMAIL, "test#test.com")
values.put(COLUMN_PRIV_ACCESS_ADMIN_LIST, true)
values.put(COLUMN_PRIV_CHANGE_ADMIN_LIST, true)
values.put(COLUMN_PRIV_SEND_EMAIL_REPORT, true)
values.put(COLUMN_IS_ACTIVE, admin.isActive)
val db = this.writableDatabase
db.insert(TABLE_NAME, null, values)
I also can successfully retrieve data with this:
val db = this.readableDatabase
val cursor = db.rawQuery("SELECT * FROM $TABLE_NAME", null)
by which I get the info that the data I put there has the ID = 1
But I cannot change the data into something else, either with this code:
val values = ContentValues()
values.put(COLUMN_USERNAME, "adminssss")
values.put(COLUMN_PASSWORD, "passwordsss")
values.put(COLUMN_EMAIL, "test#test.org")
values.put(COLUMN_PRIV_ACCESS_ADMIN_LIST, false)
values.put(COLUMN_PRIV_CHANGE_ADMIN_LIST, true)
values.put(COLUMN_PRIV_SEND_EMAIL_REPORT, false)
values.put(COLUMN_IS_ACTIVE, true)
val db = this.writableDatabase
db.update(TABLE_NAME, values, "$COLUMN_ID=1", arrayOf())
// or
db.update(TABLE_NAME, values, "$COLUMN_ID=?", arrayOf("1"))
Or
val db = this.writableDatabase
val query = "UPDATE $TABLE_NAME " +
"SET $COLUMN_USERNAME = 'adminssss', $COLUMN_PASSWORD = 'passwordsss', $COLUMN_EMAIL = 'test#test.org', " +
"$COLUMN_PRIV_ACCESS_ADMIN_LIST = 0, " +
"$COLUMN_PRIV_CHANGE_ADMIN_LIST = 1, " +
"$COLUMN_PRIV_SEND_EMAIL_REPORT = 0, " +
"$COLUMN_IS_ACTIVE = 1 " +
"WHERE $COLUMN_ID = 1"
db.rawQuery(query, null)
// or
db.execQuery(query)
I'm not too strong with query language, but I've tried to double check the query and can't found anything wrong with it. When the update query is run, which ever version it is from above example, all can run without error, but when I re-select the data again, nothing is changed. The data stays the same like the original first time I put them in.
Can somebody help?
There is nothing wrong with your first update code (both work), it works (see Working example below).
I suspect that you issue might be that you have deleted a row and the added another row. In such a case, because you have AUTOINCREMENT coded such a row would not have an ID as 1 but perhaps two.
You could check the underlying rows by using the logAll function (as used in the Working Example below).
If using the code from the working example then the issues in attempting to use rawQuery and execQuery become moot.
I believe that your issue is how you are viewing the result (or is as previously explained). Consider the following working example :-
Working Example
The Database Helper class, DBHelper.kt (based upon the available code) including the code, such as update as functions :-
class DBHelper(context: Context) : SQLiteOpenHelper(context, DBNAME, null, DBVERSION) {
val all: Cursor
get() = this.writableDatabase.query(TABLE_NAME, null, null, null, null, null, null)
override fun onCreate(db: SQLiteDatabase) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + "(" +
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COLUMN_USERNAME + " STRING, " +
COLUMN_PASSWORD + " STRING, " +
COLUMN_EMAIL + " STRING, " +
COLUMN_LAST_LOGIN + " DATETIME DEFAULT NULL, " +
COLUMN_PRIV_ACCESS_ADMIN_LIST + " BOOLEAN, " +
COLUMN_PRIV_CHANGE_ADMIN_LIST + " BOOLEAN," +
COLUMN_PRIV_SEND_EMAIL_REPORT + " BOOLEAN, " +
COLUMN_IS_ACTIVE + " BOOLEAN" +
")"
)
}
fun add(
username: String,
password: String,
email: String,
privaccessadminlist: Boolean,
privchangeadminlist: Boolean,
privsendemailreport: Boolean,
is_active: Boolean): Long {
val cv = ContentValues()
cv.put(COLUMN_USERNAME, username)
cv.put(COLUMN_PASSWORD, password)
cv.put(COLUMN_EMAIL, email)
cv.put(COLUMN_PRIV_ACCESS_ADMIN_LIST, privaccessadminlist)
cv.put(COLUMN_PRIV_CHANGE_ADMIN_LIST, privchangeadminlist)
cv.put(COLUMN_PRIV_SEND_EMAIL_REPORT, privsendemailreport)
return this.writableDatabase.insert(TABLE_NAME, null, cv)
}
fun logAll() {
val csr = all
var sb = StringBuilder()
while (csr.moveToNext()) {
sb = StringBuilder().append("Row is " + csr.position.toString())
sb.append("\n\tUserName is :").append(csr.getString(csr.getColumnIndex(COLUMN_USERNAME)))
sb.append("\n\tPasword is :").append(csr.getString(csr.getColumnIndex(COLUMN_PASSWORD)))
sb.append("\n\tEmail is :").append(csr.getString(csr.getColumnIndex(COLUMN_EMAIL)))
sb.append("\n\t PRIVACCESSAL is ").append((csr.getInt(csr.getColumnIndex(COLUMN_PRIV_ACCESS_ADMIN_LIST)) > 0).toString())
sb.append("\n\t PRIVCHGAL is ").append((csr.getInt(csr.getColumnIndex(COLUMN_PRIV_CHANGE_ADMIN_LIST)) > 0).toString())
sb.append("\n\t PRIVSNDEMAIL is ").append((csr.getInt(csr.getColumnIndex(COLUMN_PRIV_SEND_EMAIL_REPORT)) > 0).toString())
Log.d("LOGDATA", sb.toString())
}
}
// Suggested update code
fun updateById(id: Long,
username: String,
password: String,
email: String,
privaccessadminlist: Boolean,
privchangeadminlist: Boolean,
privsendemailreport: Boolean,
is_active: Boolean): Int {
val cv = ContentValues()
cv.put(COLUMN_USERNAME, username)
cv.put(COLUMN_PASSWORD, password)
cv.put(COLUMN_EMAIL, email)
cv.put(COLUMN_PRIV_ACCESS_ADMIN_LIST, privaccessadminlist)
cv.put(COLUMN_PRIV_CHANGE_ADMIN_LIST, privchangeadminlist)
cv.put(COLUMN_PRIV_SEND_EMAIL_REPORT, privsendemailreport)
val whereclause = "$COLUMN_ID=?"
val whereargs = arrayOf(id.toString())
return this.writableDatabase.update(TABLE_NAME, cv, whereclause, whereargs)
}
//Your code
fun update() {
val values = ContentValues()
values.put(COLUMN_USERNAME, "adminszzz")
values.put(COLUMN_PASSWORD, "passwordzzz")
values.put(COLUMN_EMAIL, "test#test.orgzzz")
values.put(COLUMN_PRIV_ACCESS_ADMIN_LIST, false)
values.put(COLUMN_PRIV_CHANGE_ADMIN_LIST, true)
values.put(COLUMN_PRIV_SEND_EMAIL_REPORT, false)
values.put(COLUMN_IS_ACTIVE, true)
val db = this.writableDatabase
db.update(TABLE_NAME, values, "$COLUMN_ID=1", arrayOf())
// or
//db.update(TABLE_NAME, values, "$COLUMN_ID=?", arrayOf("1"))
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
}
companion object {
val DBNAME = "mydb"
val DBVERSION = 1
val TABLE_NAME = "mytable"
val COLUMN_ID = BaseColumns._ID
val COLUMN_USERNAME = "username"
val COLUMN_PASSWORD = "password"
val COLUMN_EMAIL = "email"
val COLUMN_LAST_LOGIN = "last_login"
val COLUMN_PRIV_ACCESS_ADMIN_LIST = "priv_access_admin_list"
val COLUMN_PRIV_CHANGE_ADMIN_LIST = "priv_change_admin_list"
val COLUMN_PRIV_SEND_EMAIL_REPORT = "priv_send_email_report"
val COLUMN_IS_ACTIVE = "is_active"
}
}
And an Activity to invoke the functions MainAvctivity.kt :-
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var dbhlpr = DBHelper(this)
dbhlpr = DBHelper(this)
dbhlpr.add("admin", "password", "test#test.com", true, true, true, true)
dbhlpr.logAll()
dbhlpr.updateById(1, "adminssss", "passwordsss", "test#test.org", false, true, false, true)
dbhlpr.logAll()
dbhlpr.update();
dbhlpr.logAll();
}
}
Result
When run the following is output to the log :-
2019-05-17 16:12:07.182 18164-18164/aso.so56179532update D/LOGDATA: Row is 0
UserName is :admin
Pasword is :password
Email is :test#test.com
PRIVACCESSAL is true
PRIVCHGAL is true
PRIVSNDEMAIL is true
2019-05-17 16:12:07.184 18164-18164/aso.so56179532update D/LOGDATA: Row is 0
UserName is :adminssss
Pasword is :passwordsss
Email is :test#test.org
PRIVACCESSAL is false
PRIVCHGAL is true
PRIVSNDEMAIL is false
2019-05-17 16:12:07.186 18164-18164/aso.so56179532update D/LOGDATA: Row is 0
UserName is :adminszzz
Pasword is :passwordzzz
Email is :test#test.orgzzz
PRIVACCESSAL is false
PRIVCHGAL is true
PRIVSNDEMAIL is false
i.e. There are 3 lots, each showing the single row from the database. The second two show that the data has been updated accordingly.
It seems you haven't closed the database by calling db.close() method after updating operation.
Closing the connection flushes the changes you've made, otherwise, the engine waits for the flush period before doing it. It's a good idea to close the connection when you're done using it to ensure that your changes actually go to the store. A power loss after a write and before a flush will lose data.

Failed to parse the row anko kotlin

i dont know why this code can't parse the row. please help.
private var dataCards :MutableList<DataCard> = mutableListOf()
btn_read.setOnClickListener {
showAllCardData()
var data = dataCards
tvResult.text = ""
for (i in 0..(data.size - 1)) {
tvResult.append(data.get(i).id.toString() + " " +
data.get(i).title + " " +
data.get(i).instruction + " " +
data.get(i).level + " " +
data.get(i).rewardPoint + " " +
data.get(i).rewardExp + " " +
data.get(i).inputdate + "\n")
}
}
private fun showAllCardData(){
missionDB.use {
val result = select(DataCard.TABLE_USERCARD)
val cards = result.parseList(classParser<DataCard>())
dataCards.addAll(cards)
}
}
Any reference or suggestion ?, the error is "failed to parse the row" please help.
row you get from showAllCardData function not match with DataCard,
example row you get from database (field1,field2)
but your Datacard constructor parameter (field1,field2,field3,field4)

Categories

Resources