diff --git a/docs/notORM.md b/docs/notORM.md new file mode 100644 index 0000000..d62e22e --- /dev/null +++ b/docs/notORM.md @@ -0,0 +1,108 @@ +# HTTP.sh's notORM, the not quite arbitrary data store + +notORM aims to be a generic interface between bash and databases, for storing ASCII and +UTF-8 strigns. Currently it only supports file-backed CSV-like stores, but our aim is to +make it talk with several SQL databases, exposing a common API to the application. + +For some examples, check out [unit tests](../tests/04-notORM.sh). + +## What notORM can't do + +- store 0x00, 0x01 and 0x02; Other non-printable characters are unsupported, but may work. +- do complex matches. those can be reimplemented manually with `data_iter` +- guarantee full security. data does get sanitized, but remember to treat unsafe input + very carefully. +- cook you dinner (haven't tried tho) + +## Public functions + +The API is still evolving. Functions marked in italics are to be deprecated: + +- data_add (adds an entry. creates a store if it does not exist) +- data_get (retrieves the first entry that matches constraints) +- data_iter (calls an user-defined function on every match) +- *data_replace_value* (replaces one cell on all rows that match) +- data_replace (replaces a row with a bash array on all rows that match) +- data_yeet (removes all rows that match) + +For in-depth descriptions, see references in `src/notORM.sh`. Each function has some usage +notes in a comment above it. + +## Calling conventions + +Currently, notORM supports two calling conventions for calls that select data: +- original (positional arguments, different for every function) +- improved (special selectors, generic for all getters). + +It is recommended to only use the improved calling convention: + +``` +COMMAND STORE_PATH { SEARCH } [additional_args] +COMMAND STORE_PATH { SEARCH COLUMN } [additional_args] +COMMAND STORE_PATH { SEARCH COLUMN } { SEARCH COLUMN } (...) [additional_args] +``` + +- `COMMAND` can be one of `data_get`, `data_iter`, `data_yeet`. (`data_replace` in + a future version, TBD) +- `STORE_PATH` selects a specific notORM store file +- `{` is a literal curly brace. it has to be paired with `}` after a search term. +- `SEARCH` is a literal that has to match when selecting a row. Optional, left out matches + all possible rows. +- `COLUMN` specifies which column the `SEARCH` term should be matched on. 0-indexed, + optional, defaults to 0 (usually unique key or autoincrement ID) +- `}` is a literal closing curly brace. it may be followed by another `{`, or + command-specific arguments. + +### Example usage + +``` +data_get storage/asdf.dat { "meow" } # matches "meow" on 0th column +data_get storage/asdf.dat { "meow" 1 } # matches "meow" on 1st column +data_get storage/asdf.dat { "meow" 1 } { 1337 } # matches "meow" on 1st, and "1337" on 0th +data_get storage/asdf.dat { } # matches first record in the store +``` + +## Autoincrement key + +By default, all keys are modified manually. That is, what you put in is what you take out. +`data_add` has a special mode which inserts a number as the 0th element in each entry: + +``` +data_add STORE_PATH ARRAY AUTOINCREMENT +``` + +It's important to warn that in the current impl this is much more resource-intensive than +a plain `data_add`, as it needs to find the last element in the store and increment the +counter. A rewrite is pending. + +### Example usage + +``` +a=(123 456) +data_add store a true +data_get store { } +declare -p res # res=(0 123 456) +``` + +## Iterators + +``` +data_iter STORE_PATH { ... } CALLBACK +``` + +`CALLBACK` is the name of an user-defined function that will get called on every matched +entry. Common debug value is `x`, which will run `declare -p data`, listing all records. + +Returning value `255` from the callback will terminate the iterator. + +### Example usage + +``` +cb() { + echo "${data[0]}" +} +data_iter store { } cb +``` + +Depending on your coding style, calling `unset` on the function after use may be desired. + diff --git a/tests/04-notORM.sh b/tests/04-notORM.sh index 2ad6764..7a257bf 100644 --- a/tests/04-notORM.sh +++ b/tests/04-notORM.sh @@ -106,7 +106,32 @@ notORM_backslashes() { fi return 0 - } + } + + cleanup() { + rm "$store" + } +} + +notORM_add_autoincrement() { + prepare() { + a=("meow" "nyaa") + data_add "$store" a true + data_add "$store" a true + a=("nyaa" "...") + data_add "$store" a true + } + + tst() { + data_get "$store" { 2 } { "..." 2 } || return 1 + echo -n "${res[1]}" + } + + match="nyaa" + + cleanup() { + rm "$store" + } } subtest_list=( @@ -119,4 +144,5 @@ subtest_list=( notORM_yeet_multiple_filters notORM_replace_oldsyntax notORM_backslashes + notORM_add_autoincrement )