Albums: Improve database error handling #3320
Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
parent
1f13b95f32
commit
e7d862d07a
7 changed files with 90 additions and 38 deletions
|
@ -273,7 +273,7 @@ func FindMonthAlbum(year, month int) *Album {
|
|||
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
|
||||
}
|
||||
|
||||
|
@ -288,7 +288,7 @@ func FindAlbumBySlug(albumSlug, albumType string) *Album {
|
|||
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
|
||||
}
|
||||
|
||||
|
@ -315,7 +315,7 @@ func FindAlbumByAttr(slugs, filters []string, albumType string) *Album {
|
|||
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
|
||||
}
|
||||
|
||||
|
@ -336,7 +336,7 @@ func FindFolderAlbum(albumPath string) *Album {
|
|||
stmt := UnscopedDb().Where("album_type = ?", AlbumFolder).
|
||||
Where("album_slug = ? OR album_path = ?", albumSlug, albumPath)
|
||||
|
||||
if stmt.First(&m).RecordNotFound() {
|
||||
if stmt.First(&m).Error != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -349,7 +349,7 @@ func FindAlbum(find Album) *Album {
|
|||
|
||||
// Search by UID.
|
||||
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
|
||||
} else if m.AlbumUID != "" {
|
||||
albumCache.SetDefault(m.AlbumUID, m)
|
||||
|
@ -382,7 +382,7 @@ func FindAlbum(find Album) *Album {
|
|||
}
|
||||
|
||||
// Find first matching record.
|
||||
if stmt.First(&m).RecordNotFound() {
|
||||
if stmt.First(&m).Error != 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.
|
||||
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)
|
||||
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.
|
||||
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)
|
||||
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.
|
||||
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
|
||||
}
|
||||
|
||||
// Updates multiple columns in the database.
|
||||
func (m *Album) Updates(values interface{}) error {
|
||||
if !m.HasID() {
|
||||
return fmt.Errorf("album does not exist")
|
||||
}
|
||||
|
||||
return UnscopedDb().Model(m).Updates(values).Error
|
||||
}
|
||||
|
||||
// UpdateFolder updates the path, filter and slug for a folder album.
|
||||
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))
|
||||
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")
|
||||
}
|
||||
|
||||
if err := UnscopedDb().Model(m).Updates(map[string]interface{}{
|
||||
if err := m.Updates(map[string]interface{}{
|
||||
"AlbumPath": albumPath,
|
||||
"AlbumFilter": albumFilter,
|
||||
"AlbumSlug": albumSlug,
|
||||
}).Error; err != nil {
|
||||
}); err != nil {
|
||||
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 {
|
||||
return err
|
||||
|
@ -663,6 +683,10 @@ func (m *Album) PublishCountChange(n int) {
|
|||
|
||||
// Delete marks the entity as deleted in the database.
|
||||
func (m *Album) Delete() error {
|
||||
if !m.HasID() {
|
||||
return fmt.Errorf("album does not exist")
|
||||
}
|
||||
|
||||
if m.Deleted() {
|
||||
return nil
|
||||
}
|
||||
|
@ -679,6 +703,10 @@ func (m *Album) Delete() error {
|
|||
|
||||
// DeletePermanently permanently removes an album from the index.
|
||||
func (m *Album) DeletePermanently() error {
|
||||
if !m.HasID() {
|
||||
return fmt.Errorf("album does not exist")
|
||||
}
|
||||
|
||||
wasDeleted := m.Deleted()
|
||||
|
||||
if err := UnscopedDb().Delete(m).Error; err != nil {
|
||||
|
@ -704,6 +732,10 @@ func (m *Album) Deleted() bool {
|
|||
|
||||
// Restore restores the entity in the database.
|
||||
func (m *Album) Restore() error {
|
||||
if !m.HasID() {
|
||||
return fmt.Errorf("album does not exist")
|
||||
}
|
||||
|
||||
if !m.Deleted() {
|
||||
return nil
|
||||
}
|
||||
|
@ -738,7 +770,15 @@ func (m *Album) ZipName() string {
|
|||
|
||||
// AddPhotos adds photos to an existing album.
|
||||
func (m *Album) AddPhotos(UIDs []string) (added PhotoAlbums) {
|
||||
if !m.HasID() {
|
||||
return added
|
||||
}
|
||||
|
||||
for _, uid := range UIDs {
|
||||
if !rnd.IsUID(uid, PhotoUID) {
|
||||
continue
|
||||
}
|
||||
|
||||
entry := PhotoAlbum{AlbumUID: m.AlbumUID, PhotoUID: uid, Hidden: false}
|
||||
|
||||
if err := entry.Save(); err != nil {
|
||||
|
@ -753,7 +793,15 @@ func (m *Album) AddPhotos(UIDs []string) (added PhotoAlbums) {
|
|||
|
||||
// RemovePhotos removes photos from an album.
|
||||
func (m *Album) RemovePhotos(UIDs []string) (removed PhotoAlbums) {
|
||||
if !m.HasID() {
|
||||
return removed
|
||||
}
|
||||
|
||||
for _, uid := range UIDs {
|
||||
if !rnd.IsUID(uid, PhotoUID) {
|
||||
continue
|
||||
}
|
||||
|
||||
entry := PhotoAlbum{AlbumUID: m.AlbumUID, PhotoUID: uid, Hidden: true}
|
||||
|
||||
if err := entry.Save(); err != nil {
|
||||
|
|
|
@ -373,26 +373,28 @@ func TestAlbum_IsMoment(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAlbum_Update(t *testing.T) {
|
||||
t.Run("success", func(t *testing.T) {
|
||||
album := Album{
|
||||
AlbumUID: "abc123",
|
||||
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.Run("Success", func(t *testing.T) {
|
||||
album := NewAlbum("Test Title", AlbumManual)
|
||||
if err := album.Save(); err != nil {
|
||||
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)
|
||||
|
||||
if err := album.DeletePermanently(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
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")
|
||||
|
||||
initialDate := album.UpdatedAt
|
||||
|
@ -411,7 +413,7 @@ func TestAlbum_Save(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{
|
||||
AlbumType: AlbumManual,
|
||||
}
|
||||
|
@ -422,7 +424,7 @@ func TestAlbum_Create(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
t.Run("moment", func(t *testing.T) {
|
||||
t.Run("Moment", func(t *testing.T) {
|
||||
album := Album{
|
||||
AlbumType: AlbumMoment,
|
||||
}
|
||||
|
@ -433,7 +435,7 @@ func TestAlbum_Create(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
t.Run("month", func(t *testing.T) {
|
||||
t.Run("Month", func(t *testing.T) {
|
||||
album := Album{
|
||||
AlbumType: AlbumMonth,
|
||||
}
|
||||
|
@ -444,7 +446,7 @@ func TestAlbum_Create(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
t.Run("folder", func(t *testing.T) {
|
||||
t.Run("Folder", func(t *testing.T) {
|
||||
album := Album{
|
||||
AlbumType: AlbumFolder,
|
||||
}
|
||||
|
@ -458,7 +460,7 @@ func TestAlbum_Create(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{
|
||||
AlbumUID: "abc123",
|
||||
AlbumSlug: "test-slug",
|
||||
|
@ -470,7 +472,7 @@ func TestAlbum_Title(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")
|
||||
links := album.Links()
|
||||
assert.Equal(t, "4jxf3jfn2k", links[0].LinkToken)
|
||||
|
@ -478,14 +480,15 @@ func TestAlbum_Links(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{
|
||||
AlbumUID: "abc123",
|
||||
ID: 1000000,
|
||||
AlbumUID: "at9lxuqxpogaaba7",
|
||||
AlbumSlug: "test-slug",
|
||||
AlbumType: AlbumManual,
|
||||
AlbumTitle: "Test Title",
|
||||
}
|
||||
added := album.AddPhotos([]string{"ab", "cd"})
|
||||
added := album.AddPhotos([]string{"pt9jtdre2lvl0yh7", "pt9jtdre2lvl0yh8"})
|
||||
assert.Equal(t, 2, len(added))
|
||||
})
|
||||
}
|
||||
|
@ -493,12 +496,13 @@ func TestAlbum_AddPhotos(t *testing.T) {
|
|||
func TestAlbum_RemovePhotos(t *testing.T) {
|
||||
t.Run("success", func(t *testing.T) {
|
||||
album := Album{
|
||||
AlbumUID: "abc123",
|
||||
ID: 1000000,
|
||||
AlbumUID: "at9lxuqxpogaaba7",
|
||||
AlbumSlug: "test-slug",
|
||||
AlbumType: AlbumManual,
|
||||
AlbumTitle: "Test Title",
|
||||
}
|
||||
removed := album.RemovePhotos([]string{"ab", "cd"})
|
||||
removed := album.RemovePhotos([]string{"pt9jtdre2lvl0yh7", "pt9jtdre2lvl0yh8"})
|
||||
assert.Equal(t, 2, len(removed))
|
||||
})
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ func FindUserShare(find UserShare) *UserShare {
|
|||
m := &UserShare{}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
|
|
|
@ -200,7 +200,7 @@ func FindLink(linkUid string) *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))
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -302,14 +302,14 @@ func FindPhoto(find Photo) *Photo {
|
|||
|
||||
// Search for UID.
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
// Search for ID.
|
||||
if find.ID > 0 {
|
||||
if !stmt.First(&m, "id = ?", find.ID).RecordNotFound() {
|
||||
if stmt.First(&m, "id = ?", find.ID).Error == nil {
|
||||
return &m
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ func CreateUnknownPlace() {
|
|||
func FindPlace(id string) *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))
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ func FindReaction(uid, userUid string) (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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue