База данных sqlite.Обновление без потери данных - PullRequest
0 голосов
/ 18 декабря 2018

Есть таблица со столбцами: идентификатор, заголовок, стихотворение, годы, избранное.Таким образом, в избранное добавляется 1 или 0, по умолчанию 0, оно меняется, если пользователь добавляет строку в Избранное.Проблема в том, что если я обновлю базу данных (добавлю больше строк), все избранное исчезнет у пользователя.На просторах SO я нашел решение - прикрепить старую и обновленную базу данных.Я увеличиваю версию, добавляю базу данных в проект.В приложении все останется как было.Избранное сохранено, но новые не добавлены.

 public class PoemsDbHelper extends SQLiteOpenHelper {
        private static String DB_NAME = "brodsky.db";
        private static String DB_PATH = "";
        private static final int DB_VERSION = 8;

        private SQLiteDatabase db;
        private final Context context;
        private boolean needUpdate = false;

        public PoemsDbHelper(Context context) {
            super(context, DB_NAME, null, DB_VERSION);
            if (android.os.Build.VERSION.SDK_INT >= 17)
                DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
            else
                DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
            this.context = context;

            copyDataBase();

            this.getReadableDatabase();
        }

        public void updateDataBase() throws IOException {
            if (needUpdate) {
                File dbFile = new File(DB_PATH + DB_NAME);
                if (dbFile.exists()) {
                    //   dbFile.delete();
                    //   copyDataBase();
                    openDataBase();
                    db.execSQL("ATTACH DATABASE '" + DB_PATH + File.separator + DB_NAME + "' AS Old_DB");
                    db.execSQL("INSERT OR IGNORE INTO poems_table (favorite) SELECT id, title, poem, subject, years FROM Old_DB.poems_table;");

                    }
            }
            needUpdate = false;
        }

        private boolean checkDataBase() {
            File dbFile = new File(DB_PATH + DB_NAME);
            return dbFile.exists();
        }

        private void copyDataBase() {
            if (!checkDataBase()) {
                this.getReadableDatabase();
                this.close();
                try {
                    copyDBFile();
                } catch (IOException mIOException) {
                    throw new Error("ErrorCopyingDataBase");
                }
            }
        }

        private void copyDBFile() throws IOException {
            InputStream input = context.getAssets().open(DB_NAME);
            OutputStream output = new FileOutputStream(DB_PATH + DB_NAME);
            byte[] buffer = new byte[1024];
            int length;
            while ((length = input.read(buffer)) > 0)
                output.write(buffer, 0, length);
            output.flush();
            output.close();
            input.close();
        }

        public boolean openDataBase() throws SQLException {
            db = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.CREATE_IF_NECESSARY);
            return db != null;
        }

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

        @Override
        public void onCreate(SQLiteDatabase db) {

        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            if (newVersion > oldVersion) {
                needUpdate = true;

          }
       }
    }



 public class PoemsProvider extends ContentProvider {
 @Override
    public boolean onCreate() {
        poemsDbHelper = new PoemsDbHelper(getContext());
        try {
            poemsDbHelper.updateDataBase();
        } catch (IOException mIOException) {
            throw new Error("UnableToUpdateDatabase");
        }

        return true;
    }
}

1 Ответ

0 голосов
/ 18 декабря 2018

Ваша проблема в том, что вы перезаписываете базу данных, а не имеете две отдельные копии старой и обновленной базы данных.По сути, вы присоединяете базу данных к себе.

Решение уже предоставлено на Обновление БД.Библиотека Sqlite-asset-helper

Решение использует вторичную базу данных (копирует обновленную базу данных из папки активов) и пытается скопировать строки из обновленной базы данных в исходную базу данных, не копируя (пропуская)строки, если они уже существуют.Строки, добавленные приложением (в отличие от строк, загруженных с внешней базой данных), остаются в исходной базе данных.

...