Browse Source

group by api (#2074)

Signed-off-by: Vijay Kumar Rathore <professional.vijay8492@gmail.com>
pull/1687/head
Vijay Rathore 2 years ago committed by GitHub
parent
commit
c3d3fa3e5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      packages/noco-docs/content/en/developer-resources/rest-apis.md
  2. 40
      packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSqlv2.ts
  3. 36
      packages/nocodb/src/lib/noco/meta/api/dataApis/dataAliasApis.ts
  4. 14
      packages/nocodb/src/lib/noco/meta/api/swagger/helpers/swagger-base.json
  5. 10
      packages/nocodb/src/lib/noco/meta/api/swagger/helpers/templates/params.ts
  6. 39
      packages/nocodb/src/lib/noco/meta/api/swagger/helpers/templates/paths.ts
  7. 3
      packages/nocodb/src/lib/utils/projectAcl.ts

2
packages/noco-docs/content/en/developer-resources/rest-apis.md

@ -54,6 +54,7 @@ Currently, the default value for {orgs} is <b>noco</b>. Users will be able to ch
| Data | Delete| dbTableRow | bulkDeleteAll | /api/v1/db/data/bulk/{orgs}/{projectName}/{tableName}/all |
| Data | Get | dbTableRow | list | /api/v1/db/data/{orgs}/{projectName}/{tableName} |
| Data | Get | dbTableRow | findOne | /api/v1/db/data/{orgs}/{projectName}/{tableName}/find-one |
| Data | Get | dbTableRow | groupBy | /api/v1/db/data/{orgs}/{projectName}/{tableName}/groupby |
| Data | Get | dbTableRow | exist | /api/v1/db/data/{orgs}/{projectName}/{tableName}/{rowId}/exist |
| Data | Post | dbTableRow | create | /api/v1/db/data/{orgs}/{projectName}/{tableName} |
| Data | Get | dbTableRow | read | /api/v1/db/data/{orgs}/{projectName}/{tableName}/{rowId} |
@ -62,6 +63,7 @@ Currently, the default value for {orgs} is <b>noco</b>. Users will be able to ch
| Data | Get | dbTableRow | count | /api/v1/db/data/{orgs}/{projectName}/{tableName}/count |
| Data | Get | dbViewRow | list | /api/v1/db/data/{orgs}/{projectName}/{tableName}/views/{viewName} |
| Data | Get | dbViewRow | findOne | /api/v1/db/data/{orgs}/{projectName}/{tableName}/views/{viewName}/find-one |
| Data | Get | dbViewRow | groupBy | /api/v1/db/data/{orgs}/{projectName}/{tableName}/views/{viewName}/groupby |
| Data | Get | dbViewRow | exist | /api/v1/db/data/{orgs}/{projectName}/{tableName}/views/{viewName}/{rowId}/exist |
| Data | Post | dbViewRow | create | /api/v1/db/data/{orgs}/{projectName}/{tableName}/views/{viewName} |
| Data | Get | dbViewRow | read | /api/v1/db/data/{orgs}/{projectName}/{tableName}/views/{viewName}/{rowId} |

40
packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSqlv2.ts

@ -308,6 +308,46 @@ class BaseModelSqlv2 {
return ((await qb) as any).count;
}
async groupBy(
args: {
where?: string;
column_name: string;
limit?;
offset?;
sort?: string | string[];
} = {
column_name: ''
}
) {
const { where, ...rest } = this._getListArgs(args as any);
const qb = this.dbDriver(this.model.table_name);
qb.count(`${this.model.primaryKey?.column_name || '*'} as count`);
qb.select(args.column_name);
const aliasColObjMap = await this.model.getAliasColObjMap();
const sorts = extractSortsObject(args?.sort, aliasColObjMap);
const filterObj = extractFilterFromXwhere(args?.where, aliasColObjMap);
await conditionV2(
[
new Filter({
children: filterObj,
is_group: true,
logical_op: 'and'
})
],
qb,
this.dbDriver
);
qb.groupBy(args.column_name);
if (sorts) await sortV2(sorts, qb, this.dbDriver);
applyPaginate(qb, rest);
return await qb;
}
async multipleHmList({ colId, ids }, args?: { limit?; offset? }) {
try {
// todo: get only required fields

36
packages/nocodb/src/lib/noco/meta/api/dataApis/dataAliasApis.ts

@ -20,6 +20,11 @@ async function dataFindOne(req: Request, res: Response) {
res.json(await getFindOne(model, view, req));
}
async function dataGroupBy(req: Request, res: Response) {
const { model, view } = await getViewAndModelFromRequestByAliasOrId(req);
res.json(await getDataGroupBy(model, view, req));
}
async function dataCount(req: Request, res: Response) {
const { model, view } = await getViewAndModelFromRequestByAliasOrId(req);
@ -138,6 +143,25 @@ async function getFindOne(model, view: View, req) {
);
}
async function getDataGroupBy(model, view: View, req) {
const base = await Base.get(model.base_id);
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
});
const listArgs: any = { ...req.query };
const data = await baseModel.groupBy({ ...req.query });
const count = await baseModel.count(listArgs);
return new PagedResponseImpl(data, {
...req.query,
count
});
}
async function dataRead(req: Request, res: Response) {
const { model, view } = await getViewAndModelFromRequestByAliasOrId(req);
@ -187,6 +211,12 @@ router.get(
ncMetaAclMw(dataFindOne, 'dataFindOne')
);
router.get(
'/api/v1/db/data/:orgs/:projectName/:tableName/groupby',
apiMetrics,
ncMetaAclMw(dataGroupBy, 'dataGroupBy')
);
router.get(
'/api/v1/db/data/:orgs/:projectName/:tableName/:rowId/exist',
apiMetrics,
@ -242,6 +272,12 @@ router.get(
ncMetaAclMw(dataFindOne, 'dataFindOne')
);
router.get(
'/api/v1/db/data/:orgs/:projectName/:tableName/views/:viewName/groupby',
apiMetrics,
ncMetaAclMw(dataGroupBy, 'dataGroupBy')
);
router.get(
'/api/v1/db/data/:orgs/:projectName/:tableName/views/:viewName/:rowId/exist',
apiMetrics,

14
packages/nocodb/src/lib/noco/meta/api/swagger/helpers/swagger-base.json

@ -33,6 +33,20 @@
"type": "number"
}
}
},
"Groupby": {
"title": "Groupby",
"type": "object",
"properties": {
"count": {
"type": "number",
"description": "count"
},
"column_name": {
"type": "string",
"description": "the value of the given column"
}
}
}
},
"securitySchemes": {

10
packages/nocodb/src/lib/noco/meta/api/swagger/helpers/templates/params.ts

@ -74,6 +74,16 @@ export const offsetParam = {
example: 0
};
export const columnNameQueryParam = {
schema: {
type: 'string'
},
in: 'query',
name: 'column_name',
description:
'Column name of the column you want to group by, eg. `column_name=column1`'
};
export const columnNameParam = (columns: SwaggerColumn[]) => {
const columnNames = [];
for (const { column } of columns) {

39
packages/nocodb/src/lib/noco/meta/api/swagger/helpers/templates/paths.ts

@ -1,6 +1,7 @@
import { ModelTypes, UITypes } from 'nocodb-sdk';
import {
columnNameParam,
columnNameQueryParam,
csvExportOffsetParam,
exportTypeParam,
fieldsParam,
@ -165,6 +166,44 @@ export const getModelPaths = async (ctx: {
}
}
},
[`/api/v1/db/data/${ctx.orgs}/${ctx.projectName}/${ctx.tableName}/groupby`]: {
get: {
summary: `${ctx.tableName} groupby`,
operationId: `${ctx.tableName.toLowerCase()}-groupby`,
description: 'Group by a column.',
tags: [ctx.tableName],
parameters: [
columnNameQueryParam,
sortParam,
whereParam,
limitParam,
offsetParam
],
responses: {
'200': {
description: 'OK',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
list: {
type: 'array',
items: {
$ref: `#/components/schemas/Groupby`
}
},
PageInfo: {
$ref: `#/components/schemas/Paginated`
}
}
}
}
}
}
}
}
},
...(ctx.type === ModelTypes.TABLE
? {
[`/api/v1/db/data/bulk/${ctx.orgs}/${ctx.projectName}/${ctx.tableName}`]: {

3
packages/nocodb/src/lib/utils/projectAcl.ts

@ -23,6 +23,7 @@ export default {
dataRead: true,
dataExist: true,
dataFindOne: true,
dataGroupBy: true,
commentsCount: true,
exportCsv: true,
@ -157,6 +158,7 @@ export default {
dataRead: true,
dataExist: true,
dataFindOne: true,
dataGroupBy: true,
commentsCount: true,
xcTableAndViewList: true,
@ -194,6 +196,7 @@ export default {
dataRead: true,
dataExist: true,
dataFindOne: true,
dataGroupBy: true,
commentsCount: true,
exportCsv: true,

Loading…
Cancel
Save