UNPKG

stackpress

Version:

Incept is a content management framework.

180 lines (179 loc) 6.22 kB
import Exception from '../Exception.js'; export const stringable = ['String', 'Text', 'Json', 'Object', 'Hash']; export const floatable = ['Number', 'Float']; export const dateable = ['Date', 'Time', 'Datetime']; export const boolable = ['Boolean']; export const intable = ['Integer']; export function toErrorResponse(e, code = 400) { if (typeof e.toResponse !== 'function') { e = Exception.upgrade(e, code); } const error = e; return error.toResponse(); } ; export function toResponse(results, total) { if (typeof total === 'number') { return { code: 200, status: 'OK', results, total: total }; } return { code: 200, status: 'OK', results }; } ; export function toSqlString(value, strict = false) { if (typeof value === 'undefined') { return (strict ? '' : undefined); } else if (value === null) { return (strict ? '' : null); } else if (typeof value === 'object') { return JSON.stringify(value); } return value.toString(); } export function toSqlBoolean(value, strict = false) { if (typeof value === 'undefined') { return (strict ? false : undefined); } else if (value === null) { return (strict ? false : null); } return Boolean(value); } export function toSqlDate(value, strict = false) { if (!strict) { if (typeof value === 'undefined') { return undefined; } else if (value === null) { return null; } } let date = value instanceof Date ? value : new Date(value); if (isNaN(date.getTime())) { date = new Date(0); } return date; } export function toSqlInteger(value, strict = false) { if (typeof value === 'undefined') { return (strict ? 0 : undefined); } else if (value === null) { return (strict ? 0 : null); } return (parseInt(value) || 0); } export function toSqlFloat(value, strict = false) { if (typeof value === 'undefined') { return (strict ? 0 : undefined); } else if (value === null) { return (strict ? 0 : null); } return (parseFloat(value) || 0); } export function sequence(models) { const sequence = []; while (sequence.length < models.length) { const floating = models.filter(model => !sequence.find(order => order.name === model.name)); for (const model of floating) { const dependents = floating.filter(float => float.relations .map(column => column.type) .find(table => table === model.name)); if (!dependents.length) { sequence.push(model); } } } return sequence; } export function getColumns(column, model, prefixes = []) { if (column === '*') { const columns = []; model.columns.forEach(column => { if (column.model) { return; } const prefix = prefixes.length > 0 ? prefixes.join('.') + '.' : ''; columns.push(`${prefix}${column.name}`); }); return columns; } const path = column.split('.'); if (path.length > 1) { const column = model.columns.get(path[0]); if (column && column.model) { return getColumns(path.slice(1).join('.'), column.model, [...prefixes, path[0]]); } } if (prefixes.length > 0) { return [`${prefixes.join('.')}.${column}`]; } return [column]; } export function getColumnInfo(selector, model) { const name = selector; const table = getAlias(selector.substring(0, selector.lastIndexOf('.'))); const column = getAlias(selector.substring(selector.lastIndexOf('.') + 1)); const alias = getAlias(selector); const path = getColumnPath(selector, model); const last = path[path.length - 1]; const joins = getColumnJoins(selector, model); return { name, table, column, alias, path, last, joins }; } export function getColumnPath(selector, model, path = []) { const selectors = selector.split('.'); const column = model.columns.get(selectors[0]); if (!column) { return []; } else if (selectors.length === 1) { return path.concat([{ model, column }]); } if (!column.model) { return []; } return getColumnPath(selectors.slice(1).join('.'), column.model, path.concat([{ model, column }])); } export function getColumnJoins(selector, model, index = 0, joins = {}) { const selectors = selector.split('.'); if (selectors.length === (index + 1)) { return joins; } const alias = { parent: getAlias(selectors.slice(0, index).join('.')), child: getAlias(selectors.slice(0, index + 1).join('.')) }; if (alias.parent.length > 0) { alias.parent += '.'; } const column = model.columns.get(selectors[index]); if (column?.relation) { const relation = column.relation; const table = relation.parent.model.snake; const from = `${alias.parent}${relation.child.key.snake}`; const to = `${alias.child}.${relation.parent.key.snake}`; const key = `INNER JOIN ${table} AS ${alias.child} ON (${from} = ${to})`; joins[key] = { table, from, to, alias: alias.child }; return getColumnJoins(selector, relation.parent.model, index + 1, joins); } else if (column?.related && !column?.related.parent.column.multiple) { const related = column.related; const table = related.child.model.snake; const aliasParent = alias.parent || `${related.parent.model.snake}.`; const from = `${aliasParent}${related.parent.key.snake}`; const to = `${alias.child}.${related.child.key.snake}`; const key = `INNER JOIN ${table} AS ${alias.child} ON (${from} = ${to})`; joins[key] = { table, from, to, alias: alias.child }; return getColumnJoins(selector, related.child.model, index + 1, joins); } return {}; } export function getAlias(selector) { return selector.split('.').map(part => part.trim() .replace(/([a-z])([A-Z0-9])/g, '$1_$2') .replace(/-{2,}/g, '_') .replace(/^_+|_+$/g, '') .toLowerCase()).join('__'); }