snapshot of https://github.com/sqlc-dev/sqlc.git (main, 2026-09-16; blobs > 131072B omitted)
Some checks failed
kotlin / test (push) Has been skipped
python / test (push) Has been skipped
typescript / test (push) Has been skipped
go / build darwin/amd64 (push) Has been cancelled
go / build linux/amd64 (push) Has been cancelled
go / build windows/amd64 (push) Has been cancelled
go / build darwin/arm64 (push) Has been cancelled
go / build linux/arm64 (push) Has been cancelled
go / build windows/arm64 (push) Has been cancelled
go / test (push) Has been cancelled
go / vuln_check (push) Has been cancelled
Some checks failed
kotlin / test (push) Has been skipped
python / test (push) Has been skipped
typescript / test (push) Has been skipped
go / build darwin/amd64 (push) Has been cancelled
go / build linux/amd64 (push) Has been cancelled
go / build windows/amd64 (push) Has been cancelled
go / build darwin/arm64 (push) Has been cancelled
go / build linux/arm64 (push) Has been cancelled
go / build windows/arm64 (push) Has been cancelled
go / test (push) Has been cancelled
go / vuln_check (push) Has been cancelled
This commit is contained in:
23
internal/sqltest/docker/enabled.go
Normal file
23
internal/sqltest/docker/enabled.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
|
||||
"golang.org/x/sync/singleflight"
|
||||
)
|
||||
|
||||
var flight singleflight.Group
|
||||
|
||||
func Installed() error {
|
||||
if _, err := exec.LookPath("docker"); err != nil {
|
||||
return fmt.Errorf("docker not found: %w", err)
|
||||
}
|
||||
// Verify the Docker daemon is actually running and accessible.
|
||||
// Without this check, tests will try Docker, fail on docker pull,
|
||||
// and t.Fatal instead of falling back to native database support.
|
||||
if out, err := exec.Command("docker", "info").CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("docker daemon not available: %w\n%s", err, out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
104
internal/sqltest/docker/mysql.go
Normal file
104
internal/sqltest/docker/mysql.go
Normal file
@@ -0,0 +1,104 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
)
|
||||
|
||||
var mysqlHost string
|
||||
|
||||
func StartMySQLServer(c context.Context) (string, error) {
|
||||
if err := Installed(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if mysqlHost != "" {
|
||||
return mysqlHost, nil
|
||||
}
|
||||
value, err, _ := flight.Do("mysql", func() (any, error) {
|
||||
host, err := startMySQLServer(c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
mysqlHost = host
|
||||
return host, nil
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
data, ok := value.(string)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("returned value was not a string")
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func startMySQLServer(c context.Context) (string, error) {
|
||||
{
|
||||
_, err := exec.Command("docker", "pull", "mysql:9").CombinedOutput()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("docker pull: mysql:9 %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
var exists bool
|
||||
{
|
||||
cmd := exec.Command("docker", "container", "inspect", "sqlc_sqltest_docker_mysql")
|
||||
// This means we've already started the container
|
||||
exists = cmd.Run() == nil
|
||||
}
|
||||
|
||||
if !exists {
|
||||
cmd := exec.Command("docker", "run",
|
||||
"--name", "sqlc_sqltest_docker_mysql",
|
||||
"-e", "MYSQL_ROOT_PASSWORD=mysecretpassword",
|
||||
"-e", "MYSQL_DATABASE=dinotest",
|
||||
"-p", "3306:3306",
|
||||
"-d",
|
||||
"mysql:9",
|
||||
)
|
||||
|
||||
output, err := cmd.CombinedOutput()
|
||||
fmt.Println(string(output))
|
||||
|
||||
msg := `Conflict. The container name "/sqlc_sqltest_docker_mysql" is already in use by container`
|
||||
if !strings.Contains(string(output), msg) && err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(c, 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Create a ticker that fires every 10ms
|
||||
ticker := time.NewTicker(10 * time.Millisecond)
|
||||
defer ticker.Stop()
|
||||
|
||||
uri := "root:mysecretpassword@/dinotest?multiStatements=true&parseTime=true"
|
||||
|
||||
db, err := sql.Open("mysql", uri)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("sql.Open: %w", err)
|
||||
}
|
||||
|
||||
defer db.Close()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return "", fmt.Errorf("timeout reached: %w", ctx.Err())
|
||||
|
||||
case <-ticker.C:
|
||||
// Run your function here
|
||||
if err := db.PingContext(ctx); err != nil {
|
||||
continue
|
||||
}
|
||||
return uri, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
105
internal/sqltest/docker/postgres.go
Normal file
105
internal/sqltest/docker/postgres.go
Normal file
@@ -0,0 +1,105 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
)
|
||||
|
||||
var postgresHost string
|
||||
|
||||
func StartPostgreSQLServer(c context.Context) (string, error) {
|
||||
if err := Installed(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if postgresHost != "" {
|
||||
return postgresHost, nil
|
||||
}
|
||||
value, err, _ := flight.Do("postgresql", func() (any, error) {
|
||||
host, err := startPostgreSQLServer(c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
postgresHost = host
|
||||
return host, err
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
data, ok := value.(string)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("returned value was not a string")
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func startPostgreSQLServer(c context.Context) (string, error) {
|
||||
{
|
||||
_, err := exec.Command("docker", "pull", "postgres:16").CombinedOutput()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("docker pull: postgres:16 %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
uri := "postgres://postgres:mysecretpassword@localhost:5432/postgres?sslmode=disable"
|
||||
|
||||
var exists bool
|
||||
{
|
||||
cmd := exec.Command("docker", "container", "inspect", "sqlc_sqltest_docker_postgres")
|
||||
// This means we've already started the container
|
||||
exists = cmd.Run() == nil
|
||||
}
|
||||
|
||||
if !exists {
|
||||
cmd := exec.Command("docker", "run",
|
||||
"--name", "sqlc_sqltest_docker_postgres",
|
||||
"-e", "POSTGRES_PASSWORD=mysecretpassword",
|
||||
"-e", "POSTGRES_USER=postgres",
|
||||
"-p", "5432:5432",
|
||||
"-d",
|
||||
"postgres:16",
|
||||
"-c", "max_connections=200",
|
||||
)
|
||||
|
||||
output, err := cmd.CombinedOutput()
|
||||
fmt.Println(string(output))
|
||||
|
||||
msg := `Conflict. The container name "/sqlc_sqltest_docker_postgres" is already in use by container`
|
||||
if !strings.Contains(string(output), msg) && err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(c, 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Create a ticker that fires every 10ms
|
||||
ticker := time.NewTicker(10 * time.Millisecond)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return "", fmt.Errorf("timeout reached: %w", ctx.Err())
|
||||
|
||||
case <-ticker.C:
|
||||
// Run your function here
|
||||
conn, err := pgx.Connect(ctx, uri)
|
||||
if err != nil {
|
||||
slog.Debug("sqltest", "connect", err)
|
||||
continue
|
||||
}
|
||||
defer conn.Close(ctx)
|
||||
if err := conn.Ping(ctx); err != nil {
|
||||
slog.Error("sqltest", "ping", err)
|
||||
continue
|
||||
}
|
||||
return uri, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user