Browse Source

wip(api): grouped list api

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/3814/head
Pranav C 2 years ago
parent
commit
65aaaa0416
  1. 30
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts
  2. 60
      packages/nocodb/src/lib/meta/api/dataApis/dataAliasApis.ts

30
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts

@ -2330,7 +2330,12 @@ class BaseModelSqlv2 {
}); });
} }
public async groupedList(args: { groupColumnId: string }) { public async groupedList(args: { groupColumnId: string }): Promise<
{
key: string;
value: Record<string, unknown>[];
}[]
> {
const column = await this.model const column = await this.model
.getColumns() .getColumns()
.then((cols) => cols?.find((col) => col.id === args.groupColumnId)); .then((cols) => cols?.find((col) => col.id === args.groupColumnId));
@ -2352,15 +2357,17 @@ class BaseModelSqlv2 {
const qb = this.dbDriver(this.model.table_name); const qb = this.dbDriver(this.model.table_name);
await this.selectObject({ qb }); await this.selectObject({ qb });
const nullQb = qb.clone().whereNull(column.title); const nullListQb = qb.clone().whereNull(column.title);
nullQb.limit(20); nullListQb.limit(20);
nullQb.offset(0); nullListQb.offset(0);
const groupedQb = this.dbDriver.from( const groupedQb = this.dbDriver.from(
this.dbDriver this.dbDriver
.unionAll( .unionAll(
[ [
this.isSqlite ? this.dbDriver.select().from(nullQb) : nullQb, this.isSqlite
? this.dbDriver.select().from(nullListQb)
: nullListQb,
...groupingValues.map((r) => { ...groupingValues.map((r) => {
const query = qb.clone().where(column.title, r); const query = qb.clone().where(column.title, r);
query.limit(20); query.limit(20);
@ -2376,7 +2383,18 @@ class BaseModelSqlv2 {
const result = await groupedQb; const result = await groupedQb;
return _.groupBy(result, column.title); // todo: handle null values
const groupedResult: Record<string, Record<string, unknown>[]> = _.groupBy(
result,
column.title
);
const r = Object.entries(groupedResult).map(([key, value]) => ({
key,
value,
}));
return r;
} }
public async groupedListCount(args: { groupColumnId: string }) { public async groupedListCount(args: { groupColumnId: string }) {

60
packages/nocodb/src/lib/meta/api/dataApis/dataAliasApis.ts

@ -222,6 +222,59 @@ async function dataExist(req: Request, res: Response) {
res.json(await baseModel.exist(req.params.rowId)); res.json(await baseModel.exist(req.params.rowId));
} }
// todo: Handle the error case where view doesnt belong to model
async function groupedDataList(req: Request, res: Response) {
const { model, view } = await getViewAndModelFromRequestByAliasOrId(req);
res.json(await getGroupedDataList(model, view, req));
}
async function getGroupedDataList(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 requestObj = await getAst({ model, query: req.query, view });
const listArgs: any = { ...req.query };
try {
listArgs.filterArr = JSON.parse(listArgs.filterArrJson);
} catch (e) {}
try {
listArgs.sortArr = JSON.parse(listArgs.sortArrJson);
} catch (e) {}
let data = [];
let count = 0;
try {
data = await nocoExecute(
requestObj,
await baseModel.list(listArgs),
{},
listArgs
);
count = await baseModel.count(listArgs);
} catch (e) {
// show empty result instead of throwing error here
// e.g. search some text in a numeric field
}
return new PagedResponseImpl(data, {
...req.query,
count,
});
}
const router = Router({ mergeParams: true }); const router = Router({ mergeParams: true });
// table data crud apis // table data crud apis
@ -304,6 +357,13 @@ router.get(
ncMetaAclMw(dataGroupBy, 'dataGroupBy') ncMetaAclMw(dataGroupBy, 'dataGroupBy')
); );
router.get(
'/api/v1/db/data/:orgs/:projectName/:tableName/views/:viewName/grouped',
apiMetrics,
ncMetaAclMw(groupedDataList, 'groupedDataList')
);
router.get( router.get(
'/api/v1/db/data/:orgs/:projectName/:tableName/views/:viewName/:rowId/exist', '/api/v1/db/data/:orgs/:projectName/:tableName/views/:viewName/:rowId/exist',
apiMetrics, apiMetrics,

Loading…
Cancel
Save