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

     1  // Copyright 2021 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  	"errors"
    18  
    19  	"github.com/pingcap/tiflow/dm/ctl/common"
    20  	"github.com/pingcap/tiflow/dm/pb"
    21  	"github.com/spf13/cobra"
    22  )
    23  
    24  // NewSourceTableSchemaCmd creates a SourceTableSchema command.
    25  func NewSourceTableSchemaCmd() *cobra.Command {
    26  	cmd := &cobra.Command{
    27  		Use:   "binlog-schema <command>",
    28  		Short: "manage or show table schema in schema tracker",
    29  	}
    30  	cmd.AddCommand(
    31  		newSourceTableSchemaUpdateCmd(),
    32  		newSourceTableSchemaDeleteCmd(),
    33  		newSourceTableSchemaListCmd(),
    34  	)
    35  
    36  	return cmd
    37  }
    38  
    39  func newSourceTableSchemaListCmd() *cobra.Command {
    40  	cmd := &cobra.Command{
    41  		Use:   "list <task-name> <database> <table>",
    42  		Short: "show table schema structure",
    43  		RunE: func(cmd *cobra.Command, args []string) error {
    44  			if len(args) < 3 {
    45  				return cmd.Help()
    46  			}
    47  			taskName := common.GetTaskNameFromArgOrFile(args[0])
    48  			sources, err := common.GetSourceArgs(cmd)
    49  			if err != nil {
    50  				return err
    51  			}
    52  			database := args[1]
    53  			table := args[2]
    54  			request := &pb.OperateSchemaRequest{
    55  				Op:         pb.SchemaOp_GetSchema,
    56  				Task:       taskName,
    57  				Sources:    sources,
    58  				Database:   database,
    59  				Table:      table,
    60  				Schema:     "",
    61  				Flush:      false,
    62  				Sync:       false,
    63  				FromSource: false,
    64  				FromTarget: false,
    65  			}
    66  			return sendOperateSchemaRequest(request)
    67  		},
    68  	}
    69  	return cmd
    70  }
    71  
    72  func newSourceTableSchemaUpdateCmd() *cobra.Command {
    73  	cmd := &cobra.Command{
    74  		Use:   "update <task-name> <database> <table> [schema-file]",
    75  		Short: "update tables schema structure",
    76  		RunE: func(cmd *cobra.Command, args []string) error {
    77  			if len(args) < 3 {
    78  				return cmd.Help()
    79  			}
    80  
    81  			var (
    82  				taskName, database, table           string
    83  				sources                             []string
    84  				schemaContent                       []byte
    85  				flush, sync, fromSource, fromTarget bool
    86  				err                                 error
    87  			)
    88  
    89  			fromSource, err = cmd.Flags().GetBool("from-source")
    90  			if err != nil {
    91  				return err
    92  			}
    93  			fromTarget, err = cmd.Flags().GetBool("from-target")
    94  			if err != nil {
    95  				return err
    96  			}
    97  
    98  			if fromSource && fromTarget {
    99  				common.PrintLinesf("from-source and from-target can not be used together")
   100  				return errors.New("please check output to see error")
   101  			}
   102  
   103  			if !fromSource && !fromTarget && len(args) < 4 {
   104  				return cmd.Help()
   105  			}
   106  
   107  			if len(args) == 4 && (fromSource || fromTarget) {
   108  				common.PrintLinesf("can not set schema-file when use from-source or from-target")
   109  				return errors.New("please check output to see error")
   110  			}
   111  
   112  			taskName = common.GetTaskNameFromArgOrFile(args[0])
   113  			sources, err = common.GetSourceArgs(cmd)
   114  			if err != nil {
   115  				return err
   116  			}
   117  			database = args[1]
   118  			table = args[2]
   119  
   120  			if !fromSource && !fromTarget {
   121  				schemaFile := args[3]
   122  				schemaContent, err = common.GetFileContent(schemaFile)
   123  				if err != nil {
   124  					return err
   125  				}
   126  			}
   127  
   128  			flush, err = cmd.Flags().GetBool("flush")
   129  			if err != nil {
   130  				return err
   131  			}
   132  			sync, err = cmd.Flags().GetBool("sync")
   133  			if err != nil {
   134  				return err
   135  			}
   136  			request := &pb.OperateSchemaRequest{
   137  				Op:         pb.SchemaOp_SetSchema,
   138  				Task:       taskName,
   139  				Sources:    sources,
   140  				Database:   database,
   141  				Table:      table,
   142  				Schema:     string(schemaContent),
   143  				Flush:      flush,
   144  				Sync:       sync,
   145  				FromSource: fromSource,
   146  				FromTarget: fromTarget,
   147  			}
   148  			return sendOperateSchemaRequest(request)
   149  		},
   150  	}
   151  	cmd.Flags().Bool("flush", true, "flush the table info and checkpoint immediately")
   152  	cmd.Flags().Bool("sync", true, "sync the table info to master to resolve shard ddl lock, only for optimistic mode now")
   153  	cmd.Flags().Bool("from-source", false, "use the schema from upstream database as the schema of the specified tables")
   154  	cmd.Flags().Bool("from-target", false, "use the schema from downstream database as the schema of the specified tables")
   155  	return cmd
   156  }
   157  
   158  func newSourceTableSchemaDeleteCmd() *cobra.Command {
   159  	cmd := &cobra.Command{
   160  		Use:   "delete <task-name> <database> <table>",
   161  		Short: "delete table schema structure",
   162  		RunE: func(cmd *cobra.Command, args []string) error {
   163  			if len(args) < 3 {
   164  				return cmd.Help()
   165  			}
   166  			taskName := common.GetTaskNameFromArgOrFile(args[0])
   167  			sources, err := common.GetSourceArgs(cmd)
   168  			if err != nil {
   169  				return err
   170  			}
   171  			database := args[1]
   172  			table := args[2]
   173  			request := &pb.OperateSchemaRequest{
   174  				Op:         pb.SchemaOp_RemoveSchema,
   175  				Task:       taskName,
   176  				Sources:    sources,
   177  				Database:   database,
   178  				Table:      table,
   179  				Schema:     "",
   180  				Flush:      false,
   181  				Sync:       false,
   182  				FromSource: false,
   183  				FromTarget: false,
   184  			}
   185  			return sendOperateSchemaRequest(request)
   186  		},
   187  	}
   188  	return cmd
   189  }