mirror of https://github.com/nocodb/nocodb
Pranav C
1 year ago
7 changed files with 319 additions and 3 deletions
@ -0,0 +1,18 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing'; |
||||
import { DataTableController } from './data-table.controller'; |
||||
|
||||
describe('DataTableController', () => { |
||||
let controller: DataTableController; |
||||
|
||||
beforeEach(async () => { |
||||
const module: TestingModule = await Test.createTestingModule({ |
||||
controllers: [DataTableController], |
||||
}).compile(); |
||||
|
||||
controller = module.get<DataTableController>(DataTableController); |
||||
}); |
||||
|
||||
it('should be defined', () => { |
||||
expect(controller).toBeDefined(); |
||||
}); |
||||
}); |
@ -0,0 +1,137 @@
|
||||
import { |
||||
Body, |
||||
Controller, |
||||
Delete, |
||||
Get, |
||||
HttpCode, |
||||
Param, |
||||
Patch, |
||||
Post, |
||||
Query, |
||||
Request, |
||||
Response, |
||||
UseGuards, |
||||
} from '@nestjs/common'; |
||||
import { GlobalGuard } from '../guards/global/global.guard'; |
||||
import { parseHrtimeToSeconds } from '../helpers'; |
||||
import { |
||||
Acl, |
||||
ExtractProjectIdMiddleware, |
||||
} from '../middlewares/extract-project-id/extract-project-id.middleware'; |
||||
import { DataTableService } from '../services/data-table.service'; |
||||
import { DatasService } from '../services/datas.service'; |
||||
|
||||
@Controller() |
||||
@UseGuards(ExtractProjectIdMiddleware, GlobalGuard) |
||||
export class DataTableController { |
||||
constructor(private readonly dataTableService: DataTableService) {} |
||||
|
||||
// todo: Handle the error case where view doesnt belong to model
|
||||
@Get('/api/v1/db/:projectId/tables/:modelId') |
||||
@Acl('dataList') |
||||
async dataList( |
||||
@Request() req, |
||||
@Response() res, |
||||
@Param('projectId') projectId: string, |
||||
@Param('modelId') modelId: string, |
||||
@Query('viewId') viewId: string, |
||||
) { |
||||
const startTime = process.hrtime(); |
||||
const responseData = await this.dataTableService.dataList({ |
||||
query: req.query, |
||||
projectId: projectId, |
||||
modelId: modelId, |
||||
}); |
||||
const elapsedSeconds = parseHrtimeToSeconds(process.hrtime(startTime)); |
||||
res.setHeader('xc-db-response', elapsedSeconds); |
||||
res.json(responseData); |
||||
} |
||||
|
||||
@Get(['/api/v1/db/:projectId/tables/:modelId/count']) |
||||
@Acl('dataCount') |
||||
async dataCount( |
||||
@Request() req, |
||||
@Response() res, |
||||
@Param('projectId') projectId: string, |
||||
@Param('modelId') modelId: string, |
||||
@Query('viewId') viewId: string, |
||||
) { |
||||
const countResult = await this.dataTableService.dataCount({ |
||||
query: req.query, |
||||
modelId, |
||||
projectId, |
||||
}); |
||||
|
||||
res.json(countResult); |
||||
} |
||||
|
||||
@Post(['/api/v1/db/:projectId/tables/:modelId']) |
||||
@HttpCode(200) |
||||
@Acl('dataInsert') |
||||
async dataInsert( |
||||
@Request() req, |
||||
@Param('projectId') projectId: string, |
||||
@Param('modelId') modelId: string, |
||||
@Query('viewId') viewId: string, |
||||
@Body() body: any, |
||||
) { |
||||
return await this.dataTableService.dataInsert({ |
||||
projectId: projectId, |
||||
modelId: modelId, |
||||
body: body, |
||||
cookie: req, |
||||
}); |
||||
} |
||||
|
||||
@Patch(['/api/v1/db/:projectId/tables/:modelId/:rowId']) |
||||
@Acl('dataUpdate') |
||||
async dataUpdate( |
||||
@Request() req, |
||||
@Param('projectId') projectId: string, |
||||
@Param('modelId') modelId: string, |
||||
@Query('viewId') viewId: string, |
||||
@Param('rowId') rowId: string, |
||||
) { |
||||
return await this.dataTableService.dataUpdate({ |
||||
projectId: projectId, |
||||
modelId: modelId, |
||||
body: req.body, |
||||
cookie: req, |
||||
rowId: rowId, |
||||
}); |
||||
} |
||||
|
||||
@Delete(['/api/v1/db/:projectId/tables/:modelId/:rowId']) |
||||
@Acl('dataDelete') |
||||
async dataDelete( |
||||
@Request() req, |
||||
@Param('projectId') projectId: string, |
||||
@Param('modelId') modelId: string, |
||||
@Query('viewId') viewId: string, |
||||
@Param('rowId') rowId: string, |
||||
) { |
||||
return await this.dataTableService.dataDelete({ |
||||
projectId: projectId, |
||||
modelId: modelId, |
||||
cookie: req, |
||||
rowId: rowId, |
||||
}); |
||||
} |
||||
|
||||
@Get(['/api/v1/db/:projectId/tables/:modelId/:rowId']) |
||||
@Acl('dataRead') |
||||
async dataRead( |
||||
@Request() req, |
||||
@Param('projectId') projectId: string, |
||||
@Param('modelId') modelId: string, |
||||
@Query('viewId') viewId: string, |
||||
@Param('rowId') rowId: string, |
||||
) { |
||||
return await this.dataTableService.dataRead({ |
||||
modelId, |
||||
projectId, |
||||
rowId: rowId, |
||||
query: req.query, |
||||
}); |
||||
} |
||||
} |
@ -0,0 +1,18 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing'; |
||||
import { DataTableService } from './data-table.service'; |
||||
|
||||
describe('DataTableService', () => { |
||||
let service: DataTableService; |
||||
|
||||
beforeEach(async () => { |
||||
const module: TestingModule = await Test.createTestingModule({ |
||||
providers: [DataTableService], |
||||
}).compile(); |
||||
|
||||
service = module.get<DataTableService>(DataTableService); |
||||
}); |
||||
|
||||
it('should be defined', () => { |
||||
expect(service).toBeDefined(); |
||||
}); |
||||
}); |
@ -0,0 +1,140 @@
|
||||
import { Injectable } from '@nestjs/common'; |
||||
import { NcError } from '../helpers/catchError'; |
||||
import { Base, Model } from '../models'; |
||||
import NcConnectionMgrv2 from '../utils/common/NcConnectionMgrv2'; |
||||
import { DatasService } from './datas.service'; |
||||
|
||||
@Injectable() |
||||
export class DataTableService { |
||||
constructor(private datasService: DatasService) {} |
||||
|
||||
async dataList(param: { projectId?: string; modelId: string; query: any }) { |
||||
const model = await this.getModelAndValidate(param); |
||||
|
||||
return await this.datasService.getDataList({ |
||||
model, |
||||
query: param.query, |
||||
}); |
||||
} |
||||
|
||||
async dataRead(param: { |
||||
projectId?: string; |
||||
modelId: string; |
||||
rowId: string; |
||||
query: any; |
||||
}) { |
||||
const model = await this.getModelAndValidate(param); |
||||
|
||||
const base = await Base.get(model.base_id); |
||||
|
||||
const baseModel = await Model.getBaseModelSQL({ |
||||
id: model.id, |
||||
dbDriver: await NcConnectionMgrv2.get(base), |
||||
}); |
||||
|
||||
const row = await baseModel.readByPk(param.rowId, false, param.query); |
||||
|
||||
if (!row) { |
||||
NcError.notFound('Row not found'); |
||||
} |
||||
|
||||
return row; |
||||
} |
||||
|
||||
async dataInsert(param: { |
||||
projectId?: string; |
||||
modelId: string; |
||||
body: any; |
||||
cookie: any; |
||||
}) { |
||||
const model = await this.getModelAndValidate(param); |
||||
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 dataUpdate(param: { |
||||
projectId?: string; |
||||
modelId: string; |
||||
rowId: string; |
||||
body: any; |
||||
cookie: any; |
||||
}) { |
||||
const model = await this.getModelAndValidate(param); |
||||
|
||||
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 dataDelete(param: { |
||||
projectId?: string; |
||||
modelId: string; |
||||
rowId: string; |
||||
cookie: any; |
||||
}) { |
||||
const model = await this.getModelAndValidate(param); |
||||
const base = await Base.get(model.base_id); |
||||
const baseModel = await Model.getBaseModelSQL({ |
||||
id: model.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); |
||||
} |
||||
|
||||
private async getModelAndValidate(param: { |
||||
projectId?: string; |
||||
modelId: string; |
||||
query: any; |
||||
}) { |
||||
const model = await Model.get(param.modelId); |
||||
|
||||
if (model.project_id && model.project_id !== param.projectId) { |
||||
throw new Error('Model not found in project'); |
||||
} |
||||
return model; |
||||
} |
||||
|
||||
async dataCount(param: { projectId?: string; modelId: string; query: any }) { |
||||
|
||||
const model = await this.getModelAndValidate(param); |
||||
|
||||
const base = await Base.get(model.base_id); |
||||
|
||||
const baseModel = await Model.getBaseModelSQL({ |
||||
id: model.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 }; |
||||
|
||||
} |
||||
} |
Loading…
Reference in new issue