1

After Deleting folder programmatically which contain Database , when next time Insert query called , It's returning -1.I think solution is creating database again by calling database constructor.But i don't know how to doing it inside Fragment.

Data Base Class:

public class SQliteHelperClass  extends SQLiteOpenHelper {
    public static final String Dabase_name= "UserRecord.db";
    public static final String Table_name= "RTable";
    public static final String col_0= "Id";
    public static final String col_1= "KM";
    public static final String col_2= "MDATE";
    public static final String col_3= "MTIME";
    public static final String col_4= "MDIFFER";


    public SQliteHelperClass(Context context) {
        super(context, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
                + File.separator+"MyCarData"
                + File.separator +  Dabase_name, null, 1);

    }

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("CREATE TABLE "+ Table_name +"(Id INTEGER PRIMARY KEY AUTOINCREMENT, KM INTEGER, MDATE TEXT, MTIME TEXT , MDIFFER INTEGER) ");

}

public boolean insertData(KmDataModel kmDataModel) {
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues contentValues = new ContentValues();
    contentValues.put(col_0,kmDataModel.getId());
    contentValues.put(col_1,kmDataModel.getKm());
    contentValues.put(col_2,kmDataModel.getDate());
    contentValues.put(col_3,kmDataModel.getTime());
    contentValues.put(col_4,kmDataModel.getDffKm());
    long result =db.insert(Table_name,null,contentValues);
    if(result == -1){
        return false;
    }else{
        return true;
    }
}

}

Delete method which call for deleting Contain of specific folder:

public void DeleteDataFolder(){
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
        + File.separator+"MyCarData"
        + File.separator);
if (dir.isDirectory())
{
    String[] children = dir.list();
    for (int i = 0; i < children.length; i++)
    {

        Log.e("File_List",children[i]);
        new File(dir, children[i]).delete();
    }
}
}

Note that if I close app and start it again then database working fine, so i was calling method which is force app to close but i don't want to close the app.

earthling
  • 147
  • 16
  • This is expected. You are deleting the database file. Insert will return -1 if the execution fails which is ought to happen here as the file does not exist. – Umang Feb 23 '19 at 04:38
  • I can understand that but what can i do to create database again before inserting data – earthling Feb 23 '19 at 04:43
  • Ideally you should not be deleting the database file, if you really want to do that make sure you check the table exists before inserting. If the table does not exist create it and then proceed to insert. – Umang Feb 23 '19 at 04:50
  • boolean tableExists(SQLiteDatabase db, final String tableName) { Cursor cursor = null; try { cursor = db.rawQuery( "select DISTINCT tbl_name from sqlite_master where tbl_name = '" + tableName + "'", null); return (cursor != null && cursor.getCount() > 0); } finally { if (null != cursor) { cursor.close(); } } } – Umang Feb 23 '19 at 04:50
  • use the able snippet to check whether the table exists or not – Umang Feb 23 '19 at 04:50
  • Table not exists – earthling Feb 23 '19 at 04:54
  • @Umang there is not single quary for delete database in sqlite, In mysql there is command like "Drop" but not in sqlite so by deleting folder contain i m trying to achieve same result as drop – earthling Feb 23 '19 at 04:59

1 Answers1

0

Your thought, that you need to re-create/create another instance of the database helper is correct.

So refresh the exisitng instance e.g. myInstanceOfDBHelper = new SQliteHelperClass(context)

  • where context needs to be a valid context

If you don't then you will get something along the lines of the following in the log :-

2019-02-23 16:15:32.049 31038-31038/abc.so54838140sqlitealtfilelocation D/DBINSERT: Attempt # 1 at inserting into DB
2019-02-23 16:15:32.070 31038-31038/abc.so54838140sqlitealtfilelocation E/File_List: UserRecord.db
2019-02-23 16:15:32.070 31038-31038/abc.so54838140sqlitealtfilelocation E/File_List: UserRecord.db-wal
2019-02-23 16:15:32.071 31038-31038/abc.so54838140sqlitealtfilelocation E/File_List: UserRecord.db-shm
2019-02-23 16:15:32.071 31038-31038/abc.so54838140sqlitealtfilelocation D/DBINSERT: Attempt # 2 at inserting into DB
2019-02-23 16:15:32.074 31038-31038/abc.so54838140sqlitealtfilelocation E/SQLiteDatabase: Error inserting MDIFFER=30 KM=100 Id=1 MTIME=10:30 MDATE=2019-01-01
    android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: RTable.Id (code 1555 SQLITE_CONSTRAINT_PRIMARYKEY)
        at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
        at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:796)
        at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
        at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
        at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1564)
        at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1433)
        at abc.so54838140sqlitealtfilelocation.SQliteHelperClass.insertData(SQliteHelperClass.java:48)
        at abc.so54838140sqlitealtfilelocation.MainActivity.onCreate(MainActivity.java:30)
        at android.app.Activity.performCreate(Activity.java:7136)
        at android.app.Activity.performCreate(Activity.java:7127)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

You may wonder how you are getting a duplicate after deleting, it is probably that the old connection is allowing access to cached data

The following code was used for the above :-

  • your SQliteHelperClass (slightly modified to output the insert attempt #)
  • an approximation of your KmDataModel class, and
  • an invoking activity (easier to code)

The activity code being :-

public class MainActivity extends AppCompatActivity {

    SQliteHelperClass mDBHlpr;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if(Build.VERSION.SDK_INT >= 23) {
            ExternalStoragePermissions.verifyStoragePermissions(this);
        }

        mDBHlpr = new SQliteHelperClass(this); //<<<<<<<<<< original instantiation
        KmDataModel k = new KmDataModel();
        k.setId(1);
        k.setKm(100);
        k.setDate("2019-01-01");
        k.setTime("10:30");
        k.setDffKm(30);
        mDBHlpr.insertData(k,1);
        mDBHlpr.DeleteDataFolder();
        // If not commeneted out line below will re-instantiate the DB helper
        //mDBHlpr = new SQliteHelperClass(this); //<<<<<<<<<< COMMENTED OUT TO FAIL
        mDBHlpr.insertData(k,2);
    }
}
  • with the line commented out not commented out the above works. = so all you need to do is apply the above within your fragment, which will require getting a suitable context. If you have difficulties getting the context then Using context in a fragment may help.

With the re-instantiation the log after running is :-

2019-02-23 16:19:39.179 31176-31176/abc.so54838140sqlitealtfilelocation D/DBINSERT: Attempt # 1 at inserting into DB
2019-02-23 16:19:39.200 31176-31176/abc.so54838140sqlitealtfilelocation E/File_List: UserRecord.db
2019-02-23 16:19:39.200 31176-31176/abc.so54838140sqlitealtfilelocation E/File_List: UserRecord.db-wal
2019-02-23 16:19:39.200 31176-31176/abc.so54838140sqlitealtfilelocation E/File_List: UserRecord.db-shm
2019-02-23 16:19:39.202 31176-31176/abc.so54838140sqlitealtfilelocation D/DBINSERT: Attempt # 2 at inserting into DB
2019-02-23 16:19:39.239 31176-31176/abc.so54838140sqlitealtfilelocation D/OpenGLRenderer: Skia GL Pipeline
MikeT
  • 51,415
  • 16
  • 49
  • 68