Add migration for renaming reminders table
continuous-integration/drone/pr Build is failing Details

This commit is contained in:
kolaente 2020-02-07 22:20:27 +01:00
parent a8d47d9052
commit 132a932db0
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
2 changed files with 97 additions and 28 deletions

View File

@ -0,0 +1,69 @@
// Vikunja is a todo-list application to facilitate your life.
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package migration
import (
"code.vikunja.io/api/pkg/timeutil"
"github.com/go-xorm/xorm"
"src.techknowlogick.com/xormigrate"
)
type taskReminder20200207220730 struct {
ID int64 `xorm:"int(11) autoincr not null unique pk"`
TaskID int64 `xorm:"int(11) not null INDEX"`
ReminderUnix timeutil.TimeStamp `xorm:"int(11) not null INDEX"`
Reminder timeutil.TimeStamp `xorm:"int(11) null INDEX"`
Created timeutil.TimeStamp `xorm:"created not null"`
}
func (t taskReminder20200207220730) TableName() string {
return "task_reminders"
}
func init() {
migrations = append(migrations, &xormigrate.Migration{
ID: "20200207220730",
Description: "Migrate unix reminders to datetime",
Migrate: func(tx *xorm.Engine) error {
err := tx.Sync2(taskReminder20200207220730{})
if err != nil {
return err
}
// Because we're changing the colum from unix timestamps, we need to updated everything manually
reminders := []*taskReminder20200207220730{}
err = tx.Find(&reminders)
if err != nil {
return err
}
for _, r := range reminders {
r.Reminder = r.ReminderUnix
_, err = tx.Update(r)
if err != nil {
return err
}
}
return dropTableColum(tx, "task_reminders", "reminder_unix")
},
Rollback: func(tx *xorm.Engine) error {
return dropTableColum(tx, "task_reminders", "reminder")
},
})
}

View File

@ -44,8 +44,8 @@ type Task struct {
// A unix timestamp when the task is due.
DueDateUnix int64 `xorm:"int(11) INDEX null" json:"dueDate"`
// An array of unix timestamps when the user wants to be reminded of the task.
RemindersUnix []int64 `xorm:"-" json:"reminderDates"`
CreatedByID int64 `xorm:"int(11) not null" json:"-"` // ID of the user who put that task on the list
Reminders []timeutil.TimeStamp `xorm:"-" json:"reminderDates"`
CreatedByID int64 `xorm:"int(11) not null" json:"-"` // ID of the user who put that task on the list
// The list this task belongs to.
ListID int64 `xorm:"int(11) INDEX not null" json:"listID" param:"list"`
// An amount in seconds this task repeats itself. If this is set, when marking the task as done, it will mark itself as "undone" and then increase all remindes and the due date by its amount.
@ -102,10 +102,10 @@ func (Task) TableName() string {
// TaskReminder holds a reminder on a task
type TaskReminder struct {
ID int64 `xorm:"int(11) autoincr not null unique pk"`
TaskID int64 `xorm:"int(11) not null INDEX"`
ReminderUnix int64 `xorm:"int(11) not null INDEX"`
Created timeutil.TimeStamp `xorm:"created not null"`
ID int64 `xorm:"int(11) autoincr not null unique pk"`
TaskID int64 `xorm:"int(11) not null INDEX"`
Reminder timeutil.TimeStamp `xorm:"int(11) not null INDEX"`
Created timeutil.TimeStamp `xorm:"created not null"`
}
// TableName returns a pretty table name
@ -391,9 +391,9 @@ func addMoreInfoToTasks(taskMap map[int64]*Task) (tasks []*Task, err error) {
return
}
taskRemindersUnix := make(map[int64][]int64)
taskRemindersUnix := make(map[int64][]timeutil.TimeStamp)
for _, r := range reminders {
taskRemindersUnix[r.TaskID] = append(taskRemindersUnix[r.TaskID], r.ReminderUnix)
taskRemindersUnix[r.TaskID] = append(taskRemindersUnix[r.TaskID], r.Reminder)
}
// Get all identifiers
@ -410,7 +410,7 @@ func addMoreInfoToTasks(taskMap map[int64]*Task) (tasks []*Task, err error) {
task.CreatedBy = users[task.CreatedByID]
// Add the reminders
task.RemindersUnix = taskRemindersUnix[task.ID]
task.Reminders = taskRemindersUnix[task.ID]
// Prepare the subtasks
task.RelatedTasks = make(RelatedTaskMap)
@ -519,7 +519,7 @@ func (t *Task) Create(a web.Auth) (err error) {
}
// Update the reminders
if err := t.updateReminders(t.RemindersUnix); err != nil {
if err := t.updateReminders(t.Reminders); err != nil {
return err
}
@ -559,7 +559,7 @@ func (t *Task) Update() (err error) {
}
// Update the reminders
if err := ot.updateReminders(t.RemindersUnix); err != nil {
if err := ot.updateReminders(t.Reminders); err != nil {
return err
}
@ -656,8 +656,8 @@ func updateDone(oldTask *Task, newTask *Task) {
if !oldTask.Done && newTask.Done && oldTask.RepeatAfter > 0 {
oldTask.DueDateUnix = oldTask.DueDateUnix + oldTask.RepeatAfter // assuming we'll save the old task (merged)
for in, r := range oldTask.RemindersUnix {
oldTask.RemindersUnix[in] = r + oldTask.RepeatAfter
for in, r := range oldTask.Reminders {
oldTask.Reminders[in] = timeutil.FromTime(r.ToTime().Add(time.Duration(oldTask.RepeatAfter) * time.Second))
}
newTask.Done = false
@ -675,7 +675,7 @@ func updateDone(oldTask *Task, newTask *Task) {
// Creates or deletes all necessary remindes without unneded db operations.
// The parameter is a slice with unix dates which holds the new reminders.
func (t *Task) updateReminders(reminders []int64) (err error) {
func (t *Task) updateReminders(reminders []timeutil.TimeStamp) (err error) {
// Load the current reminders
taskReminders, err := getRemindersForTasks([]int64{t.ID})
@ -683,35 +683,35 @@ func (t *Task) updateReminders(reminders []int64) (err error) {
return err
}
t.RemindersUnix = make([]int64, 0, len(taskReminders))
t.Reminders = make([]timeutil.TimeStamp, 0, len(taskReminders))
for _, reminder := range taskReminders {
t.RemindersUnix = append(t.RemindersUnix, reminder.ReminderUnix)
t.Reminders = append(t.Reminders, reminder.Reminder)
}
// If we're removing everything, delete all reminders right away
if len(reminders) == 0 && len(t.RemindersUnix) > 0 {
if len(reminders) == 0 && len(t.Reminders) > 0 {
_, err = x.Where("task_id = ?", t.ID).
Delete(TaskReminder{})
t.RemindersUnix = nil
t.Reminders = nil
return err
}
// If we didn't change anything (from 0 to zero) don't do anything.
if len(reminders) == 0 && len(t.RemindersUnix) == 0 {
if len(reminders) == 0 && len(t.Reminders) == 0 {
return nil
}
// Make a hashmap of the new reminders for easier comparison
newReminders := make(map[int64]*TaskReminder, len(reminders))
newReminders := make(map[timeutil.TimeStamp]*TaskReminder, len(reminders))
for _, newReminder := range reminders {
newReminders[newReminder] = &TaskReminder{ReminderUnix: newReminder}
newReminders[newReminder] = &TaskReminder{Reminder: newReminder}
}
// Get old reminders to delete
var found bool
var remindersToDelete []int64
oldReminders := make(map[int64]*TaskReminder, len(t.RemindersUnix))
for _, oldReminder := range t.RemindersUnix {
var remindersToDelete []timeutil.TimeStamp
oldReminders := make(map[timeutil.TimeStamp]*TaskReminder, len(t.Reminders))
for _, oldReminder := range t.Reminders {
found = false
// If a new reminder is already in the list with old reminders
if newReminders[oldReminder] != nil {
@ -723,7 +723,7 @@ func (t *Task) updateReminders(reminders []int64) (err error) {
remindersToDelete = append(remindersToDelete, oldReminder)
}
oldReminders[oldReminder] = &TaskReminder{ReminderUnix: oldReminder}
oldReminders[oldReminder] = &TaskReminder{Reminder: oldReminder}
}
// Delete all reminders not passed
@ -745,15 +745,15 @@ func (t *Task) updateReminders(reminders []int64) (err error) {
}
// Add the new reminder
_, err = x.Insert(TaskReminder{TaskID: t.ID, ReminderUnix: r})
_, err = x.Insert(TaskReminder{TaskID: t.ID, Reminder: r})
if err != nil {
return err
}
}
t.RemindersUnix = reminders
t.Reminders = reminders
if len(reminders) == 0 {
t.RemindersUnix = nil
t.Reminders = nil
}
err = updateListLastUpdated(&List{ID: t.ListID})