From 21a32853da919dbc079fc0eb156ba609cbbeeabd Mon Sep 17 00:00:00 2001 From: kolaente Date: Sat, 25 Jan 2025 17:35:13 +0100 Subject: [PATCH] wip, still broken https://gitea.com/xorm/xorm/issues/2500 --- pkg/caldav/parsing.go | 39 ++-- pkg/caldav/parsing_test.go | 72 +++---- pkg/files/files.go | 4 +- pkg/metrics/active_users.go | 11 +- pkg/models/api_tokens.go | 4 +- pkg/models/kanban.go | 8 +- pkg/models/kanban_task_bucket.go | 4 +- pkg/models/label.go | 4 +- pkg/models/label_task.go | 2 +- pkg/models/label_task_test.go | 6 +- pkg/models/label_test.go | 20 +- pkg/models/link_sharing.go | 4 +- pkg/models/listeners.go | 8 +- pkg/models/main_test.go | 4 +- pkg/models/models.go | 4 +- pkg/models/project.go | 8 +- pkg/models/project_team.go | 4 +- pkg/models/project_team_test.go | 4 +- pkg/models/project_users.go | 4 +- pkg/models/project_users_rights_test.go | 4 +- pkg/models/project_users_test.go | 16 +- pkg/models/project_view.go | 4 +- pkg/models/reaction.go | 2 +- pkg/models/saved_filters.go | 4 +- pkg/models/subscription.go | 2 +- pkg/models/task_assignees.go | 8 +- pkg/models/task_attachment.go | 2 +- pkg/models/task_collection_filter.go | 34 ++-- pkg/models/task_collection_filter_test.go | 10 +- pkg/models/task_collection_test.go | 178 +++++++++--------- pkg/models/task_comments.go | 8 +- pkg/models/task_relation.go | 2 +- pkg/models/task_reminder.go | 4 +- pkg/models/task_search.go | 2 +- pkg/models/tasks.go | 38 ++-- pkg/models/tasks_test.go | 76 ++++---- pkg/models/teams.go | 6 +- pkg/models/teams_rights_test.go | 4 +- pkg/models/typesense.go | 22 +-- pkg/models/user_delete.go | 4 +- pkg/models/webhooks.go | 4 +- .../microsoft-todo/microsoft_todo.go | 8 +- .../microsoft-todo/microsoft_todo_test.go | 2 +- pkg/modules/migration/ticktick/ticktick.go | 16 +- .../migration/ticktick/ticktick_test.go | 6 +- pkg/modules/migration/todoist/todoist.go | 68 +++---- pkg/modules/migration/todoist/todoist_test.go | 16 +- pkg/modules/migration/trello/trello.go | 6 +- pkg/modules/migration/trello/trello_test.go | 4 +- pkg/modules/time.go | 39 ++-- pkg/notifications/database.go | 10 +- pkg/routes/api/v1/user_show.go | 2 +- pkg/routes/caldav/listStorageProvider.go | 2 +- pkg/user/delete.go | 8 +- pkg/user/token.go | 12 +- pkg/user/user.go | 8 +- 56 files changed, 439 insertions(+), 416 deletions(-) diff --git a/pkg/caldav/parsing.go b/pkg/caldav/parsing.go index 363e07de2..5bed44424 100644 --- a/pkg/caldav/parsing.go +++ b/pkg/caldav/parsing.go @@ -191,7 +191,6 @@ func GetCaldavTodosForTasks(project *models.ProjectWithTasksAndBuckets, projectT var caldavtodos []*Todo for _, t := range projectTasks { - duration := t.EndDate.Sub(t.StartDate) var categories []string for _, label := range t.Labels { categories = append(categories, label.Title) @@ -215,20 +214,32 @@ func GetCaldavTodosForTasks(project *models.ProjectWithTasksAndBuckets, projectT } } + var duration time.Duration + if t.StartDate != nil && t.EndDate != nil { + duration = t.EndDate.Sub(t.StartDate) + } + + getTimeIfNotNil := func(t *modules.Time) time.Time { + if t == nil { + return time.Time{} // Return zero value of time.Time if t is nil + } + return t.Time() // Dereference the pointer and return the value + } + caldavtodos = append(caldavtodos, &Todo{ Timestamp: t.Updated.Time(), UID: t.UID, Summary: t.Title, Description: t.Description, - Completed: t.DoneAt.Time(), - // Organizer: &t.CreatedBy, // Disabled until we figure out how this works + Completed: getTimeIfNotNil(t.DoneAt), + // Organizer: &t.CreatedBy, // Disabled until we figure out how this works Categories: categories, Priority: t.Priority, - Start: t.StartDate.Time(), - End: t.EndDate.Time(), - Created: t.Created.Time(), - Updated: t.Updated.Time(), - DueDate: t.DueDate.Time(), + Start: getTimeIfNotNil(t.StartDate), + End: getTimeIfNotNil(t.EndDate), + Created: getTimeIfNotNil(t.Created), + Updated: getTimeIfNotNil(t.Updated), + DueDate: getTimeIfNotNil(t.DueDate), Duration: duration, RepeatAfter: t.RepeatAfter, RepeatMode: t.RepeatMode, @@ -407,7 +418,7 @@ func parseVAlarm(vAlarm *ics.VAlarm, vTask *models.Task) *models.Task { if contains(property.ICalParameters["RELATED"], "END") { // Example: TRIGGER;RELATED=END:-P2D - if vTask.EndDate.IsZero() { + if vTask.EndDate == nil || (vTask.EndDate != nil && vTask.EndDate.IsZero()) { vTask.Reminders = append(vTask.Reminders, &models.TaskReminder{ RelativePeriod: int64(duration.Seconds()), RelativeTo: models.ReminderRelationDueDate}) @@ -438,10 +449,10 @@ func contains(array []string, str string) bool { } // https://tools.ietf.org/html/rfc5545#section-3.3.5 -func caldavTimeToTimestamp(ianaProperty ics.IANAProperty) modules.Time { +func caldavTimeToTimestamp(ianaProperty ics.IANAProperty) *modules.Time { tstring := ianaProperty.Value if tstring == "" { - return modules.Time{} + return nil } format := DateFormat @@ -465,14 +476,14 @@ func caldavTimeToTimestamp(ianaProperty ics.IANAProperty) modules.Time { if err != nil { log.Warningf("Error while parsing caldav time %s to TimeStamp: %s at location %s", tstring, loc, err) } else { - return modules.Time(tt.In(config.GetTimeZone())) + return modules.TimeFromTime(tt.In(config.GetTimeZone())) } } } tt, err := time.Parse(format, tstring) if err != nil { log.Warningf("Error while parsing caldav time %s to TimeStamp: %s", tstring, err) - return modules.Time{} + return nil } - return modules.Time(tt) + return modules.TimeFromTime(tt) } diff --git a/pkg/caldav/parsing_test.go b/pkg/caldav/parsing_test.go index e72ba8497..a7a69f2af 100644 --- a/pkg/caldav/parsing_test.go +++ b/pkg/caldav/parsing_test.go @@ -57,7 +57,7 @@ END:VCALENDAR`, Title: "Todo #1", UID: "randomuid", Description: "Lorem Ipsum", - Updated: modules.Time(time.Unix(1543626724, 0).In(config.GetTimeZone())), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(config.GetTimeZone())), }, }, { @@ -83,7 +83,7 @@ END:VCALENDAR`, UID: "randomuid", Description: "Lorem Ipsum", Priority: 1, - Updated: modules.Time(time.Unix(1543626724, 0).In(config.GetTimeZone())), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(config.GetTimeZone())), }, }, { @@ -116,7 +116,7 @@ END:VCALENDAR`, Title: "cat2", }, }, - Updated: modules.Time(time.Unix(1543626724, 0).In(config.GetTimeZone())), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(config.GetTimeZone())), }, }, { @@ -145,10 +145,10 @@ END:VCALENDAR`, Description: "Lorem Ipsum", Reminders: []*models.TaskReminder{ { - Reminder: modules.Time(time.Date(2018, 12, 1, 1, 12, 10, 0, config.GetTimeZone())), + Reminder: modules.TimeFromTime(time.Date(2018, 12, 1, 1, 12, 10, 0, config.GetTimeZone())), }, }, - Updated: modules.Time(time.Unix(1543626724, 0).In(config.GetTimeZone())), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(config.GetTimeZone())), }, }, { @@ -193,8 +193,8 @@ END:VCALENDAR`, Title: "Todo #1", UID: "randomuid", Description: "Lorem Ipsum", - StartDate: modules.Time(time.Date(2023, 2, 28, 17, 0, 0, 0, config.GetTimeZone())), - DueDate: modules.Time(time.Date(2023, 3, 4, 15, 0, 0, 0, config.GetTimeZone())), + StartDate: modules.TimeFromTime(time.Date(2023, 2, 28, 17, 0, 0, 0, config.GetTimeZone())), + DueDate: modules.TimeFromTime(time.Date(2023, 3, 4, 15, 0, 0, 0, config.GetTimeZone())), Reminders: []*models.TaskReminder{ { RelativeTo: models.ReminderRelationStartDate, @@ -217,7 +217,7 @@ END:VCALENDAR`, RelativePeriod: -1800, }, }, - Updated: modules.Time(time.Unix(1543626724, 0).In(config.GetTimeZone())), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(config.GetTimeZone())), }, }, { @@ -242,7 +242,7 @@ END:VCALENDAR`, Title: "SubTask #1", UID: "randomuid", Description: "Lorem Ipsum", - Updated: modules.Time(time.Unix(1543626724, 0).In(config.GetTimeZone())), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(config.GetTimeZone())), RelatedTasks: map[models.RelationKind][]*models.Task{ models.RelationKindParenttask: { { @@ -274,7 +274,7 @@ END:VCALENDAR`, Title: "Parent", UID: "randomuid", Description: "Lorem Ipsum", - Updated: modules.Time(time.Unix(1543626724, 0).In(config.GetTimeZone())), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(config.GetTimeZone())), RelatedTasks: map[models.RelationKind][]*models.Task{ models.RelationKindSubtask: { { @@ -332,7 +332,7 @@ END:VTIMEZONE END:VCALENDAR`, }, wantVTask: &models.Task{ - Updated: modules.Time(time.Date(2023, 4, 2, 7, 41, 58, 0, config.GetTimeZone())), + Updated: modules.TimeFromTime(time.Date(2023, 4, 2, 7, 41, 58, 0, config.GetTimeZone())), UID: "4290517349243274514", Title: "Test with tasks.org", Priority: 1, @@ -341,15 +341,15 @@ END:VCALENDAR`, Title: "Vikunja", }, }, - DueDate: modules.Time(time.Date(2023, 4, 2, 15, 0, 1, 0, config.GetTimeZone())), - StartDate: modules.Time(time.Date(2023, 4, 1, 7, 0, 0, 0, config.GetTimeZone())), + DueDate: modules.TimeFromTime(time.Date(2023, 4, 2, 15, 0, 1, 0, config.GetTimeZone())), + StartDate: modules.TimeFromTime(time.Date(2023, 4, 1, 7, 0, 0, 0, config.GetTimeZone())), Reminders: []*models.TaskReminder{ { RelativeTo: models.ReminderRelationDueDate, RelativePeriod: 0, }, { - Reminder: modules.Time(time.Date(2023, 4, 2, 10, 0, 0, 0, config.GetTimeZone())), + Reminder: modules.TimeFromTime(time.Date(2023, 4, 2, 10, 0, 0, 0, config.GetTimeZone())), }, }, }, @@ -530,12 +530,12 @@ func TestGetCaldavTodosForTasks(t *testing.T) { UID: "randomuid", Description: "Description", Priority: 3, - Created: modules.Time(time.Unix(1543626721, 0).In(config.GetTimeZone())), - DueDate: modules.Time(time.Unix(1543626722, 0).In(config.GetTimeZone())), - StartDate: modules.Time(time.Unix(1543626723, 0).In(config.GetTimeZone())), - EndDate: modules.Time(time.Unix(1543626724, 0).In(config.GetTimeZone())), - Updated: modules.Time(time.Unix(1543626725, 0).In(config.GetTimeZone())), - DoneAt: modules.Time(time.Unix(1543626726, 0).In(config.GetTimeZone())), + Created: modules.TimeFromTime(time.Unix(1543626721, 0).In(config.GetTimeZone())), + DueDate: modules.TimeFromTime(time.Unix(1543626722, 0).In(config.GetTimeZone())), + StartDate: modules.TimeFromTime(time.Unix(1543626723, 0).In(config.GetTimeZone())), + EndDate: modules.TimeFromTime(time.Unix(1543626724, 0).In(config.GetTimeZone())), + Updated: modules.TimeFromTime(time.Unix(1543626725, 0).In(config.GetTimeZone())), + DoneAt: modules.TimeFromTime(time.Unix(1543626726, 0).In(config.GetTimeZone())), RepeatAfter: 86400, Labels: []*models.Label{ { @@ -549,10 +549,10 @@ func TestGetCaldavTodosForTasks(t *testing.T) { }, Reminders: []*models.TaskReminder{ { - Reminder: modules.Time(time.Unix(1543626730, 0).In(config.GetTimeZone())), + Reminder: modules.TimeFromTime(time.Unix(1543626730, 0).In(config.GetTimeZone())), }, { - Reminder: modules.Time(time.Unix(1543626731, 0).In(config.GetTimeZone())), + Reminder: modules.TimeFromTime(time.Unix(1543626731, 0).In(config.GetTimeZone())), RelativePeriod: -3600, RelativeTo: models.ReminderRelationDueDate, }, @@ -610,23 +610,23 @@ END:VCALENDAR`, UID: "randomuid_parent", Description: "A parent task", Priority: 3, - Created: modules.Time(time.Unix(1543626721, 0).In(config.GetTimeZone())), - Updated: modules.Time(time.Unix(1543626725, 0).In(config.GetTimeZone())), + Created: modules.TimeFromTime(time.Unix(1543626721, 0).In(config.GetTimeZone())), + Updated: modules.TimeFromTime(time.Unix(1543626725, 0).In(config.GetTimeZone())), RelatedTasks: map[models.RelationKind][]*models.Task{ models.RelationKindSubtask: { { Title: "Subtask 1", UID: "randomuid_child_1", Description: "The first child task", - Created: modules.Time(time.Unix(1543626724, 0).In(config.GetTimeZone())), - Updated: modules.Time(time.Unix(1543626724, 0).In(config.GetTimeZone())), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(config.GetTimeZone())), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(config.GetTimeZone())), }, { Title: "Subtask 2", UID: "randomuid_child_2", Description: "The second child task", - Created: modules.Time(time.Unix(1543626724, 0).In(config.GetTimeZone())), - Updated: modules.Time(time.Unix(1543626724, 0).In(config.GetTimeZone())), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(config.GetTimeZone())), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(config.GetTimeZone())), }, }, }, @@ -637,8 +637,8 @@ END:VCALENDAR`, Title: "Subtask 1", UID: "randomuid_child_1", Description: "The first child task", - Created: modules.Time(time.Unix(1543626724, 0).In(config.GetTimeZone())), - Updated: modules.Time(time.Unix(1543626724, 0).In(config.GetTimeZone())), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(config.GetTimeZone())), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(config.GetTimeZone())), RelatedTasks: map[models.RelationKind][]*models.Task{ models.RelationKindParenttask: { { @@ -646,8 +646,8 @@ END:VCALENDAR`, UID: "randomuid_parent", Description: "A parent task", Priority: 3, - Created: modules.Time(time.Unix(1543626721, 0).In(config.GetTimeZone())), - Updated: modules.Time(time.Unix(1543626725, 0).In(config.GetTimeZone())), + Created: modules.TimeFromTime(time.Unix(1543626721, 0).In(config.GetTimeZone())), + Updated: modules.TimeFromTime(time.Unix(1543626725, 0).In(config.GetTimeZone())), }, }, }, @@ -658,8 +658,8 @@ END:VCALENDAR`, Title: "Subtask 2", UID: "randomuid_child_2", Description: "The second child task", - Created: modules.Time(time.Unix(1543626724, 0).In(config.GetTimeZone())), - Updated: modules.Time(time.Unix(1543626724, 0).In(config.GetTimeZone())), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(config.GetTimeZone())), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(config.GetTimeZone())), RelatedTasks: map[models.RelationKind][]*models.Task{ models.RelationKindParenttask: { { @@ -667,8 +667,8 @@ END:VCALENDAR`, UID: "randomuid_parent", Description: "A parent task", Priority: 3, - Created: modules.Time(time.Unix(1543626721, 0).In(config.GetTimeZone())), - Updated: modules.Time(time.Unix(1543626725, 0).In(config.GetTimeZone())), + Created: modules.TimeFromTime(time.Unix(1543626721, 0).In(config.GetTimeZone())), + Updated: modules.TimeFromTime(time.Unix(1543626725, 0).In(config.GetTimeZone())), }, }, }, diff --git a/pkg/files/files.go b/pkg/files/files.go index 531dad9be..d65069198 100644 --- a/pkg/files/files.go +++ b/pkg/files/files.go @@ -43,8 +43,8 @@ type File struct { Mime string `xorm:"text null" json:"mime"` Size uint64 `xorm:"bigint not null" json:"size"` - Created modules.Time `xorm:"created" json:"created"` - CreatedByID int64 `xorm:"bigint not null" json:"-"` + Created *modules.Time `xorm:"created" json:"created"` + CreatedByID int64 `xorm:"bigint not null" json:"-"` File afero.File `xorm:"-" json:"-"` // This ReadCloser is only used for migration purposes. Use with care! diff --git a/pkg/metrics/active_users.go b/pkg/metrics/active_users.go index 9ec593951..c13926c9f 100644 --- a/pkg/metrics/active_users.go +++ b/pkg/metrics/active_users.go @@ -21,7 +21,6 @@ import ( "time" "code.vikunja.io/api/pkg/log" - "code.vikunja.io/api/pkg/modules" "code.vikunja.io/api/pkg/modules/keyvalue" "code.vikunja.io/api/pkg/web" @@ -36,7 +35,7 @@ const activeLinkSharesKey = `active_link_shares` // ActiveAuthenticable defines an active user or link share type ActiveAuthenticable struct { ID int64 - LastSeen modules.Time + LastSeen time.Time } type activeUsersMap map[int64]*ActiveAuthenticable @@ -84,7 +83,7 @@ func setupActiveUsersMetric() { } count := 0 for _, u := range allActiveUsers { - if time.Since(u.LastSeen.Time()) < secondsUntilInactive*time.Second { + if time.Since(u.LastSeen) < secondsUntilInactive*time.Second { count++ } } @@ -111,7 +110,7 @@ func setupActiveLinkSharesMetric() { } count := 0 for _, u := range allActiveLinkShares { - if time.Since(u.LastSeen.Time()) < secondsUntilInactive*time.Second { + if time.Since(u.LastSeen) < secondsUntilInactive*time.Second { count++ } } @@ -128,7 +127,7 @@ func SetUserActive(a web.Auth) (err error) { defer activeUsers.mutex.Unlock() activeUsers.users[a.GetID()] = &ActiveAuthenticable{ ID: a.GetID(), - LastSeen: modules.Time(time.Now()), + LastSeen: time.Now(), } return keyvalue.Put(activeUsersKey, activeUsers.users) @@ -140,7 +139,7 @@ func SetLinkShareActive(a web.Auth) (err error) { defer activeLinkShares.mutex.Unlock() activeLinkShares.shares[a.GetID()] = &ActiveAuthenticable{ ID: a.GetID(), - LastSeen: modules.Time(time.Now()), + LastSeen: time.Now(), } return keyvalue.Put(activeLinkSharesKey, activeLinkShares.shares) diff --git a/pkg/models/api_tokens.go b/pkg/models/api_tokens.go index 59d97331d..dc9302650 100644 --- a/pkg/models/api_tokens.go +++ b/pkg/models/api_tokens.go @@ -47,10 +47,10 @@ type APIToken struct { // The permissions this token has. Possible values are available via the /routes endpoint and consist of the keys of the list from that endpoint. For example, if the token should be able to read all tasks as well as update existing tasks, you should add `{"tasks":["read_all","update"]}`. Permissions APIPermissions `xorm:"json not null" json:"permissions" valid:"required"` // The date when this key expires. - ExpiresAt modules.Time `xorm:"not null" json:"expires_at" valid:"required"` + ExpiresAt *modules.Time `xorm:"not null" json:"expires_at" valid:"required"` // A timestamp when this api key was created. You cannot change this value. - Created modules.Time `xorm:"created not null" json:"created"` + Created *modules.Time `xorm:"created not null" json:"created"` OwnerID int64 `xorm:"bigint not null" json:"-"` diff --git a/pkg/models/kanban.go b/pkg/models/kanban.go index c26ef8a6b..3ec8df33d 100644 --- a/pkg/models/kanban.go +++ b/pkg/models/kanban.go @@ -51,9 +51,9 @@ type Bucket struct { Position float64 `xorm:"double null" json:"position"` // A timestamp when this bucket was created. You cannot change this value. - Created modules.Time `xorm:"created not null" json:"created"` + Created *modules.Time `xorm:"created not null" json:"created"` // A timestamp when this bucket was last updated. You cannot change this value. - Updated modules.Time `xorm:"updated not null" json:"updated"` + Updated *modules.Time `xorm:"updated not null" json:"updated"` // The user who initially created the bucket. CreatedBy *user.User `xorm:"-" json:"created_by" valid:"-"` @@ -176,8 +176,8 @@ func GetTasksInBucketsForView(s *xorm.Session, view *ProjectView, projects []*Pr ProjectViewID: view.ID, Position: float64(id), CreatedByID: auth.GetID(), - Created: modules.Time(time.Now()), - Updated: modules.Time(time.Now()), + Created: modules.TimeFromTime(time.Now()), + Updated: modules.TimeFromTime(time.Now()), }) } } diff --git a/pkg/models/kanban_task_bucket.go b/pkg/models/kanban_task_bucket.go index 36d94a28d..4255059ec 100644 --- a/pkg/models/kanban_task_bucket.go +++ b/pkg/models/kanban_task_bucket.go @@ -153,9 +153,9 @@ func (b *TaskBucket) Update(s *xorm.Session, a web.Auth) (err error) { if doneChanged { if task.Done { - task.DoneAt = modules.Time(time.Now()) + task.DoneAt = modules.TimeFromTime(time.Now()) } else { - task.DoneAt = modules.Time{} + task.DoneAt = &modules.Time{} } _, err = s.Where("id = ?", task.ID). Cols( diff --git a/pkg/models/label.go b/pkg/models/label.go index af2355af5..91e538e25 100644 --- a/pkg/models/label.go +++ b/pkg/models/label.go @@ -41,9 +41,9 @@ type Label struct { CreatedBy *user.User `xorm:"-" json:"created_by"` // A timestamp when this label was created. You cannot change this value. - Created modules.Time `xorm:"created not null" json:"created"` + Created *modules.Time `xorm:"created not null" json:"created"` // A timestamp when this label was last updated. You cannot change this value. - Updated modules.Time `xorm:"updated not null" json:"updated"` + Updated *modules.Time `xorm:"updated not null" json:"updated"` web.CRUDable `xorm:"-" json:"-"` web.Rights `xorm:"-" json:"-"` diff --git a/pkg/models/label_task.go b/pkg/models/label_task.go index 329bf928e..2c41d2848 100644 --- a/pkg/models/label_task.go +++ b/pkg/models/label_task.go @@ -37,7 +37,7 @@ type LabelTask struct { // The label id you want to associate with a task. LabelID int64 `xorm:"bigint INDEX not null" json:"label_id" param:"label"` // A timestamp when this task was created. You cannot change this value. - Created modules.Time `xorm:"created not null" json:"created"` + Created *modules.Time `xorm:"created not null" json:"created"` web.CRUDable `xorm:"-" json:"-"` web.Rights `xorm:"-" json:"-"` diff --git a/pkg/models/label_task_test.go b/pkg/models/label_task_test.go index 0e16b5eaf..200724c63 100644 --- a/pkg/models/label_task_test.go +++ b/pkg/models/label_task_test.go @@ -53,7 +53,7 @@ func TestLabelTask_ReadAll(t *testing.T) { ID int64 TaskID int64 LabelID int64 - Created modules.Time + Created *modules.Time CRUDable web.CRUDable Rights web.Rights } @@ -159,7 +159,7 @@ func TestLabelTask_Create(t *testing.T) { ID int64 TaskID int64 LabelID int64 - Created modules.Time + Created *modules.Time CRUDable web.CRUDable Rights web.Rights } @@ -263,7 +263,7 @@ func TestLabelTask_Delete(t *testing.T) { ID int64 TaskID int64 LabelID int64 - Created modules.Time + Created *modules.Time CRUDable web.CRUDable Rights web.Rights } diff --git a/pkg/models/label_test.go b/pkg/models/label_test.go index 7aa71c3ee..7a58bacdc 100644 --- a/pkg/models/label_test.go +++ b/pkg/models/label_test.go @@ -36,8 +36,8 @@ func TestLabel_ReadAll(t *testing.T) { HexColor string CreatedByID int64 CreatedBy *user.User - Created modules.Time - Updated modules.Time + Created *modules.Time + Updated *modules.Time CRUDable web.CRUDable Rights web.Rights } @@ -172,8 +172,8 @@ func TestLabel_ReadOne(t *testing.T) { HexColor string CreatedByID int64 CreatedBy *user.User - Created modules.Time - Updated modules.Time + Created *modules.Time + Updated *modules.Time CRUDable web.CRUDable Rights web.Rights } @@ -302,8 +302,8 @@ func TestLabel_Create(t *testing.T) { HexColor string CreatedByID int64 CreatedBy *user.User - Created modules.Time - Updated modules.Time + Created *modules.Time + Updated *modules.Time CRUDable web.CRUDable Rights web.Rights } @@ -372,8 +372,8 @@ func TestLabel_Update(t *testing.T) { HexColor string CreatedByID int64 CreatedBy *user.User - Created modules.Time - Updated modules.Time + Created *modules.Time + Updated *modules.Time CRUDable web.CRUDable Rights web.Rights } @@ -462,8 +462,8 @@ func TestLabel_Delete(t *testing.T) { HexColor string CreatedByID int64 CreatedBy *user.User - Created modules.Time - Updated modules.Time + Created *modules.Time + Updated *modules.Time CRUDable web.CRUDable Rights web.Rights } diff --git a/pkg/models/link_sharing.go b/pkg/models/link_sharing.go index cc9f7195c..48f7e05a0 100644 --- a/pkg/models/link_sharing.go +++ b/pkg/models/link_sharing.go @@ -65,9 +65,9 @@ type LinkSharing struct { SharedByID int64 `xorm:"bigint INDEX not null" json:"-"` // A timestamp when this project was shared. You cannot change this value. - Created modules.Time `xorm:"created not null" json:"created"` + Created *modules.Time `xorm:"created not null" json:"created"` // A timestamp when this share was last updated. You cannot change this value. - Updated modules.Time `xorm:"updated not null" json:"updated"` + Updated *modules.Time `xorm:"updated not null" json:"updated"` web.CRUDable `xorm:"-" json:"-"` web.Rights `xorm:"-" json:"-"` diff --git a/pkg/models/listeners.go b/pkg/models/listeners.go index ff3bb2176..e17ee0398 100644 --- a/pkg/models/listeners.go +++ b/pkg/models/listeners.go @@ -831,9 +831,9 @@ func (wl *WebhookListener) Name() string { } type WebhookPayload struct { - EventName string `json:"event_name"` - Time modules.Time `json:"time"` - Data interface{} `json:"data"` + EventName string `json:"event_name"` + Time *modules.Time `json:"time"` + Data interface{} `json:"data"` } func getIDAsInt64(id interface{}) int64 { @@ -965,7 +965,7 @@ func (wl *WebhookListener) Handle(msg *message.Message) (err error) { for _, webhook := range matchingWebhooks { err = webhook.sendWebhookPayload(&WebhookPayload{ EventName: wl.EventName, - Time: modules.Time(time.Now()), + Time: modules.TimeFromTime(time.Now()), Data: event, }) if err != nil { diff --git a/pkg/models/main_test.go b/pkg/models/main_test.go index d48526b61..c10d3cd46 100644 --- a/pkg/models/main_test.go +++ b/pkg/models/main_test.go @@ -37,14 +37,14 @@ func setupTime() { os.Exit(1) } testCreatedTimeRaw, err := time.ParseInLocation(time.RFC3339Nano, "2018-12-01T15:13:12.0+00:00", loc) - testCreatedTime = modules.Time(testCreatedTimeRaw) + testCreatedTime = modules.TimeFromTime(testCreatedTimeRaw) if err != nil { fmt.Printf("Error setting up time: %s", err) os.Exit(1) } testCreatedTime = testCreatedTime.In(loc) testUpdatedTimeRaw, err := time.ParseInLocation(time.RFC3339Nano, "2018-12-02T15:13:12.0+00:00", loc) - testUpdatedTime = modules.Time(testUpdatedTimeRaw) + testUpdatedTime = modules.TimeFromTime(testUpdatedTimeRaw) if err != nil { fmt.Printf("Error setting up time: %s", err) os.Exit(1) diff --git a/pkg/models/models.go b/pkg/models/models.go index 4e653610e..05ae6dd4d 100644 --- a/pkg/models/models.go +++ b/pkg/models/models.go @@ -31,8 +31,8 @@ import ( var ( x *xorm.Engine - testCreatedTime modules.Time - testUpdatedTime modules.Time + testCreatedTime *modules.Time + testUpdatedTime *modules.Time ) // GetTables returns all structs which are also a table. diff --git a/pkg/models/project.go b/pkg/models/project.go index db0b0cbdf..288dfdc28 100644 --- a/pkg/models/project.go +++ b/pkg/models/project.go @@ -82,9 +82,9 @@ type Project struct { MaxRight Right `xorm:"-" json:"max_right"` // A timestamp when this project was created. You cannot change this value. - Created modules.Time `xorm:"created not null" json:"created"` + Created *modules.Time `xorm:"created not null" json:"created"` // A timestamp when this project was last updated. You cannot change this value. - Updated modules.Time `xorm:"updated not null" json:"updated"` + Updated *modules.Time `xorm:"updated not null" json:"updated"` web.CRUDable `xorm:"-" json:"-"` web.Rights `xorm:"-" json:"-"` @@ -155,8 +155,8 @@ var FavoritesPseudoProject = Project{ }, }, - Created: modules.Time(time.Now()), - Updated: modules.Time(time.Now()), + Created: modules.TimeFromTime(time.Now()), + Updated: modules.TimeFromTime(time.Now()), } // ReadAll gets all projects a user has access to diff --git a/pkg/models/project_team.go b/pkg/models/project_team.go index 20fdb236d..c5b036669 100644 --- a/pkg/models/project_team.go +++ b/pkg/models/project_team.go @@ -38,9 +38,9 @@ type TeamProject struct { Right Right `xorm:"bigint INDEX not null default 0" json:"right" valid:"length(0|2)" maximum:"2" default:"0"` // A timestamp when this relation was created. You cannot change this value. - Created modules.Time `xorm:"created not null" json:"created"` + Created *modules.Time `xorm:"created not null" json:"created"` // A timestamp when this relation was last updated. You cannot change this value. - Updated modules.Time `xorm:"updated not null" json:"updated"` + Updated *modules.Time `xorm:"updated not null" json:"updated"` web.CRUDable `xorm:"-" json:"-"` web.Rights `xorm:"-" json:"-"` diff --git a/pkg/models/project_team_test.go b/pkg/models/project_team_test.go index 875233593..122ae9705 100644 --- a/pkg/models/project_team_test.go +++ b/pkg/models/project_team_test.go @@ -211,8 +211,8 @@ func TestTeamProject_Update(t *testing.T) { TeamID int64 ProjectID int64 Right Right - Created modules.Time - Updated modules.Time + Created *modules.Time + Updated *modules.Time CRUDable web.CRUDable Rights web.Rights } diff --git a/pkg/models/project_users.go b/pkg/models/project_users.go index 272f08729..3c06c002b 100644 --- a/pkg/models/project_users.go +++ b/pkg/models/project_users.go @@ -41,9 +41,9 @@ type ProjectUser struct { Right Right `xorm:"bigint INDEX not null default 0" json:"right" valid:"length(0|2)" maximum:"2" default:"0"` // A timestamp when this relation was created. You cannot change this value. - Created modules.Time `xorm:"created not null" json:"created"` + Created *modules.Time `xorm:"created not null" json:"created"` // A timestamp when this relation was last updated. You cannot change this value. - Updated modules.Time `xorm:"updated not null" json:"updated"` + Updated *modules.Time `xorm:"updated not null" json:"updated"` web.CRUDable `xorm:"-" json:"-"` web.Rights `xorm:"-" json:"-"` diff --git a/pkg/models/project_users_rights_test.go b/pkg/models/project_users_rights_test.go index 336a6884a..897d98594 100644 --- a/pkg/models/project_users_rights_test.go +++ b/pkg/models/project_users_rights_test.go @@ -31,8 +31,8 @@ func TestProjectUser_CanDoSomething(t *testing.T) { UserID int64 ProjectID int64 Right Right - Created modules.Time - Updated modules.Time + Created *modules.Time + Updated *modules.Time CRUDable web.CRUDable Rights web.Rights } diff --git a/pkg/models/project_users_test.go b/pkg/models/project_users_test.go index ff51a3528..cf54c5226 100644 --- a/pkg/models/project_users_test.go +++ b/pkg/models/project_users_test.go @@ -36,8 +36,8 @@ func TestProjectUser_Create(t *testing.T) { Username string ProjectID int64 Right Right - Created modules.Time - Updated modules.Time + Created *modules.Time + Updated *modules.Time CRUDable web.CRUDable Rights web.Rights } @@ -178,8 +178,8 @@ func TestProjectUser_ReadAll(t *testing.T) { UserID int64 ProjectID int64 Right Right - Created modules.Time - Updated modules.Time + Created *modules.Time + Updated *modules.Time CRUDable web.CRUDable Rights web.Rights } @@ -270,8 +270,8 @@ func TestProjectUser_Update(t *testing.T) { Username string ProjectID int64 Right Right - Created modules.Time - Updated modules.Time + Created *modules.Time + Updated *modules.Time CRUDable web.CRUDable Rights web.Rights } @@ -360,8 +360,8 @@ func TestProjectUser_Delete(t *testing.T) { UserID int64 ProjectID int64 Right Right - Created modules.Time - Updated modules.Time + Created *modules.Time + Updated *modules.Time CRUDable web.CRUDable Rights web.Rights } diff --git a/pkg/models/project_view.go b/pkg/models/project_view.go index 3a86a9670..2e9b93a65 100644 --- a/pkg/models/project_view.go +++ b/pkg/models/project_view.go @@ -144,9 +144,9 @@ type ProjectView struct { DoneBucketID int64 `xorm:"bigint INDEX null" json:"done_bucket_id"` // A timestamp when this view was updated. You cannot change this value. - Updated modules.Time `xorm:"updated not null" json:"updated"` + Updated *modules.Time `xorm:"updated not null" json:"updated"` // A timestamp when this reaction was created. You cannot change this value. - Created modules.Time `xorm:"created not null" json:"created"` + Created *modules.Time `xorm:"created not null" json:"created"` web.CRUDable `xorm:"-" json:"-"` web.Rights `xorm:"-" json:"-"` diff --git a/pkg/models/reaction.go b/pkg/models/reaction.go index 93d31bfda..430b6d965 100644 --- a/pkg/models/reaction.go +++ b/pkg/models/reaction.go @@ -50,7 +50,7 @@ type Reaction struct { Value string `xorm:"varchar(20) not null INDEX" json:"value" valid:"required"` // A timestamp when this reaction was created. You cannot change this value. - Created modules.Time `xorm:"created not null" json:"created"` + Created *modules.Time `xorm:"created not null" json:"created"` web.CRUDable `xorm:"-" json:"-"` web.Rights `xorm:"-" json:"-"` diff --git a/pkg/models/saved_filters.go b/pkg/models/saved_filters.go index 5c976db35..db9bffcc8 100644 --- a/pkg/models/saved_filters.go +++ b/pkg/models/saved_filters.go @@ -48,9 +48,9 @@ type SavedFilter struct { IsFavorite bool `xorm:"default false" json:"is_favorite"` // A timestamp when this filter was created. You cannot change this value. - Created modules.Time `xorm:"created not null" json:"created"` + Created *modules.Time `xorm:"created not null" json:"created"` // A timestamp when this filter was last updated. You cannot change this value. - Updated modules.Time `xorm:"updated not null" json:"updated"` + Updated *modules.Time `xorm:"updated not null" json:"updated"` web.CRUDable `xorm:"-" json:"-"` web.Rights `xorm:"-" json:"-"` diff --git a/pkg/models/subscription.go b/pkg/models/subscription.go index 7c9b0bd27..29b508b9c 100644 --- a/pkg/models/subscription.go +++ b/pkg/models/subscription.go @@ -106,7 +106,7 @@ type Subscription struct { UserID int64 `xorm:"bigint index not null" json:"-"` // A timestamp when this subscription was created. You cannot change this value. - Created modules.Time `xorm:"created not null" json:"created"` + Created *modules.Time `xorm:"created not null" json:"created"` web.CRUDable `xorm:"-" json:"-"` web.Rights `xorm:"-" json:"-"` diff --git a/pkg/models/task_assignees.go b/pkg/models/task_assignees.go index 6d116705f..2bf0ae31e 100644 --- a/pkg/models/task_assignees.go +++ b/pkg/models/task_assignees.go @@ -29,10 +29,10 @@ import ( // TaskAssginee represents an assignment of a user to a task type TaskAssginee struct { - ID int64 `xorm:"bigint autoincr not null unique pk" json:"-"` - TaskID int64 `xorm:"bigint INDEX not null" json:"-" param:"projecttask"` - UserID int64 `xorm:"bigint INDEX not null" json:"user_id" param:"user"` - Created modules.Time `xorm:"created not null"` + ID int64 `xorm:"bigint autoincr not null unique pk" json:"-"` + TaskID int64 `xorm:"bigint INDEX not null" json:"-" param:"projecttask"` + UserID int64 `xorm:"bigint INDEX not null" json:"user_id" param:"user"` + Created *modules.Time `xorm:"created not null"` web.CRUDable `xorm:"-" json:"-"` web.Rights `xorm:"-" json:"-"` diff --git a/pkg/models/task_attachment.go b/pkg/models/task_attachment.go index 70aef2eb5..955feb831 100644 --- a/pkg/models/task_attachment.go +++ b/pkg/models/task_attachment.go @@ -45,7 +45,7 @@ type TaskAttachment struct { File *files.File `xorm:"-" json:"file"` - Created modules.Time `xorm:"created" json:"created"` + Created *modules.Time `xorm:"created" json:"created"` web.CRUDable `xorm:"-" json:"-"` web.Rights `xorm:"-" json:"-"` diff --git a/pkg/models/task_collection_filter.go b/pkg/models/task_collection_filter.go index ebf959ded..d6b29c6d9 100644 --- a/pkg/models/task_collection_filter.go +++ b/pkg/models/task_collection_filter.go @@ -62,7 +62,7 @@ type taskFilter struct { join taskFilterConcatinator } -func parseTimeFromUserInput(timeString string) (value modules.Time, err error) { +func parseTimeFromUserInput(timeString string) (value *modules.Time, err error) { var timeValue time.Time timeValue, err = time.Parse(time.RFC3339, timeString) if err != nil { @@ -90,9 +90,9 @@ func parseTimeFromUserInput(timeString string) (value modules.Time, err error) { return value, err } timeValue = time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC) - return modules.Time(timeValue.In(config.GetTimeZone())), nil + return modules.TimeFromTime(timeValue.In(config.GetTimeZone())), nil } - return modules.Time(timeValue.In(config.GetTimeZone())), nil + return modules.TimeFromTime(timeValue.In(config.GetTimeZone())), nil } func parseFilterFromExpression(f fexpr.ExprGroup, loc *time.Location) (filter *taskFilter, err error) { @@ -289,10 +289,10 @@ func getValueForField(field reflect.StructField, rawValue string, loc *time.Loca case reflect.Struct: if field.Type == reflect.TypeOf((*modules.Time)(nil)).Elem() { var t datemath.Expression - var tt modules.Time + var tt *modules.Time t, err = datemath.Parse(rawValue) if err == nil { - tt = modules.Time(t.Time(datemath.WithLocation(config.GetTimeZone())).In(loc)) + tt = modules.TimeFromTime(t.Time(datemath.WithLocation(config.GetTimeZone())).In(loc)) } else { tt, err = parseTimeFromUserInput(rawValue) } @@ -302,11 +302,23 @@ func getValueForField(field reflect.StructField, rawValue string, loc *time.Loca // Mysql/Mariadb does not support date values where the year < 1. To make this edge-case work, // we're setting the year to 1 in that case. if db.GetDialect() == builder.MYSQL && tt.Time().Year() < 1 { - tt = modules.Time(tt.Time().AddDate(1-tt.Time().Year(), 0, 0)) + tt = modules.TimeFromTime(tt.Time().AddDate(1-tt.Time().Year(), 0, 0)) } value = tt } - case reflect.Slice: + case reflect.Slice, reflect.Ptr: + // There are probably better ways to do this - please let me know if you have one. + if field.Type.Elem().String() == "time.Time" || field.Type.Elem().String() == "modules.Time" { + value, err = time.Parse(time.RFC3339, rawValue) + value = value.(time.Time).In(config.GetTimeZone()) + + if field.Type.Elem().String() == "modules.Time" { + value, err = parseTimeFromUserInput(rawValue) + } + + return + } + // If this is a slice of pointers we're dealing with some property which is a relation // In that case we don't really care about what the actual type is, we just cast the value to an // int64 since we need the id - yes, this assumes we only ever have int64 IDs, but this is fine. @@ -315,15 +327,9 @@ func getValueForField(field reflect.StructField, rawValue string, loc *time.Loca return } - // There are probably better ways to do this - please let me know if you have one. - if field.Type.Elem().String() == "time.Time" { - value, err = time.Parse(time.RFC3339, rawValue) - value = value.(time.Time).In(config.GetTimeZone()) - return - } fallthrough default: - panic(fmt.Errorf("unrecognized filter type %s for field %s, value %s", field.Type.String(), field.Name, value)) + panic(fmt.Errorf("unrecognized filter type %s for field %s (kind %s), value %s", field.Type.String(), field.Type.Kind(), field.Name, value)) } return diff --git a/pkg/models/task_collection_filter_test.go b/pkg/models/task_collection_filter_test.go index 0f84a7573..17f32423f 100644 --- a/pkg/models/task_collection_filter_test.go +++ b/pkg/models/task_collection_filter_test.go @@ -116,7 +116,7 @@ func TestParseFilter(t *testing.T) { require.Len(t, result, 1) assert.Equal(t, "due_date", result[0].field) in30Days := time.Now().Add(time.Hour * 24 * 30) - assert.Equal(t, in30Days.Unix(), result[0].value.(modules.Time).Unix()) + assert.Equal(t, in30Days.Unix(), result[0].value.(*modules.Time).Unix()) }) t.Run("date math strings with quotes", func(t *testing.T) { result, err := getTaskFiltersFromFilterString("due_date < 'now+30d'", "UTC") @@ -125,7 +125,7 @@ func TestParseFilter(t *testing.T) { require.Len(t, result, 1) assert.Equal(t, "due_date", result[0].field) in30Days := time.Now().Add(time.Hour * 24 * 30) - assert.Equal(t, in30Days.Unix(), result[0].value.(modules.Time).Unix()) + assert.Equal(t, in30Days.Unix(), result[0].value.(*modules.Time).Unix()) }) t.Run("string values with single quotes", func(t *testing.T) { result, err := getTaskFiltersFromFilterString("title = 'foo bar'", "UTC") @@ -247,7 +247,7 @@ func TestParseFilter(t *testing.T) { assert.Equal(t, "start_date", result[0].field) assert.Equal(t, taskFilterComparatorEquals, result[0].comparator) expectedDate, _ := time.Parse("2006-01-02", "2023-06-15") - assert.Equal(t, expectedDate.Unix(), result[0].value.(modules.Time).Unix()) + assert.Equal(t, expectedDate.Unix(), result[0].value.(*modules.Time).Unix()) }) t.Run("in query with multiple values", func(t *testing.T) { result, err := getTaskFiltersFromFilterString("priority in 1,3,5", "UTC") @@ -269,14 +269,14 @@ func TestParseFilter(t *testing.T) { assert.Equal(t, "done_at", result[0].field) assert.Equal(t, taskFilterComparatorGreater, result[0].comparator) sevenDaysAgo := time.Now().Add(-7 * 24 * time.Hour) - assert.Equal(t, sevenDaysAgo.Unix(), result[0].value.(modules.Time).Unix()) + assert.Equal(t, sevenDaysAgo.Unix(), result[0].value.(*modules.Time).Unix()) }) t.Run("date filter with 0000-01-01", func(t *testing.T) { result, err := getTaskFiltersFromFilterString("due_date > 0000-01-01", "UTC") require.NoError(t, err) require.Len(t, result, 1) - date := result[0].value.(modules.Time) + date := result[0].value.(*modules.Time) if db.GetDialect() == builder.MYSQL { assert.Equal(t, 1, date.Time().Year()) } else { diff --git a/pkg/models/task_collection_test.go b/pkg/models/task_collection_test.go index b88c1e167..aca3ce94b 100644 --- a/pkg/models/task_collection_test.go +++ b/pkg/models/task_collection_test.go @@ -117,8 +117,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { Index: 14, CreatedByID: 1, ProjectID: 1, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), }, }, }, @@ -134,7 +134,7 @@ func TestTaskCollection_ReadAll(t *testing.T) { ID: 1, Name: "test", Size: 100, - Created: modules.Time(time.Unix(1570998791, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1570998791, 0).In(loc)), CreatedByID: 1, }, }, @@ -157,13 +157,13 @@ func TestTaskCollection_ReadAll(t *testing.T) { ID: 1, Name: "test", Size: 100, - Created: modules.Time(time.Unix(1570998791, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1570998791, 0).In(loc)), CreatedByID: 1, }, }, }, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } var task1WithReaction = &Task{} *task1WithReaction = *task1 @@ -187,12 +187,12 @@ func TestTaskCollection_ReadAll(t *testing.T) { { ID: 3, TaskID: 2, - Reminder: modules.Time(time.Unix(1543626824, 0).In(loc)), - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), + Reminder: modules.TimeFromTime(time.Unix(1543626824, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), }, }, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task3 := &Task{ ID: 3, @@ -203,8 +203,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user1, ProjectID: 1, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), Priority: 100, } task4 := &Task{ @@ -216,8 +216,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user1, ProjectID: 1, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), Priority: 1, } task5 := &Task{ @@ -229,9 +229,9 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user1, ProjectID: 1, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), - DueDate: modules.Time(time.Unix(1543636724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + DueDate: modules.TimeFromTime(time.Unix(1543636724, 0).In(loc)), } task6 := &Task{ ID: 6, @@ -242,9 +242,9 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user1, ProjectID: 1, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), - DueDate: modules.Time(time.Unix(1543616724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + DueDate: modules.TimeFromTime(time.Unix(1543616724, 0).In(loc)), } task7 := &Task{ ID: 7, @@ -255,9 +255,9 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user1, ProjectID: 1, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), - StartDate: modules.Time(time.Unix(1544600000, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + StartDate: modules.TimeFromTime(time.Unix(1544600000, 0).In(loc)), } task8 := &Task{ ID: 8, @@ -268,9 +268,9 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user1, ProjectID: 1, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), - EndDate: modules.Time(time.Unix(1544700000, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + EndDate: modules.TimeFromTime(time.Unix(1544700000, 0).In(loc)), } task9 := &Task{ ID: 9, @@ -281,10 +281,10 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user1, ProjectID: 1, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), - StartDate: modules.Time(time.Unix(1544600000, 0).In(loc)), - EndDate: modules.Time(time.Unix(1544700000, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + StartDate: modules.TimeFromTime(time.Unix(1544600000, 0).In(loc)), + EndDate: modules.TimeFromTime(time.Unix(1544700000, 0).In(loc)), } task10 := &Task{ ID: 10, @@ -295,8 +295,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user1, ProjectID: 1, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task11 := &Task{ ID: 11, @@ -307,8 +307,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user1, ProjectID: 1, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task12 := &Task{ ID: 12, @@ -319,8 +319,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user1, ProjectID: 1, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task15 := &Task{ ID: 15, @@ -332,8 +332,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { ProjectID: 6, IsFavorite: true, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task16 := &Task{ ID: 16, @@ -344,8 +344,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user6, ProjectID: 7, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task17 := &Task{ ID: 17, @@ -356,8 +356,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user6, ProjectID: 8, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task18 := &Task{ ID: 18, @@ -368,8 +368,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user6, ProjectID: 9, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task19 := &Task{ ID: 19, @@ -380,8 +380,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user6, ProjectID: 10, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task20 := &Task{ ID: 20, @@ -392,8 +392,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user6, ProjectID: 11, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task21 := &Task{ ID: 21, @@ -404,8 +404,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user6, ProjectID: 32, // parent project is shared to user 1 via direct share RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task22 := &Task{ ID: 22, @@ -416,8 +416,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user6, ProjectID: 33, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task23 := &Task{ ID: 23, @@ -428,8 +428,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user6, ProjectID: 34, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task24 := &Task{ ID: 24, @@ -440,8 +440,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user6, ProjectID: 15, // parent project is shared to user 1 via team RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task25 := &Task{ ID: 25, @@ -452,8 +452,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user6, ProjectID: 16, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task26 := &Task{ ID: 26, @@ -464,8 +464,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user6, ProjectID: 17, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task27 := &Task{ ID: 27, @@ -478,23 +478,23 @@ func TestTaskCollection_ReadAll(t *testing.T) { { ID: 1, TaskID: 27, - Reminder: modules.Time(time.Unix(1543626724, 0).In(loc)), - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), + Reminder: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), }, { ID: 2, TaskID: 27, - Reminder: modules.Time(time.Unix(1543626824, 0).In(loc)), - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), + Reminder: modules.TimeFromTime(time.Unix(1543626824, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), RelativePeriod: -3600, RelativeTo: "start_date", }, }, - StartDate: modules.Time(time.Unix(1543616724, 0).In(loc)), + StartDate: modules.TimeFromTime(time.Unix(1543616724, 0).In(loc)), ProjectID: 1, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task28 := &Task{ ID: 28, @@ -506,8 +506,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { ProjectID: 1, RelatedTasks: map[RelationKind][]*Task{}, RepeatAfter: 3600, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task29 := &Task{ ID: 29, @@ -527,13 +527,13 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedByID: 1, ProjectID: 1, IsFavorite: true, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), }, }, }, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task30 := &Task{ ID: 30, @@ -548,8 +548,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { user2, }, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task31 := &Task{ ID: 31, @@ -561,8 +561,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user1, ProjectID: 1, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task32 := &Task{ ID: 32, @@ -573,8 +573,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user1, ProjectID: 3, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task33 := &Task{ ID: 33, @@ -586,8 +586,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { ProjectID: 1, PercentDone: 0.5, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task35 := &Task{ ID: 35, @@ -614,8 +614,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedByID: 1, ProjectID: 1, IsFavorite: true, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), }, { ID: 1, @@ -625,13 +625,13 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedByID: 1, ProjectID: 1, IsFavorite: true, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), }, }, }, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } task39 := &Task{ ID: 39, @@ -641,8 +641,8 @@ func TestTaskCollection_ReadAll(t *testing.T) { CreatedBy: user1, ProjectID: 25, RelatedTasks: map[RelationKind][]*Task{}, - Created: modules.Time(time.Unix(1543626724, 0).In(loc)), - Updated: modules.Time(time.Unix(1543626724, 0).In(loc)), + Created: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), + Updated: modules.TimeFromTime(time.Unix(1543626724, 0).In(loc)), } type fields struct { diff --git a/pkg/models/task_comments.go b/pkg/models/task_comments.go index c22fe6b1c..72e8257fb 100644 --- a/pkg/models/task_comments.go +++ b/pkg/models/task_comments.go @@ -38,8 +38,8 @@ type TaskComment struct { Reactions ReactionMap `xorm:"-" json:"reactions"` - Created modules.Time `xorm:"created" json:"created"` - Updated modules.Time `xorm:"updated" json:"updated"` + Created *modules.Time `xorm:"created" json:"created"` + Updated *modules.Time `xorm:"updated" json:"updated"` web.CRUDable `xorm:"-" json:"-"` web.Rights `xorm:"-" json:"-"` @@ -66,8 +66,8 @@ func (tc *TaskComment) TableName() string { func (tc *TaskComment) Create(s *xorm.Session, a web.Auth) (err error) { tc.ID = 0 - tc.Created = modules.Time{} - tc.Updated = modules.Time{} + tc.Created = &modules.Time{} + tc.Updated = &modules.Time{} return tc.CreateWithTimestamps(s, a) } diff --git a/pkg/models/task_relation.go b/pkg/models/task_relation.go index 612c4c98b..ebe900093 100644 --- a/pkg/models/task_relation.go +++ b/pkg/models/task_relation.go @@ -92,7 +92,7 @@ type TaskRelation struct { CreatedBy *user.User `xorm:"-" json:"created_by"` // A timestamp when this label was created. You cannot change this value. - Created modules.Time `xorm:"created not null" json:"created"` + Created *modules.Time `xorm:"created not null" json:"created"` web.CRUDable `xorm:"-" json:"-"` web.Rights `xorm:"-" json:"-"` diff --git a/pkg/models/task_reminder.go b/pkg/models/task_reminder.go index fc87c910f..378a39867 100644 --- a/pkg/models/task_reminder.go +++ b/pkg/models/task_reminder.go @@ -51,8 +51,8 @@ type TaskReminder struct { ID int64 `xorm:"bigint autoincr not null unique pk" json:"-"` TaskID int64 `xorm:"bigint not null INDEX" json:"-"` // The absolute time when the user wants to be reminded of the task. - Reminder modules.Time `xorm:"DATETIME not null INDEX 'reminder'" json:"reminder"` - Created modules.Time `xorm:"created not null" json:"-"` + Reminder *modules.Time `xorm:"DATETIME not null INDEX 'reminder'" json:"reminder"` + Created *modules.Time `xorm:"created not null" json:"-"` // A period in seconds relative to another date argument. Negative values mean the reminder triggers before the date. Default: 0, tiggers when RelativeTo is due. RelativePeriod int64 `xorm:"bigint null" json:"relative_period"` // The name of the date field to which the relative period refers to. diff --git a/pkg/models/task_search.go b/pkg/models/task_search.go index b02653dc6..d175f47b9 100644 --- a/pkg/models/task_search.go +++ b/pkg/models/task_search.go @@ -464,7 +464,7 @@ func convertFilterValues(value interface{}) string { } return "false" - case modules.Time: + case *modules.Time: return strconv.FormatInt(v.Time().Unix(), 10) case time.Time: return strconv.FormatInt(v.Unix(), 10) diff --git a/pkg/models/tasks.go b/pkg/models/tasks.go index 636b39ef1..90fcb6c80 100644 --- a/pkg/models/tasks.go +++ b/pkg/models/tasks.go @@ -61,9 +61,9 @@ type Task struct { // Whether a task is done or not. Done bool `xorm:"INDEX null" json:"done"` // The time when a task was marked as done. - DoneAt modules.Time `xorm:"INDEX null 'done_at'" json:"done_at"` + DoneAt *modules.Time `xorm:"INDEX null 'done_at'" json:"done_at"` // The time when the task is due. - DueDate modules.Time `xorm:"DATETIME INDEX null 'due_date'" json:"due_date"` + DueDate *modules.Time `xorm:"DATETIME INDEX null 'due_date'" json:"due_date"` // An array of reminders that are associated with this task. Reminders []*TaskReminder `xorm:"-" json:"reminders"` // The project this task belongs to. @@ -75,9 +75,9 @@ type Task struct { // The task priority. Can be anything you want, it is possible to sort by this later. Priority int64 `xorm:"bigint null" json:"priority"` // When this task starts. - StartDate modules.Time `xorm:"DATETIME INDEX null 'start_date'" json:"start_date" query:"-"` + StartDate *modules.Time `xorm:"DATETIME INDEX null 'start_date'" json:"start_date" query:"-"` // When this task ends. - EndDate modules.Time `xorm:"DATETIME INDEX null 'end_date'" json:"end_date" query:"-"` + EndDate *modules.Time `xorm:"DATETIME INDEX null 'end_date'" json:"end_date" query:"-"` // An array of users who are assigned to this task Assignees []*user.User `xorm:"-" json:"assignees"` // An array of labels which are associated with this task. This property is read-only, you must use the separate endpoint to add labels to a task. @@ -112,9 +112,9 @@ type Task struct { Subscription *Subscription `xorm:"-" json:"subscription,omitempty"` // A timestamp when this task was created. You cannot change this value. - Created modules.Time `xorm:"created not null" json:"created"` + Created *modules.Time `xorm:"created not null" json:"created"` // A timestamp when this task was last updated. You cannot change this value. - Updated modules.Time `xorm:"updated not null" json:"updated"` + Updated *modules.Time `xorm:"updated not null" json:"updated"` // The bucket id. Will only be populated when the task is accessed via a view with buckets. // Can be used to move a task between buckets. In that case, the new bucket must be in the same view as the old one. @@ -1253,20 +1253,20 @@ func (t *Task) Update(s *xorm.Session, a web.Auth) (err error) { ot.Description = "" } // Due date - if t.DueDate.Time().IsZero() { - ot.DueDate = modules.Time{} + if t.DueDate != nil && t.DueDate.Time().IsZero() { + ot.DueDate = &modules.Time{} } // Repeat after if t.RepeatAfter == 0 { ot.RepeatAfter = 0 } // Start date - if t.StartDate.Time().IsZero() { - ot.StartDate = modules.Time{} + if t.StartDate != nil && t.StartDate.Time().IsZero() { + ot.StartDate = &modules.Time{} } // End date - if t.EndDate.Time().IsZero() { - ot.EndDate = modules.Time{} + if t.EndDate != nil && t.EndDate.Time().IsZero() { + ot.EndDate = &modules.Time{} } // Color if t.HexColor == "" { @@ -1318,9 +1318,9 @@ func (t *Task) Update(s *xorm.Session, a web.Auth) (err error) { return updateProjectLastUpdated(s, &Project{ID: t.ProjectID}) } -func addOneMonthToDate(dd modules.Time) modules.Time { +func addOneMonthToDate(dd *modules.Time) *modules.Time { d := dd.Time() - return modules.Time(time.Date(d.Year(), d.Month()+1, d.Day(), d.Hour(), d.Minute(), d.Second(), d.Nanosecond(), config.GetTimeZone())) + return modules.TimeFromTime(time.Date(d.Year(), d.Month()+1, d.Day(), d.Hour(), d.Minute(), d.Second(), d.Nanosecond(), config.GetTimeZone())) } func setTaskDatesDefault(oldTask, newTask *Task) { @@ -1329,7 +1329,7 @@ func setTaskDatesDefault(oldTask, newTask *Task) { } // Current time in an extra variable to base all calculations on the same time - now := modules.Time(time.Now()) + now := modules.TimeFromTime(time.Now()) repeatDuration := time.Duration(oldTask.RepeatAfter) * time.Second @@ -1409,7 +1409,7 @@ func setTaskDatesFromCurrentDateRepeat(oldTask, newTask *Task) { } // Current time in an extra variable to base all calculations on the same time - now := modules.Time(time.Now()) + now := modules.TimeFromTime(time.Now()) repeatDuration := time.Duration(oldTask.RepeatAfter) * time.Second @@ -1487,12 +1487,12 @@ func updateDone(oldTask *Task, newTask *Task) { setTaskDatesDefault(oldTask, newTask) } - newTask.DoneAt = modules.Time(time.Now()) + newTask.DoneAt = modules.TimeFromTime(time.Now()) } // When unmarking a task as done, reset the timestamp if oldTask.Done && !newTask.Done { - newTask.DoneAt = modules.Time{} + newTask.DoneAt = &modules.Time{} } } @@ -1501,7 +1501,7 @@ func updateRelativeReminderDates(task *Task) (err error) { for _, reminder := range task.Reminders { relativeDuration := time.Duration(reminder.RelativePeriod) * time.Second if reminder.RelativeTo != "" { - reminder.Reminder = modules.Time{} + reminder.Reminder = &modules.Time{} } switch reminder.RelativeTo { case ReminderRelationDueDate: diff --git a/pkg/models/tasks_test.go b/pkg/models/tasks_test.go index fd5036775..0dada7bd3 100644 --- a/pkg/models/tasks_test.go +++ b/pkg/models/tasks_test.go @@ -82,9 +82,9 @@ func TestTask_Create(t *testing.T) { Title: "Lorem", Description: "Lorem Ipsum Dolor", ProjectID: 1, - DueDate: modules.Time(time.Date(2023, time.March, 7, 22, 5, 0, 0, time.Local)), - StartDate: modules.Time(time.Date(2023, time.March, 7, 22, 5, 10, 0, time.Local)), - EndDate: modules.Time(time.Date(2023, time.March, 7, 22, 5, 20, 0, time.Local)), + DueDate: modules.TimeFromTime(time.Date(2023, time.March, 7, 22, 5, 0, 0, time.Local)), + StartDate: modules.TimeFromTime(time.Date(2023, time.March, 7, 22, 5, 10, 0, time.Local)), + EndDate: modules.TimeFromTime(time.Date(2023, time.March, 7, 22, 5, 20, 0, time.Local)), Reminders: []*TaskReminder{ { RelativeTo: "due_date", @@ -99,7 +99,7 @@ func TestTask_Create(t *testing.T) { RelativePeriod: -1, }, { - Reminder: modules.Time(time.Date(2023, time.March, 7, 23, 0, 0, 0, time.Local)), + Reminder: modules.TimeFromTime(time.Date(2023, time.March, 7, 23, 0, 0, 0, time.Local)), }, }} err := task.Create(s, usr) @@ -360,9 +360,9 @@ func TestTask_Update(t *testing.T) { ID: 1, ProjectID: 1, Title: "test", - DueDate: modules.Time(time.Date(2023, time.March, 7, 22, 5, 0, 0, time.Local)), - StartDate: modules.Time(time.Date(2023, time.March, 7, 22, 5, 10, 0, time.Local)), - EndDate: modules.Time(time.Date(2023, time.March, 7, 22, 5, 20, 0, time.Local)), + DueDate: modules.TimeFromTime(time.Date(2023, time.March, 7, 22, 5, 0, 0, time.Local)), + StartDate: modules.TimeFromTime(time.Date(2023, time.March, 7, 22, 5, 10, 0, time.Local)), + EndDate: modules.TimeFromTime(time.Date(2023, time.March, 7, 22, 5, 20, 0, time.Local)), Reminders: []*TaskReminder{ { RelativeTo: "due_date", @@ -377,7 +377,7 @@ func TestTask_Update(t *testing.T) { RelativePeriod: -1, }, { - Reminder: modules.Time(time.Date(2023, time.March, 7, 23, 0, 0, 0, time.Local)), + Reminder: modules.TimeFromTime(time.Date(2023, time.March, 7, 23, 0, 0, 0, time.Local)), }, }} err := task.Update(s, u) @@ -404,10 +404,10 @@ func TestTask_Update(t *testing.T) { Title: "test", Reminders: []*TaskReminder{ { - Reminder: modules.Time(time.Unix(1674745156, 0)), + Reminder: modules.TimeFromTime(time.Unix(1674745156, 0)), }, { - Reminder: modules.Time(time.Unix(1674745156, 223)), + Reminder: modules.TimeFromTime(time.Unix(1674745156, 223)), }, }, ProjectID: 1, @@ -427,7 +427,7 @@ func TestTask_Update(t *testing.T) { taskBefore := &Task{ Title: "test", ProjectID: 1, - StartDate: modules.Time(time.Date(2022, time.March, 8, 8, 5, 20, 0, time.Local)), + StartDate: modules.TimeFromTime(time.Date(2022, time.March, 8, 8, 5, 20, 0, time.Local)), Reminders: []*TaskReminder{ { RelativeTo: "start_date", @@ -442,7 +442,7 @@ func TestTask_Update(t *testing.T) { // when start_date is modified task := taskBefore - task.StartDate = modules.Time(time.Date(2023, time.March, 8, 8, 5, 0, 0, time.Local)) + task.StartDate = modules.TimeFromTime(time.Date(2023, time.March, 8, 8, 5, 0, 0, time.Local)) err = task.Update(s, u) require.NoError(t, err) @@ -482,7 +482,7 @@ func TestUpdateDone(t *testing.T) { oldTask := &Task{Done: false} newTask := &Task{Done: true} updateDone(oldTask, newTask) - assert.NotEqual(t, modules.Time{}, newTask.DoneAt) + assert.NotEqual(t, &modules.Time{}, newTask.DoneAt) }) t.Run("unmarking a task as done", func(t *testing.T) { db.LoadAndAssertFixtures(t) @@ -492,10 +492,10 @@ func TestUpdateDone(t *testing.T) { oldTask := &Task{Done: true} newTask := &Task{Done: false} updateDone(oldTask, newTask) - assert.Equal(t, modules.Time{}, newTask.DoneAt) + assert.Equal(t, &modules.Time{}, newTask.DoneAt) }) t.Run("no interval set, default repeat mode", func(t *testing.T) { - dueDate := modules.Time(time.Unix(1550000000, 0)) + dueDate := modules.TimeFromTime(time.Unix(1550000000, 0)) oldTask := &Task{ Done: false, RepeatAfter: 0, @@ -516,7 +516,7 @@ func TestUpdateDone(t *testing.T) { oldTask := &Task{ Done: false, RepeatAfter: 8600, - DueDate: modules.Time(time.Unix(1550000000, 0)), + DueDate: modules.TimeFromTime(time.Unix(1550000000, 0)), } newTask := &Task{ Done: true, @@ -535,11 +535,11 @@ func TestUpdateDone(t *testing.T) { oldTask := &Task{ Done: false, RepeatAfter: 8600, - DueDate: modules.Time{}, + DueDate: &modules.Time{}, } newTask := &Task{ Done: true, - DueDate: modules.Time(time.Unix(1543626724, 0)), + DueDate: modules.TimeFromTime(time.Unix(1543626724, 0)), } updateDone(oldTask, newTask) assert.Equal(t, time.Unix(1543626724, 0), newTask.DueDate) @@ -551,10 +551,10 @@ func TestUpdateDone(t *testing.T) { RepeatAfter: 8600, Reminders: []*TaskReminder{ { - Reminder: modules.Time(time.Unix(1550000000, 0)), + Reminder: modules.TimeFromTime(time.Unix(1550000000, 0)), }, { - Reminder: modules.Time(time.Unix(1555000000, 0)), + Reminder: modules.TimeFromTime(time.Unix(1555000000, 0)), }, }, } @@ -581,7 +581,7 @@ func TestUpdateDone(t *testing.T) { oldTask := &Task{ Done: false, RepeatAfter: 8600, - StartDate: modules.Time(time.Unix(1550000000, 0)), + StartDate: modules.TimeFromTime(time.Unix(1550000000, 0)), } newTask := &Task{ Done: true, @@ -600,7 +600,7 @@ func TestUpdateDone(t *testing.T) { oldTask := &Task{ Done: false, RepeatAfter: 8600, - EndDate: modules.Time(time.Unix(1550000000, 0)), + EndDate: modules.TimeFromTime(time.Unix(1550000000, 0)), } newTask := &Task{ Done: true, @@ -619,7 +619,7 @@ func TestUpdateDone(t *testing.T) { oldTask := &Task{ Done: false, RepeatAfter: 8600, - DueDate: modules.Time(time.Now().Add(time.Hour)), + DueDate: modules.TimeFromTime(time.Now().Add(time.Hour)), } newTask := &Task{ Done: true, @@ -635,7 +635,7 @@ func TestUpdateDone(t *testing.T) { Done: false, RepeatAfter: 8600, RepeatMode: TaskRepeatModeFromCurrentDate, - DueDate: modules.Time(time.Unix(1550000000, 0)), + DueDate: modules.TimeFromTime(time.Unix(1550000000, 0)), } newTask := &Task{ Done: true, @@ -653,10 +653,10 @@ func TestUpdateDone(t *testing.T) { RepeatMode: TaskRepeatModeFromCurrentDate, Reminders: []*TaskReminder{ { - Reminder: modules.Time(time.Unix(1550000000, 0)), + Reminder: modules.TimeFromTime(time.Unix(1550000000, 0)), }, { - Reminder: modules.Time(time.Unix(1555000000, 0)), + Reminder: modules.TimeFromTime(time.Unix(1555000000, 0)), }, }} newTask := &Task{ @@ -677,7 +677,7 @@ func TestUpdateDone(t *testing.T) { Done: false, RepeatAfter: 8600, RepeatMode: TaskRepeatModeFromCurrentDate, - StartDate: modules.Time(time.Unix(1550000000, 0)), + StartDate: modules.TimeFromTime(time.Unix(1550000000, 0)), } newTask := &Task{ Done: true, @@ -693,7 +693,7 @@ func TestUpdateDone(t *testing.T) { Done: false, RepeatAfter: 8600, RepeatMode: TaskRepeatModeFromCurrentDate, - EndDate: modules.Time(time.Unix(1560000000, 0)), + EndDate: modules.TimeFromTime(time.Unix(1560000000, 0)), } newTask := &Task{ Done: true, @@ -709,8 +709,8 @@ func TestUpdateDone(t *testing.T) { Done: false, RepeatAfter: 8600, RepeatMode: TaskRepeatModeFromCurrentDate, - StartDate: modules.Time(time.Unix(1550000000, 0)), - EndDate: modules.Time(time.Unix(1560000000, 0)), + StartDate: modules.TimeFromTime(time.Unix(1550000000, 0)), + EndDate: modules.TimeFromTime(time.Unix(1560000000, 0)), } newTask := &Task{ Done: true, @@ -730,7 +730,7 @@ func TestUpdateDone(t *testing.T) { oldTask := &Task{ Done: false, RepeatMode: TaskRepeatModeMonth, - DueDate: modules.Time(time.Unix(1550000000, 0)), + DueDate: modules.TimeFromTime(time.Unix(1550000000, 0)), } newTask := &Task{ Done: true, @@ -749,16 +749,16 @@ func TestUpdateDone(t *testing.T) { RepeatMode: TaskRepeatModeMonth, Reminders: []*TaskReminder{ { - Reminder: modules.Time(time.Unix(1550000000, 0)), + Reminder: modules.TimeFromTime(time.Unix(1550000000, 0)), }, { - Reminder: modules.Time(time.Unix(1555000000, 0)), + Reminder: modules.TimeFromTime(time.Unix(1555000000, 0)), }, }} newTask := &Task{ Done: true, } - oldReminders := make([]modules.Time, len(oldTask.Reminders)) + oldReminders := make([]*modules.Time, len(oldTask.Reminders)) for i, r := range newTask.Reminders { oldReminders[i] = r.Reminder } @@ -776,7 +776,7 @@ func TestUpdateDone(t *testing.T) { oldTask := &Task{ Done: false, RepeatMode: TaskRepeatModeMonth, - StartDate: modules.Time(time.Unix(1550000000, 0)), + StartDate: modules.TimeFromTime(time.Unix(1550000000, 0)), } newTask := &Task{ Done: true, @@ -793,7 +793,7 @@ func TestUpdateDone(t *testing.T) { oldTask := &Task{ Done: false, RepeatMode: TaskRepeatModeMonth, - EndDate: modules.Time(time.Unix(1560000000, 0)), + EndDate: modules.TimeFromTime(time.Unix(1560000000, 0)), } newTask := &Task{ Done: true, @@ -810,8 +810,8 @@ func TestUpdateDone(t *testing.T) { oldTask := &Task{ Done: false, RepeatMode: TaskRepeatModeMonth, - StartDate: modules.Time(time.Unix(1550000000, 0)), - EndDate: modules.Time(time.Unix(1560000000, 0)), + StartDate: modules.TimeFromTime(time.Unix(1550000000, 0)), + EndDate: modules.TimeFromTime(time.Unix(1560000000, 0)), } newTask := &Task{ Done: true, diff --git a/pkg/models/teams.go b/pkg/models/teams.go index 23338935c..a723c5a32 100644 --- a/pkg/models/teams.go +++ b/pkg/models/teams.go @@ -49,9 +49,9 @@ type Team struct { Members []*TeamUser `xorm:"-" json:"members"` // A timestamp when this relation was created. You cannot change this value. - Created modules.Time `xorm:"created" json:"created"` + Created *modules.Time `xorm:"created" json:"created"` // A timestamp when this relation was last updated. You cannot change this value. - Updated modules.Time `xorm:"updated" json:"updated"` + Updated *modules.Time `xorm:"updated" json:"updated"` // Defines wether the team should be publicly discoverable when sharing a project IsPublic bool `xorm:"not null default false" json:"is_public"` @@ -82,7 +82,7 @@ type TeamMember struct { Admin bool `xorm:"null" json:"admin"` // A timestamp when this relation was created. You cannot change this value. - Created modules.Time `xorm:"created not null" json:"created"` + Created *modules.Time `xorm:"created not null" json:"created"` web.CRUDable `xorm:"-" json:"-"` web.Rights `xorm:"-" json:"-"` diff --git a/pkg/models/teams_rights_test.go b/pkg/models/teams_rights_test.go index 66bcd9727..bec34e463 100644 --- a/pkg/models/teams_rights_test.go +++ b/pkg/models/teams_rights_test.go @@ -33,8 +33,8 @@ func TestTeam_CanDoSomething(t *testing.T) { CreatedByID int64 CreatedBy *user.User Members []*TeamUser - Created modules.Time - Updated modules.Time + Created *modules.Time + Updated *modules.Time CRUDable web.CRUDable Rights web.Rights } diff --git a/pkg/models/typesense.go b/pkg/models/typesense.go index b71c00efd..9254e2aff 100644 --- a/pkg/models/typesense.go +++ b/pkg/models/typesense.go @@ -367,10 +367,10 @@ func indexDummyTask() (err error) { { ID: -10, TaskID: -100, - Reminder: modules.Time(time.Now()), + Reminder: modules.TimeFromTime(time.Now()), RelativePeriod: 10, RelativeTo: ReminderRelationDueDate, - Created: modules.Time(time.Now()), + Created: modules.TimeFromTime(time.Now()), }, }, Assignees: []*user.User{ @@ -379,8 +379,8 @@ func indexDummyTask() (err error) { Username: "dummy", Name: "dummy", Email: "dummy@vikunja", - Created: modules.Time(time.Now()), - Updated: modules.Time(time.Now()), + Created: modules.TimeFromTime(time.Now()), + Updated: modules.TimeFromTime(time.Now()), }, }, Labels: []*Label{ @@ -389,30 +389,30 @@ func indexDummyTask() (err error) { Title: "dummylabel", Description: "Lorem Ipsum Dummy", HexColor: "000000", - Created: modules.Time(time.Now()), - Updated: modules.Time(time.Now()), + Created: modules.TimeFromTime(time.Now()), + Updated: modules.TimeFromTime(time.Now()), }, }, Attachments: []*TaskAttachment{ { ID: -120, TaskID: -100, - Created: modules.Time(time.Now()), + Created: modules.TimeFromTime(time.Now()), }, }, Comments: []*TaskComment{ { ID: -220, Comment: "Lorem Ipsum Dummy", - Created: modules.Time(time.Now()), - Updated: modules.Time(time.Now()), + Created: modules.TimeFromTime(time.Now()), + Updated: modules.TimeFromTime(time.Now()), Author: &user.User{ ID: -100, Username: "dummy", Name: "dummy", Email: "dummy@vikunja", - Created: modules.Time(time.Now()), - Updated: modules.Time(time.Now()), + Created: modules.TimeFromTime(time.Now()), + Updated: modules.TimeFromTime(time.Now()), }, }, }, diff --git a/pkg/models/user_delete.go b/pkg/models/user_delete.go index 3778dee67..18330e93c 100644 --- a/pkg/models/user_delete.go +++ b/pkg/models/user_delete.go @@ -57,10 +57,10 @@ func deleteUsers() { log.Debugf("Found %d users scheduled for deletion", len(users)) - now := time.Now() + now := modules.TimeFromTime(time.Now()) for _, u := range users { - if !u.DeletionScheduledAt.Before(modules.Time(now)) { + if !u.DeletionScheduledAt.Before(now) { log.Debugf("User %d is not yet scheduled for deletion. Scheduled at %s, now is %s", u.ID, u.DeletionScheduledAt, now) continue } diff --git a/pkg/models/webhooks.go b/pkg/models/webhooks.go index 2ba05eba4..6492f3080 100644 --- a/pkg/models/webhooks.go +++ b/pkg/models/webhooks.go @@ -62,9 +62,9 @@ type Webhook struct { CreatedByID int64 `xorm:"bigint not null" json:"-"` // A timestamp when this webhook target was created. You cannot change this value. - Created modules.Time `xorm:"created not null" json:"created"` + Created *modules.Time `xorm:"created not null" json:"created"` // A timestamp when this webhook target was last updated. You cannot change this value. - Updated modules.Time `xorm:"updated not null" json:"updated"` + Updated *modules.Time `xorm:"updated not null" json:"updated"` web.CRUDable `xorm:"-" json:"-"` web.Rights `xorm:"-" json:"-"` diff --git a/pkg/modules/migration/microsoft-todo/microsoft_todo.go b/pkg/modules/migration/microsoft-todo/microsoft_todo.go index 0eec93fef..d38ce433a 100644 --- a/pkg/modules/migration/microsoft-todo/microsoft_todo.go +++ b/pkg/modules/migration/microsoft-todo/microsoft_todo.go @@ -55,8 +55,8 @@ type task struct { IsReminderOn bool `json:"isReminderOn"` Status string `json:"status"` Title string `json:"title"` - CreatedDateTime modules.Time `json:"createdDateTime"` - LastModifiedDateTime modules.Time `json:"lastModifiedDateTime"` + CreatedDateTime *modules.Time `json:"createdDateTime"` + LastModifiedDateTime *modules.Time `json:"lastModifiedDateTime"` ID string `json:"id"` Body *body `json:"body"` DueDateTime *dateTimeTimeZone `json:"dueDateTime"` @@ -114,14 +114,14 @@ type projectsResponse struct { Value []*project `json:"value"` } -func (dtt *dateTimeTimeZone) toTime() (t modules.Time, err error) { +func (dtt *dateTimeTimeZone) toTime() (t *modules.Time, err error) { loc, err := time.LoadLocation(dtt.TimeZone) if err != nil { return t, err } tt, err := time.ParseInLocation(time.RFC3339Nano, dtt.DateTime+"Z", loc) - return modules.Time(tt), err + return modules.TimeFromTime(tt), err } // AuthURL returns the url users need to authenticate against diff --git a/pkg/modules/migration/microsoft-todo/microsoft_todo_test.go b/pkg/modules/migration/microsoft-todo/microsoft_todo_test.go index ba1de26b4..1ddfbbd3b 100644 --- a/pkg/modules/migration/microsoft-todo/microsoft_todo_test.go +++ b/pkg/modules/migration/microsoft-todo/microsoft_todo_test.go @@ -37,7 +37,7 @@ func TestConverting(t *testing.T) { testTime, err := time.Parse(time.RFC3339Nano, "2020-12-18T03:00:00.4770000Z") require.NoError(t, err) - testtimeTime := modules.Time(testTime) + testtimeTime := modules.TimeFromTime(testTime) microsoftTodoData := []*project{ { diff --git a/pkg/modules/migration/ticktick/ticktick.go b/pkg/modules/migration/ticktick/ticktick.go index bc431d1e6..964bfadae 100644 --- a/pkg/modules/migration/ticktick/ticktick.go +++ b/pkg/modules/migration/ticktick/ticktick.go @@ -63,11 +63,11 @@ type tickTickTask struct { } type tickTickTime struct { - modules.Time + *modules.Time } func (date *tickTickTime) UnmarshalCSV(csv string) (err error) { - date.Time = modules.Time{} + date.Time = &modules.Time{} if csv == "" { return nil } @@ -75,7 +75,7 @@ func (date *tickTickTime) UnmarshalCSV(csv string) (err error) { if err != nil { return err } - date.Time = modules.Time(tt) + date.Time = modules.TimeFromTime(tt) return nil } @@ -115,17 +115,17 @@ func convertTickTickToVikunja(tasks []*tickTickTask) (result []*models.ProjectWi ID: t.TaskID, Title: t.Title, Description: t.Content, - StartDate: modules.Time(t.StartDate.Time), - EndDate: modules.Time(t.DueDate.Time), - DueDate: modules.Time(t.DueDate.Time), + StartDate: t.StartDate.Time, + EndDate: t.DueDate.Time, + DueDate: t.DueDate.Time, Done: t.Status == "1", - DoneAt: modules.Time(t.CompletedTime.Time), + DoneAt: t.CompletedTime.Time, Position: t.Order, Labels: labels, }, } - if !t.DueDate.IsZero() && t.Reminder > 0 { + if (t.DueDate.Time != nil && !t.DueDate.IsZero()) && t.Reminder > 0 { task.Task.Reminders = []*models.TaskReminder{ { RelativeTo: models.ReminderRelationDueDate, diff --git a/pkg/modules/migration/ticktick/ticktick_test.go b/pkg/modules/migration/ticktick/ticktick_test.go index a6f5fdd6b..55f93d059 100644 --- a/pkg/modules/migration/ticktick/ticktick_test.go +++ b/pkg/modules/migration/ticktick/ticktick_test.go @@ -29,13 +29,13 @@ import ( func TestConvertTicktickTasksToVikunja(t *testing.T) { t1, err := time.Parse(time.RFC3339Nano, "2022-11-18T03:00:00.4770000Z") require.NoError(t, err) - time1 := tickTickTime{Time: modules.Time(t1)} + time1 := tickTickTime{Time: modules.TimeFromTime(t1)} t2, err := time.Parse(time.RFC3339Nano, "2022-12-18T03:00:00.4770000Z") require.NoError(t, err) - time2 := tickTickTime{Time: modules.Time(t2)} + time2 := tickTickTime{Time: modules.TimeFromTime(t2)} t3, err := time.Parse(time.RFC3339Nano, "2022-12-10T03:00:00.4770000Z") require.NoError(t, err) - time3 := tickTickTime{Time: modules.Time(t3)} + time3 := tickTickTime{Time: modules.TimeFromTime(t3)} duration, err := time.ParseDuration("24h") require.NoError(t, err) diff --git a/pkg/modules/migration/todoist/todoist.go b/pkg/modules/migration/todoist/todoist.go index 6992c378d..1b2425e7c 100644 --- a/pkg/modules/migration/todoist/todoist.go +++ b/pkg/modules/migration/todoist/todoist.go @@ -78,24 +78,24 @@ type dueDate struct { } type item struct { - ID string `json:"id"` - UserID string `json:"user_id"` - ProjectID string `json:"project_id"` - Content string `json:"content"` - Priority int64 `json:"priority"` - Due *dueDate `json:"due"` - ParentID string `json:"parent_id"` - ChildOrder int64 `json:"child_order"` - SectionID string `json:"section_id"` - Children interface{} `json:"children"` - Labels []string `json:"labels"` - AddedByUID string `json:"added_by_uid"` - AssignedByUID string `json:"assigned_by_uid"` - ResponsibleUID string `json:"responsible_uid"` - Checked bool `json:"checked"` - DateAdded modules.Time `json:"added_at"` - HasMoreNotes bool `json:"has_more_notes"` - DateCompleted modules.Time `json:"completed_at"` + ID string `json:"id"` + UserID string `json:"user_id"` + ProjectID string `json:"project_id"` + Content string `json:"content"` + Priority int64 `json:"priority"` + Due *dueDate `json:"due"` + ParentID string `json:"parent_id"` + ChildOrder int64 `json:"child_order"` + SectionID string `json:"section_id"` + Children interface{} `json:"children"` + Labels []string `json:"labels"` + AddedByUID string `json:"added_by_uid"` + AssignedByUID string `json:"assigned_by_uid"` + ResponsibleUID string `json:"responsible_uid"` + Checked bool `json:"checked"` + DateAdded *modules.Time `json:"added_at"` + HasMoreNotes bool `json:"has_more_notes"` + DateCompleted *modules.Time `json:"completed_at"` } type itemWrapper struct { @@ -103,11 +103,11 @@ type itemWrapper struct { } type doneItem struct { - CompletedDate modules.Time `json:"completed_at"` - Content string `json:"content"` - ID string `json:"id"` - ProjectID string `json:"project_id"` - TaskID string `json:"task_id"` + CompletedDate *modules.Time `json:"completed_at"` + Content string `json:"content"` + ID string `json:"id"` + ProjectID string `json:"project_id"` + TaskID string `json:"task_id"` } type doneItemSync struct { @@ -129,14 +129,14 @@ type note struct { ItemID string `json:"item_id"` Content string `json:"content"` FileAttachment *fileAttachment `json:"file_attachment"` - Posted modules.Time `json:"posted_at"` + Posted *modules.Time `json:"posted_at"` } type projectNote struct { Content string `json:"content"` FileAttachment *fileAttachment `json:"file_attachment"` ID string `json:"id"` - Posted modules.Time `json:"posted"` + Posted *modules.Time `json:"posted"` ProjectID string `json:"project_id"` } @@ -149,12 +149,12 @@ type reminder struct { } type section struct { - ID string `json:"id"` - DateAdded modules.Time `json:"added_at"` - IsDeleted bool `json:"is_deleted"` - Name string `json:"name"` - ProjectID string `json:"project_id"` - SectionOrder int64 `json:"section_order"` + ID string `json:"id"` + DateAdded *modules.Time `json:"added_at"` + IsDeleted bool `json:"is_deleted"` + Name string `json:"name"` + ProjectID string `json:"project_id"` + SectionOrder int64 `json:"section_order"` } type sync struct { @@ -225,13 +225,13 @@ func (m *Migration) AuthURL() string { "&state=" + utils.MakeRandomString(32) } -func parseDate(dateString string) (date modules.Time, err error) { +func parseDate(dateString string) (date *modules.Time, err error) { if len(dateString) == 10 { // We're probably dealing with a date in the form of 2021-11-23 without a time tdate, err := time.Parse("2006-01-02", dateString) if err == nil { // round the day to eod - date = modules.Time(tdate) + date = modules.TimeFromTime(tdate) return date.Add(time.Hour*23 + time.Minute*59), nil } } @@ -244,7 +244,7 @@ func parseDate(dateString string) (date modules.Time, err error) { tdate, err = time.Parse("2006-01-02", dateString) } - return modules.Time(tdate), err + return modules.TimeFromTime(tdate), err } func convertTodoistToVikunja(sync *sync, doneItems map[string]*doneItem) (fullVikunjaHierachie []*models.ProjectWithTasksAndBuckets, err error) { diff --git a/pkg/modules/migration/todoist/todoist_test.go b/pkg/modules/migration/todoist/todoist_test.go index 092269776..83f61349c 100644 --- a/pkg/modules/migration/todoist/todoist_test.go +++ b/pkg/modules/migration/todoist/todoist_test.go @@ -35,10 +35,10 @@ func TestConvertTodoistToVikunja(t *testing.T) { config.InitConfig() - parseAndConvertToTimeZone := func(timeStr string) modules.Time { + parseAndConvertToTimeZone := func(timeStr string) *modules.Time { parsedTime, err := time.Parse(time.RFC3339Nano, timeStr) require.NoError(t, err) - return modules.Time(parsedTime.In(config.GetTimeZone())) + return modules.TimeFromTime(parsedTime.In(config.GetTimeZone())) } time1 := parseAndConvertToTimeZone("2014-09-26T08:25:05Z") @@ -392,8 +392,8 @@ func TestConvertTodoistToVikunja(t *testing.T) { Done: false, Created: time1, Reminders: []*models.TaskReminder{ - {Reminder: modules.Time(time.Date(2020, time.June, 15, 23, 59, 0, 0, time.UTC).In(config.GetTimeZone()))}, - {Reminder: modules.Time(time.Date(2020, time.June, 16, 7, 0, 0, 0, time.UTC).In(config.GetTimeZone()))}, + {Reminder: modules.TimeFromTime(time.Date(2020, time.June, 15, 23, 59, 0, 0, time.UTC).In(config.GetTimeZone()))}, + {Reminder: modules.TimeFromTime(time.Date(2020, time.June, 16, 7, 0, 0, 0, time.UTC).In(config.GetTimeZone()))}, }, }, }, @@ -411,7 +411,7 @@ func TestConvertTodoistToVikunja(t *testing.T) { Done: false, Created: time1, Reminders: []*models.TaskReminder{ - {Reminder: modules.Time(time.Date(2020, time.July, 15, 7, 0, 0, 0, time.UTC).In(config.GetTimeZone()))}, + {Reminder: modules.TimeFromTime(time.Date(2020, time.July, 15, 7, 0, 0, 0, time.UTC).In(config.GetTimeZone()))}, }, }, }, @@ -425,7 +425,7 @@ func TestConvertTodoistToVikunja(t *testing.T) { DoneAt: time3, Labels: vikunjaLabels, Reminders: []*models.TaskReminder{ - {Reminder: modules.Time(time.Date(2020, time.June, 15, 7, 0, 0, 0, time.UTC).In(config.GetTimeZone()))}, + {Reminder: modules.TimeFromTime(time.Date(2020, time.June, 15, 7, 0, 0, 0, time.UTC).In(config.GetTimeZone()))}, }, }, }, @@ -445,7 +445,7 @@ func TestConvertTodoistToVikunja(t *testing.T) { Created: time1, DoneAt: time3, Reminders: []*models.TaskReminder{ - {Reminder: modules.Time(time.Date(2020, time.June, 15, 7, 0, 0, 0, time.UTC).In(config.GetTimeZone()))}, + {Reminder: modules.TimeFromTime(time.Date(2020, time.June, 15, 7, 0, 0, 0, time.UTC).In(config.GetTimeZone()))}, }, }, }, @@ -537,7 +537,7 @@ func TestConvertTodoistToVikunja(t *testing.T) { Done: false, Created: time1, Reminders: []*models.TaskReminder{ - {Reminder: modules.Time(time.Date(2020, time.June, 15, 7, 0, 0, 0, time.UTC).In(config.GetTimeZone()))}, + {Reminder: modules.TimeFromTime(time.Date(2020, time.June, 15, 7, 0, 0, 0, time.UTC).In(config.GetTimeZone()))}, }, }, }, diff --git a/pkg/modules/migration/trello/trello.go b/pkg/modules/migration/trello/trello.go index bc7f2819e..180135369 100644 --- a/pkg/modules/migration/trello/trello.go +++ b/pkg/modules/migration/trello/trello.go @@ -297,7 +297,7 @@ func convertTrelloDataToVikunja(organizationName string, trelloData []*trello.Bo } if card.Due != nil { - task.DueDate = modules.Time(*card.Due) + task.DueDate = modules.TimeFromTime(*card.Due) } // Checklists (as markdown in description) @@ -406,8 +406,8 @@ func convertTrelloDataToVikunja(organizationName string, trelloData []*trello.Bo comment := &models.TaskComment{ Comment: action.Data.Text, - Created: modules.Time(action.Date), - Updated: modules.Time(action.Date), + Created: modules.TimeFromTime(action.Date), + Updated: modules.TimeFromTime(action.Date), } if currentMember == nil || action.IDMemberCreator != currentMember.ID { diff --git a/pkg/modules/migration/trello/trello_test.go b/pkg/modules/migration/trello/trello_test.go index f7606730b..3e7f869e2 100644 --- a/pkg/modules/migration/trello/trello_test.go +++ b/pkg/modules/migration/trello/trello_test.go @@ -33,7 +33,7 @@ import ( "github.com/stretchr/testify/require" ) -func getTestBoard(t *testing.T) ([]*trello.Board, modules.Time) { +func getTestBoard(t *testing.T) ([]*trello.Board, *modules.Time) { config.InitConfig() @@ -235,7 +235,7 @@ func getTestBoard(t *testing.T) ([]*trello.Board, modules.Time) { } trelloData[0].Prefs.BackgroundImage = "https://vikunja.io/testimage.jpg" // Using an image which we are hosting, so it'll still be up - return trelloData, modules.Time(time1) + return trelloData, modules.TimeFromTime(time1) } func TestConvertTrelloToVikunja(t *testing.T) { diff --git a/pkg/modules/time.go b/pkg/modules/time.go index c4de840db..50e1bdf18 100644 --- a/pkg/modules/time.go +++ b/pkg/modules/time.go @@ -20,11 +20,11 @@ import "time" type Time time.Time -func (t Time) MarshalJSON() ([]byte, error) { - if time.Time(t).IsZero() { +func (t *Time) MarshalJSON() ([]byte, error) { + if time.Time(*t).IsZero() { return []byte("null"), nil } - return []byte(`"` + time.Time(t).Format(time.RFC3339) + `"`), nil + return []byte(`"` + time.Time(*t).Format(time.RFC3339) + `"`), nil } func (t *Time) UnmarshalJSON(data []byte) error { @@ -40,42 +40,49 @@ func (t *Time) UnmarshalJSON(data []byte) error { return nil } -func (t Time) Time() time.Time { - return time.Time(t) +func (t *Time) Time() time.Time { + return time.Time(*t) } -func (t Time) IsZero() bool { +func (t *Time) IsZero() bool { return t.Time().IsZero() } -func (t Time) Add(d time.Duration) Time { - return Time(t.Time().Add(d)) +func (t *Time) Add(d time.Duration) *Time { + newTime := Time(t.Time().Add(d)) + return &newTime } -func (t Time) After(u Time) bool { +func (t *Time) After(u *Time) bool { return t.Time().After(u.Time()) } -func (t Time) Before(u Time) bool { +func (t *Time) Before(u *Time) bool { return t.Time().Before(u.Time()) } -func (t Time) Sub(u Time) time.Duration { +func (t *Time) Sub(u *Time) time.Duration { return t.Time().Sub(u.Time()) } -func (t Time) Unix() int64 { +func (t *Time) Unix() int64 { return t.Time().Unix() } -func (t Time) In(loc *time.Location) Time { - return Time(t.Time().In(loc)) +func (t *Time) In(loc *time.Location) *Time { + newTime := Time(t.Time().In(loc)) + return &newTime } -func (t Time) Format(layout string) string { +func (t *Time) Format(layout string) string { return t.Time().Format(layout) } -func (t Time) Month() time.Month { +func (t *Time) Month() time.Month { return t.Time().Month() } + +func TimeFromTime(time time.Time) *Time { + t := Time(time) + return &t +} diff --git a/pkg/notifications/database.go b/pkg/notifications/database.go index fbddf89cb..0ae0fb045 100644 --- a/pkg/notifications/database.go +++ b/pkg/notifications/database.go @@ -39,10 +39,10 @@ type DatabaseNotification struct { SubjectID int64 `xorm:"bigint null" json:"-"` // When this notification is marked as read, this will be updated with the current timestamp. - ReadAt modules.Time `xorm:"datetime null" json:"read_at"` + ReadAt *modules.Time `xorm:"datetime null" json:"read_at"` // A timestamp when this notification was created. You cannot change this value. - Created modules.Time `xorm:"created not null" json:"created"` + Created *modules.Time `xorm:"created not null" json:"created"` } // TableName resolves to a better table name for notifications @@ -88,9 +88,9 @@ func CanMarkNotificationAsRead(s *xorm.Session, notification *DatabaseNotificati // MarkNotificationAsRead marks a notification as read. It should be called only after CanMarkNotificationAsRead has // been called. func MarkNotificationAsRead(s *xorm.Session, notification *DatabaseNotification, read bool) (err error) { - notification.ReadAt = modules.Time{} + notification.ReadAt = &modules.Time{} if read { - notification.ReadAt = modules.Time(time.Now()) + notification.ReadAt = modules.TimeFromTime(time.Now()) } _, err = s. @@ -105,7 +105,7 @@ func MarkAllNotificationsAsRead(s *xorm.Session, userID int64) (err error) { Where("notifiable_id = ?", userID). Cols("read_at"). Update(&DatabaseNotification{ - ReadAt: modules.Time(time.Now()), + ReadAt: modules.TimeFromTime(time.Now()), }) return } diff --git a/pkg/routes/api/v1/user_show.go b/pkg/routes/api/v1/user_show.go index c2f955297..27e0caea6 100644 --- a/pkg/routes/api/v1/user_show.go +++ b/pkg/routes/api/v1/user_show.go @@ -33,7 +33,7 @@ import ( type UserWithSettings struct { user.User Settings *UserSettings `json:"settings"` - DeletionScheduledAt modules.Time `json:"deletion_scheduled_at"` + DeletionScheduledAt *modules.Time `json:"deletion_scheduled_at"` IsLocalUser bool `json:"is_local_user"` AuthProvider string `json:"auth_provider"` } diff --git a/pkg/routes/caldav/listStorageProvider.go b/pkg/routes/caldav/listStorageProvider.go index f41eb75e6..ebc5ec887 100644 --- a/pkg/routes/caldav/listStorageProvider.go +++ b/pkg/routes/caldav/listStorageProvider.go @@ -252,7 +252,7 @@ func (vcls *VikunjaCaldavProjectStorage) GetResource(rpath string) (*data.Resour } vcls.task = tasks[0] - if updated.Unix() > 0 { + if updated != nil && updated.Unix() > 0 { vcls.task.Updated = updated } diff --git a/pkg/user/delete.go b/pkg/user/delete.go index 78ae65809..c9bc34dd1 100644 --- a/pkg/user/delete.go +++ b/pkg/user/delete.go @@ -76,7 +76,7 @@ func notifyUsersScheduledForDeletion() { continue } - user.DeletionLastReminderSent = modules.Time(time.Now()) + user.DeletionLastReminderSent = modules.TimeFromTime(time.Now()) _, err = s.Where("id = ?", user.ID). Cols("deletion_last_reminder_sent"). Update(user) @@ -116,7 +116,7 @@ func ConfirmDeletion(s *xorm.Session, user *User, token string) (err error) { return err } - user.DeletionScheduledAt = modules.Time(time.Now().Add(3 * 24 * time.Hour)) + user.DeletionScheduledAt = modules.TimeFromTime(time.Now().Add(3 * 24 * time.Hour)) _, err = s.Where("id = ?", user.ID). Cols("deletion_scheduled_at"). Update(user) @@ -125,8 +125,8 @@ func ConfirmDeletion(s *xorm.Session, user *User, token string) (err error) { // CancelDeletion cancels the deletion of a user func CancelDeletion(s *xorm.Session, user *User) (err error) { - user.DeletionScheduledAt = modules.Time{} - user.DeletionLastReminderSent = modules.Time{} + user.DeletionScheduledAt = &modules.Time{} + user.DeletionLastReminderSent = &modules.Time{} _, err = s.Where("id = ?", user.ID). Cols("deletion_scheduled_at", "deletion_last_reminder_sent"). Update(user) diff --git a/pkg/user/token.go b/pkg/user/token.go index f23ec6f47..d653b2f71 100644 --- a/pkg/user/token.go +++ b/pkg/user/token.go @@ -42,12 +42,12 @@ const ( // Token is a token a user can use to do things like verify their email or resetting their password type Token struct { - ID int64 `xorm:"bigint autoincr not null unique pk" json:"id"` - UserID int64 `xorm:"not null" json:"-"` - Token string `xorm:"varchar(450) not null index" json:"-"` - ClearTextToken string `xorm:"-" json:"token"` - Kind TokenKind `xorm:"not null" json:"-"` - Created modules.Time `xorm:"created not null" json:"created"` + ID int64 `xorm:"bigint autoincr not null unique pk" json:"id"` + UserID int64 `xorm:"not null" json:"-"` + Token string `xorm:"varchar(450) not null index" json:"-"` + ClearTextToken string `xorm:"-" json:"token"` + Kind TokenKind `xorm:"not null" json:"-"` + Created *modules.Time `xorm:"created not null" json:"created"` } // TableName returns the real table name for user tokens diff --git a/pkg/user/user.go b/pkg/user/user.go index f9f25c389..6a2d97350 100644 --- a/pkg/user/user.go +++ b/pkg/user/user.go @@ -103,17 +103,17 @@ type User struct { Language string `xorm:"varchar(50) null" json:"-"` Timezone string `xorm:"varchar(255) null" json:"-"` - DeletionScheduledAt modules.Time `xorm:"datetime null" json:"-"` - DeletionLastReminderSent modules.Time `xorm:"datetime null" json:"-"` + DeletionScheduledAt *modules.Time `xorm:"datetime null" json:"-"` + DeletionLastReminderSent *modules.Time `xorm:"datetime null" json:"-"` FrontendSettings interface{} `xorm:"json null" json:"-"` ExportFileID int64 `xorm:"bigint null" json:"-"` // A timestamp when this task was created. You cannot change this value. - Created modules.Time `xorm:"created not null" json:"created"` + Created *modules.Time `xorm:"created not null" json:"created"` // A timestamp when this task was last updated. You cannot change this value. - Updated modules.Time `xorm:"updated not null" json:"updated"` + Updated *modules.Time `xorm:"updated not null" json:"updated"` web.Auth `xorm:"-" json:"-"` }