diff --git a/client/core/src/components/rest-model/crud-model.js b/client/core/src/components/rest-model/crud-model.js
index 614d15aee..1d71dfd61 100644
--- a/client/core/src/components/rest-model/crud-model.js
+++ b/client/core/src/components/rest-model/crud-model.js
@@ -27,8 +27,7 @@ export default class CrudModel extends ModelProxy {
where: mergeWhere(this.link, this.where),
include: this.include,
order: this.order,
- limit: this.limit,
- userData: this.userData
+ limit: this.limit
};
let filter = this.filter;
@@ -153,7 +152,7 @@ ngModule.component('vnCrudModel', {
order: '@?',
limit: '',
filter: '',
- userData: '',
+ userParams: '',
primaryKey: '@?',
autoLoad: ''
}
@@ -232,8 +231,6 @@ function mergeFilters(src, dst) {
res.order = src.order;
if (src.limit)
res.limit = src.limit;
- if (src.userData)
- res.userData = src.userData;
return res;
}
diff --git a/client/item/src/index/index.html b/client/item/src/index/index.html
index d998416a4..a310769c3 100644
--- a/client/item/src/index/index.html
+++ b/client/item/src/index/index.html
@@ -1,8 +1,8 @@
diff --git a/client/item/src/index/index.js b/client/item/src/index/index.js
index 9aada522c..6e17a8521 100644
--- a/client/item/src/index/index.js
+++ b/client/item/src/index/index.js
@@ -8,22 +8,6 @@ class Controller {
this.$state = $state;
this.$ = $scope;
this.itemSelected = null;
-
- this.filter = {
- include: [
- {
- relation: 'itemType',
- scope: {
- fields: ['name', 'workerFk'],
- include: {
- relation: 'worker',
- fields: ['firstName', 'name']
- }
- }
- }
- ],
- order: 'name ASC'
- };
}
exprBuilder(param, value) {
@@ -31,10 +15,10 @@ class Controller {
case 'search':
return /^\d+$/.test(value)
? {id: value}
- : {name: {regexp: value}};
+ : {name: {like: `%${value}%`}};
case 'name':
case 'description':
- return {[param]: {regexp: value}};
+ return {[param]: {like: `%${value}%`}};
case 'id':
case 'typeFk':
return {[param]: value};
diff --git a/client/item/src/index/product.html b/client/item/src/index/product.html
index 63a413c6b..99419f138 100644
--- a/client/item/src/index/product.html
+++ b/client/item/src/index/product.html
@@ -21,10 +21,10 @@
value="{{::$ctrl.item.size}}">
+ value="{{::$ctrl.item.type}}">
+ value="{{::$ctrl.item.firstName}} {{::$ctrl.item.worker}}">
diff --git a/services/loopback/common/methods/item/filter.js b/services/loopback/common/methods/item/filter.js
index 1decb9c10..8334e77d8 100644
--- a/services/loopback/common/methods/item/filter.js
+++ b/services/loopback/common/methods/item/filter.js
@@ -1,3 +1,6 @@
+
+const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
+
module.exports = Self => {
Self.remoteMethod('filter', {
description: 'Find all instances of the model matched by filter from the data source.',
@@ -6,7 +9,7 @@ module.exports = Self => {
{
arg: 'filter',
type: 'Object',
- description: 'Filter defining fields, where, include, order, offset, and limit - must be a JSON-encoded string ({"something":"value"})',
+ description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
http: {source: 'query'}
}, {
arg: 'tags',
@@ -26,7 +29,29 @@ module.exports = Self => {
});
Self.filter = async(filter, tags) => {
- console.log(tags);
- return await Self.find(filter);
+ let stmt = new ParameterizedSQL(
+ `SELECT i.id, i.image, i.name, i.description, i.size,
+ t.name type, w.firstName, w.name worker
+ FROM item i
+ JOIN itemType t ON t.id = i.typeFk
+ JOIN worker w ON w.id = t.workerFk`
+ );
+
+ if (tags) {
+ let i = 1;
+ for (let tag of tags) {
+ if (tag.value == null) continue;
+ let tAlias = `it${i++}`;
+ stmt.merge({
+ sql: `JOIN itemTag ${tAlias} ON ${tAlias}.itemFk = i.id
+ AND ${tAlias}.tagFk = ?
+ AND ${tAlias}.value = ?`,
+ params: [tag.tagFk, tag.value]
+ });
+ }
+ }
+
+ stmt.merge(Self.buildSuffix(filter, 'i'));
+ return Self.rawStmt(stmt);
};
};
diff --git a/services/loopback/common/methods/vn-model/rawSql.js b/services/loopback/common/methods/vn-model/rawSql.js
deleted file mode 100644
index 9b8a0a07e..000000000
--- a/services/loopback/common/methods/vn-model/rawSql.js
+++ /dev/null
@@ -1,15 +0,0 @@
-module.exports = function(Self) {
- Self.rawSql = function(query, params, cb) {
- var connector = this.dataSource.connector;
- return new Promise(function(resolve, reject) {
- connector.execute(query, params, function(error, response) {
- if (cb)
- cb(error, response);
- if (error)
- reject(error);
- else
- resolve(response);
- });
- });
- };
-};
diff --git a/services/loopback/common/models/vn-model.js b/services/loopback/common/models/vn-model.js
index 5d1f4b7be..f1e19351d 100644
--- a/services/loopback/common/models/vn-model.js
+++ b/services/loopback/common/models/vn-model.js
@@ -1,3 +1,6 @@
+
+const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
+
module.exports = function(Self) {
Self.setup = function() {
Self.super_.setup.call(this);
@@ -162,7 +165,89 @@ module.exports = function(Self) {
};
};
- require('../methods/vn-model/rawSql')(Self);
+ Self.rawSql = function(query, params, cb) {
+ var connector = this.dataSource.connector;
+ return new Promise(function(resolve, reject) {
+ connector.execute(query, params, function(error, response) {
+ if (cb)
+ cb(error, response);
+ if (error)
+ reject(error);
+ else
+ resolve(response);
+ });
+ });
+ };
+
+ Self.rawStmt = function(stmt) {
+ return this.rawSql(stmt.sql, stmt.params);
+ };
+
+ Self.escapeName = function(name) {
+ return this.dataSource.connector.escapeName(name);
+ };
+
+ Self.buildWhere = function(filter, tableAlias) {
+ let connector = this.dataSource.connector;
+ let wrappedConnector = Object.create(connector);
+ wrappedConnector.columnEscaped = function(model, property) {
+ let sql = tableAlias
+ ? connector.escapeName(tableAlias) + '.'
+ : '';
+ return sql + connector.columnEscaped(model, property);
+ };
+
+ return wrappedConnector.buildWhere(this.modelName, filter.where);
+ };
+
+ Self.buildLimit = function(filter) {
+ let sql = new ParameterizedSQL('');
+ this.dataSource.connector.applyPagination(this.modelName, sql, filter);
+ return sql;
+ };
+
+ Self.buildOrderBy = function(filter) {
+ let order = filter.order;
+
+ if (!order)
+ return '';
+ if (typeof order === 'string')
+ order = [order];
+
+ let clauses = [];
+
+ for (let clause of order) {
+ let sqlOrder = '';
+ let t = clause.split(/[\s,]+/);
+ let names = t[0].split('.');
+
+ if (names.length > 1)
+ sqlOrder += this.escapeName(names[0]) + '.';
+ sqlOrder += this.escapeName(names[names.length - 1]);
+
+ if (t.length > 1)
+ sqlOrder += ' ' + (t[1].toUpperCase() == 'ASC' ? 'ASC' : 'DESC');
+
+ clauses.push(sqlOrder);
+ }
+
+ return `ORDER BY ${clauses.join(', ')}`;
+ };
+
+ Self.buildPagination = function(filter) {
+ return ParameterizedSQL.join([
+ this.buildOrderBy(filter),
+ this.buildLimit(filter)
+ ]);
+ };
+
+ Self.buildSuffix = function(filter, tableAlias) {
+ return ParameterizedSQL.join([
+ this.buildWhere(filter, tableAlias),
+ this.buildPagination(filter)
+ ]);
+ };
+
require('../methods/vn-model/installMethod')(Self);
require('../methods/vn-model/validateBinded')(Self);
};