xref: /plan9/sys/src/cmd/ndb/query.c (revision dfda52d80255562ef033681626b3a6450d80329d)
1 /*
2  *  search the network database for matches
3  */
4 #include <u.h>
5 #include <libc.h>
6 #include <bio.h>
7 #include <ndb.h>
8 
9 static int all, multiple;
10 static Biobuf bout;
11 
12 void
usage(void)13 usage(void)
14 {
15 	fprint(2, "usage: query [-am] [-f ndbfile] attr value "
16 		"[returned-attr [reps]]\n");
17 	exits("usage");
18 }
19 
20 /* print values of nt's attributes matching rattr */
21 static void
prmatch(Ndbtuple * nt,char * rattr)22 prmatch(Ndbtuple *nt, char *rattr)
23 {
24 	for(; nt; nt = nt->entry)
25 		if (strcmp(nt->attr, rattr) == 0)
26 			Bprint(&bout, "%s\n", nt->val);
27 }
28 
29 void
search(Ndb * db,char * attr,char * val,char * rattr)30 search(Ndb *db, char *attr, char *val, char *rattr)
31 {
32 	char *p;
33 	Ndbs s;
34 	Ndbtuple *t, *nt;
35 
36 	/* first entry with a matching rattr */
37 	if(rattr && !all){
38 		p = ndbgetvalue(db, &s, attr, val, rattr, &t);
39 		if (multiple)
40 			prmatch(t, rattr);
41 		else if(p)
42 			Bprint(&bout, "%s\n", p);
43 		ndbfree(t);
44 		free(p);
45 		return;
46 	}
47 
48 	/* all entries with matching rattrs */
49 	if(rattr) {
50 		for(t = ndbsearch(db, &s, attr, val); t != nil;
51 		    t = ndbsnext(&s, attr, val)){
52 			prmatch(t, rattr);
53 			ndbfree(t);
54 		}
55 		return;
56 	}
57 
58 	/* all entries */
59 	for(t = ndbsearch(db, &s, attr, val); t; t = ndbsnext(&s, attr, val)){
60 		for(nt = t; nt; nt = nt->entry)
61 			Bprint(&bout, "%s=%s ", nt->attr, nt->val);
62 		Bprint(&bout, "\n");
63 		ndbfree(t);
64 	}
65 }
66 
67 void
main(int argc,char ** argv)68 main(int argc, char **argv)
69 {
70 	int reps = 1;
71 	char *rattr = nil, *dbfile = nil;
72 	Ndb *db;
73 
74 	ARGBEGIN{
75 	case 'a':
76 		all++;
77 		break;
78 	case 'm':
79 		multiple++;
80 		break;
81 	case 'f':
82 		dbfile = EARGF(usage());
83 		break;
84 	default:
85 		usage();
86 	}ARGEND;
87 
88 	switch(argc){
89 	case 4:
90 		reps = atoi(argv[3]);	/* wtf use is this? */
91 		/* fall through */
92 	case 3:
93 		rattr = argv[2];
94 		break;
95 	case 2:
96 		rattr = nil;
97 		break;
98 	default:
99 		usage();
100 	}
101 
102 	if(Binit(&bout, 1, OWRITE) == -1)
103 		sysfatal("Binit: %r");
104 	db = ndbopen(dbfile);
105 	if(db == nil){
106 		fprint(2, "%s: no db files\n", argv0);
107 		exits("no db");
108 	}
109 	while(reps--)
110 		search(db, argv[0], argv[1], rattr);
111 	ndbclose(db);
112 
113 	exits(0);
114 }
115