Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[vtctld] Migrate ApplyVSchema to VtctldServer #8113

Merged
merged 11 commits into from
Jun 7, 2021
93 changes: 93 additions & 0 deletions go/cmd/vtctldclient/internal/command/vschemas.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@ package command

import (
"fmt"
"io/ioutil"

"github.com/spf13/cobra"

"vitess.io/vitess/go/cmd/vtctldclient/cli"
"vitess.io/vitess/go/json2"

vschemapb "vitess.io/vitess/go/vt/proto/vschema"
vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata"
)

Expand All @@ -33,8 +36,89 @@ var (
Args: cobra.ExactArgs(1),
RunE: commandGetVSchema,
}
// ApplyVSchema makes an ApplyVSchema gRPC call to a vtctld.
ApplyVSchema = &cobra.Command{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A net-new thing (that you could not have known!) I'm trying to introduce is:

  • Set DisableFlagsInUseLine: true on every command. This will change the help from {{ .Use }} [flags] to just {{ .Use }} (which is better, because you include the actual named flags in the Use string).
  • Include a .Short help text, which in most cases I just copy from the old vtctl command.

Use: "ApplyVSchema {-vschema=<vschema> || -vschema-file=<vschema file> || -sql=<sql> || -sql-file=<sql file>} [-cells=c1,c2,...] [-skip-rebuild] [-dry-run] <keyspace>",
Args: cobra.ExactArgs(1),
DisableFlagsInUseLine: true,
RunE: commandApplyVSchema,
Short: "Applies the VTGate routing schema to the provided keyspace. Shows the result after application.",
}
)

var applyVSchemaOptions = struct {
VSchema string
VSchemaFile string
SQL string
SQLFile string
DryRun bool
SkipRebuild bool
Cells []string
}{}

func commandApplyVSchema(cmd *cobra.Command, args []string) error {
sqlMode := (applyVSchemaOptions.SQL != "") != (applyVSchemaOptions.SQLFile != "")
jsonMode := (applyVSchemaOptions.VSchema != "") != (applyVSchemaOptions.VSchemaFile != "")

if sqlMode && jsonMode {
return fmt.Errorf("only one of the sql, sql-file, vschema, or vschema-file flags may be specified when calling the ApplyVSchema command")
}

if !sqlMode && !jsonMode {
return fmt.Errorf("one of the sql, sql-file, vschema, or vschema-file flags must be specified when calling the ApplyVSchema command")
}

req := &vtctldatapb.ApplyVSchemaRequest{
Keyspace: cmd.Flags().Arg(0),
SkipRebuild: applyVSchemaOptions.SkipRebuild,
Cells: applyVSchemaOptions.Cells,
DryRun: applyVSchemaOptions.DryRun,
}

var err error
if sqlMode {
if applyVSchemaOptions.SQLFile != "" {
sqlBytes, err := ioutil.ReadFile(applyVSchemaOptions.SQLFile)
if err != nil {
return err
}
req.Sql = string(sqlBytes)
} else {
req.Sql = applyVSchemaOptions.SQL
}
} else { // jsonMode
var schema []byte
if applyVSchemaOptions.VSchemaFile != "" {
schema, err = ioutil.ReadFile(applyVSchemaOptions.VSchemaFile)
if err != nil {
return err
}
} else {
schema = []byte(applyVSchemaOptions.VSchema)
}

var vs *vschemapb.Keyspace
err = json2.Unmarshal(schema, vs)
if err != nil {
return err
}
req.VSchema = vs
}

cli.FinishedParsing(cmd)

res, err := client.ApplyVSchema(commandCtx, req)
if err != nil {
return err
}
data, err := cli.MarshalJSON(res.VSchema)
if err != nil {
return err
}
fmt.Printf("New VSchema object:\n%s\nIf this is not what you expected, check the input data (as JSON parsing will skip unexpected fields).\n", data)
return nil
}

func commandGetVSchema(cmd *cobra.Command, args []string) error {
cli.FinishedParsing(cmd)

Expand All @@ -58,5 +142,14 @@ func commandGetVSchema(cmd *cobra.Command, args []string) error {
}

func init() {
ApplyVSchema.Flags().StringVar(&applyVSchemaOptions.VSchema, "vschema", "", "VSchema")
ApplyVSchema.Flags().StringVar(&applyVSchemaOptions.VSchemaFile, "vschema-file", "", "VSchema File")
ApplyVSchema.Flags().StringVar(&applyVSchemaOptions.SQL, "sql", "", "A VSchema DDL SQL statement, e.g. `alter table t add vindex hash(id)`")
ApplyVSchema.Flags().StringVar(&applyVSchemaOptions.SQLFile, "sql-file", "", "A file containing VSchema DDL SQL")
ApplyVSchema.Flags().BoolVar(&applyVSchemaOptions.DryRun, "dry-run", false, "If set, do not save the altered vschema, simply echo to console.")
ApplyVSchema.Flags().BoolVar(&applyVSchemaOptions.SkipRebuild, "skip-rebuild", false, "If set, do no rebuild the SrvSchema objects.")
ApplyVSchema.Flags().StringSliceVar(&applyVSchemaOptions.Cells, "cells", nil, "If specified, limits the rebuild to the cells, after upload. Ignored if skipRebuild is set.")
Root.AddCommand(ApplyVSchema)

Root.AddCommand(GetVSchema)
}
Loading