@codenameryuu/adonis-datatable
Version:
Server side datatables package for Adonis JS
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;
}
}