SQLite onUpgrade()受挫

时间:2016-05-07 23:19:54

标签: java android sqlite android-sqlite sqliteopenhelper

我正在使用预先填充的数据库。在Mozilla中使用SQLite Manager,现在我有一个虚拟数据库,只是想测试onUpgrade方法,所以我在其中一个列中更改了一个字符串,将其导出为一个新的数据库,并且你将在我的数据库中看到代码,试图打开新更新的版本。同样重要的是,我在代码中手动更新版本号

private static final int DB_VERSION = 3;

并在onUpgrade中

if (newVersion == 3) {
        Log.e("WORKED!!", "onUpgrade executed");

所以,下次我将这两个数字更新为4.不确定我是否正确行事或错误但我收到了日志消息,只是没有看到数据更新在应用程序中。

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.util.Log;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;


public class DataBaseHelper extends SQLiteOpenHelper {
    private static String DB_PATH;
    private static final String DB_NAME = "DummyTestOne.sqlite";
    private static final int DB_VERSION = 3;
    private static final String DB_NAME2 = "DummyTestFive.sqlite";
    private SQLiteDatabase mDataBase;
    private final Context mContext;

public static final String DBTABLENAME = "questiontable";
public static final String DBATABLENAME = "answertable";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_NAME = "question";
public static final String COLUMN_CATEGORY = "category";
public static final String COLUMN_FID = "fid";

public static final String COLUMN_ANSWER = "answer";

public DataBaseHelper(Context context) {
    super(context, DB_NAME, null, DB_VERSION);
    this.mContext = context;

    DB_PATH = context.getDatabasePath(DB_NAME).getPath();


}

public void createDataBase() {
    boolean dbExist = checkDataBase();

    if (dbExist) {

    } else {
        this.getReadableDatabase();
        try {
            copyDataBase();
        } catch (IOException e) {
            throw new Error("Error copying database");
        }
    }
}

private boolean checkDataBase() {
    SQLiteDatabase checkDB = null;

    try {
        checkDB = SQLiteDatabase.openDatabase(DB_PATH, null, SQLiteDatabase.OPEN_READWRITE);
    } catch (SQLiteException e) {
        Log.e(this.getClass().toString(), "Error while checking db");
    }

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

    return checkDB != null ? true : false;
}

private void copyDataBase() throws IOException {
    InputStream externalDbStream = mContext.getAssets().open(DB_NAME);
    OutputStream localDbStream = new FileOutputStream(DB_PATH);

    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = externalDbStream.read(buffer)) > 0) {
        localDbStream.write(buffer, 0, bytesRead);
    }


    localDbStream.flush();
    localDbStream.close();
    externalDbStream.close();
}

public void openDataBase() throws SQLException {


    mDataBase = this.getWritableDatabase();

}

@Override
public synchronized void close() {
    if (mDataBase != null) {
        mDataBase.close();
    }
    super.close();
}

public Cursor getCursorForAllQs() {
    SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
    queryBuilder.setTables(DBTABLENAME);

    String[] asColumnsToReturn = new String[]{COLUMN_ID, COLUMN_NAME, COLUMN_CATEGORY, COLUMN_FID};

    Cursor mCursor = queryBuilder.query(mDataBase, asColumnsToReturn, null,
            null, null, null, "_id");

    return mCursor;
}

public List<String> getAnswersForQ(int questionFid) {
    List<String> answers = new ArrayList<>();
    SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
    queryBuilder.setTables(DBATABLENAME);
    String[] tableColumns = new String[]{DataBaseHelper.COLUMN_ANSWER};
    String where = "fid = ?";
    String[] selectionArgs = new String[]{String.valueOf(questionFid)};
    String orderBy = DataBaseHelper.COLUMN_ID;


    Cursor c = queryBuilder.query(mDataBase, tableColumns, where, selectionArgs, null, null, orderBy);
    if (c.moveToFirst()) {
        do {
            try{
                answers.add(c.getString(c.getColumnIndex(DataBaseHelper.COLUMN_ANSWER)));
            } catch (Exception e) {
                Log.e("FAILED", c.getString((c.getColumnIndex(DataBaseHelper.COLUMN_ANSWER))));
            }

        } while (c.moveToNext());
    }
    Log.d("getAnswersForQ", answers.toString());
    return answers;

}

public String getName(Cursor c) {
    return (c.getString(1));
}



@Override
public void onCreate(SQLiteDatabase db) {

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    if (newVersion == 3) {
        Log.e("WORKED!!", "onUpgrade executed");
    }
    if (newVersion > oldVersion) {
        InputStream inputStream = null;
        OutputStream outputStream = null;
        String dbFilePath = DB_PATH + DB_NAME;


        try {
            inputStream = mContext.getAssets().open(DB_NAME2);

            outputStream = new FileOutputStream(dbFilePath);

            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) > 0) {
                outputStream.write(buffer, 0, length);
            }

            outputStream.flush();
            outputStream.close();
            inputStream.close();
        } catch (IOException e) {
            throw new Error("Problem copying database from resource file.");
        }
    }
}
}

1 个答案:

答案 0 :(得分:2)

升级数据库意味着将其更改到位,同时尽可能保持旧数据的完整性。 因此,如果要添加或重命名列,则必须执行正确的SQL命令才能在onUpgrade回调中执行此操作。

(注意:SQLiteAssetHelper使预填充数据库更容易使用,您应该使用它,但升级仍需要单独的SQL脚本。)

如果您不关心旧数据库的内容,则不应升级它。只需为新数据库版本提供一个新文件名,以便将其简单复制并删除旧文件。