all repos — litestore @ 30f8321864aa016f2d87e20cc227a140846551b7

A minimalist nosql document store.

Updated docs; minor changes.
h3rald h3rald@h3rald.com
Tue, 17 Mar 2020 18:22:46 +0100
commit

30f8321864aa016f2d87e20cc227a140846551b7

parent

4ae0e98ee5d55c70836a4f3b7eebf07ad92d0164

M build_guidebuild_guide

@@ -11,6 +11,7 @@ md/configuration-file.md

md/middleware.md md/global-js-objects.md md/system-documents.md + md/multiple-stores.md md/admin_app.md md/api.md md/api_info.md

@@ -18,6 +19,7 @@ md/api_dir.md

md/api_docs.md md/api_tags.md md/api_indexes.md + md/api_stores.md md/nim-api.md md/nim-api_high.md md/nim-api_low.md
M src/admin/js/components/info.jssrc/admin/js/components/info.js

@@ -16,15 +16,19 @@ return m("li", [m("span", title+": "), m("strong", content)]);

} }; var readonly = info.read_only ? m("span.label.label-success", "Yes") : m("span.label.label-danger", "No"); + var auth = info.auth ? m("span.label.label-success", "Yes") : m("span.label.label-danger", "No"); var mirror = info.mount ? m("span.label.label-success", "Yes") : m("span.label.label-danger", "No"); var infolist = m(".col-sm-6", [m("ul.list-unstyled", [ li("Version", info.version), li("Datastore Version", info.datastore_version), + li("API Version", info.api_version), li("Size", info.size), li("Serving Directory", info.directory, info.directory === null), li("Mirroring Changes", mirror), li("Log Level", info.log_level), li("Read-Only", readonly), + li("Auth", auth), + li("Additional Stores", info.additional_stores && info.additional_stores.join(", ") || "n/a"), li("Total Documents", m("span.badge", info.total_documents)), li("Total Tags", m("span.badge", info.total_tags)), ])]);

@@ -42,4 +46,4 @@ return v;

}; u.layout(app.info); -}()) +}())
M src/admin/js/components/navbar.jssrc/admin/js/components/navbar.js

@@ -22,6 +22,7 @@ {path: "/guide/configuration-file", title: "Configuration File"},

{path: "/guide/middleware", title: "Middleware"}, {path: "/guide/global-js-objects", title: caret+"Global JavaScript Objects"}, {path: "/guide/system-documents", title: "System Documents"}, + {path: "/guide/multiple-stores", title: "Multiple Data Stores"}, {path: "/guide/admin_app", title: "Administration App"}, {path: "/guide/api", title: "HTTP API Reference"}, {path: "/guide/api_info", title: caret+"info (LiteStore Information)"},

@@ -29,6 +30,7 @@ {path: "/guide/api_dir", title: caret+"dir (LiteStore Directory)"},

{path: "/guide/api_docs", title: caret+"docs (LiteStore Documents)"}, {path: "/guide/api_tags", title: caret+"tags (LiteStore Tags)"}, {path: "/guide/api_indexes", title: caret+"indexes (LiteStore Indexes)"}, + {path: "/guide/api_stores", title: caret+"stores (LiteStore Stores)"}, {path: "/guide/nim-api", title: "Nim API Reference"}, {path: "/guide/nim-api_high", title: caret+"High-Level Nim API"}, {path: "/guide/nim-api_low", title: caret+"Low-Level Nim API"},
M src/admin/md/api_info.mdsrc/admin/md/api_info.md

@@ -24,12 +24,16 @@

Returns the following server statistics: * Version +* Datastore version +* API version * Size of the database on disk (in MB) * Whether the database is read-only or not * Log level (debug, info, warning, error, none) * Mounted directory (if any) +* Additional stores (if any) +* Whether authorization is enabled or not * Total documents -* Total Tags +* Total tags * Number of documents per tag ##### Example

@@ -39,18 +43,21 @@ $ curl -i http://127.0.0.1:9500/info

HTTP/1.1 200 OK Content-Length: 965 Content-Type: application/json -Access-Control-Allow-Headers: Content-Type -Access-Control-Allow-Origin: * -Server: LiteStore/1.0.3 +Access-Control-Allow-Headers: Authorization, Content-Type +Access-Control-Allow-Origin: http://127.0.0.1:9500 +Server: LiteStore/1.9.0 { - "version": "LiteStore v1.1.0", - "datastore_version": 1, - "size": "5.76 MB", + "version": "LiteStore v1.9.0", + "datastore_version": 2, + "api_version": 7, + "size": "6.98 MB", "read_only": false, - "log_level": "info", + "log_level": "warn", "directory": "admin", "mount": true, + "additional_stores": [], + "auth": false, "total_documents": 68, "total_tags": 18, "tags": [

@@ -71,4 +78,4 @@ "$subtype:html": 2

} ] } -``` +```
A src/admin/md/api_stores.md

@@ -0,0 +1,253 @@

+### stores (LiteStore Stores) + +> %note% +> API v7 Required +> +> This resource has been introduced in version 7 of the LiteStore API. + +As of version 1.9.0, it is possible for a single LiteStore process to manage multiple data store files. These additional stores can be accessed but also added or removed at run time using this resource. + +#### OPTIONS stores + +Returns the allowed HTTP verbs for this resource. + +##### Example + +``` +$ curl -i -X OPTIONS http://127.0.0.1:9500/stores +HTTP/1.1 200 OK +server: LiteStore/1.9.0 +access-control-allow-origin: http://localhost:9500 +access-control-allow-headers: Content-Type +allow: GET,OPTIONS +access-control-allow-methods: GET,OPTIONS +content-length: 0 +``` + +#### OPTIONS stores/:id + +Returns the allowed HTTP verbs for this resource. + +##### Example + +``` +$ curl -i -X OPTIONS http://127.0.0.1:9500/stores/test1 +HTTP/1.1 200 OK +server: LiteStore/1.9.0 +access-control-allow-origin: http://localhost:9500 +access-control-allow-headers: Content-Type +allow: GET,OPTIONS,PUT,DELETE +access-control-allow-methods: GET,OPTIONS,PUT,DELETE +Content-Length: 0 +``` + +#### GET indexes + +Retrieves information on all available stores (file name and configuration). + +##### Example + +``` +$ curl -i http://localhost:9500/stores +HTTP/1.1 200 OK +content-type: application/json +access-control-allow-origin: http://127.0.0.1:9500 +access-control-allow-headers: Authorization, Content-Type +vary: Origin +server: LiteStore/1.9.0 +Content-Length: 2346 + +{ + "total": 4, + "execution_time": 0.0, + "results": [ + { + "id": "test1", + "file": "test1.db", + "config": null + }, + { + "id": "test2", + "file": "test2.db", + "config": null + }, + { + "id": "test3", + "file": "test3.db", + "config": null + }, + { + "id": "master", + "file": "data.db", + "config": { + "settings": { + "log": "debug", + "port": 9200 + }, + "stores": { + "test1": { + "file": "test1.db", + "config": null + }, + "test2": { + "file": "test2.db", + "config": null + }, + "test3": { + "file": "test3.db", + "config": null + } + }, + "resources": { + "/docs/vehicles/*": { + "GET": { + "middleware": [ + "validate", + "log" + ] + }, + "HEAD": { + "middleware": [ + "validate", + "log" + ] + }, + "POST": { + "allowed": false + }, + "PATCH": { + "auth": [ + "admin:vehicles" + ], + "middleware": [ + "validate", + "log" + ] + }, + "PUT": { + "auth": [ + "admin:vehicles" + ], + "middleware": [ + "validate", + "log" + ] + }, + "DELETE": { + "auth": [ + "admin:vehicles" + ], + "middleware": [ + "validate", + "log" + ] + } + }, + "/docs/logs/*": { + "GET": { + "auth": [ + "admin:server" + ] + }, + "POST": { + "allowed": false + }, + "PUT": { + "allowed": false + }, + "PATCH": { + "allowed": false + }, + "DELETE": { + "allowed": false + } + } + }, + "signature": "\n-----BEGIN CERTIFICATE-----\n<certificate text goes here>\n-----END CERTIFICATE-----\n" + } + } + ] +} +``` + +#### GET stores/:id + +Retrieves information on the specified store. + +##### Example + +``` +HTTP/1.1 200 OK +content-type: application/json +access-control-allow-origin: http://127.0.0.1:9500 +access-control-allow-headers: Authorization, Content-Type +vary: Origin +server: LiteStore/1.9.0 +Content-Length: 46 + +{"id":"test1","file":"test1.db","config":null} +``` + +#### PUT stores/:id + +Adds a new stores with the specified ID. If a file called **\<id\>.db** does not exist already, it will be created in the current working directory and initialized as a LiteStore store. + +Note that: +* Index IDs can only contain letters, numbers, and underscores. +* The body must be present and contain the store configuration (or **null**). + +> %warning% +> No updates +> +> It is not possible to update an existing store. Remove it and re-add it instead. + + +##### Example + +``` +curl -i -X PUT -d "null" "http://127.0.0.1:9500/stores/test3" --header "Content-Type:application/json" +HTTP/1.1 201 Created +content-type: application/json +access-control-allow-origin: http://127.0.0.1:9500 +access-control-allow-headers: Authorization, Content-Type +vary: Origin +server: LiteStore/1.9.0 +Content-Length: 46 + +{"id":"test3","file":"test3.db","config":null} +``` + +#### DELETE stores/:id + +Removes the specified store. Although it will no longer be accessible via LiteStore, the corresponding file will *not* be deleted from the filesystem. + +##### Example + +``` +$ curl -i -X DELETE "http://127.0.0.1:9200/stores/test3" +HTTP/1.1 204 No Content +vary: Origin +access-control-allow-origin: http://127.0.0.1:9200 +access-control-allow-headers: Authorization, Content-Type +content-length: 0 +server: LiteStore/1.9.0 +Content-Length: 0 +``` + +#### \* stores/:id/\* + +Forward the request to the specified store. Essentially, the path fragment after the store ID will be forwarded as a standard request to the specified store. + +##### Examples + +Retrieve all tags from store **vehicles**: +``` +$ curl -i http://localhost:9500/stores/vehicles/tags/ +``` + + +Delete the document with ID **AA457DB** from store **vehicles**: + +``` +$ curl -i -X DELETE "http://127.0.0.1:9200/stores/vehicles/docs/AA457DB" +```
M src/admin/md/configuration-file.mdsrc/admin/md/configuration-file.md

@@ -12,6 +12,32 @@ "settings": {

"log": "debug", "port": 9200 }, + "stores": { + "logs": { + "file": "logs.db", + "config": { + "resources": { + "/docs/*": { + "GET": { + "auth": ["admin:server"] + }, + "POST": { + "allowed": false + }, + "PUT": { + "allowed": false + }, + "PATCH": { + "allowed": false + }, + "DELETE": { + "allowed": false + } + } + } + } + } + }, "resources": { "/docs/vehicles/*": { "GET": {

@@ -35,26 +61,8 @@ "DELETE": {

"auth": ["admin:vehicles"], "middleware": ["validate", "log"] } - }, - "/docs/logs/*": { - "GET": { - "auth": ["admin:server"] - }, - "POST": { - "allowed": false - }, - "PUT": { - "allowed": false - }, - "PATCH": { - "allowed": false - }, - "DELETE": { - "allowed": false - } } - }, - "signature": "\n-----BEGIN CERTIFICATE-----\n<certificate text goes here>\n-----END CERTIFICATE-----\n" + } } ```

@@ -74,6 +82,12 @@ * middleware

* log If a configuration file is specified and some of these settings are configured, they will be recognized as if they were specified via command line. However, if you also specify the same settings via command line, the command line settings will take precedence over the settings defined in the configuration file. + +### stores + +This section is used to defined additional stores to be managed by LiteStore by specifying the SQLite file to open and optionally the store configuration. + +In this case, the **logs** store is configured as an additional store. ### resources
A src/admin/md/multiple-stores.md

@@ -0,0 +1,84 @@

+## Multiple Data Stores + +As of version 1.9.0, it is possible to configure LiteStore to manage several different SQLite database files, or *stores*. Essentially, besides the *master* store it is possible to create, delete or access additional stores at run time though the new **/stores** resource. + +Although folders already provide some partitioning for documents, in certain situations you may want to physically separate your data into multiple files, for example when: + +* Managing time-dependent content (store only records of a day or month in a single file) +* Storing accessory content that is unrelated to other data, like logging/diagnostic information +* Managing data belonging to different tenants + +Although all stores can be accessed by the same process using the **/stores** resource (which can essentially forward requests to be executed on a specific file), each store can have its own configuration file stored as a system document, its own authentication and its own middleware. + +### Configuring additional stores + +If you know the details of each store at development/configuration time, you can configure them in the **stores** section of the LiteStore configuration file, like this: + +``` +{ + "settings": { + "log": "debug", + "port": 9200 + }, + "stores": { + "test1": { + "file": "test1.db", + "config": null + }, + "test2": { + "file": "test2.db", + "config": null + }, + "test3": { + "file": "test3.db", + "config": null + } + }, + "resources": { + "/docs/vehicles/*": { + "GET": { + "middleware": ["validate", "log"] + }, + "HEAD": { + "middleware": ["validate", "log"] + }, + "POST": { + "allowed": false + }, + "PATCH": { + "auth": ["admin:vehicles"], + "middleware": ["validate", "log"] + }, + "PUT": { + "auth": ["admin:vehicles"], + "middleware": ["validate", "log"] + }, + "DELETE": { + "auth": ["admin:vehicles"], + "middleware": ["validate", "log"] + } + }, + "/docs/logs/*": { + "GET": { + "auth": ["admin:server"] + }, + "POST": { + "allowed": false + }, + "PUT": { + "allowed": false + }, + "PATCH": { + "allowed": false + }, + "DELETE": { + "allowed": false + } + } + } +} +``` + + When LiteStore is executed, the three additional stores will be created and initialized, their configuration (if any) will be saved as a system document and they will be immediately accessible. + + Alternatively, you can add or remove stores dynamically at run time by executing POST and DELETE requests to the **/stores** resource, optionally specifying configuration settings as the request body.
M src/admin/md/overview.mdsrc/admin/md/overview.md

@@ -47,6 +47,10 @@ #### Middleware

By leveraging the [duktape](https://duktape.org/) library, you can create your own middleware functions in JavaScript to perform additional tasks (validation, logging, data aggregation...) before accessing data. +#### Multiple Data Stores + +LiteStore can be configured to manage more than one SQLite file through the same process. At run time, it will be possible to access data stored in each store but also add and remove stores. + #### Nim API If you want, you can use LiteStore as a [Nim](https://nim-lang.org) library and perform data store operations from your own Nim program.
M src/litestorepkg/lib/api_v7.nimsrc/litestorepkg/lib/api_v7.nim

@@ -529,6 +529,7 @@ let tags = LS.store.retrieveTagsWithTotals()

var content = newJObject() content["version"] = %(LS.appname & " v" & LS.appversion) content["datastore_version"] = %version + content["api_version"] = %7 content["size"] = %($((LS.file.getFileSize().float/(1024*1024)).formatFloat(ffDecimal, 2)) & " MB") content["read_only"] = %LS.readonly content["log_level"] = %LS.loglevel

@@ -537,6 +538,14 @@ content["directory"] = newJNull()

else: content["directory"] = %LS.directory content["mount"] = %LS.mount + if LS.config != newJNull() and LS.config.hasKey("stores") and LS.config["stores"].len > 0: + content["additional_stores"] = %toSeq(LS.config["stores"].keys) + else: + content["additional_stores"] = newJArray() + if LS.auth != newJNull(): + content["auth"] = %true + else: + content["auth"] = %false content["total_documents"] = %total_documents content["total_tags"] = %total_tags content["tags"] = tags