diff --git a/.run/Run NocoDB Sqlite.run.xml b/.run/Run NocoDB Sqlite.run.xml
index 19996f59ba..e7b120a2af 100644
--- a/.run/Run NocoDB Sqlite.run.xml
+++ b/.run/Run NocoDB Sqlite.run.xml
@@ -12,4 +12,4 @@
-
\ No newline at end of file
+
diff --git a/packages/nc-gui/components/dashboard/settings/data-sources/CreateBase.vue b/packages/nc-gui/components/dashboard/settings/data-sources/CreateBase.vue
index bb4f6d56d8..296f0bced1 100644
--- a/packages/nc-gui/components/dashboard/settings/data-sources/CreateBase.vue
+++ b/packages/nc-gui/components/dashboard/settings/data-sources/CreateBase.vue
@@ -495,7 +495,7 @@ watch(
-
+
{{ $t('activity.useConnectionUrl') }}
@@ -611,7 +611,7 @@ watch(
-
+
{{ $t('activity.testDbConn') }}
diff --git a/packages/nc-gui/lang/fr.json b/packages/nc-gui/lang/fr.json
index 28d5266003..402c97bd4f 100644
--- a/packages/nc-gui/lang/fr.json
+++ b/packages/nc-gui/lang/fr.json
@@ -260,7 +260,7 @@
"barcodeFormat": "Format du code-barres",
"qrCodeValueTooLong": "Trop de caractères pour un code QR",
"barcodeValueTooLong": "Trop de caractères pour un code-barres",
- "currentLocation": "Current Location",
+ "currentLocation": "Emplacement actuel",
"lng": "Lng",
"lat": "Lat",
"aggregateFunction": "Fonction agrégée",
@@ -385,12 +385,12 @@
"nextRecord": "Ligne suivante",
"previousRecord": "Ligne précédente",
"copyApiURL": "Copier l'URL de l'API",
- "createTable": "Create New Table",
+ "createTable": "Créer une nouvelle table",
"refreshTable": "Actualiser le tableau",
- "renameTable": "Rename Table",
- "deleteTable": "Delete Table",
+ "renameTable": "Renommer la table",
+ "deleteTable": "Supprimer la table",
"addField": "Ajouter un nouveau champ à ce tableau",
- "setDisplay": "Set as Display value",
+ "setDisplay": "Définir comme valeur d'affichage",
"addRow": "Ajouter une nouvelle ligne",
"saveRow": "Enregistrer la ligne",
"saveAndExit": "Enregistrer et quitter",
diff --git a/packages/nc-gui/package-lock.json b/packages/nc-gui/package-lock.json
index 4a50a2051b..db8ca28452 100644
--- a/packages/nc-gui/package-lock.json
+++ b/packages/nc-gui/package-lock.json
@@ -110,7 +110,7 @@
}
},
"../nocodb-sdk": {
- "version": "0.107.4",
+ "version": "0.107.5",
"license": "AGPL-3.0-or-later",
"dependencies": {
"axios": "^0.21.1",
diff --git a/packages/nc-lib-gui/package.json b/packages/nc-lib-gui/package.json
index 34d5efbf1b..c480b45bae 100644
--- a/packages/nc-lib-gui/package.json
+++ b/packages/nc-lib-gui/package.json
@@ -1,6 +1,6 @@
{
"name": "nc-lib-gui",
- "version": "0.107.4",
+ "version": "0.107.5",
"description": "NocoDB GUI",
"author": {
"name": "NocoDB",
diff --git a/packages/nocodb-sdk/package-lock.json b/packages/nocodb-sdk/package-lock.json
index bc7fc27f3c..3eeec3c695 100644
--- a/packages/nocodb-sdk/package-lock.json
+++ b/packages/nocodb-sdk/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "nocodb-sdk",
- "version": "0.107.4",
+ "version": "0.107.5",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "nocodb-sdk",
- "version": "0.107.4",
+ "version": "0.107.5",
"license": "AGPL-3.0-or-later",
"dependencies": {
"axios": "^0.21.1",
diff --git a/packages/nocodb-sdk/package.json b/packages/nocodb-sdk/package.json
index 9709ad7d86..eafc8a6866 100644
--- a/packages/nocodb-sdk/package.json
+++ b/packages/nocodb-sdk/package.json
@@ -1,6 +1,6 @@
{
"name": "nocodb-sdk",
- "version": "0.107.4",
+ "version": "0.107.5",
"description": "NocoDB SDK",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",
diff --git a/packages/nocodb-sdk/src/lib/Api.ts b/packages/nocodb-sdk/src/lib/Api.ts
index 3d0a0e92f3..8903a6d481 100644
--- a/packages/nocodb-sdk/src/lib/Api.ts
+++ b/packages/nocodb-sdk/src/lib/Api.ts
@@ -1603,7 +1603,7 @@ export interface NormalColumnRequestType {
/** Data Type Extra */
dtx?: StringOrNullType;
/** Data Type Extra Precision */
- dtxp?: StringOrNullType | number;
+ dtxp?: string | number | null;
/** Data Type Extra Scale */
dtxs?: StringOrNullType | number;
/** Numeric Precision */
diff --git a/packages/nocodb/package-lock.json b/packages/nocodb/package-lock.json
index 6095a65621..de526510b2 100644
--- a/packages/nocodb/package-lock.json
+++ b/packages/nocodb/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "nocodb",
- "version": "0.107.4",
+ "version": "0.107.5",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "nocodb",
- "version": "0.107.4",
+ "version": "0.107.5",
"license": "AGPL-3.0-or-later",
"dependencies": {
"@google-cloud/storage": "^5.7.2",
@@ -80,7 +80,7 @@
"mysql2": "^3.2.0",
"nanoid": "^3.1.20",
"nc-help": "^0.2.87",
- "nc-lib-gui": "0.107.4",
+ "nc-lib-gui": "0.107.5",
"nc-plugin": "^0.1.3",
"ncp": "^2.0.0",
"nocodb-sdk": "file:../nocodb-sdk",
@@ -190,7 +190,7 @@
}
},
"../nocodb-sdk": {
- "version": "0.107.4",
+ "version": "0.107.5",
"license": "AGPL-3.0-or-later",
"dependencies": {
"axios": "^0.21.1",
@@ -13157,9 +13157,9 @@
}
},
"node_modules/nc-lib-gui": {
- "version": "0.107.4",
- "resolved": "https://registry.npmjs.org/nc-lib-gui/-/nc-lib-gui-0.107.4.tgz",
- "integrity": "sha512-+e0jjJgrBfgLGTTShkcu1QQ2I0QxE/NUCCJ5L8KeZibm71pvgxL/P2hfatSz8PvzSDU/YwXnyXZQkeaSDBzNyA==",
+ "version": "0.107.5",
+ "resolved": "https://registry.npmjs.org/nc-lib-gui/-/nc-lib-gui-0.107.5.tgz",
+ "integrity": "sha512-bFmKo6qDmrHY7a3itHMnp1A8qFecHyNKZABWK4GIdA8xCeSx6rLL8LGzxDRsD3fIXFwTCzSd8iPJECHaF5fcFg==",
"dependencies": {
"express": "^4.17.1"
}
@@ -28442,9 +28442,9 @@
}
},
"nc-lib-gui": {
- "version": "0.107.4",
- "resolved": "https://registry.npmjs.org/nc-lib-gui/-/nc-lib-gui-0.107.4.tgz",
- "integrity": "sha512-+e0jjJgrBfgLGTTShkcu1QQ2I0QxE/NUCCJ5L8KeZibm71pvgxL/P2hfatSz8PvzSDU/YwXnyXZQkeaSDBzNyA==",
+ "version": "0.107.5",
+ "resolved": "https://registry.npmjs.org/nc-lib-gui/-/nc-lib-gui-0.107.5.tgz",
+ "integrity": "sha512-bFmKo6qDmrHY7a3itHMnp1A8qFecHyNKZABWK4GIdA8xCeSx6rLL8LGzxDRsD3fIXFwTCzSd8iPJECHaF5fcFg==",
"requires": {
"express": "^4.17.1"
}
diff --git a/packages/nocodb/package.json b/packages/nocodb/package.json
index 1b8701a2e6..d9dc9b67c7 100644
--- a/packages/nocodb/package.json
+++ b/packages/nocodb/package.json
@@ -1,6 +1,6 @@
{
"name": "nocodb",
- "version": "0.107.4",
+ "version": "0.107.5",
"description": "NocoDB Backend",
"main": "dist/bundle.js",
"author": {
@@ -113,7 +113,7 @@
"mysql2": "^3.2.0",
"nanoid": "^3.1.20",
"nc-help": "^0.2.87",
- "nc-lib-gui": "0.107.4",
+ "nc-lib-gui": "0.107.5",
"nc-plugin": "^0.1.3",
"ncp": "^2.0.0",
"nocodb-sdk": "file:../nocodb-sdk",
diff --git a/packages/nocodb/src/Noco.ts b/packages/nocodb/src/Noco.ts
index 1b93161bb7..048901ac47 100644
--- a/packages/nocodb/src/Noco.ts
+++ b/packages/nocodb/src/Noco.ts
@@ -1,6 +1,6 @@
+import path from 'path';
import Sentry, { Handlers } from '@sentry/node';
import { Logger } from '@nestjs/common';
-import path from 'path';
import { NestFactory } from '@nestjs/core';
import clear from 'clear';
import * as express from 'express';
diff --git a/packages/nocodb/src/db/BaseModelSqlv2.ts b/packages/nocodb/src/db/BaseModelSqlv2.ts
index b82ced126d..1d8dd24a1f 100644
--- a/packages/nocodb/src/db/BaseModelSqlv2.ts
+++ b/packages/nocodb/src/db/BaseModelSqlv2.ts
@@ -144,10 +144,24 @@ class BaseModelSqlv2 {
autoBind(this);
}
- public async readByPk(id?: any, validateFormula = false): Promise {
+ public async readByPk(
+ id?: any,
+ validateFormula = false,
+ query: any = {},
+ ): Promise {
const qb = this.dbDriver(this.tnPath);
- await this.selectObject({ qb, validateFormula });
+ const { ast, dependencyFields } = await getAst({
+ query,
+ model: this.model,
+ view: this.viewId && (await View.get(this.viewId)),
+ });
+
+ await this.selectObject({
+ ...(dependencyFields ?? {}),
+ qb,
+ validateFormula,
+ });
qb.where(_wherePk(this.model.primaryKeys, id));
@@ -167,14 +181,7 @@ class BaseModelSqlv2 {
data.__proto__ = proto;
}
- // retrieve virtual column data as well
- const project = await Project.get(this.model.project_id);
- const { model, view } = await getViewAndModelByAliasOrId({
- projectName: project.title,
- tableName: this.model.title,
- });
- const { ast } = await getAst({ model, view });
- return data ? await nocoExecute(ast, data, {}) : {};
+ return data ? await nocoExecute(ast, data, {}, query) : {};
}
public async exist(id?: any): Promise {
@@ -204,7 +211,7 @@ class BaseModelSqlv2 {
): Promise {
const { where, ...rest } = this._getListArgs(args as any);
const qb = this.dbDriver(this.tnPath);
- await this.selectObject({ qb, validateFormula });
+ await this.selectObject({ ...args, qb, validateFormula });
const aliasColObjMap = await this.model.getAliasColObjMap();
const sorts = extractSortsObject(rest?.sort, aliasColObjMap);
@@ -2188,6 +2195,7 @@ class BaseModelSqlv2 {
raw?: boolean;
} = {},
) {
+ let trx;
try {
// TODO: ag column handling for raw bulk insert
const insertDatas = raw
@@ -2216,7 +2224,7 @@ class BaseModelSqlv2 {
// refer : https://www.sqlite.org/limits.html
const chunkSize = this.isSqlite ? 10 : _chunkSize;
- const trx = await this.dbDriver.transaction();
+ trx = await this.dbDriver.transaction();
if (!foreign_key_checks) {
if (this.isPg) {
@@ -2247,6 +2255,7 @@ class BaseModelSqlv2 {
return response;
} catch (e) {
+ await trx?.rollback();
// await this.errorInsertb(e, data, null);
throw e;
}
diff --git a/packages/nocodb/src/schema/swagger.json b/packages/nocodb/src/schema/swagger.json
index 2912be1cb4..690c3ce3bb 100644
--- a/packages/nocodb/src/schema/swagger.json
+++ b/packages/nocodb/src/schema/swagger.json
@@ -17834,10 +17834,13 @@
"dtxp": {
"oneOf": [
{
- "$ref": "#/components/schemas/StringOrNull"
+ "type": "string"
},
{
"type": "number"
+ },
+ {
+ "type": "null"
}
],
"description": "Data Type Extra Precision"
diff --git a/packages/nocodb/src/services/app-init.service.ts b/packages/nocodb/src/services/app-init.service.ts
index c913fcaefb..e1050d480c 100644
--- a/packages/nocodb/src/services/app-init.service.ts
+++ b/packages/nocodb/src/services/app-init.service.ts
@@ -4,7 +4,7 @@ import { Connection } from '../connection/connection';
import initAdminFromEnv from '../helpers/initAdminFromEnv';
import NcPluginMgrv2 from '../helpers/NcPluginMgrv2';
import { MetaService } from '../meta/meta.service';
-import { User } from '../models'
+import { User } from '../models';
import Noco from '../Noco';
import getInstance from '../utils/getInstance';
import NcConfigFactory from '../utils/NcConfigFactory';
diff --git a/packages/nocodb/src/services/datas.service.ts b/packages/nocodb/src/services/datas.service.ts
index 1e1aa78d24..c41609f6c0 100644
--- a/packages/nocodb/src/services/datas.service.ts
+++ b/packages/nocodb/src/services/datas.service.ts
@@ -185,8 +185,8 @@ export class DatasService {
view,
});
- const data = await baseModel.findOne({ ...args, dependencyFields });
- return data ? await nocoExecute(ast, data, {}, {}) : {};
+ const data = await baseModel.findOne({ ...args, ...dependencyFields });
+ return data ? await nocoExecute(ast, data, {}, dependencyFields) : {};
}
async getDataGroupBy(param: { model: Model; view: View; query?: any }) {
@@ -221,15 +221,13 @@ export class DatasService {
dbDriver: await NcConnectionMgrv2.get(base),
});
- const row = await baseModel.readByPk(param.rowId);
+ const row = await baseModel.readByPk(param.rowId, false, param.query);
if (!row) {
NcError.notFound('Row not found');
}
- const { ast } = await getAst({ model, query: param.query, view });
-
- return await nocoExecute(ast, row, {}, param.query);
+ return row;
}
async dataExist(param: PathParams & { rowId: string; query: any }) {
@@ -274,9 +272,9 @@ export class DatasService {
dbDriver: await NcConnectionMgrv2.get(base),
});
- const { ast } = await getAst({ model, query, view });
+ const { ast, dependencyFields } = await getAst({ model, query, view });
- const listArgs: any = { ...query };
+ const listArgs: any = { ...dependencyFields };
try {
listArgs.filterArr = JSON.parse(listArgs.filterArrJson);
} catch (e) {}
@@ -637,13 +635,16 @@ export class DatasService {
dbDriver: await NcConnectionMgrv2.get(base),
});
- const { ast } = await getAst({ model, query: param.query });
+ const { ast, dependencyFields } = await getAst({
+ model,
+ query: param.query,
+ });
return await nocoExecute(
ast,
- await baseModel.readByPk(param.rowId),
- {},
+ await baseModel.readByPk(param.rowId, false),
{},
+ dependencyFields,
);
} catch (e) {
console.log(e);
diff --git a/packages/nocodb/tests/unit/rest/tests/tableRow.test.ts b/packages/nocodb/tests/unit/rest/tests/tableRow.test.ts
index 02af981a57..488bb50493 100644
--- a/packages/nocodb/tests/unit/rest/tests/tableRow.test.ts
+++ b/packages/nocodb/tests/unit/rest/tests/tableRow.test.ts
@@ -1106,7 +1106,9 @@ function tableTest() {
);
const nestedFields = {
- 'Rental List': ['RentalDate', 'ReturnDate'],
+ 'Rental List': {
+ f: 'RentalDate,ReturnDate',
+ },
};
const nestedFilter = [
@@ -1276,6 +1278,39 @@ function tableTest() {
}
});
+ it('Read table row with nested fields', async () => {
+ const rowId = 1;
+ const actorTable = await getTable({
+ project: sakilaProject,
+ name: 'actor',
+ });
+ const response = await request(context.app)
+ .get(
+ `/api/v1/db/data/noco/${sakilaProject.id}/${actorTable.id}/${rowId}/`,
+ )
+ .set('xc-auth', context.token)
+ .query({
+ 'nested[Film List][fields]': 'Title,ReleaseYear,Language',
+ })
+ .expect(200);
+
+ const record = response.body;
+ expect(record['Film List']).length(19);
+ expect(record['Film List'][0]).to.have.all.keys(
+ 'Title',
+ 'ReleaseYear',
+ 'Language',
+ );
+
+ // for SQLite Sakila, Language is null
+ if (isPg(context)) {
+ expect(record['Film List'][0]['Language']).to.have.all.keys(
+ 'Name',
+ 'LanguageId',
+ );
+ }
+ });
+
it('Update table row', async function () {
const table = await createTable(context, project);
const row = await createRow(context, { project, table });
diff --git a/packages/nocodb/tests/unit/rest/tests/viewRow.test.ts b/packages/nocodb/tests/unit/rest/tests/viewRow.test.ts
index 971c471879..3473c79bcf 100644
--- a/packages/nocodb/tests/unit/rest/tests/viewRow.test.ts
+++ b/packages/nocodb/tests/unit/rest/tests/viewRow.test.ts
@@ -901,7 +901,7 @@ function viewRowTests() {
);
const nestedFields = {
- 'Rental List': ['RentalDate', 'ReturnDate'],
+ 'Rental List': { f: 'RentalDate,ReturnDate' },
};
const nestedFilter = [