Browse Source

Merge pull request #1433 from finn-auto/fix-distinct-endpoint

fix distinct api enpoint
pull/1437/head
աɨռɢӄաօռɢ 3 years ago committed by GitHub
parent
commit
2062eb3077
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      packages/nocodb/src/lib/dataMapper/lib/BaseModel.ts
  2. 66
      packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts

12
packages/nocodb/src/lib/dataMapper/lib/BaseModel.ts

@ -924,10 +924,18 @@ abstract class BaseModel {
* @memberof BaseModel
* @throws {Error}
*/
async distinct({ cn, fields = '', where, limit, offset, sort, condition }) {
async distinct({
column_name,
fields = '',
where,
limit,
offset,
sort,
condition
}) {
try {
const query = this.$db;
query.distinct(cn, ...fields.split(',').filter(Boolean));
query.distinct(column_name, ...fields.split(',').filter(Boolean));
query.xwhere(where).condition(condition);
this._paginateAndSort(query, { limit, offset, sort });
return await this._run(query);

66
packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts

@ -1205,8 +1205,7 @@ class BaseModelSql extends BaseModel {
* @throws {Error}
*/
async distinct({
cn,
fields = '',
column_name,
where,
limit,
offset,
@ -1214,9 +1213,8 @@ class BaseModelSql extends BaseModel {
conditionGraph = null
}) {
try {
const query = this.$db;
query.distinct(
this.selectQuery([cn, ...fields.split(',').filter(Boolean)].join(','))
const query = this._buildDistinctQuery(
column_name ? column_name.split(',') : []
);
query.xwhere(where, this.selectQuery('')).conditionGraph(conditionGraph);
this._paginateAndSort(query, { limit, offset, sort });
@ -1227,6 +1225,64 @@ class BaseModelSql extends BaseModel {
}
}
/**
* Builds a query string that will return distinct values for the given column
* @param {string[]} columns - the column to query for distinct values
* @returns {object} the query.
*/
private _buildDistinctQuery(columns: string[]) {
const query = this.$db;
const formulaColumns = this.filterFormulaColumns(columns);
const otherColumns = _.difference(columns, formulaColumns);
if (!otherColumns.length && !formulaColumns.length) {
query.distinct(this.selectQuery('')).distinct(...this.selectFormulas);
}
if (otherColumns.length) {
query.distinct(this.selectQuery(otherColumns.join(',')));
}
if (formulaColumns.length) {
query.distinct(...this.selectFormulasForColumns(formulaColumns));
}
return query;
}
/**
* Selects the formulas for the give columns.
* @param {Array} sheet - The colums to select formulas for.
* @returns Array of formulas.
*/
private selectFormulasForColumns(columns: string[]) {
return (this.virtualColumns || [])?.reduce((arr, v) => {
if (
v.formula?.value &&
!v.formula?.error?.length &&
columns.includes(v._cn)
) {
arr.push(
formulaQueryBuilder(
v.formula?.tree,
v._cn,
this.dbDriver,
this.aliasToColumn
)
);
}
return arr;
}, []);
}
/**
* Returns an array of the columns that are of formula type.
* @returns {Array<string>} - an array of the formula columns.
*/
private filterFormulaColumns(columns: string[]) {
return columns.filter(column => {
return this.virtualColumns.find(
col => col._cn === column && col?.formula
);
});
}
/**
* Runs raw query on database
*

Loading…
Cancel
Save