const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; module.exports = Self => { Self.remoteMethod('getLeaves', { description: 'Returns the first shipped and landed possible for params', accessType: '', accepts: [{ arg: 'filter', type: 'Object', description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string', http: {source: 'query'} }, { arg: 'zoneFk', type: 'Number', required: true, }, { arg: 'parentFk', type: 'Number', default: 1, required: false, }], returns: { type: ['object'], root: true }, http: { path: `/getLeaves`, verb: 'GET' } }); Self.getLeaves = async(filter, zoneFk, parentFk = 1) => { let conn = Self.dataSource.connector; let stmts = []; stmts.push(new ParameterizedSQL( `SELECT lft, rgt, depth + 1 INTO @lft, @rgt, @depth FROM zoneTreeview WHERE id = ?`, [parentFk])); stmts.push(`DROP TEMPORARY TABLE IF EXISTS tChilds`); let stmt = new ParameterizedSQL( `CREATE TEMPORARY TABLE tChilds ENGINE = MEMORY SELECT id, lft, rgt FROM zoneTreeview pt`); stmt.merge(conn.makeSuffix(filter)); if (!filter.where) { stmt.merge(`WHERE pt.lft > @lft AND pt.rgt < @rgt AND pt.depth = @depth`); } stmts.push(stmt); stmts.push(`DROP TEMPORARY TABLE IF EXISTS tZones`); stmts.push(new ParameterizedSQL( `CREATE TEMPORARY TABLE tZones (INDEX (id)) ENGINE = MEMORY SELECT t.id FROM tChilds t JOIN zoneTreeview zt ON zt.lft > t.lft AND zt.rgt < t.rgt JOIN zoneIncluded zi ON zi.geoFk = zt.id AND zi.zoneFk = ? GROUP BY t.id`, [zoneFk])); const resultIndex = stmts.push(new ParameterizedSQL( `SELECT pt.id, pt.name, pt.lft, pt.rgt, pt.depth, pt.sons, ti.id IS NOT NULL hasCheckedChilds, zi.geoFk IS NOT NULL AS selected, zi.isIncluded AS excluded FROM zoneTreeview pt LEFT JOIN vn.zoneIncluded zi ON zi.geoFk = pt.id AND zi.zoneFk = ? JOIN tChilds c ON c.id = pt.id LEFT JOIN tZones ti ON ti.id = pt.id ORDER BY selected DESC, name`, [zoneFk])) - 1; const sql = ParameterizedSQL.join(stmts, ';'); const result = await Self.rawStmt(sql); return result[resultIndex]; }; };