@athenna/database
Version:
The Athenna database handler for SQL/NoSQL.
80 lines (79 loc) • 3.01 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 BelongsToRelation {
/**
* Get the options with defined default values.
*/
static options(relation) {
const RelationModel = relation.model();
relation.primaryKey =
relation.primaryKey || RelationModel.schema().getMainPrimaryKeyProperty();
relation.foreignKey =
relation.foreignKey || `${String.toCamelCase(RelationModel.name)}Id`;
return relation;
}
/**
* Load a belongs to relation.
*/
static async load(model, relation) {
this.options(relation);
model[relation.property] = await relation
.model()
.query()
.where(relation.primaryKey, model[relation.foreignKey])
.when(relation.withClosure, relation.withClosure)
.find();
return model;
}
/**
* Load all models that belongs to relation.
*/
static async loadAll(models, relation) {
this.options(relation);
const foreignValues = models.map(model => model[relation.foreignKey]);
const results = await relation
.model()
.query()
.whereIn(relation.primaryKey, foreignValues)
.when(relation.withClosure, relation.withClosure)
.findMany();
const map = new Map();
results.forEach(result => map.set(result[relation.primaryKey], result));
return models.map(model => {
model[relation.property] = map.get(model[relation.foreignKey]);
return model;
});
}
/**
* Apply a where has relation to the query when the relation
* is a belongs to the given model.
*/
static whereHas(Model, query, relation) {
const RelationModel = relation.model();
const modelSchema = Model.schema();
const relationSchema = RelationModel.schema();
const primaryKey = relation.primaryKey
? relationSchema.getColumnNameByProperty(relation.primaryKey)
: relationSchema.getMainPrimaryKeyName();
const foreignKey = relation.foreignKey
? modelSchema.getColumnNameByProperty(relation.foreignKey)
: modelSchema.getColumnNameByProperty(`${String.toCamelCase(RelationModel.name)}Id`);
let whereRaw = `${Model.table()}.${foreignKey} = ${RelationModel.table()}.${primaryKey}`;
switch (RelationModel.schema().getModelDriverName()) {
case 'sqlite':
case 'postgres':
whereRaw = `"${Model.table()}"."${foreignKey}" = "${RelationModel.table()}"."${primaryKey}"`;
}
RelationModel.query()
.setDriver(query, RelationModel.table())
.whereRaw(whereRaw)
.when(relation.closure, relation.closure);
}
}