refs #6667 sql #1940

Merged
carlossa merged 6 commits from 6667-searchFilter into dev 2024-01-22 10:36:11 +00:00
3 changed files with 181 additions and 0 deletions
Showing only changes of commit 01c7ca353a - Show all commits

View File

@ -0,0 +1,77 @@
const {ParameterizedSQL} = require('loopback-connector');
const {buildFilter, mergeFilters} = require('vn-loopback/util/filter');
// const {models} = require('vn-loopback/server/server');
module.exports = Self => {
Self.remoteMethod('filter', {
description:
'Find all postcodes of the model matched by postcode, town, province or country.',
accessType: 'READ',
returns: {
type: ['object'],
root: true,
},
accepts: [
{
arg: 'filter',
type: 'object',
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
http: {source: 'query'}
},
{
arg: 'search',
type: 'string',
description: 'Value to filter',
http: {source: 'query'}
},
],
http: {
path: `/filter`,
verb: 'GET',
},
});
Self.filter = async(ctx, filter, options) => {
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const conn = Self.dataSource.connector;
const where = buildFilter(ctx.args, (param, value) => {
switch (param) {
case 'search':
return {or: [
{'pc.code': {like: `%${value}%`}},
{'t.name': {like: `%${value}%`}},
{'p.name': {like: `%${value}%`}},
{'c.country': {like: `%${value}%`}}
]
};
}
}) ?? {};
filter = mergeFilters(ctx.args?.filter ?? {}, {where});
const stmts = [];
let stmt;
stmt = new ParameterizedSQL(`
SELECT
pc.code,
t.name as town,
p.name as province,
c.country
FROM
postCode pc
JOIN town t on t.id = pc.townFk
JOIN province p on p.id = t.provinceFk
JOIN country c on c.id = p.countryFk
`);
stmt.merge(conn.makeSuffix(filter));
const itemsIndex = stmts.push(stmt) - 1;
const sql = ParameterizedSQL.join(stmts, ';');
const result = await conn.executeStmt(sql, myOptions);
return itemsIndex === 0 ? result : result[itemsIndex];
};
};

View File

@ -0,0 +1,103 @@
const {models} = require('vn-loopback/server/server');
describe('Postcode filter()', () => {
it('should retrieve with no filter', async() => {
const tx = await models.Postcode.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: {
},
};
const results = await models.Postcode.filter(ctx, options);
expect(results.length).toBeGreaterThan(0);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should retrieve with filter as postcode', async() => {
const tx = await models.Postcode.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: {
search: 46,
},
};
const results = await models.Postcode.filter(ctx, options);
expect(results.length).toEqual(4);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should retrieve with filter as city', async() => {
const tx = await models.Postcode.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: {
search: 'Alz',
},
};
const results = await models.Postcode.filter(ctx, options);
expect(results.length).toEqual(1);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should retrieve with filter as province', async() => {
const tx = await models.Postcode.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: {
search: 'one',
},
};
const results = await models.Postcode.filter(ctx, options);
expect(results.length).toEqual(4);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should retrieve with filter as country', async() => {
const tx = await models.Postcode.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: {
search: 'Ec',
},
};
const results = await models.Postcode.filter(ctx, options);
expect(results.length).toEqual(1);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
});

View File

@ -1,6 +1,7 @@
let UserError = require('vn-loopback/util/user-error'); let UserError = require('vn-loopback/util/user-error');
module.exports = Self => { module.exports = Self => {
require('../methods/postcode/filter.js')(Self);
Self.rewriteDbError(function(err) { Self.rewriteDbError(function(err) {
if (err.code === 'ER_DUP_ENTRY') if (err.code === 'ER_DUP_ENTRY')
return new UserError(`This postcode already exists`); return new UserError(`This postcode already exists`);