@codenameryuu/adonis-datatable
Version:
Package server side datatables on AdonisJS 6
74 lines (73 loc) • 2.83 kB
JavaScript
import { ModelQueryBuilder } from '@adonisjs/lucid/orm';
import lodash from 'lodash';
import { Exception } from '@adonisjs/core/exceptions';
import DatabaseDataTable from './database_datatable.js';
export default class LucidDataTable extends DatabaseDataTable {
query;
constructor(query) {
super(query);
this.query = query;
}
compileQuerySearch(query, columnName, keyword, boolean = 'or') {
const parts = columnName.split('.');
const column = parts.pop();
const relation = parts.join('.');
if (this.isNotEagerLoaded(relation)) {
return super.compileQuerySearch(query, columnName, keyword, boolean);
}
const method = lodash.lowerFirst(`${boolean}WhereHas`);
query[method](relation, (model) => {
super.compileQuerySearch(model, column, keyword, '');
});
}
isNotEagerLoaded(relation) {
return (relation === '' ||
!Object.keys(Object.fromEntries(this.query.model['$relationsDefinitions'])).includes(relation) ||
relation === this.query.model.name);
}
resolveRelationColumn(column) {
const parts = column.split('.');
const columnName = parts.pop();
const relation = parts.join('.');
if (this.isNotEagerLoaded(relation)) {
return column;
}
return this.joinEagerLoadedColumn(relation, columnName);
}
joinEagerLoadedColumn(relation, relationColumn) {
let tableName = '';
let foreignKey;
let ownerKey;
let lastQuery = this.query;
const relations = relation.split('.');
for (const eachRelation of Object.values(relations)) {
const model = lastQuery.model.$getRelation(eachRelation);
switch (true) {
case model.type === 'belongsTo':
tableName = model.relatedModel().table;
foreignKey = `${this.query.model.table}.${model.foreignKeyColumnName}`;
ownerKey = `${tableName}.${model.localKeyColumnName}`;
break;
default:
throw new Exception(`Relation ${eachRelation} is not yet supported.`);
}
this.performJoin(tableName, foreignKey, ownerKey);
lastQuery = this.query;
}
return `${tableName}.${relationColumn}`;
}
performJoin(table, foreign, other) {
this.getBaseQueryBuilder().leftJoin(table, foreign, '=', other);
}
getPrimaryKeyName() {
return this.query.model.primaryKey;
}
static canCreate(source) {
return source instanceof ModelQueryBuilder;
}
async count() {
const builder = this.query.clone();
const result = await builder.exec();
return result.length;
}
}