internal/enrollment/managed_postgres.go
Rama main · réplica de lectura del repositorio original.
package enrollment
import (
"context"
"errors"
"os"
"path/filepath"
"strconv"
"strings"
embeddedpostgres "github.com/fergusstrange/embedded-postgres"
"github.com/yeomyeonggeori/blueclaw/internal/store/postgres"
)
const (
managedDatabaseName = "blueclaw"
managedAccountName = "blueclaw"
managedPassword = "blueclaw"
managedPortEnvName = "BLUECLAW_MANAGED_POSTGRES_PORT"
defaultManagedPort = 25432
)
type ManagedPostgres struct {
home Home
}
func NewManagedPostgres(home Home) ManagedPostgres {
return ManagedPostgres{home: home}
}
func (managed ManagedPostgres) DirectoryPath() string {
return filepath.Join(managed.home.DirectoryPath, "postgres")
}
func (managed ManagedPostgres) Port() uint32 {
if configuredPort := strings.TrimSpace(os.Getenv(managedPortEnvName)); configuredPort != "" {
if parsedPort, errorValue := strconv.ParseUint(configuredPort, 10, 32); errorValue == nil {
return uint32(parsedPort)
}
}
return defaultManagedPort
}
func (managed ManagedPostgres) ConnectionString() string {
return "postgres://" + managedAccountName + ":" + managedPassword + "@127.0.0.1:" + strconv.FormatUint(uint64(managed.Port()), 10) + "/" + managedDatabaseName + "?sslmode=disable"
}
func (managed ManagedPostgres) IsInstalled() bool {
_, errorValue := os.Stat(filepath.Join(managed.DirectoryPath(), "data"))
return errorValue == nil
}
func (managed ManagedPostgres) server() *embeddedpostgres.EmbeddedPostgres {
directoryPath := managed.DirectoryPath()
return embeddedpostgres.NewDatabase(embeddedpostgres.DefaultConfig().
Username(managedAccountName).
Password(managedPassword).
Database(managedDatabaseName).
Port(managed.Port()).
RuntimePath(filepath.Join(directoryPath, "runtime")).
BinariesPath(filepath.Join(directoryPath, "binaries")).
DataPath(filepath.Join(directoryPath, "data")).
CachePath(filepath.Join(directoryPath, "cache")))
}
func (managed ManagedPostgres) EnsureRunning(ctx context.Context) error {
if managed.IsReachable(ctx) {
return nil
}
if errorValue := os.MkdirAll(managed.DirectoryPath(), 0o700); errorValue != nil {
return errorValue
}
if errorValue := managed.server().Start(); errorValue != nil {
return errors.New("blueclaw could not start the database it manages for you: " + errorValue.Error())
}
if !managed.IsReachable(ctx) {
return errors.New("blueclaw started its database but cannot reach it, so something else is holding port " + strconv.FormatUint(uint64(managed.Port()), 10))
}
return nil
}
func (managed ManagedPostgres) IsReachable(ctx context.Context) bool {
connectContext, cancel := context.WithTimeout(ctx, databaseCheckTimeout)
defer cancel()
database, errorValue := postgres.OpenDatabase(connectContext, managed.ConnectionString(), 0)
if errorValue != nil {
return false
}
database.Close()
return true
}