code: 9ferno

ref: e57fd0cf983e4eddd433d83eb0b216e3cb069ac4
dir: /appl/cmd/ndb/query.b/

View raw version
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;
	}
}