@athenna/database
Version:
The Athenna database handler for SQL/NoSQL.
78 lines (77 loc) • 2.84 kB
JavaScript
/**
* @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;
});
}
}