mirror of
https://github.com/hcengineering/platform.git
synced 2025-05-13 10:53:06 +00:00
Fixed mixin projections in postgres adapter (#8838)
Signed-off-by: Victor Ilyushchenko <alt13ri@gmail.com>
This commit is contained in:
parent
5dfef1f218
commit
4a24ca257f
@ -88,6 +88,7 @@ import {
|
|||||||
DBCollectionHelper,
|
DBCollectionHelper,
|
||||||
type DBDoc,
|
type DBDoc,
|
||||||
doFetchTypes,
|
doFetchTypes,
|
||||||
|
filterProjection,
|
||||||
getDBClient,
|
getDBClient,
|
||||||
inferType,
|
inferType,
|
||||||
isDataField,
|
isDataField,
|
||||||
@ -662,7 +663,9 @@ abstract class PostgresAdapterBase implements DbAdapter {
|
|||||||
const joins = this.buildJoins<T>(_class, options)
|
const joins = this.buildJoins<T>(_class, options)
|
||||||
// Add workspace name as $1
|
// Add workspace name as $1
|
||||||
|
|
||||||
const select = `SELECT ${this.getProjection(vars, domain, options?.projection, joins, options?.associations)} FROM ${domain}`
|
const projection = this.localizeProjection(_class, options?.projection ?? undefined)
|
||||||
|
|
||||||
|
const select = `SELECT ${this.getProjection(vars, domain, projection, joins, options?.associations)} FROM ${domain}`
|
||||||
|
|
||||||
const showArchived = shouldShowArchived(query, options)
|
const showArchived = shouldShowArchived(query, options)
|
||||||
const secJoin = this.addSecurity(vars, query, showArchived, domain, ctx.contextData)
|
const secJoin = this.addSecurity(vars, query, showArchived, domain, ctx.contextData)
|
||||||
@ -714,11 +717,11 @@ abstract class PostgresAdapterBase implements DbAdapter {
|
|||||||
options?.associations === undefined
|
options?.associations === undefined
|
||||||
) {
|
) {
|
||||||
return toFindResult(
|
return toFindResult(
|
||||||
result.map((p) => parseDocWithProjection(p, domain, options?.projection)),
|
result.map((p) => parseDocWithProjection(p, domain, projection)),
|
||||||
total
|
total
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
const res = this.parseLookup<T>(result, joins, options?.projection, domain)
|
const res = this.parseLookup<T>(result, joins, projection, domain)
|
||||||
return toFindResult(res, total)
|
return toFindResult(res, total)
|
||||||
}
|
}
|
||||||
})) as FindResult<T>
|
})) as FindResult<T>
|
||||||
@ -739,6 +742,36 @@ abstract class PostgresAdapterBase implements DbAdapter {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private localizeProjection<T extends Doc>(
|
||||||
|
_class: Ref<Class<T>>,
|
||||||
|
projection: Projection<T> | undefined
|
||||||
|
): Projection<T> | undefined {
|
||||||
|
if (projection === undefined) return
|
||||||
|
|
||||||
|
if (!this.hierarchy.isMixin(_class)) {
|
||||||
|
return projection
|
||||||
|
}
|
||||||
|
|
||||||
|
projection = { ...projection }
|
||||||
|
for (const key in projection) {
|
||||||
|
if (key.includes('.')) continue
|
||||||
|
try {
|
||||||
|
const attr = this.hierarchy.findAttribute(_class, key)
|
||||||
|
if (attr !== undefined && this.hierarchy.isMixin(attr.attributeOf)) {
|
||||||
|
const newKey = `${attr.attributeOf}.${attr.name}` as keyof Projection<T>
|
||||||
|
projection[newKey] = projection[key]
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
||||||
|
delete projection[key]
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
// ignore, if
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return projection
|
||||||
|
}
|
||||||
|
|
||||||
private buildJoins<T extends Doc>(_class: Ref<Class<T>>, options: ServerFindOptions<T> | undefined): JoinProps[] {
|
private buildJoins<T extends Doc>(_class: Ref<Class<T>>, options: ServerFindOptions<T> | undefined): JoinProps[] {
|
||||||
const joins = this.buildJoin(_class, options?.lookup)
|
const joins = this.buildJoin(_class, options?.lookup)
|
||||||
if (options?.domainLookup !== undefined) {
|
if (options?.domainLookup !== undefined) {
|
||||||
@ -888,17 +921,8 @@ abstract class PostgresAdapterBase implements DbAdapter {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (column === 'data') {
|
if (column === 'data') {
|
||||||
const data = row[column]
|
let data = row[column]
|
||||||
if (projection !== undefined) {
|
data = filterProjection(data, projection)
|
||||||
if (projection !== undefined) {
|
|
||||||
for (const key in data) {
|
|
||||||
if (!Object.prototype.hasOwnProperty.call(projection, key) || (projection as any)[key] === 0) {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
||||||
delete data[key]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
doc = { ...doc, ...data }
|
doc = { ...doc, ...data }
|
||||||
} else {
|
} else {
|
||||||
if (column === 'createdOn' || column === 'modifiedOn') {
|
if (column === 'createdOn' || column === 'modifiedOn') {
|
||||||
|
@ -554,6 +554,9 @@ export function convertArrayParams (parameters?: ParameterOrJSON<any>[]): any[]
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function filterProjection<T extends Doc> (data: any, projection: Projection<T> | undefined): any {
|
export function filterProjection<T extends Doc> (data: any, projection: Projection<T> | undefined): any {
|
||||||
|
if (projection === undefined) {
|
||||||
|
return data
|
||||||
|
}
|
||||||
for (const key in data) {
|
for (const key in data) {
|
||||||
if (!Object.prototype.hasOwnProperty.call(projection, key) || (projection as any)[key] === 0) {
|
if (!Object.prototype.hasOwnProperty.call(projection, key) || (projection as any)[key] === 0) {
|
||||||
// check nested projections in case of object
|
// check nested projections in case of object
|
||||||
|
Loading…
Reference in New Issue
Block a user