From 700f86a7f56ce9c61bec18842476ab0701880ddf Mon Sep 17 00:00:00 2001 From: Philippe PITTOLI Date: Fri, 17 May 2024 14:08:32 +0200 Subject: [PATCH] API documentation. --- graphs/graphs.ms | 181 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 157 insertions(+), 24 deletions(-) diff --git a/graphs/graphs.ms b/graphs/graphs.ms index 0621a47..77899f7 100644 --- a/graphs/graphs.ms +++ b/graphs/graphs.ms @@ -15,12 +15,21 @@ .KE .QE .. -. -.de COMMAND +.de FUNCTION_CALL .I \\$* .. +. +.de COMMAND +.I "\\$*" +.. .de DIRECTORY -.I \\$* +.I "\\$*" +.. +.de PRIMARY_KEY +.I \\$1 \\$2 \\$3 +.. +.de FOREIGN_KEY +.I \\$1 \\$2 \\$3 .. . . \" The document starts here. @@ -46,12 +55,6 @@ Anything else is Universities all around the world teach about Structured Query Language (SQL) and relational databases. . -.de PRIMARY_KEY -.I \\$1 \\$2 \\$3 -.. -.de FOREIGN_KEY -.I \\$1 \\$2 \\$3 -.. .UL "Relational databases" are built around the idea to put data into @@ -226,9 +229,6 @@ The file "0000000000" contains the following: The car is serialized as expected in the file .I 0000000000 . .QE -.de FUNCTION_CALL -.I \\$* -.. . . Next step, to retrieve, to modify or to delete a value, its key will be required. @@ -490,19 +490,18 @@ database = DODB::RAMOnlyDataBase(Car).new "path/to/db-cars" Yes, the path still is required which may be seen as a quirk but the rationale\*[*] is sound. .QE .FOOTNOTE1 -A path is still required despite the databse being only in memory for two reasons. -First, indexes can still be instanciated for the database, and those indexes can provide a file-system representation of the data. -Second, I worked enough already, leave me alone. +A path is still required despite the database being only in memory because indexes can still be instanciated for the database, and those indexes will require this directory. +Also, I worked enough already, leave me alone. .FOOTNOTE2 .SS RAM-only indexes -All indexes have their RAM-only counterpart. +Indexes have their RAM-only version. .QP .SOURCE Ruby ps=10 # RAM-only basic indexes. cars_by_name = cars.new_RAM_index "name", &.name # RAM-only partitions. -cars_by_colors = cars.new_RAM_partition "color", &.color +cars_by_color = cars.new_RAM_partition "color", &.color # RAM-only tags. cars_by_keywords = cars.new_RAM_tags "keywords", &.keywords @@ -543,7 +542,7 @@ But for highly memory-constrained environments, the cache can be removed. cars_by_name = cars.new_uncached_index "name", &.name # Uncached partitions. -cars_by_colors = cars.new_uncached_partition "color", &.color +cars_by_color = cars.new_uncached_partition "color", &.color # Uncached tags. cars_by_keywords = cars.new_uncached_tags "keywords", &.keywords @@ -556,13 +555,147 @@ is exactly the same as the others. . . .SECTION Recap of the DODB API -.TBD -.SS Database creation -.SS Database update and deletion with the key -.SS Indexes creation -.SS Database update and deletion with an index -.SSS Tags: specific functions +This section provides a quick shorthand manual for the most important parts of the DODB API. +For an exhaustive API documentation, please generate the development documentation for the library. +The command +.COMMAND "make doc" +generates the documentation, then the +.COMMAND "make serve-doc" +command enables to browse the full documentation with a web browser. . +.SS Database creation +.QP +.SOURCE Ruby ps=10 +# Uncached, cached and RAM-only database creation. +database = DODB::DataBase(Car).new "path/to/db-cars" +database = DODB::CachedDataBase(Car).new "path/to/db-cars" +database = DODB::RAMOnlyDataBase(Car).new "path/to/db-cars" +.SOURCE +.QE +. +.SS Browsing the database +.QP +.SOURCE Ruby ps=10 +# List all the values in the database +database.each do |value| + # ... +end +.SOURCE +.QE + +.QP +.SOURCE Ruby ps=10 +# List all the values in the database with their key +database.each_with_index do |value, key| + # ... +end +.SOURCE +.QE +. +.SS Database search, update and deletion with the key (integer associated to the value) +.KS +.QP +.SOURCE Ruby ps=10 +value = database[key] # May throw a MissingEntry exception +value = database[key]? # Return nil if the value doesn't exist +database[key] = value +database.delete key +.SOURCE +Side note for the +.I [] +function: in case the value isn't in the database, the function throws an exception named +.I DODB::MissingEntry . +To avoid this exception and get a +.I nil +value instead, use the +.I []? +function. +.QE +.KE +. +. +.SS Indexes creation +.QP +.SOURCE Ruby ps=10 +# Uncached, cached and RAM-only basic indexes. +cars_by_name = cars.new_uncached_index "name", &.name +cars_by_name = cars.new_index "name", &.name +cars_by_name = cars.new_RAM_index "name", &.name + +# Uncached, cached and RAM-only partitions. +cars_by_color = cars.new_uncached_partition "color", &.color +cars_by_color = cars.new_partition "color", &.color +cars_by_color = cars.new_RAM_partition "color", &.color + +# Uncached, cached and RAM-only tags. +cars_by_keywords = cars.new_uncached_tags "keywords", &.keywords +cars_by_keywords = cars.new_tags "keywords", &.keywords +cars_by_keywords = cars.new_RAM_tags "keywords", &.keywords +.SOURCE +.QE +. +. +.SS Database retrieval, update and deletion with an index +.QP +.SOURCE Ruby ps=10 +# Get a value from an index. +car = cars_by_name.get "Corvet" # May throw a MissingEntry exception +car = cars_by_name.get? "Corvet" # Return nil if the value doesn't exist +.SOURCE +Works the same for partitions and tags, the API is consistent. +.QE +.QP +.SOURCE Ruby ps=10 +# Update a value. +car = cars_by_name.update updated_car +# In case the indexed attribute changed. +car = cars_by_name.update "Corvet", updated_car +.SOURCE +.QE + +.QP +.SOURCE Ruby ps=10 +# In case the value may not exist. +car = cars_by_name.update_or_create updated_car +# In case the indexed attribute has changed. +car = cars_by_name.update_or_create "Corvet", updated_car +.SOURCE +.QE + +.QP +.SOURCE Ruby ps=10 +cars_by_name.delete "Corvet" + +# Delete all red cars. +cars_by_color.delete "red" + +# Delete all cars that are both blue and slow. +cars_by_color.delete "blue", do |car| + car.keywords.includes? "slow" +end + +# Same. +cars_by_keywords.delete "slow", do |car| + car.color == "blue" +end +.SOURCE +.QE +. +. +.SSS Tags: search on multiple keys +The Tag index enables to search for a value based on multiple keys. +For example, searching for all cars that are both fast and elegant can be written this way: +.QP +.SOURCE Ruby ps=10 +fast_elegant_cars = cars_by_keywords.get ["fast", "elegant"] +.SOURCE +Used with a list of keys, the +.FUNCTION_CALL get +function returns an empty list in case the search failed. +.br +The implementation was designed to be simple (7 lines of code), not efficient. +However, with data and index caches, the search is expected to meet about everyone's requirements, speed-wise, given that the tags are small enough (a few thousand entries). +.QE . . .SECTION Limits of DODB