plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

commit 82f6feeb9cbe041f52f369f323189f7b6c8d0049
parent f6445e59a70e9378fe5f08052302d12928cfa8d0
Author: ssnf <ssnf@ssnf.xyz>
Date:   Fri, 11 Jul 2025 01:22:00 +0000

add libsdbr manpage

Diffstat:
Mman/man3/INDEX | 18++++++++++++++++++
Aman/man3/sdbr.3 | 325+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 343 insertions(+), 0 deletions(-)

diff --git a/man/man3/INDEX b/man/man3/INDEX @@ -1171,6 +1171,24 @@ s_restart string.3 s_terminate string.3 s_tolower string.3 s_unique string.3 +sdbr_add sdbr.3 +sdbr_arg2r sdbr.3 +sdbr_attr sdbr.3 +sdbr_close sdbr.3 +sdbr_dup sdbr.3 +sdbr_edit sdbr.3 +sdbr_edit2 sdbr.3 +sdbr_escape sdbr.3 +sdbr_init sdbr.3 +sdbr_match sdbr.3 +sdbr_n sdbr.3 +sdbr_print sdbr.3 +sdbr_query sdbr.3 +sdbr_str2r sdbr.3 +sdbr_val sdbr.3 +sdbr_zero sdbr.3 +vsdbr_join sdbr.3 +sdbr sdbr.3 Str str.3 Strn str.3 Straddc str.3 diff --git a/man/man3/sdbr.3 b/man/man3/sdbr.3 @@ -0,0 +1,325 @@ +.TH SDBR 3 +.SH NAME +sdbr_add, sdbr_arg2r, sdbr_attr, sdbr_close, sdbr_dup, sdbr_edit, sdbr_edit2, sdbr_escape, sdbr_init, sdbr_match, sdbr_n, sdbr_print, sdbr_query, sdbr_str2r, sdbr_val, sdbr_zero, vsdbr_join \- simple database records +.SH SYNOPSIS +.B #include <u.h> +.br +.B #include <libc.h> +.br +.B #include <str.h> +.br +.B #include <vec.h> +.br +.B #include <sdbr.h> +.PP +.ft L +.nf +.ta \w'\fL 'u +\w'\fLString 'u +typedef struct { + String *attr; + String *val; +} Sdbr; +.fi +.PP +.ta \w'\fLvoid 'u +.B +void sdbr_add(Sdbr *r, String attr, String val) +.PP +.B +void sdbr_arg2r(Sdbr *r, char *argv[]) +.PP +.B +int sdbr_attr(Sdbr r, char *attr) +.PP +.B +void sdbr_close(Sdbr *r) +.PP +.B +void sdbr_dup(Sdbr *sr, Sdbr r) +.PP +.B +void sdbr_edit(Sdbr *sr, Sdbr r) +.PP +.B +void sdbr_edit2(Sdbr *r, String attr, String val) +.PP +.B +char* sdbr_escape(String *s, String val) +.PP +.B +void sdbr_init(Sdbr *r) +.PP +.B +char sdbr_match(char *k, char *v) +.PP +.B +ulong sdbr_n(Sdbr r) +.PP +.B +void sdbr_print(Sdbr r) +.PP +.B +int sdbr_query(Sdbr r, Sdbr q) +.PP +.B +void sdbr_str2r(Sdbr *sr, String s) +.PP +.B +String sdbr_val(Sdbr r, char *attr) +.PP +.B +void sdbr_zero(Sdbr *r) +.PP +.B +void vsdbr_join(Sdbr *v[], Sdbr r) +.SH DESCRIPTION +These functions provide a simple database record system for storing and querying +attribute-value pairs using the same format as Plan 9's network database (ndb). +An +.B Sdbr +record contains vectors of attribute names and their corresponding values, +both stored as dynamic strings. +While ndb is designed specifically for network configuration, +sdb records can be used for any general-purpose attribute-value data. +.PP +.I Sdbr_init +initializes a record +.IR r . +The record is initially empty. +.PP +.I Sdbr_close +frees all memory associated with record +.IR r . +.PP +.I Sdbr_add +adds an attribute-value pair to record +.IR r . +The attribute name is +.I attr +and its value is +.IR val . +.PP +.I Sdbr_n +returns the number of attribute-value pairs in record +.IR r . +.PP +.I Sdbr_zero +removes all attribute-value pairs from record +.I r +but keeps the record structure intact for reuse. +.PP +.I Sdbr_dup +copies all attribute-value pairs from record +.I src +to record +.IR dst . +.PP +.I Sdbr_str2r +parses a string +.I s +containing space-separated attribute=value pairs and adds them to record +.IR r . +Values containing spaces can be quoted with double quotes. +Escape sequences \e0, \et, \en, \e", and \e\e are supported within quoted values. +.PP +.I Sdbr_arg2r +parses command-line arguments +.I argv +(null-terminated array) as alternating attribute-value pairs and adds them to record +.IR r . +Arguments are processed in pairs where argv[0] is the attribute and argv[1] is the value. +.PP +.I Sdbr_val +returns the value of attribute +.I attr +in record +.IR r . +If the attribute is not found, it returns an empty string. +The attribute name can contain glob patterns. +.PP +.I Sdbr_attr +returns the index of attribute +.I attr +in record +.IR r , +or -1 if not found. +.PP +.I Sdbr_match +tests whether +.I value +matches +.IR pattern . +The pattern supports glob-style wildcards (*) and comparison operators +(>, >=, <, <=). +These operators perform lexicographic string comparison, not numeric. +Literal asterisks can be escaped with backslash. +.PP +.I Sdbr_query +tests whether record +.I r +matches all conditions specified in query record +.IR query . +It returns 1 if the record matches, 0 otherwise. +Attribute names in the query starting with '!' are negated conditions. +.PP +.I Sdbr_edit +applies edits from record +.I r +to record +.IR sr . +For each attribute in +.IR r , +the corresponding value in +.I sr +is updated or added. +.PP +.I Sdbr_edit2 +updates or adds a single attribute-value pair in record +.IR r . +.PP +.I Sdbr_escape +formats string +.I val +for output, escaping special characters and storing the result in string +.IR s . +It returns a pointer to the formatted string. +.PP +.I Sdbr_print +prints record +.I r +to standard output in attribute=value format. +.PP +.I Vsdbr_join +appends record +.I r +to the vector of records +.IR v . +.SH EXAMPLES +.PP +Basic record operations: +.IP +.EX +Sdbr r; + +sdbr_init(&r); +sdbr_add(&r, Str("name"), Str("John")); +sdbr_add(&r, Str("age"), Str("30")); +sdbr_print(r); +sdbr_close(&r); +.EE +.PP +Parsing from string: +.IP +.EX +Sdbr r; +String s; + +sdbr_init(&r); +s = Str("name=John age=30 city=\\"New York\\""); +sdbr_str2r(&r, s); +print("Name: %s\en", sdbr_val(r, "name").s); +sdbr_close(&r); +.EE +.PP +Querying records: +.IP +.EX +Sdbr r, q; + +sdbr_init(&r); +sdbr_init(&q); +sdbr_add(&r, Str("type"), Str("user")); +sdbr_add(&r, Str("status"), Str("active")); +sdbr_add(&q, Str("type"), Str("user")); +sdbr_add(&q, Str("!status"), Str("inactive")); +if(sdbr_query(r, q)) + print("Record matches query\en"); +sdbr_close(&r); +sdbr_close(&q); +.EE +.PP +Pattern matching: +.IP +.EX +if(sdbr_match("*user*", "admin_user")) + print("Pattern matches\en"); +if(sdbr_match(">=100", "150")) + print("Comparison matches\en"); +.EE +.PP +Process tracking: +.IP +.EX +Sdbr r; + +sdbr_init(&r); +sdbr_str2r(&r, "pid=1234 cmd=rc user=glenda cpu=0.5"); +sdbr_add(&r, Str("tags"), Str("shell,interactive")); +sdbr_add(&r, Str("started"), Str("2025-01-15T10:30:00")); +sdbr_print(r); +sdbr_close(&r); +.EE +.PP +Configuration with inheritance: +.IP +.EX +Sdbr def, usr; + +sdbr_init(&def); +sdbr_init(&usr); +sdbr_str2r(&def, "editor=sam theme=light font=lucsans"); +sdbr_str2r(&usr, "theme=dark font=go"); +sdbr_edit(&def, usr); +print("Font: %s\en", sdbr_val(def, "font").s); +sdbr_close(&def); +sdbr_close(&usr); +.EE +.PP +Date range queries: +.IP +.EX +Sdbr ev, q; + +sdbr_init(&ev); +sdbr_init(&q); +sdbr_str2r(&ev, "timestamp=2025-01-15T14:30:00 level=error"); +sdbr_str2r(&q, + "timestamp=>=2025-01-15T14:00:00 " + "timestamp=<=2025-01-15T15:00:00"); +if(sdbr_query(ev, q)) + print("Event in time range\en"); +sdbr_close(&ev); +sdbr_close(&q); +.EE +.PP +Geographic range queries: +.IP +.EX +Sdbr loc, q; + +sdbr_init(&loc); +sdbr_init(&q); +sdbr_str2r(&loc, "lat=40.7128 lon=-74.0060 city=\"New York\""); +sdbr_str2r(&q, + "lat=>=40.0 lat=<=41.0 " + "lon=>=-73.0 lon=<=-75.0"); +if(sdbr_query(loc, q)) + print("Location in bounding box\en"); +sdbr_close(&loc); +sdbr_close(&q); +.EE +.SH SOURCE +.B \*9/src/libsdbr +.SH SEE ALSO +.MR ndb (3) , +.MR ndb (7) , +.MR sdb (1) , +.MR sdb (3) , +.MR str (3) , +.MR vec (3) +.SH DIAGNOSTICS +Functions call +.I sysfatal +if memory allocation fails. +.SH BUGS +None.