People: Update entity database table names #22

Work in progress.
This commit is contained in:
Michael Mayer 2021-08-13 20:31:41 +02:00
parent ca0d52b36e
commit 45355c7303
11 changed files with 106 additions and 78 deletions

View file

@ -55,9 +55,9 @@ var Entities = Types{
"photos_keywords": &PhotoKeyword{}, "photos_keywords": &PhotoKeyword{},
"passwords": &Password{}, "passwords": &Password{},
"links": &Link{}, "links": &Link{},
Marker{}.TableName(): &Marker{},
Person{}.TableName(): &Person{}, Person{}.TableName(): &Person{},
PersonFace{}.TableName(): &PersonFace{}, Face{}.TableName(): &Face{},
Marker{}.TableName(): &Marker{},
} }
type RowCount struct { type RowCount struct {

View file

@ -6,10 +6,10 @@ import (
"time" "time"
) )
type PeopleFaces []PersonFace type Faces []Face
// PersonFace represents the face of a Person. // Face represents the face of a Person.
type PersonFace struct { type Face struct {
ID string `gorm:"type:VARBINARY(42);primary_key;auto_increment:false;" json:"ID" yaml:"ID"` ID string `gorm:"type:VARBINARY(42);primary_key;auto_increment:false;" json:"ID" yaml:"ID"`
PersonUID string `gorm:"type:VARBINARY(42);index;" json:"PersonUID" yaml:"PersonUID,omitempty"` PersonUID string `gorm:"type:VARBINARY(42);index;" json:"PersonUID" yaml:"PersonUID,omitempty"`
Embedding string `gorm:"type:LONGTEXT;" json:"Embedding" yaml:"Embedding,omitempty"` Embedding string `gorm:"type:LONGTEXT;" json:"Embedding" yaml:"Embedding,omitempty"`
@ -19,16 +19,16 @@ type PersonFace struct {
} }
// TableName returns the entity database table name. // TableName returns the entity database table name.
func (PersonFace) TableName() string { func (Face) TableName() string {
return "people_faces_dev" return "faces_dev2"
} }
// NewPersonFace returns a new face. // NewPersonFace returns a new face.
func NewPersonFace(personUID, embedding string) *PersonFace { func NewPersonFace(personUID, embedding string) *Face {
timeStamp := Timestamp() timeStamp := Timestamp()
s := sha1.Sum([]byte(embedding)) s := sha1.Sum([]byte(embedding))
result := &PersonFace{ result := &Face{
ID: base32.StdEncoding.EncodeToString(s[:]), ID: base32.StdEncoding.EncodeToString(s[:]),
PersonUID: personUID, PersonUID: personUID,
Embedding: embedding, Embedding: embedding,
@ -40,12 +40,12 @@ func NewPersonFace(personUID, embedding string) *PersonFace {
} }
// UnmarshalEmbedding parses the face embedding JSON string. // UnmarshalEmbedding parses the face embedding JSON string.
func (m *PersonFace) UnmarshalEmbedding() (result Embedding) { func (m *Face) UnmarshalEmbedding() (result Embedding) {
return UnmarshalEmbedding(m.Embedding) return UnmarshalEmbedding(m.Embedding)
} }
// Save updates the existing or inserts a new face. // Save updates the existing or inserts a new face.
func (m *PersonFace) Save() error { func (m *Face) Save() error {
peopleMutex.Lock() peopleMutex.Lock()
defer peopleMutex.Unlock() defer peopleMutex.Unlock()
@ -53,7 +53,7 @@ func (m *PersonFace) Save() error {
} }
// Create inserts the face to the database. // Create inserts the face to the database.
func (m *PersonFace) Create() error { func (m *Face) Create() error {
peopleMutex.Lock() peopleMutex.Lock()
defer peopleMutex.Unlock() defer peopleMutex.Unlock()
@ -61,17 +61,17 @@ func (m *PersonFace) Create() error {
} }
// Delete removes the face from the database. // Delete removes the face from the database.
func (m *PersonFace) Delete() error { func (m *Face) Delete() error {
return Db().Delete(m).Error return Db().Delete(m).Error
} }
// Deleted returns true if the face is deleted. // Deleted returns true if the face is deleted.
func (m *PersonFace) Deleted() bool { func (m *Face) Deleted() bool {
return m.DeletedAt != nil return m.DeletedAt != nil
} }
// Restore restores the face in the database. // Restore restores the face in the database.
func (m *PersonFace) Restore() error { func (m *Face) Restore() error {
if m.Deleted() { if m.Deleted() {
return UnscopedDb().Model(m).Update("DeletedAt", nil).Error return UnscopedDb().Model(m).Update("DeletedAt", nil).Error
} }
@ -80,11 +80,11 @@ func (m *PersonFace) Restore() error {
} }
// Update a face property in the database. // Update a face property in the database.
func (m *PersonFace) Update(attr string, value interface{}) error { func (m *Face) Update(attr string, value interface{}) error {
return UnscopedDb().Model(m).Update(attr, value).Error return UnscopedDb().Model(m).Update(attr, value).Error
} }
// Updates face properties in the database. // Updates face properties in the database.
func (m *PersonFace) Updates(values interface{}) error { func (m *Face) Updates(values interface{}) error {
return UnscopedDb().Model(m).Updates(values).Error return UnscopedDb().Model(m).Updates(values).Error
} }

View file

@ -0,0 +1,12 @@
package entity
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestFace_TableName(t *testing.T) {
m := &Face{}
assert.Contains(t, m.TableName(), "faces")
}

View file

@ -45,7 +45,7 @@ var UnknownMarker = NewMarker(0, "", SrcAuto, MarkerUnknown, 0, 0, 0, 0)
// TableName returns the entity database table name. // TableName returns the entity database table name.
func (Marker) TableName() string { func (Marker) TableName() string {
return "markers_dev" return "markers_dev2"
} }
// NewMarker creates a new entity. // NewMarker creates a new entity.

View file

@ -7,8 +7,8 @@ import (
) )
func TestMarker_TableName(t *testing.T) { func TestMarker_TableName(t *testing.T) {
fileSync := &Marker{} m := &Marker{}
assert.Equal(t, "markers_dev", fileSync.TableName()) assert.Contains(t, m.TableName(), "markers")
} }
func TestNewMarker(t *testing.T) { func TestNewMarker(t *testing.T) {

View file

@ -15,31 +15,6 @@ var peopleMutex = sync.Mutex{}
type People []Person type People []Person
// Relationships.
/*
const (
RelUnknown = ""
RelBaby = "baby"
RelWife = "wife"
RelHusband = "husband"
RelDad = "dad"
RelMom = "mom"
RelWorkmate = "workmate"
RelBestFriend = "best-friend"
RelFriend = "friend"
RelClassmate = "classmate"
RelBoyfriend = "boyfriend"
RelGirlfriend = "girlfriend"
RelFamily = "family"
RelGrandfather = "grandfather"
RelGrandmother = "grandmother"
RelBrother = "brother"
RelSister = "sister"
RelRelative = "relative"
RelOther = "other"
)
*/
// Person represents a person on one or more photos. // Person represents a person on one or more photos.
type Person struct { type Person struct {
ID uint `gorm:"primary_key" json:"ID" yaml:"-"` ID uint `gorm:"primary_key" json:"ID" yaml:"-"`
@ -80,7 +55,7 @@ func CreateUnknownPerson() {
// TableName returns the entity database table name. // TableName returns the entity database table name.
func (Person) TableName() string { func (Person) TableName() string {
return "people_dev" return "people_dev2"
} }
// BeforeCreate creates a random UID if needed before inserting a new row to the database. // BeforeCreate creates a random UID if needed before inserting a new row to the database.

View file

@ -7,6 +7,11 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestPerson_TableName(t *testing.T) {
m := &Person{}
assert.Contains(t, m.TableName(), "people")
}
func TestNewPerson(t *testing.T) { func TestNewPerson(t *testing.T) {
t.Run("Jens_Mander", func(t *testing.T) { t.Run("Jens_Mander", func(t *testing.T) {
m := NewPerson("Jens Mander", SrcAuto, 0) m := NewPerson("Jens Mander", SrcAuto, 0)

View file

@ -82,7 +82,7 @@ func (w *Faces) Analyze() (err error) {
log.Infof("faces: max Ø %f < median %f < %f", maxMin, maxMedian, maxMax) log.Infof("faces: max Ø %f < median %f < %f", maxMin, maxMedian, maxMax)
} }
if known, err := query.PeopleFaces(); err != nil { if known, err := query.Faces(); err != nil {
log.Errorf("faces: %s", err) log.Errorf("faces: %s", err)
} else if len(known) == 0 { } else if len(known) == 0 {
log.Infof("faces: no faces found") log.Infof("faces: no faces found")
@ -233,7 +233,7 @@ func (w *Faces) Start() (err error) {
log.Errorf("faces: %s", err) log.Errorf("faces: %s", err)
} }
peopleFaces, err := query.PeopleFaces() peopleFaces, err := query.Faces()
if err != nil { if err != nil {
return err return err
@ -298,7 +298,7 @@ func (w *Faces) Start() (err error) {
log.Errorf("faces: failed adding %s", txt.Quote(marker.MarkerLabel)) log.Errorf("faces: failed adding %s", txt.Quote(marker.MarkerLabel))
} else if f, ok := faceMap[faceId]; ok { } else if f, ok := faceMap[faceId]; ok {
faceMap[faceId] = Face{Embedding: f.Embedding, PersonUID: person.PersonUID} faceMap[faceId] = Face{Embedding: f.Embedding, PersonUID: person.PersonUID}
entity.Db().Model(&entity.PersonFace{}).Where("id = ?", faceId).Update("PersonUID", person.PersonUID) entity.Db().Model(&entity.Face{}).Where("id = ?", faceId).Update("PersonUID", person.PersonUID)
} }
// Existing person? // Existing person?

View file

@ -18,8 +18,8 @@ func People(limit, offset int, embeddings bool) (result entity.People, err error
return result, err return result, err
} }
// PeopleFaces finds a list of faces. // Faces finds a list of faces.
func PeopleFaces() (result entity.PeopleFaces, err error) { func Faces() (result entity.Faces, err error) {
stmt := Db(). stmt := Db().
Order("id") Order("id")
@ -31,6 +31,6 @@ func PeopleFaces() (result entity.PeopleFaces, err error) {
// PurgeUnknownFaces removes unknown faces from the index. // PurgeUnknownFaces removes unknown faces from the index.
func PurgeUnknownFaces() error { func PurgeUnknownFaces() error {
return UnscopedDb().Delete( return UnscopedDb().Delete(
entity.PersonFace{}, entity.Face{},
"person_uid = '' AND updated_at < ?", entity.Yesterday()).Error "person_uid = '' AND updated_at < ?", entity.Yesterday()).Error
} }

View file

@ -0,0 +1,36 @@
package query
import (
"github.com/photoprism/photoprism/internal/entity"
"testing"
"github.com/stretchr/testify/assert"
)
func TestPeople(t *testing.T) {
results, err := People(3, 0, false)
if err != nil {
t.Fatal(err)
}
assert.GreaterOrEqual(t, 1, len(results))
for _, val := range results {
assert.IsType(t, entity.Person{}, val)
}
}
func TestFaces(t *testing.T) {
results, err := Faces()
if err != nil {
t.Fatal(err)
}
assert.GreaterOrEqual(t, 1, len(results))
for _, val := range results {
assert.IsType(t, entity.Face{}, val)
}
}