|
|
@ -138,9 +138,11 @@ class BaseModelSqlv2 { |
|
|
|
{ |
|
|
|
{ |
|
|
|
ignoreView = false, |
|
|
|
ignoreView = false, |
|
|
|
getHiddenColumn = false, |
|
|
|
getHiddenColumn = false, |
|
|
|
|
|
|
|
throwErrorIfInvalidParams = false, |
|
|
|
}: { |
|
|
|
}: { |
|
|
|
ignoreView?: boolean; |
|
|
|
ignoreView?: boolean; |
|
|
|
getHiddenColumn?: boolean; |
|
|
|
getHiddenColumn?: boolean; |
|
|
|
|
|
|
|
throwErrorIfInvalidParams?: boolean; |
|
|
|
} = {}, |
|
|
|
} = {}, |
|
|
|
): Promise<any> { |
|
|
|
): Promise<any> { |
|
|
|
const qb = this.dbDriver(this.tnPath); |
|
|
|
const qb = this.dbDriver(this.tnPath); |
|
|
@ -150,6 +152,7 @@ class BaseModelSqlv2 { |
|
|
|
model: this.model, |
|
|
|
model: this.model, |
|
|
|
view: ignoreView ? null : this.viewId && (await View.get(this.viewId)), |
|
|
|
view: ignoreView ? null : this.viewId && (await View.get(this.viewId)), |
|
|
|
getHiddenColumn, |
|
|
|
getHiddenColumn, |
|
|
|
|
|
|
|
throwErrorIfInvalidParams, |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
await this.selectObject({ |
|
|
|
await this.selectObject({ |
|
|
@ -265,6 +268,7 @@ class BaseModelSqlv2 { |
|
|
|
} = {}, |
|
|
|
} = {}, |
|
|
|
ignoreViewFilterAndSort = false, |
|
|
|
ignoreViewFilterAndSort = false, |
|
|
|
validateFormula = false, |
|
|
|
validateFormula = false, |
|
|
|
|
|
|
|
throwErrorIfInvalidParams = false, |
|
|
|
): Promise<any> { |
|
|
|
): Promise<any> { |
|
|
|
const { where, fields, ...rest } = this._getListArgs(args as any); |
|
|
|
const { where, fields, ...rest } = this._getListArgs(args as any); |
|
|
|
|
|
|
|
|
|
|
@ -281,8 +285,16 @@ class BaseModelSqlv2 { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const aliasColObjMap = await this.model.getAliasColObjMap(); |
|
|
|
const aliasColObjMap = await this.model.getAliasColObjMap(); |
|
|
|
let sorts = extractSortsObject(rest?.sort, aliasColObjMap); |
|
|
|
let sorts = extractSortsObject( |
|
|
|
const filterObj = extractFilterFromXwhere(where, aliasColObjMap); |
|
|
|
rest?.sort, |
|
|
|
|
|
|
|
aliasColObjMap, |
|
|
|
|
|
|
|
throwErrorIfInvalidParams, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
const filterObj = extractFilterFromXwhere( |
|
|
|
|
|
|
|
where, |
|
|
|
|
|
|
|
aliasColObjMap, |
|
|
|
|
|
|
|
throwErrorIfInvalidParams, |
|
|
|
|
|
|
|
); |
|
|
|
// todo: replace with view id
|
|
|
|
// todo: replace with view id
|
|
|
|
if (!ignoreViewFilterAndSort && this.viewId) { |
|
|
|
if (!ignoreViewFilterAndSort && this.viewId) { |
|
|
|
await conditionV2( |
|
|
|
await conditionV2( |
|
|
@ -305,6 +317,8 @@ class BaseModelSqlv2 { |
|
|
|
}), |
|
|
|
}), |
|
|
|
], |
|
|
|
], |
|
|
|
qb, |
|
|
|
qb, |
|
|
|
|
|
|
|
undefined, |
|
|
|
|
|
|
|
throwErrorIfInvalidParams, |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
if (!sorts) |
|
|
|
if (!sorts) |
|
|
@ -312,7 +326,7 @@ class BaseModelSqlv2 { |
|
|
|
? args.sortArr |
|
|
|
? args.sortArr |
|
|
|
: await Sort.list({ viewId: this.viewId }); |
|
|
|
: await Sort.list({ viewId: this.viewId }); |
|
|
|
|
|
|
|
|
|
|
|
await sortV2(this, sorts, qb); |
|
|
|
await sortV2(this, sorts, qb, undefined, throwErrorIfInvalidParams); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
await conditionV2( |
|
|
|
await conditionV2( |
|
|
|
this, |
|
|
|
this, |
|
|
@ -329,11 +343,13 @@ class BaseModelSqlv2 { |
|
|
|
}), |
|
|
|
}), |
|
|
|
], |
|
|
|
], |
|
|
|
qb, |
|
|
|
qb, |
|
|
|
|
|
|
|
undefined, |
|
|
|
|
|
|
|
throwErrorIfInvalidParams, |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
if (!sorts) sorts = args.sortArr; |
|
|
|
if (!sorts) sorts = args.sortArr; |
|
|
|
|
|
|
|
|
|
|
|
await sortV2(this, sorts, qb); |
|
|
|
await sortV2(this, sorts, qb, undefined, throwErrorIfInvalidParams); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// sort by primary key if not autogenerated string
|
|
|
|
// sort by primary key if not autogenerated string
|
|
|
@ -366,6 +382,7 @@ class BaseModelSqlv2 { |
|
|
|
public async count( |
|
|
|
public async count( |
|
|
|
args: { where?: string; limit?; filterArr?: Filter[] } = {}, |
|
|
|
args: { where?: string; limit?; filterArr?: Filter[] } = {}, |
|
|
|
ignoreViewFilterAndSort = false, |
|
|
|
ignoreViewFilterAndSort = false, |
|
|
|
|
|
|
|
throwErrorIfInvalidParams = false, |
|
|
|
): Promise<any> { |
|
|
|
): Promise<any> { |
|
|
|
await this.model.getColumns(); |
|
|
|
await this.model.getColumns(); |
|
|
|
const { where } = this._getListArgs(args); |
|
|
|
const { where } = this._getListArgs(args); |
|
|
@ -374,7 +391,11 @@ class BaseModelSqlv2 { |
|
|
|
|
|
|
|
|
|
|
|
// qb.xwhere(where, await this.model.getAliasColMapping());
|
|
|
|
// qb.xwhere(where, await this.model.getAliasColMapping());
|
|
|
|
const aliasColObjMap = await this.model.getAliasColObjMap(); |
|
|
|
const aliasColObjMap = await this.model.getAliasColObjMap(); |
|
|
|
const filterObj = extractFilterFromXwhere(where, aliasColObjMap); |
|
|
|
const filterObj = extractFilterFromXwhere( |
|
|
|
|
|
|
|
where, |
|
|
|
|
|
|
|
aliasColObjMap, |
|
|
|
|
|
|
|
throwErrorIfInvalidParams, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
if (!ignoreViewFilterAndSort && this.viewId) { |
|
|
|
if (!ignoreViewFilterAndSort && this.viewId) { |
|
|
|
await conditionV2( |
|
|
|
await conditionV2( |
|
|
@ -398,6 +419,8 @@ class BaseModelSqlv2 { |
|
|
|
...(args.filterArr || []), |
|
|
|
...(args.filterArr || []), |
|
|
|
], |
|
|
|
], |
|
|
|
qb, |
|
|
|
qb, |
|
|
|
|
|
|
|
undefined, |
|
|
|
|
|
|
|
throwErrorIfInvalidParams, |
|
|
|
); |
|
|
|
); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
await conditionV2( |
|
|
|
await conditionV2( |
|
|
@ -416,6 +439,8 @@ class BaseModelSqlv2 { |
|
|
|
...(args.filterArr || []), |
|
|
|
...(args.filterArr || []), |
|
|
|
], |
|
|
|
], |
|
|
|
qb, |
|
|
|
qb, |
|
|
|
|
|
|
|
undefined, |
|
|
|
|
|
|
|
throwErrorIfInvalidParams, |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2991,7 +3016,7 @@ class BaseModelSqlv2 { |
|
|
|
const { where } = this._getListArgs(args); |
|
|
|
const { where } = this._getListArgs(args); |
|
|
|
const qb = this.dbDriver(this.tnPath); |
|
|
|
const qb = this.dbDriver(this.tnPath); |
|
|
|
const aliasColObjMap = await this.model.getAliasColObjMap(); |
|
|
|
const aliasColObjMap = await this.model.getAliasColObjMap(); |
|
|
|
const filterObj = extractFilterFromXwhere(where, aliasColObjMap); |
|
|
|
const filterObj = extractFilterFromXwhere(where, aliasColObjMap, true); |
|
|
|
|
|
|
|
|
|
|
|
const conditionObj = [ |
|
|
|
const conditionObj = [ |
|
|
|
new Filter({ |
|
|
|
new Filter({ |
|
|
@ -3177,7 +3202,7 @@ class BaseModelSqlv2 { |
|
|
|
const { where } = this._getListArgs(args); |
|
|
|
const { where } = this._getListArgs(args); |
|
|
|
const qb = this.dbDriver(this.tnPath); |
|
|
|
const qb = this.dbDriver(this.tnPath); |
|
|
|
const aliasColObjMap = await this.model.getAliasColObjMap(); |
|
|
|
const aliasColObjMap = await this.model.getAliasColObjMap(); |
|
|
|
const filterObj = extractFilterFromXwhere(where, aliasColObjMap); |
|
|
|
const filterObj = extractFilterFromXwhere(where, aliasColObjMap, true); |
|
|
|
|
|
|
|
|
|
|
|
await conditionV2( |
|
|
|
await conditionV2( |
|
|
|
this, |
|
|
|
this, |
|
|
@ -3194,6 +3219,8 @@ class BaseModelSqlv2 { |
|
|
|
}), |
|
|
|
}), |
|
|
|
], |
|
|
|
], |
|
|
|
qb, |
|
|
|
qb, |
|
|
|
|
|
|
|
undefined, |
|
|
|
|
|
|
|
true, |
|
|
|
); |
|
|
|
); |
|
|
|
const execQueries: ((trx: Knex.Transaction, qb: any) => Promise<any>)[] = |
|
|
|
const execQueries: ((trx: Knex.Transaction, qb: any) => Promise<any>)[] = |
|
|
|
[]; |
|
|
|
[]; |
|
|
@ -4846,6 +4873,7 @@ class BaseModelSqlv2 { |
|
|
|
export function extractSortsObject( |
|
|
|
export function extractSortsObject( |
|
|
|
_sorts: string | string[], |
|
|
|
_sorts: string | string[], |
|
|
|
aliasColObjMap: { [columnAlias: string]: Column }, |
|
|
|
aliasColObjMap: { [columnAlias: string]: Column }, |
|
|
|
|
|
|
|
throwErrorIfInvalid = false, |
|
|
|
): Sort[] { |
|
|
|
): Sort[] { |
|
|
|
if (!_sorts?.length) return; |
|
|
|
if (!_sorts?.length) return; |
|
|
|
|
|
|
|
|
|
|
@ -4862,6 +4890,11 @@ export function extractSortsObject( |
|
|
|
// replace + at the beginning if present
|
|
|
|
// replace + at the beginning if present
|
|
|
|
else sort.fk_column_id = aliasColObjMap[s.replace(/^\+/, '')]?.id; |
|
|
|
else sort.fk_column_id = aliasColObjMap[s.replace(/^\+/, '')]?.id; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (throwErrorIfInvalid && !sort.fk_column_id) |
|
|
|
|
|
|
|
NcError.unprocessableEntity( |
|
|
|
|
|
|
|
`Invalid column '${s.replace(/^[+-]/, '')}' in sort`, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
return new Sort(sort); |
|
|
|
return new Sort(sort); |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
@ -4869,6 +4902,7 @@ export function extractSortsObject( |
|
|
|
export function extractFilterFromXwhere( |
|
|
|
export function extractFilterFromXwhere( |
|
|
|
str, |
|
|
|
str, |
|
|
|
aliasColObjMap: { [columnAlias: string]: Column }, |
|
|
|
aliasColObjMap: { [columnAlias: string]: Column }, |
|
|
|
|
|
|
|
throwErrorIfInvalid = false, |
|
|
|
) { |
|
|
|
) { |
|
|
|
if (!str) { |
|
|
|
if (!str) { |
|
|
|
return []; |
|
|
|
return []; |
|
|
@ -4890,7 +4924,11 @@ export function extractFilterFromXwhere( |
|
|
|
nestedArrayConditions = str.split( |
|
|
|
nestedArrayConditions = str.split( |
|
|
|
/(?=~(?:or(?:not)?|and(?:not)?|not)\()/, |
|
|
|
/(?=~(?:or(?:not)?|and(?:not)?|not)\()/, |
|
|
|
); |
|
|
|
); |
|
|
|
return extractCondition(nestedArrayConditions || [], aliasColObjMap); |
|
|
|
return extractCondition( |
|
|
|
|
|
|
|
nestedArrayConditions || [], |
|
|
|
|
|
|
|
aliasColObjMap, |
|
|
|
|
|
|
|
throwErrorIfInvalid, |
|
|
|
|
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// iterate until finding right closing
|
|
|
|
// iterate until finding right closing
|
|
|
@ -4918,7 +4956,11 @@ export function extractFilterFromXwhere( |
|
|
|
const lhsOfNestedQuery = str.substring(0, openIndex); |
|
|
|
const lhsOfNestedQuery = str.substring(0, openIndex); |
|
|
|
|
|
|
|
|
|
|
|
nestedArrayConditions.push( |
|
|
|
nestedArrayConditions.push( |
|
|
|
...extractFilterFromXwhere(lhsOfNestedQuery, aliasColObjMap), |
|
|
|
...extractFilterFromXwhere( |
|
|
|
|
|
|
|
lhsOfNestedQuery, |
|
|
|
|
|
|
|
aliasColObjMap, |
|
|
|
|
|
|
|
throwErrorIfInvalid, |
|
|
|
|
|
|
|
), |
|
|
|
// calling recursively for nested query
|
|
|
|
// calling recursively for nested query
|
|
|
|
new Filter({ |
|
|
|
new Filter({ |
|
|
|
is_group: true, |
|
|
|
is_group: true, |
|
|
@ -4929,7 +4971,11 @@ export function extractFilterFromXwhere( |
|
|
|
), |
|
|
|
), |
|
|
|
}), |
|
|
|
}), |
|
|
|
// RHS of nested query(recursion)
|
|
|
|
// RHS of nested query(recursion)
|
|
|
|
...extractFilterFromXwhere(str.substring(closingIndex + 2), aliasColObjMap), |
|
|
|
...extractFilterFromXwhere( |
|
|
|
|
|
|
|
str.substring(closingIndex + 2), |
|
|
|
|
|
|
|
aliasColObjMap, |
|
|
|
|
|
|
|
throwErrorIfInvalid, |
|
|
|
|
|
|
|
), |
|
|
|
); |
|
|
|
); |
|
|
|
return nestedArrayConditions; |
|
|
|
return nestedArrayConditions; |
|
|
|
} |
|
|
|
} |
|
|
@ -4956,7 +5002,11 @@ function validateFilterComparison(uidt: UITypes, op: any, sub_op?: any) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
export function extractCondition(nestedArrayConditions, aliasColObjMap) { |
|
|
|
export function extractCondition( |
|
|
|
|
|
|
|
nestedArrayConditions, |
|
|
|
|
|
|
|
aliasColObjMap, |
|
|
|
|
|
|
|
throwErrorIfInvalid, |
|
|
|
|
|
|
|
) { |
|
|
|
return nestedArrayConditions?.map((str) => { |
|
|
|
return nestedArrayConditions?.map((str) => { |
|
|
|
let [logicOp, alias, op, value] = |
|
|
|
let [logicOp, alias, op, value] = |
|
|
|
str.match(/(?:~(and|or|not))?\((.*?),(\w+),(.*)\)/)?.slice(1) || []; |
|
|
|
str.match(/(?:~(and|or|not))?\((.*?),(\w+),(.*)\)/)?.slice(1) || []; |
|
|
@ -4983,6 +5033,8 @@ export function extractCondition(nestedArrayConditions, aliasColObjMap) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
validateFilterComparison(aliasColObjMap[alias].uidt, op, sub_op); |
|
|
|
validateFilterComparison(aliasColObjMap[alias].uidt, op, sub_op); |
|
|
|
|
|
|
|
} else if (throwErrorIfInvalid) { |
|
|
|
|
|
|
|
NcError.unprocessableEntity(`Column '${alias}' not found.`); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return new Filter({ |
|
|
|
return new Filter({ |
|
|
|