blob: 60a68ca0161be3d1eac53b6caead1923cf10d085 [file] [log] [blame]
// Package exportschema contains a re-usable Main function that exports an SQL
// schema as a JSON seriailized schema.Description.
package exportschema
import (
"context"
"encoding/json"
"flag"
"fmt"
"io"
"math/rand"
"time"
"github.com/jackc/pgx/v4/pgxpool"
"go.skia.org/infra/go/emulators"
"go.skia.org/infra/go/skerr"
"go.skia.org/infra/go/sklog"
"go.skia.org/infra/go/sql/schema"
"go.skia.org/infra/go/util"
)
// Main exports the expected schema as a serialized schema.Description.
//
// Note that this works by requiring a local instance of the CockroachDB
// emulator to be running, so this is not appropriate to call in a go:generate
// statement.
func Main(args []string, tables interface{}, schemaAsString string) error {
var out string
fs := flag.NewFlagSet("exportschema", flag.ExitOnError)
fs.StringVar(&out, "out", "", "Filename of the schema Description to write.")
err := fs.Parse(args[1:])
if err != nil {
return skerr.Wrap(err)
}
if out == "" {
return skerr.Fmt("--out flag must be supplied")
}
ctx := context.Background()
rand.Seed(time.Now().UnixNano())
databaseName := fmt.Sprintf("%s_%d", "export", rand.Uint64())
host := emulators.GetEmulatorHostEnvVar(emulators.CockroachDB)
connectionString := fmt.Sprintf("postgresql://root@%s/%s?sslmode=disable", host, databaseName)
db, err := pgxpool.Connect(ctx, connectionString)
if err != nil {
sklog.Fatal(err)
}
// Create the database in cockroachdb.
_, err = db.Exec(ctx, fmt.Sprintf(`
CREATE DATABASE %s;
SET DATABASE = %s;`, databaseName, databaseName))
if err != nil {
sklog.Fatal(err)
}
// Create the tables.
_, err = db.Exec(ctx, schemaAsString)
if err != nil {
sklog.Fatal(err)
}
sch, err := schema.GetDescription(ctx, db, tables)
if err != nil {
sklog.Fatal(err)
}
err = util.WithWriteFile(out, func(w io.Writer) error {
enc := json.NewEncoder(w)
enc.SetIndent("", " ")
return enc.Encode(sch)
})
if err != nil {
sklog.Fatal(err)
}
db.Close()
return nil
}