2021-11-21 14:05:07 +01:00
|
|
|
package entity
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"time"
|
|
|
|
|
2021-11-28 13:52:27 +01:00
|
|
|
"github.com/jinzhu/gorm"
|
|
|
|
|
2021-11-21 14:05:07 +01:00
|
|
|
"github.com/photoprism/photoprism/internal/migrate"
|
2021-12-14 20:01:39 +01:00
|
|
|
"github.com/photoprism/photoprism/pkg/sanitize"
|
2021-11-21 14:05:07 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
type Tables map[string]interface{}
|
|
|
|
|
|
|
|
// Entities contains database entities and their table names.
|
|
|
|
var Entities = Tables{
|
|
|
|
migrate.Migration{}.TableName(): &migrate.Migration{},
|
|
|
|
"errors": &Error{},
|
|
|
|
"addresses": &Address{},
|
|
|
|
"users": &User{},
|
|
|
|
"accounts": &Account{},
|
|
|
|
"folders": &Folder{},
|
|
|
|
"duplicates": &Duplicate{},
|
|
|
|
File{}.TableName(): &File{},
|
|
|
|
"files_share": &FileShare{},
|
|
|
|
"files_sync": &FileSync{},
|
|
|
|
Photo{}.TableName(): &Photo{},
|
|
|
|
"details": &Details{},
|
|
|
|
Place{}.TableName(): &Place{},
|
|
|
|
Cell{}.TableName(): &Cell{},
|
|
|
|
"cameras": &Camera{},
|
|
|
|
"lenses": &Lens{},
|
|
|
|
"countries": &Country{},
|
|
|
|
"albums": &Album{},
|
|
|
|
"photos_albums": &PhotoAlbum{},
|
|
|
|
"labels": &Label{},
|
|
|
|
"categories": &Category{},
|
|
|
|
"photos_labels": &PhotoLabel{},
|
|
|
|
"keywords": &Keyword{},
|
|
|
|
"photos_keywords": &PhotoKeyword{},
|
|
|
|
"passwords": &Password{},
|
|
|
|
"links": &Link{},
|
|
|
|
Subject{}.TableName(): &Subject{},
|
|
|
|
Face{}.TableName(): &Face{},
|
|
|
|
Marker{}.TableName(): &Marker{},
|
|
|
|
}
|
|
|
|
|
|
|
|
// WaitForMigration waits for the database migration to be successful.
|
2021-11-28 13:52:27 +01:00
|
|
|
func (list Tables) WaitForMigration(db *gorm.DB) {
|
2021-11-21 14:05:07 +01:00
|
|
|
type RowCount struct {
|
|
|
|
Count int
|
|
|
|
}
|
|
|
|
|
|
|
|
attempts := 100
|
|
|
|
for name := range list {
|
|
|
|
for i := 0; i <= attempts; i++ {
|
|
|
|
count := RowCount{}
|
2021-11-28 13:52:27 +01:00
|
|
|
if err := db.Raw(fmt.Sprintf("SELECT COUNT(*) AS count FROM %s", name)).Scan(&count).Error; err == nil {
|
2021-12-14 20:01:39 +01:00
|
|
|
log.Tracef("entity: %s migrated", sanitize.Log(name))
|
2021-11-21 14:05:07 +01:00
|
|
|
break
|
|
|
|
} else {
|
2021-12-14 20:01:39 +01:00
|
|
|
log.Debugf("entity: waiting for %s migration (%s)", sanitize.Log(name), err.Error())
|
2021-11-21 14:05:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if i == attempts {
|
|
|
|
panic("migration failed")
|
|
|
|
}
|
|
|
|
|
|
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Truncate removes all data from tables without dropping them.
|
2021-11-28 13:52:27 +01:00
|
|
|
func (list Tables) Truncate(db *gorm.DB) {
|
2021-11-21 14:05:07 +01:00
|
|
|
for name := range list {
|
2021-11-28 13:52:27 +01:00
|
|
|
if err := db.Exec(fmt.Sprintf("DELETE FROM %s WHERE 1", name)).Error; err == nil {
|
2021-11-21 14:05:07 +01:00
|
|
|
// log.Debugf("entity: removed all data from %s", name)
|
|
|
|
break
|
|
|
|
} else if err.Error() != "record not found" {
|
2021-12-14 20:01:39 +01:00
|
|
|
log.Debugf("entity: %s in %s", err, sanitize.Log(name))
|
2021-11-21 14:05:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Migrate migrates all database tables of registered entities.
|
2021-11-28 13:52:27 +01:00
|
|
|
func (list Tables) Migrate(db *gorm.DB, runFailed bool) {
|
2021-11-21 14:05:07 +01:00
|
|
|
for name, entity := range list {
|
2021-11-28 13:52:27 +01:00
|
|
|
if err := db.AutoMigrate(entity).Error; err != nil {
|
2021-11-21 14:05:07 +01:00
|
|
|
log.Debugf("entity: %s (waiting 1s)", err.Error())
|
|
|
|
|
|
|
|
time.Sleep(time.Second)
|
|
|
|
|
2021-11-28 13:52:27 +01:00
|
|
|
if err := db.AutoMigrate(entity).Error; err != nil {
|
2021-12-14 20:01:39 +01:00
|
|
|
log.Errorf("entity: failed migrating %s", sanitize.Log(name))
|
2021-11-21 14:05:07 +01:00
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-28 13:52:27 +01:00
|
|
|
if err := migrate.Auto(db, runFailed); err != nil {
|
2021-11-21 14:05:07 +01:00
|
|
|
log.Error(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Drop drops all database tables of registered entities.
|
2021-11-28 13:52:27 +01:00
|
|
|
func (list Tables) Drop(db *gorm.DB) {
|
2021-11-21 14:05:07 +01:00
|
|
|
for _, entity := range list {
|
2021-11-28 13:52:27 +01:00
|
|
|
if err := db.DropTableIfExists(entity).Error; err != nil {
|
2021-11-21 14:05:07 +01:00
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|