plan9port

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

sdb.3 (5388B)


      1 .TH SDB 3
      2 .SH NAME
      3 sdb_add, sdb_Bopen, sdb_close, sdb_edit, sdb_flush, sdb_n, sdb_next, sdb_open, sdb_openf, sdb_query, sdb_remove, sdb_rewind \- simple database
      4 .SH SYNOPSIS
      5 .B #include <u.h>
      6 .br
      7 .B #include <libc.h>
      8 .br
      9 .B #include <bio.h>
     10 .br
     11 .B #include <str.h>
     12 .br
     13 .B #include <vec.h>
     14 .br
     15 .B #include <sdbr.h>
     16 .br
     17 .B #include <sdb.h>
     18 .PP
     19 .ft L
     20 .nf
     21 .ta \w'\fL    'u +\w'\fLString 'u
     22 typedef struct {
     23         String  ln;
     24         Sdbr    *r;
     25         Biobuf  *b;
     26         ulong   n;
     27 } Sdb;
     28 .fi
     29 .PP
     30 .ta \w'\fLvoid 'u
     31 .B
     32 void    sdb_add(Sdb *db, Sdbr r)
     33 .PP
     34 .B
     35 void    sdb_Bopen(Sdb *db, Biobuf *b)
     36 .PP
     37 .B
     38 void    sdb_close(Sdb *db)
     39 .PP
     40 .B
     41 void    sdb_edit(Sdb *db, Sdbr q, Sdbr r)
     42 .PP
     43 .B
     44 void    sdb_flush(Sdb *db)
     45 .PP
     46 .B
     47 ulong   sdb_n(Sdb db)
     48 .PP
     49 .B
     50 int     sdb_next(Sdb *db)
     51 .PP
     52 .B
     53 void    sdb_open(Sdb *db, char *file)
     54 .PP
     55 .B
     56 void    sdb_openf(Sdb *db, char *fmt, ...)
     57 .PP
     58 .B
     59 int     sdb_query(Sdb *db, Sdbr q)
     60 .PP
     61 .B
     62 void    sdb_remove(Sdb *db)
     63 .PP
     64 .B
     65 void    sdb_rewind(Sdb *db)
     66 .SH DESCRIPTION
     67 These functions provide a simple database system for storing and querying
     68 collections of records using the same format as Plan 9's network database (ndb).
     69 An
     70 .B Sdb
     71 database contains a vector of
     72 .B Sdbr
     73 records, a current line buffer, a 
     74 .B Biobuf
     75 for I/O, and a current record position.
     76 While ndb supports importing multiple database files,
     77 sdb operates on a single file or input stream.
     78 .PP
     79 .I Sdb_open
     80 opens a database file
     81 .I file
     82 for reading.
     83 If
     84 .I file
     85 is nil or empty, it reads from standard input.
     86 .PP
     87 .I Sdb_openf
     88 opens a database file using a formatted filename created with
     89 .I fmt
     90 and additional arguments.
     91 .PP
     92 .I Sdb_Bopen
     93 initializes a database using an existing
     94 .I Biobuf
     95 .IR b .
     96 .PP
     97 .I Sdb_close
     98 closes the database and frees all associated resources.
     99 .PP
    100 .I Sdb_n
    101 returns the number of records currently loaded in the database.
    102 .PP
    103 .I Sdb_next
    104 advances to the next record in the database.
    105 If records are already loaded, it moves to the next loaded record.
    106 Otherwise, it reads the next record from the input.
    107 It returns the record number starting from 1, or 0 if no more records.
    108 Records are parsed from the input where each record consists of
    109 attribute=value pairs separated by whitespace.
    110 Multi-line records are supported with continuation lines starting with whitespace.
    111 Comments starting with '#' are ignored.
    112 .PP
    113 .I Sdb_rewind
    114 resets the current record position to the beginning of the loaded records.
    115 .PP
    116 .I Sdb_add
    117 adds record
    118 .I r
    119 to the database and sets the current position to the newly added record.
    120 .PP
    121 .I Sdb_query
    122 searches the database for records matching query
    123 .IR q .
    124 It returns 1 if a matching record is found and sets the current position to that record,
    125 or 0 if no match is found.
    126 The search starts from the current position and continues through all records,
    127 loading new records from input as needed.
    128 .PP
    129 .I Sdb_edit
    130 finds all records matching query
    131 .I q
    132 and applies edits from record
    133 .I r
    134 to each matching record.
    135 If no matching record is found, it adds query
    136 .I q
    137 as a new record.
    138 .PP
    139 .I Sdb_remove
    140 removes the current record from the database.
    141 .PP
    142 .I Sdb_flush
    143 reads all remaining records from the input and prints all records
    144 in the database to standard output.
    145 .SH EXAMPLES
    146 .PP
    147 Reading and querying a database:
    148 .IP
    149 .EX
    150 Sdb db;
    151 Sdbr q;
    152 
    153 sdb_open(&db, "users.db");
    154 sdbr_init(&q);
    155 sdbr_add(&q, Str("type"), Str("admin"));
    156 if(sdb_query(&db, q))
    157     sdbr_print(db.r[db.n]);
    158 sdbr_close(&q);
    159 sdb_close(&db);
    160 .EE
    161 .PP
    162 Adding records to a database:
    163 .IP
    164 .EX
    165 Sdb db;
    166 Sdbr r;
    167 
    168 sdb_open(&db, "");
    169 sdbr_init(&r);
    170 sdbr_add(&r, Str("name"), Str("Alice"));
    171 sdbr_add(&r, Str("role"), Str("user"));
    172 sdb_add(&db, r);
    173 sdb_flush(&db);
    174 sdbr_close(&r);
    175 sdb_close(&db);
    176 .EE
    177 .PP
    178 Iterating through all records:
    179 .IP
    180 .EX
    181 Sdb db;
    182 
    183 sdb_open(&db, "data.db");
    184 while(sdb_next(&db))
    185     sdbr_print(db.r[db.n]);
    186 sdb_close(&db);
    187 .EE
    188 .PP
    189 Editing records:
    190 .IP
    191 .EX
    192 Sdb db;
    193 Sdbr q, r;
    194 
    195 sdb_open(&db, "users.db");
    196 sdbr_init(&q);
    197 sdbr_init(&r);
    198 sdbr_add(&q, Str("name"), Str("Bob"));
    199 sdbr_add(&r, Str("status"), Str("active"));
    200 sdb_edit(&db, q, r);
    201 sdb_flush(&db);
    202 sdbr_close(&q);
    203 sdbr_close(&r);
    204 sdb_close(&db);
    205 .EE
    206 .PP
    207 Log analysis with range queries:
    208 .IP
    209 .EX
    210 Sdb db;
    211 Sdbr q;
    212 String s;
    213 
    214 sdb_open(&db, "access.log");
    215 sdbr_init(&q);
    216 sdbr_str2r(&q, Str("level=error "
    217                    "timestamp=>=2024-01-15T14:00:00"));
    218 while(sdb_query(&db, q)) {
    219         s = sdbr_val(db.r[db.n], "component");
    220         if(sdbr_match("*auth*", s.s))
    221                 print("AUTH ERROR: %s\en", 
    222                       sdbr_val(db.r[db.n], "message").s);
    223         if(!sdb_next(&db))
    224                 break;
    225 }
    226 sdbr_close(&q);
    227 sdb_close(&db);
    228 .EE
    229 .PP
    230 Server monitoring with negation:
    231 .IP
    232 .EX
    233 Sdb db;
    234 Sdbr q;
    235 String s;
    236 
    237 sdb_open(&db, "servers.db");
    238 sdbr_init(&q);
    239 sdbr_str2r(&q, Str("type=server !status=maintenance "
    240                    "location=datacenter1"));
    241 while(sdb_query(&db, q)) {
    242         s = sdbr_val(db.r[db.n], "hostname");
    243         print("Active server: %s\en", s.s);
    244         if(!sdb_next(&db))
    245                break;
    246 }
    247 sdbr_close(&q);
    248 sdb_close(&db);
    249 .EE
    250 .SH SOURCE
    251 .B \*9/src/libsdb
    252 .SH SEE ALSO
    253 .MR ndb (1) ,
    254 .MR ndb (3) ,
    255 .MR ndb (7) ,
    256 .MR sdb (1) ,
    257 .MR sdbr (3) ,
    258 .MR bio (3) ,
    259 .MR str (3) ,
    260 .MR vec (3)
    261 .SH DIAGNOSTICS
    262 Functions call
    263 .I sysfatal
    264 if file operations fail.
    265 .SH BUGS
    266 .I Sdb_flush
    267 only prints to standard output, so you cannot directly write to a database file.
    268 But maybe that's good!