harness-drone/store/shared/db/conn.go
2021-06-22 10:20:17 +01:00

86 lines
1.8 KiB
Go

// Copyright 2019 Drone.IO Inc. All rights reserved.
// Use of this source code is governed by the Drone Non-Commercial License
// that can be found in the LICENSE file.
// +build !oss
package db
import (
"database/sql"
"sync"
"time"
"github.com/jmoiron/sqlx"
"github.com/drone/drone/store/shared/migrate/mysql"
"github.com/drone/drone/store/shared/migrate/postgres"
"github.com/drone/drone/store/shared/migrate/sqlite"
)
// Connect to a database and verify with a ping.
func Connect(driver, datasource string, maxOpenConnections int) (*DB, error) {
db, err := sql.Open(driver, datasource)
if err != nil {
return nil, err
}
switch driver {
case "mysql":
db.SetMaxIdleConns(0)
}
if err := pingDatabase(db); err != nil {
return nil, err
}
if err := setupDatabase(db, driver); err != nil {
return nil, err
}
// generally set to 0, user configured for larger installs
db.SetMaxOpenConns(maxOpenConnections)
var engine Driver
var locker Locker
switch driver {
case "mysql":
engine = Mysql
locker = &nopLocker{}
case "postgres":
engine = Postgres
locker = &nopLocker{}
default:
engine = Sqlite
locker = &sync.RWMutex{}
}
return &DB{
conn: sqlx.NewDb(db, driver),
lock: locker,
driver: engine,
}, nil
}
// helper function to ping the database with backoff to ensure
// a connection can be established before we proceed with the
// database setup and migration.
func pingDatabase(db *sql.DB) (err error) {
for i := 0; i < 30; i++ {
err = db.Ping()
if err == nil {
return
}
time.Sleep(time.Second)
}
return
}
// helper function to setup the database by performing automated
// database migration steps.
func setupDatabase(db *sql.DB, driver string) error {
switch driver {
case "mysql":
return mysql.Migrate(db)
case "postgres":
return postgres.Migrate(db)
default:
return sqlite.Migrate(db)
}
}