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 }