diff --git a/src/index.js b/src/index.js index 2e77e71..0b50402 100644 --- a/src/index.js +++ b/src/index.js @@ -3,6 +3,7 @@ const assert = require("assert"); const matchValue = require("match-value"); const dbErrors = require("db-errors"); +const DataLoader = require("dataloader"); const knexIntrospect = require("./introspect"); const dataloaderFromKnexResults = require("./dataloader-from-knex-results"); @@ -94,8 +95,13 @@ module.exports = { }; }, generateModule: async function generate(globalKnex, tableName, relations = {}) { + // Make sure we only look up each table once, even when resolving relations + let introspectLoader = new DataLoader((tables) => { + return Promise.all(tables.map((table) => knexIntrospect(globalKnex, table))); + }); + // relations: { columnName: [ belongsTo, hasMany ] }, eg. on a posts table, it might have { thread_id: [ "thread", "posts" ] } - let tableLayout = await knexIntrospect(globalKnex, tableName); + let tableLayout = await introspectLoader.load(tableName); let fieldNames = Object.keys(tableLayout); let primaryKeyColumn = Object.values(tableLayout).find((props) => props.isPrimaryKey === true); @@ -161,7 +167,7 @@ module.exports = { for (let name of Object.keys(relations)) { let localField = relations[name][0]; // eg. "thread" let foreignKey = tableLayout[name].foreignKey; - let remoteTableLayout = await knexIntrospect(globalKnex, foreignKey.table); + let remoteTableLayout = await introspectLoader.load(foreignKey.table); if (remoteTableLayout[foreignKey.column].isPrimaryKey === true) { let field = [ localField, async function (_, { $make, $getProperty }) {