From a8d9f36b347c59c530f7563298e18543a8ba3a41 Mon Sep 17 00:00:00 2001 From: kitsunecafe Date: Mon, 25 Nov 2024 09:24:20 -0600 Subject: [PATCH] perform from check in relationship query --- src/query.js | 24 +++++------------------- tests/query.test.js | 44 ++++++++++++++++++++++---------------------- 2 files changed, 27 insertions(+), 41 deletions(-) diff --git a/src/query.js b/src/query.js index 4b0ff62..32243ba 100644 --- a/src/query.js +++ b/src/query.js @@ -34,10 +34,10 @@ const hasComponents = (world, types, entity) => ( types.every(type => hasComponent(world, type, entity)) ) -const matches = (world, types, set = new Set()) => entity => { +const matches = (world, types, results, set = new Set()) => entity => { if (set.has(entity)) { return true - } else if (hasComponents(world, types, entity)) { + } else if (hasComponents(world, types, entity) && (results == null || results.includes(entity))) { set.add(entity) return true } else { @@ -51,23 +51,15 @@ const queryRelationship = (query, world) => { return node.relationship ? node.from : node }) - const matchesFrom = matches(world, from.components.map(prop('type'))) + const matchesFrom = matches(world, from.components.map(prop('type')), from.query(world)) const matchesTo = matches(world, to.components.map(prop('type'))) const Edge = edge.components[0].type - // FIXME: filter these to make sure the from components match the previous edge's to components const edges = edge.query(world) - console.log('59', edges) const result = [] for (let i = 0; i < edges.length; i++) { const eid = edges[i] - if (matchesFrom(Edge.from[eid])) { - console.log('65', eid, from.components.map(({ name, label }) => ({ name, label }))) - if (matchesTo(Edge.to[eid])) { - console.log('67', eid, to.components.map(({ name, label }) => ({ name, label }))) - } - } if (matchesFrom(Edge.from[eid]) && matchesTo(Edge.to[eid])) { result.push(eid) } @@ -84,7 +76,6 @@ const executeQuery = curry((query, world) => { } const edges = queryRelationship(query, world) - console.log('80', query.from.components, edges) if (query.to.relationship) { return edges.reduce((acc, eid) => { @@ -94,12 +85,10 @@ const executeQuery = curry((query, world) => { query.to ) - const a = executeQuery(next, world) + return executeQuery(next, world) .map(child => [eid, ...child]) .map(([l, r]) => [{ entity: l, query }, r]) - //.concat(acc) - console.log(a) - return a.concat(acc) + .concat(acc) }, []) } else { return assembleQuery(query, edges) @@ -162,11 +151,8 @@ export const query = curry((input, { world, component }) => { return parseAll(q, input).map(({ use, ...rest }) => { const useWorld = world[use?.value ?? 'default'] const preparedQuery = prepareQuery(rest, component) - //console.log('prepared', preparedQuery) const results = executeQuery(preparedQuery, useWorld) - //console.log('results', results) const returns = resolveReturns(results) - //console.log('returns', returns) return returns }) }) diff --git a/tests/query.test.js b/tests/query.test.js index 4d1ca24..faa440f 100644 --- a/tests/query.test.js +++ b/tests/query.test.js @@ -53,18 +53,18 @@ describe('query', () => { relate(world, b, Knows, a) // 9 relate(world, c, Knows, player) // 10 - //assert.deepEqual( - // query('MATCH (player:Player) RETURN player', engine).unwrap(), - // [{ player: {} }] - //) + assert.deepEqual( + query('MATCH (player:Player) RETURN player', engine).unwrap(), + [{ player: {} }] + ) - //assert.deepEqual( - // query('MATCH (player:Player)-[e1:Knows]->(a:NPC) RETURN player, e1, a', engine).unwrap(), - // [ - // { player: {}, e1: { from: 0, to: 1 }, a: {} }, - // { player: {}, e1: { from: 0, to: 3 }, a: {} } - // ] - //) + assert.deepEqual( + query('MATCH (player:Player)-[e1:Knows]->(a:NPC) RETURN player, e1, a', engine).unwrap(), + [ + { player: {}, e1: { from: 0, to: 1 }, a: {} }, + { player: {}, e1: { from: 0, to: 3 }, a: {} } + ] + ) assert.deepEqual( query('MATCH (player:Player)-[e1:Knows]->(a:NPC)-[e2:Knows]->(b:NPC) RETURN player, e1, a, e2, b', engine).unwrap(), @@ -75,17 +75,17 @@ describe('query', () => { ) }) - //it('should match multiple components', () => { - // const world = engine.world.default - // const { Player, Health } = engine.component - // const player = create(world, Player, Health) + it('should match multiple components', () => { + const world = engine.world.default + const { Player, Health } = engine.component + const player = create(world, Player, Health) - // Health.max[player] = 50 - // Health.current[player] = 25 - // assert.deepEqual( - // query('MATCH (e:Entity, h:Health) return e, h.max', engine).unwrap(), - // [{ e: 11, h: { current: 25, max: 50 } }] - // ) - //}) + Health.max[player] = 50 + Health.current[player] = 25 + assert.deepEqual( + query('MATCH (e:Entity, h:Health) return e, h.max', engine).unwrap(), + [{ e: 11, h: { current: 25, max: 50 } }] + ) + }) })