Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
It's all broken
  • Loading branch information
kyleconroy committed May 8, 2024
commit 0a485ddd6feaa5d31422bbebbee09e6c746c264b
4 changes: 4 additions & 0 deletions internal/compiler/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package compiler
import (
"errors"
"fmt"
"hash/fnv"
"io"
"os"
"path/filepath"
Expand Down Expand Up @@ -31,13 +32,15 @@ func (c *Compiler) parseCatalog(schemas []string) error {
return err
}
merr := multierr.New()
h := fnv.New64()
for _, filename := range files {
blob, err := os.ReadFile(filename)
if err != nil {
merr.Add(filename, "", 0, err)
continue
}
contents := migrations.RemoveRollbackStatements(string(blob))
io.WriteString(h, contents)
c.schema = append(c.schema, contents)
stmts, err := c.parser.Parse(strings.NewReader(contents))
if err != nil {
Expand All @@ -51,6 +54,7 @@ func (c *Compiler) parseCatalog(schemas []string) error {
}
}
}
c.schemaHash = fmt.Sprintf("%x", h.Sum(nil))
if len(merr.Errs()) > 0 {
return merr
}
Expand Down
3 changes: 2 additions & 1 deletion internal/compiler/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ type Compiler struct {
analyzer analyzer.Analyzer
client pb.QuickClient

schema []string
schema []string
schemaHash string
}

func NewCompiler(conf config.SQL, combo config.CombinedSettings) (*Compiler, error) {
Expand Down
6 changes: 6 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ const (
type Config struct {
Version string `json:"version" yaml:"version"`
Cloud Cloud `json:"cloud" yaml:"cloud"`
Servers []Server `json:"servers" yaml:"servers"`
SQL []SQL `json:"sql" yaml:"sql"`
Overrides Overrides `json:"overrides,omitempty" yaml:"overrides"`
Plugins []Plugin `json:"plugins" yaml:"plugins"`
Expand All @@ -78,6 +79,11 @@ type Cloud struct {
AuthToken string `json:"-" yaml:"-"`
}

type Server struct {
Name string `json:"name" yaml:"name"`
URI string `json:"uri" yaml:"uri"`
}

type Plugin struct {
Name string `json:"name" yaml:"name"`
Env []string `json:"env" yaml:"env"`
Expand Down
114 changes: 114 additions & 0 deletions internal/pgx/createdb/createdb.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package createdb

import (
"context"
"fmt"
"hash/fnv"
"net/url"
"os"
"strings"

"github.com/jackc/pgx/v4/pgxpool"
"github.com/jackc/pgx/v5"
"golang.org/x/sync/singleflight"

migrate "github.com/sqlc-dev/sqlc/internal/migrations"
"github.com/sqlc-dev/sqlc/internal/pgx/poolcache"
"github.com/sqlc-dev/sqlc/internal/sql/sqlpath"
)

var flight singleflight.Group
var cache = poolcache.New()

type Server struct {
pool *pgxpool.Pool
}

func Create(ctx context.Context, srv *pgxpool.Pool, migrations []string) (*pgxpool.Pool, error) {
ctx := context.Background()

dburi := os.Getenv("POSTGRESQL_SERVER_URI")
if dburi == "" {
t.Skip("POSTGRESQL_SERVER_URI is empty")
}

postgresPool, err := cache.Open(ctx, dburi)
if err != nil {
t.Fatalf("PostgreSQL pool creation failed: %s", err)
}

var seed []string
files, err := sqlpath.Glob(migrations)
if err != nil {
t.Fatal(err)
}

h := fnv.New64()
for _, f := range files {
blob, err := os.ReadFile(f)
if err != nil {
t.Fatal(err)
}
h.Write(blob)
seed = append(seed, migrate.RemoveRollbackStatements(string(blob)))
}

var name string
if rw {
name = fmt.Sprintf("sqlc_test_%s", id())
} else {
name = fmt.Sprintf("sqlc_test_%x", h.Sum(nil))
}

uri, err := url.Parse(dburi)
if err != nil {
t.Fatal(err)
}
uri.Path = name
dropQuery := fmt.Sprintf(`DROP DATABASE IF EXISTS "%s" WITH (FORCE)`, name)

key := uri.String()

_, err, _ = flight.Do(key, func() (interface{}, error) {
row := postgresPool.QueryRow(ctx,
fmt.Sprintf(`SELECT datname FROM pg_database WHERE datname = '%s'`, name))

var datname string
if err := row.Scan(&datname); err == nil {
t.Logf("database exists: %s", name)
return nil, nil
}

t.Logf("creating database: %s", name)
if _, err := postgresPool.Exec(ctx, fmt.Sprintf(`CREATE DATABASE "%s"`, name)); err != nil {
return nil, err
}

conn, err := pgx.Connect(ctx, uri.String())
if err != nil {
return nil, fmt.Errorf("connect %s: %s", name, err)
}
defer conn.Close(ctx)

for _, q := range seed {
if len(strings.TrimSpace(q)) == 0 {
continue
}
if _, err := conn.Exec(ctx, q); err != nil {
return nil, fmt.Errorf("%s: %s", q, err)
}
}
return nil, nil
})
if rw || err != nil {
t.Cleanup(func() {
if _, err := postgresPool.Exec(ctx, dropQuery); err != nil {
t.Fatalf("failed cleaning up: %s", err)
}
})
}
if err != nil {
t.Fatalf("create db: %s", err)
}
return key
}
27 changes: 18 additions & 9 deletions internal/pgx/poolcache/poolcache.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,22 @@ import (
"github.com/jackc/pgx/v5/pgxpool"
)

var lock sync.RWMutex
var pools = map[string]*pgxpool.Pool{}
type Cache struct {
lock sync.RWMutex
pools map[string]*pgxpool.Pool
}

func New() *Cache {
return &Cache{
pools: map[string]*pgxpool.Pool{},
}
}

func New(ctx context.Context, uri string) (*pgxpool.Pool, error) {
lock.RLock()
existing, found := pools[uri]
lock.RUnlock()
// Should only be used in testing contexts
func (c *Cache) Open(ctx context.Context, uri string) (*pgxpool.Pool, error) {
c.lock.RLock()
existing, found := c.pools[uri]
c.lock.RUnlock()

if found {
return existing, nil
Expand All @@ -24,9 +33,9 @@ func New(ctx context.Context, uri string) (*pgxpool.Pool, error) {
return nil, err
}

lock.Lock()
pools[uri] = pool
lock.Unlock()
c.lock.Lock()
c.pools[uri] = pool
c.lock.Unlock()

return pool, nil
}
3 changes: 2 additions & 1 deletion internal/sqltest/local/postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
)

var flight singleflight.Group
var cache = poolcache.New()

func PostgreSQL(t *testing.T, migrations []string) string {
return postgreSQL(t, migrations, true)
Expand All @@ -36,7 +37,7 @@ func postgreSQL(t *testing.T, migrations []string, rw bool) string {
t.Skip("POSTGRESQL_SERVER_URI is empty")
}

postgresPool, err := poolcache.New(ctx, dburi)
postgresPool, err := cache.Open(ctx, dburi)
if err != nil {
t.Fatalf("PostgreSQL pool creation failed: %s", err)
}
Expand Down