diff --git a/lib/controller.js b/lib/controller.js index 981ffeb..32e8841 100644 --- a/lib/controller.js +++ b/lib/controller.js @@ -45,6 +45,18 @@ class Controller extends DataService { this.actions.select, ); + this.actions.distinct = _.merge( + {}, + _.omit(this.actions.default, 'orderBy'), + { + method: ['get', 'head'], + handler: 'distinct', + name: 'distinct', + path: 'distinct/:distinctField' + }, + this.actions.distinct + ); + this.actions.count = _.merge( {}, this.actions.select, diff --git a/lib/data-service.js b/lib/data-service.js index 812af9d..0bde141 100644 --- a/lib/data-service.js +++ b/lib/data-service.js @@ -98,6 +98,46 @@ class DataService { .then(collection => this._handlePostForCollection(collection, scope)); } + distinct(scope) { + return Bb + .try(this._handlePre.bind(this, scope)) + .then(() => { + // pick distinctField value to avoid filter affecting + scope.context.distinctField = scope.req.params.distinctField; + delete scope.req.params.distinctField; + }) + .then(this.getFilter.bind(this, scope)) + .then((filter) => { + // field list + scope.fieldList = this.extractFieldList(scope); + // q + const q = scope.getQ(); + // orderBy + const orderBy = this.getOrderBy(scope); + const pagination = scope.pagination = this.getPagination(scope); + const distinctField = scope.context.distinctField; + + return this.dataSource.find({ + distinctField: distinctField, + filter: filter, + fields: scope.fieldList, + q: q, + qFields: this.qFields, + limit: pagination.limit, + skip: (pagination.page - 1) * pagination.limit, + queryPipe: this.queryPipe ? (query) => { + this.queryPipe(query, scope); + } : undefined + }); + }) + .then((collection) => { + return this._handleCollectionPost(collection, scope); + }) + .then((collection) => { + return this._handlePostForCollection(collection, scope); + }); + } + selectOne(scope) { return this .locateModel(scope, true, true) diff --git a/lib/scope.js b/lib/scope.js index 02aeb06..18183d0 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -6,6 +6,7 @@ const ACTIONS = { SELECT: 'select', + DISTINCT: 'distinct', SELECT_ONE: 'selectOne', INSERT: 'insert', REPLACE: 'replace', @@ -40,7 +41,11 @@ class RestifizerScope { } isSelect() { - return this.checkActionName(ACTIONS.SELECT, ACTIONS.SELECT_ONE, ACTIONS.COUNT); + return this.checkActionName(ACTIONS.SELECT, ACTIONS.SELECT_ONE, ACTIONS.COUNT, ACTIONS.DISTINCT); + } + + isSelectDistinct() { + return this.checkActionName(ACTIONS.DISTINCT); } isChanging() {