add support for searching queries
This commit is contained in:
@ -142,6 +142,76 @@ let def: SystemDef = {
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
component: 'task',
|
||||||
|
table: 'task',
|
||||||
|
type: 'search',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
table: 'task'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'description',
|
||||||
|
table: 'task'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'completed',
|
||||||
|
table: 'task'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'completed_date',
|
||||||
|
table: 'task'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
orderBy: [
|
||||||
|
{
|
||||||
|
column: {
|
||||||
|
name: 'modified',
|
||||||
|
table: 'task'
|
||||||
|
},
|
||||||
|
direction: 'desc'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
param: 'list',
|
||||||
|
column: {
|
||||||
|
name: 'list_id',
|
||||||
|
table: 'task'
|
||||||
|
},
|
||||||
|
comparison: '=',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
param: 'completed',
|
||||||
|
column: {
|
||||||
|
name: 'completed',
|
||||||
|
table: 'task'
|
||||||
|
},
|
||||||
|
comparison: '=',
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
param: 'name',
|
||||||
|
column: {
|
||||||
|
name: 'name',
|
||||||
|
table: 'task'
|
||||||
|
},
|
||||||
|
comparison: 'LIKE',
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
param: 'description',
|
||||||
|
column: {
|
||||||
|
name: 'description',
|
||||||
|
table: 'task'
|
||||||
|
},
|
||||||
|
comparison: 'LIKE',
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
component: 'task',
|
component: 'task',
|
||||||
table: 'task',
|
table: 'task',
|
||||||
|
@ -67,7 +67,7 @@ interface Order {
|
|||||||
interface Filter {
|
interface Filter {
|
||||||
param: string; // the query param used to get the value
|
param: string; // the query param used to get the value
|
||||||
column: ColumnRef;
|
column: ColumnRef;
|
||||||
comparison: '=' | '!=' | '>' | '<' | 'contains';
|
comparison: '=' | '!=' | '>' | '<' | 'contains' | 'LIKE';
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,8 @@ function createMapperFunc(view: EndpointDef): string {
|
|||||||
let func: string = '';
|
let func: string = '';
|
||||||
if (view.type === 'list' || view.type === 'count') {
|
if (view.type === 'list' || view.type === 'count') {
|
||||||
func = buildGetList(view);
|
func = buildGetList(view);
|
||||||
|
} else if (view.type === 'search') {
|
||||||
|
func = buildGetList(view, true);
|
||||||
} else if (view.type === 'item') {
|
} else if (view.type === 'item') {
|
||||||
func = buildGetItem(view);
|
func = buildGetItem(view);
|
||||||
} else if (view.type === 'update') {
|
} else if (view.type === 'update') {
|
||||||
@ -22,10 +24,7 @@ function buildDeleteItem(view: EndpointDef): string {
|
|||||||
let func: string = '';
|
let func: string = '';
|
||||||
let funcName = buildFunctionName(view);
|
let funcName = buildFunctionName(view);
|
||||||
let tables: string = `${view.table}`;
|
let tables: string = `${view.table}`;
|
||||||
let filtersObj = buildFilters(view);
|
let {filters, requiredQueryValues, optionalFilterParts} = constructFilters(view);
|
||||||
let filters: string = filtersObj.filters;
|
|
||||||
let requiredFilterValues: string = filtersObj.requiredFilterValues;
|
|
||||||
let optionalFilterParts = filtersObj.optionalFiltersCode;
|
|
||||||
let query: string = `DELETE FROM ${tables}${filters}`;
|
let query: string = `DELETE FROM ${tables}${filters}`;
|
||||||
let funcParams = 'params: {[key: string]: string}';
|
let funcParams = 'params: {[key: string]: string}';
|
||||||
|
|
||||||
@ -33,7 +32,7 @@ function buildDeleteItem(view: EndpointDef): string {
|
|||||||
public ${funcName}(${funcParams}) {
|
public ${funcName}(${funcParams}) {
|
||||||
|
|
||||||
let query: string = '${query}';
|
let query: string = '${query}';
|
||||||
let queryValues: string[] = [${requiredFilterValues}];
|
let queryValues: string[] = [${requiredQueryValues}];
|
||||||
|
|
||||||
// optional params?
|
// optional params?
|
||||||
${optionalFilterParts}
|
${optionalFilterParts}
|
||||||
@ -49,10 +48,7 @@ function buildGetItem(view: EndpointDef): string {
|
|||||||
let funcName = buildFunctionName(view);
|
let funcName = buildFunctionName(view);
|
||||||
let columns: string = `${view.component}.${view.component}_id, ${view.columns.map(c => `${c.table}.${c.name}`).join(', ')}`;
|
let columns: string = `${view.component}.${view.component}_id, ${view.columns.map(c => `${c.table}.${c.name}`).join(', ')}`;
|
||||||
let tables: string = view.join?.length ? buildJoin(view) : `${view.table}`;
|
let tables: string = view.join?.length ? buildJoin(view) : `${view.table}`;
|
||||||
let filtersObj = buildFilters(view);
|
let {filters, requiredQueryValues, optionalFilterParts} = constructFilters(view);
|
||||||
let filters: string = filtersObj.filters;
|
|
||||||
let requiredFilterValues: string = filtersObj.requiredFilterValues;
|
|
||||||
let optionalFilterParts = filtersObj.optionalFiltersCode;
|
|
||||||
let query: string = `SELECT ${columns} FROM ${tables}${filters} LIMIT 1`;
|
let query: string = `SELECT ${columns} FROM ${tables}${filters} LIMIT 1`;
|
||||||
let funcParams = 'params: {[key: string]: string}';
|
let funcParams = 'params: {[key: string]: string}';
|
||||||
|
|
||||||
@ -60,7 +56,7 @@ function buildGetItem(view: EndpointDef): string {
|
|||||||
public ${funcName}(${funcParams}) {
|
public ${funcName}(${funcParams}) {
|
||||||
|
|
||||||
let query: string = '${query}';
|
let query: string = '${query}';
|
||||||
let queryValues: string[] = [${requiredFilterValues}];
|
let queryValues: string[] = [${requiredQueryValues}];
|
||||||
|
|
||||||
// optional params?
|
// optional params?
|
||||||
${optionalFilterParts}
|
${optionalFilterParts}
|
||||||
@ -128,17 +124,8 @@ function getCreateOrUpdateFunc(query: string, view: EndpointDef): string {
|
|||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildGetList(view: EndpointDef): string {
|
function constructFilters(view: EndpointDef, isSearch=false) {
|
||||||
// TODO: optionally allow a raw query definition with predefined params
|
|
||||||
// This would be so much simpler and easy if it were just the queries wanted
|
|
||||||
let func: string = '';
|
|
||||||
let funcName: string = '';
|
|
||||||
let columns: string = view.type === 'count' ? `count(*)` : `${view.component}.${view.component}_id, ${view.columns.map(c => `${c.table}.${c.name}`).join(', ')}`;
|
|
||||||
let query: string = '';
|
|
||||||
let tables: string = view.join?.length ? buildJoin(view) : `${view.table}`;
|
|
||||||
let filters: string = '';
|
let filters: string = '';
|
||||||
funcName = buildFunctionName(view);
|
|
||||||
|
|
||||||
let requiredFilterStrings = [];
|
let requiredFilterStrings = [];
|
||||||
let requiredQueryValues = '';
|
let requiredQueryValues = '';
|
||||||
let optionalFilterParts = '';
|
let optionalFilterParts = '';
|
||||||
@ -160,13 +147,27 @@ function buildGetList(view: EndpointDef): string {
|
|||||||
*/
|
*/
|
||||||
optionalFilterParts = optionalFilterParts + `
|
optionalFilterParts = optionalFilterParts + `
|
||||||
if (params.${f.param}) {
|
if (params.${f.param}) {
|
||||||
query = query + ' AND ${f.column.table}.${f.column.name} ${f.comparison} ?';
|
query = query + ' ${isSearch ? 'OR' : 'AND'} ${f.column.table}.${f.column.name} ${isSearch ? 'LIKE' : f.comparison} ?';
|
||||||
queryValues.push(params.${f.param});
|
queryValues.push(${isSearch ? '\'%\' + params.' + f.param + ' + \'%\'' : 'params.' + f.param});
|
||||||
}`;
|
}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
filters = ` WHERE ${requiredFilterStrings.join(' AND ')}`;
|
filters = ` WHERE ${requiredFilterStrings.join(' AND ')}`;
|
||||||
}
|
}
|
||||||
|
return {filters, requiredQueryValues, optionalFilterParts};
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildGetList(view: EndpointDef, isSearch=false): string {
|
||||||
|
// TODO: optionally allow a raw query definition with predefined params
|
||||||
|
// This would be so much simpler and easy if it were just the queries wanted
|
||||||
|
let func: string = '';
|
||||||
|
let funcName: string = '';
|
||||||
|
let columns: string = view.type === 'count' ? `count(*)` : `${view.component}.${view.component}_id, ${view.columns.map(c => `${c.table}.${c.name}`).join(', ')}`;
|
||||||
|
let query: string = '';
|
||||||
|
let tables: string = view.join?.length ? buildJoin(view) : `${view.table}`;
|
||||||
|
funcName = buildFunctionName(view);
|
||||||
|
|
||||||
|
let {filters, requiredQueryValues, optionalFilterParts} = constructFilters(view, isSearch);
|
||||||
|
|
||||||
query = `SELECT ${columns} FROM ${tables}${filters}`;
|
query = `SELECT ${columns} FROM ${tables}${filters}`;
|
||||||
let orderByCode = '';
|
let orderByCode = '';
|
||||||
@ -200,7 +201,7 @@ function buildGetList(view: EndpointDef): string {
|
|||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildFilters(view: EndpointDef): {filters: string, requiredFilterValues: string, optionalFiltersCode: string} {
|
function buildSearches(view: EndpointDef): {filters: string, requiredFilterValues: string, optionalFiltersCode: string} {
|
||||||
let filtersObj: {filters: string, requiredFilterValues: string, optionalFiltersCode: string} = {
|
let filtersObj: {filters: string, requiredFilterValues: string, optionalFiltersCode: string} = {
|
||||||
filters: '',
|
filters: '',
|
||||||
requiredFilterValues: '',
|
requiredFilterValues: '',
|
||||||
@ -229,8 +230,8 @@ function buildFilters(view: EndpointDef): {filters: string, requiredFilterValues
|
|||||||
*/
|
*/
|
||||||
optionalFilterParts = optionalFilterParts + `
|
optionalFilterParts = optionalFilterParts + `
|
||||||
if (params.${f.param}) {
|
if (params.${f.param}) {
|
||||||
query = query + ' AND ${f.column.table}.${f.column.name} ${f.comparison} ?';
|
query = query + ' OR ${f.column.table}.${f.column.name} ${f.comparison} ?';
|
||||||
queryValues.push(params.${f.param});
|
queryValues.push('%' + params.${f.param} + '%');
|
||||||
}`;
|
}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -278,7 +279,7 @@ function buildFunctionName(view: EndpointDef): string {
|
|||||||
'update': (view: EndpointDef) => `update${uppercaseFirstLetter(view.component)}`,
|
'update': (view: EndpointDef) => `update${uppercaseFirstLetter(view.component)}`,
|
||||||
'create': (view: EndpointDef) => `create${uppercaseFirstLetter(view.component)}`,
|
'create': (view: EndpointDef) => `create${uppercaseFirstLetter(view.component)}`,
|
||||||
'delete': (view: EndpointDef) => `delete${uppercaseFirstLetter(view.component)}`,
|
'delete': (view: EndpointDef) => `delete${uppercaseFirstLetter(view.component)}`,
|
||||||
'search': (view: EndpointDef) => `search${uppercaseFirstLetter(view.component)}`,
|
'search': (view: EndpointDef) => `search${pluralize(uppercaseFirstLetter(view.component))}`,
|
||||||
};
|
};
|
||||||
return selector[view.type](view);
|
return selector[view.type](view);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user