2019-02-24 21:30:53 +00:00
|
|
|
// Package msql implements connecting to a MySQL/MariaDB instance (and possibly
|
|
|
|
// others) and simplifies a number of interactions with it.
|
|
|
|
package msql
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
// If something is importing msql it must need mysql, because that's all
|
|
|
|
// that is implemented at the moment
|
|
|
|
_ "github.com/go-sql-driver/mysql"
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
|
|
"github.com/mediocregopher/mediocre-go-lib/mcfg"
|
2019-06-23 18:55:55 +00:00
|
|
|
"github.com/mediocregopher/mediocre-go-lib/mcmp"
|
2019-02-24 21:30:53 +00:00
|
|
|
"github.com/mediocregopher/mediocre-go-lib/mctx"
|
|
|
|
"github.com/mediocregopher/mediocre-go-lib/merr"
|
|
|
|
"github.com/mediocregopher/mediocre-go-lib/mlog"
|
|
|
|
"github.com/mediocregopher/mediocre-go-lib/mrun"
|
|
|
|
)
|
|
|
|
|
|
|
|
// SQL is a wrapper around a sqlx client which provides more functionality.
|
|
|
|
type SQL struct {
|
|
|
|
*sqlx.DB
|
2019-06-23 18:55:55 +00:00
|
|
|
cmp *mcmp.Component
|
2019-02-24 21:30:53 +00:00
|
|
|
}
|
|
|
|
|
2019-06-23 18:55:55 +00:00
|
|
|
// InstMySQL returns a SQL instance which will be initialized when the Init
|
|
|
|
// event is triggered on the given Component. The SQL instance will have Close
|
|
|
|
// called on it when the Shutdown event is triggered on the given Component.
|
2019-02-24 21:30:53 +00:00
|
|
|
//
|
|
|
|
// defaultDB indicates the name of the database in MySQL to use by default,
|
|
|
|
// though it will be overwritable in the config.
|
2019-06-23 18:55:55 +00:00
|
|
|
func InstMySQL(cmp *mcmp.Component, defaultDB string) *SQL {
|
|
|
|
sql := SQL{cmp: cmp.Child("mysql")}
|
2019-02-24 21:30:53 +00:00
|
|
|
|
2019-06-23 18:55:55 +00:00
|
|
|
addr := mcfg.String(sql.cmp, "addr",
|
|
|
|
mcfg.ParamDefault("[::1]:3306"),
|
|
|
|
mcfg.ParamUsage("Address where MySQL server can be found"))
|
|
|
|
user := mcfg.String(sql.cmp, "user",
|
|
|
|
mcfg.ParamDefault("root"),
|
|
|
|
mcfg.ParamUsage("User to authenticate to MySQL server as"))
|
|
|
|
pass := mcfg.String(sql.cmp, "password",
|
|
|
|
mcfg.ParamUsage("Password to authenticate to MySQL server with"))
|
|
|
|
db := mcfg.String(sql.cmp, "database",
|
|
|
|
mcfg.ParamDefault(defaultDB),
|
|
|
|
mcfg.ParamUsage("MySQL database to use"))
|
2019-02-24 21:30:53 +00:00
|
|
|
|
2019-06-23 18:55:55 +00:00
|
|
|
mrun.InitHook(sql.cmp, func(ctx context.Context) error {
|
|
|
|
sql.cmp.Annotate("addr", *addr, "user", *user)
|
2019-02-24 21:30:53 +00:00
|
|
|
dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s", *user, *pass, *addr, *db)
|
2019-06-23 18:55:55 +00:00
|
|
|
mlog.From(sql.cmp).Debug("constructed dsn", mctx.Annotate(ctx, "dsn", dsn))
|
|
|
|
mlog.From(sql.cmp).Info("connecting to MySQL server", ctx)
|
2019-02-24 21:30:53 +00:00
|
|
|
var err error
|
2019-06-23 18:55:55 +00:00
|
|
|
sql.DB, err = sqlx.ConnectContext(ctx, "mysql", dsn)
|
|
|
|
return merr.Wrap(err, sql.cmp.Context(), ctx)
|
2019-02-24 21:30:53 +00:00
|
|
|
})
|
2019-06-23 18:55:55 +00:00
|
|
|
|
|
|
|
mrun.ShutdownHook(sql.cmp, func(ctx context.Context) error {
|
|
|
|
mlog.From(sql.cmp).Info("closing connection to MySQL server", ctx)
|
|
|
|
return merr.Wrap(sql.Close(), sql.cmp.Context(), ctx)
|
2019-02-24 21:30:53 +00:00
|
|
|
})
|
|
|
|
|
2019-06-23 18:55:55 +00:00
|
|
|
return &sql
|
2019-02-24 21:30:53 +00:00
|
|
|
}
|
2019-02-24 22:07:35 +00:00
|
|
|
|
|
|
|
// Context returns the annotated Context from this instance's initialization.
|
|
|
|
func (sql *SQL) Context() context.Context {
|
2019-06-23 18:55:55 +00:00
|
|
|
return sql.cmp.Context()
|
2019-02-24 22:07:35 +00:00
|
|
|
}
|