"use strict"; const Promise = require("bluebird"); const memoizee = require("memoizee"); const DataLoader = require("dataloader"); const lvm = require("../wrappers/lvm"); const smartctl = require("../wrappers/smartctl"); const lsblk = require("../wrappers/lsblk"); const findmnt = require("../wrappers/findmnt"); const All = require("../graphql/symbols/all"); function linearizeDevices(devices) { let linearizedDevices = []; function add(list) { for (let device of list) { linearizedDevices.push(device); if (device.children != null) { add(device.children); } } } add(devices); return linearizedDevices; } module.exports = function createLoaders() { /* The below is to ensure that commands that produce a full list of all possible items, only ever get called and processed *once* per query, no matter what data is requested. */ let smartctlScanOnce = memoizee(smartctl.scan); let lvmGetPhysicalVolumesOnce = memoizee(lvm.getPhysicalVolumes); let lsblkOnce = memoizee(() => { return Promise.try(() => { return lsblk(); }).then((devices) => { return { tree: devices, list: linearizeDevices(devices) }; }); }); return { lsblk: new DataLoader((names) => { return Promise.try(() => { return lsblkOnce(); }).then(({tree, list}) => { return names.map((name) => { if (name === All) { return tree; } else { return list.find((device) => device.name === name); } }); }); }), smartctlScan: new DataLoader((paths) => { return Promise.try(() => { return smartctlScanOnce(); }).then((devices) => { return paths.map((path) => { if (path === All) { return devices; } else { return devices.find((device) => device.path === path); } }); }); }), smartctlInfo: new DataLoader((paths) => { return Promise.map(paths, (path) => { return smartctl.info({ devicePath: path }); }); }), smartctlAttributes: new DataLoader((paths) => { return Promise.map(paths, (path) => { return smartctl.attributes({ devicePath: path }); }); }), lvmPhysicalVolumes: new DataLoader((paths) => { return Promise.try(() => { return lvmGetPhysicalVolumesOnce(); }).then((volumes) => { return paths.map((path) => { if (path === All) { return volumes; } else { return volumes.find((device) => device.path === path); } }); }); }), }; };