No such table: table1 error when copying database from assets

1k views Asked by At

I'm having a database stored in assets/databases named myDatabase.db and I want to copy it to the internal storage using the code in here:

public class DatabaseOpener extends SQLiteOpenHelper {

private static String DB_PATH;

private static String DB_NAME = "table1.db";

private static int DB_VERSION = 4;

private SQLiteDatabase myDataBase;

private static Context myContext;

private static DatabaseOpener instance;

private DatabaseOpener(Context context) {
    super(context, DB_NAME, null, DB_VERSION);
    this.myContext = context;
}

public static synchronized DatabaseOpener getInstance(Context context) {
    if (instance==null) {
        instance = new DatabaseOpener(context);
    }

    if(Build.VERSION.SDK_INT >= 4.2) {
        DB_PATH = myContext.getApplicationInfo().dataDir + "/databases/";
    } else {
        DB_PATH = "/data/data/" + myContext.getPackageName() + "/databases/";
    }
    return instance;
}

public void createDataBase() throws IOException {
    boolean dbExist = checkDataBase();
    if(dbExist) {

    } else {
        this.getReadableDatabase();
        try {
            copyDataBase();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

private boolean checkDataBase(){
    SQLiteDatabase checkDB = null;
    try{
        String myPath = DB_PATH + DB_NAME;
        File file = new File(myPath);
        if (file.exists() && !file.isDirectory()) {
            checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
        }
    }catch(SQLiteException e){
        e.printStackTrace();
    }

    if(checkDB != null){
        checkDB.close();
    }

    return checkDB != null ? true : false;
}

private void copyDataBase() throws IOException{
    //Open your local db as the input stream
    InputStream myInput = myContext.getAssets().open(DB_NAME);

    // Path to the just created empty db
    String outFileName = DB_PATH + DB_NAME;

    //Open the empty db as the output stream
    OutputStream myOutput = new FileOutputStream(outFileName);

    //transfer bytes from the inputfile to the outputfile
    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer))>0){
        myOutput.write(buffer, 0, length);
    }

    //Close the streams
    myOutput.flush();
    myOutput.close();
    myInput.close();
}

public void openDataBase() throws SQLException {
    String myPath = DB_PATH + DB_NAME;
    File file = new File(myPath);
    if (file.exists() && !file.isDirectory()) {
        myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
    }
}

@Override
public synchronized void close() {
    if(myDataBase != null)
        myDataBase.close();

    super.close();
}

@Override
public void onCreate(SQLiteDatabase db) {

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

}

The above code worked successfully until i uninstalled my application. The problem is the database is not copying successfully. The file I have is alright, but when it's copied into the path, if I take it and open it in DB Browser, it has no tables. If I push it into the emulator, it works again, but I can't push it into an unrooted device. The only way is to create a DB file at the path and copy the one from assets. So, what am I doing wrong? Also, this is how I call the DatabaseOpener class:

    DatabaseOpener db = DatabaseOpener.getInstance(context);
    try {
        db.createDataBase();
    } catch (IOException e) {
        throw new Error ("Unable to create database");
    }
    try {
        db.openDataBase();
    }catch(SQLException sqle){
        throw sqle;
    }

    Object object = db.getObjectByName(name);

    db.close();
    return object;

EDIT: the error I'm receiving is android.database.sqlite.SQLiteException: no such table: table1 (code 1): , while compiling.

2

There are 2 answers

0
Andrei Zamfir On BEST ANSWER

I solved the problem with the following code:

public DatabaseOpener(Context context) throws IOException {
    super(context, DB_NAME, null, DB_VERSION);
    this.myContext = context;

    if (Build.VERSION.SDK_INT >= 4.2) {
        DB_PATH = myContext.getApplicationInfo().dataDir + "/databases/";
    } else {
        DB_PATH = "/data/data/" + myContext.getPackageName() + "/databases/";
    }

    boolean dbexist = checkDataBase();
    if (dbexist) {
        openDataBase();
    } else {
        System.out.println("Database doesn't exist");
        createDataBase();
    }
}

public void createDataBase() throws IOException {
    boolean dbexist = checkDataBase();
    if (dbexist) {
        // System.out.println(" Database exists.");
    } else {
        this.getReadableDatabase();
        try {
            copyDataBase();
        } catch (IOException e) {
            throw new Error("Error copying database");
        }
    }
}

private boolean checkDataBase() {
    boolean checkdb = false;
    try {
        String myPath = DB_PATH + DB_NAME;
        File dbfile = new File(myPath);
        checkdb = dbfile.exists();
    } catch (SQLiteException e) {
        System.out.println("Database doesn't exist");
    }
    return checkdb;
}

private void copyDataBase() throws IOException {
    // Open your local db as the input stream
    InputStream myinput = myContext.getAssets().open("databases/" + DB_NAME);

    // Path to the just created empty db
    String outfilename = DB_PATH + DB_NAME;

    // Open the empty db as the output stream
    OutputStream myoutput = new FileOutputStream(DB_PATH + DB_NAME);

    // transfer byte to inputfile to outputfile
    byte[] buffer = new byte[1024];
    int length;
    while ((length = myinput.read(buffer)) > 0) {
        myoutput.write(buffer, 0, length);
    }

    // Close the streams
    myoutput.flush();
    myoutput.close();
    myinput.close();
}

public void openDataBase() throws SQLException {
    // Open the database
    String mypath = DB_PATH + DB_NAME;
    myDataBase = SQLiteDatabase.openDatabase(mypath, null, SQLiteDatabase.OPEN_READWRITE);
}

@Override
public synchronized void close() {
    if (myDataBase != null)
        myDataBase.close();

    super.close();
}
0
Tulsi On

Once you uninstalled the application android deletes all the local data storage related to the application hence SQLDatabase will be destroyed.

And when you reinstall the application you are before creation of the table trying to access it hence throw an error. Make sure you create the table before manipulate its data.

You need to write in onCreate(SQLiteDatabase db)

db.execSQL(CREATE_TABLE_QUERY);