开发者

Re-creating tables in SQLite

While implementing the save-/loadfunction of my database, I dropped the tables to see if my app can handle the creation of the tables if necessary - well it can't

So in the onCreate of my testactivity, I create an instance of DB which creates in it's constructor an instance of DBOpenHelper. Basically when the DBOpenHelper instance calls getWritableDatabase() DBOpenHelper's onCreate should be executed, creating the tables in my database. I think the problem is, that getWritableDatabase() doesn't get called, because the Database itself already exists - think I've read something like this method absorbed the function of openOrCreateDatabase.

How can I make sure, that the tables are recreated if not existing without having to delete and recreate the database everytime?

DBOpenhelper:

public class DBOpenHelper extends SQLiteOpenHelper {

public static final int DATABASE_VERSION = 1;
public static String DATABASE_NAME = "RTDB";
public static final String DB_TABLE_NAME1 = "playertable";
public static final String DB_TABLE_NAME2 = "itemtable";
public static String TAG = "openhelper";
private static final String DB_CREATE_TABLE_PT = "CREATE TABLE IF NOT EXISTS "
        + DB_TABLE_NAME1
        + " ("
        + "ID INT(2) PRIMARY KEY AUTOINCREMENT,"
        + "Name VARCHAR(30) ,"
        + "HP INT(3) ,"
        + "Satisfaction INT(3) ,"
        + "Hygiene INT(1) , " + "IsAlive INT(1) " + " )";

private static final String DB_CREATE_TABLE_IT = "CREATE TABLE IF NOT EXISTS "
        + DB_TABLE_NAME2
        + " ("
        + "Money INT(3) ,"
        + "Gas INT(3) ,"
        + "Food INT(3) ,"
        + "Toiletries INT(3) ,"
        + "Spareparts INT(3) ,"
        + "Meds INT(3) ,"
        + "Tents INT(3) ,"
        + "Ration INT(1) ,"
        + "Trabbihp INT(3) ," + "Trabbispeed INT(2)" + " )";

public DBOpenHelper(Context context, String databaseName) {
    super(context, databaseName, null, DATABASE_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {
    Log.d("TAG", "PT :" + DB_CREATE_TABLE_PT);
    db.execSQL(DB_CREATE_TABLE_PT);
    Log.d(TAG, "PT create" + DB_CREATE_TABLE_PT);
    db.execSQL(DB_CREATE_TABLE_IT);
    Log.d(TAG, "IT create" + DB_CREATE_TABLE_IT);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE_NAME1);
    db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE_NAME2);
    onCreate(db);
}

}

DB:

public class DB {

private Context context;
private SQLiteDatabase db;
private static String TAG = "save";
private static ContentValues itemValues = new ContentValues();
private static ContentValues playerValues = new ContentValues();

public DB(Context context) {
    this.context = context;
    DBOpenHelper dbHelper = new DBOpenHelper(this.context, "RTDB");
    this.db = dbHelper.getWritableDatabase();
}

public void savePlayer(Player player[]) {

    for (int i = 0; i <= 3; i++) {

        playerValues.put("Name", player[i].getName());
        playerValues.put("HP", player[i].getHp());
        playerValues.put("Satisfaction", player[i].getsatisfaction());
        playerValues.put("Hygiene", player[i].isHygieneInt());
        playerValues.put("IsAlive", player[i].isAliveInt());

    }
    db.insert("playertable", null, playerValues);
}

// Speichern der Items
// TODO Position fehlt noch
public void saveItems() {
    itemValues.put("Money", Resource.money);
    itemValues.put("Gas", Resource.gas);
    itemValues.put("Food", Resource.food);
    itemValues.put("Toiletries", Resource.toiletries);
    itemValues.put("Spareparts", Resource.spareparts);
    itemValues.put("Meds", Resource.meds);
    itemValues.put("Tents", Resource.tents);
    itemValues.put("Ration", Resource.ration);
    itemValu开发者_C百科es.put("Trabbihp", Resource.trabbihp);
    itemValues.put("Trabbispeed", Resource.trabbispeed);

    db.insert("itemtable", null, itemValues);
}

// Hier werden die Items aus der Datenbank abgefragt, der zurueckgelieferte
// Cursor vie cursorToIntArray() in einen Int Array umgewandelt und dessen
// Inhalt in die Ressource Klasse geschrieben
public void loadItems() {
    Cursor itemCursor = db.query("itemtable", null, null, null, null, null,
            null);
    int[] itemIntArray = cursorToInt(itemCursor, 9);

    Resource.money = itemIntArray[0];
    Resource.gas = itemIntArray[1];
    Resource.food = itemIntArray[2];
    Resource.toiletries = itemIntArray[3];
    Resource.meds = itemIntArray[4];
    Resource.tents = itemIntArray[5];
    Resource.ration = itemIntArray[6];
    Resource.trabbihp = itemIntArray[7];
    Resource.trabbispeed = itemIntArray[8];
}

// Name und Restliche Int-Werte der Playerobjekte werden separat aus der
// Datenbank geholt und gesetzt
public void loadPlayer() {
    String[] namecolumn = { "Name" };
    String[] intcolumn = { "ID, Name, HP, Satisfaction, Hygiene, IsAlive" };
    String[] namesToString = new String[4];

    Cursor playerCursor = db.query("playertable", intcolumn, null, null,
            null, null, "ID");
    playerCursor.moveToPosition(-1);
    int i = 0;
    while (i <= 3) {
        playerCursor.moveToNext();
        String temp = playerCursor.getString(1);
        Resource.playerArray[i].setName(temp);
        int tempint = playerCursor.getInt(2);
        Resource.playerArray[i].setHp(tempint);
        tempint = playerCursor.getInt(3);
        Resource.playerArray[i].setsatisfaction(tempint);
        tempint = playerCursor.getInt(4);
        Resource.playerArray[i].setHygieneInt(tempint);
        tempint = playerCursor.getInt(5);
        Resource.playerArray[i].setAliveInt(tempint);
        i++;

    }
}

public void dropTables() {
    db.execSQL("DROP TABLE 'playertable';");
    db.execSQL("DROP TABLE 'itemtable';");
}

private int[] cursorToInt(Cursor cursor, int n) {
    int[] results = new int[n];
    for (int i = 0; i <= n - 1; i++) {
        results[i] = cursor.getInt(i + 1);
    }

    return results;
}

private String[] cursorToString(Cursor cursor) {
    String[] results = new String[4];
    int columnIndex = cursor.getColumnIndex("Name");
    for (int i = 0; i <= 3; i++) {
        results[i] = cursor.getString(columnIndex);
    }

    return results;
}

}

Testactivity onCreate instancing DB:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    this.myDB = new DB(this);
    initUI();
    testcase1();


Not sure your description of how getWritableDatabase functions is correct: looking at your code you appear to be doing the right thing, as I use a very similar structure in many deployed apps without any errors. It correctly handles creating/upgrading all tables, regardless of whether or not they exist or the database exists. You might want to try making DBOpenHelper a static class: that works for me. Alternatively check your logs carefully: if there's some other exception taking place that may not appear related at first glance then that might point you towards a solution.

EDIT: Try private static class DBOpenHelper extends SQLiteOpenHelper. What I'd also suggest is changing the database version to force the onUpgrade method to be called. In general the case where you've dropped tables but the file exists would need you to call into the information schema to check if the database file has the tables defined. onCreate only gets called if the file doesn't exist, and onUpdate only gets called if you change the database version.

EDIT: see http://www.sqlite.org/faq.html#q7 for more detail on using the information schema table to check if your table exists. You can just run a query against the SQLITE_MASTER table and then if you can't find a particular table run the CREATE statement.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜