@ArtBigTema

ActiveAndroid, как добавить поле(column) без потери данных?

На сайте написано, что надо поднять версию БД (AA_DB_VERSION), но толку нет, при save() существующего экземпляра класса, приложение падает.
Кто пользуется этим ORM, как вы обновляете, добавляете поля?
  • Вопрос задан
  • 177 просмотров
Пригласить эксперта
Ответы на вопрос 2
@z0rgoyok
ActiveAndroid хорошо добавляет новые таблицы, но не поля, поля надо миграциями. Для автоматизации делал такой вот костыль:
public void upgrade(Context context) {
        //надо найти файл с описанием прошлой базы
        //в ней есть версия
        /*если новая версия больше - посмотреть какие поля есть в моделях, которых нет в файле описания
                если такие есть - добавить
                создать новый файл описания*/

        String path = context.getFilesDir().getAbsolutePath() + "/db_version.txt";
        File file = new File(path);

        int lastDBVersion = -1;
        boolean needCreateFile = false;
        boolean needApplyUpdates = false;
        List<String> savedFields = null;

        //файл существует
        if (file.exists()) {
            BufferedReader br = null;
            try {
                br = new BufferedReader(new FileReader(file));
                String line = br.readLine();
                lastDBVersion = Integer.parseInt(line);
            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                try {
                    if (br != null) {
                        br.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } else {
            //
            needApplyUpdates = true;
        }

        //костыль при переходе на версию
        //boolean needChangeEventTypeValue = false;
        //dbVersion += 1;

        if (lastDBVersion != -1 && lastDBVersion < dbVersion) {
            needApplyUpdates = true;
        }

        if (needApplyUpdates) {

            //читаем старый список
            savedFields = new ArrayList<>();

            //создаем список из полей в бд
            for (Class classModel : models) {
                String tableName = getTableName(classModel);

                Cursor cursor = ActiveAndroid.getDatabase().rawQuery("PRAGMA table_info(" + tableName + ")", null);
                try {
                    int nameIdx = cursor.getColumnIndexOrThrow("name");
                    int typeIdx = cursor.getColumnIndexOrThrow("type");
                    while (cursor.moveToNext()) {
                        String type = cursor.getString(typeIdx);
                        String name = cursor.getString(nameIdx);
                        savedFields.add(tableName + "." + name + "." + type);
                    }
                } finally {
                    cursor.close();
                }
            }

            //создаем новый список
            List<FieldClassStruct> newFields = new ArrayList<>();
            for (Class model : models) {
                Set<Field> modelFields = getClassFields(model);
                for (Field field : modelFields) {
                    newFields.add(new FieldClassStruct(field, model));
                }
            }

            try {
                //ActiveAndroid.beginTransaction();
                //сравниваем новый список со старым
                for (FieldClassStruct newField : newFields) {
                    if (!savedFields.contains(newField.getDesc())) {
                        makeAlterForField(newField);
                    }
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                /*ActiveAndroid.setTransactionSuccessful();
                ActiveAndroid.endTransaction();*/
            }
        }

        /*ActiveAndroid.dispose();
        ActiveAndroid.initialize(configurationBuilder.create());*/

        //сохраняем новый список

        file.delete();

        BufferedWriter wr = null;
        try {
            wr = new BufferedWriter(new FileWriter(file));
            wr.write(dbVersion + "\n");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (wr != null) {
                try {
                    wr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
Ответ написан
Комментировать
@ArtBigTema Автор вопроса
Решил, все же сам: (Работает без повышения версии)
Cursor c = ActiveAndroid.getDatabase().rawQuery(new Select().from(Post.class).toSql(), null);
  String[] names = c.getColumnNames();//список всех полей БД

  String[] newColumns = DbActiveHelper.getNewColumnNames(names, ActiveAndroid.getDatabase().getVersion());
        // новые поля, корых нет в списке names

for (String s : newColumns) {
            try {
                ActiveAndroid.getDatabase().execSQL("ALTER TABLE Post ADD COLUMN " + s); // s == "field INTEGER"
            } catch (SQLException e) {
                Log.e(TAG, e.getMessage());
            }
        }

Как убавлять поля, я пока не нашел.
Может кому поможет в будущем
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы