From fcdb5b4e7b13c0bf3d51fc4a44fca10af82513d9 Mon Sep 17 00:00:00 2001 From: viktorstrate Date: Sun, 17 Jan 2021 12:45:23 +0100 Subject: [PATCH] Work on sqlite support --- api/database/database.go | 37 +++++++++++++++++++++++++++++------- api/example.env | 2 +- api/graphql/models/media.go | 8 ++------ api/graphql/models/utils.go | 9 +++++++++ api/scanner/scanner_album.go | 2 +- api/scanner/scanner_media.go | 2 +- api/scanner/scanner_user.go | 2 +- 7 files changed, 45 insertions(+), 17 deletions(-) diff --git a/api/database/database.go b/api/database/database.go index 5adfc098..417b0878 100644 --- a/api/database/database.go +++ b/api/database/database.go @@ -18,13 +18,13 @@ import ( ) func getMysqlAddress() (*url.URL, error) { - address, err := url.Parse(os.Getenv("MYSQL_URL")) + address, err := url.Parse(os.Getenv("PHOTOVIEW_MYSQL_URL")) if err != nil { return nil, errors.Wrap(err, "Could not parse mysql url") } if address.String() == "" { - return nil, errors.New("Environment variable MYSQL_URL missing, exiting") + return nil, errors.New("Environment variable PHOTOVIEW_MYSQL_URL missing, exiting") } queryValues := address.Query() @@ -35,6 +35,28 @@ func getMysqlAddress() (*url.URL, error) { return address, nil } +func getSqliteAddress() (*url.URL, error) { + path := os.Getenv("PHOTOVIEW_SQLITE_PATH") + if path == "" { + path = "photoview.db" + } + + address, err := url.Parse(path) + if err != nil { + return nil, errors.Wrapf(err, "Could not parse sqlite url (%s)", path) + } + + queryValues := address.Query() + queryValues.Add("cache", "shared") + queryValues.Add("mode", "rwc") + // queryValues.Add("_busy_timeout", "60000") // 1 minute + address.RawQuery = queryValues.Encode() + + // log.Panicf("%s", address.String()) + + return address, nil +} + // SetupDatabase connects to the database using environment variables func SetupDatabase() (*gorm.DB, error) { @@ -44,7 +66,8 @@ func SetupDatabase() (*gorm.DB, error) { config.Logger = logger.Default.LogMode(logger.Info) var databaseDialect gorm.Dialector - switch strings.ToLower(os.Getenv("PHOTOVIEW_DATABASE_DRIVER")) { + databaseDriver := strings.ToLower(os.Getenv("PHOTOVIEW_DATABASE_DRIVER")) + switch databaseDriver { case "mysql": mysqlAddress, err := getMysqlAddress() if err != nil { @@ -54,11 +77,11 @@ func SetupDatabase() (*gorm.DB, error) { databaseDialect = mysql.Open(mysqlAddress.String()) case "sqlite": - path := os.Getenv("PHOTOVIEW_SQLITE_PATH") - if path == "" { - path = "photoview.db" + sqliteAddress, err := getSqliteAddress() + if err != nil { + return nil, err } - databaseDialect = sqlite.Open(path) + databaseDialect = sqlite.Open(sqliteAddress.String()) } db, err := gorm.Open(databaseDialect, &config) diff --git a/api/example.env b/api/example.env index 1eae1a9c..5d35a056 100644 --- a/api/example.env +++ b/api/example.env @@ -1,6 +1,6 @@ # Copy this file to .env -MYSQL_URL=user:password@tcp(localhost)/dbname +PHOTOVIEW_MYSQL_URL=user:password@tcp(localhost)/dbname PHOTOVIEW_LISTEN_IP=localhost PHOTOVIEW_LISTEN_PORT=4001 diff --git a/api/graphql/models/media.go b/api/graphql/models/media.go index 36d813bb..f911237a 100644 --- a/api/graphql/models/media.go +++ b/api/graphql/models/media.go @@ -1,8 +1,6 @@ package models import ( - "crypto/md5" - "encoding/hex" "path" "strings" "time" @@ -40,12 +38,10 @@ func (Media) TableName() string { func (m *Media) BeforeSave(tx *gorm.DB) error { // Update hashes - hash := md5.Sum([]byte(m.Path)) - m.PathHash = hex.EncodeToString(hash[:]) + m.PathHash = MD5Hash(m.Path) if m.SideCarPath != nil { - hash = md5.Sum([]byte(*m.SideCarPath)) - encodedHash := hex.EncodeToString(hash[:]) + encodedHash := MD5Hash(*m.SideCarPath) m.SideCarHash = &encodedHash } diff --git a/api/graphql/models/utils.go b/api/graphql/models/utils.go index 520bdc2f..93caf5a5 100644 --- a/api/graphql/models/utils.go +++ b/api/graphql/models/utils.go @@ -1,6 +1,9 @@ package models import ( + "crypto/md5" + "encoding/hex" + "gorm.io/gorm" "gorm.io/gorm/clause" ) @@ -38,3 +41,9 @@ func (filter *Filter) FormatSQL(tx *gorm.DB) *gorm.DB { return tx } + +// MD5Hash hashes value to a 32 length digest, the result is the same as the MYSQL function md5() +func MD5Hash(value string) string { + hash := md5.Sum([]byte(value)) + return hex.EncodeToString(hash[:]) +} diff --git a/api/scanner/scanner_album.go b/api/scanner/scanner_album.go index 1a328573..c1dae395 100644 --- a/api/scanner/scanner_album.go +++ b/api/scanner/scanner_album.go @@ -20,7 +20,7 @@ func NewRootAlbum(db *gorm.DB, rootPath string, owner *models.User) (*models.Alb } var matchedAlbums []models.Album - if err := db.Where("path_hash = MD5(?)", rootPath).Find(&matchedAlbums).Error; err != nil { + if err := db.Where("path_hash = ?", models.MD5Hash(rootPath)).Find(&matchedAlbums).Error; err != nil { return nil, err } diff --git a/api/scanner/scanner_media.go b/api/scanner/scanner_media.go index e9e7ba1f..cc272726 100644 --- a/api/scanner/scanner_media.go +++ b/api/scanner/scanner_media.go @@ -109,7 +109,7 @@ func ScanMedia(tx *gorm.DB, mediaPath string, albumId int, cache *AlbumScannerCa { var media []*models.Media - result := tx.Where("path_hash = MD5(?)", mediaPath).Find(&media) + result := tx.Where("path_hash = ?", models.MD5Hash(mediaPath)).Find(&media) if result.Error != nil { return nil, false, errors.Wrap(result.Error, "scan media fetch from database") diff --git a/api/scanner/scanner_user.go b/api/scanner/scanner_user.go index eb4ba153..bee7c3d0 100644 --- a/api/scanner/scanner_user.go +++ b/api/scanner/scanner_user.go @@ -80,7 +80,7 @@ func findAlbumsForUser(db *gorm.DB, user *models.User, album_cache *AlbumScanner // check if album already exists var albumResult []models.Album - result := tx.Where("path_hash = md5(?)", albumPath).Find(&albumResult) + result := tx.Where("path_hash = ?", models.MD5Hash(albumPath)).Find(&albumResult) if result.Error != nil { return result.Error }