diff --git a/pkg/migration/20191207204427.go b/pkg/migration/20191207204427.go new file mode 100644 index 000000000..e19187b96 --- /dev/null +++ b/pkg/migration/20191207204427.go @@ -0,0 +1,44 @@ +// Copyright 2019 Vikunja and contriubtors. All rights reserved. +// +// This file is part of Vikunja. +// +// Vikunja is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Vikunja is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Vikunja. If not, see . + +package migration + +import ( + "github.com/go-xorm/xorm" + "src.techknowlogick.com/xormigrate" +) + +type list20191207204427 struct { + Identifier string `xorm:"varchar(10) null" json:"identifier"` +} + +func (list20191207204427) TableName() string { + return "list" +} + +func init() { + migrations = append(migrations, &xormigrate.Migration{ + ID: "20191207204427", + Description: "Add task identifier to list", + Migrate: func(tx *xorm.Engine) error { + return tx.Sync2(list20191207204427{}) + }, + Rollback: func(tx *xorm.Engine) error { + return tx.DropTables(list20191207204427{}) + }, + }) +} diff --git a/pkg/models/error.go b/pkg/models/error.go index 0af2b978b..0acb6cbb0 100644 --- a/pkg/models/error.go +++ b/pkg/models/error.go @@ -471,6 +471,29 @@ func (err ErrListShareDoesNotExist) HTTPError() web.HTTPError { return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeListShareDoesNotExist, Message: "The list share does not exist."} } +// ErrListIdentifierIsNotUnique represents a "ErrListIdentifierIsNotUnique" kind of error. Used if the provided list identifier is not unique. +type ErrListIdentifierIsNotUnique struct { + Identifier string +} + +// IsErrListIdentifierIsNotUnique checks if an error is a ErrListIdentifierIsNotUnique. +func IsErrListIdentifierIsNotUnique(err error) bool { + _, ok := err.(ErrListIdentifierIsNotUnique) + return ok +} + +func (err ErrListIdentifierIsNotUnique) Error() string { + return fmt.Sprintf("List identifier is not unique.") +} + +// ErrCodeListIdentifierIsNotUnique holds the unique world-error code of this error +const ErrCodeListIdentifierIsNotUnique = 3007 + +// HTTPError holds the http error description +func (err ErrListIdentifierIsNotUnique) HTTPError() web.HTTPError { + return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeListIdentifierIsNotUnique, Message: "There already exists a list with this identifier."} +} + // ================ // List task errors // ================ diff --git a/pkg/models/fixtures/list.yml b/pkg/models/fixtures/list.yml index a86aa6084..209fe515d 100644 --- a/pkg/models/fixtures/list.yml +++ b/pkg/models/fixtures/list.yml @@ -2,6 +2,7 @@ id: 1 title: Test1 description: Lorem Ipsum + identifier: test owner_id: 1 namespace_id: 1 updated: 0 diff --git a/pkg/models/list.go b/pkg/models/list.go index 8ffd1a07c..901865f2e 100644 --- a/pkg/models/list.go +++ b/pkg/models/list.go @@ -268,6 +268,17 @@ func CreateOrUpdateList(list *List) (err error) { } } + // Check if the identifier is unique and not empty + if list.Identifier != "" { + exists, err := x.Where("identifier = ?", list.Identifier).Exist(&List{}) + if err != nil { + return err + } + if exists { + return ErrListIdentifierIsNotUnique{Identifier: list.Identifier} + } + } + if list.ID == 0 { _, err = x.Insert(list) metrics.UpdateCount(1, metrics.ListCountKey)