Backend: Don't regenerate existing unique IDs

Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
Michael Mayer 2020-05-01 12:57:26 +02:00
parent 2836d25e1b
commit e3356aa79b
7 changed files with 58 additions and 28 deletions

View file

@ -32,11 +32,11 @@ type Album struct {
// BeforeCreate computes a random UUID when a new album is created in database
func (m *Album) BeforeCreate(scope *gorm.Scope) error {
if err := scope.SetColumn("AlbumUUID", rnd.PPID('a')); err != nil {
return err
if rnd.IsPPID(m.AlbumUUID, 'a') {
return nil
}
return nil
return scope.SetColumn("AlbumUUID", rnd.PPID('a'))
}
// NewAlbum creates a new album; default name is current month and year

View file

@ -62,6 +62,10 @@ func FirstFileByHash(fileHash string) (File, error) {
// BeforeCreate computes a random UUID when a new file is created in database
func (m *File) BeforeCreate(scope *gorm.Scope) error {
if rnd.IsPPID(m.FileUUID, 'f') {
return nil
}
return scope.SetColumn("FileUUID", rnd.PPID('f'))
}

View file

@ -31,12 +31,11 @@ type Label struct {
// BeforeCreate computes a random UUID when a new label is created in database
func (m *Label) BeforeCreate(scope *gorm.Scope) error {
if err := scope.SetColumn("LabelUUID", rnd.PPID('l')); err != nil {
log.Errorf("label: %s", err)
return err
if rnd.IsPPID(m.LabelUUID, 'l') {
return nil
}
return nil
return scope.SetColumn("LabelUUID", rnd.PPID('l'))
}
// NewLabel creates a label in database with a given name and priority

View file

@ -146,10 +146,6 @@ func (m *Photo) ClassifyLabels() classify.Labels {
// BeforeCreate computes a unique UUID, and set a default takenAt before indexing a new photo
func (m *Photo) BeforeCreate(scope *gorm.Scope) error {
if err := scope.SetColumn("PhotoUUID", rnd.PPID('p')); err != nil {
return err
}
if m.TakenAt.IsZero() || m.TakenAtLocal.IsZero() {
now := time.Now()
@ -162,9 +158,13 @@ func (m *Photo) BeforeCreate(scope *gorm.Scope) error {
}
}
if rnd.IsPPID(m.PhotoUUID, 'p') {
return nil
}
return scope.SetColumn("PhotoUUID", rnd.PPID('p'))
}
// BeforeSave ensures the existence of TakenAt properties before indexing or updating a photo
func (m *Photo) BeforeSave(scope *gorm.Scope) error {
if m.TakenAt.IsZero() || m.TakenAtLocal.IsZero() {

View file

@ -6,11 +6,20 @@ import (
)
// PPID returns a unique id with prefix as string.
func PPID(prefix rune) string {
func PPID(prefix byte) string {
result := make([]byte, 0, 16)
result = append(result, byte(prefix))
result = append(result, prefix)
result = append(result, strconv.FormatInt(time.Now().UTC().Unix(), 36)[0:6]...)
result = append(result, Token(9)...)
return string(result)
}
// IsPPID returns true if the id seems to be a PhotoPrism unique id.
func IsPPID(id string, prefix byte) bool {
if len(id) != 16 {
return false
}
return id[0] == prefix
}

32
pkg/rnd/ppid_test.go Normal file
View file

@ -0,0 +1,32 @@
package rnd
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestPPID(t *testing.T) {
for n := 0; n < 5; n++ {
uuid := PPID('x')
t.Logf("id: %s", uuid)
assert.Equal(t, len(uuid), 16)
}
}
func BenchmarkPPID(b *testing.B) {
for n := 0; n < b.N; n++ {
PPID('x')
}
}
func TestIsPPID(t *testing.T) {
prefix := byte('x')
for n := 0; n < 10; n++ {
id := PPID(prefix)
assert.True(t, IsPPID(id, prefix))
}
assert.True(t, IsPPID("lt9k3pw1wowuy3c2", 'l'))
}

View file

@ -54,17 +54,3 @@ func BenchmarkRandomToken3(b *testing.B) {
Token(3)
}
}
func TestPPID(t *testing.T) {
for n := 0; n < 5; n++ {
uuid := PPID('x')
t.Logf("id: %s", uuid)
assert.Equal(t, len(uuid), 16)
}
}
func BenchmarkPPID(b *testing.B) {
for n := 0; n < b.N; n++ {
PPID('x')
}
}