'use strict'
const flow = require('an-flow')
// on ne peut pas mettre ces services en dépendance de $groupeRepository car ils sont déclarés après
let $ressourceRepository
let $personneRepository
module.exports = function (component) {
component.service('$groupeRepository', function (EntityGroupe, $cacheGroupe) {
/**
* @typedef groupesCallback
* @param {Error} [error]
* @param {Groupe[]} groupes
*/
/**
* Supprime un groupe (ET modifie les ressources liées)
* @param {string} nom
* @param {errorCallback} next
* @memberOf $groupeRepository
*/
function deleteGroupe (nom, next) {
// on affecte au 1er appel
if (!$ressourceRepository) $ressourceRepository = lassi.service('$ressourceRepository')
if (!$personneRepository) $personneRepository = lassi.service('$personneRepository')
flow().seq(function () {
// on efface d'abord le groupe des ressources
$ressourceRepository.removeGroup(nom, this)
}).seq(function () {
// puis des personnes
$personneRepository.removeGroup(nom, this)
}).seq(function () {
// on peut virer le groupe
EntityGroupe.match('nom').equals(nom).purge(this)
}).seq(function () {
// et on vire du cache
$cacheGroupe.delete(nom, next)
}).catch(next)
}
/**
* Récupère une liste de groupes
* @param {string[]} noms
* @param {groupesCallback} next
*/
function fetchListByNom (noms, next) {
if (!Array.isArray(noms) || !noms.length) return next(Error('noms invalides'))
const groupes = []
flow(noms).seqEach(function (nom) {
$cacheGroupe.getByNom(nom, this)
}).seq(function (cachedGroups) {
const missing = []
cachedGroups.forEach((groupe, index) => {
if (groupe) groupes.push(groupe)
else missing.push(noms[index])
})
if (!missing.length) return next(null, groupes)
EntityGroupe.match('nom').in(missing).grab(this)
}).seq(function (grps) {
next(null, groupes.concat(grps))
}).catch(next)
}
/**
* Récupère une liste de groupes dont le oid fourni est gestionnaire
* @param {string} oid
* @param {groupeListCallback} next
* @memberOf $groupeRepository
*/
function fetchListManagedBy (oid, next) {
EntityGroupe.match('gestionnaires').equals(oid).sort('nom').grab(next)
}
/**
* Récupère un groupe d'après son oip
* @param {string} groupeNom
* @param {groupeCallback} next
* @memberOf $groupeRepository
*/
function load (oid, next) {
$cacheGroupe.get(oid, function (error, groupe) {
if (error) return next(error)
if (groupe) return next(null, groupe)
// pas en cache, on va chercher en bdd
EntityGroupe.match('oid').equals(oid).grabOne(function (error, groupe) {
if (error) return next(error)
if (!groupe) return next()
$cacheGroupe.set(groupe)
next(null, groupe)
})
})
}
/**
* Récupère un groupe d'après son nom
* @param {string} nom
* @param {groupeCallback} next
* @memberOf $groupeRepository
*/
function loadByNom (nom, next) {
$cacheGroupe.getByNom(nom, function (error, groupe) {
if (error) log.error(error)
if (groupe) return next(null, groupe)
// pas en cache, on va chercher en bdd
EntityGroupe.match('nom').equals(nom).grabOne(function (error, groupe) {
if (error) return next(error)
if (!groupe) return next()
next(null, groupe)
$cacheGroupe.set(groupe)
})
})
}
/**
* Récupère tous les groupes ouverts
* @param {groupeCallback} next
* @memberOf $groupeRepository
*/
function loadOuvert (next) {
EntityGroupe.match('ouvert').equals(true).grab(function (error, groupes) {
if (error) return next(error)
next(null, groupes)
})
}
/**
* Récupère tous les groupes publics
* @param {groupeCallback} next
* @memberOf $groupeRepository
*/
function loadPublic (next) {
EntityGroupe.match('public').equals(true).grab(function (error, groupes) {
if (error) return next(error)
next(null, groupes)
})
}
/**
* Enregistre une groupe en bdd (et met à jour le cache)
* @param {EntityGroupe} groupe
* @param {entityPersonneCallback} next
* @memberOf $groupeRepository
*/
function save (groupe, next) {
if (!groupe.nom) return next(Error('Impossible d’enregistrer un groupe sans nom'))
if (!groupe.store) groupe = EntityGroupe.create(groupe)
// la mise en cache est dans afterStore de l'entity
groupe.store(next)
}
/**
* Service d'accès aux groupes utilisé par les différents contrôleurs
* @service $groupeRepository
*/
const $groupeRepository = {
delete: deleteGroupe,
fetchListByNom,
fetchListManagedBy,
load,
loadByNom,
loadOuvert,
loadPublic,
save
}
return $groupeRepository
})
}