Get User By User Email From SQLite - android

Here's my getUser mothod :
public User getUser(String Email) {
SQLiteDatabase db = this.getReadableDatabase();
String sql = "SELECT * FROM " + DBContract.Users.TABLE_NAME
+ " WHERE " + DBContract.Users.COL_EMAIL + " = " + Email;
try {
Cursor cursor = db.rawQuery(sql, null);
User user = new User();
// Read data, I simplify cursor in one line
if (cursor != null) {
cursor.moveToFirst();
// Get imageData in byte[]. Easy, right?
user.setUserID(Integer.parseInt(cursor.getString(cursor.getColumnIndex(DBContract.Users._ID))));
user.setUserName(cursor.getString(cursor.getColumnIndex(DBContract.Users.COL_NAME)));
user.setUserImage(cursor.getBlob(cursor.getColumnIndex(DBContract.Users.COL_IMAGE)));
user.setUserPassword(cursor.getString(cursor.getColumnIndex(DBContract.Users.COL_PASSWORD)));
user.setUserEmail(cursor.getString(cursor.getColumnIndex(DBContract.Users.COL_EMAIL)));
user.setUserLocation(cursor.getString(cursor.getColumnIndex(DBContract.Users.COL_LOCATION)));
}
cursor.close();
db.close();
return user;
} catch (SQLException e) {
}
return null;
}
User Profile Fragment where i call the getUser:
public class UserHomeFragment extends Fragment {
DBHelper dbHelper;
User user;
ImageView userImageView;
TextView userNameTexView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.user_profile_home_fragment, container, false);
dbHelper = new DBHelper(v.getContext());
user = new User();
userImageView = (ImageView) v.findViewById(R.id.userimg);
userNameTexView = (TextView) v.findViewById(R.id.user_name);
Bundle extras = getActivity().getIntent().getExtras();
assert extras != null;
String userEmail = extras.getString("userEmail");
user = dbHelper.getUser(userEmail);
// Bitmap bitmap = BitmapFactory.decodeByteArray(userImage, 0, userImage.length);
// userImageView.setImageBitmap(bitmap);
userNameTexView.setText(user.getUserName());
return v;
}}
Why the getUser return null ? I've checked there are users at the user's table .
Error Massage:Attempt to invoke virtual method 'java.lang.String com.arfni.ayafinal.model.User.getUserName()' on a null object reference

The issue you are encountering is two-fold.
The prime error is that you need to enclose a string value in quotes otherwise it may be considered as a keyword or an entity (e.g. a table or a column name) or it may cause a syntax error. In short the SQL will not execute and result in an exception.
The compounding error is that the exception is caught and thus the exception is ignored result in no Cursor being created and returned and hence the Cursor variable is never set, so it will be null and then when you then try to close the Cursor it will be null as it outside the scope of the null check.
Furthermore, you also have a potential issue in that if the cursor is not null but is empty, then the moveToFirst will not move to the first row as there isn't a first row to move to. This is indicated by the moveToFirst method returning false. The returned value isn't checked in your code so when you attempt to get the data an exception will occur (along the lines of try to read Index 0 when there are 0 rows) this too being trapped and perhaps leading to confusion.
I'd suggest replacing the getUser method with the following :-
public User getUser(String Email) {
SQLiteDatabase db = this.getReadableDatabase();
String sql = "SELECT * FROM " + DBContract.Users.TABLE_NAME
+ " WHERE " + DBContract.Users.COL_EMAIL + " = " + Email;
Cursor cursor = db.rawQuery(sql, null);
User user = new User();
// Read data, I simplify cursor in one line
if (cursor.moveToFirst()) {
// Get imageData in byte[]. Easy, right?
user.setUserID(Integer.parseInt(cursor.getString(cursor.getColumnIndex(DBContract.Users._ID))));
user.setUserName(cursor.getString(cursor.getColumnIndex(DBContract.Users.COL_NAME)));
user.setUserImage(cursor.getBlob(cursor.getColumnIndex(DBContract.Users.COL_IMAGE)));
user.setUserPassword(cursor.getString(cursor.getColumnIndex(DBContract.Users.COL_PASSWORD)));
user.setUserEmail(cursor.getString(cursor.getColumnIndex(DBContract.Users.COL_EMAIL)));
user.setUserLocation(cursor.getString(cursor.getColumnIndex(DBContract.Users.COL_LOCATION)));
}
cursor.close();
db.close();
return user;
}
Notes
If the SQL fails then the exception stop the App. (i.e try/catch has bee removed).
Should the SQL result in nothing being extracted then an empty cursor is returned (you do not get a null Cursor except if you force it), as such the check for a null Cursor has been removed, rather than moving it so that it will not result in an exception.
user will either be null (no rows in the Cursor) or the user will be populated so there is no need to return null.

Related

How to write a sqlite query to get specific data?

I want to get the first name, middle name and last name of a student whose userid is used for login. I have written this particular piece of code but it stops my application.
I have used both the ways like database.query() and .rawquery() also.
Cursor studentData(String userId) {
SQLiteDatabase db = getWritableDatabase();
Cursor cursor = db.query(studentTable, new String[] { "First_Name", "Middle_Name", "Last_Name"}, "User_ID=?", new String[] { userId }, null, null, null, null);
// Cursor cursor = db.rawQuery("select First_Name, Middle_Name, Last_Name from Student_Table where User_ID =?", new String[]{userId});
String data = cursor.getString(cursor.getColumnIndex("First_Name"));
db.close();
return cursor;
}
I should get whole name in the string.
You have a number of issues.
Attempting to use String data = cursor.getString(cursor.getColumnIndex("First_Name"));,
will result in an error because you have not moved the cursor beyond BEFORE THE FIRST ROW and the attempt to access the row -1 will result in an exception (the likely issue you have encountered).
you can use various move??? methods e.g. moveToFirst, moveToNext (the 2 most common), moveToLast, moveToPosition.
Most of the Cursor move??? methods return true if the move could be made, else false.
You CANNOT close the database and then access the Cursor (this would happen if the issue above was resolved)
The Cursor buffers rows and then ONLY when required.
That is The Cursor is when returned from the query method (or rawQuery) at a position of BEFORE THE FIRST ROW (-1), it's only when an attempt is made to move through the Cursor that the CursorWindow (the buffer) is filled (getCount() included) and the actual data obtained. So the database MUST be open.
If you want a single String, the full name, then you could use :-
String studentData(String userId) { //<<<<<<<<<< returns the string rather than the Cursor
SQLiteDatabase db = getWritableDatabase();
String rv = "NO NAME FOUND"; //<<<<<<<<<< value returned if no row is located
Cursor cursor = db.query(studentTable, new String[] { "First_Name", "Middle_Name", "Last_Name"}, "User_ID=?", new String[] { userId }, null, null, null, null);
if (cursor.modeToFirst()) {
String rv =
cursor.getString(cursor.getColumnIndex("First_Name")) +
" " +
cursor.getString(cursor.getColumnIndex("Middle_Name")) +
" " +
cursor.getString(cursor.getColumnIndex("Last_Name"));
}
cursor.close(); //<<<<<<<<<< should close all cursors when done with them
db.close(); //<<<<<<<<<< not required but would result in an exception if returning a Cursor
return rv;
}
Or alternately :-
String studentData(String userId) { //<<<<<<<<<< returns the string rather than the Cursor
SQLiteDatabase db = getWritableDatabase();
String rv = "NO NAME FOUND"; //<<<<<<<<<< value returned if no row is located
Cursor cursor = db.query(studentTable, new String[] { "First_Name"||" "||"Middle_Name"||" "||"Last_Name" AS fullname}, "User_ID=?", new String[] { userId }, null, null, null, null);
if (cursor.modeToFirst()) {
String rv =
cursor.getString(cursor.getColumnIndex("fullname"));
}
cursor.close(); //<<<<<<<<<< should close all cursors when done with them
db.close(); //<<<<<<<<<< not required but would result in an exception if returning a Cursor
return rv;
}
the underlying query being SELECT First_Name||" "||Middle_Name||" "||LastName AS fullname FROM student_table; so you concatenate the names as part of the query which returns just one dynamically created column named fullname.

Method does not search in database?

Since morning, I've been trying to figure it out a problem that occured me today, and now, close to midnight I found out the problem.. I have 2 methods in a database, one for registering new users and one for login management purposes. Both use the same parameters:
1- user class, 2- var for user class.
The login management gets text from 2 edittexts and compare their values with database ( something like username/password ) and the other have the basic variables.getVariables() -> insert(table,null,variables).
When I call registra_usuario method, translated for register_user it proceeds like it inserted the info into database. But, when I use the second method busca_acesso (search_access) it gives me an OutofBounds error
android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 0
Does this mean that the database has nothing inside TABLE_USER? Because cursor has a size of 0?
These are my two methods:
public boolean registra_usuario(user user){ <- ***THIS ONE SAYS IT'S NEVER USED***
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
try{
values.put(COLUMN_USER_ENTRY_ID, user.getId());
values.put(COLUMN_USER_USERNAME, user.getUsername());
values.put(COLUMN_USER_PASSWORD, user.getPassword());
values.put(KEY_CREATED_AT , user.getCreated_at());
db.insert(TABLE_USER, null, values);
CharSequence text = "Usuário Cadastrado!!";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(null, text, duration);
toast.show();
return true;
}catch (Exception e){
db.close();
return false;
}
}
UPDATED METHOD
public boolean busca_acesso(user user){
SQLiteDatabase db = this.getReadableDatabase();
String [] tabela_user = new String[]{"usuaid","username","password"};
String [] whereargs = new String[]{user.getUsername()};
String compare_user = projeto_db.COLUMN_USER_PASSWORD + " = ?";
Cursor cursor = db.query(TABLE_USER, tabela_user, compare_user, whereargs, null, null, null );
int index = cursor.getColumnIndex(COLUMN_USER_PASSWORD);
cursor.moveToFirst();
while(!cursor.getString(index).equals(user.getPassword())){
cursor.moveToNext();
}
if(cursor.getString(index).equals(user.getPassword())) {
return true;
}else{
return false;
}}
final projeto_db db = new projeto_db(this);
user user = new user(); ***MAIN_ACTIVITY
user.setUsername(username_login);
user.setPassword(password_login);
db.busca_acesso(user);
user user = new user(); ***DIFFERENT ACTIVITY
user.setId();
user.setUsername(editText_username.getText().toString());
user.setPassword(editText_password.getText().toString());
user.setCreated_at(getDateTime());
db.registra_usuario(user);
Both are being called inside onCreate from class and from onClick of Button.
Thanks in advance!

my sqlite cursor returns empty result for a query

I have a small function for checking to see if a records already exists in my sqlite database. There is data in the database that should match the query, i have verified this by opening up the database.But i get an empty result.
Below is the function, it takes in a parameter and uses that as the search parameter. i have also verified that the parameter is correct.
public boolean checkParent(String email)
{
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = null;
try
{
res = db.rawQuery("SELECT * FROM parents WHERE email = ' " + email + " ' ",null);
res.close();
}
catch (Exception ex)
{
Log.e("Error checking parent", ex.toString());
}
if(res == null)
{
return true;
}
else
{
return false;
}
}
Right way to pass argument in rawQuery method.
db.rawQuery("SELECT * FROM parents WHERE email = ?",new String[]{email});
You are checking whether the cursor object res is null. This will never happen; rawQuery() always returns a cursor object.
You have to check whether the cursor is empty, i.e., whether the cursor actually contains any rows. To do this, call a method like moveToFirst() and check if it succeeds.
Or even better, use a helper function that does handle the cursor for you:
public boolean checkParent(String email)
{
SQLiteDatabase db = this.getReadableDatabase();
long count = DatabaseUtils.queryNumEntries(db,
"parents", "email = ?", new String[]{ email });
return count > 0;
}

Android - Checking value from an SQLite DB table

I'm trying to read data from newly deleted SQLite db table row.
Basically my program will delete a row when a certain activity is loaded, and I want to check the value inside the row.
This is my get code :
public String getSlot() {
String slots = new String();
Cursor cursor = database.query(ChosenSlotDatabaseHandler.TABLE_CHOSEN_PARKING_SLOT,
chosenSlotColumn, null, null, null, null, null);
if( cursor.moveToFirst() ) {
slots = cursor.getString(0);
}
// make sure to close the cursor
cursor.close();
return slots;
}
I've used these codes to delete the value :
public static final String DELETE_SLOT = "DELETE FROM "
+ TABLE_CHOSEN_PARKING_SLOT + " WHERE "
+ "_ID = " + CHOSEN_ID + ";";
public void deleteSlotSQL()
{
database.execSQL(ChosenSlotDatabaseHandler.DELETE_SLOT);
}
And this is my condition to set a TextViewvalue :
if(slots == null)
{
chosenSlotView.setText("You have not parked");
}
else
{
chosenSlotView.setText("You are parked in : " + slots);
}
At first, I thought that once the only row is deleted, getSlot() would return null, but it seems that it's not null from this Log.d I ran :
if(slots != null)
{
Log.d("notnull","not null dude");
}else
{
Log.d("null","Yay null");
}
The log returns "not null dude"..
Any suggestion on how to get the slots value so I can set the TextView value??
your slots definitely not null because of this :
String slots = new String();
it should be
String slots = null;
Cursor cursor = database.query(ChosenSlotDatabaseHandler.TABLE_CHOSEN_PARKING_SLOT,
chosenSlotColumn, null, null, null, null, null);
if( cursor.moveToFirst() ) {
slots = cursor.getString(0);
}
// make sure to close the cursor
cursor.close();
return slots;
EDIT :
Nevermind that String slot = null,
Try using :
if(slots.isEmpty())
{
chosenSlotView.setText(notParked);
}
else
{
chosenSlotView.setText(isParked + slots);
}
First off all you should avoid using logs like "not null dude", you will find them funny and suggestive but after a while we won t be able to write clean and professional code.
My second advice is to use constants instead of hadcoded strings . Create a class Constants and add there strings
public static final String NOT_PARKED = "You have not parked"
My third advice is to take a look at ormlite http://logic-explained.blogspot.ro/2011/12/using-ormlite-in-android-projects.html
If the logs are ok , maybe there is a problem with textview . Try putting a text in textview before the condition to check if will get set . Check the layout file also .

how to check if the column of a SQLite dabase is null

i am not able to get a reliable result to tell if the collumn of a database is null or not. i tried using a query checking to see if the the column of the database returns null or a string value of "" but no matter what i do the result of my check returns a result that there is something stored in that column, even if it is empty.
to make sure it is empty i delete all the data from the app and uninstall it from the device. that way i know the database column is empty
is there a better way to check if a particular column is empty?
if a column has never been used before on a newly created database, what is in that column? is it null or is there something put in by the system as a placeholder?
displayAll.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
textToShow.setText(DisplayAllFieldsObjectFromDB());
if (DisplayAllFieldsObjectFromDB() == null) {
Toast.makeText(DisplayTable.this, "TABLE NULL ", Toast.LENGTH_SHORT).show();
} else if (DisplayAllFieldsObjectFromDB() != null) {
Toast.makeText(DisplayTable.this, "TABLE HOLDS A VALUE ", Toast.LENGTH_SHORT).show();
} else if (DisplayAllFieldsObjectFromDB().equals("")) {
Toast.makeText(DisplayTable.this, "TABLE HOLDS EMPTY QUOTES VALUE ", Toast.LENGTH_SHORT).show();
}
}
});
code from the database table
// display all data from table
public String getAllFromDB() {
String tableString = "";
String result = "";
Cursor cursor = sqLiteDatabase.query(MYDATABASE_TABLE, null,
null, null, null, null, null);
if (cursor != null) {
// cursor.moveToFirst(); // use only this for getting one row
while (cursor.moveToNext()) { // use only this for getting multiple rows
tableString = cursor.getString(cursor.getColumnIndex(TABLE_STRING));
result += tableString + "\n";
}
}
return result;
}
Read the documentation: the cursor object has an isNull function.

Categories

Resources