blob: 07c0b0532cba25051079c86d0d29afd22ddd5ce8 [file] [log] [blame]
// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package commands
import (
"fmt"
"strings"
"v.io/v23/context"
wire "v.io/v23/services/syncbase"
"v.io/v23/services/watch"
"v.io/v23/syncbase"
"v.io/v23/vdl"
"v.io/x/lib/cmdline"
)
var cmdWatch = &cmdline.Command{
Name: "watch",
Short: "Watch for updates to the database",
Long: "Watch for updates to the database.",
ArgsName: "(<collection_blessing>,<collection_name>[,<row_key>] )*",
ArgsLong: `
If no patterns are specified, watch defaults to watching for updates to any row
of any collection.
`,
Runner: SbRunner(runWatch),
}
func runWatch(ctx *context.T, db syncbase.Database, env *cmdline.Env, args []string) error {
// Get list of patterns to watch for.
var patterns []wire.CollectionRowPattern
if len(args) == 0 {
patterns = []wire.CollectionRowPattern{
wire.CollectionRowPattern{"%", "%", "%"},
}
} else {
patterns = make([]wire.CollectionRowPattern, len(args))
for i, arg := range args {
patterns[i] = parsePattern(arg)
}
}
// Watch for and print out changes.
ws := db.Watch(ctx, watch.ResumeMarker("now"), patterns)
for ws.Advance() {
ch := ws.Change()
switch ch.EntityType {
case syncbase.EntityRow:
fmt.Printf("change on row %s of collection %s:\n", ch.Row, ch.Collection)
switch ch.ChangeType {
case syncbase.PutChange:
var v vdl.Value
if err := ch.Value(&v); err != nil {
fmt.Fprintf(env.Stderr, "\terror reading new value: %v\n", err)
} else {
fmt.Printf("\tnew value: %s\n", v.String())
}
case syncbase.DeleteChange:
fmt.Printf("\trow removed\n")
default:
fmt.Fprintf(env.Stderr, "\tbad change type\n")
}
case syncbase.EntityCollection:
fmt.Printf("change on collection %s:\n", ch.Collection)
switch ch.ChangeType {
case syncbase.PutChange:
fmt.Printf("\tnew info: %v\n", ch.CollectionInfo())
case syncbase.DeleteChange:
fmt.Printf("\tcollection deleted\n")
default:
fmt.Fprintf(env.Stderr, "\tbad change type\n")
}
default:
fmt.Fprintln(env.Stderr, "malformed change detected")
}
}
return ws.Err()
}
func parsePattern(p string) wire.CollectionRowPattern {
fields := strings.SplitN(p, ",", 3)
return wire.CollectionRowPattern{fields[0], fields[1], fields[2]}
}