1
Fork 0
photoview/api/database/database.go

133 lines
2.8 KiB
Go
Raw Normal View History

2020-01-30 14:49:39 +01:00
package database
import (
2021-01-12 19:12:56 +01:00
"context"
2020-01-30 14:49:39 +01:00
"log"
2020-01-31 15:22:58 +01:00
"net/url"
2020-01-30 14:49:39 +01:00
"os"
2021-01-12 19:12:56 +01:00
"time"
2020-01-30 14:49:39 +01:00
"github.com/photoview/photoview/api/database/drivers"
2020-12-17 23:18:00 +01:00
"github.com/photoview/photoview/api/graphql/models"
"github.com/pkg/errors"
"gorm.io/driver/mysql"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
2020-11-30 21:29:49 +01:00
"gorm.io/gorm/logger"
2020-01-30 14:49:39 +01:00
)
func getMysqlAddress() (*url.URL, error) {
2021-01-17 12:45:23 +01:00
address, err := url.Parse(os.Getenv("PHOTOVIEW_MYSQL_URL"))
2020-01-31 15:22:58 +01:00
if err != nil {
2020-04-15 20:52:08 +02:00
return nil, errors.Wrap(err, "Could not parse mysql url")
2020-01-31 15:22:58 +01:00
}
if address.String() == "" {
2021-01-17 12:45:23 +01:00
return nil, errors.New("Environment variable PHOTOVIEW_MYSQL_URL missing, exiting")
}
2020-01-31 15:22:58 +01:00
queryValues := address.Query()
queryValues.Add("multiStatements", "true")
2020-02-11 14:32:35 +01:00
queryValues.Add("parseTime", "true")
2020-01-31 15:22:58 +01:00
address.RawQuery = queryValues.Encode()
return address, nil
}
2020-01-31 15:22:58 +01:00
2021-01-17 12:45:23 +01:00
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) {
2020-01-30 14:49:39 +01:00
2020-11-30 21:29:49 +01:00
config := gorm.Config{}
// Enable database debug logging
config.Logger = logger.Default.LogMode(logger.Info)
var databaseDialect gorm.Dialector
switch drivers.DatabaseDriver() {
case drivers.DatabaseDriverMysql:
mysqlAddress, err := getMysqlAddress()
if err != nil {
return nil, err
}
log.Printf("Connecting to database: %s", mysqlAddress)
databaseDialect = mysql.Open(mysqlAddress.String())
case drivers.DatabaseDriverSqlite:
2021-01-17 12:45:23 +01:00
sqliteAddress, err := getSqliteAddress()
if err != nil {
return nil, err
}
2021-01-17 12:45:23 +01:00
databaseDialect = sqlite.Open(sqliteAddress.String())
}
db, err := gorm.Open(databaseDialect, &config)
2021-01-12 19:12:56 +01:00
sqlDB, dbErr := db.DB()
if dbErr != nil {
log.Println(dbErr)
return nil, dbErr
}
2021-01-12 19:12:56 +01:00
sqlDB.SetMaxOpenConns(80)
if err != nil {
for retryCount := 1; retryCount <= 5; retryCount++ {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
if err := sqlDB.PingContext(ctx); err == nil {
cancel()
return db, nil
2021-01-12 19:12:56 +01:00
}
cancel()
log.Printf("WARN: Could not ping database: %s. Will retry after 5 seconds\n", err)
time.Sleep(time.Duration(5) * time.Second)
2021-01-12 19:12:56 +01:00
}
2021-01-12 19:12:56 +01:00
return nil, err
}
return db, nil
2020-01-30 14:49:39 +01:00
}
2020-01-31 15:22:58 +01:00
func MigrateDatabase(db *gorm.DB) error {
2020-01-31 15:22:58 +01:00
2020-11-23 19:59:01 +01:00
db.AutoMigrate(
&models.User{},
&models.AccessToken{},
&models.SiteInfo{},
2020-11-23 20:43:00 +01:00
&models.Media{},
&models.MediaURL{},
2020-11-23 19:59:01 +01:00
&models.Album{},
&models.MediaEXIF{},
2020-11-25 23:06:47 +01:00
&models.VideoMetadata{},
2020-12-08 16:24:08 +01:00
&models.ShareToken{},
&models.UserMediaData{},
2020-11-23 19:59:01 +01:00
)
2020-01-31 15:22:58 +01:00
return nil
}