Browse Source

feat: add new data apis

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/5901/head
Pranav C 1 year ago
parent
commit
b722d039bb
  1. 6
      packages/nocodb/src/app.module.ts
  2. 1
      packages/nocodb/src/controllers/data-alias-nested.controller.ts
  3. 18
      packages/nocodb/src/controllers/data-table.controller.spec.ts
  4. 137
      packages/nocodb/src/controllers/data-table.controller.ts
  5. 18
      packages/nocodb/src/services/data-table.service.spec.ts
  6. 140
      packages/nocodb/src/services/data-table.service.ts
  7. 2
      packages/nocodb/src/services/datas.service.ts

6
packages/nocodb/src/app.module.ts

@ -19,6 +19,9 @@ import { MetasModule } from './modules/metas/metas.module';
import { JobsModule } from './modules/jobs/jobs.module';
import { AppInitService } from './services/app-init.service';
import type { MiddlewareConsumer } from '@nestjs/common';
import { DataTableController } from './controllers/data-table.controller';
import { DataTableController } from './servicess/data-table.controller';
import { DataTableService } from './services/data-table.service';
@Module({
imports: [
@ -38,7 +41,7 @@ import type { MiddlewareConsumer } from '@nestjs/common';
]
: []),
],
controllers: [],
controllers: [DataTableController],
providers: [
AuthService,
{
@ -50,6 +53,7 @@ import type { MiddlewareConsumer } from '@nestjs/common';
BaseViewStrategy,
HookHandlerService,
AppInitService,
DataTableService,
],
})
export class AppModule {

1
packages/nocodb/src/controllers/data-alias-nested.controller.ts

@ -8,7 +8,6 @@ import {
Request,
UseGuards,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { GlobalGuard } from '../guards/global/global.guard';
import {
Acl,

18
packages/nocodb/src/controllers/data-table.controller.spec.ts

@ -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();
});
});

137
packages/nocodb/src/controllers/data-table.controller.ts

@ -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,
});
}
}

18
packages/nocodb/src/services/data-table.service.spec.ts

@ -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();
});
});

140
packages/nocodb/src/services/data-table.service.ts

@ -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 };
}
}

2
packages/nocodb/src/services/datas.service.ts

@ -113,7 +113,7 @@ export class DatasService {
async getDataList(param: {
model: Model;
view: View;
view?: View;
query: any;
baseModel?: BaseModelSqlv2;
}) {

Loading…
Cancel
Save