Browse Source

Merge pull request #2558 from nocodb/feat/shuffle-in-api

feat: shuffle option in list api
pull/2646/head
mertmit 2 years ago committed by GitHub
parent
commit
ebf7cbdc2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      packages/noco-docs/content/en/developer-resources/rest-apis.md
  2. 2
      packages/nocodb/src/lib/db/sql-data-mapper/lib/BaseModel.ts
  3. 47
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts
  4. 13
      packages/nocodb/src/lib/meta/api/swagger/helpers/templates/params.ts
  5. 7
      packages/nocodb/src/lib/meta/api/swagger/helpers/templates/paths.ts

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

@ -175,10 +175,11 @@ Currently, the default value for {orgs} is <b>noco</b>. Users will be able to ch
| **Name** | **Alias** | **Use case** | **Default value** |**Example value** |
|---|---|---|---|---|
| [where](#comparison-operators) | [w](#comparison-operators) | Complicated where conditions | | `(colName,eq,colValue)~or(colName2,gt,colValue2)` <br />[Usage: Comparison operators](#comparison-operators) <br />[Usage: Logical operators](#logical-operators) |
| limit | l | Number of rows to get(SQL limit value) | 10 | 20 |
| offset | o | Offset for pagination(SQL offset value) | 0 | 20 |
| limit | l | Number of rows to get (SQL limit value) | 10 | 20 |
| offset | o | Offset for pagination (SQL offset value) | 0 | 20 |
| sort | s | Sort by column name, Use `-` as prefix for descending sort | | column_name |
| fields | f | Required column names in result | * | column_name1,column_name2 |
| shuffle | r | Shuffle the result for pagination | 0 | 1 (Only allow 0 or 1. Other values would see it as 0) |
<!--
| fields1 | f1 | Required column names in child result | * | column_name1,column_name2 |

2
packages/nocodb/src/lib/db/sql-data-mapper/lib/BaseModel.ts

@ -1511,6 +1511,7 @@ export interface XcFilter {
condition?: any;
conditionGraph?: any;
limit?: string | number;
shuffle?: string | number;
offset?: string | number;
sort?: string;
fields?: string;
@ -1521,6 +1522,7 @@ export interface XcFilterWithAlias extends XcFilter {
h?: string;
c?: any;
l?: string | number;
r?: string | number;
o?: string | number;
s?: string;
f?: string;

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

@ -178,6 +178,9 @@ class BaseModelSqlv2 {
const qb = this.dbDriver(this.tnPath);
await this.selectObject({ qb });
if (+rest?.shuffle) {
await this.shuffle({ qb });
}
const aliasColObjMap = await this.model.getAliasColObjMap();
let sorts = extractSortsObject(args?.sort, aliasColObjMap);
@ -247,7 +250,7 @@ class BaseModelSqlv2 {
if (!ignoreFilterSort) applyPaginate(qb, rest);
const proto = await this.getProto();
const data = await this.extractRawQueryAndExec(qb);
let data = await this.extractRawQueryAndExec(qb);
return data?.map((d) => {
d.__proto__ = proto;
@ -335,6 +338,10 @@ class BaseModelSqlv2 {
qb.count(`${this.model.primaryKey?.column_name || '*'} as count`);
qb.select(args.column_name);
if (+rest?.shuffle) {
await this.shuffle({ qb });
}
const aliasColObjMap = await this.model.getAliasColObjMap();
const sorts = extractSortsObject(args?.sort, aliasColObjMap);
@ -354,8 +361,8 @@ class BaseModelSqlv2 {
qb.groupBy(args.column_name);
if (sorts) await sortV2(sorts, qb, this.dbDriver);
applyPaginate(qb, rest);
return await qb;
let data = await qb;
return data;
}
async multipleHmList({ colId, ids }, args?: { limit?; offset? }) {
@ -852,6 +859,10 @@ class BaseModelSqlv2 {
.orWhereNull(rcn)
);
if (+args?.shuffle) {
await this.shuffle({ qb });
}
await childModel.selectObject({ qb });
const aliasColObjMap = await childTable.getAliasColObjMap();
@ -861,8 +872,9 @@ class BaseModelSqlv2 {
applyPaginate(qb, args);
const proto = await childModel.getProto();
let data = await qb;
return (await qb).map((c) => {
return data.map((c) => {
c.__proto__ = proto;
return c;
});
@ -945,6 +957,10 @@ class BaseModelSqlv2 {
).orWhereNull(cn);
});
if (+args?.shuffle) {
await this.shuffle({ qb });
}
await childModel.selectObject({ qb });
const aliasColObjMap = await childTable.getAliasColObjMap();
@ -954,8 +970,9 @@ class BaseModelSqlv2 {
applyPaginate(qb, args);
const proto = await childModel.getProto();
let data = await this.extractRawQueryAndExec(qb);
return (await this.extractRawQueryAndExec(qb)).map((c) => {
return data.map((c) => {
c.__proto__ = proto;
return c;
});
@ -1038,6 +1055,10 @@ class BaseModelSqlv2 {
).orWhereNull(rcn);
});
if (+args?.shuffle) {
await this.shuffle({ qb });
}
await parentModel.selectObject({ qb });
const aliasColObjMap = await parentTable.getAliasColObjMap();
@ -1047,7 +1068,9 @@ class BaseModelSqlv2 {
applyPaginate(qb, args);
const proto = await parentModel.getProto();
return (await this.extractRawQueryAndExec(qb)).map((c) => {
let data = await this.extractRawQueryAndExec(qb);
return data.map((c) => {
c.__proto__ = proto;
return c;
});
@ -1227,6 +1250,7 @@ class BaseModelSqlv2 {
const obj: XcFilter = {};
obj.where = args.where || args.w || '';
obj.having = args.having || args.h || '';
obj.shuffle = args.shuffle || args.r || '';
obj.condition = args.condition || args.c || {};
obj.conditionGraph = args.conditionGraph || {};
obj.limit = Math.max(
@ -1242,6 +1266,16 @@ class BaseModelSqlv2 {
return obj;
}
public async shuffle({ qb }: { qb: QueryBuilder }): Promise<void> {
if (this.isMySQL) {
qb.orderByRaw('RAND()');
} else if (this.isPg || this.isSqlite) {
qb.orderByRaw('RANDOM()');
} else if (this.isMssql) {
qb.orderByRaw('NEWID()');
}
}
public async selectObject({ qb }: { qb: QueryBuilder }): Promise<void> {
const res = {};
const columns = await this.model.getColumns();
@ -2259,7 +2293,6 @@ function applyPaginate(
) {
query.offset(offset);
if (!ignoreLimit) query.limit(limit);
return query;
}

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

@ -74,6 +74,19 @@ export const offsetParam = {
example: 0,
};
export const shuffleParam = {
schema: {
type: 'number',
minimum: 0,
maximum: 1,
},
in: 'query',
name: 'shuffle',
description:
'The `shuffle` parameter used for pagination, the response will be shuffled if it is set to 1.',
example: 0,
};
export const columnNameQueryParam = {
schema: {
type: 'string',

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

@ -8,6 +8,7 @@ import {
getNestedParams,
limitParam,
offsetParam,
shuffleParam,
referencedRowIdParam,
relationTypeParam,
rowIdParam,
@ -35,6 +36,7 @@ export const getModelPaths = async (ctx: {
sortParam,
whereParam,
limitParam,
shuffleParam,
offsetParam,
...(await getNestedParams(ctx.columns)),
],
@ -200,6 +202,7 @@ export const getModelPaths = async (ctx: {
whereParam,
limitParam,
offsetParam,
shuffleParam,
],
responses: {
'200': {
@ -404,7 +407,7 @@ export const getModelPaths = async (ctx: {
},
},
tags: [ctx.tableName],
parameters: [limitParam, offsetParam],
parameters: [limitParam, shuffleParam, offsetParam],
description: '',
},
delete: {
@ -445,7 +448,7 @@ export const getModelPaths = async (ctx: {
},
},
tags: [ctx.tableName],
parameters: [limitParam, offsetParam],
parameters: [limitParam, shuffleParam, offsetParam],
},
},
}

Loading…
Cancel
Save