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  }