github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/rpc/inspect.go (about) 1 // Copyright 2021 - 2022 Matrix Origin 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 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package rpc 16 17 import ( 18 "fmt" 19 "io" 20 "os" 21 22 "github.com/matrixorigin/matrixone/pkg/common/moerr" 23 "github.com/matrixorigin/matrixone/pkg/container/types" 24 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/catalog" 25 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common" 26 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/db" 27 "github.com/spf13/cobra" 28 ) 29 30 type inspectContext struct { 31 db *db.DB 32 acinfo *db.AccessInfo 33 args []string 34 out io.Writer 35 resp *db.InspectResp 36 } 37 38 // impl Pflag.Value interface 39 func (i *inspectContext) String() string { return "" } 40 func (i *inspectContext) Set(string) error { return nil } 41 func (i *inspectContext) Type() string { return "ictx" } 42 43 type catalogArg struct { 44 ctx *inspectContext 45 outfile *os.File 46 verbose common.PPLevel 47 } 48 49 func (c *catalogArg) fromCommand(cmd *cobra.Command) error { 50 c.ctx = cmd.Flag("ictx").Value.(*inspectContext) 51 count, _ := cmd.Flags().GetCount("verbose") 52 var lv common.PPLevel 53 switch count { 54 case 0: 55 lv = common.PPL0 56 case 1: 57 lv = common.PPL1 58 case 2: 59 lv = common.PPL2 60 case 3: 61 lv = common.PPL3 62 } 63 c.verbose = lv 64 65 file, _ := cmd.Parent().PersistentFlags().GetString("outfile") 66 if file != "" { 67 if f, err := os.Create(file); err != nil { 68 cmd.OutOrStdout().Write([]byte(fmt.Sprintf("open %s err: %v", file, err))) 69 return err 70 } else { 71 c.outfile = f 72 } 73 } 74 return nil 75 } 76 77 func runCatalog(arg *catalogArg, respWriter io.Writer) { 78 if arg.outfile != nil { 79 ret := arg.ctx.db.Catalog.SimplePPString(arg.verbose) 80 arg.outfile.WriteString(ret) 81 defer arg.outfile.Close() 82 respWriter.Write([]byte("write file done")) 83 } else { 84 visitor := newCatalogRespVisitor(arg.verbose) 85 arg.ctx.db.Catalog.RecurLoop(visitor) 86 87 ret, _ := types.Encode(visitor.GetResponse()) 88 arg.ctx.resp.Payload = ret 89 arg.ctx.resp.Typ = db.InspectCata 90 } 91 } 92 93 func initCommand(ctx *inspectContext) *cobra.Command { 94 rootCmd := &cobra.Command{ 95 Use: "inspect", 96 } 97 98 catalogCmd := &cobra.Command{ 99 Use: "catalog", 100 Short: "show catalog", 101 Run: func(cmd *cobra.Command, args []string) { 102 arg := &catalogArg{} 103 if err := arg.fromCommand(cmd); err != nil { 104 return 105 } 106 runCatalog(arg, cmd.OutOrStdout()) 107 }, 108 } 109 110 rootCmd.PersistentFlags().VarPF(ctx, "ictx", "", "").Hidden = true 111 112 rootCmd.SetArgs(ctx.args) 113 rootCmd.SetErr(ctx.out) 114 rootCmd.SetOut(ctx.out) 115 116 catalogCmd.Flags().CountP("verbose", "v", "verbose level") 117 catalogCmd.Flags().StringP("outfile", "o", "", "write output to a file") 118 rootCmd.AddCommand(catalogCmd) 119 return rootCmd 120 } 121 122 func RunInspect(ctx *inspectContext) { 123 rootCmd := initCommand(ctx) 124 rootCmd.Execute() 125 } 126 127 type catalogRespVisitor struct { 128 catalog.LoopProcessor 129 level common.PPLevel 130 stack []*db.CatalogResp 131 } 132 133 func newCatalogRespVisitor(lv common.PPLevel) *catalogRespVisitor { 134 return &catalogRespVisitor{ 135 level: lv, 136 stack: []*db.CatalogResp{{Item: "Catalog"}}, 137 } 138 } 139 140 func (c *catalogRespVisitor) GetResponse() *db.CatalogResp { 141 return c.stack[0] 142 } 143 144 func entryLevelString[T interface { 145 StringWithLevel(common.PPLevel) string 146 }](entry T, lv common.PPLevel) *db.CatalogResp { 147 return &db.CatalogResp{Item: entry.StringWithLevel(lv)} 148 } 149 150 func (c *catalogRespVisitor) onstack(idx int, resp *db.CatalogResp) { 151 c.stack = c.stack[:idx+1] 152 c.stack[idx].Sub = append(c.stack[idx].Sub, resp) 153 c.stack = append(c.stack, resp) 154 } 155 156 func (c *catalogRespVisitor) OnDatabase(database *catalog.DBEntry) error { 157 c.onstack(0, entryLevelString(database, c.level)) 158 return nil 159 } 160 161 func (c *catalogRespVisitor) OnTable(table *catalog.TableEntry) error { 162 if c.level == common.PPL0 { 163 return moerr.GetOkStopCurrRecur() 164 } 165 c.onstack(1, entryLevelString(table, c.level)) 166 return nil 167 } 168 169 func (c *catalogRespVisitor) OnSegment(seg *catalog.SegmentEntry) error { 170 if c.level == common.PPL0 { 171 return moerr.GetOkStopCurrRecur() 172 } 173 c.onstack(2, entryLevelString(seg, c.level)) 174 return nil 175 } 176 177 func (c *catalogRespVisitor) OnBlock(blk *catalog.BlockEntry) error { 178 if c.level == common.PPL0 { 179 return moerr.GetOkStopCurrRecur() 180 } 181 c.onstack(3, entryLevelString(blk, c.level)) 182 return nil 183 }