diff --git a/packages/nc-gui/package.json b/packages/nc-gui/package.json index b8fa48268e..67e5eb682c 100644 --- a/packages/nc-gui/package.json +++ b/packages/nc-gui/package.json @@ -29,7 +29,7 @@ "monaco-editor": "^0.19.3", "monaco-themes": "^0.2.5", "nano-assign": "^1.0.1", - "nocodb-sdk": "0.90.5", + "nocodb-sdk": "file:../nocodb-sdk", "nuxt": "^2.14.0", "odometer": "^0.4.8", "papaparse": "^5.3.1", diff --git a/packages/noco-docs/content/en/developer-resources/rest-apis.md b/packages/noco-docs/content/en/developer-resources/rest-apis.md index 37786d0b4c..71b2d73212 100644 --- a/packages/noco-docs/content/en/developer-resources/rest-apis.md +++ b/packages/noco-docs/content/en/developer-resources/rest-apis.md @@ -55,16 +55,18 @@ Currently, the default value for {orgs} is noco. Users will be able to ch | Data | Patch | dbTableRow | bulkUpdateAll | /api/v1/db/data/bulk/{orgs}/{projectName}/{tableName}/all | | Data | Delete| dbTableRow | bulkDeleteAll | /api/v1/db/data/bulk/{orgs}/{projectName}/{tableName}/all | | Data | Get | dbTableRow | list | /api/v1/db/data/{orgs}/{projectName}/{tableName} | +| Data | Get | dbTableRow | findOne | /api/v1/db/data/{orgs}/{projectName}/{tableName}/find-one | | Data | Post | dbTableRow | create | /api/v1/db/data/{orgs}/{projectName}/{tableName} | | Data | Get | dbTableRow | read | /api/v1/db/data/{orgs}/{projectName}/{tableName}/{rowId} | | Data | Patch | dbTableRow | update | /api/v1/db/data/{orgs}/{projectName}/{tableName}/{rowId} | | Data | Delete| dbTableRow | delete | /api/v1/db/data/{orgs}/{projectName}/{tableName}/{rowId} | | Data | Get | dbTableRow | count | /api/v1/db/data/{orgs}/{projectName}/{tableName}/count | -| Data | Get | dbViewRow | list | /api/v1/db/data/{orgs}/{projectName}/{tableName}/view/{viewName} | -| Data | Post | dbViewRow | create | /api/v1/db/data/{orgs}/{projectName}/{tableName}/view/{viewName} | -| Data | Get | dbViewRow | read | /api/v1/db/data/{orgs}/{projectName}/{tableName}/view/{viewName}/{rowId} | -| Data | Patch | dbViewRow | update | /api/v1/db/data/{orgs}/{projectName}/{tableName}/view/{viewName}/{rowId} | -| Data | Delete| dbViewRow | delete | /api/v1/db/data/{orgs}/{projectName}/{tableName}/view/{viewName}/{rowId} | +| Data | Get | dbViewRow | list | /api/v1/db/data/{orgs}/{projectName}/{tableName}/views/{viewName} | +| Data | Get | dbViewRow | findOne | /api/v1/db/data/{orgs}/{projectName}/{tableName}/views/{viewName}/find-one | +| Data | Post | dbViewRow | create | /api/v1/db/data/{orgs}/{projectName}/{tableName}/views/{viewName} | +| Data | Get | dbViewRow | read | /api/v1/db/data/{orgs}/{projectName}/{tableName}/views/{viewName}/{rowId} | +| Data | Patch | dbViewRow | update | /api/v1/db/data/{orgs}/{projectName}/{tableName}/views/{viewName}/{rowId} | +| Data | Delete| dbViewRow | delete | /api/v1/db/data/{orgs}/{projectName}/{tableName}/views/{viewName}/{rowId} | | Data | Get | dbViewRow | count | /api/v1/db/data/{orgs}/{projectName}/{tableName}/views/{viewName}/count | ### Meta APIs diff --git a/packages/nocodb-sdk/src/lib/Api.ts b/packages/nocodb-sdk/src/lib/Api.ts index a8dbeb7f4f..ee6bb65487 100644 --- a/packages/nocodb-sdk/src/lib/Api.ts +++ b/packages/nocodb-sdk/src/lib/Api.ts @@ -1097,7 +1097,7 @@ export class Api< * @request GET:/api/v1/db/meta/projects/{projectId}/info * @response `200` `{ Node?: string, Arch?: string, Platform?: string, Docker?: boolean, Database?: string, ProjectOnRootDB?: string, RootDB?: string, PackageVersion?: string }` OK */ - metaGet: (projectId: string, params: RequestParams = {}) => + metaGet: (projectId: string, params: RequestParams = {}, query: object) => this.request< { Node?: string; @@ -1113,6 +1113,7 @@ export class Api< >({ path: `/api/v1/db/meta/projects/${projectId}/info`, method: 'GET', + query: query, format: 'json', ...params, }), @@ -2233,6 +2234,30 @@ export class Api< ...params, }), + /** + * No description + * + * @tags DB table row + * @name FindOne + * @summary Table row FindOne + * @request GET:/api/v1/db/data/{orgs}/{projectName}/{tableName}/find-one + * @response `200` `any` OK + */ + findOne: ( + orgs: string, + projectName: string, + tableName: string, + query?: { fields?: any[]; sort?: any[]; where?: string }, + params: RequestParams = {} + ) => + this.request({ + path: `/api/v1/db/data/${orgs}/${projectName}/${tableName}/find-one`, + method: 'GET', + query: query, + format: 'json', + ...params, + }), + /** * No description * @@ -2636,6 +2661,31 @@ export class Api< ...params, }), + /** + * No description + * + * @tags DB view row + * @name FindOne + * @summary Table view row FindOne + * @request GET:/api/v1/db/data/{orgs}/{projectName}/{tableName}/views/{viewName}/find-one + * @response `200` `any` OK + */ + findOne: ( + orgs: string, + projectName: string, + tableName: string, + viewName: string, + query?: { fields?: any[]; sort?: any[]; where?: string; nested?: any }, + params: RequestParams = {} + ) => + this.request({ + path: `/api/v1/db/data/${orgs}/${projectName}/${tableName}/views/${viewName}/find-one`, + method: 'GET', + query: query, + format: 'json', + ...params, + }), + /** * No description * diff --git a/packages/nocodb/package.json b/packages/nocodb/package.json index 94a85f1d19..9c8bf23835 100644 --- a/packages/nocodb/package.json +++ b/packages/nocodb/package.json @@ -154,7 +154,7 @@ "nc-lib-gui": "0.90.5", "nc-plugin": "^0.1.1", "ncp": "^2.0.0", - "nocodb-sdk": "0.90.5", + "nocodb-sdk": "file:../nocodb-sdk", "nodemailer": "^6.4.10", "openapi-to-postmanv2": "^3.1.0", "ora": "^4.0.4", diff --git a/packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSqlv2.ts b/packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSqlv2.ts index c2227f0ec2..0af3c47f01 100644 --- a/packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSqlv2.ts +++ b/packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSqlv2.ts @@ -90,6 +90,45 @@ class BaseModelSqlv2 { return data; } + public async findOne( + args: { + where?: string; + filterArr?: Filter[]; + } = {} + ): Promise { + const qb = this.dbDriver(this.model.table_name); + await this.selectObject({ qb }); + + const aliasColObjMap = await this.model.getAliasColObjMap(); + const filterObj = extractFilterFromXwhere(args?.where, aliasColObjMap); + + await conditionV2( + [ + new Filter({ + children: args.filterArr || [], + is_group: true, + logical_op: 'and' + }), + new Filter({ + children: filterObj, + is_group: true, + logical_op: 'and' + }), + ...(args.filterArr || []) + ], + qb, + this.dbDriver + ); + + const data = await qb.first(); + + if (data) { + const proto = await this.getProto(); + data.__proto__ = proto; + } + return data; + } + public async list( args: { where?: string; diff --git a/packages/nocodb/src/lib/noco/meta/api/dataApis/dataAliasApis.ts b/packages/nocodb/src/lib/noco/meta/api/dataApis/dataAliasApis.ts index c3e8c31987..82ff1d2a4c 100644 --- a/packages/nocodb/src/lib/noco/meta/api/dataApis/dataAliasApis.ts +++ b/packages/nocodb/src/lib/noco/meta/api/dataApis/dataAliasApis.ts @@ -13,6 +13,11 @@ async function dataList(req: Request, res: Response) { res.json(await getDataList(model, view, req)); } +async function dataFindOne(req: Request, res: Response) { + const { model, view } = await getViewAndModelFromRequestByAliasOrId(req); + res.json(await getFindOne(model, view, req)); +} + async function dataCount(req: Request, res: Response) { const { model, view } = await getViewAndModelFromRequestByAliasOrId(req); @@ -106,6 +111,31 @@ async function getDataList(model, view: View, req) { }); } +async function getFindOne(model, view: View, req) { + const base = await Base.get(model.base_id); + + const baseModel = await Model.getBaseModelSQL({ + id: model.id, + viewId: view?.id, + dbDriver: NcConnectionMgrv2.get(base) + }); + + const args: any = { ...req.query }; + try { + args.filterArr = JSON.parse(args.filterArrJson); + } catch (e) {} + try { + args.sortArr = JSON.parse(args.sortArrJson); + } catch (e) {} + + return await nocoExecute( + await baseModel.defaultResolverReq(), + await baseModel.findOne(args), + {}, + {} + ); +} + async function dataRead(req: Request, res: Response) { const { model, view } = await getViewAndModelFromRequestByAliasOrId(req); @@ -135,6 +165,11 @@ router.get( ncMetaAclMw(dataList, 'dataList') ); +router.get( + '/api/v1/db/data/:orgs/:projectName/:tableName/find-one', + ncMetaAclMw(dataFindOne, 'dataFindOne') +); + router.get( '/api/v1/db/data/:orgs/:projectName/:tableName/count', ncMetaAclMw(dataCount, 'dataCount') @@ -168,6 +203,11 @@ router.get( ncMetaAclMw(dataList, 'dataList') ); +router.get( + '/api/v1/db/data/:orgs/:projectName/:tableName/views/:viewName/find-one', + ncMetaAclMw(dataFindOne, 'dataFindOne') +); + router.post( '/api/v1/db/data/:orgs/:projectName/:tableName', ncMetaAclMw(dataInsert, 'dataInsert') diff --git a/scripts/sdk/swagger.json b/scripts/sdk/swagger.json index d63ba0e38d..091505e9a9 100644 --- a/scripts/sdk/swagger.json +++ b/scripts/sdk/swagger.json @@ -573,6 +573,16 @@ }, "tags": [ "Project" + ], + "parameters": [ + { + "schema": { + "type": "number", + "minimum": 1, + "multipleOf": 1 + }, + "in": "query" + } ] } }, @@ -2521,6 +2531,75 @@ } } }, + "/api/v1/db/data/{orgs}/{projectName}/{tableName}/find-one": { + "parameters": [ + { + "schema": { + "type": "string" + }, + "name": "orgs", + "in": "path", + "required": true + }, + { + "schema": { + "type": "string" + }, + "name": "projectName", + "in": "path", + "required": true + }, + { + "schema": { + "type": "string" + }, + "name": "tableName", + "in": "path", + "required": true + } + ], + "get": { + "summary": "Table row FindOne", + "operationId": "db-table-row-find-one", + "description": "", + "tags": [ + "DB table row" + ], + "parameters": [ + { + "schema": { + "type": "array" + }, + "in": "query", + "name": "fields" + }, + { + "schema": { + "type": "array" + }, + "in": "query", + "name": "sort" + }, + { + "schema": { + "type": "string" + }, + "in": "query", + "name": "where" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": {} + } + } + } + } + } + }, "/api/v1/db/data/{orgs}/{projectName}/{tableName}/count": { "parameters": [ { @@ -2689,6 +2768,89 @@ } } }, + "/api/v1/db/data/{orgs}/{projectName}/{tableName}/views/{viewName}/find-one": { + "parameters": [ + { + "schema": { + "type": "string" + }, + "name": "orgs", + "in": "path", + "required": true + }, + { + "schema": { + "type": "string" + }, + "name": "projectName", + "in": "path", + "required": true + }, + { + "schema": { + "type": "string" + }, + "name": "tableName", + "in": "path", + "required": true + }, + { + "schema": { + "type": "string" + }, + "name": "viewName", + "in": "path", + "required": true + } + ], + "get": { + "summary": "Table view row FindOne", + "operationId": "db-view-row-find-one", + "description": "", + "tags": [ + "DB view row" + ], + "parameters": [ + { + "schema": { + "type": "array" + }, + "in": "query", + "name": "fields" + }, + { + "schema": { + "type": "array" + }, + "in": "query", + "name": "sort" + }, + { + "schema": { + "type": "string" + }, + "in": "query", + "name": "where" + }, + { + "schema": {}, + "in": "query", + "name": "nested", + "description": "Query params for nested data" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": {} + } + } + } + } + } + }, "/api/v1/db/data/{orgs}/{projectName}/{tableName}/views/{viewName}/count": { "parameters": [ {