mirror of https://github.com/nocodb/nocodb
Pranav C
1 year ago
7 changed files with 1301 additions and 1 deletions
@ -0,0 +1,20 @@ |
|||||||
|
import { Test, TestingModule } from '@nestjs/testing'; |
||||||
|
import { DatasController } from './datas.controller'; |
||||||
|
import { DatasService } from './datas.service'; |
||||||
|
|
||||||
|
describe('DatasController', () => { |
||||||
|
let controller: DatasController; |
||||||
|
|
||||||
|
beforeEach(async () => { |
||||||
|
const module: TestingModule = await Test.createTestingModule({ |
||||||
|
controllers: [DatasController], |
||||||
|
providers: [DatasService], |
||||||
|
}).compile(); |
||||||
|
|
||||||
|
controller = module.get<DatasController>(DatasController); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should be defined', () => { |
||||||
|
expect(controller).toBeDefined(); |
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,206 @@ |
|||||||
|
import { |
||||||
|
Body, |
||||||
|
Controller, |
||||||
|
Delete, |
||||||
|
Get, |
||||||
|
Param, |
||||||
|
Patch, |
||||||
|
Post, |
||||||
|
Request, |
||||||
|
} from '@nestjs/common'; |
||||||
|
import { Acl } from '../../middlewares/extract-project-id/extract-project-id.middleware'; |
||||||
|
import { DatasService } from './datas.service'; |
||||||
|
|
||||||
|
@Controller('datas') |
||||||
|
export class DatasController { |
||||||
|
constructor(private readonly datasService: DatasService) {} |
||||||
|
|
||||||
|
@Get('/data/:viewId/') |
||||||
|
@Acl('dataList') |
||||||
|
async dataList(@Request() req, @Param('viewId') viewId: string) { |
||||||
|
return await this.datasService.dataListByViewId({ |
||||||
|
viewId: viewId, |
||||||
|
query: req.query, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Get('/data/:viewId/:rowId/mm/:colId') |
||||||
|
@Acl('mmList') |
||||||
|
async mmList( |
||||||
|
@Request() req, |
||||||
|
@Param('viewId') viewId: string, |
||||||
|
@Param('colId') colId: string, |
||||||
|
@Param('rowId') rowId: string, |
||||||
|
) { |
||||||
|
return await this.datasService.mmList({ |
||||||
|
viewId: viewId, |
||||||
|
colId: colId, |
||||||
|
rowId: rowId, |
||||||
|
query: req.query, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Get('/data/:viewId/:rowId/mm/:colId/exclude') |
||||||
|
@Acl('mmExcludedList') |
||||||
|
async mmExcludedList( |
||||||
|
@Request() req, |
||||||
|
@Param('viewId') viewId: string, |
||||||
|
@Param('colId') colId: string, |
||||||
|
@Param('rowId') rowId: string, |
||||||
|
) { |
||||||
|
return await this.datasService.mmExcludedList({ |
||||||
|
viewId: viewId, |
||||||
|
colId: colId, |
||||||
|
rowId: rowId, |
||||||
|
query: req.query, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Get('/data/:viewId/:rowId/hm/:colId/exclude') |
||||||
|
@Acl('hmExcludedList') |
||||||
|
async hmExcludedList( |
||||||
|
@Request() req, |
||||||
|
@Param('viewId') viewId: string, |
||||||
|
@Param('colId') colId: string, |
||||||
|
@Param('rowId') rowId: string, |
||||||
|
) { |
||||||
|
await this.datasService.hmExcludedList({ |
||||||
|
viewId: viewId, |
||||||
|
colId: colId, |
||||||
|
rowId: rowId, |
||||||
|
query: req.query, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Get('/data/:viewId/:rowId/bt/:colId/exclude') |
||||||
|
@Acl('btExcludedList') |
||||||
|
async btExcludedList( |
||||||
|
@Request() req, |
||||||
|
@Param('viewId') viewId: string, |
||||||
|
@Param('colId') colId: string, |
||||||
|
@Param('rowId') rowId: string, |
||||||
|
) { |
||||||
|
return await this.datasService.btExcludedList({ |
||||||
|
viewId: viewId, |
||||||
|
colId: colId, |
||||||
|
rowId: rowId, |
||||||
|
query: req.query, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Get('/data/:viewId/:rowId/hm/:colId') |
||||||
|
@Acl('hmList') |
||||||
|
async hmList( |
||||||
|
@Request() req, |
||||||
|
@Param('viewId') viewId: string, |
||||||
|
@Param('colId') colId: string, |
||||||
|
@Param('rowId') rowId: string, |
||||||
|
) { |
||||||
|
return await this.datasService.hmList({ |
||||||
|
viewId: viewId, |
||||||
|
colId: colId, |
||||||
|
rowId: rowId, |
||||||
|
query: req.query, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Get('/data/:viewId/:rowId') |
||||||
|
@Acl('dataRead') |
||||||
|
async dataRead( |
||||||
|
@Request() req, |
||||||
|
@Param('viewId') viewId: string, |
||||||
|
@Param('rowId') rowId: string, |
||||||
|
) { |
||||||
|
return await this.datasService.dataReadByViewId({ |
||||||
|
viewId, |
||||||
|
rowId, |
||||||
|
query: req.query, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Post('/data/:viewId/') |
||||||
|
@Acl('dataInsert') |
||||||
|
async dataInsert( |
||||||
|
@Request() req, |
||||||
|
@Param('viewId') viewId: string, |
||||||
|
@Body() body: any, |
||||||
|
) { |
||||||
|
return await this.datasService.dataInsertByViewId({ |
||||||
|
viewId: viewId, |
||||||
|
body: body, |
||||||
|
cookie: req, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Patch('/data/:viewId/:rowId') |
||||||
|
@Acl('dataUpdate') |
||||||
|
async dataUpdate( |
||||||
|
@Request() req, |
||||||
|
@Param('viewId') viewId: string, |
||||||
|
@Param('rowId') rowId: string, |
||||||
|
@Body() body: any, |
||||||
|
) { |
||||||
|
return await this.datasService.dataUpdateByViewId({ |
||||||
|
viewId: viewId, |
||||||
|
rowId: rowId, |
||||||
|
body: body, |
||||||
|
cookie: req, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Delete('/data/:viewId/:rowId') |
||||||
|
@Acl('dataDelete') |
||||||
|
async dataDelete( |
||||||
|
@Request() req, |
||||||
|
@Param('viewId') viewId: string, |
||||||
|
@Param('rowId') rowId: string, |
||||||
|
) { |
||||||
|
return await this.datasService.dataDeleteByViewId({ |
||||||
|
viewId: viewId, |
||||||
|
rowId: rowId, |
||||||
|
cookie: req, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Delete('/data/:viewId/:rowId/:relationType/:colId/:childId') |
||||||
|
@Acl('relationDataDelete') |
||||||
|
async relationDataDelete( |
||||||
|
@Request() req, |
||||||
|
@Param('viewId') viewId: string, |
||||||
|
@Param('rowId') rowId: string, |
||||||
|
@Param('relationType') relationType: string, |
||||||
|
@Param('colId') colId: string, |
||||||
|
@Param('childId') childId: string, |
||||||
|
) { |
||||||
|
await this.datasService.relationDataDelete({ |
||||||
|
viewId: viewId, |
||||||
|
colId: colId, |
||||||
|
childId: childId, |
||||||
|
rowId: rowId, |
||||||
|
cookie: req, |
||||||
|
}); |
||||||
|
|
||||||
|
return { msg: 'The relation data has been deleted successfully' }; |
||||||
|
} |
||||||
|
|
||||||
|
@Post('/data/:viewId/:rowId/:relationType/:colId/:childId') |
||||||
|
@Acl('relationDataAdd') |
||||||
|
async relationDataAdd( |
||||||
|
@Request() req, |
||||||
|
@Param('viewId') viewId: string, |
||||||
|
@Param('rowId') rowId: string, |
||||||
|
@Param('relationType') relationType: string, |
||||||
|
@Param('colId') colId: string, |
||||||
|
@Param('childId') childId: string, |
||||||
|
) { |
||||||
|
await this.datasService.relationDataAdd({ |
||||||
|
viewId: viewId, |
||||||
|
colId: colId, |
||||||
|
childId: childId, |
||||||
|
rowId: rowId, |
||||||
|
cookie: req, |
||||||
|
}); |
||||||
|
|
||||||
|
return { msg: 'The relation data has been created successfully' }; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
import { Module } from '@nestjs/common'; |
||||||
|
import { DatasService } from './datas.service'; |
||||||
|
import { DatasController } from './datas.controller'; |
||||||
|
|
||||||
|
@Module({ |
||||||
|
controllers: [DatasController], |
||||||
|
providers: [DatasService] |
||||||
|
}) |
||||||
|
export class DatasModule {} |
@ -0,0 +1,18 @@ |
|||||||
|
import { Test, TestingModule } from '@nestjs/testing'; |
||||||
|
import { DatasService } from './datas.service'; |
||||||
|
|
||||||
|
describe('DatasService', () => { |
||||||
|
let service: DatasService; |
||||||
|
|
||||||
|
beforeEach(async () => { |
||||||
|
const module: TestingModule = await Test.createTestingModule({ |
||||||
|
providers: [DatasService], |
||||||
|
}).compile(); |
||||||
|
|
||||||
|
service = module.get<DatasService>(DatasService); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should be defined', () => { |
||||||
|
expect(service).toBeDefined(); |
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,768 @@ |
|||||||
|
import { Injectable } from '@nestjs/common'; |
||||||
|
import { NcError } from '../../helpers/catchError'; |
||||||
|
import getAst from '../../helpers/getAst'; |
||||||
|
import { PagedResponseImpl } from '../../helpers/PagedResponse'; |
||||||
|
import { Base, Model, View } from '../../models'; |
||||||
|
import NcConnectionMgrv2 from '../../utils/common/NcConnectionMgrv2'; |
||||||
|
import { getViewAndModelByAliasOrId, PathParams } from './helpers'; |
||||||
|
import { nocoExecute } from 'nc-help'; |
||||||
|
|
||||||
|
@Injectable() |
||||||
|
export class DatasService { |
||||||
|
async dataList(param: PathParams & { query: any }) { |
||||||
|
const { model, view } = await getViewAndModelByAliasOrId(param); |
||||||
|
const responseData = await this.getDataList({ |
||||||
|
model, |
||||||
|
view, |
||||||
|
query: param.query, |
||||||
|
}); |
||||||
|
return responseData; |
||||||
|
} |
||||||
|
|
||||||
|
async dataFindOne(param: PathParams & { query: any }) { |
||||||
|
const { model, view } = await getViewAndModelByAliasOrId(param); |
||||||
|
return await this.getFindOne({ model, view, query: param.query }); |
||||||
|
} |
||||||
|
|
||||||
|
async dataGroupBy(param: PathParams & { query: any }) { |
||||||
|
const { model, view } = await getViewAndModelByAliasOrId(param); |
||||||
|
return await this.getDataGroupBy({ model, view, query: param.query }); |
||||||
|
} |
||||||
|
|
||||||
|
async dataCount(param: PathParams & { query: any }) { |
||||||
|
const { model, view } = await getViewAndModelByAliasOrId(param); |
||||||
|
|
||||||
|
const base = await Base.get(model.base_id); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: model.id, |
||||||
|
viewId: view?.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
const countArgs: any = { ...param.query }; |
||||||
|
try { |
||||||
|
countArgs.filterArr = JSON.parse(countArgs.filterArrJson); |
||||||
|
} catch (e) {} |
||||||
|
|
||||||
|
const count: number = await baseModel.count(countArgs); |
||||||
|
|
||||||
|
return { count }; |
||||||
|
} |
||||||
|
|
||||||
|
async dataInsert(param: PathParams & { body: unknown; cookie: any }) { |
||||||
|
const { model, view } = await getViewAndModelByAliasOrId(param); |
||||||
|
|
||||||
|
const base = await Base.get(model.base_id); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: model.id, |
||||||
|
viewId: view?.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
return await baseModel.insert(param.body, null, param.cookie); |
||||||
|
} |
||||||
|
|
||||||
|
async dataUpdate( |
||||||
|
param: PathParams & { body: unknown; cookie: any; rowId: string }, |
||||||
|
) { |
||||||
|
const { model, view } = await getViewAndModelByAliasOrId(param); |
||||||
|
const base = await Base.get(model.base_id); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: model.id, |
||||||
|
viewId: view?.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
return await baseModel.updateByPk( |
||||||
|
param.rowId, |
||||||
|
param.body, |
||||||
|
null, |
||||||
|
param.cookie, |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
async dataDelete(param: PathParams & { rowId: string; cookie: any }) { |
||||||
|
const { model, view } = await getViewAndModelByAliasOrId(param); |
||||||
|
const base = await Base.get(model.base_id); |
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: model.id, |
||||||
|
viewId: view?.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
// todo: Should have error http status code
|
||||||
|
const message = await baseModel.hasLTARData(param.rowId, model); |
||||||
|
if (message.length) { |
||||||
|
return { message }; |
||||||
|
} |
||||||
|
return await baseModel.delByPk(param.rowId, null, param.cookie); |
||||||
|
} |
||||||
|
|
||||||
|
async getDataList(param: { model: Model; view: View; query: any }) { |
||||||
|
const { model, view, query = {} } = param; |
||||||
|
|
||||||
|
const base = await Base.get(model.base_id); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: model.id, |
||||||
|
viewId: view?.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
const { ast, dependencyFields } = await getAst({ model, query, view }); |
||||||
|
|
||||||
|
const listArgs: any = dependencyFields; |
||||||
|
try { |
||||||
|
listArgs.filterArr = JSON.parse(listArgs.filterArrJson); |
||||||
|
} catch (e) {} |
||||||
|
try { |
||||||
|
listArgs.sortArr = JSON.parse(listArgs.sortArrJson); |
||||||
|
} catch (e) {} |
||||||
|
|
||||||
|
let data = []; |
||||||
|
let count = 0; |
||||||
|
try { |
||||||
|
data = await nocoExecute( |
||||||
|
ast, |
||||||
|
await baseModel.list(listArgs), |
||||||
|
{}, |
||||||
|
listArgs, |
||||||
|
); |
||||||
|
count = await baseModel.count(listArgs); |
||||||
|
} catch (e) { |
||||||
|
console.log(e); |
||||||
|
NcError.internalServerError( |
||||||
|
'Internal Server Error, check server log for more details', |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
return new PagedResponseImpl(data, { |
||||||
|
...query, |
||||||
|
count, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
async getFindOne(param: { model: Model; view: View; query: any }) { |
||||||
|
const { model, view, query = {} } = param; |
||||||
|
|
||||||
|
const base = await Base.get(model.base_id); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: model.id, |
||||||
|
viewId: view?.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
const args: any = { ...query }; |
||||||
|
try { |
||||||
|
args.filterArr = JSON.parse(args.filterArrJson); |
||||||
|
} catch (e) {} |
||||||
|
try { |
||||||
|
args.sortArr = JSON.parse(args.sortArrJson); |
||||||
|
} catch (e) {} |
||||||
|
|
||||||
|
const { ast, dependencyFields } = await getAst({ |
||||||
|
model, |
||||||
|
query: args, |
||||||
|
view, |
||||||
|
}); |
||||||
|
|
||||||
|
const data = await baseModel.findOne({ ...args, dependencyFields }); |
||||||
|
return data ? await nocoExecute(ast, data, {}, {}) : {}; |
||||||
|
} |
||||||
|
|
||||||
|
async getDataGroupBy(param: { model: Model; view: View; query?: any }) { |
||||||
|
const { model, view, query = {} } = param; |
||||||
|
|
||||||
|
const base = await Base.get(model.base_id); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: model.id, |
||||||
|
viewId: view?.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
const listArgs: any = { ...query }; |
||||||
|
const data = await baseModel.groupBy({ ...query }); |
||||||
|
const count = await baseModel.count(listArgs); |
||||||
|
|
||||||
|
return new PagedResponseImpl(data, { |
||||||
|
...query, |
||||||
|
count, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
async dataRead(param: PathParams & { query: any; rowId: string }) { |
||||||
|
const { model, view } = await getViewAndModelByAliasOrId(param); |
||||||
|
|
||||||
|
const base = await Base.get(model.base_id); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: model.id, |
||||||
|
viewId: view?.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
const row = await baseModel.readByPk(param.rowId); |
||||||
|
|
||||||
|
if (!row) { |
||||||
|
NcError.notFound('Row not found'); |
||||||
|
} |
||||||
|
|
||||||
|
const { ast } = await getAst({ model, query: param.query, view }); |
||||||
|
|
||||||
|
return await nocoExecute(ast, row, {}, param.query); |
||||||
|
} |
||||||
|
|
||||||
|
async dataExist(param: PathParams & { rowId: string; query: any }) { |
||||||
|
const { model, view } = await getViewAndModelByAliasOrId(param); |
||||||
|
|
||||||
|
const base = await Base.get(model.base_id); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: model.id, |
||||||
|
viewId: view?.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
return await baseModel.exist(param.rowId); |
||||||
|
} |
||||||
|
|
||||||
|
// todo: Handle the error case where view doesnt belong to model
|
||||||
|
async groupedDataList(param: PathParams & { query: any; columnId: string }) { |
||||||
|
const { model, view } = await getViewAndModelByAliasOrId(param); |
||||||
|
const groupedData = await this.getGroupedDataList({ |
||||||
|
model, |
||||||
|
view, |
||||||
|
query: param.query, |
||||||
|
columnId: param.columnId, |
||||||
|
}); |
||||||
|
return groupedData; |
||||||
|
} |
||||||
|
|
||||||
|
async getGroupedDataList(param: { |
||||||
|
model; |
||||||
|
view: View; |
||||||
|
query: any; |
||||||
|
columnId: string; |
||||||
|
}) { |
||||||
|
const { model, view, query = {} } = param; |
||||||
|
|
||||||
|
const base = await Base.get(model.base_id); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: model.id, |
||||||
|
viewId: view?.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
const { ast } = await getAst({ model, query, view }); |
||||||
|
|
||||||
|
const listArgs: any = { ...query }; |
||||||
|
try { |
||||||
|
listArgs.filterArr = JSON.parse(listArgs.filterArrJson); |
||||||
|
} catch (e) {} |
||||||
|
try { |
||||||
|
listArgs.sortArr = JSON.parse(listArgs.sortArrJson); |
||||||
|
} catch (e) {} |
||||||
|
try { |
||||||
|
listArgs.options = JSON.parse(listArgs.optionsArrJson); |
||||||
|
} catch (e) {} |
||||||
|
|
||||||
|
let data = []; |
||||||
|
|
||||||
|
const groupedData = await baseModel.groupedList({ |
||||||
|
...listArgs, |
||||||
|
groupColumnId: param.columnId, |
||||||
|
}); |
||||||
|
data = await nocoExecute({ key: 1, value: ast }, groupedData, {}, listArgs); |
||||||
|
const countArr = await baseModel.groupedListCount({ |
||||||
|
...listArgs, |
||||||
|
groupColumnId: param.columnId, |
||||||
|
}); |
||||||
|
data = data.map((item) => { |
||||||
|
// todo: use map to avoid loop
|
||||||
|
const count = |
||||||
|
countArr.find((countItem: any) => countItem.key === item.key)?.count ?? |
||||||
|
0; |
||||||
|
|
||||||
|
item.value = new PagedResponseImpl(item.value, { |
||||||
|
...query, |
||||||
|
count: count, |
||||||
|
}); |
||||||
|
return item; |
||||||
|
}); |
||||||
|
|
||||||
|
return data; |
||||||
|
} |
||||||
|
|
||||||
|
async dataListByViewId(param: { viewId: string; query: any }) { |
||||||
|
const view = await View.get(param.viewId); |
||||||
|
|
||||||
|
const model = await Model.getByIdOrName({ |
||||||
|
id: view?.fk_model_id || param.viewId, |
||||||
|
}); |
||||||
|
|
||||||
|
if (!model) NcError.notFound('Table not found'); |
||||||
|
|
||||||
|
return await this.getDataList({ model, view, query: param.query }); |
||||||
|
} |
||||||
|
|
||||||
|
async mmList(param: { |
||||||
|
viewId: string; |
||||||
|
colId: string; |
||||||
|
query: any; |
||||||
|
rowId: string; |
||||||
|
}) { |
||||||
|
const view = await View.get(param.viewId); |
||||||
|
|
||||||
|
const model = await Model.getByIdOrName({ |
||||||
|
id: view?.fk_model_id || param.viewId, |
||||||
|
}); |
||||||
|
|
||||||
|
if (!model) NcError.notFound('Table not found'); |
||||||
|
|
||||||
|
const base = await Base.get(model.base_id); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: model.id, |
||||||
|
viewId: view?.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
const key = `${model.title}List`; |
||||||
|
const requestObj: any = { |
||||||
|
[key]: 1, |
||||||
|
}; |
||||||
|
|
||||||
|
const data = ( |
||||||
|
await nocoExecute( |
||||||
|
requestObj, |
||||||
|
{ |
||||||
|
[key]: async (args) => { |
||||||
|
return await baseModel.mmList( |
||||||
|
{ |
||||||
|
colId: param.colId, |
||||||
|
parentId: param.rowId, |
||||||
|
}, |
||||||
|
args, |
||||||
|
); |
||||||
|
}, |
||||||
|
}, |
||||||
|
{}, |
||||||
|
|
||||||
|
{ nested: { [key]: param.query } }, |
||||||
|
) |
||||||
|
)?.[key]; |
||||||
|
|
||||||
|
const count: any = await baseModel.mmListCount({ |
||||||
|
colId: param.colId, |
||||||
|
parentId: param.rowId, |
||||||
|
}); |
||||||
|
|
||||||
|
return new PagedResponseImpl(data, { |
||||||
|
count, |
||||||
|
...param.query, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
async mmExcludedList(param: { |
||||||
|
viewId: string; |
||||||
|
colId: string; |
||||||
|
query: any; |
||||||
|
rowId: string; |
||||||
|
}) { |
||||||
|
const view = await View.get(param.viewId); |
||||||
|
|
||||||
|
const model = await Model.getByIdOrName({ |
||||||
|
id: view?.fk_model_id || param.viewId, |
||||||
|
}); |
||||||
|
|
||||||
|
if (!model) NcError.notFound('Table not found'); |
||||||
|
|
||||||
|
const base = await Base.get(model.base_id); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: model.id, |
||||||
|
viewId: view?.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
const key = 'List'; |
||||||
|
const requestObj: any = { |
||||||
|
[key]: 1, |
||||||
|
}; |
||||||
|
|
||||||
|
const data = ( |
||||||
|
await nocoExecute( |
||||||
|
requestObj, |
||||||
|
{ |
||||||
|
[key]: async (args) => { |
||||||
|
return await baseModel.getMmChildrenExcludedList( |
||||||
|
{ |
||||||
|
colId: param.colId, |
||||||
|
pid: param.rowId, |
||||||
|
}, |
||||||
|
args, |
||||||
|
); |
||||||
|
}, |
||||||
|
}, |
||||||
|
{}, |
||||||
|
|
||||||
|
{ nested: { [key]: param.query } }, |
||||||
|
) |
||||||
|
)?.[key]; |
||||||
|
|
||||||
|
const count = await baseModel.getMmChildrenExcludedListCount( |
||||||
|
{ |
||||||
|
colId: param.colId, |
||||||
|
pid: param.rowId, |
||||||
|
}, |
||||||
|
param.query, |
||||||
|
); |
||||||
|
|
||||||
|
return new PagedResponseImpl(data, { |
||||||
|
count, |
||||||
|
...param.query, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
async hmExcludedList(param: { |
||||||
|
viewId: string; |
||||||
|
colId: string; |
||||||
|
query: any; |
||||||
|
rowId: string; |
||||||
|
}) { |
||||||
|
const view = await View.get(param.viewId); |
||||||
|
|
||||||
|
const model = await Model.getByIdOrName({ |
||||||
|
id: view?.fk_model_id || param.viewId, |
||||||
|
}); |
||||||
|
|
||||||
|
if (!model) NcError.notFound('Table not found'); |
||||||
|
|
||||||
|
const base = await Base.get(model.base_id); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: model.id, |
||||||
|
viewId: view?.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
const key = 'List'; |
||||||
|
const requestObj: any = { |
||||||
|
[key]: 1, |
||||||
|
}; |
||||||
|
|
||||||
|
const data = ( |
||||||
|
await nocoExecute( |
||||||
|
requestObj, |
||||||
|
{ |
||||||
|
[key]: async (args) => { |
||||||
|
return await baseModel.getHmChildrenExcludedList( |
||||||
|
{ |
||||||
|
colId: param.colId, |
||||||
|
pid: param.rowId, |
||||||
|
}, |
||||||
|
args, |
||||||
|
); |
||||||
|
}, |
||||||
|
}, |
||||||
|
{}, |
||||||
|
|
||||||
|
{ nested: { [key]: param.query } }, |
||||||
|
) |
||||||
|
)?.[key]; |
||||||
|
|
||||||
|
const count = await baseModel.getHmChildrenExcludedListCount( |
||||||
|
{ |
||||||
|
colId: param.colId, |
||||||
|
pid: param.rowId, |
||||||
|
}, |
||||||
|
param.query, |
||||||
|
); |
||||||
|
|
||||||
|
return new PagedResponseImpl(data, { |
||||||
|
count, |
||||||
|
...param.query, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
async btExcludedList(param: { |
||||||
|
viewId: string; |
||||||
|
colId: string; |
||||||
|
query: any; |
||||||
|
rowId: string; |
||||||
|
}) { |
||||||
|
const view = await View.get(param.viewId); |
||||||
|
|
||||||
|
const model = await Model.getByIdOrName({ |
||||||
|
id: view?.fk_model_id || param.viewId, |
||||||
|
}); |
||||||
|
|
||||||
|
if (!model) return NcError.notFound('Table not found'); |
||||||
|
|
||||||
|
const base = await Base.get(model.base_id); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: model.id, |
||||||
|
viewId: view?.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
const key = 'List'; |
||||||
|
const requestObj: any = { |
||||||
|
[key]: 1, |
||||||
|
}; |
||||||
|
|
||||||
|
const data = ( |
||||||
|
await nocoExecute( |
||||||
|
requestObj, |
||||||
|
{ |
||||||
|
[key]: async (args) => { |
||||||
|
return await baseModel.getBtChildrenExcludedList( |
||||||
|
{ |
||||||
|
colId: param.colId, |
||||||
|
cid: param.rowId, |
||||||
|
}, |
||||||
|
args, |
||||||
|
); |
||||||
|
}, |
||||||
|
}, |
||||||
|
{}, |
||||||
|
|
||||||
|
{ nested: { [key]: param.query } }, |
||||||
|
) |
||||||
|
)?.[key]; |
||||||
|
|
||||||
|
const count = await baseModel.getBtChildrenExcludedListCount( |
||||||
|
{ |
||||||
|
colId: param.colId, |
||||||
|
cid: param.rowId, |
||||||
|
}, |
||||||
|
param.query, |
||||||
|
); |
||||||
|
|
||||||
|
return new PagedResponseImpl(data, { |
||||||
|
count, |
||||||
|
...param.query, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
async hmList(param: { |
||||||
|
viewId: string; |
||||||
|
colId: string; |
||||||
|
query: any; |
||||||
|
rowId: string; |
||||||
|
}) { |
||||||
|
const view = await View.get(param.viewId); |
||||||
|
|
||||||
|
const model = await Model.getByIdOrName({ |
||||||
|
id: view?.fk_model_id || param.viewId, |
||||||
|
}); |
||||||
|
|
||||||
|
if (!model) NcError.notFound('Table not found'); |
||||||
|
|
||||||
|
const base = await Base.get(model.base_id); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: model.id, |
||||||
|
viewId: view?.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
const key = `${model.title}List`; |
||||||
|
const requestObj: any = { |
||||||
|
[key]: 1, |
||||||
|
}; |
||||||
|
|
||||||
|
const data = ( |
||||||
|
await nocoExecute( |
||||||
|
requestObj, |
||||||
|
{ |
||||||
|
[key]: async (args) => { |
||||||
|
return await baseModel.hmList( |
||||||
|
{ |
||||||
|
colId: param.colId, |
||||||
|
id: param.rowId, |
||||||
|
}, |
||||||
|
args, |
||||||
|
); |
||||||
|
}, |
||||||
|
}, |
||||||
|
{}, |
||||||
|
{ nested: { [key]: param.query } }, |
||||||
|
) |
||||||
|
)?.[key]; |
||||||
|
|
||||||
|
const count = await baseModel.hmListCount({ |
||||||
|
colId: param.colId, |
||||||
|
id: param.rowId, |
||||||
|
}); |
||||||
|
|
||||||
|
return new PagedResponseImpl(data, { |
||||||
|
totalRows: count, |
||||||
|
} as any); |
||||||
|
} |
||||||
|
|
||||||
|
async dataReadByViewId(param: { viewId: string; rowId: string; query: any }) { |
||||||
|
try { |
||||||
|
const model = await Model.getByIdOrName({ |
||||||
|
id: param.viewId, |
||||||
|
}); |
||||||
|
if (!model) NcError.notFound('Table not found'); |
||||||
|
|
||||||
|
const base = await Base.get(model.base_id); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: model.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
const { ast } = await getAst({ model, query: param.query }); |
||||||
|
|
||||||
|
return await nocoExecute( |
||||||
|
ast, |
||||||
|
await baseModel.readByPk(param.rowId), |
||||||
|
{}, |
||||||
|
{}, |
||||||
|
); |
||||||
|
} catch (e) { |
||||||
|
console.log(e); |
||||||
|
NcError.internalServerError( |
||||||
|
'Internal Server Error, check server log for more details', |
||||||
|
); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
async dataInsertByViewId(param: { viewId: string; body: any; cookie: any }) { |
||||||
|
const model = await Model.getByIdOrName({ |
||||||
|
id: param.viewId, |
||||||
|
}); |
||||||
|
if (!model) return NcError.notFound('Table not found'); |
||||||
|
|
||||||
|
const base = await Base.get(model.base_id); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: model.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
return await baseModel.insert(param.body, null, param.cookie); |
||||||
|
} |
||||||
|
|
||||||
|
async dataUpdateByViewId(param: { |
||||||
|
viewId: string; |
||||||
|
rowId: string; |
||||||
|
body: any; |
||||||
|
cookie: any; |
||||||
|
}) { |
||||||
|
const model = await Model.getByIdOrName({ |
||||||
|
id: param.viewId, |
||||||
|
}); |
||||||
|
if (!model) NcError.notFound('Table not found'); |
||||||
|
|
||||||
|
const base = await Base.get(model.base_id); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: model.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
return await baseModel.updateByPk( |
||||||
|
param.rowId, |
||||||
|
param.body, |
||||||
|
null, |
||||||
|
param.cookie, |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
async dataDeleteByViewId(param: { |
||||||
|
viewId: string; |
||||||
|
rowId: string; |
||||||
|
cookie: any; |
||||||
|
}) { |
||||||
|
const model = await Model.getByIdOrName({ |
||||||
|
id: param.viewId, |
||||||
|
}); |
||||||
|
if (!model) NcError.notFound('Table not found'); |
||||||
|
|
||||||
|
const base = await Base.get(model.base_id); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: model.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
return await baseModel.delByPk(param.rowId, null, param.cookie); |
||||||
|
} |
||||||
|
|
||||||
|
async relationDataDelete(param: { |
||||||
|
viewId: string; |
||||||
|
colId: string; |
||||||
|
childId: string; |
||||||
|
rowId: string; |
||||||
|
cookie: any; |
||||||
|
}) { |
||||||
|
const view = await View.get(param.viewId); |
||||||
|
|
||||||
|
const model = await Model.getByIdOrName({ |
||||||
|
id: view?.fk_model_id || param.viewId, |
||||||
|
}); |
||||||
|
|
||||||
|
if (!model) NcError.notFound('Table not found'); |
||||||
|
|
||||||
|
const base = await Base.get(model.base_id); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: model.id, |
||||||
|
viewId: view?.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
await baseModel.removeChild({ |
||||||
|
colId: param.colId, |
||||||
|
childId: param.childId, |
||||||
|
rowId: param.rowId, |
||||||
|
cookie: param.cookie, |
||||||
|
}); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
async relationDataAdd(param: { |
||||||
|
viewId: string; |
||||||
|
colId: string; |
||||||
|
childId: string; |
||||||
|
rowId: string; |
||||||
|
cookie: any; |
||||||
|
}) { |
||||||
|
const view = await View.get(param.viewId); |
||||||
|
|
||||||
|
const model = await Model.getByIdOrName({ |
||||||
|
id: view?.fk_model_id || param.viewId, |
||||||
|
}); |
||||||
|
|
||||||
|
if (!model) NcError.notFound('Table not found'); |
||||||
|
|
||||||
|
const base = await Base.get(model.base_id); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: model.id, |
||||||
|
viewId: view?.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
await baseModel.addChild({ |
||||||
|
colId: param.colId, |
||||||
|
childId: param.childId, |
||||||
|
rowId: param.rowId, |
||||||
|
cookie: param.cookie, |
||||||
|
}); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,278 @@ |
|||||||
|
import { nocoExecute } from 'nc-help'; |
||||||
|
import { isSystemColumn, UITypes } from 'nocodb-sdk'; |
||||||
|
import * as XLSX from 'xlsx'; |
||||||
|
import papaparse from 'papaparse'; |
||||||
|
import getAst from '../../db/sql-data-mapper/lib/sql/helpers/getAst'; |
||||||
|
import { NcError } from '../../meta/helpers/catchError'; |
||||||
|
import { Model, View } from '../../models'; |
||||||
|
import Base from '../../models/Base'; |
||||||
|
import Column from '../../models/Column'; |
||||||
|
import Project from '../../models/Project'; |
||||||
|
import NcConnectionMgrv2 from '../../utils/common/NcConnectionMgrv2'; |
||||||
|
import type LinkToAnotherRecordColumn from '../../models/LinkToAnotherRecordColumn'; |
||||||
|
import type LookupColumn from '../../models/LookupColumn'; |
||||||
|
import type { BaseModelSqlv2 } from '../../db/sql-data-mapper/lib/sql/BaseModelSqlv2'; |
||||||
|
import type { Request } from 'express'; |
||||||
|
|
||||||
|
export interface PathParams { |
||||||
|
projectName: string; |
||||||
|
tableName: string; |
||||||
|
viewName?: string; |
||||||
|
} |
||||||
|
|
||||||
|
export async function getViewAndModelByAliasOrId(param: { |
||||||
|
projectName: string; |
||||||
|
tableName: string; |
||||||
|
viewName?: string; |
||||||
|
}) { |
||||||
|
const project = await Project.getWithInfoByTitleOrId(param.projectName); |
||||||
|
|
||||||
|
const model = await Model.getByAliasOrId({ |
||||||
|
project_id: project.id, |
||||||
|
aliasOrId: param.tableName, |
||||||
|
}); |
||||||
|
const view = |
||||||
|
param.viewName && |
||||||
|
(await View.getByTitleOrId({ |
||||||
|
titleOrId: param.viewName, |
||||||
|
fk_model_id: model.id, |
||||||
|
})); |
||||||
|
if (!model) NcError.notFound('Table not found'); |
||||||
|
return { model, view }; |
||||||
|
} |
||||||
|
|
||||||
|
export async function extractXlsxData(view: View, req: Request) { |
||||||
|
const base = await Base.get(view.base_id); |
||||||
|
|
||||||
|
await view.getModelWithInfo(); |
||||||
|
await view.getColumns(); |
||||||
|
|
||||||
|
view.model.columns = view.columns |
||||||
|
.filter((c) => c.show) |
||||||
|
.map( |
||||||
|
(c) => |
||||||
|
new Column({ ...c, ...view.model.columnsById[c.fk_column_id] } as any) |
||||||
|
) |
||||||
|
.filter((column) => !isSystemColumn(column) || view.show_system_fields); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: view.model.id, |
||||||
|
viewId: view?.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
const { offset, dbRows, elapsed } = await getDbRows({ |
||||||
|
baseModel, |
||||||
|
view, |
||||||
|
siteUrl: (req as any).ncSiteUrl, |
||||||
|
query: req.query, |
||||||
|
}); |
||||||
|
|
||||||
|
const fields = req.query.fields as string[]; |
||||||
|
|
||||||
|
const data = XLSX.utils.json_to_sheet(dbRows, { header: fields }); |
||||||
|
|
||||||
|
return { offset, dbRows, elapsed, data }; |
||||||
|
} |
||||||
|
|
||||||
|
export async function extractCsvData(view: View, req: Request) { |
||||||
|
const base = await Base.get(view.base_id); |
||||||
|
const fields = req.query.fields; |
||||||
|
|
||||||
|
await view.getModelWithInfo(); |
||||||
|
await view.getColumns(); |
||||||
|
|
||||||
|
view.model.columns = view.columns |
||||||
|
.filter((c) => c.show) |
||||||
|
.map( |
||||||
|
(c) => |
||||||
|
new Column({ ...c, ...view.model.columnsById[c.fk_column_id] } as any) |
||||||
|
) |
||||||
|
.filter((column) => !isSystemColumn(column) || view.show_system_fields); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: view.model.id, |
||||||
|
viewId: view?.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
const { offset, dbRows, elapsed } = await getDbRows({ |
||||||
|
baseModel, |
||||||
|
view, |
||||||
|
query: req.query, |
||||||
|
siteUrl: (req as any).ncSiteUrl, |
||||||
|
}); |
||||||
|
|
||||||
|
const data = papaparse.unparse( |
||||||
|
{ |
||||||
|
fields: view.model.columns |
||||||
|
.sort((c1, c2) => |
||||||
|
Array.isArray(fields) |
||||||
|
? fields.indexOf(c1.title as any) - fields.indexOf(c2.title as any) |
||||||
|
: 0 |
||||||
|
) |
||||||
|
.filter( |
||||||
|
(c) => |
||||||
|
!fields || !Array.isArray(fields) || fields.includes(c.title as any) |
||||||
|
) |
||||||
|
.map((c) => c.title), |
||||||
|
data: dbRows, |
||||||
|
}, |
||||||
|
{ |
||||||
|
escapeFormulae: true, |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
return { offset, dbRows, elapsed, data }; |
||||||
|
} |
||||||
|
|
||||||
|
export async function serializeCellValue({ |
||||||
|
value, |
||||||
|
column, |
||||||
|
siteUrl, |
||||||
|
}: { |
||||||
|
column?: Column; |
||||||
|
value: any; |
||||||
|
siteUrl: string; |
||||||
|
}) { |
||||||
|
if (!column) { |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
if (!value) return value; |
||||||
|
|
||||||
|
switch (column?.uidt) { |
||||||
|
case UITypes.Attachment: { |
||||||
|
let data = value; |
||||||
|
try { |
||||||
|
if (typeof value === 'string') { |
||||||
|
data = JSON.parse(value); |
||||||
|
} |
||||||
|
} catch {} |
||||||
|
|
||||||
|
return (data || []).map( |
||||||
|
(attachment) => |
||||||
|
`${encodeURI(attachment.title)}(${encodeURI( |
||||||
|
attachment.path ? `${siteUrl}/${attachment.path}` : attachment.url |
||||||
|
)})` |
||||||
|
); |
||||||
|
} |
||||||
|
case UITypes.Lookup: |
||||||
|
{ |
||||||
|
const colOptions = await column.getColOptions<LookupColumn>(); |
||||||
|
const lookupColumn = await colOptions.getLookupColumn(); |
||||||
|
return ( |
||||||
|
await Promise.all( |
||||||
|
[...(Array.isArray(value) ? value : [value])].map(async (v) => |
||||||
|
serializeCellValue({ |
||||||
|
value: v, |
||||||
|
column: lookupColumn, |
||||||
|
siteUrl, |
||||||
|
}) |
||||||
|
) |
||||||
|
) |
||||||
|
).join(', '); |
||||||
|
} |
||||||
|
break; |
||||||
|
case UITypes.LinkToAnotherRecord: |
||||||
|
{ |
||||||
|
const colOptions = |
||||||
|
await column.getColOptions<LinkToAnotherRecordColumn>(); |
||||||
|
const relatedModel = await colOptions.getRelatedTable(); |
||||||
|
await relatedModel.getColumns(); |
||||||
|
return [...(Array.isArray(value) ? value : [value])] |
||||||
|
.map((v) => { |
||||||
|
return v[relatedModel.displayValue?.title]; |
||||||
|
}) |
||||||
|
.join(', '); |
||||||
|
} |
||||||
|
break; |
||||||
|
default: |
||||||
|
if (value && typeof value === 'object') { |
||||||
|
return JSON.stringify(value); |
||||||
|
} |
||||||
|
return value; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export async function getColumnByIdOrName( |
||||||
|
columnNameOrId: string, |
||||||
|
model: Model |
||||||
|
) { |
||||||
|
const column = (await model.getColumns()).find( |
||||||
|
(c) => |
||||||
|
c.title === columnNameOrId || |
||||||
|
c.id === columnNameOrId || |
||||||
|
c.column_name === columnNameOrId |
||||||
|
); |
||||||
|
|
||||||
|
if (!column) |
||||||
|
NcError.notFound(`Column with id/name '${columnNameOrId}' is not found`); |
||||||
|
|
||||||
|
return column; |
||||||
|
} |
||||||
|
|
||||||
|
export async function getDbRows(param: { |
||||||
|
baseModel: BaseModelSqlv2; |
||||||
|
view: View; |
||||||
|
query: any; |
||||||
|
siteUrl: string; |
||||||
|
}) { |
||||||
|
const { baseModel, view, query = {}, siteUrl } = param; |
||||||
|
let offset = +query.offset || 0; |
||||||
|
const limit = 100; |
||||||
|
// const size = +process.env.NC_EXPORT_MAX_SIZE || 1024;
|
||||||
|
const timeout = +process.env.NC_EXPORT_MAX_TIMEOUT || 5000; |
||||||
|
const dbRows = []; |
||||||
|
const startTime = process.hrtime(); |
||||||
|
let elapsed, temp; |
||||||
|
|
||||||
|
const listArgs: any = { ...query }; |
||||||
|
try { |
||||||
|
listArgs.filterArr = JSON.parse(listArgs.filterArrJson); |
||||||
|
} catch (e) {} |
||||||
|
try { |
||||||
|
listArgs.sortArr = JSON.parse(listArgs.sortArrJson); |
||||||
|
} catch (e) {} |
||||||
|
|
||||||
|
for ( |
||||||
|
elapsed = 0; |
||||||
|
elapsed < timeout; |
||||||
|
offset += limit, |
||||||
|
temp = process.hrtime(startTime), |
||||||
|
elapsed = temp[0] * 1000 + temp[1] / 1000000 |
||||||
|
) { |
||||||
|
const { ast, dependencyFields } = await getAst({ |
||||||
|
query: query, |
||||||
|
includePkByDefault: false, |
||||||
|
model: view.model, |
||||||
|
view, |
||||||
|
}); |
||||||
|
const rows = await nocoExecute( |
||||||
|
ast, |
||||||
|
await baseModel.list({ ...listArgs, ...dependencyFields, offset, limit }), |
||||||
|
{}, |
||||||
|
query |
||||||
|
); |
||||||
|
|
||||||
|
if (!rows?.length) { |
||||||
|
offset = -1; |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
for (const row of rows) { |
||||||
|
const dbRow = { ...row }; |
||||||
|
|
||||||
|
for (const column of view.model.columns) { |
||||||
|
if (isSystemColumn(column) && !view.show_system_fields) continue; |
||||||
|
dbRow[column.title] = await serializeCellValue({ |
||||||
|
value: row[column.title], |
||||||
|
column, |
||||||
|
siteUrl, |
||||||
|
}); |
||||||
|
} |
||||||
|
dbRows.push(dbRow); |
||||||
|
} |
||||||
|
} |
||||||
|
return { offset, dbRows, elapsed }; |
||||||
|
} |
Loading…
Reference in new issue