Skip to content

Commit 6f0cb7e

Browse files
committed
Add makeVariableName method, update unit tests
1 parent e86733e commit 6f0cb7e

3 files changed

Lines changed: 90 additions & 18 deletions

File tree

packages/console/src/csv/CsvInputBar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class CsvInputBar extends Component<CsvInputBarProps, CsvInputBarState> {
8989
// Set the table name from a file
9090
if (!tableNameSet && file != null && !tableName) {
9191
const dotIndex = file.name.lastIndexOf('.');
92-
const fileTableName = DbNameValidator.legalizeTableName(
92+
const fileTableName = DbNameValidator.makeVariableName(
9393
file.name.substring(0, dotIndex)
9494
);
9595
this.setState({

packages/utils/src/DbNameValidator.test.ts

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,27 @@ import DbNameValidator from './DbNameValidator';
33
const TABLE_PREFIX = 'table_';
44
const COLUMN_PREFIX = 'column_';
55

6-
const VALID_TABLE_NAME = '$+@abc-123_ABC';
7-
const CLEANED_VALID_TABLE_NAME = 'abc_123_ABC';
8-
const INVALID_TABLE_NAMES = ['%^&ab-c', '-a_b c', '-'];
9-
const CLEANED_INVALID_TABLE_NAMES = ['ab_c', '_a_b_c', '_'];
6+
// $ is not a valid table name in Deephaven, but this behavior is consistent with the Java class
7+
const VALID_TABLE_NAMES = ['$+@abc-123_ABC', '$'];
8+
const VARIABLE_NAMES_FROM_VALID = ['$__abc_123_ABC', '$'];
9+
10+
const INVALID_TABLE_NAMES = ['%^&ab-c', '-a_b c', '-', '0', '%', ''];
11+
const LEGALIZED_INVALID_TABLE_NAMES = [
12+
'ab-c',
13+
'table_-a_b_c',
14+
'table_-',
15+
'table_0',
16+
'table_0',
17+
'table_0',
18+
];
19+
const VARIABLE_NAMES_FROM_INVALID = [
20+
'ab_c',
21+
'table__a_b_c',
22+
'table__',
23+
'table_0',
24+
'table_0',
25+
'table_0',
26+
];
1027

1128
const VALID_COL_NAME = 'abc123_ABC';
1229
const INVALID_COL_NAME = '@abc123_ABC-123';
@@ -17,8 +34,8 @@ const RESERVED_JAVA_WORD = 'return';
1734
const RESERVED_DEEPHAVEN_WORD = 'not';
1835

1936
describe('Table name validation', () => {
20-
it('Returns true on valid table names', () => {
21-
expect(DbNameValidator.isValidTableName(VALID_TABLE_NAME)).toBe(true);
37+
it.each(VALID_TABLE_NAMES)('Returns true on valid table name %s', name => {
38+
expect(DbNameValidator.isValidTableName(name)).toBe(true);
2239
});
2340

2441
it.each(INVALID_TABLE_NAMES)(
@@ -50,14 +67,15 @@ describe('Column name validation', () => {
5067
});
5168

5269
describe('legalizeTableName', () => {
53-
it('Sanitizes a table name even if it is valid', () => {
54-
expect(DbNameValidator.legalizeTableName(VALID_TABLE_NAME)).toBe(
55-
CLEANED_VALID_TABLE_NAME
56-
);
70+
it.each(VALID_TABLE_NAMES)('Does not change a valid table name $s', name => {
71+
expect(DbNameValidator.legalizeTableName(name)).toBe(name);
5772
});
5873

5974
it.each(
60-
INVALID_TABLE_NAMES.map((name, i) => [name, CLEANED_INVALID_TABLE_NAMES[i]])
75+
INVALID_TABLE_NAMES.map((name, i) => [
76+
name,
77+
LEGALIZED_INVALID_TABLE_NAMES[i],
78+
])
6179
)('Legalize an invalid table name %s > %s', (invalid, cleaned) => {
6280
expect(DbNameValidator.legalizeTableName(invalid)).toBe(cleaned);
6381
});
@@ -73,6 +91,25 @@ describe('legalizeTableName', () => {
7391
});
7492
});
7593

94+
describe('makeVariableName', () => {
95+
it.each(
96+
VALID_TABLE_NAMES.map((name, i) => [name, VARIABLE_NAMES_FROM_VALID[i]])
97+
)(
98+
'Makes a variable name for a valid table name %s > %s',
99+
(invalid, variableName) => {
100+
expect(DbNameValidator.makeVariableName(invalid)).toBe(variableName);
101+
}
102+
);
103+
it.each(
104+
INVALID_TABLE_NAMES.map((name, i) => [name, VARIABLE_NAMES_FROM_INVALID[i]])
105+
)(
106+
'Makes a variable name for an invalid table name %s > %s',
107+
(invalid, variableName) => {
108+
expect(DbNameValidator.makeVariableName(invalid)).toBe(variableName);
109+
}
110+
);
111+
});
112+
76113
describe('legalizeColumnName', () => {
77114
it('Does not change a valid column name', () => {
78115
expect(DbNameValidator.legalizeColumnName(VALID_COL_NAME)).toBe(

packages/utils/src/DbNameValidator.ts

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,19 @@ const STERILE_TABLE_AND_NAMESPACE_REGEX = /[^a-zA-Z0-9_$\-+@]/g;
6969
const STERILE_COLUMN_AND_QUERY_REGEX = /[^A-Za-z0-9_$]/g;
7070

7171
// From io.deephaven.db.tables.utils.DBNameValidator#TABLE_NAME_PATTERN
72-
const TABLE_NAME_PATTERN = /^[a-zA-Z_$][a-zA-Z0-9_$\-+@]*$/g;
72+
const TABLE_NAME_PATTERN = /^[a-zA-Z_$][a-zA-Z0-9_$\-+@]*$/;
73+
74+
const STERILE_VARIABLE_NAME_REGEX = /[^a-zA-Z0-9_$]/g;
75+
76+
function columnNameReplacer(input: string): string {
77+
// Replace all dashes and spaces with underscores
78+
return input.replace(/[ -]/g, '_');
79+
}
80+
81+
function tableNameReplacer(input: string): string {
82+
// Replace spaces with underscores
83+
return input.replace(/\s/g, '_');
84+
}
7385

7486
/**
7587
* Similar to DBNameValidator.java, this class has utilities for validating and legalizing
@@ -78,12 +90,13 @@ const TABLE_NAME_PATTERN = /^[a-zA-Z_$][a-zA-Z0-9_$\-+@]*$/g;
7890
class DbNameValidator {
7991
static legalize = (
8092
name: string,
93+
replace: (input: string) => string,
8194
prefix: string,
8295
regex: RegExp,
8396
checkReserved: boolean,
8497
i: number
8598
): string => {
86-
let legalName = name.trim().replace(/[ -]/g, '_');
99+
let legalName = replace(name.trim());
87100

88101
// Add prefix to reserved names
89102
if (
@@ -97,28 +110,49 @@ class DbNameValidator {
97110
// Remove illegal characters
98111
legalName = legalName.replace(regex, '');
99112

100-
// Check if the name ended up blank
113+
// Check if the name ended up blank and append the prefix.
114+
// Note, io.deephaven.db.tables.utils.DBNameValidator throws an exception in this case.
101115
if (!legalName) {
102-
legalName = prefix + i;
116+
return prefix + i;
103117
}
104118

105-
// If name starts with a number, append prefix to the front
106-
if (!Number.isNaN(Number(legalName.charAt(0)))) {
119+
// If name starts with a number or a dash, append the prefix.
120+
// Note, io.deephaven.db.tables.utils.DBNameValidator throws an exception for names starting with a dash.
121+
if (/^[0-9-]/.test(legalName)) {
107122
legalName = prefix + legalName;
108123
}
109124

110125
return legalName;
111126
};
112127

128+
/**
129+
* Get a legal table name based on the passed in string.
130+
* Follows the same rules as DBNameValidator.java except that here
131+
* we prepend a prefix in cases where the Java class throws an exception.
132+
* @param name The name to legalize
133+
* @returns Legalized table name
134+
*/
113135
static legalizeTableName = (name: string): string =>
114136
DbNameValidator.legalize(
115137
name,
138+
tableNameReplacer,
116139
TABLE_PREFIX,
117140
STERILE_TABLE_AND_NAMESPACE_REGEX,
118141
false,
119142
0
120143
);
121144

145+
/**
146+
* Get a variable name based on the passed in string.
147+
* @param name The name to get the variable name for
148+
* @returns Variable name
149+
*/
150+
static makeVariableName = (name: string): string =>
151+
DbNameValidator.legalizeTableName(name).replace(
152+
STERILE_VARIABLE_NAME_REGEX,
153+
'_'
154+
);
155+
122156
static legalizeColumnNames = (headers: string[]): string[] => {
123157
const legalHeaders: string[] = [];
124158
headers.forEach((header, i) => {
@@ -138,6 +172,7 @@ class DbNameValidator {
138172
// Replace all dashes and spaces with underscores
139173
DbNameValidator.legalize(
140174
header,
175+
columnNameReplacer,
141176
COLUMN_PREFIX,
142177
STERILE_COLUMN_AND_QUERY_REGEX,
143178
true,

0 commit comments

Comments
 (0)