diff options
Diffstat (limited to 'appl/cmd/ndb/query.b')
| -rw-r--r-- | appl/cmd/ndb/query.b | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/appl/cmd/ndb/query.b b/appl/cmd/ndb/query.b new file mode 100644 index 00000000..b636492d --- /dev/null +++ b/appl/cmd/ndb/query.b @@ -0,0 +1,135 @@ +implement Query; + +include "sys.m"; + sys: Sys; + +include "draw.m"; + +include "bufio.m"; + +include "attrdb.m"; + attrdb: Attrdb; + Attr, Tuples, Dbentry, Db: import attrdb; + +include "arg.m"; + +Query: module +{ + init: fn(nil: ref Draw->Context, nil: list of string); +}; + +usage() +{ + sys->fprint(sys->fildes(2), "usage: query attr [value [rattr]]\n"); + raise "fail:usage"; +} + +init(nil: ref Draw->Context, args: list of string) +{ + sys = load Sys Sys->PATH; + + dbfile := "/lib/ndb/local"; + arg := load Arg Arg->PATH; + if(arg == nil) + badload(Arg->PATH); + arg->init(args); + arg->setusage("query [-a] [-f dbfile] attr [value [rattr]]"); + all := 0; + while((o := arg->opt()) != 0) + case o { + 'f' => dbfile = arg->earg(); + 'a' => all = 1; + * => arg->usage(); + } + args = arg->argv(); + if(args == nil) + arg->usage(); + attr := hd args; + args = tl args; + value, rattr: string; + vflag := 0; + if(args != nil){ + vflag = 1; + value = hd args; + args = tl args; + if(args != nil) + rattr = hd args; + } + arg = nil; + + attrdb = load Attrdb Attrdb->PATH; + if(attrdb == nil) + badload(Attrdb->PATH); + err := attrdb->init(); + if(err != nil) + error(sys->sprint("can't init Attrdb: %s", err)); + + db := Db.open(dbfile); + if(db == nil) + error(sys->sprint("can't open %s: %r", dbfile)); + ptr: ref Attrdb->Dbptr; + for(;;){ + e: ref Dbentry; + if(rattr != nil) + (e, ptr) = db.findbyattr(ptr, attr, value, rattr); + else if(vflag) + (e, ptr) = db.findpair(ptr, attr, value); + else + (e, ptr) = db.find(ptr, attr); + if(e == nil) + break; + if(rattr != nil){ + matches: list of (ref Tuples, list of ref Attr); + if(rattr != nil) + matches = e.findbyattr(attr, value, rattr); + else + matches = e.find(attr); + for(; matches != nil; matches = tl matches){ + (line, attrs) := hd matches; + if(attrs != nil) + printvals(attrs, all); + if(!all) + exit; + } + }else + printentry(e); + if(!all) + exit; + } +} + +badload(s: string) +{ + error(sys->sprint("can't load %s: %r", s)); +} + +error(s: string) +{ + sys->fprint(sys->fildes(2), "query: %s\n", s); + raise "fail:error"; +} + +printentry(e: ref Dbentry) +{ + s := ""; + for(lines := e.lines; lines != nil; lines = tl lines){ + line := hd lines; + for(al := line.pairs; al != nil; al = tl al){ + a := hd al; + s += sys->sprint(" %q=%q", a.attr, a.val); + } + } + if(s != "") + s = s[1:]; + sys->print("%s\n", s); +} + +printvals(al: list of ref Attr, all: int) +{ + for(; al != nil; al = tl al){ + a := hd al; + sys->print("%q\n", a.val); + if(!all) + break; + } +} |
