SQLite Insert fails - java

Well i been fighting with this all yesterday and today, i got a simple SQLite insert that keeps returning a -1 as a return value, i read somewhere to change the primary key name to _id but made no change.
so here are the snaps op the code.
My constants for the fields:
//BALLS TABLE
public static final String BALLS_TABLE = "balls";
public static final String BALL_ID = "id";
public static final String BALL_USERID = "userId";
public static final String BALL_MODEL = "model";
public static final String BALL_BRAND = "brand";
public static final String BALL_SERIAL = "serial";
public static final String BALL_NOTES = "notes";
public static final String BALL_IMAGE = "image";
then on my createTables(SQLiteDatabase db) i got
//BALLS TABLE
db.execSQL(
"create table " + BALLS_TABLE +" (" +
BALL_ID + " integer primary key autoincrement not null," +
BALL_USERID + "integer not null," +
BALL_MODEL + " text not null," +
BALL_BRAND + " text not null," +
BALL_SERIAL + " text not null," +
BALL_NOTES + " text not null," +
BALL_IMAGE + " blob" +
");");
the creation of tables is working as i got other tables that are been populated.
and finally the whole ball Helper class
package com.kegel.android.bowlermanager.data;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class BallHelper {
private SQLiteDatabase database;
private ArrayList<Ball> currentBalls;
private Context context;
public BallHelper(Context context,SQLiteDatabase database)
{
this.context = context;
this.database = database;
loadBalls();
}
public ArrayList<Ball> getCurrentBalls() {
return currentBalls;
}
public Boolean BallExists(long id)
{
for (Ball ball : currentBalls)
{
if (ball.getId() == id)
return true;
}
return false;
}
public Boolean BallExists(Ball u)
{
for (Ball ball : currentBalls)
{
if (ball.getId() == u.getId())
return true;
}
return false;
}
public void updateBall(Ball b) {
assert(null != b);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] by = null;
if (b.getImage() != null )
{
Bitmap bmp = b.getImage();
bmp.compress(Bitmap.CompressFormat.PNG, 100, baos);
by = baos.toByteArray();
}
ContentValues values = new ContentValues();
values.put(SQLiteOpenDataHelper.BALL_USERID, 1);
values.put(SQLiteOpenDataHelper.BALL_MODEL, b.getModel());
values.put(SQLiteOpenDataHelper.BALL_BRAND , b.getBrand());
values.put(SQLiteOpenDataHelper.BALL_SERIAL , b.getSerial());
values.put(SQLiteOpenDataHelper.BALL_NOTES, b.getNotes());
values.put(SQLiteOpenDataHelper.BALL_IMAGE , by);
if (b.isValid())
{
if (b.getId() == 0)
{
b.setId(database.insert(SQLiteOpenDataHelper.BALLS_TABLE, null, values));
}
else
{
long id = b.getId();
String where = String.format("%s = %d", SQLiteOpenDataHelper.BALL_ID, id);
database.update(SQLiteOpenDataHelper.BALLS_TABLE, values, where, null);
}
loadBalls();
}
}
public void deleteBalls(Long id) {
String where = String.format("%s in (%s)", SQLiteOpenDataHelper.BALL_ID, id);
database.delete(SQLiteOpenDataHelper.BALLS_TABLE, where, null);
loadBalls();
}
public void deleteBalls(Ball u) {
String where = String.format("%s in (%s)", SQLiteOpenDataHelper.BALL_ID, u.getId());
database.delete(SQLiteOpenDataHelper.BALLS_TABLE, where, null);
loadBalls();
}
private void loadBalls() {
byte[] img = null;
currentBalls = new ArrayList<Ball>();
//try
//{
Cursor ballsCursor = database.query(SQLiteOpenDataHelper.BALLS_TABLE, new String[] {SQLiteOpenDataHelper.BALL_ID,SQLiteOpenDataHelper.USER_ID, SQLiteOpenDataHelper.BALL_MODEL, SQLiteOpenDataHelper.BALL_BRAND, SQLiteOpenDataHelper.BALL_SERIAL, SQLiteOpenDataHelper.BALL_NOTES, SQLiteOpenDataHelper.BALL_IMAGE}, null, null, null, null, null);
ballsCursor.moveToFirst();
Ball b;
if (! ballsCursor.isAfterLast()) {
do {
long id = ballsCursor.getInt(0);
long bowlerId = ballsCursor.getLong(1);
String model = ballsCursor.getString(2);
String brand = ballsCursor.getString(3);
String serial = ballsCursor.getString(4);
String notes = ballsCursor.getString(5);
img = ballsCursor.getBlob(6);
Bitmap bmp=BitmapFactory.decodeByteArray(img,0,img.length);
b = new Ball(context,bowlerId,model,brand,serial,notes);
b.setId(id);
b.setImage(bmp);
currentBalls.add(b);
} while (ballsCursor.moveToNext());
}
ballsCursor.close();
}
}
A second pair of eyes here will come handy! so if anyone can spot anything here, or let me know if I'm missing something i will really appreciate it. I already checked the values on b ( is even passing my internal validation ) but and insertion like this will fail:
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.fake_pofile);
Ball ball = new Ball(this,1, "Test", "Test", "", "");
ball.setImage(bm);
mHelper.updateBall(ball);

Well... as i didn't, nobody else noted on the code for the table creation, between the field BALL_USERID i wasn't leaving a space so it was a whole word, funny thing that db.exec is supposed to throw exceptions but in this case didn't and accepted a strange name as a field with no type and created the table with no field "userId" but "useridinteger" with no type ( is there a default type if you don't set one?? )
Sometimes are just those litte things that can make you go nuts.

I know this is an old example, but for anyone looking for an Objective C sample, this is good. However, be sure to put the sqlite3_reset(statement) lines BEFORE the return statements. Otherwise, the code only works on the first save or find.

Related

Null Pointer Exception in Android Content Provider [duplicate]

Im trying to store a particular columns data in a method and call that method in another classes String [] where a spinner will access that array to display the columns rows for the user to select which will then get stored in another database.
Im getting nulpointerexception and when I try and open() the database the database gets locked. Sorry for sounding like a complete amateur, relatively new to android. Thank you in advance for any help.
Here is my code when I call getInstance() and getCPnames() in my main class
String[] carParks = CarParkDb.getInstance().getCpnames();
Here is my code for the database:
package com.example.parkangel;
import java.util.ArrayList;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class CarParkDb {
public static final String KEY_ID = "_id";
public static final String KEY_CPNAME = "cpname";
public static final String KEY_COST = "cost";
private static final String DATABASE_NAME = "CPDB";
private static final String DATABASE_TABLE = "CPTable";
private static final int DATABASE_VERSION = 1;
private CPDbHelper cpdbHelper;
private Context ourContext;
private SQLiteDatabase ourDatabase;
private static CarParkDb instance;
private static class CPDbHelper extends SQLiteOpenHelper{
public CPDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// TODO Auto-generated constructor stub
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" +
KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
KEY_CPNAME + " TEXT NOT NULL, " + KEY_COST + " TEXTNOT NULL);");
db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values('1','LearningResource Center','2');");
db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values ('2','ParkandRide','1');");
db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values ('3','deHavilland Campus','2');");
db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values('4','MultiStorey Building','2');");
db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values('5','Reception','2');");
}
public void onOpen(final SQLiteDatabase db) {
super.onOpen(db);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
onCreate(db);
}
}
public CarParkDb (final Context c)
{
this.cpdbHelper= new CPDbHelper(c);
establishDb();
//ourContext = c;
}
public void establishDb()
{
if (this.ourDatabase == null)
{
this.ourDatabase = this.cpdbHelper.getWritableDatabase();
}
}
public CarParkDb() {
// TODO Auto-generated constructor stub
}
public CarParkDb open() throws SQLException
{
System.out.println ("running open");
cpdbHelper = new CPDbHelper(ourContext);
ourDatabase = cpdbHelper.getWritableDatabase();
return this;
}
public void close()
{
ourDatabase.close();
}
/*public long createEntry(String cpname, String cost){
ContentValues cv = new ContentValues();
cv.put(KEY_CPNAME, cpname);
cv.put(KEY_COST, cost);
return ourDatabase.insert(DATABASE_TABLE, null, cv);
}*/
public String getData() {
// TODO Auto-generated method stub
//open();
String[] columns = new String[] {KEY_ID, KEY_CPNAME, KEY_COST};
Cursor c = ourDatabase.query(DATABASE_TABLE, columns, null,null,null, null, null);
String result = " ";
int iRow = c.getColumnIndexOrThrow(KEY_ID);
int iCpname = c.getColumnIndexOrThrow(KEY_CPNAME);
int iCost = c.getColumnIndexOrThrow(KEY_COST);
for(c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){
result = result + c.getString(iRow) + " " +c.getString(iCpname) + " " + c.getString(iCost) + " " + "\n";
c.close();
ourDatabase.close();
}
return result;
}
public static CarParkDb getInstance()
{
synchronized(CarParkDb.class)
{
if (instance == null)
{
instance = new CarParkDb();
}
return instance;
}
}
public String[] getCpnames()
{
//open();
if (ourDatabase == null) System.out.println ("is null");
Cursor c = null;
ArrayList<String> list = new ArrayList<String>();
ourDatabase = cpdbHelper.getReadableDatabase();
//SQLiteDatabase db = cpdbHelper.getReadableDatabase();
String query = "SELECT " + KEY_CPNAME + " FROM " + DATABASE_TABLE;
{
c = this.ourDatabase.rawQuery(query, null);
int iCpname = c.getColumnIndexOrThrow(KEY_CPNAME);
if (c.moveToFirst())
{
do
{
list.add(c.getString(iCpname));;
}
while (c.moveToNext());
}
if (c != null && !c.isClosed())
{
c.close();
ourDatabase.close();
}
return list.toArray(new String[]{});
}
}
}
**LogCat**
03-12 01:32:39.759: E/AndroidRuntime(4176): Caused by:java.lang.NullPointerException
03-12 01:32:39.759: E/AndroidRuntime(4176):
at com.example.parkangel.CarParkDb.getCpnames(CarParkDb.java:191)
03-12 01:32:39.759: E/AndroidRuntime(4176):
at com.example.parkangel.BookTicket.<init>(BookTicket.java:22)
03-12 01:32:39.759: E/AndroidRuntime(4176):
at java.lang.Class.newInstanceImpl(Native Method)
03-12 01:32:39.759: E/AndroidRuntime(4176):
at java.lang.Class.newInstance(Class.java:1208)
The database doesn't get locked. The "locked" thinkg is just a NPE in a method called getDatabaseLocked() and it's caused by a null Context passed to SQLiteOpenHelper in constructor that manifests itself with getWritableDatabase() or getReadableDatabase().
To fix the NPE in getDatabaseLocked(), make sure ourContext in open() is not null. As of now, you've never initialized ourContext and it's always null. Uncomment the //ourContext = c; in constructor and move it above the establishDb(), remove the other no-argument constructor and pass in a Context for example as suggested by Merlevede.
The NPE stacktrace in your question is when you call getCpNames() with open() commented out and are trying to call a method on a null ourDatabase object reference. Uncomment the open() there once it's fixed. The stacktrace also says you're trying to call getCpNames() in object initialization phase e.g. when initializing a member variable. That might be too early, for example an activity cannot be used as a Context until onCreate().
Some other things in your code you'd hit next:
in onCreate(): + KEY_COST + " TEXTNOT NULL) - add space between TEXT and NOT
in getData(): you're closing the cursor and database in the loop where you're accessing the cursor. Do it after the loop. The code shouldn't compile as you're not returning anything from a non-void function in case moveToFirst() returns false.
Try updating your getInstance() code with this:
public static CarParkDb getInstance(Context c) // <-- added context as parameter
{
synchronized(CarParkDb.class)
{
if (instance == null)
{
instance = new CarParkDb(c); // <-- used context in constructor
}
return instance;
}
}
The problem seems to be that you're using a constructor (for CarParkDb) that does nothing. You have another constructor that takes a Context as parameter and initializes some of the objects that you're using later.

Android Studio: NullPointerException: Attempt to invoke virtual method '...' on a null object reference

Hello friends,
I have been working on this all night and really don't understand what I am missing. I understand that the problem is in the addWord() method but I don't understand how.
I tried removing the checkword() method from the addword() method and I also removed the .trim() from the string declarations for w1 and m1. I did not include the XML becuase of the character limit but i am sure the initializations are fine.
Would really appreciate it if you can help a noob out.
thank you
The Error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.login_signup_sqlite, PID: 18102
java.lang.NullPointerException: Attempt to invoke virtual method 'long com.example.login_signup_sqlite.DatabaseHelper.addWord(java.lang.String, java.lang.String)' on a null object reference
at com.example.login_signup_sqlite.AddWords$1.onClick(AddWords.java:51)
at android.view.View.performClick(View.java:4780)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
at android.view.View$PerformClick.run(View.java:19866)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
java code for AddWords.class
package com.example.login_signup_sqlite;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class AddWords extends AppCompatActivity {
EditText word1,word2,word3,word4,word5,word6,word7,word8,word9,word10,word11,word12,word13,word14,word15;
EditText meaning1,meaning2,meaning3,meaning4,meaning5,meaning6,meaning7,meaning8,meaning9,meaning10,meaning11,meaning12,meaning13,meaning14,meaning15;
Button addWordsButton;
DatabaseHelper db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_words);
//words initialization
word1 = findViewById(R.id.word1);word2 = findViewById(R.id.word2); word3 = findViewById(R.id.word3);word4 = findViewById(R.id.word4);word5 = findViewById(R.id.word5);
word6 = findViewById(R.id.word6);word7 = findViewById(R.id.word7); word8 = findViewById(R.id.word8);word9 = findViewById(R.id.word9);word10 = findViewById(R.id.word10);
word11 = findViewById(R.id.word11);word12 = findViewById(R.id.word12); word13 = findViewById(R.id.word13);word14 = findViewById(R.id.word14);word15 = findViewById(R.id.word15);
//Meanings initialization
meaning1 = findViewById(R.id.meaning1);meaning2 = findViewById(R.id.meaning2);meaning3 = findViewById(R.id.meaning3);meaning4 = findViewById(R.id.meaning4);meaning5 = findViewById(R.id.meaning5);
meaning6 = findViewById(R.id.meaning6);meaning7 = findViewById(R.id.meaning7);meaning8 = findViewById(R.id.meaning8);meaning9 = findViewById(R.id.meaning9);meaning10 = findViewById(R.id.meaning10);
meaning11 = findViewById(R.id.meaning11);meaning12 = findViewById(R.id.meaning12);meaning13 = findViewById(R.id.meaning13);meaning14 = findViewById(R.id.meaning14);meaning15 = findViewById(R.id.meaning15);
//Button
addWordsButton = findViewById(R.id.addWordsBTN);
addWordsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//getting the text from the words
String w1 = word1.getText().toString().trim();String w2 = word2.getText().toString().trim();String w3 = word3.getText().toString().trim();String w4 = word4.getText().toString().trim();String w5 = word5.getText().toString().trim();
String w6 = word6.getText().toString().trim();String w7 = word7.getText().toString().trim();String w8 = word8.getText().toString().trim();String w9 = word9.getText().toString().trim();String w10 = word10.getText().toString().trim();
String w11 = word11.getText().toString().trim();String w12 = word12.getText().toString().trim();String w13 = word13.getText().toString().trim();String w14 = word14.getText().toString().trim();String w15 = word15.getText().toString().trim();
//getting the text from the words
String m1 = meaning1.getText().toString().trim();String m2 = meaning2.getText().toString().trim();String m3 = meaning3.getText().toString().trim();String m4 = meaning4.getText().toString().trim();String m5 = meaning5.getText().toString().trim();
String m6 = meaning6.getText().toString().trim();String m7 = meaning7.getText().toString().trim();String m8 = meaning8.getText().toString().trim();String m9 = meaning9.getText().toString().trim();String m10 = meaning10.getText().toString().trim();
String m11 = meaning11.getText().toString().trim();String m12 = meaning12.getText().toString().trim();String m13 = meaning13.getText().toString().trim();String m14 = meaning14.getText().toString().trim();String m15 = meaning15.getText().toString().trim();
//adding the words
db.addWord(w1,m1);
db.addWord(w2,m2);db.addWord(w3,m3);db.addWord(w4,m4);db.addWord(w5,m5);
db.addWord(w6,m6);db.addWord(w7,m7);db.addWord(w8,m8);db.addWord(w9,m9);db.addWord(w10,m10);
db.addWord(w11,m11);db.addWord(w12,m12);db.addWord(w13,m13);db.addWord(w14,m14);
long val = db.addWord(w15,m15);
if (val>0){
Toast.makeText(AddWords.this,"Congratulations, the words were added to the student's box 1",Toast.LENGTH_SHORT).show();
Intent backToInstructorMainScreen = new Intent(AddWords.this,InstructorMainScreen.class);
startActivity(backToInstructorMainScreen);
}
}
});
}
}
Java code for the DatabaseHelper.class
package com.example.login_signup_sqlite;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import androidx.annotation.Nullable;
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME="register.db";
//TABLES
public static final String INSTRUCTORS_TABLE ="registeruser";
public static final String STUDENTS_TABLE ="registerstudent";
public static final String WORDS_TABLE = "words";
//USERS COLUMNS
public static final String COL_1_USERS="ID";
public static final String COL_2_USERS ="username";
public static final String COL_3_USERS ="email";
public static final String COL_4_USERS ="password";
//WORDS COLUMNS
public static final String INDEX_WORDS ="ID";
public static final String WORD ="word";
public static final String MEANING ="meaning";
public static final String BOX_NO ="box_no";
public static final String LEARNT ="learnt";
public DatabaseHelper(#Nullable Context context) {
super(context, DATABASE_NAME, null,1);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL("CREATE TABLE registeruser (ID INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT,email TEXT, password TEXT)");
sqLiteDatabase.execSQL("CREATE TABLE registerstudent (ID INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT,email TEXT, password TEXT)");
sqLiteDatabase.execSQL("CREATE TABLE words (ID INTEGER PRIMARY KEY AUTOINCREMENT, word TEXT,meaning TEXT, box_no TEXT,learnt INTEGER )");
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
String query = INSTRUCTORS_TABLE +", "+STUDENTS_TABLE+", "+WORDS_TABLE;
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS "+ query);
onCreate(sqLiteDatabase);
}
public long addWord(String word, String meaning){
if(checkword(word)){
return 0;
}else{
String i ="1";
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("word",word);
contentValues.put("meaning",meaning);
contentValues.put("box_no",i);
long res = db.insert("words",null,contentValues);
db.close();
return res;
}
}
//this function will enter the username and password in to the database
public long addUser(String user, String password,String email){
if(checkUser(user,password)){
return 0;
}else{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("username",user);
contentValues.put("email",email);
contentValues.put("password",password);
long res = db.insert("registeruser",null,contentValues);
db.close();
return res;
}
}
public long addStudent(String user, String password,String email){
if(checkStudent(user,password)){
return 0;
}else{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("username",user);
contentValues.put("email",email);
contentValues.put("password",password);
long res = db.insert("registerstudent",null,contentValues);
db.close();
return res;
}
}
public boolean checkword(String word){
String[] columns = {INDEX_WORDS};
SQLiteDatabase db = getReadableDatabase();
String selection = WORD;
String[] selectionArgs = {word};//this will get the username and passwords from the database
Cursor cursor = db.query(INSTRUCTORS_TABLE, columns,selection,selectionArgs,null,null, null);
int count = cursor.getCount();
cursor.close();
db.close(); // to close the database
if(count>0){ // if the data exists
return true;// then return true
}else { // if not
return false;// return false
}
}
//this function will check if the username and password is in the database
public boolean checkUser(String username, String password){
String[] columns = {COL_1_USERS};
SQLiteDatabase db = getReadableDatabase();
String selection = COL_2_USERS + "=?"+" and "+ COL_4_USERS +"=?";
String[] selectionArgs = {username,password};//this will get the username and passwords from the database
Cursor cursor = db.query(INSTRUCTORS_TABLE, columns,selection,selectionArgs,null,null, null); // this will select the whatever there is in the ID, Uername and password columns
//we can change the null to queries but we do not want to, because we do not need any specific order here we just want to search everything
int count = cursor.getCount(); // this will get the count of everything
cursor.close(); //this will finish the query
db.close(); // to close the database
if(count>0){ // if the data exists
return true;// then return true
}else { // if not
return false;// return false
}
}
public boolean checkStudent(String username, String password){
String[] columns = {COL_1_USERS};
SQLiteDatabase db = getReadableDatabase();
String selection = COL_2_USERS + "=?"+" and "+ COL_4_USERS +"=?";
String[] selectionArgs = {username,password};//this will get the username and passwords from the database
Cursor cursor = db.query(STUDENTS_TABLE, columns,selection,selectionArgs,null,null, null); // this will select the whatever there is in the ID, Uername and password columns
//we can change the null to queries but we do not want to, because we do not need any specific order here we just want to search everything
int count = cursor.getCount(); // this will get the count of everything
cursor.close(); //this will finish the query
db.close(); // to close the database
if(count>0){ // if the data exists
return true;// then return true
}else { // if not
return false;// return false
}
}
}
The problem isn't in the addWord method, but that db is null, and you can't call a method on null. Adding the line db = new DatabaseHelper(); in AddWords.onCreate might help.
you have created an object of your DatabaseHelper class but you did not initialize that,
add this line in onCreate method
db=new DatabaseHelper(this);
after the setContentView

How to properly write SQLite update function with string comparison in the where cluse

I have a table with two columns first is date and the second is a counter. I do not have a primary key but the date acts as one. So my code checks if the current date exists in the table, if so it will only increment the counter other wise it will add a new entry. The existence of the current date is only possible at the last row. here is the code:
SQLiteOpenHelper implementation:
public class SqliteHelperInstance extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "app_stats";
public static final String TABLE_NAME = "day_stats";
public static final String COLUMN_DATE = "date";
public static final String COLUMN_CIGCOUNT = "cigcount";
public static final int DATABASE_VERSION = 1;
private static final String CREATE_DB = "create table " + TABLE_NAME + " ( " + COLUMN_DATE + " text, "
+ COLUMN_CIGCOUNT + " integer );";
public SqliteHelperInstance(Context context){
super(context,DATABASE_NAME , null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(CREATE_DB);
}
}
The implementation of database manager:
public class DbManager {
private SqliteHelperInstance sqlHelper;
private SQLiteDatabase database;
private String[] columns = { SqliteHelperInstance.COLUMN_DATE, SqliteHelperInstance.COLUMN_CIGCOUNT};
public DbManager(Context context){
sqlHelper = new SqliteHelperInstance(context);
}
public void addEntry(Calendar cal){
ContentValues values = new ContentValues();
String dateEntry = dateFormatter(cal);
Cursor cursor = database.query(SqliteHelperInstance.TABLE_NAME, null, null, null, null, null,
SqliteHelperInstance.COLUMN_DATE + " DESC LIMIT 1");
//check if the last entered date is equal to the current date
if(cursor.moveToFirst()){
String lastDate = cursor.getString(0);
if(lastDate.equalsIgnoreCase(dateEntry)){
//the cigNum should be updated for the current date
int cigNum = cursor.getInt(1);
cigNum ++;
values.put(SqliteHelperInstance.COLUMN_DATE,lastDate);
values.put(SqliteHelperInstance.COLUMN_CIGCOUNT, cigNum);
int i = database.update(SqliteHelperInstance.TABLE_NAME, values,SqliteHelperInstance.COLUMN_DATE + " = " + lastDate , null);
if(i == 0){
Log.d("Tag", "No row is affected");
}
}
else{
//the last date is different than current day so we need to add a new entry
DbEntry newEntry = new DbEntry();
newEntry.setDate(dateEntry);
values.put(SqliteHelperInstance.COLUMN_DATE, dateEntry);
values.put(SqliteHelperInstance.COLUMN_CIGCOUNT, newEntry.getCigNum());
database.insert(SqliteHelperInstance.TABLE_NAME, null, values);
}
}
else{
//its the first time that the application is loading
DbEntry newEntry = new DbEntry();
newEntry.setDate(dateEntry);
newEntry.setCignum(1);
values.put(SqliteHelperInstance.COLUMN_DATE, dateEntry);
values.put(SqliteHelperInstance.COLUMN_CIGCOUNT, newEntry.getCigNum());
Log.i(null, "values are set");
database.insert(SqliteHelperInstance.TABLE_NAME, null, values);
}
}
But when I run the application, I keep getting 0 row affected by the update function.I assume the comparison in the where clause is not returning any particular row. can anyone help me with this issue?
Try getting the lastDate like this:
String lastDate = cursor.getString(cursor.getColumnIndex(SqliteHelperInstance.COLUMN_DATE));
Also, you should use parameterized queries:
int i = database.update(SqliteHelperInstance.TABLE_NAME, values,SqliteHelperInstance.COLUMN_DATE + " = ?", new String[]{ lastDate });
Other than that, I'm not sure what could be wrong.

how to separate [String] by "-" and make multiple column on android?

I'm working on a Searchable dictionary. Its Raw database is separated by "-" like
ColumnA(Key_Word) ColumnB(Key_defination)
Apple - One kind of Fruit
Mango - One fruit also
But I want to make it 3 column, (Column C will be Key_details)
ColumnA ColumnB ColumnC (Key_details)
Apple - One kind of Fruit - Round shape
Mango - One fruit also - Found in Bangladesh
When people search A, application will show Column B and C. The reason why i splited string is I want to show Coumn B and C on different window. How to do that? Here is my source-
/**
* Contains logic to return specific words from the dictionary, and
* load the dictionary table when it needs to be created.
*/
public class DictionaryDatabase {
private static final String TAG = "DictionaryDatabase";
//The columns we'll include in the dictionary table
public static final String KEY_WORD = SearchManager.SUGGEST_COLUMN_TEXT_1;
public static final String KEY_DEFINITION = SearchManager.SUGGEST_COLUMN_TEXT_2;
private static final String DATABASE_NAME = "dictionary";
private static final String FTS_VIRTUAL_TABLE = "FTSdictionary";
private static final int DATABASE_VERSION = 2;
private final DictionaryOpenHelper mDatabaseOpenHelper;
private static final HashMap<String,String> mColumnMap = buildColumnMap();
public DictionaryDatabase(Context context) {
mDatabaseOpenHelper = new DictionaryOpenHelper(context);
}
private static HashMap<String,String> buildColumnMap() {
HashMap<String,String> map = new HashMap<String,String>();
map.put(KEY_WORD, KEY_WORD);
map.put(KEY_DEFINITION, KEY_DEFINITION);
map.put(BaseColumns._ID, "rowid AS " +
BaseColumns._ID);
map.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID, "rowid AS " +
SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID);
map.put(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID, "rowid AS " +
SearchManager.SUGGEST_COLUMN_SHORTCUT_ID);
return map;
}
public Cursor getWord(String rowId, String[] columns) {
String selection = "rowid = ?";
String[] selectionArgs = new String[] {rowId};
return query(selection, selectionArgs, columns);
}
public Cursor getWordMatches(String query, String[] columns) {
String selection = KEY_WORD + " MATCH ?";
String[] selectionArgs = new String[] {query+"*"};
return query(selection, selectionArgs, columns);
}
private Cursor query(String selection, String[] selectionArgs, String[] columns) {
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
builder.setTables(FTS_VIRTUAL_TABLE);
builder.setProjectionMap(mColumnMap);
Cursor cursor = builder.query(mDatabaseOpenHelper.getReadableDatabase(),
columns, selection, selectionArgs, null, null, null);
if (cursor == null) {
return null;
} else if (!cursor.moveToFirst()) {
cursor.close();
return null;
}
return cursor;
}
private static class DictionaryOpenHelper extends SQLiteOpenHelper {
private final Context mHelperContext;
private SQLiteDatabase mDatabase;
private static final String FTS_TABLE_CREATE =
"CREATE VIRTUAL TABLE " + FTS_VIRTUAL_TABLE +
" USING fts3 (" +
KEY_WORD + ", " +
KEY_DEFINITION + ");";
DictionaryOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
mHelperContext = context;
}
#Override
public void onCreate(SQLiteDatabase db) {
mDatabase = db;
mDatabase.execSQL(FTS_TABLE_CREATE);
loadDictionary();
}
private void loadDictionary() {
new Thread(new Runnable() {
public void run() {
try {
loadWords();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}).start();
}
private void loadWords() throws IOException {
Log.d(TAG, "Loading words...");
final Resources resources = mHelperContext.getResources();
InputStream inputStream = resources.openRawResource(R.raw.definitions);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
try {
String line;
while ((line = reader.readLine()) != null) {
String[] strings = TextUtils.split(line, "-");
if (strings.length < 2) continue;
long id = addWord(strings[0].trim(), strings[1].trim());
if (id < 0) {
Log.e(TAG, "unable to add word: " + strings[0].trim());
}
}
} finally {
reader.close();
}
Log.d(TAG, "DONE loading words.");
}
public long addWord(String word, String definition) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_WORD, word);
initialValues.put(KEY_DEFINITION, definition);
return mDatabase.insert(FTS_VIRTUAL_TABLE, null, initialValues);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + FTS_VIRTUAL_TABLE);
onCreate(db);
}
}
}
String[] arr = string.split("-");
String#split(String regex)
Returns the array of strings computed by splitting this string around
matches of the given regular expression.
EDIT:
long id = addWord(strings[0].trim(), strings[1].trim());
Above line should be:
long id = addWord(strings[0].trim(), strings[1].trim(),strings[2].trim());
And change your addWord function as I mentioned below.
public long addWord(String word, String definition,String details) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_WORD, word);
initialValues.put(KEY_DEFINITION, definition);
initialValues.put(KEY_DETAILS, details);
return mDatabase.insert(FTS_VIRTUAL_TABLE, null, initialValues);
}
A better way to handle the tokenization is by using StringTokenizer
StringTokenizer token = new StringTokenizer(str,"-");
To access the tokens,
while(token.hasNext())
{
String tmp = token.nextToken();
...
}

Android Adding DATE (now) to SQLite database

Currently my SQLite database is working great, I have read up on various methods such as this one to achieve this, though currently I am having issues with setting up the Date constructor and also how to define the data for use in putting it to the database (and getting it back!)
So far I have used static final String to define my data variables, notsure which is the correct way to use Date.
I'm not concerned with the time, just the date the entry was created.
Below is my java class:
import java.sql.Date;
import java.text.SimpleDateFormat;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class Stats {
public static final String KEY_ROWID = "_id";
public static final String KEY_WEIGHT = "weight";
public static final String KEY_WAIST = "waist";
public static final String KEY_CHEST = "chest";
public static final String KEY_LEGS = "legs";
public static final String KEY_ARMS = "arms";
public static final String KEY_DATE = "date";
private static final String DATABASE_NAME = "statsDB";
private static final String DATABASE_TABLE = "personalStats";
private static final int DATABASE_VERSION = 3;
private DbHelper ffHelper;
private final Context ffContext;
private SQLiteDatabase ffDatabase;
private static class DbHelper extends SQLiteOpenHelper {
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" + KEY_ROWID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_WEIGHT
+ " TEXT NOT NULL, " + KEY_WAIST + " TEXT NOT NULL, "
+ KEY_CHEST + " TEXT NOT NULL, " + KEY_LEGS
+ " TEXT NOT NULL, " + KEY_ARMS + " TEXT NOT NULL, "
+ KEY_DATE + " TEXT NOT NULL);");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
onCreate(db);
}
}
public Stats(Context c) {
ffContext = c;
}
public Stats open() throws SQLException {
ffHelper = new DbHelper(ffContext);
ffDatabase = ffHelper.getWritableDatabase();
return this;
}
public void close() {
ffHelper.close();
}
public long createEntry(String weight, String waist, String chest, String legs, String arms) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
ContentValues cv = new ContentValues();
cv.put(KEY_WEIGHT, weight);
cv.put(KEY_WAIST, waist);
cv.put(KEY_CHEST, chest);
cv.put(KEY_LEGS, legs);
cv.put(KEY_ARMS, arms);
cv.put("date_created", dateFormat.format(date));
return ffDatabase.insert(DATABASE_TABLE, null, cv);
}
public String getData() {
String[] columns = new String[] { KEY_ROWID, KEY_WEIGHT, KEY_WAIST, KEY_CHEST, KEY_LEGS, KEY_ARMS, KEY_DATE };
Cursor c = ffDatabase.query(DATABASE_TABLE, columns, null, null, null,
null, null);
String result = "";
int iRow = c.getColumnIndex(KEY_ROWID);
int iWeight = c.getColumnIndex(KEY_WEIGHT);
int iWaist = c.getColumnIndex(KEY_WAIST);
int iChest = c.getColumnIndex(KEY_CHEST);
int iLegs = c.getColumnIndex(KEY_LEGS);
int iArms = c.getColumnIndex(KEY_ARMS);
int iDate = c.getColumnIndex(KEY_DATE);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
result = result + c.getString(iRow) + " " + c.getString(iWeight)
+ " " + c.getString(iWaist)
+ " " + c.getString(iChest)
+ " " + c.getString(iLegs)
+ " " + c.getString(iArms)
+ " " + c.getString(iDate)+ "\n";
}
return result;
}
}
Obviously any time Date is mentioned is where I have attempted to add this extra functionality.
You may put date like string in database, but this string must have good format.
For SQLite it is:
YYYY-MM-dd
YYYY-MM-dd hh:mm
YYYY-MM-dd hh:mm:ss
YYYY-MM-dd hh:mm:ss.sss
YYYY-MM-DDThh:mm
YYYY-MM-DDThh:mm:ss
YYYY-MM-DDThh:mm:ss.sss
hh:mm
hh:mm:ss
hh:mm:ss.sss
Like Yoann write you can convert date to string with:
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateForinsert = dateFormat(new GregorianCalendar(2013, GregorianCalendar.MAY, 5).getTime());
"Now" you can set with:
String dateForinsert = dateFormat(new GregorianCalendar().getTime());

Categories

Resources