UNPKG

@codenameryuu/adonis-datatable

Version:
74 lines (73 loc) 2.83 kB
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; } }