all repos — litestore @ 76203f335be017d657b12ff623821083aef7523e

A minimalist nosql document store.

Added validation for indexes.
h3rald h3rald@h3rald.com
Mon, 13 Jan 2020 17:20:00 +0100
commit

76203f335be017d657b12ff623821083aef7523e

parent

98a52155446efe3062f71ef0a0b45a577ad365e6

3 files changed, 21 insertions(+), 5 deletions(-)

jump to
M src/litestorepkg/lib/api_v5.nimsrc/litestorepkg/lib/api_v5.nim

@@ -349,7 +349,7 @@ proc getTag*(LS: LiteStore, id: string, options = newQueryOptions(), req: LSRequest): LSResponse =

let doc = LS.store.retrieveTag(id, options) result.headers = ctJsonHeader() setOrigin(LS, req, result.headers) - if doc == newJObject(): + if doc == newJNull(): result = resTagNotFound(id) else: result.content = $doc

@@ -359,7 +359,7 @@ proc getIndex*(LS: LiteStore, id: string, options = newQueryOptions(), req: LSRequest): LSResponse =

let doc = LS.store.retrieveIndex(id, options) result.headers = ctJsonHeader() setOrigin(LS, req, result.headers) - if doc == newJObject(): + if doc == newJNull(): result = resIndexNotFound(id) else: result.content = $doc

@@ -513,6 +513,12 @@ result.code = Http200

proc putIndex*(LS: LiteStore, id, field: string, req: LSRequest): LSResponse = try: + if (not id.match(PEG_INDEX)): + return resError(Http400, "invalid index ID: $1" % id) + if (not field.match(PEG_JSON_FIELD)): + return resError(Http400, "invalid field path: $1" % field) + if (LS.store.retrieveIndex(id) != newJNull()): + return resError(Http409, "Index already exists: $1" % id) LS.store.createIndex(id, field) result.headers = ctJsonHeader() setOrigin(LS, req, result.headers)

@@ -523,6 +529,10 @@ eWarn()

result = resError(Http500, "Unable to create index.") proc deleteIndex*(LS: LiteStore, id: string, req: LSRequest): LSResponse = + if (not id.match(PEG_INDEX)): + return resError(Http400, "invalid index ID: $1" % id) + if (LS.store.retrieveIndex(id) == newJNull()): + return resError(Http404, "Index not found: $1" % id) try: LS.store.dropIndex(id) result.headers = newHttpHeaders(TAB_HEADERS)
M src/litestorepkg/lib/core.nimsrc/litestorepkg/lib/core.nim

@@ -132,6 +132,8 @@ var options = options

options.single = true let query = prepareSelectIndexesQuery(options) let raw_index = store.db.getRow(query.sql, "json_index_" & id) + if raw_index[0] == "": + return newJNull() var matches: array[0..0, string] let fieldPeg = peg"'CREATE INDEX json_index_test ON documents(json_extract(data, \'' {[^']+}" discard raw_index[1].match(fieldPeg, matches)

@@ -144,11 +146,9 @@ if (options.like.len > 0):

echo options.like if (options.like[options.like.len-1] == '*' and options.like[0] != '*'): let str = "json_index_" & options.like.substr(0, options.like.len-2) - echo str raw_indexes = store.db.getAllRows(query.sql, str, str & "{") else: let str = "json_index_" & options.like.replace("*", "%") - echo str, "---" raw_indexes = store.db.getAllRows(query.sql, str) else: raw_indexes = store.db.getAllRows(query.sql)

@@ -157,7 +157,7 @@ for index in raw_indexes:

var matches: array[0..0, string] let fieldPeg = peg"'CREATE INDEX json_index_test ON documents(json_extract(data, \'' {[^']+}" discard index[1].match(fieldPeg, matches) - indexes.add(%[("id", %index[0]), ("field", %matches[0])]) + indexes.add(%[("id", %index[0].replace("json_index_", "")), ("field", %matches[0])]) return %indexes proc countIndexes*(store: Datastore, q = "", like = ""): int64 =

@@ -199,6 +199,8 @@ var options = options

options.single = true var query = prepareSelectTagsQuery(options) var raw_tag = store.db.getRow(query.sql, id) + if raw_tag[0] == "": + return newJNull() return %[("id", %raw_tag[0]), ("documents", %(raw_tag[1].parseInt))] proc retrieveTags*(store: Datastore, options: QueryOptions = newQueryOptions()): JsonNode =
M src/litestorepkg/lib/types.nimsrc/litestorepkg/lib/types.nim

@@ -92,11 +92,15 @@

var PEG_TAG* {.threadvar.}: Peg PEG_USER_TAG* {.threadvar.}: Peg + PEG_INDEX* {.threadvar}: Peg + PEG_JSON_FIELD* {.threadvar.}: Peg PEG_DEFAULT_URL* {.threadvar.}: Peg PEG_URL* {.threadvar.}: Peg PEG_TAG = peg"""^\$? [a-zA-Z0-9_\-?~:.@#^!+]+$""" PEG_USER_TAG = peg"""^[a-zA-Z0-9_\-?~:.@#^!+]+$""" +PEG_INDEX = peg"""^[a-zA-Z0-9_]+$""" +PEG_JSON_FIELD = peg"""'$' ('.' [a-z-A-Z0-9_]+)+""" PEG_DEFAULT_URL = peg"""^\/{(docs / info / dir / tags / indexes)} (\/ {(.+)} / \/?)$""" PEG_URL = peg"""^\/({(v\d+)} \/) {([^\/]+)} (\/ {(.+)} / \/?)$"""