Browse Source

feat: nested read api

Signed-off-by: Pranav C <61551451+pranavxc@users.noreply.github.com>
pull/401/head
Pranav C 3 years ago
parent
commit
4a8282bace
  1. 10
      packages/nc-gui/components/project/spreadsheet/components/expandedForm.vue
  2. 6
      packages/nc-gui/plugins/ncApis/gqlApi.js
  3. 4
      packages/nc-gui/plugins/ncApis/restApi.js
  4. 57
      packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts
  5. 3
      packages/nocodb/src/lib/noco/rest/RestCtrl.ts
  6. 20
      packages/nocodb/src/lib/sqlMgr/code/routers/xc-ts/SwaggerXc.ts

10
packages/nc-gui/components/project/spreadsheet/components/expandedForm.vue

@ -418,12 +418,12 @@ export default {
}
},
async reload() {
// const id = this.meta.columns.filter((c) => c.pk).map(c => this.localState[c._cn]).join('___');
const where = this.meta.columns.filter(c => c.pk).map(c => `(${c._cn},eq,${this.localState[c._cn]})`).join('~and')
const id = this.meta.columns.filter(c => c.pk).map(c => this.localState[c._cn]).join('___')
// const where = this.meta.columns.filter(c => c.pk).map(c => `(${c._cn},eq,${this.localState[c._cn]})`).join('~and')
this.$set(this, 'changedColumns', {})
// this.localState = await this.api.read(id);
const data = await this.api.list({ ...(this.queryParams || {}), where }) || [{}]
this.localState = data[0] || this.localState
this.localState = await this.api.read(id, this.queryParams || {})
// const data = await this.api.list({ ...(this.queryParams || {}), where }) || [{}]
// this.localState = data[0] || this.localState
if (!this.isNew && this.toggleDrawer) {
this.getAuditsAndComments()
}

6
packages/nc-gui/plugins/ncApis/gqlApi.js

@ -65,8 +65,8 @@ export default class GqlApi {
return `{${this.gqlQueryListName}${this.generateQueryParams(params)}{${this.gqlReqBody}${await this.gqlRelationReqBody(params)}}}`
}
gqlReadQuery(id) {
return `{${this.gqlQueryReadName}(id:"${id}"){${this.gqlReqBody}}}`
async gqlReadQuery(id) {
return `{${this.gqlQueryReadName}(id:"${id}"){${this.gqlReqBody}${await this.gqlRelationReqBody(params)}}}`
}
gqlCountQuery(params) {
@ -209,7 +209,7 @@ export default class GqlApi {
async read(id) {
const data = await this.post(`/nc/${this.$ctx.projectId}/v1/graphql`, {
query: this.gqlReadQuery(id),
query: await this.gqlReadQuery(id),
variables: null
})
return data.data.data[this.gqlQueryReadName]

4
packages/nc-gui/plugins/ncApis/restApi.js

@ -11,8 +11,8 @@ export default class RestApi {
return data.data
}
async read(id) {
const data = await this.get(`/nc/${this.$ctx.projectId}/api/v1/${this.table}/${id}`)
async read(id, params = {}) {
const data = await this.get(`/nc/${this.$ctx.projectId}/api/v1/${this.table}/${id}`, params)
return data.data
}

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

@ -1334,6 +1334,63 @@ class BaseModelSql extends BaseModel {
}
}
async nestedRead(id, {hm: childs = '', bt: parents = '', mm: many = '', where, fields: fields1, f, ...rest}) {
let fields = fields1 || f || '*';
try {
// todo: use fields in readbyPk
if (fields !== '*' && fields.split(',').indexOf(this.pks[0].cn) === -1) {
fields += ',' + this.pks[0].cn;
}
const item = await this.readByPk(id);
if (!item) return item;
for (const parent of parents.split(',')) {
const {cn} = this.belongsToRelations.find(({rtn}) => rtn === parent) || {};
if (fields !== '*' && fields.split(',').indexOf(cn) === -1) {
fields += ',' + cn;
}
}
const items = [item];
if (items && items.length) {
await Promise.all([...new Set(childs.split(','))].map((child, index) => child && this._getChildListInParent({
parent: items,
child
}, rest, index)));
}
await Promise.all(parents.split(',').map((parent, index): any => {
if (!parent) {
return;
}
const {cn, rcn} = this.belongsToRelations.find(({rtn}) => rtn === parent) || {};
const parentIds = [...new Set(items.map(c => c[cn] || c[this.columnToAlias[cn]]))];
return this._belongsTo({parent, rcn, parentIds, childs: items, cn, ...rest}, index);
}))
if (items && items.length) {
await Promise.all([...new Set(many.split(','))].map((child, index) => child && this._getManyToManyList({
parent: items,
child
}, rest, index)));
}
return item;
} catch (e) {
console.log(e);
throw e;
}
}
// todo: naming
public m2mNotChildren({pid = null, assoc = null, ...args}): Promise<any> {
if (pid === null || assoc === null) {

3
packages/nocodb/src/lib/noco/rest/RestCtrl.ts

@ -60,7 +60,8 @@ export class RestCtrl extends RestBaseCtrl {
}
public async get(req: Request | any, res): Promise<void> {
const data = await req.model.readByPk(req.params.id, req.query);
// const data = await req.model.readByPk(req.params.id, req.query);
const data = await req.model.nestedRead(req.params.id, req.query);
res.xcJson(data);
}

20
packages/nocodb/src/lib/sqlMgr/code/routers/xc-ts/SwaggerXc.ts

@ -221,7 +221,25 @@ class SwaggerXc extends BaseRender {
"required": true,
"type": "integer",
"format": "int64"
}
},
{
"in": "query",
"name": "bt",
"type": "String",
"description": "Comma separated parent table names(Belongs To)"
},
{
"in": "query",
"name": "hm",
"type": "String",
"description": "Comma separated child table names(Has Many)"
},
{
"in": "query",
"name": "mm",
"type": "String",
"description": "Comma separated child table names(Many to Many)"
},
],
"responses": {
"200": {

Loading…
Cancel
Save