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

101 lines
2.0 KiB
Go
Raw Normal View History

2020-01-30 14:49:39 +01:00
package database
import (
"context"
2020-01-30 14:49:39 +01:00
"database/sql"
"log"
2020-01-31 15:22:58 +01:00
"net/url"
2020-01-30 14:49:39 +01:00
"os"
2020-02-19 21:33:28 +01:00
"time"
2020-01-30 14:49:39 +01:00
"github.com/pkg/errors"
2020-01-30 14:49:39 +01:00
// Load mysql driver
2020-01-31 15:22:58 +01:00
_ "github.com/go-sql-driver/mysql"
2020-01-30 15:10:01 +01:00
2020-01-31 15:22:58 +01:00
"github.com/golang-migrate/migrate"
"github.com/golang-migrate/migrate/database/mysql"
2020-02-19 21:33:28 +01:00
2020-01-31 15:22:58 +01:00
// Migrate from file
_ "github.com/golang-migrate/migrate/source/file"
2020-01-30 14:49:39 +01:00
)
// SetupDatabase connects to the database using environment variables
func SetupDatabase() (*sql.DB, error) {
2020-01-30 14:49:39 +01:00
2020-01-31 15:22:58 +01:00
address, err := url.Parse(os.Getenv("MYSQL_URL"))
if err != nil {
return nil, errors.Wrapf(err, "Could not parse mysql url")
2020-01-31 15:22:58 +01:00
}
if address.String() == "" {
return nil, errors.New("Environment variable 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()
2020-01-30 14:49:39 +01:00
log.Printf("Connecting to database: %s", address)
2020-02-19 21:33:28 +01:00
var db *sql.DB
tryCount := 0
for {
db, err = sql.Open("mysql", address.String())
if err != nil {
if tryCount < 4 {
tryCount++
log.Printf("WARN: Could not connect to database: %s. Will retry after 1 second", err.Error())
time.Sleep(time.Second)
continue
} else {
return nil, errors.New("Could not connect to database, exiting")
2020-02-19 21:33:28 +01:00
}
}
break
2020-01-30 14:49:39 +01:00
}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
2020-02-19 21:33:28 +01:00
if err := db.PingContext(ctx); err != nil {
return nil, errors.Wrap(err, "Could not ping database, exiting")
2020-01-30 14:49:39 +01:00
}
2020-02-29 10:03:56 +01:00
db.SetMaxOpenConns(80)
return db, nil
2020-01-30 14:49:39 +01:00
}
2020-01-31 15:22:58 +01:00
func MigrateDatabase(db *sql.DB) error {
driver, err := mysql.WithInstance(db, &mysql.Config{})
if err != nil {
return err
}
m, err := migrate.NewWithDatabaseInstance(
"file://database/migrations",
"mysql",
driver,
)
if err != nil {
return err
}
if err := m.Up(); err != nil {
if err.Error() == "no change" {
log.Println("Database is up to date")
} else {
return err
}
} else {
log.Println("Database migrated")
}
return nil
}