Как перенести базу данных, изменив тип столбца с строкового типа на тип даты - PullRequest
0 голосов
/ 29 апреля 2019

Я пытаюсь перенести базу данных, изменив тип столбца с типа String на Date. Вот что я сделал, что не дало ожидаемых результатов ...

    public static final Migration MIGRATION_1_2 = new Migration(1, 2) {

    SimpleDateFormat mDateFormat = new SimpleDateFormat("dd/MM/yyyy");

    @Override
    public void migrate(@NonNull SupportSQLiteDatabase database) {
        // Create a new table
        database.execSQL("CREATE TABLE newExpense (id INTEGER NOT Null, title TEXT, amount TEXT, date INTEGER" +
                ", PRIMARY KEY(id))");
        // Copy the contents of the old table into this new one
        database.execSQL("INSERT INTO newExpense (id,title,amount,date) SELECT id,title,amount" +
                ", 'mDateFormat.parse(date).getTime()' AS date FROM Expense ");
        // Delete the old table
        database.execSQL("DROP TABLE Expense");
        // Rename the new table to the old table
        database.execSQL("ALTER TABLE newExpense RENAME TO Expense");
    }
};

Вот как выглядела сущность раньше

    // BEFORE (version 1)
    @Entity
    public class Expense {

       @PrimaryKey(autoGenerate = true)
       private int id;
       private String title;
       private String amount;
       private String date;

       ...

    }

А теперь

    // NOW (version 2) 
    @Entity
    public class Expense {
    @PrimaryKey(autoGenerate = true)
    private int id;
    private String title;
    private String amount;
    private Date date;

       ...
    }

Когда я смоделировал обновление на устройстве-эмуляторе, результат показал неверную дату. Я особенно не уверен в этом утверждении в миграции

    database.execSQL("INSERT INTO newExpense (id,title,amount,date) SELECT id,title,amount" +
            ", 'mDateFormat.parse(date).getTime()' AS date FROM Expense ")

особенно 'mDateFormat.parse (date) .getTime ()'. В этом я пытался добиться того, чтобы преобразовать дату, которая раньше была представлена ​​в виде строки в формате dd / MM / yyyy, в объект даты, используя метод синтаксического анализа SimpleDateFormat. Что может быть не так с этим подходом или как еще я могу достичь цели?

1 Ответ

0 голосов
/ 01 мая 2019

Вот то, что я в итоге сделал, и это сработало гладко.

    ...

    // Create a Pojo that represents what the Expense looked like in version 1 of database.
    private static class OldExpense {

    private int id;
    private String title;
    private String amount;
    private String date;
    private SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat("dd/MM/yyyy");

    public OldExpense(int id, String title, String amount, String date) {
        this.id = id;
        this.title = title;
        this.amount = amount;
        this.date = date;
    }

    public Expense toExpense()  {
        Date date = null;
        try {
            date = mSimpleDateFormat.parse(this.date);
        } catch (ParseException e) {
            date = new Date();
            e.printStackTrace();
        }
        return new Expense(id, title, amount
                , date);
    }



    public static final Migration MIGRATION_1_2 = new Migration(1, 2) {

      SimpleDateFormat mDateFormat = new SimpleDateFormat("dd/MM/yyyy");

      @Override
      public void migrate(@NonNull SupportSQLiteDatabase database) {
        // Create a new table
        database.execSQL("CREATE TABLE NewExpense (id INTEGER NOT Null, title TEXT, amount TEXT, date INTEGER" +
                ", PRIMARY KEY(id))");


        // Read every thing from the former Expense table
        Cursor cursor = database.query("SELECT * FROM Expense");

        int id;
        String title;
        String amount;
        String date;
        List<OldExpense> expenses = new ArrayList<>();

        while (cursor.moveToNext()) {

            id = cursor.getInt(cursor.getColumnIndex("id"));
            title = cursor.getString(cursor.getColumnIndex("title"));
            amount = cursor.getString(cursor.getColumnIndex("amount"));
            date = cursor.getString(cursor.getColumnIndex("date"));

            expenses.add(new OldExpense(id,title,amount,date));
        }


        // transform the former Expenses into current Expenses
        List<Expense> newExpenses = new ArrayList<>();
        Expense newExpense;
        for(OldExpense oldExpense: expenses) {
            newExpense = oldExpense.toExpense();
            newExpenses.add(newExpense);
        }


        // Insert the current Expenses into current Expense table
        for (Expense expense: newExpenses){
            database.execSQL("INSERT INTO NewExpense (id, title, amount, date) VALUES" +
                    " ('"+expense.getId()+"', '"+expense.getTitle()+"', '"+expense.getAmount()+"', '"+expense.getDate().getTime()+"'  )");
        }


        // Delete the former table
        database.execSQL("DROP TABLE Expense");
        // Rename the current table to the former table name so that all other code continues to work
        database.execSQL("ALTER TABLE NewExpense RENAME TO Expense");



     }
  };
...