Work in progress on subscriptions
This commit is contained in:
parent
d9211377dd
commit
e73c0a8b28
42 changed files with 1558 additions and 678 deletions
|
@ -3,108 +3,106 @@
|
|||
const knex = require('../lib/knex');
|
||||
const permissions = require('../lib/permissions');
|
||||
|
||||
async function ajaxList(params, queryFun, columns, options) {
|
||||
async function ajaxListTx(tx, params, queryFun, columns, options) {
|
||||
options = options || {};
|
||||
|
||||
return await knex.transaction(async (tx) => {
|
||||
const columnsNames = [];
|
||||
const columnsSelect = [];
|
||||
|
||||
for (const col of columns) {
|
||||
if (typeof col === 'string') {
|
||||
columnsNames.push(col);
|
||||
columnsSelect.push(col);
|
||||
} else {
|
||||
columnsNames.push(col.name);
|
||||
|
||||
if (col.raw) {
|
||||
columnsSelect.push(tx.raw(col.raw));
|
||||
} else if (col.query) {
|
||||
columnsSelect.push(function () { return col.query(this); });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.operation === 'getBy') {
|
||||
const query = queryFun(tx);
|
||||
query.whereIn(columnsNames[parseInt(params.column)], params.values);
|
||||
query.select(columnsSelect);
|
||||
|
||||
const rows = await query;
|
||||
const rowsOfArray = rows.map(row => Object.keys(row).map(key => row[key]));
|
||||
return rowsOfArray;
|
||||
const columnsNames = [];
|
||||
const columnsSelect = [];
|
||||
|
||||
for (const col of columns) {
|
||||
if (typeof col === 'string') {
|
||||
columnsNames.push(col);
|
||||
columnsSelect.push(col);
|
||||
} else {
|
||||
const whereFun = function() {
|
||||
let searchVal = '%' + params.search.value.replace(/\\/g, '\\\\').replace(/([%_])/g, '\\$1') + '%';
|
||||
for (let colIdx = 0; colIdx < params.columns.length; colIdx++) {
|
||||
const col = params.columns[colIdx];
|
||||
if (col.searchable) {
|
||||
this.orWhere(columnsNames[parseInt(col.data)], 'like', searchVal);
|
||||
}
|
||||
}
|
||||
columnsNames.push(col.name);
|
||||
|
||||
if (col.raw) {
|
||||
columnsSelect.push(tx.raw(col.raw));
|
||||
} else if (col.query) {
|
||||
columnsSelect.push(function () { return col.query(this); });
|
||||
}
|
||||
|
||||
/* There are a few SQL peculiarities that make this query a bit weird:
|
||||
- Group by (which is used in getting permissions) don't go well with count(*). Thus we run the actual query
|
||||
as a sub-query and then count the number of results.
|
||||
- SQL does not like if it have columns with the same name in the subquery. This happens multiple tables are joined.
|
||||
To circumvent this, we select only the first column (whatever it is). Since this is not "distinct", it is supposed
|
||||
to give us the right number of rows anyway.
|
||||
*/
|
||||
const recordsTotalQuery = tx.count('* as recordsTotal').from(function () { return queryFun(this).select(columnsSelect[0]).as('records'); }).first();
|
||||
const recordsTotal = (await recordsTotalQuery).recordsTotal;
|
||||
|
||||
const recordsFilteredQuery = tx.count('* as recordsFiltered').from(function () { return queryFun(this).select(columnsSelect[0]).where(whereFun).as('records'); }).first();
|
||||
const recordsFiltered = (await recordsFilteredQuery).recordsFiltered;
|
||||
|
||||
const query = queryFun(tx);
|
||||
query.where(whereFun);
|
||||
|
||||
query.offset(parseInt(params.start));
|
||||
|
||||
const limit = parseInt(params.length);
|
||||
if (limit >= 0) {
|
||||
query.limit(limit);
|
||||
}
|
||||
|
||||
query.select(columnsSelect);
|
||||
|
||||
for (const order of params.order) {
|
||||
if (options.orderByBuilder) {
|
||||
options.orderByBuilder(query, columnsNames[params.columns[order.column].data], order.dir);
|
||||
} else {
|
||||
query.orderBy(columnsNames[params.columns[order.column].data], order.dir);
|
||||
}
|
||||
}
|
||||
|
||||
query.options({rowsAsArray:true});
|
||||
|
||||
const rows = await query;
|
||||
const rowsOfArray = rows.map(row => {
|
||||
const arr = Object.keys(row).map(field => row[field]);
|
||||
|
||||
if (options.mapFun) {
|
||||
const result = options.mapFun(arr);
|
||||
return result || arr;
|
||||
} else {
|
||||
return arr;
|
||||
}
|
||||
});
|
||||
|
||||
const result = {
|
||||
draw: params.draw,
|
||||
recordsTotal,
|
||||
recordsFiltered,
|
||||
data: rowsOfArray
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (params.operation === 'getBy') {
|
||||
const query = queryFun(tx);
|
||||
query.whereIn(columnsNames[parseInt(params.column)], params.values);
|
||||
query.select(columnsSelect);
|
||||
|
||||
const rows = await query;
|
||||
const rowsOfArray = rows.map(row => Object.keys(row).map(key => row[key]));
|
||||
return rowsOfArray;
|
||||
|
||||
} else {
|
||||
const whereFun = function() {
|
||||
let searchVal = '%' + params.search.value.replace(/\\/g, '\\\\').replace(/([%_])/g, '\\$1') + '%';
|
||||
for (let colIdx = 0; colIdx < params.columns.length; colIdx++) {
|
||||
const col = params.columns[colIdx];
|
||||
if (col.searchable) {
|
||||
this.orWhere(columnsNames[parseInt(col.data)], 'like', searchVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* There are a few SQL peculiarities that make this query a bit weird:
|
||||
- Group by (which is used in getting permissions) don't go well with count(*). Thus we run the actual query
|
||||
as a sub-query and then count the number of results.
|
||||
- SQL does not like if it have columns with the same name in the subquery. This happens multiple tables are joined.
|
||||
To circumvent this, we select only the first column (whatever it is). Since this is not "distinct", it is supposed
|
||||
to give us the right number of rows anyway.
|
||||
*/
|
||||
const recordsTotalQuery = tx.count('* as recordsTotal').from(function () { return queryFun(this).select(columnsSelect[0]).as('records'); }).first();
|
||||
const recordsTotal = (await recordsTotalQuery).recordsTotal;
|
||||
|
||||
const recordsFilteredQuery = tx.count('* as recordsFiltered').from(function () { return queryFun(this).select(columnsSelect[0]).where(whereFun).as('records'); }).first();
|
||||
const recordsFiltered = (await recordsFilteredQuery).recordsFiltered;
|
||||
|
||||
const query = queryFun(tx);
|
||||
query.where(whereFun);
|
||||
|
||||
query.offset(parseInt(params.start));
|
||||
|
||||
const limit = parseInt(params.length);
|
||||
if (limit >= 0) {
|
||||
query.limit(limit);
|
||||
}
|
||||
|
||||
query.select(columnsSelect);
|
||||
|
||||
for (const order of params.order) {
|
||||
if (options.orderByBuilder) {
|
||||
options.orderByBuilder(query, columnsNames[params.columns[order.column].data], order.dir);
|
||||
} else {
|
||||
query.orderBy(columnsNames[params.columns[order.column].data], order.dir);
|
||||
}
|
||||
}
|
||||
|
||||
query.options({rowsAsArray:true});
|
||||
|
||||
const rows = await query;
|
||||
const rowsOfArray = rows.map(row => {
|
||||
const arr = Object.keys(row).map(field => row[field]);
|
||||
|
||||
if (options.mapFun) {
|
||||
const result = options.mapFun(arr);
|
||||
return result || arr;
|
||||
} else {
|
||||
return arr;
|
||||
}
|
||||
});
|
||||
|
||||
const result = {
|
||||
draw: params.draw,
|
||||
recordsTotal,
|
||||
recordsFiltered,
|
||||
data: rowsOfArray
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
async function ajaxListWithPermissions(context, fetchSpecs, params, queryFun, columns, options) {
|
||||
async function ajaxListWithPermissionsTx(tx, context, fetchSpecs, params, queryFun, columns, options) {
|
||||
options = options || {};
|
||||
|
||||
const permCols = [];
|
||||
|
@ -121,7 +119,8 @@ async function ajaxListWithPermissions(context, fetchSpecs, params, queryFun, co
|
|||
});
|
||||
}
|
||||
|
||||
return await ajaxList(
|
||||
return await ajaxListTx(
|
||||
tx,
|
||||
params,
|
||||
builder => {
|
||||
let query = queryFun(builder);
|
||||
|
@ -163,7 +162,21 @@ async function ajaxListWithPermissions(context, fetchSpecs, params, queryFun, co
|
|||
);
|
||||
}
|
||||
|
||||
async function ajaxList(params, queryFun, columns, options) {
|
||||
return await knex.transaction(async tx => {
|
||||
return ajaxListTx(tx, params, queryFun, columns, options)
|
||||
});
|
||||
}
|
||||
|
||||
async function ajaxListWithPermissions(context, fetchSpecs, params, queryFun, columns, options) {
|
||||
return await knex.transaction(async tx => {
|
||||
return ajaxListWithPermissionsTx(tx, context, fetchSpecs, params, queryFun, columns, options)
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
ajaxListTx,
|
||||
ajaxList,
|
||||
ajaxListWithPermissionsTx,
|
||||
ajaxListWithPermissions
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue