mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
ADD: Support for quoted identifiers
This commit is contained in:
@@ -58,30 +58,16 @@ public class DbConstraintNormalise {
|
||||
/**
|
||||
* Trim off the platform quoted identifier quotes like [ ' and ".
|
||||
*/
|
||||
public boolean notQuoted(String tableName) {
|
||||
public String trimQuotes(String identifier) {
|
||||
|
||||
// remove quoted identifier characters
|
||||
for (String quotedIdentifier : quotedIdentifiers) {
|
||||
if (tableName.contains(quotedIdentifier)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trim off the platform quoted identifier quotes like [ ' and ".
|
||||
*/
|
||||
public String trimQuotes(String tableName) {
|
||||
|
||||
if (tableName == null) {
|
||||
if (identifier == null) {
|
||||
return "";
|
||||
}
|
||||
// remove quoted identifier characters
|
||||
for (String quotedIdentifier : quotedIdentifiers) {
|
||||
tableName = tableName.replace(quotedIdentifier, "");
|
||||
identifier = identifier.replace(quotedIdentifier, "");
|
||||
}
|
||||
return tableName;
|
||||
return identifier;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ public class DatabasePlatform {
|
||||
* want to use quoted identifiers for. The backticks get converted to the
|
||||
* appropriate characters in convertQuotedIdentifiers
|
||||
*/
|
||||
private static final char BACK_TICK = '`';
|
||||
private static final char[] QUOTED_IDENTIFIERS = new char[] { '"', '\'', '[', ']', '`' };
|
||||
|
||||
/**
|
||||
* The non-escaped like clause (to stop slash being escaped on some platforms).
|
||||
@@ -662,8 +662,8 @@ public class DatabasePlatform {
|
||||
public String convertQuotedIdentifiers(String dbName) {
|
||||
// Ignore null values e.g. schema name or catalog
|
||||
if (dbName != null && !dbName.isEmpty()) {
|
||||
if (dbName.charAt(0) == BACK_TICK) {
|
||||
if (dbName.charAt(dbName.length() - 1) == BACK_TICK) {
|
||||
if (isQuote(dbName.charAt(0))) {
|
||||
if (isQuote(dbName.charAt(dbName.length() - 1))) {
|
||||
return openQuote + dbName.substring(1, dbName.length() - 1) + closeQuote;
|
||||
} else {
|
||||
log.error("Missing backquote on [" + dbName + "]");
|
||||
@@ -675,6 +675,15 @@ public class DatabasePlatform {
|
||||
return dbName;
|
||||
}
|
||||
|
||||
private boolean isQuote(char ch) {
|
||||
for (char identifer : QUOTED_IDENTIFIERS) {
|
||||
if (identifer == ch) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove quoted identifier quotes from the table or column name if present.
|
||||
*/
|
||||
|
||||
+2
-2
@@ -200,10 +200,10 @@ public abstract class AbstractHanaDdl extends PlatformDdl {
|
||||
/**
|
||||
* Joins alter table commands and add open/closing brackets for the alter statements
|
||||
*/
|
||||
private static class HanaAlterTableWrite extends BaseAlterTableWrite {
|
||||
class HanaAlterTableWrite extends BaseAlterTableWrite {
|
||||
|
||||
public HanaAlterTableWrite(String tableName) {
|
||||
super(tableName);
|
||||
super(tableName, AbstractHanaDdl.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+6
-3
@@ -17,6 +17,8 @@ public class BaseAlterTableWrite implements DdlAlterTable {
|
||||
|
||||
protected static final String RAW_OPERATION = "$RAW";
|
||||
|
||||
protected final PlatformDdl platformDdl;
|
||||
|
||||
public class AlterCmd {
|
||||
// the command (e.g. "alter", "modify"
|
||||
private final String operation;
|
||||
@@ -58,9 +60,9 @@ public class BaseAlterTableWrite implements DdlAlterTable {
|
||||
// of all alter commands
|
||||
target.append(getAlternation());
|
||||
} else {
|
||||
target.append("alter table ").append(tableName).append(' ').append(operation);
|
||||
target.append("alter table ").append(platformDdl.quote(tableName)).append(' ').append(operation);
|
||||
if (column != null) {
|
||||
target.append(' ').append(column);
|
||||
target.append(' ').append(platformDdl.quote(column));
|
||||
}
|
||||
if (!getAlternation().isEmpty()) {
|
||||
target.append(' ').append(getAlternation());
|
||||
@@ -85,8 +87,9 @@ public class BaseAlterTableWrite implements DdlAlterTable {
|
||||
|
||||
private boolean historyHandled;
|
||||
|
||||
public BaseAlterTableWrite(String tableName) {
|
||||
public BaseAlterTableWrite(String tableName, PlatformDdl platformDdl) {
|
||||
this.tableName = tableName;
|
||||
this.platformDdl = platformDdl;
|
||||
}
|
||||
|
||||
public String tableName() {
|
||||
|
||||
+3
-3
@@ -222,7 +222,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
String partitionMode = createTable.getPartitionMode();
|
||||
|
||||
DdlBuffer apply = writer.apply();
|
||||
apply.append(platformDdl.getCreateTableCommandPrefix()).append(" ").append(tableName).append(" (");
|
||||
apply.append(platformDdl.getCreateTableCommandPrefix()).append(" ").append(platformDdl.quote(tableName)).append(" (");
|
||||
writeTableColumns(apply, columns, identity);
|
||||
writeUniqueConstraints(apply, createTable);
|
||||
writeCompoundUniqueConstraints(apply, createTable);
|
||||
@@ -423,7 +423,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
if (i > 0) {
|
||||
buffer.append(",");
|
||||
}
|
||||
buffer.append(columns[i].trim());
|
||||
buffer.append(platformDdl.quote(columns[i].trim()));
|
||||
}
|
||||
buffer.append(")");
|
||||
}
|
||||
@@ -490,7 +490,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
buffer.append(",").newLine();
|
||||
buffer.append(" constraint ").append(uqName).append(" unique ");
|
||||
buffer.append("(");
|
||||
buffer.append(column.getName());
|
||||
buffer.append(platformDdl.quote(column.getName()));
|
||||
buffer.append(")");
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -161,10 +161,10 @@ public class DB2Ddl extends PlatformDdl {
|
||||
return writer.applyAlterTable(tableName, Db2AlterTableWrite::new);
|
||||
};
|
||||
|
||||
static class Db2AlterTableWrite extends BaseAlterTableWrite {
|
||||
class Db2AlterTableWrite extends BaseAlterTableWrite {
|
||||
|
||||
public Db2AlterTableWrite(String tableName) {
|
||||
super(tableName);
|
||||
super(tableName, DB2Ddl.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+5
-4
@@ -32,13 +32,14 @@ public class MySqlDdl extends PlatformDdl {
|
||||
*/
|
||||
@Override
|
||||
public String dropIndex(String indexName, String tableName, boolean concurrent) {
|
||||
return "drop index " + maxConstraintName(indexName) + " on " + tableName;
|
||||
return "drop index " + maxConstraintName(indexName) + " on " + quote(tableName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void alterTableDropColumn(DdlWrite writer, String tableName, String columnName) {
|
||||
if (this.useMigrationStoredProcedures) {
|
||||
alterTable(writer, tableName).raw("CALL usp_ebean_drop_column('").append(tableName).append("', '").append(columnName).append("')");
|
||||
alterTable(writer, tableName).raw("CALL usp_ebean_drop_column('").append(naming.normaliseTable(tableName))
|
||||
.append("', '").append(naming.normaliseColumn(columnName)).append("')");
|
||||
} else {
|
||||
super.alterTableDropColumn(writer, tableName, columnName);
|
||||
}
|
||||
@@ -49,7 +50,7 @@ public class MySqlDdl extends PlatformDdl {
|
||||
*/
|
||||
@Override
|
||||
public String alterTableDropForeignKey(String tableName, String fkName) {
|
||||
return "alter table " + tableName + " drop foreign key " + maxConstraintName(fkName);
|
||||
return "alter table " + quote(tableName) + " drop foreign key " + maxConstraintName(fkName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -146,7 +147,7 @@ public class MySqlDdl extends PlatformDdl {
|
||||
if (DdlHelp.isDropComment(tableComment)) {
|
||||
tableComment = "";
|
||||
}
|
||||
apply.append(String.format("alter table %s comment = '%s'", tableName, tableComment)).endOfStatement();
|
||||
apply.append(String.format("alter table %s comment = '%s'", quote(tableName), tableComment)).endOfStatement();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+23
-18
@@ -258,7 +258,7 @@ public class PlatformDdl {
|
||||
}
|
||||
|
||||
buffer.append(" ");
|
||||
buffer.append(column.getName(), 29);
|
||||
buffer.append(quote(column.getName()), 29);
|
||||
buffer.append(columnDefn);
|
||||
if (!Boolean.TRUE.equals(column.isPrimaryKey())) {
|
||||
String defaultValue = convertDefaultValue(column.getDefaultValue());
|
||||
@@ -278,7 +278,7 @@ public class PlatformDdl {
|
||||
* Returns the check constraint.
|
||||
*/
|
||||
public String createCheckConstraint(String ckName, String checkConstraint) {
|
||||
return " constraint " + ckName + " " + checkConstraint;
|
||||
return " constraint " + maxConstraintName(ckName) + " " + checkConstraint;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -292,7 +292,7 @@ public class PlatformDdl {
|
||||
* Return the drop foreign key clause.
|
||||
*/
|
||||
public String alterTableDropForeignKey(String tableName, String fkName) {
|
||||
return "alter table " + alterTableIfExists + tableName + " " + dropConstraintIfExists + " " + maxConstraintName(fkName);
|
||||
return "alter table " + alterTableIfExists + quote(tableName) + " " + dropConstraintIfExists + " " + maxConstraintName(fkName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -372,7 +372,7 @@ public class PlatformDdl {
|
||||
*/
|
||||
public String createSequence(String sequenceName, DdlIdentity identity) {
|
||||
StringBuilder sb = new StringBuilder("create sequence ");
|
||||
sb.append(sequenceName);
|
||||
sb.append(quote(sequenceName));
|
||||
sb.append(identity.sequenceOptions(sequenceStartWith, sequenceIncrementBy, sequenceCache));
|
||||
sb.append(";");
|
||||
return sb.toString();
|
||||
@@ -382,14 +382,14 @@ public class PlatformDdl {
|
||||
* Return the drop sequence statement (potentially with if exists clause).
|
||||
*/
|
||||
public String dropSequence(String sequenceName) {
|
||||
return dropSequenceIfExists + sequenceName;
|
||||
return dropSequenceIfExists + quote(sequenceName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the drop table statement (potentially with if exists clause).
|
||||
*/
|
||||
public String dropTable(String tableName) {
|
||||
return dropTableIfExists + tableName + dropTableCascade;
|
||||
return dropTableIfExists + quote(tableName) + dropTableCascade;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -422,7 +422,7 @@ public class PlatformDdl {
|
||||
if (create.isNotExistsCheck()) {
|
||||
buffer.append(createIndexIfNotExists);
|
||||
}
|
||||
buffer.append(maxConstraintName(create.getIndexName())).append(" on ").append(create.getTableName());
|
||||
buffer.append(maxConstraintName(create.getIndexName())).append(" on ").append(quote(create.getTableName()));
|
||||
appendColumns(create.getColumns(), buffer);
|
||||
return buffer.toString();
|
||||
}
|
||||
@@ -435,7 +435,7 @@ public class PlatformDdl {
|
||||
StringBuilder buffer = new StringBuilder(90);
|
||||
buffer.append("foreign key");
|
||||
appendColumns(request.cols(), buffer);
|
||||
buffer.append(" references ").append(request.refTable());
|
||||
buffer.append(" references ").append(quote(request.refTable()));
|
||||
appendColumns(request.refCols(), buffer);
|
||||
appendForeignKeySuffix(request, buffer);
|
||||
return buffer.toString();
|
||||
@@ -448,13 +448,13 @@ public class PlatformDdl {
|
||||
|
||||
StringBuilder buffer = new StringBuilder(90);
|
||||
buffer
|
||||
.append("alter table ").append(request.table())
|
||||
.append("alter table ").append(quote(request.table()))
|
||||
.append(" add constraint ").append(maxConstraintName(request.fkName()))
|
||||
.append(" foreign key");
|
||||
appendColumns(request.cols(), buffer);
|
||||
buffer
|
||||
.append(" references ")
|
||||
.append(request.refTable());
|
||||
.append(quote(request.refTable()));
|
||||
appendColumns(request.refCols(), buffer);
|
||||
appendForeignKeySuffix(request, buffer);
|
||||
if (options.isForeignKeySkipCheck()) {
|
||||
@@ -503,14 +503,14 @@ public class PlatformDdl {
|
||||
* Drop a unique constraint from the table (Sometimes this is an index).
|
||||
*/
|
||||
public String alterTableDropUniqueConstraint(String tableName, String uniqueConstraintName) {
|
||||
return "alter table " + tableName + " " + dropUniqueConstraint + " " + maxConstraintName(uniqueConstraintName);
|
||||
return "alter table " + quote(tableName) + " " + dropUniqueConstraint + " " + maxConstraintName(uniqueConstraintName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop a unique constraint from the table.
|
||||
*/
|
||||
public String alterTableDropConstraint(String tableName, String constraintName) {
|
||||
return "alter table " + tableName + " " + dropConstraintIfExists + " " + maxConstraintName(constraintName);
|
||||
return "alter table " + quote(tableName) + " " + dropConstraintIfExists + " " + maxConstraintName(constraintName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -521,7 +521,7 @@ public class PlatformDdl {
|
||||
public String alterTableAddUniqueConstraint(String tableName, String uqName, String[] columns, String[] nullableColumns) {
|
||||
|
||||
StringBuilder buffer = new StringBuilder(90);
|
||||
buffer.append("alter table ").append(tableName).append(" add constraint ").append(maxConstraintName(uqName)).append(" unique ");
|
||||
buffer.append("alter table ").append(quote(tableName)).append(" add constraint ").append(maxConstraintName(uqName)).append(" unique ");
|
||||
appendColumns(columns, buffer);
|
||||
return buffer.toString();
|
||||
}
|
||||
@@ -612,7 +612,7 @@ public class PlatformDdl {
|
||||
* Alter table adding the check constraint.
|
||||
*/
|
||||
public String alterTableAddCheckConstraint(String tableName, String checkConstraintName, String checkConstraint) {
|
||||
return "alter table " + tableName + " " + addConstraint + " " + maxConstraintName(checkConstraintName) + " " + checkConstraint;
|
||||
return "alter table " + quote(tableName) + " " + addConstraint + " " + maxConstraintName(checkConstraintName) + " " + checkConstraint;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -656,7 +656,7 @@ public class PlatformDdl {
|
||||
* Creates or replace a new DdlAlterTable for given tableName.
|
||||
*/
|
||||
protected DdlAlterTable alterTable(DdlWrite writer, String tableName) {
|
||||
return writer.applyAlterTable(tableName, BaseAlterTableWrite::new);
|
||||
return writer.applyAlterTable(tableName, k -> new BaseAlterTableWrite(k, this));
|
||||
}
|
||||
|
||||
protected void appendColumns(String[] columns, StringBuilder buffer) {
|
||||
@@ -665,7 +665,7 @@ public class PlatformDdl {
|
||||
if (i > 0) {
|
||||
buffer.append(",");
|
||||
}
|
||||
buffer.append(columns[i].trim());
|
||||
buffer.append(quote(columns[i].trim()));
|
||||
}
|
||||
buffer.append(")");
|
||||
}
|
||||
@@ -713,7 +713,7 @@ public class PlatformDdl {
|
||||
if (DdlHelp.isDropComment(tableComment)) {
|
||||
tableComment = "";
|
||||
}
|
||||
apply.append(String.format("comment on table %s is '%s'", tableName, tableComment)).endOfStatement();
|
||||
apply.append(String.format("comment on table %s is '%s'", quote(tableName), tableComment)).endOfStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -723,7 +723,7 @@ public class PlatformDdl {
|
||||
if (DdlHelp.isDropComment(comment)) {
|
||||
comment = "";
|
||||
}
|
||||
apply.append(String.format("comment on column %s.%s is '%s'", table, column, comment)).endOfStatement();
|
||||
apply.append(String.format("comment on column %s.%s is '%s'", quote(table), quote(column), comment)).endOfStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -777,4 +777,9 @@ public class PlatformDdl {
|
||||
public void addTablePartition(DdlBuffer apply, String partitionMode, String partitionColumn) {
|
||||
// only supported by postgres initially
|
||||
}
|
||||
|
||||
protected String quote(String dbName) {
|
||||
return platform.convertQuotedIdentifiers(dbName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -68,9 +68,9 @@ public class SQLiteDdl extends PlatformDdl {
|
||||
return writer.applyAlterTable(tableName, SQLiteAlterTableWrite::new);
|
||||
}
|
||||
|
||||
static class SQLiteAlterTableWrite extends BaseAlterTableWrite {
|
||||
class SQLiteAlterTableWrite extends BaseAlterTableWrite {
|
||||
public SQLiteAlterTableWrite(String tableName) {
|
||||
super(tableName);
|
||||
super(tableName, SQLiteDdl.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+11
-6
@@ -39,7 +39,7 @@ public class SqlServerHistoryDdl implements PlatformHistoryDdl {
|
||||
|
||||
private void enableSystemVersioning(DdlWrite writer, String baseTable) {
|
||||
DdlBuffer apply = writer.applyPostAlter();
|
||||
apply.append("alter table ").append(baseTable).newLine()
|
||||
apply.append("alter table ").append(quote(baseTable)).newLine()
|
||||
.append(" add ").append(systemPeriodStart).append(" datetime2 GENERATED ALWAYS AS ROW START NOT NULL DEFAULT SYSUTCDATETIME(),").newLine()
|
||||
.append(" ").append(systemPeriodEnd).append(" datetime2 GENERATED ALWAYS AS ROW END NOT NULL DEFAULT '9999-12-31T23:59:59.9999999',").newLine()
|
||||
.append("period for system_time (").append(systemPeriodStart).append(", ").append(systemPeriodEnd).append(")").endOfStatement();
|
||||
@@ -48,7 +48,8 @@ public class SqlServerHistoryDdl implements PlatformHistoryDdl {
|
||||
.append(historyTableWithSchema(baseTable)).append("))").endOfStatement();
|
||||
|
||||
DdlBuffer drop = writer.dropAll();
|
||||
drop.append("IF OBJECT_ID('").append(baseTable).append("', 'U') IS NOT NULL alter table ").append(baseTable).append(" set (system_versioning = off)").endOfStatement();
|
||||
drop.append("IF OBJECT_ID('").append(quote(baseTable)).append("', 'U') IS NOT NULL alter table ")
|
||||
.append(quote(baseTable)).append(" set (system_versioning = off)").endOfStatement();
|
||||
drop.append("IF OBJECT_ID('").append(historyTableName(baseTable)).append("', 'U') IS NOT NULL drop table ")
|
||||
.append(historyTableName(baseTable)).endOfStatement();
|
||||
}
|
||||
@@ -68,8 +69,8 @@ public class SqlServerHistoryDdl implements PlatformHistoryDdl {
|
||||
// switch of versioning & period - must be done before altering
|
||||
DdlBuffer apply = writer.apply();
|
||||
apply.append("-- dropping history support for ").append(baseTable).endOfStatement();
|
||||
apply.append("alter table ").append(baseTable).append(" set (system_versioning = off)").endOfStatement();
|
||||
apply.append("alter table ").append(baseTable).append(" drop period for system_time").endOfStatement();
|
||||
apply.append("alter table ").append(quote(baseTable)).append(" set (system_versioning = off)").endOfStatement();
|
||||
apply.append("alter table ").append(quote(baseTable)).append(" drop period for system_time").endOfStatement();
|
||||
apply.end();
|
||||
// now drop tables & columns, they will go to alter table/post alter buffers
|
||||
platformDdl.alterTableDropColumn(writer, baseTable, systemPeriodStart);
|
||||
@@ -90,15 +91,19 @@ public class SqlServerHistoryDdl implements PlatformHistoryDdl {
|
||||
if (!alter.isHistoryHandled()) {
|
||||
// SQL Server 2016 does not need triggers
|
||||
DdlBuffer apply = writer.apply();
|
||||
apply.append("-- alter table ").append(tableName).append(" set (system_versioning = off (history_table=")
|
||||
apply.append("-- alter table ").append(quote(tableName)).append(" set (system_versioning = off (history_table=")
|
||||
.append(historyTableWithSchema(tableName)).append("))").endOfStatement();
|
||||
apply.append("-- history migration goes here").newLine();
|
||||
apply.append("-- alter table ").append(tableName).append(" set (system_versioning = on (history_table=")
|
||||
apply.append("-- alter table ").append(quote(tableName)).append(" set (system_versioning = on (history_table=")
|
||||
.append(historyTableWithSchema(tableName)).append("))").endOfStatement();
|
||||
}
|
||||
alter.setHistoryHandled();
|
||||
}
|
||||
|
||||
protected String quote(String baseTable) {
|
||||
return platformDdl.quote(baseTable);
|
||||
}
|
||||
|
||||
protected String normalise(String tableName) {
|
||||
return constraintNaming.normaliseTable(tableName);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user