wisski-cloud-distillery/internal/dis/component/sql/connect.go
Tom Wiesing 39207a1cb5
pkg/environment: Remove 'net' related functions
This commit continues removing the environment abstraction and removes
all 'net' related functions, replacing them by their native equivalents.
2023-03-02 11:07:50 +01:00

122 lines
2.7 KiB
Go

package sql
import (
"context"
"database/sql"
"fmt"
"time"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/models"
"github.com/tkw1536/pkglib/timex"
)
//
// ========== low-level connection ==========
//
// Exec executes a database-independent database query.
func (sql *SQL) Exec(query string, args ...interface{}) error {
// connect to the server
conn, err := sql.connect("")
if err != nil {
return err
}
// do the query!
{
_, err := conn.Exec(query, args...)
if err != nil {
return err
}
return nil
}
}
//
// ========== connection via gorm ==========
//
// QueryTable returns a gorm.DB to connect to the provided table of the given model
func (sql *SQL) QueryTable(ctx context.Context, table component.Table) (*gorm.DB, error) {
return sql.queryTable(ctx, false, table.TableInfo().Name)
}
// queryTable returns a gorm.DB to connect to the provided distillery database table
func (sql *SQL) queryTable(ctx context.Context, silent bool, table string) (*gorm.DB, error) {
conn, err := sql.connect(sql.Config.SQL.Database)
if err != nil {
return nil, err
}
// gorm configuration
config := &gorm.Config{
Logger: newGormLogger(),
}
if silent {
config.Logger = config.Logger.LogMode(logger.Silent)
} else {
config.Logger = config.Logger.LogMode(logger.Info)
}
// mysql connection
cfg := mysql.Config{
Conn: conn,
DefaultStringSize: 256,
}
// open the gorm connection!
db, err := gorm.Open(mysql.New(cfg), config)
if err != nil {
return nil, err
}
// set the table
db = db.WithContext(ctx).Table(table)
// check that nothing went wrong
if db.Error != nil {
return nil, db.Error
}
return db, nil
}
// WaitQueryTable waits for a connection to succeed via QueryTable
func (sql *SQL) WaitQueryTable(ctx context.Context) error {
// TODO: Establish a convention on when to wait for this!
return timex.TickUntilFunc(func(time.Time) bool {
// TODO: Use a different table here
_, err := sql.queryTable(ctx, true, models.InstanceTable)
return err == nil
}, ctx, sql.PollInterval)
}
//
// ========== low-level database connection ==========
//
func (ssql *SQL) connect(database string) (*sql.DB, error) {
conn, err := sql.Open("mysql", ssql.dsn(database))
if err != nil {
return nil, err
}
conn.SetMaxIdleConns(0)
return conn, nil
}
// dsn returns a dsn fof connecting to the database
func (sql *SQL) dsn(database string) string {
user := sql.Config.SQL.AdminUsername
pass := sql.Config.SQL.AdminPassword
network := "tcp"
server := sql.ServerURL
return fmt.Sprintf("%s:%s@%s(%s)/%s?charset=utf8&parseTime=True&loc=Local", user, pass, network, server, database)
}