all repos — litestore @ a3207a1bb0db50127771438e48a518a75438b8be

A minimalist nosql document store.

Improved library usage; added proper high-level public methods.
h3rald h3rald@h3rald.com
Sat, 07 Oct 2017 14:54:26 +0200
commit

a3207a1bb0db50127771438e48a518a75438b8be

parent

e4f1854c8feff76ddf5e1c241b5867848a498bfa

3 files changed, 97 insertions(+), 43 deletions(-)

jump to
M examples/jester_integration.nimexamples/jester_integration.nim

@@ -1,19 +1,6 @@

-import jester, ../litestore, asyncdispatch, uri, strutils, sequtils, httpcore - -proc lsReq(req: jester.Request): LSRequest = - var params = newSeq[string](0) - for key, value in pairs(req.params): - params.add("$1=$2" % @[key, value]) - let query = params.join("&") - var protocol = "http" - if req.secure: - protocol = "https" - result.reqMethod = req.reqMeth - result.url = parseUri("$1://$2:$3/$4?$5" % @[protocol, req.host, $req.port, req.path, query]) - result.hostname = req.host - result.body = req.body +import jester, ../litestore, asyncdispatch, re -LS.init() +litestore.setup() routes:

@@ -22,32 +9,32 @@ get "/":

resp "Hello, World!" # Remapping LiteStore routes on Jester - get "/litestore/@resource/@id?": - let r = get(request.lsReq, LS, @"resource", @"id") - resp(r.code, r.content, r.headers["content-type"]) + get re"^\/litestore\/(docs|info)\/?(.*)": + let r = get(request.matches[0], request.matches[1], request.params) + resp(r.code, r.content, r.headers["Content-Type"]) - post "/litestore/@resource/@id?": - let r = post(request.lsReq, LS, @"resource", @"id") - resp(r.code, r.content, r.headers["content-type"]) + post re"^\/litestore\/docs\/?(.*)": + let r = post("docs", request.matches[0], request.body) + resp(r.code, r.content, r.headers["Content-Type"]) - put "/litestore/@resource/@id?": - let r = put(request.lsReq, LS, @"resource", @"id") - resp(r.code, r.content, r.headers["content-type"]) + put re"^\/litestore\/docs\/?(.*)": + let r = put("docs", request.matches[0], request.body) + resp(r.code, r.content, r.headers["Content-Type"]) - patch "/litestore/@resource/@id?": - let r = patch(request.lsReq, LS, @"resource", @"id") - resp(r.code, r.content, r.headers["content-type"]) + patch re"^\/litestore\/docs\/?(.*)": + let r = patch("docs", request.matches[0], request.body) + resp(r.code, r.content, r.headers["Content-Type"]) - delete "/litestore/@resource/@id?": - let r = delete(request.lsReq, LS, @"resource", @"id") - resp(r.code, r.content, r.headers["content-type"]) + delete re"^\/litestore\/docs\/?(.*)": + let r = delete("docs", request.matches[0]) + resp(r.code, r.content, r.headers["Content-Type"]) - head "/litestore/@resource/@id?": - let r = head(request.lsReq, LS, @"resource", @"id") - resp(r.code, r.content, r.headers["content-type"]) + head re"^\/litestore\/docs\/?(.*)": + let r = head("docs", request.matches[0]) + resp(r.code, r.content, r.headers["Content-Type"]) - options "/litestore/@resource/@id?": - let r = options(request.lsReq, LS, @"resource", @"id") - resp(r.code, r.content, r.headers["content-type"]) + options re"^\/litestore\/docs\/?(.*)": + let r = options("docs", request.matches[0]) + resp(r.code, r.content, r.headers["Content-Type"]) runForever()
M lib/api_v2.nimlib/api_v2.nim

@@ -386,7 +386,7 @@ options.select = @["documents.id AS id", "created", "modified"]

try: parseQueryOptions(req.url.query, options); if id != "" and options.folder == "": - if req.url.query.contains("raw=true") or req.headers["Accept"] == "application/json": + if req.url.query.contains("raw=true") or req.headers.hasKey("Accept") and req.headers["Accept"] == "application/json": return LS.getRawDocument(id, options) else: return LS.getDocument(id, options)
M litestore.nimlitestore.nim

@@ -7,7 +7,10 @@ oids,

times, json, pegs, + uri, strtabs, + httpcore, + cgi, base64 import lib/types,

@@ -18,9 +21,7 @@ lib/cli,

lib/server export - server, types, - core, server from asyncdispatch import runForever

@@ -28,7 +29,7 @@

{.compile: "vendor/sqlite/libsqlite3.c".} {.passC: "-DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_JSON1".} -proc init*(LS: var LiteStore, open = true) = +proc setup*(open = true) = if not LS.file.fileExists: try: LOG.debug("Creating datastore: ", LS.file)

@@ -49,9 +50,6 @@ except:

fail(201, "Unable to open datastore '$1'" % [LS.file]) when isMainModule: - - # Initialize Datastore - LS.init() # Manage vacuum operation separately if LS.operation == opVacuum:

@@ -76,3 +74,72 @@ LS.store.optimize

else: discard +else: + + proc params*(query: string): StringTableRef = + new(result) + let pairs = query.split("&") + for pair in pairs: + let data = pair.split("=") + result[data[0]] = data[1] + + proc query*(table: StringTableRef): string = + var params = newSeq[string](0) + for key, value in pairs(table): + params.add("$1=$2" % @[key, value.encodeUrl]) + return params.join("&") + + proc newLSRequest(meth: HttpMethod, resource, id, body = "", params = newStringTable()): LSRequest = + result.reqMethod = meth + result.body = body + result.headers = newHttpHeaders() + result.url = parseUri("$1://$2:$3/$4/$5?$6" % @["http", "localhost", "9500", resource, id, params.query()]) + + # Public API: Low-level + + proc getInfo*(): LSResponse = + return LS.getInfo() + + proc getRawDocuments*(options = newQueryOptions()): LSResponse = + return LS.getRawDocuments(options) + + proc getDocument*(id: string, options = newQueryOptions()): LSResponse = + return LS.getDocument(id, options) + + proc getRawDocument*(id: string, options = newQueryOptions()): LSResponse = + return LS.getRawDocument(id, options) + + proc deleteDocument*(id: string): LSResponse = + return LS.deleteDocument(id) + + proc postDocument*(body, ct: string, folder=""): LSResponse = + return LS.postDocument(body, ct, folder) + + proc putDocument*(id, body, ct: string): LSResponse = + return LS.putDocument(id, body, ct) + + proc patchDocument*(id, body: string): LSResponse = + return LS.patchDocument(id, body) + + # Public API: High-level + + proc get*(resource, id: string, params = newStringTable()): LSResponse = + return newLSRequest(HttpGet, resource, id, "", params).get(LS, resource, id) + + proc post*(resource, id, body: string): LSResponse = + return newLSRequest(HttpPost, resource, id, body).post(LS, resource, id) + + proc put*(resource, id, body: string): LSResponse = + return newLSRequest(HttpPut, resource, id, body).put(LS, resource, id) + + proc patch*(resource, id, body: string): LSResponse = + return newLSRequest(HttpPatch, resource, id, body).patch(LS, resource, id) + + proc delete*(resource, id: string): LSResponse = + return newLSRequest(HttpPatch, resource, id).delete(LS, resource, id) + + proc head*(resource, id: string): LSResponse = + return newLSRequest(HttpHead, resource, id).head(LS, resource, id) + + proc options*(resource, id: string): LSResponse = + return newLSRequest(HttpOptions, resource, id).options(LS, resource, id)