Browse Source

Merge pull request #5131 from nocodb/feat/column-length-validator

feat(nc-gui): fieldLengthValidator
pull/5138/head
Raju Udava 2 years ago committed by GitHub
parent
commit
6862d68377
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      packages/nc-gui/components/template/Editor.vue
  2. 4
      packages/nc-gui/composables/useColumnCreateStore.ts
  3. 1
      packages/nc-gui/lang/en.json
  4. 26
      packages/nc-gui/utils/validation.ts
  5. 31
      packages/nocodb/src/lib/meta/api/columnApis.ts
  6. 15
      packages/nocodb/src/lib/meta/api/tableApis.ts
  7. 13
      packages/nocodb/src/lib/models/Column.ts

8
packages/nc-gui/components/template/Editor.vue

@ -12,6 +12,7 @@ import {
computed,
createEventHook,
extractSdkResponseErrorMsg,
fieldLengthValidator,
fieldRequiredValidator,
getDateFormat,
getDateTimeFormat,
@ -110,12 +111,15 @@ const data = reactive<{
})
const validators = computed(() =>
data.tables.reduce<Record<string, [ReturnType<typeof fieldRequiredValidator>]>>((acc, table, tableIdx) => {
data.tables.reduce<Record<string, [ReturnType<typeof fieldRequiredValidator>]>>((acc: Record<string, any>, table, tableIdx) => {
acc[`tables.${tableIdx}.table_name`] = [fieldRequiredValidator()]
hasSelectColumn.value[tableIdx] = false
table.columns?.forEach((column, columnIdx) => {
acc[`tables.${tableIdx}.columns.${columnIdx}.column_name`] = [fieldRequiredValidator()]
acc[`tables.${tableIdx}.columns.${columnIdx}.column_name`] = [
fieldRequiredValidator(),
fieldLengthValidator(project.value?.bases?.[0].type || ClientType.MYSQL),
]
acc[`tables.${tableIdx}.columns.${columnIdx}.uidt`] = [fieldRequiredValidator()]
if (isSelect(column)) {
hasSelectColumn.value[tableIdx] = true

4
packages/nc-gui/composables/useColumnCreateStore.ts

@ -27,7 +27,8 @@ interface ValidationsObj {
const [useProvideColumnCreateStore, useColumnCreateStore] = createInjectionState(
(meta: Ref<TableType | undefined>, column: Ref<ColumnType | undefined>) => {
const { sqlUis, isMysql: isMysqlFunc, isPg: isPgFunc, isMssql: isMssqlFunc } = useProject()
const { project, sqlUis, isMysql: isMysqlFunc, isPg: isPgFunc, isMssql: isMssqlFunc } = useProject()
const { $api } = useNuxtApp()
const { getMeta } = useMetas()
@ -93,6 +94,7 @@ const [useProvideColumnCreateStore, useColumnCreateStore] = createInjectionState
})
},
},
fieldLengthValidator(project.value?.bases?.[0].type || ClientType.MYSQL),
],
uidt: [
{

1
packages/nc-gui/lang/en.json

@ -690,6 +690,7 @@
"nameShouldStartWithAnAlphabetOr_": "Name should start with an alphabet or _",
"followingCharactersAreNotAllowed": "Following characters are not allowed",
"columnNameRequired": "Column name is required",
"columnNameExceedsCharacters": "The length of column name exceeds the max {value} characters",
"projectNameExceeds50Characters": "Project name exceeds 50 characters",
"projectNameCannotStartWithSpace": "Project name cannot start with space",
"requiredField": "Required field",

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

@ -80,6 +80,32 @@ export const fieldRequiredValidator = () => {
}
}
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
if (sqlClientType === 'mysql2' || sqlClientType === 'mysql') {
fieldLengthLimit = 64
} else if (sqlClientType === 'pg') {
fieldLengthLimit = 59
} else if (sqlClientType === 'mssql') {
fieldLengthLimit = 128
}
return new Promise((resolve, reject) => {
if (value?.length > fieldLengthLimit) {
reject(new Error(t('msg.error.columnNameExceedsCharacters', { value: fieldLengthLimit })))
}
resolve(true)
})
},
}
}
export const importUrlValidator = {
validator: (rule: any, value: any) => {
return new Promise((resolve, reject) => {

31
packages/nocodb/src/lib/meta/api/columnApis.ts

@ -64,9 +64,27 @@ export async function columnAdd(
const table = await Model.getWithInfo({
id: req.params.tableId,
});
const base = await Base.get(table.base_id);
const project = await base.getProject();
if (req.body.title || req.body.column_name) {
const dbDriver = NcConnectionMgrv2.get(base);
const sqlClientType = dbDriver.clientType();
const mxColumnLength = Column.getMaxColumnNameLength(sqlClientType);
if ((req.body.title || req.body.column_name).length > mxColumnLength) {
NcError.badRequest(
`Column name ${
req.body.title || req.body.column_name
} exceeds ${mxColumnLength} characters`
);
}
}
if (
!isVirtualCol(req.body) &&
!(await Column.checkTitleAvailable({
@ -638,8 +656,21 @@ export async function columnUpdate(req: Request, res: Response<TableType>) {
const table = await Model.getWithInfo({
id: column.fk_model_id,
});
const base = await Base.get(table.base_id);
const sqlClient = await NcConnectionMgrv2.getSqlClient(base);
const sqlClientType = sqlClient.knex.clientType();
const mxColumnLength = Column.getMaxColumnNameLength(sqlClientType);
if (req.body.column_name.length > mxColumnLength) {
NcError.badRequest(
`Column name ${req.body.column_name} exceeds ${mxColumnLength} characters`
);
}
if (
!isVirtualCol(req.body) &&
!(await Column.checkTitleAvailable({

15
packages/nocodb/src/lib/meta/api/tableApis.ts

@ -148,10 +148,11 @@ export async function tableCreate(req: Request<any, any, TableReqType>, res) {
}
const sqlMgr = await ProjectMgrv2.getSqlMgr(project);
const sqlClient = await NcConnectionMgrv2.getSqlClient(base);
let tableNameLengthLimit = 255;
const sqlClientType = sqlClient.clientType;
const sqlClientType = sqlClient.knex.clientType();
if (sqlClientType === 'mysql2' || sqlClientType === 'mysql') {
tableNameLengthLimit = 64;
} else if (sqlClientType === 'pg') {
@ -164,6 +165,16 @@ export async function tableCreate(req: Request<any, any, TableReqType>, res) {
NcError.badRequest(`Table name exceeds ${tableNameLengthLimit} characters`);
}
const mxColumnLength = Column.getMaxColumnNameLength(sqlClientType);
for (const column of req.body.columns) {
if (column.column_name.length > mxColumnLength) {
NcError.badRequest(
`Column name ${column.column_name} exceeds ${mxColumnLength} characters`
);
}
}
req.body.columns = req.body.columns?.map((c) => ({
...getColumnPropsFromUIDT(c as any, base),
cn: c.column_name,
@ -298,7 +309,7 @@ export async function tableUpdate(req: Request<any, any>, res) {
const sqlClient = await NcConnectionMgrv2.getSqlClient(base);
let tableNameLengthLimit = 255;
const sqlClientType = sqlClient.clientType;
const sqlClientType = sqlClient.knex.clientType();
if (sqlClientType === 'mysql2' || sqlClientType === 'mysql') {
tableNameLengthLimit = 64;
} else if (sqlClientType === 'pg') {

13
packages/nocodb/src/lib/models/Column.ts

@ -1151,4 +1151,17 @@ export default class Column<T = any> implements ColumnType {
colId
);
}
static getMaxColumnNameLength(sqlClientType: string) {
// no limit for sqlite but set as 255
let fieldLengthLimit = 255;
if (sqlClientType === 'mysql2' || sqlClientType === 'mysql') {
fieldLengthLimit = 64;
} else if (sqlClientType === 'pg') {
fieldLengthLimit = 59;
} else if (sqlClientType === 'mssql') {
fieldLengthLimit = 128;
}
return fieldLengthLimit;
}
}

Loading…
Cancel
Save