Browse Source

Merge pull request #3007 from nocodb/fix/nested-filter-and-sort

fix: add filter and sort support on nested list data
pull/4083/head
աɨռɢӄաօռɢ 2 years ago committed by GitHub
parent
commit
d0f003d3f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 38
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts
  2. 2
      packages/nocodb/src/lib/meta/api/dataApis/dataAliasApis.ts
  3. 4
      packages/nocodb/tests/unit/rest/tests/tableRow.test.ts
  4. 4
      packages/nocodb/tests/unit/rest/tests/viewRow.test.ts

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

@ -369,7 +369,7 @@ class BaseModelSqlv2 {
async multipleHmList({ colId, ids }, args: { limit?; offset? } = {}) {
try {
const { where, ...rest } = this._getListArgs(args as any);
const { where, sort, ...rest } = this._getListArgs(args as any);
// todo: get only required fields
// const { cn } = this.hasManyRelations.find(({ tn }) => tn === child) || {};
@ -393,6 +393,7 @@ class BaseModelSqlv2 {
const qb = this.dbDriver(childTable.table_name);
await childModel.selectObject({ qb });
await this.applySortAndFilter({ table: childTable, where, qb, sort });
const childQb = this.dbDriver.queryBuilder().from(
this.dbDriver
@ -440,6 +441,26 @@ class BaseModelSqlv2 {
}
}
private async applySortAndFilter({
table,
where,
qb,
sort,
}: {
table: Model;
where: string;
qb;
sort: string;
}) {
const childAliasColMap = await table.getAliasColObjMap();
const filter = extractFilterFromXwhere(where, childAliasColMap);
await conditionV2(filter, qb, this.dbDriver);
if (!sort) return;
const sortObj = extractSortsObject(sort, childAliasColMap);
if (sortObj) await sortV2(sortObj, qb, this.dbDriver);
}
async multipleHmListCount({ colId, ids }) {
try {
// const { cn } = this.hasManyRelations.find(({ tn }) => tn === child) || {};
@ -483,7 +504,7 @@ class BaseModelSqlv2 {
async hmList({ colId, id }, args: { limit?; offset? } = {}) {
try {
const { where, ...rest } = this._getListArgs(args as any);
const { where, sort, ...rest } = this._getListArgs(args as any);
// todo: get only required fields
const relColumn = (await this.model.getColumns()).find(
@ -505,6 +526,7 @@ class BaseModelSqlv2 {
await parentTable.getColumns();
const qb = this.dbDriver(childTable.table_name);
await this.applySortAndFilter({ table: childTable, where, qb, sort });
qb.whereIn(
chilCol.column_name,
@ -576,7 +598,7 @@ class BaseModelSqlv2 {
{ colId, parentIds },
args: { limit?; offset? } = {}
) {
const { where, ...rest } = this._getListArgs(args as any);
const { where, sort, ...rest } = this._getListArgs(args as any);
const relColumn = (await this.model.getColumns()).find(
(c) => c.id === colId
);
@ -603,6 +625,9 @@ class BaseModelSqlv2 {
const qb = this.dbDriver(rtn).join(vtn, `${vtn}.${vrcn}`, `${rtn}.${rcn}`);
await childModel.selectObject({ qb });
await this.applySortAndFilter({ table: childTable, where, qb, sort });
const finalQb = this.dbDriver.unionAll(
parentIds.map((id) => {
const query = qb
@ -646,7 +671,7 @@ class BaseModelSqlv2 {
}
public async mmList({ colId, parentId }, args: { limit?; offset? } = {}) {
const { where, ...rest } = this._getListArgs(args as any);
const { where, sort, ...rest } = this._getListArgs(args as any);
const relColumn = (await this.model.getColumns()).find(
(c) => c.id === colId
);
@ -681,6 +706,9 @@ class BaseModelSqlv2 {
);
await childModel.selectObject({ qb });
await this.applySortAndFilter({ table: childTable, where, qb, sort });
// todo: sanitize
qb.limit(+rest?.limit || 25);
qb.offset(+rest?.offset || 0);
@ -1304,7 +1332,7 @@ class BaseModelSqlv2 {
);
obj.offset = Math.max(+(args.offset || args.o) || 0, 0);
obj.fields = args.fields || args.f || '*';
obj.sort = args.sort || args.s || this.model.primaryKey?.[0]?.tn;
obj.sort = args.sort || args.s;
return obj;
}

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

@ -203,7 +203,7 @@ async function dataRead(req: Request, res: Response) {
await getAst({ model, query: req.query, view }),
row,
{},
{}
req.query
)
);
}

4
packages/nocodb/tests/unit/rest/tests/tableRow.test.ts

@ -730,7 +730,7 @@ function tableTest() {
);
const nestedFields = {
'Rental List': ['RentalDate', 'ReturnDate'],
'Rental List': { fields : ['RentalDate', 'ReturnDate'] },
};
const nestedFilter = [
@ -805,7 +805,7 @@ function tableTest() {
ascResponse.body.list[0]['Rental List']
);
if (
nestedRentalResponse.includes('RentalId') &&
nestedRentalResponse.includes('ReturnDate') &&
nestedRentalResponse.includes('RentalDate') &&
nestedRentalResponse.length === 2
) {

4
packages/nocodb/tests/unit/rest/tests/viewRow.test.ts

@ -562,7 +562,7 @@ function viewRowTests() {
);
const nestedFields = {
'Rental List': ['RentalDate', 'ReturnDate'],
'Rental List': { fields : ['RentalDate', 'ReturnDate'] },
};
const nestedFilter = [
@ -638,7 +638,7 @@ function viewRowTests() {
if (
!(
nestedRentalResponse.includes('RentalId') &&
nestedRentalResponse.includes('ReturnDate') &&
nestedRentalResponse.includes('RentalDate') &&
nestedRentalResponse.length === 2
)

Loading…
Cancel
Save