Albums: Improve database error handling #3320
Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
parent
1f13b95f32
commit
e7d862d07a
|
@ -273,7 +273,7 @@ func FindMonthAlbum(year, month int) *Album {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if UnscopedDb().First(&m, "album_year = ? AND album_month = ? AND album_type = ?", year, month, AlbumMonth).RecordNotFound() {
|
if UnscopedDb().First(&m, "album_year = ? AND album_month = ? AND album_type = ?", year, month, AlbumMonth).Error != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +288,7 @@ func FindAlbumBySlug(albumSlug, albumType string) *Album {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if UnscopedDb().First(&m, "album_slug = ? AND album_type = ?", albumSlug, albumType).RecordNotFound() {
|
if UnscopedDb().First(&m, "album_slug = ? AND album_type = ?", albumSlug, albumType).Error != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +315,7 @@ func FindAlbumByAttr(slugs, filters []string, albumType string) *Album {
|
||||||
stmt = stmt.Where("album_slug IN (?) OR album_filter IN (?)", slugs, filters)
|
stmt = stmt.Where("album_slug IN (?) OR album_filter IN (?)", slugs, filters)
|
||||||
}
|
}
|
||||||
|
|
||||||
if stmt.First(&m).RecordNotFound() {
|
if stmt.First(&m).Error != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +336,7 @@ func FindFolderAlbum(albumPath string) *Album {
|
||||||
stmt := UnscopedDb().Where("album_type = ?", AlbumFolder).
|
stmt := UnscopedDb().Where("album_type = ?", AlbumFolder).
|
||||||
Where("album_slug = ? OR album_path = ?", albumSlug, albumPath)
|
Where("album_slug = ? OR album_path = ?", albumSlug, albumPath)
|
||||||
|
|
||||||
if stmt.First(&m).RecordNotFound() {
|
if stmt.First(&m).Error != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,7 +349,7 @@ func FindAlbum(find Album) *Album {
|
||||||
|
|
||||||
// Search by UID.
|
// Search by UID.
|
||||||
if rnd.IsUID(find.AlbumUID, AlbumUID) {
|
if rnd.IsUID(find.AlbumUID, AlbumUID) {
|
||||||
if UnscopedDb().First(&m, "album_uid = ?", find.AlbumUID).RecordNotFound() {
|
if UnscopedDb().First(&m, "album_uid = ?", find.AlbumUID).Error != nil {
|
||||||
return nil
|
return nil
|
||||||
} else if m.AlbumUID != "" {
|
} else if m.AlbumUID != "" {
|
||||||
albumCache.SetDefault(m.AlbumUID, m)
|
albumCache.SetDefault(m.AlbumUID, m)
|
||||||
|
@ -382,7 +382,7 @@ func FindAlbum(find Album) *Album {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find first matching record.
|
// Find first matching record.
|
||||||
if stmt.First(&m).RecordNotFound() {
|
if stmt.First(&m).Error != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,6 +490,10 @@ func (m *Album) SetLocation(location, state, country string) *Album {
|
||||||
|
|
||||||
// UpdateTitleAndLocation updates title, location, and slug of generated albums if needed.
|
// UpdateTitleAndLocation updates title, location, and slug of generated albums if needed.
|
||||||
func (m *Album) UpdateTitleAndLocation(title, location, state, country, slug string) error {
|
func (m *Album) UpdateTitleAndLocation(title, location, state, country, slug string) error {
|
||||||
|
if !m.HasID() {
|
||||||
|
return fmt.Errorf("album does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
title = txt.Clip(title, txt.ClipDefault)
|
title = txt.Clip(title, txt.ClipDefault)
|
||||||
slug = txt.Clip(slug, txt.ClipSlug)
|
slug = txt.Clip(slug, txt.ClipSlug)
|
||||||
|
|
||||||
|
@ -533,6 +537,10 @@ func (m *Album) UpdateTitleAndLocation(title, location, state, country, slug str
|
||||||
|
|
||||||
// UpdateTitleAndState updates the album location.
|
// UpdateTitleAndState updates the album location.
|
||||||
func (m *Album) UpdateTitleAndState(title, slug, stateName, countryCode string) error {
|
func (m *Album) UpdateTitleAndState(title, slug, stateName, countryCode string) error {
|
||||||
|
if !m.HasID() {
|
||||||
|
return fmt.Errorf("album does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
title = txt.Clip(title, txt.ClipDefault)
|
title = txt.Clip(title, txt.ClipDefault)
|
||||||
slug = txt.Clip(slug, txt.ClipSlug)
|
slug = txt.Clip(slug, txt.ClipSlug)
|
||||||
|
|
||||||
|
@ -593,16 +601,28 @@ func (m *Album) SaveForm(f form.Album) error {
|
||||||
|
|
||||||
// Update sets a new value for a database column.
|
// Update sets a new value for a database column.
|
||||||
func (m *Album) Update(attr string, value interface{}) error {
|
func (m *Album) Update(attr string, value interface{}) error {
|
||||||
|
if !m.HasID() {
|
||||||
|
return fmt.Errorf("album does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
return UnscopedDb().Model(m).Update(attr, value).Error
|
return UnscopedDb().Model(m).Update(attr, value).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates multiple columns in the database.
|
// Updates multiple columns in the database.
|
||||||
func (m *Album) Updates(values interface{}) error {
|
func (m *Album) Updates(values interface{}) error {
|
||||||
|
if !m.HasID() {
|
||||||
|
return fmt.Errorf("album does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
return UnscopedDb().Model(m).Updates(values).Error
|
return UnscopedDb().Model(m).Updates(values).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateFolder updates the path, filter and slug for a folder album.
|
// UpdateFolder updates the path, filter and slug for a folder album.
|
||||||
func (m *Album) UpdateFolder(albumPath, albumFilter string) error {
|
func (m *Album) UpdateFolder(albumPath, albumFilter string) error {
|
||||||
|
if !m.HasID() {
|
||||||
|
return fmt.Errorf("album does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
albumPath = strings.Trim(albumPath, string(os.PathSeparator))
|
albumPath = strings.Trim(albumPath, string(os.PathSeparator))
|
||||||
albumSlug := txt.Slug(albumPath)
|
albumSlug := txt.Slug(albumPath)
|
||||||
|
|
||||||
|
@ -610,11 +630,11 @@ func (m *Album) UpdateFolder(albumPath, albumFilter string) error {
|
||||||
return fmt.Errorf("folder album must have a path and filter")
|
return fmt.Errorf("folder album must have a path and filter")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := UnscopedDb().Model(m).Updates(map[string]interface{}{
|
if err := m.Updates(map[string]interface{}{
|
||||||
"AlbumPath": albumPath,
|
"AlbumPath": albumPath,
|
||||||
"AlbumFilter": albumFilter,
|
"AlbumFilter": albumFilter,
|
||||||
"AlbumSlug": albumSlug,
|
"AlbumSlug": albumSlug,
|
||||||
}).Error; err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if err = UnscopedDb().Exec("UPDATE albums SET album_path = NULL WHERE album_type = ? AND album_path = ? AND id <> ?", AlbumFolder, albumPath, m.ID).Error; err != nil {
|
} else if err = UnscopedDb().Exec("UPDATE albums SET album_path = NULL WHERE album_type = ? AND album_path = ? AND id <> ?", AlbumFolder, albumPath, m.ID).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -663,6 +683,10 @@ func (m *Album) PublishCountChange(n int) {
|
||||||
|
|
||||||
// Delete marks the entity as deleted in the database.
|
// Delete marks the entity as deleted in the database.
|
||||||
func (m *Album) Delete() error {
|
func (m *Album) Delete() error {
|
||||||
|
if !m.HasID() {
|
||||||
|
return fmt.Errorf("album does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
if m.Deleted() {
|
if m.Deleted() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -679,6 +703,10 @@ func (m *Album) Delete() error {
|
||||||
|
|
||||||
// DeletePermanently permanently removes an album from the index.
|
// DeletePermanently permanently removes an album from the index.
|
||||||
func (m *Album) DeletePermanently() error {
|
func (m *Album) DeletePermanently() error {
|
||||||
|
if !m.HasID() {
|
||||||
|
return fmt.Errorf("album does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
wasDeleted := m.Deleted()
|
wasDeleted := m.Deleted()
|
||||||
|
|
||||||
if err := UnscopedDb().Delete(m).Error; err != nil {
|
if err := UnscopedDb().Delete(m).Error; err != nil {
|
||||||
|
@ -704,6 +732,10 @@ func (m *Album) Deleted() bool {
|
||||||
|
|
||||||
// Restore restores the entity in the database.
|
// Restore restores the entity in the database.
|
||||||
func (m *Album) Restore() error {
|
func (m *Album) Restore() error {
|
||||||
|
if !m.HasID() {
|
||||||
|
return fmt.Errorf("album does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
if !m.Deleted() {
|
if !m.Deleted() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -738,7 +770,15 @@ func (m *Album) ZipName() string {
|
||||||
|
|
||||||
// AddPhotos adds photos to an existing album.
|
// AddPhotos adds photos to an existing album.
|
||||||
func (m *Album) AddPhotos(UIDs []string) (added PhotoAlbums) {
|
func (m *Album) AddPhotos(UIDs []string) (added PhotoAlbums) {
|
||||||
|
if !m.HasID() {
|
||||||
|
return added
|
||||||
|
}
|
||||||
|
|
||||||
for _, uid := range UIDs {
|
for _, uid := range UIDs {
|
||||||
|
if !rnd.IsUID(uid, PhotoUID) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
entry := PhotoAlbum{AlbumUID: m.AlbumUID, PhotoUID: uid, Hidden: false}
|
entry := PhotoAlbum{AlbumUID: m.AlbumUID, PhotoUID: uid, Hidden: false}
|
||||||
|
|
||||||
if err := entry.Save(); err != nil {
|
if err := entry.Save(); err != nil {
|
||||||
|
@ -753,7 +793,15 @@ func (m *Album) AddPhotos(UIDs []string) (added PhotoAlbums) {
|
||||||
|
|
||||||
// RemovePhotos removes photos from an album.
|
// RemovePhotos removes photos from an album.
|
||||||
func (m *Album) RemovePhotos(UIDs []string) (removed PhotoAlbums) {
|
func (m *Album) RemovePhotos(UIDs []string) (removed PhotoAlbums) {
|
||||||
|
if !m.HasID() {
|
||||||
|
return removed
|
||||||
|
}
|
||||||
|
|
||||||
for _, uid := range UIDs {
|
for _, uid := range UIDs {
|
||||||
|
if !rnd.IsUID(uid, PhotoUID) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
entry := PhotoAlbum{AlbumUID: m.AlbumUID, PhotoUID: uid, Hidden: true}
|
entry := PhotoAlbum{AlbumUID: m.AlbumUID, PhotoUID: uid, Hidden: true}
|
||||||
|
|
||||||
if err := entry.Save(); err != nil {
|
if err := entry.Save(); err != nil {
|
||||||
|
|
|
@ -373,26 +373,28 @@ func TestAlbum_IsMoment(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAlbum_Update(t *testing.T) {
|
func TestAlbum_Update(t *testing.T) {
|
||||||
t.Run("success", func(t *testing.T) {
|
t.Run("Success", func(t *testing.T) {
|
||||||
album := Album{
|
album := NewAlbum("Test Title", AlbumManual)
|
||||||
AlbumUID: "abc123",
|
if err := album.Save(); err != nil {
|
||||||
AlbumSlug: "test-slug",
|
|
||||||
AlbumType: AlbumManual,
|
|
||||||
AlbumTitle: "Test Title",
|
|
||||||
}
|
|
||||||
assert.Equal(t, "test-slug", album.AlbumSlug)
|
|
||||||
|
|
||||||
err := album.Update("AlbumSlug", "new-slug")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, "test-title", album.AlbumSlug)
|
||||||
|
|
||||||
|
if err := album.Update("AlbumSlug", "new-slug"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
assert.Equal(t, "new-slug", album.AlbumSlug)
|
assert.Equal(t, "new-slug", album.AlbumSlug)
|
||||||
|
|
||||||
|
if err := album.DeletePermanently(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAlbum_Save(t *testing.T) {
|
func TestAlbum_Save(t *testing.T) {
|
||||||
t.Run("success", func(t *testing.T) {
|
t.Run("Success", func(t *testing.T) {
|
||||||
album := NewStateAlbum("Dogs", "dogs", "label:dog")
|
album := NewStateAlbum("Dogs", "dogs", "label:dog")
|
||||||
|
|
||||||
initialDate := album.UpdatedAt
|
initialDate := album.UpdatedAt
|
||||||
|
@ -411,7 +413,7 @@ func TestAlbum_Save(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAlbum_Create(t *testing.T) {
|
func TestAlbum_Create(t *testing.T) {
|
||||||
t.Run("album", func(t *testing.T) {
|
t.Run("Album", func(t *testing.T) {
|
||||||
album := Album{
|
album := Album{
|
||||||
AlbumType: AlbumManual,
|
AlbumType: AlbumManual,
|
||||||
}
|
}
|
||||||
|
@ -422,7 +424,7 @@ func TestAlbum_Create(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
t.Run("moment", func(t *testing.T) {
|
t.Run("Moment", func(t *testing.T) {
|
||||||
album := Album{
|
album := Album{
|
||||||
AlbumType: AlbumMoment,
|
AlbumType: AlbumMoment,
|
||||||
}
|
}
|
||||||
|
@ -433,7 +435,7 @@ func TestAlbum_Create(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
t.Run("month", func(t *testing.T) {
|
t.Run("Month", func(t *testing.T) {
|
||||||
album := Album{
|
album := Album{
|
||||||
AlbumType: AlbumMonth,
|
AlbumType: AlbumMonth,
|
||||||
}
|
}
|
||||||
|
@ -444,7 +446,7 @@ func TestAlbum_Create(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
t.Run("folder", func(t *testing.T) {
|
t.Run("Folder", func(t *testing.T) {
|
||||||
album := Album{
|
album := Album{
|
||||||
AlbumType: AlbumFolder,
|
AlbumType: AlbumFolder,
|
||||||
}
|
}
|
||||||
|
@ -458,7 +460,7 @@ func TestAlbum_Create(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAlbum_Title(t *testing.T) {
|
func TestAlbum_Title(t *testing.T) {
|
||||||
t.Run("success", func(t *testing.T) {
|
t.Run("Success", func(t *testing.T) {
|
||||||
album := Album{
|
album := Album{
|
||||||
AlbumUID: "abc123",
|
AlbumUID: "abc123",
|
||||||
AlbumSlug: "test-slug",
|
AlbumSlug: "test-slug",
|
||||||
|
@ -470,7 +472,7 @@ func TestAlbum_Title(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAlbum_Links(t *testing.T) {
|
func TestAlbum_Links(t *testing.T) {
|
||||||
t.Run("1 result", func(t *testing.T) {
|
t.Run("OneResult", func(t *testing.T) {
|
||||||
album := AlbumFixtures.Get("christmas2030")
|
album := AlbumFixtures.Get("christmas2030")
|
||||||
links := album.Links()
|
links := album.Links()
|
||||||
assert.Equal(t, "4jxf3jfn2k", links[0].LinkToken)
|
assert.Equal(t, "4jxf3jfn2k", links[0].LinkToken)
|
||||||
|
@ -478,14 +480,15 @@ func TestAlbum_Links(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAlbum_AddPhotos(t *testing.T) {
|
func TestAlbum_AddPhotos(t *testing.T) {
|
||||||
t.Run("success", func(t *testing.T) {
|
t.Run("Success", func(t *testing.T) {
|
||||||
album := Album{
|
album := Album{
|
||||||
AlbumUID: "abc123",
|
ID: 1000000,
|
||||||
|
AlbumUID: "at9lxuqxpogaaba7",
|
||||||
AlbumSlug: "test-slug",
|
AlbumSlug: "test-slug",
|
||||||
AlbumType: AlbumManual,
|
AlbumType: AlbumManual,
|
||||||
AlbumTitle: "Test Title",
|
AlbumTitle: "Test Title",
|
||||||
}
|
}
|
||||||
added := album.AddPhotos([]string{"ab", "cd"})
|
added := album.AddPhotos([]string{"pt9jtdre2lvl0yh7", "pt9jtdre2lvl0yh8"})
|
||||||
assert.Equal(t, 2, len(added))
|
assert.Equal(t, 2, len(added))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -493,12 +496,13 @@ func TestAlbum_AddPhotos(t *testing.T) {
|
||||||
func TestAlbum_RemovePhotos(t *testing.T) {
|
func TestAlbum_RemovePhotos(t *testing.T) {
|
||||||
t.Run("success", func(t *testing.T) {
|
t.Run("success", func(t *testing.T) {
|
||||||
album := Album{
|
album := Album{
|
||||||
AlbumUID: "abc123",
|
ID: 1000000,
|
||||||
|
AlbumUID: "at9lxuqxpogaaba7",
|
||||||
AlbumSlug: "test-slug",
|
AlbumSlug: "test-slug",
|
||||||
AlbumType: AlbumManual,
|
AlbumType: AlbumManual,
|
||||||
AlbumTitle: "Test Title",
|
AlbumTitle: "Test Title",
|
||||||
}
|
}
|
||||||
removed := album.RemovePhotos([]string{"ab", "cd"})
|
removed := album.RemovePhotos([]string{"pt9jtdre2lvl0yh7", "pt9jtdre2lvl0yh8"})
|
||||||
assert.Equal(t, 2, len(removed))
|
assert.Equal(t, 2, len(removed))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ func FindUserShare(find UserShare) *UserShare {
|
||||||
m := &UserShare{}
|
m := &UserShare{}
|
||||||
|
|
||||||
// Find matching record.
|
// Find matching record.
|
||||||
if UnscopedDb().First(m, "user_uid = ? AND share_uid = ?", find.UserUID, find.ShareUID).RecordNotFound() {
|
if UnscopedDb().First(m, "user_uid = ? AND share_uid = ?", find.UserUID, find.ShareUID).Error != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -200,7 +200,7 @@ func FindLink(linkUid string) *Link {
|
||||||
|
|
||||||
result := Link{}
|
result := Link{}
|
||||||
|
|
||||||
if Db().Where("link_uid = ?", linkUid).First(&result).RecordNotFound() {
|
if Db().Where("link_uid = ?", linkUid).First(&result).Error != nil {
|
||||||
event.AuditWarn([]string{"link %s", "not found"}, clean.Log(linkUid))
|
event.AuditWarn([]string{"link %s", "not found"}, clean.Log(linkUid))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -302,14 +302,14 @@ func FindPhoto(find Photo) *Photo {
|
||||||
|
|
||||||
// Search for UID.
|
// Search for UID.
|
||||||
if rnd.IsUID(find.PhotoUID, PhotoUID) {
|
if rnd.IsUID(find.PhotoUID, PhotoUID) {
|
||||||
if !stmt.First(&m, "photo_uid = ?", find.PhotoUID).RecordNotFound() {
|
if stmt.First(&m, "photo_uid = ?", find.PhotoUID).Error == nil {
|
||||||
return &m
|
return &m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search for ID.
|
// Search for ID.
|
||||||
if find.ID > 0 {
|
if find.ID > 0 {
|
||||||
if !stmt.First(&m, "id = ?", find.ID).RecordNotFound() {
|
if stmt.First(&m, "id = ?", find.ID).Error == nil {
|
||||||
return &m
|
return &m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ func CreateUnknownPlace() {
|
||||||
func FindPlace(id string) *Place {
|
func FindPlace(id string) *Place {
|
||||||
m := Place{}
|
m := Place{}
|
||||||
|
|
||||||
if Db().First(&m, "id = ?", id).RecordNotFound() {
|
if Db().First(&m, "id = ?", id).Error != nil {
|
||||||
log.Debugf("place: %s not found", clean.Log(id))
|
log.Debugf("place: %s not found", clean.Log(id))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ func FindReaction(uid, userUid string) (m *Reaction) {
|
||||||
|
|
||||||
m = &Reaction{}
|
m = &Reaction{}
|
||||||
|
|
||||||
if Db().First(m, "uid = ? AND user_uid = ?", uid, userUid).RecordNotFound() {
|
if Db().First(m, "uid = ? AND user_uid = ?", uid, userUid).Error != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue