Table *cdbtoplevel TopLevel_Command cdb subcmd enum(Cdb/_SubCommand, "cdb subcommand") ... obj cdb-wr subcmd enum(Cdbwr/_SubCommand, "cdb-wr subcommand") ... obj Table cdb Cdb_SubCommand open path string => iddata(&cdbtcl_databases) lookup db iddata(&cdbtcl_databases) key obj => obj lookup-hb db iddata(&cdbtcl_databases) key hb => hb close db iddata(&cdbtcl_databases) Table cdbwr Cdbwr_SubCommand create-empty -1 pathb string # files: # .main # .lock # .cdb # .log # .tmp (might be new .main or new .cdb) # invariants: # .lock is an empty file # which is locked with fcntl by open # .main is a cdb native text file # and always exists # if .tmp exists it is irrelevant # if .cdb exists it is a cdb database # containing exactly the same as .main # if .log exists, it is a cdb native # text file _without the trailing newline_; # its contents override values from .main or .cdb open -1 pathb string on_info obj => iddata(&cdbtcl_rwdatabases) # on_info ...: # on_info open-clean # on_info open-dirty # on_info compact-start # on_info compact-end # on_info close lookup 1 db iddata(&cdbtcl_rwdatabases) key obj => obj lookup-hb 1 db iddata(&cdbtcl_rwdatabases) key hb => hb update 0 db iddata(&cdbtcl_rwdatabases) key obj value obj update-hb 0 db iddata(&cdbtcl_rwdatabases) key hb value hb update-quick 1 db iddata(&cdbtcl_rwdatabases) key obj value obj update-quick-hb 1 db iddata(&cdbtcl_rwdatabases) key hb value hb close 0 db iddata(&cdbtcl_rwdatabases) close-quick 1 db iddata(&cdbtcl_rwdatabases) EntryExtra Cdbwr_SubCommand int quick;