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?
Related
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);
}
I'm in kotlin and try to create some app. I created SQLite database for android app. In DB i have "login" and "password". How I can read it for login?
My Database.kt
fun insertIntoPartner(plogin: String?, ppassword: String?): Boolean {
var contentValues = ContentValues()
contentValues.put("plogin", plogin)
contentValues.put("ppassword", ppassword)
val rowId = writableDatabase.insert(PARTNER, null, contentValues)
return rowId>0
}
My login code:
bin.setOnClickListener {
if (login.text.toString() == // here i read database login
&& password.text.toString() == here i read database password) {
val i = Intent(this, NavigationMenu::class.java)
startActivity(i)
} else toast("No login or password")
Thank for all suggestions.
UPD 1:
fun checkUser(plogin: String?, ppassword: String?): Boolean {
val columns = arrayOf(pid)
val db = this.readableDatabase
val selection = "$plogin = ? AND $ppassword = ?"
val selectionArgs = arrayOf(plogin, ppassword)
val cursor = db.query(PARTNER, columns, selection, selectionArgs,
null, null, null)
val cursorCount = cursor.count
cursor.close()
db.close()
if (cursorCount > 0) return true
else return false
}
How I understood I must replace "USER_ID", "TABLE_NAME" and etc. to my fields. But what if I have for id "pid (INTEGER PRIMARY KEY)"? When I wrote "pid" it's red and tell "unresolved reference". What is my mistake?
My CREATE_TABLE looks like:
companion object {
val PARTNER = "partner"
val DB_VERSION = 1
val CREATE_TABLE_PARTNER = "CREATE TABLE partner(pid INTEGER PRIMARY KEY, plogin TEXT, ppassword TEXT," +
" pname TEXT, psale TEXT, pasale TEXT, pengsale TEXT, prusdescription TEXT, pengdescription TEXT," +
" pinn TEXT, pemail TEXT, pphonenumber TEXT, psitecompany TEXT, pstreet TEXT, pcity TEXT," +
" pregion TEXT, pcountry TEXT, pindex TEXT)"
val SELECT_PARTNER = "SELECT * from partner"
}
In your MyDatabase.kt class :
/**
* This method to check user exist or not
*
* #param email
* #param password
* #return true/false
*/
fun checkUser(email: String, password: String): Boolean {
// array of columns to fetch
val columns = arrayOf(COLUMN_USER_ID)
val db = this.readableDatabase
// selection criteria
val selection = "$COLUMN_USER_EMAIL = ? AND $COLUMN_USER_PASSWORD = ?"
// selection arguments
val selectionArgs = arrayOf(email, password)
// query user table with conditions
/**
* Here query function is used to fetch records from user table this function works like we use sql query.
* SQL query equivalent to this query function is
* SELECT user_id FROM user WHERE user_email = 'viral#exmaple.com' AND user_password = 'qwerty';
*/
val cursor = db.query(TABLE_USER, //Table to query
columns, //columns to return
selection, //columns for the WHERE clause
selectionArgs, //The values for the WHERE clause
null, //group the rows
null, //filter by row groups
null) //The sort order
val cursorCount = cursor.count
cursor.close()
db.close()
if (cursorCount > 0)
return true
return false
}
Then MyLogin.kt class :
private fun verifyFromSQLite() {
// Make changes as per your requirement
if (MyDatabase!!.checkUser(textInputEditTextEmail!!.text.toString().trim { it <= ' ' }, textInputEditTextPassword!!.text.toString().trim { it <= ' ' })) {
val accountsIntent = Intent(activity, UserActivity::class.java)
emptyInputEditText()
startActivity(accountsIntent)
} else {
// Snack Bar to show success message that record is wrong
Snackbar.make(nestedScrollView!!, getString(R.string.error_email_password), Snackbar.LENGTH_LONG).show()
}
}
Edited: see the create table look like:
// create table sql query
private val CREATE_USER_TABLE = ("CREATE TABLE " + TABLE_USER + "("
+ COLUMN_USER_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + COLUMN_USER_NAME + " TEXT,"
+ COLUMN_USER_EMAIL + " TEXT," + COLUMN_USER_PASSWORD + " TEXT" + ")")
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.
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.
I hope to define a not null field for a table of SQLite when I use Anko in Kotlin.
But DBRecordTable.Category to TEXT NOT NULL is wrong ,how can I fix it?
Code
implementation "org.jetbrains.anko:anko-sqlite:$anko_version"
override fun onCreate(db: SQLiteDatabase) {
db.createTable( DBRecordTable.TableNAME , true,
DBRecordTable._ID to INTEGER + PRIMARY_KEY+ AUTOINCREMENT,
DBRecordTable.Category to TEXT NOT NULL, //It's wrong
DBRecordTable.Content to TEXT,
DBRecordTable.IsFavorite to INTEGER +DEFAULT("0"),
DBRecordTable.IsProtected to INTEGER +DEFAULT("0"),
DBRecordTable.CreatedDate to INTEGER
)
}
By taking a look at sqlTypes.kt we can find that the not null constraint is defined as following:
val NOT_NULL: SqlTypeModifier = SqlTypeModifierImpl("NOT NULL")
So your code should be:
override fun onCreate(db: SQLiteDatabase) {
db.createTable( DBRecordTable.TableNAME , true,
DBRecordTable._ID to INTEGER + PRIMARY_KEY + AUTOINCREMENT,
DBRecordTable.Category to TEXT + NOT_NULL,
DBRecordTable.Content to TEXT,
DBRecordTable.IsFavorite to INTEGER + DEFAULT("0"),
DBRecordTable.IsProtected to INTEGER + DEFAULT("0"),
DBRecordTable.CreatedDate to INTEGER
)
}
We used these lines of code and it works great table created
private val dbName = THE_PATH +"JSANotes.db"
private val dbTable = "Notes"
private val colId = "Id"
private val colTitle = "Title"
private val colContent = "Content"
private val dbVersion = 1
private val CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS " + dbTable + " (" + colId + " INTEGER PRIMARY KEY," + colTitle + " TEXT, " + colContent + " TEXT NOT NULL);"
private var db: SQLiteDatabase? = null
init {
val dbHelper = DatabaseHelper(context)
db = dbHelper.writableDatabase
}
This site will help with a lot of SQLite questions LINK
We do not use the NOT NULL we do this in place of NOT NULL
if(edtContent.text.toString().equals("")){
error("ENTER Content")
edtContent.requestFocus()
return#setOnClickListener
}
You can also test for length the error message shows in a Text View at the bottom of the Activity with this code
fun error(msg:String){
object : CountDownTimer(4000, 1000) {
override fun onTick(millisUntilFinished: Long) {
tvError.visibility = View.VISIBLE
tvError.setText(msg)
}
override fun onFinish() {
tvError.visibility = View.INVISIBLE
tvError.setText("")
}
}.start()
}