Browse Source

feat: findOne (#1830)

* feat: add fineOne api

Signed-off-by: Wing-Kam Wong <wingkwong.code@gmail.com>

* feat: add findOne logic

Signed-off-by: Wing-Kam Wong <wingkwong.code@gmail.com>

* docs: add findOne & fix typos for dbViewRow

Signed-off-by: Wing-Kam Wong <wingkwong.code@gmail.com>

* fix: point to local nocodb-sdk for the tests

Signed-off-by: Wing-Kam Wong <wingkwong.code@gmail.com>

* feat: findone impl

Signed-off-by: Wing-Kam Wong <wingkwong.code@gmail.com>
pull/1840/head
աɨռɢӄաօռɢ 2 years ago committed by GitHub
parent
commit
bdef265d5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      packages/nc-gui/package.json
  2. 12
      packages/noco-docs/content/en/developer-resources/rest-apis.md
  3. 52
      packages/nocodb-sdk/src/lib/Api.ts
  4. 2
      packages/nocodb/package.json
  5. 39
      packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSqlv2.ts
  6. 40
      packages/nocodb/src/lib/noco/meta/api/dataApis/dataAliasApis.ts
  7. 162
      scripts/sdk/swagger.json

2
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",

12
packages/noco-docs/content/en/developer-resources/rest-apis.md

@ -55,16 +55,18 @@ Currently, the default value for {orgs} is <b>noco</b>. 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

52
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<any, any>({
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<any, any>({
path: `/api/v1/db/data/${orgs}/${projectName}/${tableName}/views/${viewName}/find-one`,
method: 'GET',
query: query,
format: 'json',
...params,
}),
/**
* No description
*

2
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",

39
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<any> {
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;

40
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')

162
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": [
{

Loading…
Cancel
Save