vitess.io/vitess@v0.16.2/go/cmd/vtctldclient/command/vschemas.go (about)

     1  /*
     2  Copyright 2021 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  	http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package command
    18  
    19  import (
    20  	"fmt"
    21  	"os"
    22  
    23  	"github.com/spf13/cobra"
    24  
    25  	"vitess.io/vitess/go/cmd/vtctldclient/cli"
    26  	"vitess.io/vitess/go/json2"
    27  
    28  	vschemapb "vitess.io/vitess/go/vt/proto/vschema"
    29  	vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata"
    30  )
    31  
    32  var (
    33  	// GetVSchema makes a GetVSchema gRPC call to a vtctld.
    34  	GetVSchema = &cobra.Command{
    35  		Use:                   "GetVSchema <keyspace>",
    36  		Short:                 "Prints a JSON representation of a keyspace's topo record.",
    37  		DisableFlagsInUseLine: true,
    38  		Args:                  cobra.ExactArgs(1),
    39  		RunE:                  commandGetVSchema,
    40  	}
    41  	// ApplyVSchema makes an ApplyVSchema gRPC call to a vtctld.
    42  	ApplyVSchema = &cobra.Command{
    43  		Use:                   "ApplyVSchema {--vschema=<vschema> || --vschema-file=<vschema file> || --sql=<sql> || --sql-file=<sql file>} [--cells=c1,c2,...] [--skip-rebuild] [--dry-run] <keyspace>",
    44  		Short:                 "Applies the VTGate routing schema to the provided keyspace. Shows the result after application.",
    45  		DisableFlagsInUseLine: true,
    46  		Args:                  cobra.ExactArgs(1),
    47  		RunE:                  commandApplyVSchema,
    48  	}
    49  )
    50  
    51  var applyVSchemaOptions = struct {
    52  	VSchema     string
    53  	VSchemaFile string
    54  	SQL         string
    55  	SQLFile     string
    56  	DryRun      bool
    57  	SkipRebuild bool
    58  	Cells       []string
    59  }{}
    60  
    61  func commandApplyVSchema(cmd *cobra.Command, args []string) error {
    62  	sqlMode := (applyVSchemaOptions.SQL != "") != (applyVSchemaOptions.SQLFile != "")
    63  	jsonMode := (applyVSchemaOptions.VSchema != "") != (applyVSchemaOptions.VSchemaFile != "")
    64  
    65  	if sqlMode && jsonMode {
    66  		return fmt.Errorf("only one of the sql, sql-file, vschema, or vschema-file flags may be specified when calling the ApplyVSchema command")
    67  	}
    68  
    69  	if !sqlMode && !jsonMode {
    70  		return fmt.Errorf("one of the sql, sql-file, vschema, or vschema-file flags must be specified when calling the ApplyVSchema command")
    71  	}
    72  
    73  	req := &vtctldatapb.ApplyVSchemaRequest{
    74  		Keyspace:    cmd.Flags().Arg(0),
    75  		SkipRebuild: applyVSchemaOptions.SkipRebuild,
    76  		Cells:       applyVSchemaOptions.Cells,
    77  		DryRun:      applyVSchemaOptions.DryRun,
    78  	}
    79  
    80  	var err error
    81  	if sqlMode {
    82  		if applyVSchemaOptions.SQLFile != "" {
    83  			sqlBytes, err := os.ReadFile(applyVSchemaOptions.SQLFile)
    84  			if err != nil {
    85  				return err
    86  			}
    87  			req.Sql = string(sqlBytes)
    88  		} else {
    89  			req.Sql = applyVSchemaOptions.SQL
    90  		}
    91  	} else { // jsonMode
    92  		var schema []byte
    93  		if applyVSchemaOptions.VSchemaFile != "" {
    94  			schema, err = os.ReadFile(applyVSchemaOptions.VSchemaFile)
    95  			if err != nil {
    96  				return err
    97  			}
    98  		} else {
    99  			schema = []byte(applyVSchemaOptions.VSchema)
   100  		}
   101  
   102  		var vs vschemapb.Keyspace
   103  		err = json2.Unmarshal(schema, &vs)
   104  		if err != nil {
   105  			return err
   106  		}
   107  		req.VSchema = &vs
   108  	}
   109  
   110  	cli.FinishedParsing(cmd)
   111  
   112  	res, err := client.ApplyVSchema(commandCtx, req)
   113  	if err != nil {
   114  		return err
   115  	}
   116  	data, err := cli.MarshalJSON(res.VSchema)
   117  	if err != nil {
   118  		return err
   119  	}
   120  	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)
   121  	return nil
   122  }
   123  
   124  func commandGetVSchema(cmd *cobra.Command, args []string) error {
   125  	cli.FinishedParsing(cmd)
   126  
   127  	keyspace := cmd.Flags().Arg(0)
   128  
   129  	resp, err := client.GetVSchema(commandCtx, &vtctldatapb.GetVSchemaRequest{
   130  		Keyspace: keyspace,
   131  	})
   132  	if err != nil {
   133  		return err
   134  	}
   135  
   136  	data, err := cli.MarshalJSON(resp.VSchema)
   137  	if err != nil {
   138  		return err
   139  	}
   140  
   141  	fmt.Printf("%s\n", data)
   142  
   143  	return nil
   144  }
   145  
   146  func init() {
   147  	ApplyVSchema.Flags().StringVar(&applyVSchemaOptions.VSchema, "vschema", "", "VSchema to apply, in JSON form.")
   148  	ApplyVSchema.Flags().StringVar(&applyVSchemaOptions.VSchemaFile, "vschema-file", "", "Path to a file containing the vschema to apply, in JSON form.")
   149  	ApplyVSchema.Flags().StringVar(&applyVSchemaOptions.SQL, "sql", "", "A VSchema DDL SQL statement, e.g. `alter table t add vindex hash(id)`.")
   150  	ApplyVSchema.Flags().StringVar(&applyVSchemaOptions.SQLFile, "sql-file", "", "Path to a file containing a VSchema DDL SQL.")
   151  	ApplyVSchema.Flags().BoolVar(&applyVSchemaOptions.DryRun, "dry-run", false, "If set, do not save the altered vschema, simply echo to console.")
   152  	ApplyVSchema.Flags().BoolVar(&applyVSchemaOptions.SkipRebuild, "skip-rebuild", false, "Skip rebuilding the SrvSchema objects.")
   153  	ApplyVSchema.Flags().StringSliceVar(&applyVSchemaOptions.Cells, "cells", nil, "Limits the rebuild to the specified cells, after application. Ignored if --skip-rebuild is set.")
   154  	Root.AddCommand(ApplyVSchema)
   155  
   156  	Root.AddCommand(GetVSchema)
   157  }