mirror of https://github.com/nocodb/nocodb
Browse Source
* feat: allow user to include/exclude nested fields and by default only extract pk&pv Signed-off-by: Pranav C <pranavxc@gmail.com> * chore: api metrics Signed-off-by: Pranav C <pranavxc@gmail.com> * fix: add missing await and code cleanup Signed-off-by: Pranav C <pranavxc@gmail.com> * fix: corrections in ast population Signed-off-by: Pranav C <pranavxc@gmail.com> * fix: map default primary value column on table create and include field param for belongsTo column Signed-off-by: Pranav C <pranavxc@gmail.com> * fix: old data list api response correction and count api Signed-off-by: Pranav C <pranavxc@gmail.com>pull/1901/head
Pranav C
3 years ago
committed by
GitHub
20 changed files with 25456 additions and 267 deletions
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,99 @@
|
||||
import View from '../../../../noco-models/View'; |
||||
import { isSystemColumn, UITypes } from 'nocodb-sdk'; |
||||
import Model from '../../../../noco-models/Model'; |
||||
import LinkToAnotherRecordColumn from '../../../../noco-models/LinkToAnotherRecordColumn'; |
||||
|
||||
const getAst = async ({ |
||||
query, |
||||
extractOnlyPrimaries = false, |
||||
includePkByDefault = true, |
||||
model, |
||||
view |
||||
}: { |
||||
query?: RequestQuery; |
||||
extractOnlyPrimaries?: boolean; |
||||
includePkByDefault?: boolean; |
||||
model: Model; |
||||
view?: View; |
||||
}) => { |
||||
if (!model.columns?.length) await model.getColumns(); |
||||
if (extractOnlyPrimaries) { |
||||
return { |
||||
[model.primaryKey.title]: 1, |
||||
[model.primaryValue.title]: 1 |
||||
}; |
||||
} |
||||
|
||||
let fields = query?.fields || query?.f; |
||||
if (fields && fields !== '*') { |
||||
fields = Array.isArray(fields) ? fields : fields.split(','); |
||||
} else { |
||||
fields = null; |
||||
} |
||||
|
||||
let allowedCols = null; |
||||
if (view) |
||||
allowedCols = (await View.getColumns(view.id)).reduce( |
||||
(o, c) => ({ |
||||
...o, |
||||
[c.fk_column_id]: c.show |
||||
}), |
||||
{} |
||||
); |
||||
|
||||
return model.columns.reduce(async (obj, col) => { |
||||
let value: number | boolean | { [key: string]: any } = 1; |
||||
const nestedFields = |
||||
query?.nested?.[col.title]?.fields || query?.nested?.[col.title]?.f; |
||||
if (nestedFields && nestedFields !== '*') { |
||||
if (col.uidt === UITypes.LinkToAnotherRecord) { |
||||
const model = await col |
||||
.getColOptions<LinkToAnotherRecordColumn>() |
||||
.then(colOpt => colOpt.getRelatedTable()); |
||||
|
||||
value = await getAst({ |
||||
model, |
||||
query: query?.nested?.[col.title] |
||||
}); |
||||
} else { |
||||
value = (Array.isArray(fields) ? fields : fields.split(',')).reduce( |
||||
(o, f) => ({ ...o, [f]: 1 }), |
||||
{} |
||||
); |
||||
} |
||||
} else if (col.uidt === UITypes.LinkToAnotherRecord) { |
||||
const model = await col |
||||
.getColOptions<LinkToAnotherRecordColumn>() |
||||
.then(colOpt => colOpt.getRelatedTable()); |
||||
|
||||
value = await getAst({ |
||||
model, |
||||
query: query?.nested, |
||||
extractOnlyPrimaries: true |
||||
}); |
||||
} |
||||
|
||||
return { |
||||
...(await obj), |
||||
[col.title]: |
||||
allowedCols && (!includePkByDefault || !col.pk) |
||||
? allowedCols[col.id] && |
||||
(!isSystemColumn(col) || view.show_system_fields) && |
||||
(!fields?.length || fields.includes(col.title)) && |
||||
value |
||||
: fields?.length |
||||
? fields.includes(col.title) |
||||
: value |
||||
}; |
||||
}, Promise.resolve({})); |
||||
}; |
||||
|
||||
type RequestQuery = { |
||||
[fields in 'f' | 'fields']?: string | string[]; |
||||
} & { |
||||
nested?: { |
||||
[field: string]: RequestQuery; |
||||
}; |
||||
}; |
||||
|
||||
export default getAst; |
@ -0,0 +1,19 @@
|
||||
import { Request } from 'express'; |
||||
import { Tele } from 'nc-help'; |
||||
|
||||
const countMap = {}; |
||||
|
||||
const metrics = async (req: Request) => { |
||||
if (!req?.route?.path) return; |
||||
const event = `a:api:${req.route.path}:${req.method}`; |
||||
countMap[event] = (countMap[event] || 0) + 1; |
||||
if (countMap[event] >= 50) { |
||||
Tele.event({ event }); |
||||
countMap[event] = 0; |
||||
} |
||||
}; |
||||
|
||||
export default async (req: Request, _res, next) => { |
||||
metrics(req).then(() => {}); |
||||
next(); |
||||
}; |
Loading…
Reference in new issue