github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/store/cmd/noms/noms_manifest.go (about)

     1  // Copyright 2019 Dolthub, 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  // 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 main
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"math/big"
    21  	"os"
    22  	"path/filepath"
    23  	"sort"
    24  
    25  	"github.com/dustin/go-humanize"
    26  	flag "github.com/juju/gnuflag"
    27  
    28  	"github.com/dolthub/dolt/go/store/cmd/noms/util"
    29  	"github.com/dolthub/dolt/go/store/d"
    30  	"github.com/dolthub/dolt/go/store/nbs"
    31  	"github.com/dolthub/dolt/go/store/spec"
    32  )
    33  
    34  var nomsManifest = &util.Command{
    35  	Run:       runManifest,
    36  	UsageLine: "manifest <db-spec>",
    37  	Short:     "Get or set the current root hash of the entire database",
    38  	Long:      "See Spelling Objects at https://github.com/attic-labs/noms/blob/master/doc/spelling.md for details on the database argument.",
    39  	Flags:     setupManifestFlags,
    40  	Nargs:     1,
    41  }
    42  
    43  type NbsFile struct {
    44  	manifestSpec nbs.TableSpecInfo
    45  	fileInfo     os.FileInfo
    46  	fileInfoErr  error
    47  }
    48  
    49  func (f NbsFile) sizeStr() string {
    50  	if f.fileInfoErr == nil {
    51  		bi := big.Int{}
    52  		bi.SetInt64(f.fileInfo.Size())
    53  		return humanize.BigBytes(&bi)
    54  	}
    55  
    56  	return "-"
    57  }
    58  
    59  func (f NbsFile) modTimeStr() string {
    60  	if f.fileInfoErr == nil {
    61  		return f.fileInfo.ModTime().String()[:22]
    62  	}
    63  
    64  	return "-"
    65  }
    66  
    67  func setupManifestFlags() *flag.FlagSet {
    68  	flagSet := flag.NewFlagSet("manifest", flag.ExitOnError)
    69  	return flagSet
    70  }
    71  
    72  func runManifest(ctx context.Context, args []string) int {
    73  	if len(args) < 1 {
    74  		fmt.Fprintln(os.Stderr, "Not enough arguments")
    75  		return 0
    76  	}
    77  
    78  	dbArg := args[0]
    79  	spec, err := spec.ForDatabase(dbArg)
    80  
    81  	if err != nil {
    82  		fmt.Fprintln(os.Stderr, args[0]+" is not a valid database spec")
    83  		return 1
    84  	}
    85  
    86  	if spec.Protocol != "nbs" {
    87  		fmt.Fprintln(os.Stderr, spec.Protocol+" databases not supported by this command yet.  Only nbs")
    88  		return 1
    89  	}
    90  
    91  	manifestFile := filepath.Join(spec.DatabaseName, "manifest")
    92  	manifestReader, err := os.Open(manifestFile)
    93  
    94  	if err != nil {
    95  		fmt.Fprintln(os.Stderr, "Could not read file", manifestFile, err)
    96  		return 1
    97  	}
    98  
    99  	var manifest nbs.ManifestInfo
   100  	manifest, err = nbs.ParseManifest(manifestReader)
   101  	d.PanicIfError(err)
   102  
   103  	numSpecs := manifest.NumTableSpecs()
   104  	nbsFiles := make([]NbsFile, numSpecs)
   105  	for i := 0; i < numSpecs; i++ {
   106  		tableSpecInfo := manifest.GetTableSpecInfo(i)
   107  		path := filepath.Join(spec.DatabaseName, tableSpecInfo.GetName())
   108  		fileInfo, err := os.Stat(path)
   109  		nbsFiles[i] = NbsFile{tableSpecInfo, fileInfo, err}
   110  	}
   111  
   112  	// Sort these by time stamp makes it much easier to see what happens over time and understand
   113  	// what is going on as you run different operations.
   114  	sort.SliceStable(nbsFiles, func(i, j int) bool {
   115  		f1Stat, err1 := nbsFiles[i].fileInfo, nbsFiles[i].fileInfoErr
   116  		f2Stat, err2 := nbsFiles[j].fileInfo, nbsFiles[j].fileInfoErr
   117  
   118  		if err1 != nil {
   119  			return true
   120  		} else if err2 != nil {
   121  			return false
   122  		}
   123  
   124  		return f1Stat.ModTime().Sub(f2Stat.ModTime()) < 0
   125  	})
   126  
   127  	fmt.Println(manifestFile + ":")
   128  	fmt.Printf("    version: %s\n", manifest.GetVersion())
   129  	fmt.Printf("    lock:    %s\n", manifest.GetLock())
   130  	fmt.Printf("    root:    %s\n", manifest.GetRoot())
   131  	fmt.Println("    referenced nbs files:")
   132  
   133  	for _, nbsFile := range nbsFiles {
   134  		name := nbsFile.manifestSpec.GetName()
   135  		chunkCnt := nbsFile.manifestSpec.GetChunkCount()
   136  		sizeStr := nbsFile.sizeStr()
   137  		existsStr := nbsFile.fileInfoErr == nil
   138  		modTimeStr := nbsFile.modTimeStr()
   139  		fmt.Printf("        %s  chunks: %2d  exists: %-6t  size: %7s  modified: %10s\n", name, chunkCnt, existsStr, sizeStr, modTimeStr)
   140  	}
   141  
   142  	return 0
   143  }