.Dd $Mdocdate: March 6 2023 $ .Dt DB 3 .Os Telodendria Project .Sh NAME .Nm Db .Nd A minimal flat-file database with object locking and an efficient cache. .Sh SYNOPSIS .In Db.h .Ft Db * .Fn DbOpen "char *" "size_t" .Ft void .Fn DbClose "Db *" .Ft DbRef * .Fn DbCreate "Db *" "size_t" "..." .Ft int .Fn DbDelete "Db *" "size_t" "..." .Ft DbRef * .Fn DbLock "Db *" "size_t" "..." .Ft int .Fn DbUnlock "Db *" "DbRef *" .Ft int .Fn DbExists "Db *" "size_t" "..." .Ft Array * .Fn DbList "Db *" "size_t" "..." .Ft void .Fn DbListFree "Array *" .Ft HashMap * .Fn DbJson "DbRef *" .Sh DESCRIPTION .Pp Telodendria operates on a flat-file database instead of a traditional relational database. This greatly simplifies the persistent storage code, and creates a relatively basic API, described by this page. .Pp .Fn DbOpen and .Fn DbClose open and close a data directory. .Fn DbOpen takes the path to open, and a cache size in bytes. This API relies heavily on caching, so the cache must be greater than the DB_MIN_CACHE preprocessor constant. .Pp .Fn DbCreate and .Fn DbLock load data objects from the database, with the notable difference being that .Fn DbCreate will fail if an object already exists, and .Fn DbLock will fail if an object does not exist. These are both variadic functions that take a variable number of C strings, with the exact number being specified by the second paramter. These C strings are used to generate a filesystem path from which an object is loaded, unless it is already in the cache. .Pp Objects, when loaded, are locked both in memory and on disk, so that other threads or processes cannot access them while they are locked. This is to ensure data integrity. .Pp .Fn DbUnlock unlocks an object and returns it back to the database, which syncs it to the filesystem and caches it, if it isn't in the cache already. .Pp .Fn DbExists checks the existence of the given database object in a more efficient manner than attempting to lock it with .Fn DbLock . .Fn DbExists does not lock the object, nor does it load it into memory if it exists. It takes the same arguments as .Fn DbLock and .Fn DbUnlock . .Pp .Fn DbJson converts a database reference into JSON. At this time, the database actually stores objects as JSON, so this just returns an internal pointer, but in the future it may have to be generated by decompressing a binary blob, or something of that nature. .Pp .Fn DbDelete completely removes an object from the database. It purges it from both the cache and the disk as soon as no more references to it are open. .Pp .Fn DbList lists all of the objects at a given path. Unlike the other varargs functions, it does not take a path to a specific object; it takes a directory to be iterated. Note that the resulting list only contains the objects in that directory, not subdirectories. .Fn DbListFree frees the list returned by this function. .Sh RETURN VALUES .Pp .Fn DbOpen returns a reference to a database pointer, or NULL if there was an error allocating memory, or opening the given directory with the given cache size. .Pp .Fn DbCreate and .Fn DbLock return a database reference, or NULL if there was an error obtaining a reference to the specified object. .Pp .Fn DbUnlock returns a boolean value indicating whether or not the reference was successfully unlocked. If the unlock is successful, then a non-zero value is returned. If it isn't, 0 is returned, and it is up to the caller to decide how to proceed. .Pp .Fn DbDelete follows the same return value conventions as .Fn DbUnlock ; it reports the status of the deletion operation as a boolean value. .Pp .Fn DbList returns an array of strings, or NULL if there was a memory or filesystem error. .Pp .Fn DbJson returns a JSON object. Consult .Xr Json 3 for the API used to manipulate this object.