It seems to be working in a mock-environment

This commit is contained in:
2021-03-30 14:38:45 +11:00
parent f4dd51ac31
commit 0f653571d6
3 changed files with 160 additions and 27 deletions

View File

@@ -1,13 +1,20 @@
//mock tools
const Op = {
eq: 'eq'
};
const books = {
findAll: async args => {
let arr = [
{ title: 'The Wind in the Willows', published: '1908-06-15' }
{ id: 1, title: 'The Wind in the Willows', published: '1908-06-15' },
{ id: 2, title: 'The Fart in the Fronds', published: '1908-06-15' }
];
const { attributes, where } = args;
arr = arr.filter(el => !where || el.title == where.title || el.published == where.published); //TODO: fix this
//TODO: make this more generic
console.log('books attributes:', attributes);
console.log('books where', where);
return arr;
}
@@ -15,13 +22,16 @@ const books = {
const authors = {
findAll: async args => {
const arr = [
{ name: 'Kenneth Grahame', bookIds: [1] },
let arr = [
{ name: 'Kenneth Grahame', books: [1] },
{ name: 'Frank', books: [1, 2] },
{ name: 'Betty', books: [2] }
];
const { attributes, where } = args;
arr = arr.filter(el => !where || el.title == where.title || el.published == where.published); //TODO: fix this
console.log('authors attributes:', attributes);
console.log('authors where', where);
return arr;
}
@@ -51,59 +61,71 @@ const authors = {
//depth-first search seems to be the best option
//Each query shouldn't know if it's a sub-query
const handler = {
const queryHandlers = {
//complex compound
Author: async (query, graph) => {
//DEBUGGING
// console.log('Author():', query);
//get the fields alone
const { typeName, ...fields } = query;
//get the names of matched fields
const matchedNames = Object.keys(fields.filter(field => field.match));
const matchedNames = Object.keys(fields).filter(field => fields[field].match);
//short-circuit if querying everything
const where = {};
if (matchedNames.length > 0) {
//build the "where" object
matchedNames.forEach(mn => {
where[mn] = {
[Op.eq]: query[mn].match
if (query[mn].match !== true) {
where[mn] = { [Op.eq]: query[mn].match };
}
});
}
//these are field names
const scalars = Object.keys(fields).filter(field => graph[field.typeName].scalar);
const nonScalars = Object.keys(fields).filter(field => !graph[field.typeName].scalar);
const scalars = Object.keys(fields).filter(field => graph[fields[field].typeName].scalar);
const nonScalars = Object.keys(fields).filter(field => !graph[fields[field].typeName].scalar);
const results = await authors.findAll({
const authorResults = await authors.findAll({
attributes: scalars, //fields to find (keys)
where: where
}); //sequelize ORM model
nonScalars.forEach(nonScalar => {
const promiseArray = nonScalars.map(async nonScalar => {
//delegate to a deeper part of the tree
results[nonScalar] = handler[fields[nonScalar].typeName](fields[nonScalar], graph);
const nonScalarArray = await queryHandlers[fields[nonScalar].typeName](fields[nonScalar], graph);
//for each author, update this non-scalar field with the non-scalar's recursed value
authorResults.forEach(author => {
author[nonScalar] = nonScalarArray.filter(ns => author[nonScalar].includes(ns.id));
});
});
await Promise.all(promiseArray);
//finally, return the results
return results;
return authorResults;
},
//simple compound
Book: async (query, graph) => {
// console.log('Book():', query);
//get the fields alone
const { typeName, ...fields } = query;
//get the names of matched fields
const matchedNames = Object.keys(fields.filter(field => field.match));
const matchedNames = Object.keys(fields).filter(field => fields[field].match);
//short-circuit if querying everything
const where = {};
if (matchedNames.length > 0) {
//build the "where" object
matchedNames.forEach(mn => {
where[mn] = {
[Op.eq]: query[mn].match
if (query[mn].match !== true) {
where[mn] = { [Op.eq]: query[mn].match };
}
});
}
@@ -135,4 +157,10 @@ type Author {
const sineQL = require('../source/index.js');
//run the function in debug mode (builds type graph)
const sine = sineQL(schema, handler, { debug: true });
const sine = sineQL(schema, { queryHandlers }, { debug: true });
(async () => {
const [code, result] = await sine('Author { name match books { match title "The Wind in the Willows" published } }');
console.log('\n\n', JSON.stringify(result));
})();