UNPKG

@athenna/database

Version:

The Athenna database handler for SQL/NoSQL.

78 lines (77 loc) 2.84 kB
/** * @athenna/database * * (c) João Lenon <lenon@athenna.io> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ import { String } from '@athenna/common'; export class BelongsToManyRelation { /** * Get the options with defined default values. */ static options(relation) { const RelationModel = relation.model(); const PivotModel = relation.pivotModel(); relation.pivotTable = relation.pivotTable || PivotModel.table(); relation.relationPrimaryKey = RelationModel.schema().getMainPrimaryKeyProperty(); relation.relationForeignKey = `${String.toCamelCase(RelationModel.name)}Id`; return relation; } /** * Load a belongs to many relation. */ static async load(model, relation) { this.options(relation); const pivotData = await relation .pivotModel() .query() .where(relation.foreignKey, model[relation.primaryKey]) .findMany(); const relationIds = pivotData.map(d => d[relation.relationForeignKey]); model[relation.property] = await relation .model() .query() .whereIn(relation.relationPrimaryKey, relationIds) .when(relation.closure, relation.closure) .findMany(); return model; } /** * Load all models that belongs to relation. */ static async loadAll(models, relation) { this.options(relation); const primaryKeys = models.map(m => m[relation.primaryKey]); const pivotData = await relation .pivotModel() .query() .whereIn(relation.foreignKey, primaryKeys) .findMany(); const pivotDataMap = new Map(); const relationForeignKey = []; pivotData.forEach(data => { relationForeignKey.push(data[relation.relationForeignKey]); const array = pivotDataMap.get(data[relation.foreignKey]) || []; array.push(data[relation.relationForeignKey]); pivotDataMap.set(data[relation.foreignKey], array); }); const results = await relation .model() .query() .whereIn(relation.relationPrimaryKey, relationForeignKey) .when(relation.closure, relation.closure) .findMany(); const map = new Map(); results.forEach(result => map.set(result[relation.relationPrimaryKey], result)); return models.map(model => { const ids = pivotDataMap.get(model[relation.primaryKey]) || []; model[relation.property] = ids .map(id => map.get(id)) .filter(data => data !== undefined); return model; }); } }