all repos — litestore @ 78acfa2957841722f8d38a11572889902006bac4

A minimalist nosql document store.

Updated to work with nim devel; fixed post method to support folder parameter.
h3rald h3rald@h3rald.com
Fri, 31 Aug 2018 09:09:25 +0200
commit

78acfa2957841722f8d38a11572889902006bac4

parent

ee0bbe76422df19db10c14a57707581db0339f87

M .gitignore.gitignore

@@ -3,11 +3,13 @@ nimcache

*.db *.db-journal http_api +test.nim html5 css3 sqlite3_analyzer litestore*.zip litestore +*.exe nakefile LiteStore_UserGuide.htm jester_integration
M admin/md/nim-api_high.mdadmin/md/nim-api_high.md

@@ -35,7 +35,8 @@

##### Parameters {{p-resource}} -{{p-id}} +{{ p-folder => folder +: The folder that will contain the resource (set to an empty string if not needed).}} {{p-body}} {{p-headers}}
M examples/jester_integration.nimexamples/jester_integration.nim

@@ -1,4 +1,4 @@

-import jester, ../litestore, asyncdispatch, re, strtabs, asyncnet +import jester, ../litestore, asyncdispatch, re, strtabs, asyncnet, sequtils litestore.setup()

@@ -10,7 +10,7 @@ resp "Hello, World!"

# Remapping LiteStore routes on Jester get re"^\/litestore\/(docs|info)\/?(.*)": - let r = get(request.matches[0], request.matches[1], request.params, request.headers) + let r = get(request.matches[0], request.matches[1], newStringTable(toSeq(request.params.pairs)), request.headers) resp(r.code, r.content, r.headers["Content-Type"]) post re"^\/litestore\/docs\/?(.*)":

@@ -31,18 +31,16 @@ resp(r.code, r.content)

head re"^\/litestore\/docs\/?(.*)": let r = head("docs", request.matches[0], request.headers) - headers = newStringTable() - for key, value in r.headers.pairs: - headers[key] = value - await response.sendHeaders(r.code, headers) - response.client.close() + var headers: RawHeaders = newSeq[tuple[key: string, val: string]]() + for key, val in r.headers.pairs: + headers.add({key: key, val: val}) + sendHeaders(request, r.code, headers) options re"^\/litestore\/docs\/?(.*)": let r = options("docs", request.matches[0], request.headers) - headers = newStringTable() - for key, value in r.headers.pairs: - headers[key] = value - await response.sendHeaders(r.code, headers) - response.client.close() + var headers: RawHeaders = newSeq[tuple[key: string, val: string]]() + for key, val in r.headers.pairs: + headers.add({key: key, val: val}) + sendHeaders(request, r.code, headers) runForever()
M lib/api_v1.nimlib/api_v1.nim

@@ -188,7 +188,7 @@ content["datastore_version"] = %version

content["size"] = %($((LS.file.getFileSize().float/(1024*1024)).formatFloat(ffDecimal, 2)) & " MB") content["read_only"] = %LS.readonly content["log_level"] = %LS.loglevel - if LS.directory == nil: + if LS.directory.len == 0: content["directory"] = newJNull() else: content["directory"] = %LS.directory
M lib/api_v2.nimlib/api_v2.nim

@@ -207,7 +207,7 @@ content["datastore_version"] = %version

content["size"] = %($((LS.file.getFileSize().float/(1024*1024)).formatFloat(ffDecimal, 2)) & " MB") content["read_only"] = %LS.readonly content["log_level"] = %LS.loglevel - if LS.directory == nil: + if LS.directory.len == 0: content["directory"] = newJNull() else: content["directory"] = %LS.directory

@@ -321,7 +321,7 @@ of "docs":

var folder: string if id.isFolder: folder = id - if not folder.isNil: + if not folder.len == 0: result.code = Http200 result.content = "" if LS.readonly:
M lib/api_v3.nimlib/api_v3.nim

@@ -69,7 +69,7 @@ """ & tokens)

var fieldMatches = newSeq[string](10) if str.strip.match(fields, fieldMatches): for m in fieldMatches: - if not m.isNil: + if m.len > 0: var rawTuple = newSeq[string](2) if m.match(field, rawTuple): options.jsonSelect.add((path: rawTuple[0], alias: rawTuple[1]))

@@ -102,12 +102,12 @@ var orClausesMatches = newSeq[string](10)

discard str.strip.match(orClauses, orClausesMatches) var parsedClauses = newSeq[seq[seq[string]]]() for orClause in orClausesMatches: - if not orClause.isNil: + if orClause.len > 0: var andClausesMatches = newSeq[string](10) discard orClause.strip.match(andClauses, andClausesMatches) var parsedAndClauses = newSeq[seq[string]]() for andClause in andClausesMatches: - if not andClause.isNil: + if andClause.len > 0: var clauses = newSeq[string](3) discard andClause.strip.match(clause, clauses) clauses[1] = sqlOp(clauses[1])

@@ -398,7 +398,7 @@ content["datastore_version"] = %version

content["size"] = %($((LS.file.getFileSize().float/(1024*1024)).formatFloat(ffDecimal, 2)) & " MB") content["read_only"] = %LS.readonly content["log_level"] = %LS.loglevel - if LS.directory == nil: + if LS.directory.len == 0: content["directory"] = newJNull() else: content["directory"] = %LS.directory

@@ -489,7 +489,7 @@ else:

return resError(Http400, "Bad request: patch operation #$1 is malformed." % $c) c.inc if apply: - if not origData.isNil and origData != data: + if origData.len > 0 and origData != data: try: var doc = LS.store.updateDocument(id, data.pretty, "application/json") if doc == "":

@@ -530,7 +530,7 @@ of "docs":

var folder: string if id.isFolder: folder = id - if not folder.isNil: + if folder.len > 0: result.code = Http200 result.content = "" if LS.readonly:
M lib/cli.nimlib/cli.nim

@@ -12,15 +12,15 @@ const favicon = "../admin/favicon.ico".slurp

var operation = opRun - directory:string = nil + directory:string = "" readonly = false logLevel = "warn" mount = false - exOperation:string = nil - exFile:string = nil - exBody:string = nil - exType:string = nil - exUri:string = nil + exOperation:string = "" + exFile:string = "" + exBody:string = "" + exType:string = "" + exUri:string = "" let usage* = appname & " v" & version & " - Lightweight REST Document Store" & """

@@ -146,16 +146,16 @@ discard

# Validation -if directory.isNil and (operation in [opDelete, opImport, opExport] or mount): +if directory == "" and (operation in [opDelete, opImport, opExport] or mount): fail(105, "--directory option not specified.") -if exFile.isNil and (exOperation in ["put", "post", "patch"]): +if exFile == "" and (exOperation in ["put", "post", "patch"]): fail(109, "--file option not specified") -if exUri.isNil and operation == opExecute: +if exUri == "" and operation == opExecute: fail(110, "--uri option not specified") -if exOperation.isNil and operation == opExecute: +if exOperation == "" and operation == opExecute: fail(111, "--operation option not specified") LS.operation = operation
M lib/server.nimlib/server.nim

@@ -36,7 +36,7 @@ if info.version == "v3":

if info.resource.match(peg"^docs / info$"): return api_v3.route(req, LS, info.resource, info.id) elif info.resource.match(peg"^dir$"): - if LS.directory != nil: + if LS.directory.len > 0: return api_v3.serveFile(req, LS, info.id) else: return resError(Http400, "Bad Request - Not serving any directory." % info.version)

@@ -46,7 +46,7 @@ elif info.version == "v2":

if info.resource.match(peg"^docs / info$"): return api_v2.route(req, LS, info.resource, info.id) elif info.resource.match(peg"^dir$"): - if LS.directory != nil: + if LS.directory.len > 0: return api_v2.serveFile(req, LS, info.id) else: return resError(Http400, "Bad Request - Not serving any directory." % info.version)

@@ -56,7 +56,7 @@ elif info.version == "v1":

if info.resource.match(peg"^docs / info$"): return api_v1.route(req, LS, info.resource, info.id) elif info.resource.match(peg"^dir$"): - if LS.directory != nil: + if LS.directory.len > 0: return api_v1.serveFile(req, LS, info.id) else: return resError(Http400, "Bad Request - Not serving any directory." % info.version)
M lib/utils.nimlib/utils.nim

@@ -150,7 +150,7 @@ var obj = newJObject()

for field in options.jsonSelect: let keys = field.path.replace("$.", "").split(".") let res = result["data"]{keys} - if res.isNil: + if res.len == 0: obj[field.alias] = newJNull() else: obj[field.alias] = %res

@@ -166,7 +166,7 @@ try:

json = s.parseJson() except: discard - if not json.isNil: + if json.len > 0: if json.kind == JObject: # Only process string values str = toSeq(json.pairs).filterIt(it.val.kind == JString).mapIt(it.val.getStr).join(" ")

@@ -288,7 +288,7 @@ var epsilon = 1.0 / (totalDocs*avgLength)

var sum = 0.0; for i in 0..termCount-1: for col in 0..colCount-1: - let currentX = X_OFFSET + (3 * col * (i + 1)) + let currentX = X_OFFSET + (3 * col * (i + 1)) let termFrequency = matchinfo[currentX].float let docsWithTerm = matchinfo[currentX + 2].float var idf: float = ln((totalDocs - docsWithTerm + 0.5) / (docsWithTerm + 0.5))
M lib/x_db_sqlite.nimlib/x_db_sqlite.nim

@@ -105,7 +105,7 @@ raise e

proc dbQuote*(s: string): string = ## DB quotes the string. - if s.isNil: return "NULL" + if s.len == 0: return "NULL" result = "'" for c in items(s): if c == '\'': add(result, "''")
M litestore.nimlitestore.nim

@@ -53,12 +53,12 @@ of "HEAD":

req.reqMethod = HttpHead else: fail(203, "Operation '$1' is not supported" % [operation]) - if not body.isNil: + if body.len > 0: req.body = body - elif not file.isNil: + elif file.len > 0: req.body = file.readFile req.headers = newHttpHeaders() - if not ctype.isNil: + if ctype.len > 0: req.headers["Content-Type"] = ctype req.hostname = "<cli>" req.url = parseUri("$1://$2:$3/$4" % @["http", "localhost", "9500", uri])

@@ -168,8 +168,8 @@

proc get*(resource, id: string, params = newStringTable(), headers = newHttpHeaders()): LSResponse = return newLSRequest(HttpGet, resource, id, "", params, headers).get(LS, resource, id) - proc post*(resource, id, body: string, headers = newHttpHeaders()): LSResponse = - return newLSRequest(HttpPost, resource, id, body, newStringTable(), headers).post(LS, resource, id) + proc post*(resource, folder, body: string, headers = newHttpHeaders()): LSResponse = + return newLSRequest(HttpPost, resource, "", body, newStringTable(), headers).post(LS, resource, folder & "/") proc put*(resource, id, body: string, headers = newHttpHeaders()): LSResponse = return newLSRequest(HttpPut, resource, id, body, newStringTable(), headers).put(LS, resource, id)