add parseVars API

This commit is contained in:
jangko 2021-04-16 22:21:36 +07:00
parent 765c073fef
commit 4d67fd682c
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
8 changed files with 53 additions and 14 deletions

View File

@ -28,6 +28,8 @@ If you find anything not listed or not exported in this list, please submit an i
- `addVar(ctx: GraphqlRef, name: string)`. Add a `null` variable.
- `parseVar(ctx: GraphqlRef, name: string, value: string | openArray[byte]): ParseResult`. Add new variable to the system by parsing a text string.
- `parseVars(ctx: GraphqlRef, value: string | openArray[byte]): ParseResult`.
Add new variables to the system by parsing map. Top level keys will become variables name.
- `addResolvers(ctx: GraphqlRef, ud: RootRef, typeName: Name, resolvers: openArray[(string, ResolverProc)])`. Add a list of resolvers to the system.
- `addResolvers(ctx: GraphqlRef, ud: RootRef, typeName: string, resolvers: openArray[(string, ResolverProc)])`
- `createName(ctx: GraphqlRef, name: string): Name`. `respMap` will need a name from the system using this proc.

View File

@ -86,6 +86,7 @@ proc parseVariable(q: var Parser): Node =
nextToken
if currToken == tokEof:
return
rgReset(rgValueLiteral) # recursion guard
q.valueLiteral(isConst = true, result)
proc parseVariable(ctx: GraphqlRef, name: string, input: InputStream): GraphqlResult =
@ -109,6 +110,33 @@ proc parseVar*(ctx: GraphqlRef, name: string,
var stream = unsafeMemoryInput(value)
ctx.parseVariable(name, stream)
proc parseVars(ctx: GraphqlRef, input: InputStream): GraphqlResult =
var parser = Parser.init(input, ctx.names)
parser.lex.next()
if parser.lex.tok == tokEof:
return ok()
var values: Node
parser.rgReset(rgValueLiteral) # recursion guard
parser.valueLiteral(isConst = true, values)
if parser.error != errNone:
return err(@[parser.err])
for n in values:
ctx.varTable[n[0].name] = n[1]
ok()
proc parseVars*(ctx: GraphqlRef, input: string): GraphqlResult {.gcsafe.} =
{.gcsafe.}:
var stream = unsafeMemoryInput(input)
ctx.parseVars(stream)
proc parseVars*(ctx: GraphqlRef, input: openArray[byte]): GraphqlResult {.gcsafe.} =
{.gcsafe.}:
var stream = unsafeMemoryInput(input)
ctx.parseVars(stream)
proc addResolvers*(ctx: GraphqlRef, ud: RootRef, typeName: Name,
resolvers: openArray[tuple[name: string, resolver: ResolverProc]]) =
var res = ctx.resolver.getOrDefault(typeName)
@ -193,7 +221,8 @@ proc purgeQueries*(ctx: GraphqlRef, includeVariables: bool) =
if includeVariables:
ctx.varTable.clear()
proc purgeSchema*(ctx: GraphqlRef, includeScalars, includeResolvers: bool) =
proc purgeSchema*(ctx: GraphqlRef, includeScalars,
includeResolvers, includeCoercion: bool) =
var names = initHashSet[Name]()
for n, v in ctx.typeTable:
if sfBuiltin notin v.flags:
@ -214,6 +243,10 @@ proc purgeSchema*(ctx: GraphqlRef, includeScalars, includeResolvers: bool) =
for n in names:
ctx.resolver.del(n)
if includeCoercion:
for n in names:
ctx.coerceTable.del(n)
proc getNameCounter*(ctx: GraphqlRef): NameCounter =
ctx.names.getCounter()

View File

@ -86,6 +86,8 @@ proc jsonOkResp*(data: openArray[byte]): string =
resp.getString()
proc addVariables*(ctx: GraphqlRef, vars: Node) =
if vars.kind != nkInput:
return
for n in vars:
if n.len != 2: continue
# support both json/graphql object key
@ -102,8 +104,10 @@ proc parseLiteral(ctx: GraphqlRef, input: InputStream): ParseResult =
# we want to parse a json object
parser.flags.incl pfJsonCompatibility
parser.lex.next()
if parser.lex.tok == tokEof:
return ok(ctx.emptyNode)
parser.rgReset(rgValueLiteral) # recursion guard
parser.valueLiteral(true, values)
parser.valueLiteral(isConst = true, values)
if parser.error != errNone:
return err(@[parser.err])
ok(values)

View File

@ -482,7 +482,7 @@ proc coerceEnum(ctx: GraphqlRef, typeNode, node: Node): NodeResult {.cdecl, gcsa
if node.kind == nkString:
ok(Node(kind: nkEnum, name: ctx.createName(node.stringVal), pos: node.pos))
else:
err("cannot coerce '$1' to $2" % [$node.kind, $typeNode.sym.name])
err("cannot coerce '$1' to $2" % [$node.kind, $typeNode])
{.pop.}

View File

@ -93,7 +93,7 @@ proc runSuite(ctx: GraphqlRef, savePoint: NameCounter, fileName: string, counter
else:
ctx.runExecutor(unit, testStatusIMPL)
ctx.purgeQueries(false)
ctx.purgeSchema(false, false)
ctx.purgeSchema(false, false, false)
ctx.purgeNames(savePoint)
if testStatusIMPL == OK:
inc counter.ok
@ -133,7 +133,7 @@ when isMainModule:
test unit.name:
ctx.runExecutor(unit, testStatusIMPL)
ctx.purgeQueries(true)
ctx.purgeSchema(true, true)
ctx.purgeSchema(true, true, false)
ctx.purgeNames(savePoint)
var message: string

View File

@ -133,7 +133,7 @@ proc runSuite(ctx: GraphqlRef, savePoint: NameCounter, fileName: string, counter
else:
ctx.runExecutor(unit, testStatusIMPL)
ctx.purgeQueries(false)
ctx.purgeSchema(false, false)
ctx.purgeSchema(false, false, false)
ctx.purgeNames(savePoint)
if testStatusIMPL == OK:
inc counter.ok
@ -175,7 +175,7 @@ when isMainModule:
test unit.name:
ctx.runExecutor(unit, testStatusIMPL)
ctx.purgeQueries(true)
ctx.purgeSchema(true, true)
ctx.purgeSchema(true, true, true)
ctx.purgeNames(savePoint)
var message: string

View File

@ -15,7 +15,7 @@ const
schemaFolder = "tests" / "schemas"
introsFolder = "tests" / "introspection"
proc runValidator(ctx: GraphqlRef, fileName: string, testStatusIMPL: var TestStatus) =
proc runValidator(ctx: GraphqlRef, fileName: string, testStatusIMPL: var TestStatus) =
var res = ctx.parseSchemaFromFile(fileName)
check res.isOk
if res.isErr:
@ -45,7 +45,7 @@ proc runValidator(ctx: GraphqlRef, fileName: string, testStatusIMPL: var TestSta
check ($jsonRes).len != 0
except:
check false
proc main() =
suite "schema introspection validation":
var ctx = new(GraphqlRef)
@ -57,7 +57,7 @@ proc main() =
let parts = splitFile(fileName)
test parts.name:
ctx.runValidator(fileName, testStatusIMPL)
ctx.purgeSchema(true, true)
ctx.purgeSchema(true, true, true)
ctx.purgeQueries(true)
ctx.purgeNames(savePoint)

View File

@ -101,7 +101,7 @@ proc runConverter(ctx: GraphqlRef, savePoint: NameCounter, path, output: string)
for unit in mitems(cases.units):
ctx.runConverter(unit)
ctx.purgeQueries(false)
ctx.purgeSchema(false, false)
ctx.purgeSchema(false, false, false)
ctx.purgeNames(savePoint)
writeUnit(f, unit)
@ -141,7 +141,7 @@ proc runSuite(ctx: GraphqlRef, savePoint: NameCounter, fileName: string, counter
else:
ctx.runValidator(unit, testStatusIMPL)
ctx.purgeQueries(false)
ctx.purgeSchema(false, false)
ctx.purgeSchema(false, false, false)
ctx.purgeNames(savePoint)
if testStatusIMPL == OK:
inc counter.ok
@ -183,7 +183,7 @@ proc validateSchemas() =
test fileName:
ctx.runValidator(fileName, testStatusIMPL)
ctx.purgeQueries(true)
ctx.purgeSchema(true, true)
ctx.purgeSchema(true, true, true)
ctx.purgeNames(savePoint)
when isMainModule:
@ -217,7 +217,7 @@ when isMainModule:
test unit.name:
ctx.runValidator(unit, testStatusIMPL)
ctx.purgeQueries(true)
ctx.purgeSchema(true, true)
ctx.purgeSchema(true, true, true)
ctx.purgeNames(savePoint)
var message: string