While Testing TestDb gives errors for creating table - android

I want to save the data from web site in sqlite database
WeatheDbHelper.java
/*sqlite database handler*/
package com.example.admin.sunshine.app.data;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Created by admin on 18/02/2016.
*/
public class WeatherDbHelper extends SQLiteOpenHelper{
private static final int DATABASE_VERSION=2;
static final String DATABASE_NAME="weather.db";
public WeatherDbHelper(Context context)
{
super(context,DATABASE_NAME,null,DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase)
{
final String SQL_CREATE_LOCATION_TABLE="CREATE TABLE"+ WeatherContract.LocationEntry.TABLE_NAME+"("+
WeatherContract.LocationEntry._ID+"INTEGER PRIMARY KEY,"+
WeatherContract.LocationEntry.COLUMN_LOCATION_SETTING+"TEXT UNIQUE NOT NULL,"+
WeatherContract.LocationEntry.COLUMN_CITY_NAME+"TEXT NOT NULL,"+
WeatherContract.LocationEntry.COLUMN_COORD_LAT+"REAL NOT NULL,"+
WeatherContract.LocationEntry.COLUMN_COORD_LONG+"REAL NOT NULL"+
");";
final String SQL_CREATE_WEATHER_TABLE="CREATE TABLE" + WeatherContract.WeatherEntry.TABLE_NAME+"("+
WeatherContract.WeatherEntry._ID +"INTEGER PRIMARY KEY AUTOINCREMENT,"+
WeatherContract.WeatherEntry.COLUMN_LOC_KEY +"INTEGER NOT NULL,"+
WeatherContract.WeatherEntry.COLUMN_DATE +"INTEGER NOT NULL,"+
WeatherContract.WeatherEntry.COLUMN_SHORT_DESC +"TEXT NOT NULL,"+
WeatherContract.WeatherEntry.COLUMN_WEATHER_ID +"INTEGER NOT NULL,"+
WeatherContract.WeatherEntry.COLUMN_MIN_TEMP +"REAL NOT NULL,"+
WeatherContract.WeatherEntry.COLUMN_MAX_TEMP +"REAL NOT NULL,"+
WeatherContract.WeatherEntry.COLUMN_HUMIDITY +"REAL NOT NULL,"+
WeatherContract.WeatherEntry.COLUMN_PRESSURE +"REAL NOT NULL,"+
WeatherContract.WeatherEntry.COLUMN_WIND_SPEED +"REAL NOT NULL,"+
WeatherContract.WeatherEntry.COLUMN_DEGREES +"REAL NOT NULL,"+
"FOREIGN KEY("+ WeatherContract.WeatherEntry.COLUMN_LOC_KEY +")REFERENCES "+
WeatherContract.LocationEntry.TABLE_NAME +"("+ WeatherContract.LocationEntry._ID+"),"+
"UNIQUE ("+ WeatherContract.WeatherEntry.COLUMN_DATE+","+ WeatherContract.WeatherEntry.COLUMN_LOC_KEY+
") ON CONFLICT REPLACE);";
sqLiteDatabase.execSQL(SQL_CREATE_WEATHER_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase,int oldVersion, int newVersion)
{
sqLiteDatabase.execSQL("DROP TABLE IF EXIST"+ WeatherContract.LocationEntry.TABLE_NAME);
sqLiteDatabase.execSQL("DROP TABLE IF EXIST"+ WeatherContract.WeatherEntry.TABLE_NAME);
onCreate(sqLiteDatabase);
}
}
TestDb.java for testing the create table
/*creating the SQLite database
package com.example.admin.sunshine.app.data;
/**
* Created by admin on 22/02/2016.
*/
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.test.AndroidTestCase;
import java.util.HashSet;
public class TestDb extends AndroidTestCase {
public static final String LOG_TAG = TestDb.class.getSimpleName();
// Since we want each test to start with a clean slate
void deleteTheDatabase() {
mContext.deleteDatabase(WeatherDbHelper.DATABASE_NAME);
}
/*
This function gets called before each test is executed to delete the database. This makes
sure that we always have a clean test.
*/
public void setUp() {
deleteTheDatabase();
}
/*
Students: Uncomment this test once you've written the code to create the Location
table. Note that you will have to have chosen the same column names that I did in
my solution for this test to compile, so if you haven't yet done that, this is
a good time to change your column names to match mine.
Note that this only tests that the Location table has the correct columns, since we
give you the code for the weather table. This test does not look at the
*/
public void testCreateDb() throws Throwable {
// build a HashSet of all of the table names we wish to look for
// Note that there will be another table in the DB that stores the
// Android metadata (db version information)
final HashSet<String> tableNameHashSet = new HashSet<String>();
tableNameHashSet.add(WeatherContract.LocationEntry.TABLE_NAME);
tableNameHashSet.add(WeatherContract.WeatherEntry.TABLE_NAME);
boolean b = mContext.deleteDatabase(WeatherDbHelper.DATABASE_NAME);
SQLiteDatabase db = new WeatherDbHelper(
this.mContext).getWritableDatabase();
assertEquals(true, db.isOpen());
// have we created the tables we want?
Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null);
assertTrue("Error: This means that the database has not been created correctly",
c.moveToFirst());
// verify that the tables have been created
do {
tableNameHashSet.remove(c.getString(0));
} while( c.moveToNext() );
// if this fails, it means that your database doesn't contain both the location entry
// and weather entry tables
assertTrue("Error: Your database was created without both the location entry and weather entry tables",
tableNameHashSet.isEmpty());
// now, do our tables contain the correct columns?
c = db.rawQuery("PRAGMA table_info(" + WeatherContract.LocationEntry.TABLE_NAME + ")",
null);
assertTrue("Error: This means that we were unable to query the database for table information.",
c.moveToFirst());
// Build a HashSet of all of the column names we want to look for
final HashSet<String> locationColumnHashSet = new HashSet<String>();
locationColumnHashSet.add(WeatherContract.LocationEntry._ID);
locationColumnHashSet.add(WeatherContract.LocationEntry.COLUMN_CITY_NAME);
locationColumnHashSet.add(WeatherContract.LocationEntry.COLUMN_COORD_LAT);
locationColumnHashSet.add(WeatherContract.LocationEntry.COLUMN_COORD_LONG);
locationColumnHashSet.add(WeatherContract.LocationEntry.COLUMN_LOCATION_SETTING);
int columnNameIndex = c.getColumnIndex("name");
do {
String columnName = c.getString(columnNameIndex);
locationColumnHashSet.remove(columnName);
} while(c.moveToNext());
// if this fails, it means that your database doesn't contain all of the required location
// entry columns
assertTrue("Error: The database doesn't contain all of the required location entry columns",
locationColumnHashSet.isEmpty());
db.close();
}
/*
Students: Here is where you will build code to test that we can insert and query the
location database. We've done a lot of work for you. You'll want to look in TestUtilities
where you can uncomment out the "createNorthPoleLocationValues" function. You can
also make use of the ValidateCurrentRecord function from within TestUtilities.
*/
public void testLocationTable() {
String testLocationSetting = "99705";
String testCityName = "North Pole";
double testLatitude = 64.7488;
double testLongitude = -147.353;
// First step: Get reference to writable database
SQLiteDatabase db = new WeatherDbHelper(
this.mContext).getWritableDatabase();
assertEquals(true, db.isOpen());
// Create ContentValues of what you want to insert
// (you can use the createNorthPoleLocationValues if you wish)
ContentValues locationValues = new ContentValues();
locationValues.put(WeatherContract.LocationEntry.COLUMN_LOCATION_SETTING, testLocationSetting);
locationValues.put(WeatherContract.LocationEntry.COLUMN_CITY_NAME, testCityName);
locationValues.put(WeatherContract.LocationEntry.COLUMN_COORD_LAT, testLatitude);
locationValues.put(WeatherContract.LocationEntry.COLUMN_COORD_LONG, testLongitude);
// Insert ContentValues into database and get a row ID back
long locationRowId;
locationRowId = db.insert(WeatherContract.LocationEntry.TABLE_NAME, null, locationValues);
assertTrue(locationRowId != -1);
// Query the database and receive a Cursor back
Cursor c = db.query(WeatherContract.LocationEntry.TABLE_NAME,
null, //all columns
null, //columns for the "where" clause
null, //values fro the "where" clause
null, //columns to group by
null, //columns to filter by row groups
null //sort order
);
// Move the cursor to a valid database row
assertTrue(" Error: No Records returned from location query", c.moveToFirst());
// Validate data in resulting Cursor with the original ContentValues
// (you can use the validateCurrentRecord function in TestUtilities to validate the
// query if you like)
TestUtilities.validateCurrentRecord("Error: location query validation failed", c, locationValues);
//Move the cursor to demonstrate that there is only one record in the database
assertFalse("Error: More than one record returned from location query", c.moveToNext());
// Finally, close the cursor and database
c.close();
db.close();
}
/*
Students: Here is where you will build code to test that we can insert and query the
database. We've done a lot of work for you. You'll want to look in TestUtilities
where you can use the "createWeatherValues" function. You can
also make use of the validateCurrentRecord function from within TestUtilities.
*/
public void testWeatherTable() {
// First insert the location, and then use the locationRowId to insert
// the weather. Make sure to cover as many failure cases as you can.
long locationRowId = TestUtilities.insertNorthPoleLocationValues(mContext);
// Make sure we have a valid row ID.
assertFalse("Error: Location Not Inserted Correctly", locationRowId == -1L);
// Instead of rewriting all of the code we've already written in testLocationTable
// we can move this code to insertLocation and then call insertLocation from both
// tests. Why move it? We need the code to return the ID of the inserted location
// and our testLocationTable can only return void because it's a test.
// First step: Get reference to writable database
SQLiteDatabase db = new WeatherDbHelper(this.mContext)
.getWritableDatabase();
// Create ContentValues of what you want to insert
// (you can use the createWeatherValues TestUtilities function if you wish)
ContentValues contentValues = TestUtilities.createWeatherValues(locationRowId);
// Insert ContentValues into database and get a row ID back
long weatherRowId = db.insert(WeatherContract.WeatherEntry.TABLE_NAME, null, contentValues);
assertTrue(weatherRowId != -1);
// Query the database and receive a Cursor back
Cursor cursor = db.query(WeatherContract.WeatherEntry.TABLE_NAME,
null,
null,
null,
null,
null,
null
);
// Move the cursor to a valid database row
assertTrue("Error: No Records Returned from Weather Query", cursor.moveToFirst());
// Validate data in resulting Cursor with the original ContentValues
// (you can use the validateCurrentRecord function in TestUtilities to validate the
// query if you like)
TestUtilities.validateCurrentRecord("Error: weather query validation failed", cursor, contentValues);
// Move the cursor to demonstrate that there is only one record in the database
assertFalse( "Error: More than one record returned from weather query",
cursor.moveToNext() );
// Finally, close the cursor and database
cursor.close();
db.close();
}
/*
Students: This is a helper method for the testWeatherTable quiz. You can move your
code from testLocationTable to here so that you can call this code from both
testWeatherTable and testLocationTable.
*/
public long insertLocation() {
return -1L;
}
}
Following are the error while testing the TestDb in AndroidTest
LOGCAT:
android.database.sqlite.SQLiteException: near "TABLEweather": syntax error (code 1): , while compiling: CREATE TABLEweather(_idINTEGER PRIMARY KEY AUTOINCREMENT,location_idINTEGER NOT NULL,dateINTEGER NOT NULL,short_descTEXT NOT NULL,weather_idINTEGER NOT NULL,minREAL NOT NULL,maxREAL NOT NULL,humidityREAL NOT NULL,pressureREAL NOT NULL,windREAL NOT NULL,degreesREAL NOT NULL,FOREIGN KEY(location_id)REFERENCES location(_id),UNIQUE (date,location_id) ON CONFLICT REPLACE);
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1674)
at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1605)
at com.example.admin.sunshine.app.data.WeatherDbHelper.onCreate(WeatherDbHelper.java:50)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:251)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
at com.example.admin.sunshine.app.data.TestUtilities.insertNorthPoleLocationValues(TestUtilities.java:90)
at com.example.admin.sunshine.app.data.TestDb.testWeatherTable(TestDb.java:155)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1837)

You need to put some "spaces" in your Create table scripts especially in the places where you open/close your doublequotes ("). Below I tried to put an empty space in every doublequote, you can check if it is ok or I missed anything.
final String SQL_CREATE_WEATHER_TABLE="CREATE TABLE " + WeatherContract.WeatherEntry.TABLE_NAME+" ( "+
WeatherContract.WeatherEntry._ID +" INTEGER PRIMARY KEY AUTOINCREMENT, "+
WeatherContract.WeatherEntry.COLUMN_LOC_KEY +" INTEGER NOT NULL, "+
WeatherContract.WeatherEntry.COLUMN_DATE +" INTEGER NOT NULL, "+
WeatherContract.WeatherEntry.COLUMN_SHORT_DESC +" TEXT NOT NULL, "+
WeatherContract.WeatherEntry.COLUMN_WEATHER_ID +" INTEGER NOT NULL, "+
WeatherContract.WeatherEntry.COLUMN_MIN_TEMP +" REAL NOT NULL, "+
WeatherContract.WeatherEntry.COLUMN_MAX_TEMP +" REAL NOT NULL, "+
WeatherContract.WeatherEntry.COLUMN_HUMIDITY +" REAL NOT NULL, "+
WeatherContract.WeatherEntry.COLUMN_PRESSURE +" REAL NOT NULL, "+
WeatherContract.WeatherEntry.COLUMN_WIND_SPEED +" REAL NOT NULL, "+
WeatherContract.WeatherEntry.COLUMN_DEGREES +" REAL NOT NULL, "+
" FOREIGN KEY( "+ WeatherContract.WeatherEntry.COLUMN_LOC_KEY +" ) REFERENCES "+
WeatherContract.LocationEntry.TABLE_NAME +" ("+ WeatherContract.LocationEntry._ID+" ), "+
" UNIQUE ( "+ WeatherContract.WeatherEntry.COLUMN_DATE+" , "+ WeatherContract.WeatherEntry.COLUMN_LOC_KEY+
" ) ON CONFLICT REPLACE);";

Related

How to delete the rows from a table where a column contains a specific String?

As my title question, I want to delete some rows of table on SQLite where contains specific string.
Here are my methods I tried but there are no any row is deleted. I checked table of SQLite database by get it out and put in to DB Browser for SQLite which is downloaded from https://sqlitebrowser.org/
public void delete1(String table,String COLUMN,String link) {
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("DELETE FROM "+table+" WHERE "+COLUMN+" LIKE "+link+"%");
}
public void delete2(String table,String name){
SQLiteDatabase db = this.getWritableDatabase();
db.delete(table, "PRODUCTNAME" + "LIKE ?", new String[]{name+"%"}) ;
}
Could you tell me how to do it or how have i to correct code ?
using db.delete(table, "PRODUCTNAME " + "LIKE ?", new String[]{name+"%"}) ; will only delete rows that start with the value in name.
Perhpas you want :-
db.delete(table, "PRODUCTNAME " + "LIKE ?", new String[]{"%"+name+"%"}) ;
Then it would delete rows that contain the value rather than start with the value.
With db.execSQL("DELETE FROM "+table+" WHERE "+COLUMN+" LIKE "+link+"%"); you need to enclose the string in single quotes and assuming that you want to delete a row that contains the value then use :-
db.execSQL("DELETE FROM "+table+" WHERE "+COLUMN+" LIKE '%"+link+"%'");
Using the delete convenience method (the first part) is the better option as it protects against SQL Injection, it properly encloses the value, builds the underlying SQL and also returns the number of affected (deleted) rows.
If you use the following, this will write dome debugging information that may assist in debugging :-
public void delete2(String table,String name){
SQLiteDatabase db = this.getWritableDatabase();
Log.d("DELETEINFO","Attempting to delete rows with \n\t->" + name);
int deletedCount = db.delete(table, "PRODUCTNAME " + "LIKE ?", new String[]{"%"+name+"%"}) >0) ;
Log.d("DELETEINFO","Deleted " + deletedCount + " rows.");
}

Delete all tables from sqlite database

I have done a lot of research and was unable to find a suitable method to delete all the tables in an SQLite database. Finally, I did a code to get all table names from the database and I tried to delete the tables using the retrieved table names one by one. It didn't work as well.
Please suggest me a method to delete all tables from the database.
This is the code that I used:
public void deleteall(){
SQLiteDatabase db = this.getWritableDatabase();
Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null);
do
{
db.delete(c.getString(0),null,null);
}while (c.moveToNext());
}
function deleteall() is called on button click whos code is given as below:
public void ButtonClick(View view)
{
String Button_text;
Button_text = ((Button) view).getText().toString();
if(Button_text.equals("Delete Database"))
{
DatabaseHelper a = new DatabaseHelper(this);
a.deleteall();
Toast.makeText(getApplicationContext(), "Database Deleted Succesfully!", Toast.LENGTH_SHORT).show();
}}
Use DROP TABLE:
// query to obtain the names of all tables in your database
Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null);
List<String> tables = new ArrayList<>();
// iterate over the result set, adding every table name to a list
while (c.moveToNext()) {
tables.add(c.getString(0));
}
// call DROP TABLE on every table name
for (String table : tables) {
String dropQuery = "DROP TABLE IF EXISTS " + table;
db.execSQL(dropQuery);
}
Tim Biegeleisen's answer almost worked for me, but because I used AUTOINCREMENT primary keys in my tables, there was a table called sqlite_sequence. SQLite would crash when the routine tried to drop that table. I couldn't catch the exception either. Looking at https://www.sqlite.org/fileformat.html#internal_schema_objects, I learned that there could be several of these internal schema tables that I shouldn't drop. The documentation says that any of these tables have names beginning with sqlite_ so I wrote this method
private void dropAllUserTables(SQLiteDatabase db) {
Cursor cursor = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null);
//noinspection TryFinallyCanBeTryWithResources not available with API < 19
try {
List<String> tables = new ArrayList<>(cursor.getCount());
while (cursor.moveToNext()) {
tables.add(cursor.getString(0));
}
for (String table : tables) {
if (table.startsWith("sqlite_")) {
continue;
}
db.execSQL("DROP TABLE IF EXISTS " + table);
Log.v(LOG_TAG, "Dropped table " + table);
}
} finally {
cursor.close();
}
}
delete database instead of deleting tables and then create new with same name if you need. use following code
context.deleteDatabase(DATABASE_NAME);
or
context.deleteDatabase(path);
For me, the working solution is:
Cursor c = db.rawQuery(
"SELECT name FROM sqlite_master WHERE type IS 'table'" +
" AND name NOT IN ('sqlite_master', 'sqlite_sequence')",
null
);
if(c.moveToFirst()){
do{
db.execSQL("DROP TABLE " + c.getString(c.getColumnIndex("name")));
}while(c.moveToNext());
}

SQLite Insert Query Multiple Database

I wrote the following code to insert some records into table from the table of another database.
But I'm unable to, even after executing a sql statement it shows that there are no records in the table.
public int copy_to_all_source_table(String dbpath,String backpath)
{
SQLiteDatabase db1 = this.getWritableDatabase();
//Opening App database(i.e. dbpath) and attaching it as "OLD"
db1.openDatabase(dbpath, null, SQLiteDatabase.OPEN_READWRITE);
String attach_old="ATTACH '"+ dbpath +"' AS OLD";
db1.execSQL(attach_old);
//Opening New File which is Student.db(i.e. dbpath) and attaching it as "NEW"
db1.openDatabase(backpath, null, SQLiteDatabase.OPEN_READWRITE);
String attach_new="ATTACH '"+ backpath +"' AS NEW";
db1.execSQL(attach_new);
// Getting count of records in table of "NEW"
String new_query =" SELECT * FROM 'NEW'.'"+ TABLE_CONTACTS +"'";
Cursor new_data = db1.rawQuery(new_query, null);
Integer new_count= new_data.getCount();
//INSERTING ALL RECORDS FROM TABLE OF NEW TO TABLE OF OLD
String insert_query ="INSERT INTO 'OLD'.'"+ TABLE_CONTACTS +"' SELECT * FROM 'NEW'.'"+ TABLE_CONTACTS +"'";
Cursor success_insert = db1.rawQuery(insert_query, null);
// Getting count of records in table of "NEW"
String after_insert_old_query =" SELECT * FROM 'OLD'.'"+ TABLE_CONTACTS +"'";
Cursor old_data = db1.rawQuery(after_insert_old_query, null);
Integer old_count= old_data.getCount();
}
RESULT:
new_count = 11
old_count = 0
So, no record has been inserted.
You are using rawQuery() to execute an INSERT command. Which will never work.
Use execSQL(), instead
Moreover, the last comment is misleading, because it says you want the count from the NEW table, but you are counting from the OLD one.
And, please, get rid of the string delimiter characters (').
I.e.:
this
String new_query =" SELECT * FROM 'NEW'.'"+ TABLE_CONTACTS +"'";
should be
String new_query = "SELECT * FROM NEW." + TABLE_CONTACTS;

Can't stop table from autoincrement id when insert unique field

I have a table with 2 columns, a numeric id and unique text. Created like this:
String CREATE_MY_TABLE = "CREATE TABLE " + TABLE_TEST + "("
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ KEY_FOO + " TEXT UNIQUE"
+ ")";
db.execSQL(CREATE_MY_TABLE);
I want that when I insert KEY_FOO value and it's already in the db, nothing happens. But what I get is that the id is always incremented. No new row is inserted, that's good, but the id is autoincremented.
What I'm doing to insert is as follows:
db.insertWithOnConflict(TABLE_TEST , null, values, SQLiteDatabase.CONFLICT_NONE);
I tried CONFLICT_IGNORE, CONFLICT_ABORT, CONFLICT_ROLLBACK, all the same.
The reason I need this is because other table has a foreign key on this id, thus if the id is changed, the other table points nowhere.
How I just say to let the existing entry untouched?
Try this way. In your dbhelper class write the method like following to insert.
public int insertData(String desc) {
db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
try {
db.beginTransaction();
cv.put(KEY_FOO, desc);
db.insertOrThrow(TABLE_TEST, null, cv);
db.setTransactionSuccessful();
} catch (Exception ex) {
return 1;
} finally {
db.endTransaction();
db.close();
}
return 0;
}
Then from your actvity you call this method with the parameter value of KEY_FOO. This method will return 1 if the exception is occurs (If you try insert a unique value) and it will return 0 if the transaction is successfull.
I hope this way will help you. Let me know if any problem.

data cant be inserted to the sqlit database tables

I am trying to insert data in my sqlit database but I got android SQLiteConstraintException: error code 19: constraint failed exception. I saw there are tons of question in this topic, I've read and tried a bunch of them, but the exception still , i wonder if this exception caused by the auto increment food_id value , since the insert statement return -1 , and i wonder that why this exception occur since the first insert id done correctly but all the later inserting are failed , why this error occur ,and how i can solve it? please help me..
the create statements in the DBAdapter class
private static final String Meal_TABLE_CREATE= "create table IF NOT EXISTS Meal (Date text not null , "+
"Time text not null,MealType text not null,"+ " primary key(Date,Time ,MealType) );" ;
private static final String FOOD_TABLE_CREATE= "create table IF NOT EXISTS Food (_id INTEGER primary key AUTOINCREMENT , "+
"Food_Name text not null,Calories integer not null,"+ "VB12 integer not null,Cholesterol integer not null,"+
"Protein integer not null,Iron integer not null,Sodium integer not null,Fat_Mono integer not null,Fat_Sat integer not null,carbohydrate integer not null);" ;
private static final String MealFOOD_TABLE_CREATE= "create table IF NOT EXISTS MealFood (Date text not null , "+
"Time text not null,MealType text not null,"+"Food_ID integer not null , primary key(Date,Time ,MealType,Food_ID) );" ;
inserting methods
// insert meal to the meal table
public long SaveMeal(String date , String time , String mealType)
{
ContentValues content = new ContentValues();
content.put(KEY_MDATE,date);
content.put(KEY_MTIME,time);
content.put(KEY_MEALTYPE,mealType);
return db.insert(MEAL_TABLE_NAME, null, content);
}
// insert Food to the Food table
public long SaveFood(String name,int calories,int Vit_B12,int cholesterol,int protein ,int iron ,int sodium,int Fat_Mono,int Fat_Sat,int carbohydrate)
{
ContentValues content = new ContentValues();
content.put(KEY_FOODNAME,name);
content.put(KEY_CALORIES,calories);
content.put(KEY_VB12,Vit_B12);
content.put(KEY_CHOLESTEROL,cholesterol);
content.put(KEY_PROTEIN,protein);
content.put(KEY_IRON,iron);
content.put(KEY_SODIUM,sodium);
content.put(KEY_FAT_MONO,Fat_Mono);
content.put(KEY_FAT_Sat,Fat_Sat);
content.put(KEY_CARBOHYDRATE,carbohydrate);
return db.insert(FOOD_TABLE_NAME, null, content);
}
// get food id by its name
public int getFoodIDByName(String name) throws SQLException
{ int id;
Cursor cursor = null;
try{
cursor=db.query(true,FOOD_TABLE_NAME, new String[]{KEY_FOODID}, KEY_FOODNAME+ " = '" + name + "'", null, null, null, null,null);
if (cursor != null) {
cursor.moveToFirst();
}
id=0;
while (cursor.moveToNext())
id=cursor.getInt(cursor.getColumnIndex(KEY_FOODID));
}
finally{
cursor.close();
cursor.deactivate();
}
return id;
}
// insert mealFood to mealFood table
public long SaveMealFood(String date , String time , String mealType, int Food_id)
{
ContentValues content = new ContentValues();
content.put(KEY_MFDATE,date);
content.put(KEY_MFTIME,time);
content.put(KEY_MFMEALTYPE,mealType);
content.put(KEY_MFFOODID,Food_id);
return db.insert(MEALFOOD_TABLE_NAME, null, content);
}
java code
DBAdapter dbAdapter=new DBAdapter(SaveMeal.this);
dbAdapter.open();
Food n;
String m;
int FoodIDByName;
for(int i = 0; i <MealActivity.array.size(); i++){
m=MealActivity.array.get(i).toString();
Log.e("tag", m);//selected food name
for (int j = 0; j < MealActivity.tempList.size(); j++){
n=MealActivity.tempList.get(j);
if(n.getFOOD_NAME().equals(m)){
//save food
long food_id = dbAdapter.SaveFood(n.getFOOD_NAME(),n.getCALORIES(),n.getFOOD_VITAMIN_B12(),n.getCHOLESTEROL(),n.getFOOD_PROTEIN(),n.getFOOD_IRON(),n.getFOOD_SODIUM(),
n.getFOOD_MONO_UNSATURATED_FAT(),n.getFOOD_SATURATED_FAT(),n.getFOOD_TOTAL_CARBOHYDRATE());
Log.e("tag", food_id+" food inserting done");
//save meal
long meal_id= dbAdapter.SaveMeal( meal_date,meal_time,Meal.MEAL_TYPE);
Log.e("tag",meal_id+" meal inserting done");
//save meal_food
FoodIDByName=dbAdapter.getFoodIDByName(n.FOOD_NAME);
Log.e("tag",FoodIDByName+" food_id");
long meal_food_id=dbAdapter.SaveMealFood(meal_date,meal_time,Meal.MEAL_TYPE,FoodIDByName);
Log.e("tag",meal_food_id+" meal_food inserting done");
dbAdapter.close();
this result of this line Log.e("tag", food_id+" food inserting done"); in my log is -1
mylog
Database(657):at android.database.sqlite.SQLiteStatement.native_execute(Native Method)
Database(657):at android.database.sqlite.SQLiteStatement.execute (SQLiteStatement.java:55)
Database(657):at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1410)
-1 food inserting done
18 meal inserting done
0 food_id
13 meal_food inserting done
Try to remove all (Not NULL) constraints, and save the empty food.
If it is saved properly, try to add the constraint (NOT NULL) one by one.
I think one of the values is passed as NULL.
That error.means you are.violating a constraint (obviously). Most likely leave a "not null" column null.
You could also have violated your primary key by trying to save the same combination more than once.

Categories

Resources