-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdataTableQueryBuilder.js
More file actions
80 lines (70 loc) · 3.28 KB
/
dataTableQueryBuilder.js
File metadata and controls
80 lines (70 loc) · 3.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
module.exports = (Model) => {
return class DataTableQueryBuilder extends Model.QueryBuilder {
/**
* Used for querying data from database for the jquery datatable ajax call
* https://datatables.net/manual/server-side
* @param {object} options
* @param {Number} options.draw
* @param {Number} options.start
* @param {Number} options.length
* @param {object} options.search
* @param {string} options.search.value
* @param {boolean} options.search.regex
* @param {Array<{column: number, dir: string}>} options.order
* @param {Array<{data: string, name: string, searchable: boolean, orderable: boolean, search:{value: string,regex: boolean}}>} options.columns
*/
dataTable(options) {
let query = null;
// Destruct options object from request query
const {
columns = [],
order = [],
start = 0,
length = 10,
search = { value: '' },
// _,
} = options;
// Get table columns names
const tableColumns = Object.keys(this.modelClass().jsonSchema.properties);
// Get eager columns and filter them to existing relations only
const eagerColumnNames = columns
.filter(({ data }) => data in this.modelClass().relationMappings)
.map((col) => col.data);
// Get columns names from options and filter them to existing columns only
const columnsNames = columns
.map((column) => column.data)
.filter((column) => tableColumns.includes(column));
query = this.select(columnsNames); // select columns;
// Parse offset to Integer type
const offset = parseInt(start, 10);
// query = query.offset(offset).limit(length); // paging
const eager = `[${eagerColumnNames.join(',')}]`;
query = query.withGraphFetched(eager); // select with relations if requested too
// Serialize order for Query
const orders = order.map((orderObj) => {
return { column: columnsNames[orderObj.column], order: orderObj.dir };
});
query = query.orderBy(orders); // order by column
if (search && search.value) {
for (let i = 0, length = columnsNames.length; i < length; i++) {
if (i === 0) {
query = query.where(columnsNames[i], 'like', `%${search.value}%`);
} else {
query = query.orWhere(columnsNames[i], 'like', `%${search.value}%`);
}
}
}
if (length != -1) {
query
.limit(length) // return total length
.offset(offset);
}
// Return full query
query
.range()
.skipUndefined() // if a parameter if these functions is undefined it will be skipped
.throwIfNotFound(); // throws javascript error if no records returned
return this;
}
};
};