After restart application my database always empty.
What I do wrong?
Did I clean database all the time?
here is the Code for DB class..
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import java.sql.Date;
import java.util.ArrayList;
import galimski.igor.com.do_ing.Task;
import galimski.igor.com.do_ing.TaskPriority;
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = "SQLite";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "TaskDatabase";
private static final String TABLE_TASK = "Task";
private static final String COLUMN_TASK_ID ="Id";
private static final String COLUMN_TASK_SHORT ="ShortDescription";
private static final String COLUMN_TASK_FULL = "FullDescription";
private static final String COLUMN_TASK_CREATIONDATE = "CreatedDate";
private static final String COLUMN_TASK_COMPLETIONDATE = "CompletionDate";
private static final String COLUMN_TASK_PRIORITY = "Priority";
private static final String COLUMN_TASK_SHOWN= "Shown";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
Log.i(TAG, "MyDatabaseHelper.onCreate ... ");
// String script = "CREATE TABLE " + TABLE_NOTE + "("
// + COLUMN_NOTE_ID + " INTEGER PRIMARY KEY," + COLUMN_NOTE_TITLE + " TEXT,"
// + COLUMN_NOTE_CONTENT + " TEXT" + ")";
//String script = "CREATE TABLE `Task` ( `Id` INTEGER NOT NULL, `ShortDescription` TEXT NOT NULL, `FullDescription` TEXT, `CreatedDate` TEXT NOT NULL, `CompletionDate` TEXT NOT NULL, `Priority` TEXT NOT NULL, PRIMARY KEY(`Id`) )";
String script = "CREATE TABLE " + TABLE_TASK + "("
+ COLUMN_TASK_ID + " INTEGER PRIMARY KEY,"
+ COLUMN_TASK_SHORT + " TEXT,"
+ COLUMN_TASK_CREATIONDATE + " TEXT,"
+ COLUMN_TASK_COMPLETIONDATE + " TEXT,"
+ COLUMN_TASK_PRIORITY + " TEXT,"
+ COLUMN_TASK_SHOWN + " TEXT" + ")";
db.execSQL(script);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i(TAG, "MyDatabaseHelper.onUpgrade ... ");
if (oldVersion != newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_TASK);
onCreate(db);
}
}
// Called when the database connection is being configured.
// Configure database settings for things like foreign key support, write-ahead logging, etc.
#Override
public void onConfigure(SQLiteDatabase db) {
super.onConfigure(db);
db.setForeignKeyConstraintsEnabled(true);
}
public void AddTask(Task task) {
Log.i(TAG, "MyDatabaseHelper.addTask ... ");
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COLUMN_TASK_SHORT, task.GetShortDescription());
values.put(COLUMN_TASK_FULL, task.GetFullDescription());
values.put(COLUMN_TASK_CREATIONDATE, task.GetCreatedDate().toString());
values.put(COLUMN_TASK_COMPLETIONDATE, task.GetCompletionDate().toString());
values.put(COLUMN_TASK_PRIORITY, task.GetCompletionDate().toString());
db.insert(TABLE_TASK, null, values);
db.close();
}
}
Please test your application on the real android device and check if the same problem persist and just restart the application don't re-run from android studio because android studio will re-install the application every time you re-run it resulting in the empty database.
1)Run the application on the device
2)Add the data into the database
3)Close the application
4)Remove it from recent apps.
5)Re-Run it from the menu not from the android studio.
The issue you have is not that the database is being deleted or emptied; it's because the insert will not insert any data as you are trying to insert using column FullDescription (as per values.put(COLUMN_TASK_FULL, task.GetFullDescription());). However, that column does not exist in the table (according to the create table SQL you have shown).
You either need to comment out or delete the line values.put(COLUMN_TASK_FULL, task.GetFullDescription());
or if you need the column then change
String script = "CREATE TABLE " + TABLE_TASK + "("
+ COLUMN_TASK_ID + " INTEGER PRIMARY KEY,"
+ COLUMN_TASK_SHORT + " TEXT,"
+ COLUMN_TASK_CREATIONDATE + " TEXT,"
+ COLUMN_TASK_COMPLETIONDATE + " TEXT,"
+ COLUMN_TASK_PRIORITY + " TEXT,"
+ COLUMN_TASK_SHOWN + " TEXT" + ")";
to
String script = "CREATE TABLE " + TABLE_TASK + "("
+ COLUMN_TASK_ID + " INTEGER PRIMARY KEY,"
+ COLUMN_TASK_SHORT + " TEXT,"
+ COLUMN_TASK_FULL + " TEXT,"
+ COLUMN_TASK_CREATIONDATE + " TEXT,"
+ COLUMN_TASK_COMPLETIONDATE + " TEXT,"
+ COLUMN_TASK_PRIORITY + " TEXT,"
+ COLUMN_TASK_SHOWN + " TEXT" + ")";
If you change the table's definition by adding the column you will need to rerun the App but only after doing one of the following:-
Delete the App's data
Uninstall the App
Change private static final int DATABASE_VERSION = 1; to private static final int DATABASE_VERSION = 2;
This is because the onCreate method only runs once when the database is created 1 and 2 delete the database, 3 invokes the onCreate method via the onUpgrade method
Related
Have the following error message:
Operation failed: table medicine has no column nameed amount(code1):, while compiling: INSERT INTO medicine(name,amount,type,info,registration_no)VALUES(?,?,?,?,?)
Config file:
public class Config {
public static final String COLUMN_MEDICINE_ID = "_id";
public static final String COLUMN_MEDICINE_NAME = "name";
public static final String COLUMN_MEDICINE_PRODUCT = "registration_no";
public static final String COLUMN_MEDICINE_INFO = "info";
public static final String COLUMN_MEDICINE_TYPE = "type";
public static final String COLUMN_MEDICINE_AMOUNT = "amount";
}
Helper File:
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_MEDICINE_TABLE = "CREATE TABLE " + Config.TABLE_MEDICINE + "("
+ Config.COLUMN_MEDICINE_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ Config.COLUMN_MEDICINE_NAME + " TEXT NOT NULL, "
+ Config.COLUMN_MEDICINE_PRODUCT + " INTEGER NOT NULL UNIQUE, "
+ Config.COLUMN_MEDICINE_INFO + " TEXT, " //nullable
+ Config.COLUMN_MEDICINE_TYPE + " TEXT " //nullable
+ Config.COLUMN_MEDICINE_AMOUNT + " INTEGER UNIQUE, "
+ ")";
Logger.d("Table create SQL: " + CREATE_MEDICINE_TABLE);
db.execSQL(CREATE_MEDICINE_TABLE);
Logger.d("DB created!");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + Config.TABLE_MEDICINE);
onCreate(db);
}
You forgot a comma between type and amount columns in the create SQL. Additionally there's a stray comma after the amount column def:
+ Config.COLUMN_MEDICINE_TYPE + " TEXT " //nullable
+ Config.COLUMN_MEDICINE_AMOUNT + " INTEGER UNIQUE, "
+ ")";
After fixing the SQL there, you can uninstall your app once to retrigger onCreate().
i'm still learning Android development, And i have a problem creating an sqlite database table. here is a part of my code :
`
private static final String CREATE_ADS_PICTURE = "CREATE TABLE "
+ AdsBDD.TABLE_ADS_PICTURE + "(" + AdsBDD.ID_PICS
+ " INTEGER PRIMARY KEY AUTOINCREMENT ," + AdsBDD.AD_ID
+ " INTEGER NOT NULL," + AdsBDD.PICTURE + " TEXT," + AdsBDD.FOLDER
+ " TEXT," + AdsBDD.ORDER_NO + " INTEGER NOT NULL);";
private static final String CREATE_AGENCES = "CREATE TABLE "
+ AgencesBDD.TABLE_AGENCES + "(" + AgencesBDD.ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + AgencesBDD.GROUP
+ " INTEGER," + AgencesBDD.USERNAME + " TEXT," + AgencesBDD.EMAIL
+ " TEXT," + AgencesBDD.CONTACT_NAME + " TEXT,"
+ AgencesBDD.REGISTRATION_DATE + " TEXT," + AgencesBDD.ACTIVATION
+ " TEXT," + AgencesBDD.ACTIVE + " INTEGER," + AgencesBDD.STORE
+ " INTEGER," + AgencesBDD.STORE_BANNER + " TEXT,"
+ AgencesBDD.RATING + " REAL," + AgencesBDD.LANGUAGE + " TEXT,"
+ AgencesBDD.IDENTITY + " TEXT," + AgencesBDD.ADDRESS + " TEXT,"
+ AgencesBDD.PHONE + " TEXT," + AgencesBDD.COMPANY + " TEXT,"
+ AgencesBDD.WEBPAGE + " TEXT," + AgencesBDD.CODE_POSTAL + " TEXT,"
+ AgencesBDD.JE_SUIS_UN + " TEXT," + AgencesBDD.VILLE + " TEXT,"
+ AgencesBDD.VIDEO + " TEXT);";
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_ADS_PICTURE);
db.execSQL(CREATE_AGENCES);
}
public class AgencesBDD {
public static final String TABLE_AGENCES = "agences";
public static final String ID = "id";
public static final String GROUP = "group";
public static final String USERNAME = "username";
public static final String EMAIL = "email";
public static final String CONTACT_NAME = "contact_name";
public static final String REGISTRATION_DATE = "registration_date";
public static final String ACTIVATION = "activation";
public static final String ACTIVE = "active";
public static final String STORE = "store";
public static final String STORE_BANNER = "store_banner";
public static final String RATING = "rating";
public static final String LANGUAGE = "language";
public static final String IDENTITY = "identity";
public static final String ADDRESS = "address";
public static final String PHONE = "phone";
public static final String COMPANY = "company";
public static final String WEBPAGE = "webpage";
public static final String CODE_POSTAL = "code_postal";
public static final String JE_SUIS_UN = "je_suis_un";
public static final String VILLE = "ville";
public static final String VIDEO = "video";
`
So the problem is that Sqlite throws this exception for the table AGENCES, but the Table AD_PICTURE works fine:
03-08 14:36:01.892: E/AndroidRuntime(10822): FATAL EXCEPTION: main
03-08 14:36:01.892: E/AndroidRuntime(10822): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.infonetdiffusion.immohabitation/com.infonetdiffusion.immohabitation.FragmentBaseActivity}: android.database.sqlite.SQLiteException: near "group": syntax error (code 1): , while compiling: CREATE TABLE agences(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,group INTEGER,username TEXT,email TEXT,contact_name TEXT,registration_date TEXT,activation TEXT,active INTEGER,store INTEGER,store_banner TEXT,rating REAL,language TEXT,identity TEXT,address TEXT,phone TEXT,company TEXT,webpage TEXT,code_postal TEXT,je_suis_un TEXT,ville TEXT,video TEXT);
it should be easy to fix, but i can't find where i'm wrong...
any help would be apreciated!
you are using sqlite keyword as column name i.e. group sqliteKeyword which is restrict
Drop the NOT NULL for the id column.
Read here
Those two cases are not equivalent! Note that primary key in first case doesn't have NOT NULL.
CREATE TABLE agences(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,group INTEGER,username TEXT,email TEXT,contact_name TEXT,registration_date TEXT,activation TEXT,active INTEGER,store INTEGER,store_banner TEXT,rating REAL,language TEXT,identity TEXT,address TEXT,phone TEXT,company TEXT,webpage TEXT,code_postal TEXT,je_suis_un TEXT,ville TEXT,video TEXT);
group is a key word in sql, you can't use it as a column name, change group to other strings that can't be key word in sql
When I try to submit data into the database, the app crashes.
Here are the parts of the java file concerned with creating and inserting data into the database.
My Contract.java class has the following information:
public class Contract {
public static abstract class customReminder{
public static final String TABLE_NAME = "CUSTOM_REMINDER";
public static final String ID = "ID";
public static final String TITLE = "TITLE";
public static final String DESCRIPTION = "DESCRIPTION";
public static final String DATE_TIME = "DATE_TIME";
public static final String[] REMINDER_COLUMNS = {ID, TITLE, DESCRIPTION, DATE_TIME};
}
My DBHelper.java class:
//SQLite statement for custom reminder table
public static final String CUSTOM_REMINDER_TABLE = "CREATE TABLE " + Contract.customReminder.TABLE_NAME + "("
+ Contract.customReminder.ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ Contract.customReminder.TITLE + " TEXT,"
+ Contract.customReminder.DESCRIPTION + " TEXT,"
+ Contract.customReminder.DATE_TIME + " TEXT,"
+ ");";
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CUSTOM_REMINDER_TABLE);
}
My CustumRemider.java class:
public boolean createCustomReminder(String title, String description, String dateTime){
ContentValues contentValues = new ContentValues();
contentValues.put(mAllColumns[1], title);
contentValues.put(mAllColumns[2], description);
contentValues.put(mAllColumns[3], dateTime);
long result = mDatabase.insert(Contract.customReminder.TABLE_NAME, null, contentValues);
return result != -1;
}
I downloaded the database to my PC from Android Device Monitor and opened it with SQLiteBrowser. I notice that a table android_metadata is created instead of CUSTOM_REMINDER.
CREATE TABLE android_metadata (locale TEXT)
I neither know where the query comes from nor why it does this.
You need to change
delete comma (",") after last parameter in create table query
public static final String CUSTOM_REMINDER_TABLE = "CREATE TABLE " + Contract.customReminder.TABLE_NAME + "("
+ Contract.customReminder.ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ Contract.customReminder.TITLE + " TEXT,"
+ Contract.customReminder.DESCRIPTION + " TEXT,"
+ Contract.customReminder.DATE_TIME + " TEXT"
+ ");";
instead of this
public static final String CUSTOM_REMINDER_TABLE = "CREATE TABLE " + Contract.customReminder.TABLE_NAME + "("
+ Contract.customReminder.ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ Contract.customReminder.TITLE + " TEXT,"
+ Contract.customReminder.DESCRIPTION + " TEXT,"
+ Contract.customReminder.DATE_TIME + " TEXT,"
+ ");";
I was wondering if it was possible to have my SQLHelper that extends from SQLiteOpenHelper as Singleton class.
my problem is :
To use an object which the class extends from SQLiteOpenHelper we need to pass a context which is "this" when i instantiate my class.
The fact is that i would like to use my Helper wherever i want without having to instantiate it again ...
If someone as a solution for me ilustrated with an example, that would be nice :)
thank you !
Here is the class i have for the moment and which i'd like to have as Singleton:
public class SQLHelper extends SQLiteOpenHelper {
/*
Attributs
*/
public SQLHelper(Context context){
super(context, DATABASE_NAME, null, 23);
}
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_TABLE_CATEGORIES = "CREATE TABLE " + TABLE_CATEGORIES + "(" + CATEGORY_NAME + " TEXT," + CATEGORY_ID + " INTEGER, " + CATEGORY_ID_PARENT + " INTEGER," + CATEGORY_URL_IMAGE + " TEXT" + ")" ;
String CREATE_TABLE_INFOS = "CREATE TABLE " + TABLE_INFOS + "(" + INFOS_AGE + " INTEGER," + INFOS_MAIL + " TEXT," + INFOS_DISPLAY_PRICE + " TEXT," + INFOS_TOKEN + " TEXT," + INFOS_REFRESH_TOKEN + " TEXT," + INFOS_TOKEN_EXPIRATION + " TEXT, " + INFOS_REFRESH_TOKEN_EXPIRATION + " TEXT, " + INFOS_APP_VERSION + " TEXT" + ")";
String CREATE_TABLE_ITEMS = "CREATE TABLE " + TABLE_ITEMS + "(" + ITEM_ID + " INTEGER," + ITEM_NAME + " TEXT," + ITEM_CATEGORY_ID + " INTEGER," + ITEM_PRICE + " REAL" + ")";
String CREATE_TABLE_SHOPPING_LIST = "CREATE TABLE " + TABLE_SHOPPING_LIST + "(" + SHOPPING_LIST_ID + " INTEGER," + SHOPPING_LIST_NAME + " TEXT," + SHOPPING_LIST_DATE_CREATION + " TEXT" + ")";
String CREATE_TABLE_SHOPPING_LIST_ITEMS = "CREATE TABLE " + TABLE_SHOPPING_LIST_ITEMS + "(" + SHOPPING_LIST_ITEMS_LIST_ID + " INTEGER," + SHOPPING_LIST_ITEMS_ID + " INTEGER," + SHOPPING_LIST_ITEMS_NB_ITEMS + " INTEGER," + SHOPPING_LIST_ITEMS_CHECKED + " INTEGER" + ")";
db.execSQL(CREATE_TABLE_CATEGORIES);
db.execSQL(CREATE_TABLE_INFOS);
db.execSQL(CREATE_TABLE_ITEMS);
db.execSQL(CREATE_TABLE_SHOPPING_LIST);
db.execSQL(CREATE_TABLE_SHOPPING_LIST_ITEMS);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_CATEGORIES);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_INFOS);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_ITEMS);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_SHOPPING_LIST);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_SHOPPING_LIST_ITEMS);
onCreate(db);
}
/*
Methods
*/
}
NO - In a round about way you answered your own question. Because you need to supply an argument, in this case a context, to create the SQLiteHelper the singleton pattern will not work since each time you initialize an object it must be different. Singletons work only when a single, identical object, is needed to coordinate functions across the system, not just when you only want one copy of an object.
Could you force the code such that only one copy of your SQLiteHelper exists? Sure - take a look below:
private static volatile Class mClass null;
public static Class getInstance(Context context){
if(mClass == null){
synchronized(Class.class){
if(mClass == null){
mClass = new Class(context);
}
}
}
return mClass;
}
You'd think this was a good idea at first. It looks like a legitimate way to create a singleton (though according to Effective Java there are better ways to do this like using an enum type). You will in fact get only one copy of Class initialized. The problem is that the context will be wrong in every case except the first. You don't have to be an expert on singletons to realize that's just a bad idea.
You can do something like that, but I don't think it`s a good idea:
private static DataBaseHelper instance;
private DataBaseHelper() {
super(App.getAppContext(), DB_NAME, null, 1);
this.context = context;
}
public static DataBaseHelper getInstance() {
if (instance == null) {
instance = new DataBaseHelper();
}
return instance;
}
Go for a private constructor and getInstance Method
public class SQLHelper extends SQLiteOpenHelper {
private static SQLHelper sqlHelper = null;
private SQLHelper(Context context){
super(context, DATABASE_NAME, null, 23);
}
public static SQLHelper getInstance(){
if(sqlHelper == null){
sqlHelper = new SQLHelper(context);
return sqlHelper;
}
return sqlHelper;
}
Im unsure of my problem. I am getting no such table when queriyng the second table.. these are both within the onCreate method
db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" + KEY_CBID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_NAME
+ " TEXT NOT NULL, " + KEY_RACE + " TEXT NOT NULL,"
+ KEY_CLASS + " TEXT NOT NULL," + KEY_DEITY
+ " TEXT NOT NULL," + KEY_GENDER + " TEXT NOT NULL,"
+ KEY_HEIGHT + " TEXT NOT NULL," + KEY_WEIGHT
+ " TEXT NOT NULL);");
db.execSQL("CREATE TABLE " + DATABASE_TABLE2 + " (" + KEY_CSID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_SKILL
+ " TEXT NOT NULL, " + KEY_CBID + " INTEGER PRIMARY KEY FOREIGN KEY);"
);
Edit: showing cvs
String skill = "blah test";
Cursor c = ourDatabase.rawQuery("SELECT " + KEY_CBID + " FROM " + DATABASE_TABLE + " order by " + KEY_CBID + " DESC limit 1", null);
if (c != null)
{
c.moveToFirst();
cbid = c.getInt(0);
}
ContentValues cv = new ContentValues();
cv.put(KEY_SKILL, skill);
cv.put(KEY_CBID, cbid);
return ourDatabase.insert(DATABASE_TABLE2, null, cv);
My select statements is:
Cursor c = ourDatabase.rawQuery("SELECT " + KEY_SKILL + ", " + KEY_NAME + ", " + KEY_CBID + " FROM " + DATABASE_TABLE + ", " + DATABASE_TABLE2 + " WHERE " + DATABASE_TABLE +"."+KEY_CBID+" = " +DATABASE_TABLE2+"."+KEY_CBID+" && " +DATABASE_TABLE+"."+KEY_NAME+" = '"+item+"'", null);
I don't believe that your second table is being created, here is how to declare a table with a foreign key:
CREATE TABLE artist(
artistid INTEGER PRIMARY KEY,
artistname TEXT
);
CREATE TABLE track(
trackid INTEGER,
trackname TEXT,
trackartist INTEGER,
FOREIGN KEY(trackartist) REFERENCES artist(artistid)
);
I took these from SQLite.org.
Also foreign keys are disabled by default in SQLite, for Android use:
db.execSQL("PRAGMA FOREIGN_KEYS=ON;");
before inserting data, if you haven't already;
check you log cat to see if there is an error while creating the second table.
If there is an error from sqllite, it will be logged in logcat
When a new table is added to DB, make sure DB is upgraded
IF from your code if you are calling db.open , if the database is already created it will be open. So in this case the code to create new table will not be hit. So you have to make sure that you upgrade the database where you can delete all your existing tables and create again
#Override
public void onCreate(SQLiteDatabase db) {
createAllTables(db);
Log.v(DBTAG, "DATABASE CREATED");
// Toast.makeText(mCtx, "created", Toast.LENGTH_SHORT).show();
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(DBTAG, "Upgrading database from version " + oldVersion
+ " to " + newVersion + ", which will destroy all old data");
dropExistingTables(db);
onCreate(db);
}
private void dropExistingTables(SQLiteDatabase db) {
for (int i = 0; i < Utils.getDropTableQueries().size(); i++) {
db.execSQL(Utils.getDropTableQueries().get(i));
}
}
Thus to conclude make sure you are creating the table, and that no error while creating.