How to check if a row in a table exists? - android

What i'm trying to do: ListView activity A, I touch an item, it opens a new listview activity. I take the primary key from the database row selected in list A and use putExtra. In activity B, in onCreate I want to check and see if there is any row in Table B where the column TOPIC_CONTENT_TOPIC_ID has a value that equals the primary key from table A that was putExtra. If the table is empty, or if there is no matching ID, i want to create a new row where column TOPIC_CONTENT_TOPIC_ID now equals the primary key from table A. Here is my code. It crashes on the db.query();
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.topic_content);
dbMaker = new DatabaseMaker(this);
SQLiteDatabase db = dbMaker.getReadableDatabase();
Intent myIntent = getIntent();
int topicIDInt = (int) myIntent.getLongExtra("com.spentakapps.ScripturalConcordance.Topics", -1);
String topicID = Long.toString(myIntent.getLongExtra("com.spentakapps.ScripturalConcordance.Topics", -1));
String WHERE = DatabaseStructure.TOPICS_CONTENT_TOPIC_ID + " = " + topicID;
Cursor cur = db.query(DatabaseStructure.TABLE_TOPICS_CONTENT, new String[] {DatabaseStructure.TOPICS_CONTENT_CONTENT},WHERE, null, null, null, null);
if (cur.getCount() <= 0)
{
ContentValues values = new ContentValues();
values.put(DatabaseStructure.TOPICS_CONTENT_TOPIC_ID, topicIDInt);
db = dbMaker.getWritableDatabase();
db.insert(DatabaseStructure.TABLE_TOPICS_CONTENT, null, values);
db = dbMaker.getReadableDatabase();
cur = db.query(DatabaseStructure.TABLE_TOPICS_CONTENT, new String[] {DatabaseStructure.TOPICS_CONTENT_TOPIC_ID},WHERE, null, null, null, null);
}
View addContentButton = findViewById(R.id.content_button_add);
addContentButton.setOnClickListener(this);
//Set up data binding
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,R.layout.topiccontentlineitem,cur, FROM,TO);
setListAdapter(adapter);
}

My recommendation for these sorts of issues is always to log into the emulator using:
adb shell
then open the sqlite db directly
# cd /data/data/<your application package>/databases/
# ls
# sqlite3 <your database file>
once inside you should be able to try to manually run your sql to make sure it works:
select id from TABLE_TOPICS_CONTENT where id='someidvalue' limit 1
When you say it crashes on db.query, there are two db.query statemenets in your above code. My guess is that you are running into significant problems since you are calling dbMaker.getReadableDatabase(); several times. Try to just call it once in the beginning as runnable and try to verify that your sql is valid using those. If that fails, attach your error log.

Related

SQLiteDatabase delete(table_name, null, null) is not deleting all rows in the table

This is my code :
Db.getInstance().beginTransaction();
int i = Db.getInstance().delete("friends", null, null);
Log.e(TAG, "dropDB: " + i);
Db.getInstance().setTransactionSuccessful();
Db.getInstance().endTransaction();
I have searched the SO community, but cannot find what is wrong in this code. When I delete , the value of i is number of rows deleted, but still the database keeps returning rows.
Db is my own helper class in which I initialise the SQLiteDatabase's object and get getWritableDatabase().
May be nothing, but try only calling getInstance() once and setting it to a variable.
I use this in a CustomDialog when the user clicks the btnYES to delete the table.
I know the table only ever has one record because it hold a password so try this
db = helper.getReadableDatabase();
String q = "SELECT * FROM masterPW";
Cursor cursor = db.rawQuery(q,null);
// Above query gets TABLE_PW data from Col_IDI
// TABLE_PW will only ever have one row of data
int rowID = 99;
if(cursor.moveToFirst()){
rowID = cursor.getInt(cursor.getColumnIndex(Col_IDI));
str = cursor.getString(cursor.getColumnIndex(Col_MPW));
}
cursor.close();
// Line of code below WORKS deletes entire TABLE <=====
// Not a recommended way to re-set the master password
// db.delete(TABLE_PW, null, null);

SQLiteDatabase Order By Id Skips First Element

Have a very strange issue with pulling data from SQLite Database on Android. Here is my method that takes all the entries from the table entries and iterates them through the loop, putting them in the list view.
It works fine until I wanted to change this line
Cursor c = readableDatabase.rawQuery("select * from entries", null);
to this one:
Cursor c = readableDatabase.rawQuery("select * from entries order by ID DESC", null);
So after the change I don't see the first element. Not sure what is going there. Here is the source code of that method.
EntryHelper entryHelper = new EntryHelper(this);
SQLiteDatabase readableDatabase = entryHelper.getReadableDatabase();
// NOTE: needs to be changed to order by ID...
//
Cursor c = readableDatabase.rawQuery("select * from entries", null);
c.moveToFirst();
ArrayList productsList = new ArrayList();
ProductsArrayAdapter productsArrayAdapter = new ProductsArrayAdapter(this, productsList);
while (c.moveToNext()) {
Integer entryIdIndex = c.getColumnIndexOrThrow(Schema.Entry.ID);
Integer entryBarcodeIndex = c.getColumnIndexOrThrow(Schema.Entry.COLUMN_NAME_BARCODE);
Integer entryQuantityIndex = c.getColumnIndexOrThrow(Schema.Entry.COLUMN_NAME_QUANTITY);
Integer entryId = c.getInt(entryIdIndex);
String entryBarcode = c.getString(entryBarcodeIndex);
String entryQuantity = c.getString(entryQuantityIndex);
Product lineItemProduct = new Product(entryId, entryBarcode, entryQuantity);
productsList.add(lineItemProduct);
Toast toast = Toast.makeText(this, lineItemProduct.toString(), Toast.LENGTH_SHORT);
toast.show();
}
productsListView = (ListView) findViewById(R.id.productsList);
productsListView.setAdapter(productsArrayAdapter);
Any help will be appreciated
This is your problem:
c.moveToFirst();
// other code
while (c.moveToNext()) {
Your skipping the first element, moveToFirst puts your cursor at the first position, then your while moves one more position to the second position.
Either remove the moveToFirst() (you aren't checking the return type or doing anything with this anyway). Or change your while loop to a do while but this assumes you always have at least 1 result. I recommend removing c.moveToFirst.

Android - populate ListView SQLite, cursor null pointer

I have two tables atm, users and notes. I am trying to retrieve data that belongs to the user. So all data to list must be owned by the original user and shown only to him. I have made my table in Databasehelper.
I have made a new class that controls the notes table. In listNotes() I want to loop through the cursor row and get all data owned by the user. Am I quering it correctly?
// Listing all notes
public Cursor listNotes() {
Cursor c = db.query(help.NOTE_TABLE, new String[]{help.COLUMN_TITLE,help.COLUMN_BODY, help.COLUMN_DATE}, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
db.close();
return c;
}
I then want to display the cursor data collected in a listview
public void populateList(){
Cursor cursor = control.listNotes();
getActivity().startManagingCursor(cursor);
//Mapping the fields cursor to text views
String[] fields = new String[]{help.COLUMN_TITLE,help.COLUMN_BODY, help.COLUMN_DATE};
int [] text = new int[] {R.id.item_title,R.id.item_body, R.id.item_date};
adapter = new SimpleCursorAdapter(getActivity(),R.layout.list_layout,cursor, fields, text,0);
//Calling list object instance
listView = (ListView) getView().findViewById(android.R.id.list);
adapter.notifyDataSetChanged();
listView.setAdapter(adapter);
}
You aren't creating the NOTE_TABLE right.
You miss a space and a comma here
+ COLUMN_DATE + "DATETIME DEFAULT CURRENT_TIMESTAMP"
It has to be
+ COLUMN_DATE + " DATETIME DEFAULT CURRENT_TIMESTAMP,"
There are two issues here:
One is you have missed a comma (after the Timestamp as specified in an earlier answer).
The other error you have is when using a SimpleCursorAdapter, you need to ensure that the Projection string array includes something to index the rows uniquely and this must be an integer column named as "_id". SQLite already has a feature built in for this and provides a column named "_id" for this purpose (however you can have your own integer column which you can rename to _id). To solve this, change your projection string array to something like:
new String[] {"ROW_ID AS _id", help.COLUMN_TITLE,help.COLUMN_BODY, help.COLUMN_DATE}
I guess the NullPointerException stems from this (but without the stacktrace I don't know for sure).

Android SQLite Incrementing Integer Field Read from Query

Disclosure up front, this is a school project.
I have a method in a class that manages the database for a "quzzer" feature in my app, it is intended to increment (or decrement in one case) three integer fields in an SQLite database. It needs to do this independently from the "quizzing functions", so I need to pull the data first, change it, then update it into the database.
The fields are as follows in the database:
"prof_level" - Only acceptable values are 1 to 4 inclusive.
"times_correct" - Only positive numbers.
"times_incorrect" - Only positive numbers.
I can pull the numbers fine from the db then increment them by 1, but when I update, they increment the values in the db by 2 instead, and I've no idea why. Here is the full code of the method:
public void updateCharacterProf(String table, String charToUpdate, boolean isIncreased){
//get character from table
SQLiteDatabase db = getReadableDatabase();
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(table);
String[] projection = {"prof_level", "times_correct", "times_incorrect"};
Cursor c = qb.query(db, projection, "character=='" + charToUpdate + "'", null, null, null,
null, null);
c.moveToFirst();
//check to see if the prof level is at max/min
int profLevel = c.getInt(0);
int correctTimes = c.getInt(1);
int incorrectTimes = c.getInt(2);
//mod prof levels
if (isIncreased){
profLevel++;
correctTimes++;
}
else{
profLevel--;
incorrectTimes++;
}
if (profLevel == 4 && isIncreased){
profLevel = 4;
}
else if (profLevel == 1 && !isIncreased){
profLevel = 1;
}
c.close();
ContentValues values = new ContentValues();
values.put("prof_level", profLevel);
values.put("times_correct", correctTimes);
values.put("times_incorrect", incorrectTimes);
//update db
db.update(table, values, "character=='" + charToUpdate + "'", null);
db.close();
}
I'm hoping that it's just something I don't get about how updating SQLite dbs, but I'm lost at the "var++ == +=2" thing that I'm getting now.
I discovered that the issue was o e of my own creation, I fired the callback that calls this database update twice accidently in the dialog fragment that calls it (once in an onClick method and once in a life cycle onDismiss override.).
Fixing this bug, which happened during another different dateabase related thing, fixed the problem for me.

Update singel cell of a row in an SQLite database on Android

I wont to update a single cell of a row in the database. However the row contains of 5 columns so and i would like to not passing all the other values as well as they should remain the same.
I have this code snippet:
Cursor cursor = db.query(STATION_TABLE, null, null, null, null, null, null);
//If the database already include some stations.
if(cursor.moveToFirst())
{
ContentValues stationValues = new ContentValues();
for(StopLocation station: stations)
{
stationValues.clear();
//The database already includes the station
if(cursor.getString(POS_STA_ID).equals(station.getId()))
{
values.put(KEY_STA_DISTANCE, "null");
db.update(STATION_TABLE, stationValues, KEY_STA_ID + "=?", new String[]{station.getId()});
}
The db.update method throws this exception:
java.lang.IllegalArgumentException: Empty values
Any ideas on how to solve this?
If I understand the question correctly and assuming you are always dealing with one row, there are two possible ways to approach this:
First:
Get the values of all fields in the entire row, and declare them as content values before updating:
ContentValues cv = new ContentValues();
cv.put("Field1","123");
cv.put("Field2","True")
Second:
Use execSQL() method:
String strSQL = "UPDATE your_table SET Field1 = foo WHERE POST_STA_ID = "+ station.getId();
myDataBase.execSQL(strSQL);

Categories

Resources