В большинстве случаев, для этого рекомендуют или дропать таблицы(если данные не критичны) и пересоздавать их, или же писать тонны кода в методе onUpgrade с ALTER TABLE, что как раз мне показалось несколько мерзким :) Если вы работаете в большом проекте, который будет в поддержке не один месяц, год, то спустя какое-то время onUpgrade превратится в сущий ад, километрового кода. Т.е. нужно более компромиссное решение, не сильно напрягающее по написанию кода и позволяющее спокойно отследить версию базы и в какой версии, что было изменено. По этому лучшим решением было написание скрипта для этого дела и парсера для него.
Особо в детали кода вдаваться не буду, код вы можете посмотреть и сами. Пройдусь по главным моментам моего решения.
Все решение заключено в классе SQLiteMergerHelper и скрипте находящемся в assets - dbscript.txt(создается в ручную)
Для начала объявление в onUpgrade. Для этого нам понадобиться одна строчка кода
@Override
public void onUpgrade(final SQLiteDatabase db, int oldVersion, int newVersion) {
SQLiteMergerHelper.getInstance().readScript(context,db,DATABASE_VERSION);
}
Ну, а далее вся нагрузка переходит на скрипт, по командам которого мы сейчас пройдемся.(Команды и параметры разбиваются символом ":")
1. VERSION: - первая команда, для идентификации версии базы. Т.к. пользователь может загрузить ваше приложение, потом забить на пару месяцев на него и потом проапдейтить, приложение сразу упадет если мы последовательно не применим все предыдущие изменения в базе, в конечном итоге выйдя на текущую версию. После команды указываем для какой версии базы актуальны изменения.
VERSION:
2
2. ADD_COLUMNS: - команда для добавления поля в таблицу. В параметры передаем
"название таблицы: название поля тип"
ADD_COLUMNS:
messages:test_id INTEGER
3. DROP_COLUMNS: - команда для удаления поля из таблицы. Тут параметром будет SQL запрос создания таблицы, из запроса мы исключаем поле от которого нужно избавиться. Второй параметр - имя таблицы, из которой данные будут копированы. Третим - через запятую, название полей которые будем удалять.
"SQL-запрос без поля: название таблицы: название полей для удаления через запятую"
DROP_COLUMNS:
CREATE TABLE message(_id...):message:test_id,is_deleted
4. RENAME_TABLE: - по названию сразу понятно что она делает :)
"текущее название таблицы: желаемое название таблицы"
RENAME_TABLE:
message:message2
5. OTHER_QUERY: - команда для исполнения любых SQL-запросов. Этой командой я пользовался не часто, но дело было.
OTHER_QUERY:
CREATE TABLE message (_id INTEGER PRIMARY KEY, name TEXT,message TEXT)
Вот и все команды на текущий момент. Для наглядности, вся поддержка версионности базы превращается в несколько строчек в скрипте.
И так, я избавился от кучи говнокода и проблемой слияния, что желаю и вам :)
Исходник класса я выложил на github в процессе я его еще доработаю и сделаю проект-пример.
Исходник класса я выложил на github в процессе я его еще доработаю и сделаю проект-пример.
Всех с прошедшими праздниками! Не пыльного кода и интересных проектов!
Комментариев нет :
Отправить комментарий