@adonisjs/lucid
Version:
SQL ORM built on top of Active Record pattern
104 lines (103 loc) • 3.4 kB
JavaScript
/*
* @adonisjs/lucid
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { getValue, unique } from '../../../utils/index.js';
import { BaseQueryBuilder } from '../base/query_builder.js';
/**
* Extends the model query builder for executing queries in scope
* to the current relationship
*/
export class HasOneQueryBuilder extends BaseQueryBuilder {
parent;
relation;
appliedConstraints = false;
constructor(builder, client, parent, relation) {
super(builder, client, relation, (userFn) => {
return ($builder) => {
const subQuery = new HasOneQueryBuilder($builder, this.client, this.parent, this.relation);
subQuery.isChildQuery = true;
subQuery.isRelatedPreloadQuery = this.isRelatedPreloadQuery;
userFn(subQuery);
subQuery.applyWhere();
};
});
this.parent = parent;
this.relation = relation;
}
/**
* Profiler data for HasOne relationship
*/
profilerData() {
return {
type: this.relation.type,
model: this.relation.model.name,
relatedModel: this.relation.relatedModel().name,
};
}
/**
* The keys for constructing the join query
*/
getRelationKeys() {
return [this.relation.foreignKey];
}
/**
* Clones the current query
*/
clone() {
const clonedQuery = new HasOneQueryBuilder(this.knexQuery.clone(), this.client, this.parent, this.relation);
this.applyQueryFlags(clonedQuery);
clonedQuery.appliedConstraints = this.appliedConstraints;
clonedQuery.isRelatedPreloadQuery = this.isRelatedPreloadQuery;
clonedQuery.debug(this.debugQueries);
clonedQuery.reporterData(this.customReporterData);
return clonedQuery;
}
/**
* Applies constraint to limit rows to the current relationship
* only.
*/
applyConstraints() {
if (this.appliedConstraints) {
return;
}
this.appliedConstraints = true;
const queryAction = this.queryAction();
/**
* Eager query constraints
*/
if (Array.isArray(this.parent)) {
this.wrapExisting().whereIn(this.relation.foreignKey, unique(this.parent.map((model) => {
return getValue(model, this.relation.localKey, this.relation, queryAction);
})));
return;
}
/**
* Query constraints
*/
const value = getValue(this.parent, this.relation.localKey, this.relation, queryAction);
this.wrapExisting().where(this.relation.foreignKey, value);
/**
* Do not add limit when updating or deleting
*/
if (!['update', 'delete'].includes(queryAction)) {
this.limit(1);
}
}
/**
* Dis-allow hasOne pagination
*/
paginate() {
throw new Error(`Cannot paginate a hasOne relationship "(${this.relation.relationName})"`);
}
/**
* Dis-allow hasOne group query limit
*/
getGroupLimitQuery() {
throw new Error(`Cannot apply groupLimit or groupOrderBy on hasOne relationship "(${this.relation.relationName})"`);
}
}