70 lines
1.7 KiB
Go
70 lines
1.7 KiB
Go
|
package populatedb
|
||
|
|
||
|
import (
|
||
|
"database/sql"
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"net/url"
|
||
|
"time"
|
||
|
|
||
|
"github.com/go-sql-driver/mysql"
|
||
|
tblsconfig "github.com/k1LoW/tbls/config"
|
||
|
tblsdatasource "github.com/k1LoW/tbls/datasource"
|
||
|
tblsschema "github.com/k1LoW/tbls/schema"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
dialectMySQL = "mysql"
|
||
|
)
|
||
|
|
||
|
var ErrDialectNotSupport = errors.New("dialect not support ")
|
||
|
|
||
|
type Populator interface{}
|
||
|
|
||
|
type populator struct {
|
||
|
db *sql.DB
|
||
|
tblsSchema *tblsschema.Schema
|
||
|
}
|
||
|
|
||
|
func NewPopulator(dbDialect, dbURL string) (Populator, error) {
|
||
|
if dbDialect != dialectMySQL {
|
||
|
return nil, fmt.Errorf("not support [%s]: %w", dbDialect, ErrDialectNotSupport)
|
||
|
}
|
||
|
|
||
|
// https://go.dev/doc/tutorial/database-access
|
||
|
mysqlCfg, err := mysql.ParseDSN(dbURL)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("mysql: failed to parse dsn [%s]: %w", dbURL, err)
|
||
|
}
|
||
|
|
||
|
// https://github.com/go-sql-driver/mysql#timetime-support
|
||
|
mysqlCfg.ParseTime = true
|
||
|
mysqlCfg.AllowNativePasswords = true
|
||
|
mysqlCfg.Loc = time.UTC
|
||
|
|
||
|
mysqlURL := mysqlCfg.FormatDSN()
|
||
|
db, err := sql.Open(dbDialect, mysqlURL)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("sql: failed to open [%s]: %w", mysqlURL, err)
|
||
|
}
|
||
|
|
||
|
if err := db.Ping(); err != nil {
|
||
|
return nil, fmt.Errorf("database: failed to ping [%s] : %w", mysqlURL, err)
|
||
|
}
|
||
|
|
||
|
// https://github.com/k1LoW/tbls
|
||
|
// https://stackoverflow.com/q/48671938
|
||
|
tblsURL := "mysql://" + mysqlCfg.User + ":" + url.QueryEscape(mysqlCfg.Passwd) + "@" + mysqlCfg.Addr + "/" + mysqlCfg.DBName
|
||
|
tblsSchema, err := tblsdatasource.Analyze(tblsconfig.DSN{
|
||
|
URL: tblsURL,
|
||
|
})
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("tbls: faield to analyze [%s]: %w", tblsURL, err)
|
||
|
}
|
||
|
|
||
|
return &populator{
|
||
|
db: db,
|
||
|
tblsSchema: tblsSchema,
|
||
|
}, nil
|
||
|
}
|