how to check if sqlite database is empty (android)? - android

I am making a media player which loads metadata of songs into a database.
Below is my function for checking whether the db is empty or not but it isn't working. Please tell me what's wrong with my code and suggest a correction or a better alternative.
private static boolean isDbEmpty(SQLiteDatabase songsDb) {
try {
Cursor c = songsDb.rawQuery("SELECT * FROM " + SongsTable.TABLE_NAME, null);
if (c.moveToFirst()) { // c.getCount() == 0 is also not working
Log.d(TAG, "isDbEmpty: not empty");
return false;
}
c.close();
} catch (SQLiteException e) {
Log.d(TAG, "isDbEmpty: doesn't exist");
return true;
}
return true;
}

Use the following query to achieve your goal. There are two tables created automatically - android_metadata and sqlite_sequence, so we apply a NOT condition in the query.
SELECT count(*) FROM sqlite_master WHERE type = 'table' AND name != 'android_metadata' AND name != 'sqlite_sequence';

Try this.
private static boolean isDbEmpty(SQLiteDatabase songsDb) {
Cursor c = null;
try {
c = songsDb.rawQuery("SELECT * FROM " + SongsTable.TABLE_NAME, null);
if (c == null || c.getCount() == 0) {
return true;
} else if (c.moveToFirst()) {
Log.d(TAG, "isDbEmpty: not empty");
return false;
}
} catch (SQLiteException e) {
Log.d(TAG, "isDbEmpty: doesn't exist");
return true;
}finally {
if(c != null){
c.close();
}
}
return true;
}

This will only tell you if the TABLE is empty, not the DATABASE.
Regardless, you could use code like:
Cursor countCursor = songsDb.rawQuery("select count(*) from " + SongsTable.TABLE_NAME, null);
countCursor.moveToFirst();
int count = countCursor.getInt(0);
countCursor.close();
And then test count.

You can check like this :
Cursor c = songsDb.rawQuery("SELECT * FROM " + SongsTable.TABLE_NAME, null);
cursor.moveToFirst();
if (cursor != null && cursor.getCount() == 0) {
//for empty
return true;
}else{
// not empty
return false;
}

Related

Android cursor.getColumnNames() doesn't contain the new added column

I use code below to test if a column exists:
public static boolean isColumnExists(String tableName, String columnName) {
Cursor cursor = null;
try {
SQLiteDatabase db = getDatabase();
cursor = db.rawQuery("SELECT * FROM " + tableName + " LIMIT 0", null);
String[] cloNames = cursor.getColumnNames();
if (cloNames != null) {
for (String temp : cloNames) {
if (columnName.equalsIgnoreCase(temp)) {
return true;
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != cursor && !cursor.isClosed()) {
cursor.close();
}
}
return false;
}
The column hello2 doesn't exist in initial state, after adding column to database, the following test still tells that the column doesn't exist, and the second try will cause an error about duplicate column, which is not correct.
if (!isColumnExists("PositionCache", "hello2")) {
// First try will insert column to database
getDatabase().execSQL("alter table PositionCache add hello2 Integer default 0");
}
if (!isColumnExists("PositionCache", "hello2")) {
// Second try will give and error about duplicate column of hello2
getDatabase().execSQL("alter table PositionCache add hello2 Integer default 0");
}
I need to know the reason about such an abnormal phenomenon.
If I change SELECT * FROM to select * from in method isColumnExists then everything become normal.
I believe the reason is that SQLite (I strongly suspect the Cursor, so more correctly the Android SQLite aspect of the SDK) is cacheing data (perhaps because the underlying data is never retrieved from the Database as there is no need to get the data (as far as the Cursor is concerned)).
I've tried various checks including putting breakpoints in, checking the result of getColumnnames, and making the method non-static.
As soon as I add an alternative check using the PRAGMA table_info(*table_name*); then the column exists.
As such I'd suggest using the following :-
public static boolean isColumnExistsOld(String tableName, String columnName) {
Cursor csr = getDatabase().rawQuery("PRAGMA table_info(" + tableName + ")",null);
while(csr.moveToNext()) {
if (csr.getString(csr.getColumnIndex("name")).equalsIgnoreCase(columnName)) {
return true;
}
}
return false;
/*
Cursor cursor = null;
try {
SQLiteDatabase db = getDatabase();
cursor = db.rawQuery("SELECT * FROM " + tableName + " LIMIT 1", null);
cursor.moveToFirst();
String[] cloNames = cursor.getColumnNames();
if (cloNames != null) {
for (String temp : cloNames) {
if (columnName.equalsIgnoreCase(temp)) {
return true;
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != cursor && !cursor.isClosed()) {
cursor.close();
}
}
boolean rv = colfound;
return false;
*/
}
Note your code has been left in but commented out.
I believe that evaluating forces the cache to be refreshed (i.e. I tried this an yep it does dynamically change to include the column).

Android - How to check if item exists in database?

I want to add a new item (spot) in my database, but before doing this, I want to check if this item already exists.
Here is my code :
for (Spot spot : spotsList)
{
if (dbHelper.getSpotWithDistantId(spot.getDistantId()) == null)
{
dbHelper.addSpot(spot);
}
}
And here is my getSpotWithDistantId method :
public Spot getSpotWithDistantId(int distantId)
{
Cursor cursor =
db.query(TABLE_SPOTS,
SPOTS_COLUMNS,
" " + KEY_DISTANTID + " = ?",
new String[]{String.valueOf(distantId)}, // Selections args
null, // Group by
null, // Having
null, // Order by
null); // Limit
if (cursor != null)
{
cursor.moveToFirst();
}
Spot spot = buildSpotWithCursor(cursor);
if (cursor != null)
{
cursor.close();
}
db.close();
return spot;
}
The problem is when I want to check if a spot exists, the following error appears:
android.database.CursorIndexOutOfBoundsException: Index 0 requested,
with a size of 0
What's wrong with my code ?
Thanks in advance.
You need to check if your cursor contains any records. You can do it like this
if(cursor != null && cursor.getCount() > 0)
{
...
}
else
{
cursor.close();
return false;
}
I have the similar problem and I use this simple function:
public boolean exists_the_ColumnParameter(String query){
//Declaration of variables
Cursor a2 = null;
try{
OpenDB();
a2 = database.rawQuery(query,null);
if(a2 != null) {
a2.moveToFirst();
if (a2.getString(0).equals("")) {
a2.close();
database.close();
return false;
} else {
a2.close();
database.close();
return true;
}
}else{
a2.close();
database.close();
return false;
}
}
catch (CursorIndexOutOfBoundsException ex){
return false;
}
catch (NullPointerException ex){
return false;
}
catch (Exception ex){
Log.e("-- BDD.exists_the_ColumnParameter --","Exception",ex);
return false;
}
}
The reason which I can't pass a single ID because it isn't a generic function, the big difference is which with the ID you can only view one SQLite table and with the query you can view multiple ID's from diferent tables.
Tell me if I can helps you, good programming!!

Running a raw sqlite query

I am trying to run this query but it just isn't working and i can't seem to find what is wrong with it.
public boolean verifyUser(String name , String pword){
boolean result = false;
SQLiteDatabase db = this.getReadableDatabase();
try {
Cursor res = db.rawQuery( "select * from user where username="+name+" and password="+pword+"", null );
int count = res.getCount();
res.moveToFirst();
if (count == 0)
{
result = false;
}
else{
result = true;
}
}
catch (SQLiteException se ) {
Log.e(getClass().getSimpleName(), "Could not log in");
}
return result;
//return true;
}
In SQL, you need to put your string literals in 'single quotes'. Better yet, use parameters:
Cursor res = db.rawQuery( "select * from user where username=? and password=?",
new String[] { name, pword } );
Checked this, it's edited of your code.
public boolean verifyUser(String name , String pword){
boolean result = false;
SQLiteDatabase db = this.getReadableDatabase();
try {
Cursor res = db.rawQuery( "select * from user where username='"+name+"' and password='"+pword+"'", null );
int count = res.getCount();
//res.moveToFirst(); //Remove this line (It may be crashing because of this line.)
if (count == 0)
{
result = false;
}
else{
res.moveToFirst();
result = true;
}
}
catch (SQLiteException se ) {
Log.e(getClass().getSimpleName(), "Could not log in");
}
return result;
//return true;
}
Copy and paste the following query
select * from user where username='"+name+"' and password='"+pword+"'"
actually you are missing the Single Quotes

retrieving record from database using cursor in android

I have used following codes to retrieve record:
String getCredentialsFromAdmint(String name ,String pwd) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_ADMIN, new String[] { KEY_ID,
KEY_A_USER_NAME, KEY_A_PWD }, KEY_A_USER_NAME + "=?" + " AND " + KEY_A_PWD + "=?",
new String[] { name , pwd }, null, null, null, null);
if (cursor != null){
cursor.moveToFirst();
return cursor.getString(1);
}
else{
return "norecord";
}
This code works if there is a record but if no record is found then application gets an error.
Is there any other ways to retrieve data from database?
Change your code to following
if ( cursor.moveToFirst()){
return cursor.getString(1);
} else{
return "norecord";
}
You don't check if cursor.moveToFirst() returns true;
It should looks like this:
if (cursor != null) {
if(cursor.moveToFirst()){
return cursor.getString(cursor.getColumnIndexOrThrow(KEY_A_USER_NAME));
} else{
//no record
}
} else {
//invalid uri
}
Try to use the following code instead
if (cursor != null){
cursor.moveToFirst();
if(cursor.isAfterLast() == false) {
return cursor.getString(1);
}
else
{
return "norecord";
}
}
else{
return "norecord";
}

Checking if a column exists in an application database in Android

Is there a nice way in Android to see if a column exists in a table in the application database? (I know there are questions similar to this one already, but there don't seem to be any that are Android specific.)
cursor.getColumnIndex(String columnName) returns -1 if, the column doesn't exist. So I would basically perform a simple query like "SELECT * FROM xxx LIMIT 0,1" and use the cursor to determine if the column, you are looking for, exists
OR
you can try to query the column "SELECT theCol FROM xxx" and catch an exception
My function based on #martinpelants answer:
private boolean existsColumnInTable(SQLiteDatabase inDatabase, String inTable, String columnToCheck) {
Cursor mCursor = null;
try {
// Query 1 row
mCursor = inDatabase.rawQuery("SELECT * FROM " + inTable + " LIMIT 0", null);
// getColumnIndex() gives us the index (0 to ...) of the column - otherwise we get a -1
if (mCursor.getColumnIndex(columnToCheck) != -1)
return true;
else
return false;
} catch (Exception Exp) {
// Something went wrong. Missing the database? The table?
Log.d("... - existsColumnInTable", "When checking whether a column exists in the table, an error occurred: " + Exp.getMessage());
return false;
} finally {
if (mCursor != null) mCursor.close();
}
}
Simply call:
boolean bla = existsColumnInTable(myDB,"MyTable","myColumn2check");
I actually wrote this function that seems pretty clean:
private boolean field_exists( String p_query )
{
Cursor mCursor = mDb.rawQuery( p_query, null );
if ( ( mCursor != null ) && ( mCursor.moveToFirst()) )
{
mCursor.close();
return true ;
}
mCursor.close();
return false ;
}
I call it like this:
if ( field_exists( "select * from sqlite_master "
+ "where name = 'mytable' and sql like '%myfield%' " ))
{
do_something ;
}
Here is my solution to the issue which adds to flexo's solution a little.
You can put this method in any class, perhaps your SQLiteOpenHelper extending class.
public static boolean columnExistsInTable(SQLiteDatabase db, String table, String columnToCheck) {
Cursor cursor = null;
try {
//query a row. don't acquire db lock
cursor = db.rawQuery("SELECT * FROM " + table + " LIMIT 0", null);
// getColumnIndex() will return the index of the column
//in the table if it exists, otherwise it will return -1
if (cursor.getColumnIndex(columnToCheck) != -1) {
//great, the column exists
return true;
}else {
//sorry, the column does not exist
return false;
}
} catch (SQLiteException Exp) {
//Something went wrong with SQLite.
//If the table exists and your query was good,
//the problem is likely that the column doesn't exist in the table.
return false;
} finally {
//close the db if you no longer need it
if (db != null) db.close();
//close the cursor
if (cursor != null) cursor.close();
}
}
If you use ActiveAndroid
public static boolean createIfNeedColumn(Class<? extends Model> type, String column) {
boolean isFound = false;
TableInfo tableInfo = new TableInfo(type);
Collection<Field> columns = tableInfo.getFields();
for (Field f : columns) {
if (column.equals(f.getName())) {
isFound = true;
break;
}
}
if (!isFound) {
ActiveAndroid.execSQL("ALTER TABLE " + tableInfo.getTableName() + " ADD COLUMN " + column + " TEXT;");
}
return isFound;
}
At the risk of just posting the same solution but shorter. Here's a cut down version based on #flexo's
private boolean doesColumnExistInTable(SupportSQLiteDatabase db, String tableName, String columnToCheck) {
try (Cursor cursor = db.query("SELECT * FROM " + tableName + " LIMIT 0", null)) {
return cursor.getColumnIndex(columnToCheck) != -1;
} catch (Exception Exp) {
// Something went wrong. we'll assume false it doesn't exist
return false;
}
}
And in Kotlin
private fun doesColumnExistInTable(db: SupportSQLiteDatabase, tableName: String, columnToCheck: String): Boolean {
try {
db.query("SELECT * FROM $tableName LIMIT 0", null).use { cursor -> return cursor.getColumnIndex(columnToCheck) != -1 }
} catch (e: Exception) {
// Something went wrong. we'll assume false it doesn't exist
return false
}
}
this is my testing code:
String neadle = "id"; //searched field name
String tableName = "TableName";
boolean found = false;
SQLiteDatabase mDb = ActiveAndroid.getDatabase();
Cursor mCursor = mDb.rawQuery( "SELECT * FROM sqlite_master WHERE name = '"+tableName+"' and sql like '%"+neadle+"%'" , null);
mCursor.moveToFirst();
String fie = ",";
if (mCursor.getCount() > 0) {
String[] fields = mCursor.getString(mCursor.getColumnIndex("sql")).split(",");
for (String field: fields) {
String[] fieldNameType = field.trim().split(" ");
if (fieldNameType.length > 0){
fie += fieldNameType[0]+",";
}
}
}else {
//table not exist!
}
if (mCursor != null) mCursor.close();
// return result:
found = fie.contains(","+neadle+",");

Categories

Resources