github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/ctl/master/operate_schema.go (about)

     1  // Copyright 2020 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package master
    15  
    16  import (
    17  	"context"
    18  	"errors"
    19  	"os"
    20  
    21  	"github.com/pingcap/tiflow/dm/ctl/common"
    22  	"github.com/pingcap/tiflow/dm/pb"
    23  	"github.com/spf13/cobra"
    24  )
    25  
    26  // NewOperateSchemaCmd creates a OperateSchema command.
    27  // deprecated, replaced by binlog-schema command.
    28  func NewOperateSchemaCmd() *cobra.Command {
    29  	cmd := &cobra.Command{
    30  		Use:    "operate-schema <operate-type> <-s source ...> <task-name | task-file> <-d database> <-t table> [schema-file] [--flush] [--sync]",
    31  		Short:  "`get`/`set`/`remove` the schema for an upstream table",
    32  		Hidden: true,
    33  		RunE:   operateSchemaCmd,
    34  	}
    35  	cmd.Flags().StringP("database", "d", "", "database name of the table")
    36  	cmd.Flags().StringP("table", "t", "", "table name")
    37  	cmd.Flags().Bool("flush", true, "flush the table info and checkpoint immediately")
    38  	cmd.Flags().Bool("sync", true, "sync the table info to master to resolve shard ddl lock, only for optimistic mode now")
    39  	return cmd
    40  }
    41  
    42  func convertSchemaOpType(t string) pb.SchemaOp {
    43  	switch t {
    44  	case "get":
    45  		return pb.SchemaOp_GetSchema
    46  	case "set":
    47  		return pb.SchemaOp_SetSchema
    48  	case "remove":
    49  		return pb.SchemaOp_RemoveSchema
    50  	default:
    51  		return pb.SchemaOp_InvalidSchemaOp
    52  	}
    53  }
    54  
    55  // operateSchemaCmd does the operate schema request.
    56  func operateSchemaCmd(cmd *cobra.Command, _ []string) error {
    57  	if len(cmd.Flags().Args()) < 2 || len(cmd.Flags().Args()) > 3 {
    58  		cmd.SetOut(os.Stdout)
    59  		common.PrintCmdUsage(cmd)
    60  		return errors.New("please check output to see error")
    61  	}
    62  
    63  	opType := cmd.Flags().Arg(0)
    64  	taskName := common.GetTaskNameFromArgOrFile(cmd.Flags().Arg(1))
    65  	schemaFile := cmd.Flags().Arg(2)
    66  	var err error
    67  	var schemaContent []byte
    68  	op := convertSchemaOpType(opType)
    69  	switch op {
    70  	case pb.SchemaOp_InvalidSchemaOp:
    71  		common.PrintLinesf("invalid operate '%s' on schema", opType)
    72  		return errors.New("please check output to see error")
    73  	case pb.SchemaOp_SetSchema:
    74  		if schemaFile == "" {
    75  			common.PrintLinesf("must sepcify schema file for 'set' operation")
    76  			return errors.New("please check output to see error")
    77  		}
    78  		schemaContent, err = common.GetFileContent(schemaFile)
    79  		if err != nil {
    80  			return err
    81  		}
    82  	default:
    83  		if schemaFile != "" {
    84  			common.PrintLinesf("schema file will be ignored for 'get'/'delete' operation")
    85  		}
    86  	}
    87  
    88  	sources, err := common.GetSourceArgs(cmd)
    89  	if err != nil {
    90  		return err
    91  	} else if len(sources) == 0 {
    92  		common.PrintLinesf("must specify at least one source (`-s` / `--source`)")
    93  		return errors.New("please check output to see error")
    94  	}
    95  	database, err := cmd.Flags().GetString("database")
    96  	if err != nil {
    97  		return err
    98  	} else if database == "" {
    99  		common.PrintLinesf("must specify 'database'")
   100  		return errors.New("please check output to see error")
   101  	}
   102  	table, err := cmd.Flags().GetString("table")
   103  	if err != nil {
   104  		return err
   105  	} else if table == "" {
   106  		common.PrintLinesf("must specify 'table'")
   107  		return errors.New("please check output to see error")
   108  	}
   109  
   110  	flush, err := cmd.Flags().GetBool("flush")
   111  	if err != nil {
   112  		return err
   113  	}
   114  	sync, err := cmd.Flags().GetBool("sync")
   115  	if err != nil {
   116  		return err
   117  	}
   118  	request := &pb.OperateSchemaRequest{
   119  		Op:         op,
   120  		Task:       taskName,
   121  		Sources:    sources,
   122  		Database:   database,
   123  		Table:      table,
   124  		Schema:     string(schemaContent),
   125  		Flush:      flush,
   126  		Sync:       sync,
   127  		FromSource: false,
   128  		FromTarget: false,
   129  	}
   130  	return sendOperateSchemaRequest(request)
   131  }
   132  
   133  func sendOperateSchemaRequest(request *pb.OperateSchemaRequest) error {
   134  	ctx, cancel := context.WithCancel(context.Background())
   135  	defer cancel()
   136  
   137  	resp := &pb.OperateSchemaResponse{}
   138  	err := common.SendRequest(
   139  		ctx,
   140  		"OperateSchema",
   141  		request,
   142  		&resp,
   143  	)
   144  	if err != nil {
   145  		return err
   146  	}
   147  	common.PrettyPrintResponse(resp)
   148  	return nil
   149  }