Indexer: Avoid adding the same entity simultaneously
This commit is contained in:
parent
801dc49dd7
commit
43e324700b
|
@ -2,6 +2,7 @@ package entity
|
|||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gosimple/slug"
|
||||
|
@ -9,6 +10,8 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
var cameraMutex = sync.Mutex{}
|
||||
|
||||
// Camera model and make (as extracted from UpdateExif metadata)
|
||||
type Camera struct {
|
||||
ID uint `gorm:"primary_key" json:"ID" yaml:"ID"`
|
||||
|
@ -169,6 +172,9 @@ func NewCamera(modelName string, makeName string) *Camera {
|
|||
|
||||
// Create inserts a new row to the database.
|
||||
func (m *Camera) Create() error {
|
||||
cameraMutex.Lock()
|
||||
defer cameraMutex.Unlock()
|
||||
|
||||
return Db().Create(m).Error
|
||||
}
|
||||
|
||||
|
@ -176,9 +182,9 @@ func (m *Camera) Create() error {
|
|||
func FirstOrCreateCamera(m *Camera) *Camera {
|
||||
result := Camera{}
|
||||
|
||||
if err := Db().Where("camera_model = ? AND camera_make = ?", m.CameraModel, m.CameraMake).First(&result).Error; err == nil {
|
||||
if res := Db().Where("camera_model = ? AND camera_make = ?", m.CameraModel, m.CameraMake).First(&result); res.Error == nil {
|
||||
return &result
|
||||
} else if createErr := m.Create(); createErr == nil {
|
||||
} else if err := m.Create(); err == nil {
|
||||
if !m.Unknown() {
|
||||
event.EntitiesCreated("cameras", []*Camera{m})
|
||||
|
||||
|
@ -188,10 +194,10 @@ func FirstOrCreateCamera(m *Camera) *Camera {
|
|||
}
|
||||
|
||||
return m
|
||||
} else if err := Db().Where("camera_model = ? AND camera_make = ?", m.CameraModel, m.CameraMake).First(&result).Error; err == nil {
|
||||
} else if res := Db().Where("camera_model = ? AND camera_make = ?", m.CameraModel, m.CameraMake).First(&result); res.Error == nil {
|
||||
return &result
|
||||
} else {
|
||||
log.Errorf("camera: %s (first or create %s)", createErr, m.String())
|
||||
log.Errorf("camera: %s (create %s)", err.Error(), txt.Quote(m.String()))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -2,6 +2,7 @@ package entity
|
|||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/event"
|
||||
|
@ -10,6 +11,8 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
var cellMutex = sync.Mutex{}
|
||||
|
||||
// Cell represents a S2 cell with location data.
|
||||
type Cell struct {
|
||||
ID string `gorm:"type:VARBINARY(42);primary_key;auto_increment:false;" json:"ID" yaml:"ID"`
|
||||
|
@ -95,6 +98,9 @@ func (m *Cell) Find(api string) error {
|
|||
m.CellName = l.Name()
|
||||
m.CellCategory = l.Category()
|
||||
|
||||
cellMutex.Lock()
|
||||
defer cellMutex.Unlock()
|
||||
|
||||
if createErr := db.Create(m).Error; createErr == nil {
|
||||
log.Debugf("location: added cell %s [%s]", m.ID, time.Since(start))
|
||||
return nil
|
||||
|
|
|
@ -2,10 +2,13 @@ package entity
|
|||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
var keywordMutex = sync.Mutex{}
|
||||
|
||||
// Keyword used for full text search
|
||||
type Keyword struct {
|
||||
ID uint `gorm:"primary_key"`
|
||||
|
@ -41,6 +44,9 @@ func (m *Keyword) Save() error {
|
|||
|
||||
// Create inserts a new row to the database.
|
||||
func (m *Keyword) Create() error {
|
||||
keywordMutex.Lock()
|
||||
defer keywordMutex.Unlock()
|
||||
|
||||
return Db().Create(m).Error
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package entity
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gosimple/slug"
|
||||
|
@ -11,6 +12,8 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
var labelMutex = sync.Mutex{}
|
||||
|
||||
type Labels []Label
|
||||
|
||||
// Label is used for photo, album and location categorization
|
||||
|
@ -65,11 +68,17 @@ func NewLabel(name string, priority int) *Label {
|
|||
|
||||
// Save updates the existing or inserts a new label.
|
||||
func (m *Label) Save() error {
|
||||
labelMutex.Lock()
|
||||
defer labelMutex.Unlock()
|
||||
|
||||
return Db().Save(m).Error
|
||||
}
|
||||
|
||||
// Create inserts the label to the database.
|
||||
func (m *Label) Create() error {
|
||||
labelMutex.Lock()
|
||||
defer labelMutex.Unlock()
|
||||
|
||||
return Db().Create(m).Error
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package entity
|
|||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gosimple/slug"
|
||||
|
@ -9,6 +10,8 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
var lensMutex = sync.Mutex{}
|
||||
|
||||
// Lens represents camera lens (as extracted from UpdateExif metadata)
|
||||
type Lens struct {
|
||||
ID uint `gorm:"primary_key" json:"ID" yaml:"ID"`
|
||||
|
@ -81,6 +84,9 @@ func NewLens(modelName string, makeName string) *Lens {
|
|||
|
||||
// Create inserts a new row to the database.
|
||||
func (m *Lens) Create() error {
|
||||
lensMutex.Lock()
|
||||
defer lensMutex.Unlock()
|
||||
|
||||
return Db().Create(m).Error
|
||||
}
|
||||
|
||||
|
@ -88,9 +94,9 @@ func (m *Lens) Create() error {
|
|||
func FirstOrCreateLens(m *Lens) *Lens {
|
||||
result := Lens{}
|
||||
|
||||
if err := Db().Where("lens_slug = ?", m.LensSlug).First(&result).Error; err == nil {
|
||||
if res := Db().Where("lens_slug = ?", m.LensSlug).First(&result); res.Error == nil {
|
||||
return &result
|
||||
} else if createErr := m.Create(); createErr == nil {
|
||||
} else if err := m.Create(); err == nil {
|
||||
if !m.Unknown() {
|
||||
event.EntitiesCreated("lenses", []*Lens{m})
|
||||
|
||||
|
@ -100,10 +106,10 @@ func FirstOrCreateLens(m *Lens) *Lens {
|
|||
}
|
||||
|
||||
return m
|
||||
} else if err := Db().Where("lens_slug = ?", m.LensSlug).First(&result).Error; err == nil {
|
||||
} else if res := Db().Where("lens_slug = ?", m.LensSlug).First(&result); res.Error == nil {
|
||||
return &result
|
||||
} else {
|
||||
log.Errorf("lens: %s (first or create %s)", createErr, m.String())
|
||||
log.Errorf("lens: %s (create %s)", err.Error(), txt.Quote(m.String()))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -4,11 +4,14 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
var photoYamlMutex = sync.Mutex{}
|
||||
|
||||
// Yaml returns photo data as YAML string.
|
||||
func (m *Photo) Yaml() ([]byte, error) {
|
||||
out, err := yaml.Marshal(m)
|
||||
|
@ -33,6 +36,9 @@ func (m *Photo) SaveAsYaml(fileName string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
photoYamlMutex.Lock()
|
||||
defer photoYamlMutex.Unlock()
|
||||
|
||||
// Write YAML data to file.
|
||||
if err := ioutil.WriteFile(fileName, data, os.ModePerm); err != nil {
|
||||
return err
|
||||
|
|
|
@ -2,11 +2,14 @@ package entity
|
|||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/maps"
|
||||
)
|
||||
|
||||
var placeMutex = sync.Mutex{}
|
||||
|
||||
// Place used to associate photos to places
|
||||
type Place struct {
|
||||
ID string `gorm:"type:VARBINARY(42);primary_key;auto_increment:false;" json:"PlaceID" yaml:"PlaceID"`
|
||||
|
@ -69,6 +72,9 @@ func (m *Place) Find() error {
|
|||
|
||||
// Create inserts a new row to the database.
|
||||
func (m *Place) Create() error {
|
||||
placeMutex.Lock()
|
||||
defer placeMutex.Unlock()
|
||||
|
||||
return Db().Create(m).Error
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue