Expose structure introspection

This commit is contained in:
Sven Slootweg 2024-07-01 22:49:47 +02:00
parent ebff1b3cbb
commit 3898211992

View file

@ -113,6 +113,11 @@ module.exports = {
let typeName = `dlayer-knex.${tableName}`;
let remoteTypes = {};
// Tracking the generated structure for static introspection purposes
let structure = {
[typeName]: tableLayout
};
Object.keys(relations).map((idFieldName) => {
let remoteField = relations[idFieldName][1]; // eg. "posts"
@ -122,7 +127,20 @@ module.exports = {
if (remoteTypes[remoteTypeName] == null) {
remoteTypes[remoteTypeName] = {};
}
if (structure[remoteTypeName] == null) {
structure[remoteTypeName] = {};
}
structure[remoteTypeName][remoteField] = {
name: remoteField,
type: "ref",
refTable: tableName,
refColumn: idFieldName,
sourceTable: foreignKey.table,
sourceColumn: foreignKey.column,
};
remoteTypes[remoteTypeName][remoteField] = async function(_, { $make, $getProperty, knex }) {
let tx = (knex ?? globalKnex);
@ -137,9 +155,38 @@ module.exports = {
});
};
});
let selfRelationFields = [];
for (let name of Object.keys(relations)) {
let localField = relations[name][0]; // eg. "thread"
let foreignKey = tableLayout[name].foreignKey;
let remoteTableLayout = await introspectLoader.load(foreignKey.table);
if (remoteTableLayout[foreignKey.column].isPrimaryKey === true) {
let field = [ localField, async function (_, { $make, $getProperty }) {
return $make(`dlayer-knex.${foreignKey.table}`, { id: await $getProperty(this, name) })
}];
selfRelationFields.push(field);
structure[typeName][localField] = {
name: localField,
type: "ref",
refTable: tableName,
refColumn: name,
sourceTable: foreignKey.table,
sourceColumn: foreignKey.column
};
} else {
// TODO: Throw error instead?
console.warn(`Foreign key points at column ${foreignKey.table}.${foreignKey.column}, but that column is not a primary key, and this is not supported in dlayer-knex yet`);
}
}
return {
typeName: typeName,
structure: structure,
module: {
name: `knex.${tableName}`,
makeContext: (globalContext) => {
@ -167,28 +214,9 @@ module.exports = {
}
});
let relationFields = [];
for (let name of Object.keys(relations)) {
let localField = relations[name][0]; // eg. "thread"
let foreignKey = tableLayout[name].foreignKey;
let remoteTableLayout = await introspectLoader.load(foreignKey.table);
if (remoteTableLayout[foreignKey.column].isPrimaryKey === true) {
let field = [ localField, async function (_, { $make, $getProperty }) {
return $make(`dlayer-knex.${foreignKey.table}`, { id: await $getProperty(this, name) })
}];
relationFields.push(field);
} else {
// TODO: Throw error instead?
console.warn(`Foreign key points at column ${foreignKey.table}.${foreignKey.column}, but that column is not a primary key, and this is not supported in dlayer-knex yet`);
}
}
return Object.fromEntries([
... normalFields,
... relationFields
... selfRelationFields
]);
// determine primary key field, use that as the ID attribute? then use dataloader for fetching different items, and use the same dataloader instance as a cache
}