Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save flancer64/5e36c289a4a412eb5e29863bd359152c to your computer and use it in GitHub Desktop.
Save flancer64/5e36c289a4a412eb5e29863bd359152c to your computer and use it in GitHub Desktop.
The template for a RDB query to compose the list of items for a grid on the UI
/**
* RDB query builder to select data for the customers list.
*
* @implements TeqFw_Db_Back_Api_RDb_Query_List
*/
export default class App_Back_Web_Api_Entity_List_A_Query {
/**
* @param {TeqFw_Db_Back_RDb_IConnect} conn
* @param {Lp_Base_Back_App_Db_Util_ListQuery} utilListQuery
* @param {App_Back_Store_RDb_Schema_Password} rdbPassword
* @param {App_Back_Store_RDb_Schema_User} rdbUser
* @param {App_Back_Store_RDb_Schema_User_Customer} rdbCust
* @param {App_Back_Store_RDb_Schema_Visit} rdbVisit
* @param {App_Shared_Dto_Customer_List_Item} dtoItem
*/
constructor(
{
TeqFw_Db_Back_RDb_IConnect$: conn,
Lp_Base_Back_App_Db_Util_ListQuery$: utilListQuery,
App_Back_Store_RDb_Schema_Password$: rdbPassword,
App_Back_Store_RDb_Schema_User$: rdbUser,
App_Back_Store_RDb_Schema_User_Customer$: rdbCust,
App_Back_Store_RDb_Schema_Visit$: rdbVisit,
App_Shared_Dto_Customer_List_Item$: dtoItem,
}
) {
// VARS
const {prepareGroupBy, prepareSelect} = utilListQuery;
const A_CUST = rdbCust.getAttributes();
const A_PASS = rdbPassword.getAttributes();
const A_USER = rdbUser.getAttributes();
const A_VISIT = rdbVisit.getAttributes();
const knex = conn.getKnex();
/**
* Aliases for the columns in the query.
* @memberof App_Back_Web_Api_Entity_List_A_Query
*/
const COL = dtoItem.getAttributes();
Object.freeze(COL);
/**
* Map for tables aliases in the query.
* @type {Object}
* @memberOf App_Back_Web_Api_Entity_List_A_Query
*/
const TBL = {
CUST: 'c',
PASS: 'p',
USER: 'u',
VISIT: 'v',
};
Object.freeze(TBL);
/**
* The map associates query columns with 'table.field' pairs.
* @type {Object<string, string>}
*/
const MAP_FLD = {
[COL.BID]: `${TBL.CUST}.${A_CUST.USER_REF}`,
[COL.DATE_CREATED]: `${TBL.USER}.${A_USER.DATE_CREATED}`,
[COL.DATE_LAST]: `${TBL.USER}.${A_USER.DATE_LAST}`,
[COL.EMAIL]: `${TBL.PASS}.${A_PASS.EMAIL}`,
[COL.NAME]: `${TBL.CUST}.${A_CUST.NAME}`,
[COL.UUID]: `${TBL.USER}.${A_USER.UUID}`,
};
// Object.freeze(MAP_FLD); - we don't use this object outside this es-module
/**
* The map associates aggregated query columns with SQL expressions.
* @type {Object<string, string>}
*/
const MAP_AGG = {
[COL.VISITS]: knex.raw(`COUNT(${TBL.VISIT}.${A_VISIT.BID})`),
};
const MAP = Object.assign({}, MAP_FLD, MAP_AGG);
// FUNCS
/**
* Construct base query w/o columns (just joins).
* @param {TeqFw_Db_Back_RDb_ITrans} trx
* @return {Knex.QueryBuilder}
*/
function init(trx) {
// VARS
/* knex related objects */
const tCust = {[TBL.CUST]: trx.getTableName(rdbCust)};
const tPass = {[TBL.PASS]: trx.getTableName(rdbPassword)};
const tUser = {[TBL.USER]: trx.getTableName(rdbUser)};
const tVisit = {[TBL.VISIT]: trx.getTableName(rdbVisit)};
// MAIN
/** @type {Knex.QueryBuilder} */
const res = trx.createQuery();
// main table
res.table(tCust);
// join another table
res.leftJoin(tPass, `${TBL.PASS}.${A_PASS.USER_REF}`, `${TBL.CUST}.${A_CUST.USER_REF}`);
// join another table
res.leftJoin(tUser, `${TBL.USER}.${A_USER.BID}`, `${TBL.CUST}.${A_CUST.USER_REF}`);
// join another table
res.leftJoin(tVisit, `${TBL.VISIT}.${A_VISIT.CUSTOMER_REF}`, `${TBL.CUST}.${A_CUST.USER_REF}`);
return res;
}
// INSTANCE METHODS
this.build = function (trx, opts) {
const res = init(trx);
res.select(prepareSelect(COL, MAP));
res.groupBy(prepareGroupBy(COL, MAP_FLD));
return res;
};
this.buildCount = function (trx, {bid}) {
const res = init(trx);
res.select([{total: trx.raw(`COUNT(*)`)}]);
return res;
};
/**
* Get query columns (the aliases for the select clause).
* @return {typeof App_Shared_Dto_Customer_List_Item.ATTR}
*/
this.getColumns = () => COL;
/**
* Get aliases for the query tables.
* @returns {typeof App_Back_Web_Api_Entity_List_A_Query.TBL}
*/
this.getTables = () => TBL;
/**
* Map query columns to the 'table.field' pairs or expressions.
* @param {string} col
*/
this.mapColumn = function (col) {
return MAP_FLD[col] ?? MAP_AGG[col];
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment