Browse Source

feat: limit column title to 255 for all db types

pull/6640/head
mertmit 1 year ago
parent
commit
8305957718
  1. 9
      packages/nc-gui/utils/validation.ts
  2. 4
      packages/nocodb/src/helpers/columnHelpers.ts
  3. 10
      packages/nocodb/src/modules/jobs/jobs/at-import/at-import.processor.ts
  4. 67
      packages/nocodb/src/services/columns.service.ts
  5. 12
      packages/nocodb/src/services/tables.service.ts

9
packages/nc-gui/utils/validation.ts

@ -98,13 +98,15 @@ export const fieldRequiredValidator = () => {
}
}
export const fieldLengthValidator = (sqlClientType: string) => {
export const fieldLengthValidator = (_sqlClientType: string) => {
return {
validator: (rule: any, value: any) => {
const { t } = getI18n().global
// no limit for sqlite but set as 255
let fieldLengthLimit = 255
const fieldLengthLimit = 255
/*
Now we allow 255 for all databases, truncate will be handled by backend for column_name
if (sqlClientType === 'mysql2' || sqlClientType === 'mysql') {
fieldLengthLimit = 64
@ -113,6 +115,7 @@ export const fieldLengthValidator = (sqlClientType: string) => {
} else if (sqlClientType === 'mssql') {
fieldLengthLimit = 128
}
*/
return new Promise((resolve, reject) => {
if (value?.length > fieldLengthLimit) {

4
packages/nocodb/src/helpers/columnHelpers.ts

@ -262,3 +262,7 @@ export async function populateRollupForLTAR({
);
await GridViewColumn.update(viewCol.id, { show: false });
}
export const sanitizeColumnName = (name: string) => {
return name.replace(/\W+/g, '_').trim();
};

10
packages/nocodb/src/modules/jobs/jobs/at-import/at-import.processor.ts

@ -17,6 +17,7 @@ import { importData, importLTARData } from './helpers/readAndProcessData';
import EntityMap from './helpers/EntityMap';
import type { UserType } from 'nocodb-sdk';
import type { Base } from '~/models';
import { sanitizeColumnName } from '~/helpers';
import { AttachmentsService } from '~/services/attachments.service';
import { ColumnsService } from '~/services/columns.service';
import { BulkDataAliasService } from '~/services/bulk-data-alias.service';
@ -306,13 +307,8 @@ export class AtImportProcessor {
// aTbl helper routines
//
const nc_sanitizeName = (name) => {
// replace all special characters by _
return name.replace(/\W+/g, '_').trim();
};
const nc_getSanitizedColumnName = (table, name) => {
let col_name = nc_sanitizeName(name);
let col_name = sanitizeColumnName(name);
// truncate to 60 chars if character if exceeds above 60
col_name = col_name?.slice(0, 60);
@ -524,7 +520,7 @@ export class AtImportProcessor {
// Enable to use aTbl identifiers as is: table.id = tblSchema[i].id;
table.title = tblSchema[i].name;
let sanitizedName = nc_sanitizeName(tblSchema[i].name);
let sanitizedName = sanitizeColumnName(tblSchema[i].name);
// truncate to 50 chars if character if exceeds above 50
// upto 64 should be fine but we are keeping it to 50 since

67
packages/nocodb/src/services/columns.service.ts

@ -28,6 +28,7 @@ import {
createHmAndBtColumn,
generateFkName,
randomID,
sanitizeColumnName,
validateLookupPayload,
validatePayload,
validateRequiredField,
@ -80,11 +81,6 @@ async function reuseOrSave(
return res;
}
const nc_sanitizeName = (name) => {
// replace all special characters by _
return name.replace(/\W+/g, '_').trim();
};
@Injectable()
export class ColumnsService {
constructor(
@ -123,6 +119,26 @@ export class ColumnsService {
const mxColumnLength = Column.getMaxColumnNameLength(sqlClientType);
if (!isVirtualCol(param.column)) {
param.column.column_name = sanitizeColumnName(param.column.column_name);
}
if (param.column.column_name.length > mxColumnLength) {
let colName = param.column.column_name.slice(0, mxColumnLength - 5);
let suffix = 1;
while (
!(await Column.checkTitleAvailable({
column_name: colName,
fk_model_id: column.fk_model_id,
exclude_id: param.columnId,
}))
) {
colName = param.column.column_name.slice(0, mxColumnLength - 5);
colName += `_${suffix++}`;
}
param.column.column_name = colName;
}
if (
!isVirtualCol(param.column) &&
param.column.column_name.length > mxColumnLength
@ -132,8 +148,10 @@ export class ColumnsService {
);
}
if (!isVirtualCol(param.column)) {
param.column.column_name = nc_sanitizeName(param.column.column_name);
if (param.column.title && param.column.title.length > 255) {
NcError.badRequest(
`Column title ${param.column.title} exceeds 255 characters`,
);
}
if (
@ -1043,19 +1061,36 @@ export class ColumnsService {
const mxColumnLength = Column.getMaxColumnNameLength(sqlClientType);
if (
(param.column.title || param.column.column_name).length > mxColumnLength
) {
if (!isVirtualCol(param.column)) {
param.column.column_name = sanitizeColumnName(param.column.column_name);
}
if (param.column.column_name.length > mxColumnLength) {
let colName = param.column.column_name.slice(0, mxColumnLength - 5);
let suffix = 1;
while (
!(await Column.checkTitleAvailable({
column_name: colName,
fk_model_id: param.tableId,
}))
) {
colName = param.column.column_name.slice(0, mxColumnLength - 5);
colName += `_${suffix++}`;
}
param.column.column_name = colName;
}
if (param.column.column_name.length > mxColumnLength) {
NcError.badRequest(
`Column name ${
param.column.title || param.column.column_name
} exceeds ${mxColumnLength} characters`,
`Column name ${param.column.column_name} exceeds ${mxColumnLength} characters`,
);
}
}
if (!isVirtualCol(param.column)) {
param.column.column_name = nc_sanitizeName(param.column.column_name);
if (param.column.title && param.column.title.length > 255) {
NcError.badRequest(
`Column title ${param.column.title} exceeds 255 characters`,
);
}
}
if (

12
packages/nocodb/src/services/tables.service.ts

@ -28,7 +28,7 @@ import mapDefaultDisplayValue from '~/helpers/mapDefaultDisplayValue';
import { Base, Column, Model, ModelRoleVisibility } from '~/models';
import Noco from '~/Noco';
import NcConnectionMgrv2 from '~/utils/common/NcConnectionMgrv2';
import { validatePayload } from '~/helpers';
import { sanitizeColumnName, validatePayload } from '~/helpers';
@Injectable()
export class TablesService {
@ -452,11 +452,21 @@ export class TablesService {
const mxColumnLength = Column.getMaxColumnNameLength(sqlClientType);
for (const column of param.table.columns) {
if (!isVirtualCol(column)) {
column.column_name = sanitizeColumnName(column.column_name);
}
if (column.column_name.length > mxColumnLength) {
NcError.badRequest(
`Column name ${column.column_name} exceeds ${mxColumnLength} characters`,
);
}
if (column.title && column.title.length > 255) {
NcError.badRequest(
`Column title ${column.title} exceeds 255 characters`,
);
}
}
tableCreatePayLoad.columns = await Promise.all(

Loading…
Cancel
Save