org.h2.util.ColumnNamerConfiguration Maven / Gradle / Ivy
/*
* Copyright 2004-2019 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (https://h2database.com/html/license.html).
*/
package org.h2.util;
import java.util.regex.Pattern;
import org.h2.engine.Mode.ModeEnum;
import static org.h2.engine.Mode.ModeEnum.*;
import org.h2.message.DbException;
/**
* The configuration for the allowed column names.
*/
public class ColumnNamerConfiguration {
private static final String DEFAULT_COMMAND = "DEFAULT";
private static final String REGULAR_EXPRESSION_MATCH_DISALLOWED = "REGULAR_EXPRESSION_MATCH_DISALLOWED = ";
private static final String REGULAR_EXPRESSION_MATCH_ALLOWED = "REGULAR_EXPRESSION_MATCH_ALLOWED = ";
private static final String DEFAULT_COLUMN_NAME_PATTERN = "DEFAULT_COLUMN_NAME_PATTERN = ";
private static final String MAX_IDENTIFIER_LENGTH = "MAX_IDENTIFIER_LENGTH = ";
private static final String EMULATE_COMMAND = "EMULATE = ";
private static final String GENERATE_UNIQUE_COLUMN_NAMES = "GENERATE_UNIQUE_COLUMN_NAMES = ";
private int maxIdentiferLength;
private String regularExpressionMatchAllowed;
private String regularExpressionMatchDisallowed;
private String defaultColumnNamePattern;
private boolean generateUniqueColumnNames;
private Pattern compiledRegularExpressionMatchAllowed;
private Pattern compiledRegularExpressionMatchDisallowed;
public ColumnNamerConfiguration(int maxIdentiferLength, String regularExpressionMatchAllowed,
String regularExpressionMatchDisallowed, String defaultColumnNamePattern,
boolean generateUniqueColumnNames) {
this.maxIdentiferLength = maxIdentiferLength;
this.regularExpressionMatchAllowed = regularExpressionMatchAllowed;
this.regularExpressionMatchDisallowed = regularExpressionMatchDisallowed;
this.defaultColumnNamePattern = defaultColumnNamePattern;
this.generateUniqueColumnNames = generateUniqueColumnNames;
recompilePatterns();
}
public int getMaxIdentiferLength() {
return maxIdentiferLength;
}
public void setMaxIdentiferLength(int maxIdentiferLength) {
this.maxIdentiferLength = Math.max(30, maxIdentiferLength);
if (maxIdentiferLength != getMaxIdentiferLength()) {
throw DbException.getInvalidValueException("Illegal value (<30) in SET COLUMN_NAME_RULES",
"MAX_IDENTIFIER_LENGTH=" + maxIdentiferLength);
}
}
public String getRegularExpressionMatchAllowed() {
return regularExpressionMatchAllowed;
}
public void setRegularExpressionMatchAllowed(String regularExpressionMatchAllowed) {
this.regularExpressionMatchAllowed = regularExpressionMatchAllowed;
}
public String getRegularExpressionMatchDisallowed() {
return regularExpressionMatchDisallowed;
}
public void setRegularExpressionMatchDisallowed(String regularExpressionMatchDisallowed) {
this.regularExpressionMatchDisallowed = regularExpressionMatchDisallowed;
}
public String getDefaultColumnNamePattern() {
return defaultColumnNamePattern;
}
public void setDefaultColumnNamePattern(String defaultColumnNamePattern) {
this.defaultColumnNamePattern = defaultColumnNamePattern;
}
/**
* Returns compiled pattern for allowed names.
*
* @return compiled pattern, or null for default
*/
public Pattern getCompiledRegularExpressionMatchAllowed() {
return compiledRegularExpressionMatchAllowed;
}
public void setCompiledRegularExpressionMatchAllowed(Pattern compiledRegularExpressionMatchAllowed) {
this.compiledRegularExpressionMatchAllowed = compiledRegularExpressionMatchAllowed;
}
/**
* Returns compiled pattern for disallowed names.
*
* @return compiled pattern, or null for default
*/
public Pattern getCompiledRegularExpressionMatchDisallowed() {
return compiledRegularExpressionMatchDisallowed;
}
public void setCompiledRegularExpressionMatchDisallowed(Pattern compiledRegularExpressionMatchDisallowed) {
this.compiledRegularExpressionMatchDisallowed = compiledRegularExpressionMatchDisallowed;
}
/**
* Configure the column namer.
*
* @param stringValue the configuration
*/
public void configure(String stringValue) {
try {
if (stringValue.equalsIgnoreCase(DEFAULT_COMMAND)) {
configure(REGULAR);
} else if (stringValue.startsWith(EMULATE_COMMAND)) {
configure(ModeEnum.valueOf(unquoteString(stringValue.substring(EMULATE_COMMAND.length()))));
} else if (stringValue.startsWith(MAX_IDENTIFIER_LENGTH)) {
int maxLength = Integer.parseInt(stringValue.substring(MAX_IDENTIFIER_LENGTH.length()));
setMaxIdentiferLength(maxLength);
} else if (stringValue.startsWith(GENERATE_UNIQUE_COLUMN_NAMES)) {
setGenerateUniqueColumnNames(
Integer.parseInt(stringValue.substring(GENERATE_UNIQUE_COLUMN_NAMES.length())) == 1);
} else if (stringValue.startsWith(DEFAULT_COLUMN_NAME_PATTERN)) {
setDefaultColumnNamePattern(
unquoteString(stringValue.substring(DEFAULT_COLUMN_NAME_PATTERN.length())));
} else if (stringValue.startsWith(REGULAR_EXPRESSION_MATCH_ALLOWED)) {
setRegularExpressionMatchAllowed(
unquoteString(stringValue.substring(REGULAR_EXPRESSION_MATCH_ALLOWED.length())));
} else if (stringValue.startsWith(REGULAR_EXPRESSION_MATCH_DISALLOWED)) {
setRegularExpressionMatchDisallowed(
unquoteString(stringValue.substring(REGULAR_EXPRESSION_MATCH_DISALLOWED.length())));
} else {
throw DbException.getInvalidValueException("SET COLUMN_NAME_RULES: unknown id:" + stringValue,
stringValue);
}
recompilePatterns();
}
// Including NumberFormatException|PatternSyntaxException
catch (RuntimeException e) {
throw DbException.getInvalidValueException("SET COLUMN_NAME_RULES:" + e.getMessage(), stringValue);
}
}
private void recompilePatterns() {
try {
// recompile RE patterns
setCompiledRegularExpressionMatchAllowed(
regularExpressionMatchAllowed != null ? Pattern.compile(regularExpressionMatchAllowed) : null);
setCompiledRegularExpressionMatchDisallowed(
regularExpressionMatchDisallowed != null ? Pattern.compile(regularExpressionMatchDisallowed)
: null);
} catch (Exception e) {
configure(REGULAR);
throw e;
}
}
public static ColumnNamerConfiguration getDefault() {
return new ColumnNamerConfiguration(Integer.MAX_VALUE, null, null, "_UNNAMED_$$", false);
}
private static String unquoteString(String s) {
if (s.startsWith("'") && s.endsWith("'")) {
s = s.substring(1, s.length() - 1);
return s;
}
return s;
}
public boolean isGenerateUniqueColumnNames() {
return generateUniqueColumnNames;
}
public void setGenerateUniqueColumnNames(boolean generateUniqueColumnNames) {
this.generateUniqueColumnNames = generateUniqueColumnNames;
}
/**
* Configure the rules.
*
* @param modeEnum the mode
*/
public void configure(ModeEnum modeEnum) {
switch (modeEnum) {
case Oracle:
// Nonquoted identifiers can contain only alphanumeric characters
// from your database character set and the underscore (_), dollar
// sign ($), and pound sign (#).
setMaxIdentiferLength(128);
setRegularExpressionMatchAllowed("(?m)(?s)\"?[A-Za-z0-9_\\$#]+\"?");
setRegularExpressionMatchDisallowed("(?m)(?s)[^A-Za-z0-9_\"\\$#]");
setDefaultColumnNamePattern("_UNNAMED_$$");
setGenerateUniqueColumnNames(false);
break;
case MSSQLServer:
// https://docs.microsoft.com/en-us/sql/sql-server/maximum-capacity-specifications-for-sql-server
setMaxIdentiferLength(128);
// allows [] around names
setRegularExpressionMatchAllowed("(?m)(?s)[A-Za-z0-9_\\[\\]]+");
setRegularExpressionMatchDisallowed("(?m)(?s)[^A-Za-z0-9_\\[\\]]");
setDefaultColumnNamePattern("_UNNAMED_$$");
setGenerateUniqueColumnNames(false);
break;
case PostgreSQL:
// https://www.postgresql.org/docs/current/static/sql-syntax-lexical.html
setMaxIdentiferLength(63);
setRegularExpressionMatchAllowed("(?m)(?s)[A-Za-z0-9_\\$]+");
setRegularExpressionMatchDisallowed("(?m)(?s)[^A-Za-z0-9_\\$]");
setDefaultColumnNamePattern("_UNNAMED_$$");
setGenerateUniqueColumnNames(false);
break;
case MySQL:
// https://dev.mysql.com/doc/refman/8.0/en/identifiers.html
// https://mariadb.com/kb/en/library/identifier-names/
setMaxIdentiferLength(64);
setRegularExpressionMatchAllowed("(?m)(?s)`?[A-Za-z0-9_`\\$]+`?");
setRegularExpressionMatchDisallowed("(?m)(?s)[^A-Za-z0-9_`\\$]");
setDefaultColumnNamePattern("_UNNAMED_$$");
setGenerateUniqueColumnNames(false);
break;
case REGULAR:
case DB2:
case Derby:
case HSQLDB:
case Ignite:
default:
setMaxIdentiferLength(Integer.MAX_VALUE);
setRegularExpressionMatchAllowed(null);
setRegularExpressionMatchDisallowed(null);
setDefaultColumnNamePattern("_UNNAMED_$$");
setGenerateUniqueColumnNames(false);
break;
}
recompilePatterns();
}
}