All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.ebeaninternal.dbmigration.ddlgeneration.platform.PlatformDdl Maven / Gradle / Ivy

There is a newer version: 15.8.0
Show newest version
package io.ebeaninternal.dbmigration.ddlgeneration.platform;

import io.ebean.annotation.ConstraintMode;
import io.ebean.annotation.Platform;
import io.ebean.DatabaseBuilder;
import io.ebean.config.DbConstraintNaming;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.config.dbplatform.DbDefaultValue;
import io.ebean.config.dbplatform.DbIdentity;
import io.ebean.config.dbplatform.IdType;
import io.ebean.util.StringHelper;
import io.ebeaninternal.dbmigration.ddlgeneration.*;
import io.ebeaninternal.dbmigration.ddlgeneration.platform.util.PlatformTypeConverter;
import io.ebeaninternal.dbmigration.ddlgeneration.platform.util.VowelRemover;
import io.ebeaninternal.dbmigration.migration.*;
import io.ebeaninternal.dbmigration.model.MTable;

import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Controls the DDL generation for a specific database platform.
 */
public class PlatformDdl {

  // matches on pattern "check ( COLUMNAME ... )". ColumnName is match group 2;
  private static final Pattern CHECK_PATTERN = Pattern.compile("(.*?\\( *)([^ ]+)(.*)");

  protected final DatabasePlatform platform;
  protected PlatformHistoryDdl historyDdl = new NoHistorySupportDdl();
  /**
   * Converter for logical/standard types to platform specific types. (eg. clob -> text)
   */
  private final PlatformTypeConverter typeConverter;
  /**
   * For handling support of sequences and autoincrement.
   */
  private final DbIdentity dbIdentity;
  /**
   * Set to true if table and column comments are included inline with the create statements.
   */
  protected boolean inlineComments;
  /**
   * Default assumes if exists is supported.
   */
  protected String dropTableIfExists = "drop table if exists ";
  protected String dropTableCascade = "";
  /**
   * Default assumes if exists is supported.
   */
  protected String dropSequenceIfExists = "drop sequence if exists ";
  protected String foreignKeyOnDelete = "on delete";
  protected String foreignKeyOnUpdate = "on update";
  protected String identitySuffix = " auto_increment";
  protected String identityStartWith = "start with";
  protected String identityIncrementBy = "increment by";
  protected String identityCache = "cache";
  protected String sequenceStartWith = "start with";
  protected String sequenceIncrementBy = "increment by";
  protected String sequenceCache = "cache";
  protected String alterTableIfExists = "";
  protected String dropConstraintIfExists = "drop constraint if exists";
  protected String dropIndexIfExists = "drop index if exists ";
  protected String alterColumn = "alter column";
  protected String dropUniqueConstraint = "drop constraint";
  protected String addConstraint = "add constraint";
  protected String addColumn = "add column";
  protected String columnSetType = "";
  protected String columnSetDefault = "set default";
  protected String columnDropDefault = "drop default";
  protected String columnSetNotnull = "set not null";
  protected String columnSetNull = "set null";
  protected String columnNotNull = "not null";
  protected String updateNullWithDefault = "update ${table} set ${column} = ${default} where ${column} is null";
  protected boolean createSchemaSupport;
  protected String createSchema = "create schema if not exists";
  protected String createTable = "create table";
  protected String dropColumn = "drop column";
  protected String addForeignKeySkipCheck = "";
  protected String uniqueIndex = "unique";
  protected String indexConcurrent = "";
  protected String createIndexIfNotExists = "";
  /**
   * Set false for MsSqlServer to allow multiple nulls for OneToOne mapping.
   */
  protected boolean inlineUniqueWhenNullable = true;
  protected DbConstraintNaming naming;
  /**
   * Generally not desired as then they are not named (used with SQLite).
   */
  protected boolean inlineForeignKeys;
  protected boolean includeStorageEngine;
  protected final DbDefaultValue dbDefaultValue;
  protected String fallbackArrayType = "varchar(1000)";

  public PlatformDdl(DatabasePlatform platform) {
    this.platform = platform;
    this.dbIdentity = platform.dbIdentity();
    this.dbDefaultValue = platform.dbDefaultValue();
    this.typeConverter = new PlatformTypeConverter(platform.dbTypeMap());
  }

  /**
   * Set configuration options.
   */
  public void configure(DatabaseBuilder.Settings config) {
    historyDdl.configure(config, this);
    naming = config.getConstraintNaming();
  }

  /**
   * Create a DdlHandler for the specific database platform.
   */
  public DdlHandler createDdlHandler(DatabaseBuilder.Settings config) {
    return new BaseDdlHandler(config, this);
  }

  /**
   * Return the identity type to use given the support in the underlying database
   * platform for sequences and identity/autoincrement.
   */
  public IdType useIdentityType(IdType modelIdentity) {
    if (modelIdentity == null) {
      // use the default
      return dbIdentity.getIdType();
    }
    return identityType(modelIdentity, dbIdentity.getIdType(), dbIdentity.isSupportsSequence(), dbIdentity.isSupportsIdentity());
  }

  /**
   * Determine the id type to use based on requested identityType and
   * the support for that in the database platform.
   */
  private IdType identityType(IdType modelIdentity, IdType platformIdType, boolean supportsSequence, boolean supportsIdentity) {
    switch (modelIdentity) {
      case GENERATOR:
        return IdType.GENERATOR;
      case EXTERNAL:
        return IdType.EXTERNAL;
      case SEQUENCE:
        return supportsSequence ? IdType.SEQUENCE : platformIdType;
      case IDENTITY:
        return supportsIdentity ? IdType.IDENTITY : platformIdType;
      default:
        return platformIdType;
    }
  }

  /**
   * Modify and return the column definition for autoincrement or identity definition.
   */
  public String asIdentityColumn(String columnDefn, DdlIdentity identity) {
    return columnDefn + identitySuffix;
  }

  /**
   * SQl2003 standard identity definition.
   */
  protected String asIdentityStandardOptions(String columnDefn, DdlIdentity identity) {
    StringBuilder sb = new StringBuilder(columnDefn.length() + 60);
    sb.append(columnDefn).append(identity.optionGenerated());
    sb.append(identity.identityOptions(identityStartWith, identityIncrementBy, identityCache));
    return sb.toString();
  }

  /**
   * Return true if the table and column comments are included inline.
   */
  public boolean isInlineComments() {
    return inlineComments;
  }

  /**
   * Return true if the platform includes storage engine clause.
   */
  public boolean isIncludeStorageEngine() {
    return includeStorageEngine;
  }

  /**
   * Return true if foreign key reference constraints need to inlined with create table.
   * Ideally we don't do this as then the constraints are not named. Do this for SQLite.
   */
  public boolean isInlineForeignKeys() {
    return inlineForeignKeys;
  }

  /**
   * By default this does nothing returning null / no lock timeout.
   */
  public String setLockTimeout(int lockTimeoutSeconds) {
    return null;
  }

  /**
   * Write all the table columns converting to platform types as necessary.
   */
  public void writeTableColumns(DdlBuffer apply, List columns, DdlIdentity identity) {
    if ("true".equalsIgnoreCase(System.getProperty("ebean.ddl.sortColumns", "true"))) {
      columns = sortColumns(columns);
    }
    for (int i = 0; i < columns.size(); i++) {
      if (i > 0) {
        apply.append(",");
      }
      apply.newLine();
      writeColumnDefinition(apply, columns.get(i), identity);
    }

    for (Column column : columns) {
      String checkConstraint = column.getCheckConstraint();
      if (hasValue(checkConstraint)) {
        checkConstraint = createCheckConstraint(maxConstraintName(column.getCheckConstraintName()), checkConstraint);
        if (hasValue(checkConstraint)) {
          apply.append(",").newLine();
          apply.append(checkConstraint);
        }
      }
    }
  }

  protected List sortColumns(List columns) {
    // do nothing by default
    return columns;
  }

  /**
   * Write the column definition to the create table statement.
   */
  protected void writeColumnDefinition(DdlBuffer buffer, Column column, DdlIdentity identity) {
    String columnDefn = convert(column.getType());
    if (identity.useIdentity() && isTrue(column.isPrimaryKey())) {
      columnDefn = asIdentityColumn(columnDefn, identity);
    }

    buffer.append("  ");
    buffer.append(quote(column.getName()), 29);
    buffer.append(columnDefn);
    if (!Boolean.TRUE.equals(column.isPrimaryKey())) {
      String defaultValue = convertDefaultValue(column.getDefaultValue());
      if (defaultValue != null) {
        buffer.append(" default ").append(defaultValue);
      }
    }
    if (isTrue(column.isNotnull()) || isTrue(column.isPrimaryKey())) {
      buffer.appendWithSpace(columnNotNull);
    }
    // add check constraints later as we really want to give them a nice name
    // so that the database can potentially provide a nice SQL error
  }

  /**
   * Returns the check constraint.
   */
  public String createCheckConstraint(String ckName, String checkConstraint) {
    return "  constraint " + maxConstraintName(ckName) + " " + quoteCheckConstraint(checkConstraint);
  }

  /**
   * Convert the DB column default literal to platform specific.
   */
  public String convertDefaultValue(String dbDefault) {
    return dbDefaultValue.convert(dbDefault);
  }

  /**
   * Return the drop foreign key clause.
   */
  public String alterTableDropForeignKey(String tableName, String fkName) {
    return "alter table " + alterTableIfExists + quote(tableName) + " " + dropConstraintIfExists + " " + maxConstraintName(fkName);
  }

  /**
   * Convert the standard type to the platform specific type.
   */
  public String convert(String type) {
    if (type == null) {
      return null;
    }
    String[] tmp = type.split(";", -1); // do not discard trailing empty strings
    int index = extract(tmp);
    if (index < tmp.length - 1) {
      // this is a platform specific definition. So do not apply further conversions
      return tmp[index];
    }
    type = tmp[index];
    if (type.contains("[]")) {
      return convertArrayType(type);
    }
    return typeConverter.convert(type);
  }

  // if columnType is different for different platforms, use pattern
  // @Column(columnDefinition = PLATFORM1;DEFINITION1;PLATFORM2;DEFINITON2;DEFINITON-DEFAULT)
  // e.g. @Column(columnDefinition = "db2;blob(64M);sqlserver,h2;varchar(227);varchar(127)")
  protected String extract(String type) {
    if (type == null) {
      return null;
    }
    String[] tmp = type.split(";", -1); // do not discard trailing empty strings
    return tmp[extract(tmp)]; // else
  }

  protected int extract(String[] types) {
    if (types.length % 2 == 0) {
      throw new IllegalArgumentException("You need an odd number of arguments in '" + String.join(";", types) + "'. See Issue #2559 for details");
    }
    for (int i = 0; i < types.length - 2; i += 2) {
      String[] platforms = types[i].split(",");
      for (String plat : platforms) {
        if (platform.isPlatform(Platform.valueOf(plat.toUpperCase(Locale.ENGLISH)))) {
          return i + 1;
        }
      }
    }
    return types.length - 1; // else
  }

  /**
   * Convert the logical array type to a db platform specific type to support the array data.
   */
  protected String convertArrayType(String logicalArrayType) {
    if (logicalArrayType.endsWith("]")) {
      return fallbackArrayType;
    }
    int colonPos = logicalArrayType.lastIndexOf(']');
    return "varchar" + logicalArrayType.substring(colonPos + 1);
  }

  /**
   * Add history support to this table using the platform specific mechanism.
   */
  public void createWithHistory(DdlWrite writer, MTable table) {
    historyDdl.createWithHistory(writer, table);
  }

  /**
   * Drop history support for a given table.
   */
  public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) {
    historyDdl.dropHistoryTable(writer, dropHistoryTable);
  }

  /**
   * Add history support to an existing table.
   */
  public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) {
    historyDdl.addHistoryTable(writer, addHistoryTable);
  }

  /**
   * Regenerate the history triggers (or function) due to a column being added/dropped/excluded or included.
   */
  public void regenerateHistoryTriggers(DdlWrite writer, String tableName) {
    historyDdl.updateTriggers(writer, tableName);
  }

  /**
   * Generate and return the create sequence DDL.
   */
  public String createSequence(String sequenceName, DdlIdentity identity) {
    StringBuilder sb = new StringBuilder("create sequence ");
    sb.append(quote(sequenceName));
    sb.append(identity.sequenceOptions(sequenceStartWith, sequenceIncrementBy, sequenceCache));
    sb.append(';');
    return sb.toString();
  }

  /**
   * Return the drop sequence statement (potentially with if exists clause).
   */
  public String dropSequence(String sequenceName) {
    return dropSequenceIfExists + quote(sequenceName);
  }

  /**
   * Return the drop table statement (potentially with if exists clause).
   */
  public String dropTable(String tableName) {
    return dropTableIfExists + quote(tableName) + dropTableCascade;
  }

  /**
   * Return the drop index statement for known non concurrent index.
   */
  public String dropIndex(String indexName, String tableName) {
    return dropIndex(indexName, tableName, false);
  }

  /**
   * Return the drop index statement.
   */
  public String dropIndex(String indexName, String tableName, boolean concurrent) {
    return dropIndexIfExists + maxConstraintName(indexName);
  }

  public String createIndex(WriteCreateIndex create) {
    if (create.useDefinition()) {
      return create.getDefinition();
    }
    StringBuilder buffer = new StringBuilder();
    buffer.append("create ");
    if (create.isUnique()) {
      buffer.append(uniqueIndex).append(" ");
    }
    buffer.append("index ");
    if (create.isConcurrent()) {
      buffer.append(indexConcurrent);
    }
    if (create.isNotExistsCheck()) {
      buffer.append(createIndexIfNotExists);
    }
    buffer.append(maxConstraintName(create.getIndexName())).append(" on ").append(quote(create.getTableName()));
    appendColumns(create.getColumns(), buffer);
    return buffer.toString();
  }

  /**
   * Return the foreign key constraint when used inline with create table.
   */
  public String tableInlineForeignKey(WriteForeignKey request) {
    StringBuilder buffer = new StringBuilder(90);
    buffer.append("foreign key");
    appendColumns(request.cols(), buffer);
    buffer.append(" references ").append(quote(request.refTable()));
    appendColumns(request.refCols(), buffer);
    appendForeignKeySuffix(request, buffer);
    return buffer.toString();
  }

  /**
   * Add foreign key.
   */
  public String alterTableAddForeignKey(DdlOptions options, WriteForeignKey request) {
    StringBuilder buffer = new StringBuilder(90);
    buffer
      .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(quote(request.refTable()));
    appendColumns(request.refCols(), buffer);
    appendForeignKeySuffix(request, buffer);
    if (options.isForeignKeySkipCheck()) {
      buffer.append(addForeignKeySkipCheck);
    }
    return buffer.toString();
  }

  protected void appendForeignKeySuffix(WriteForeignKey request, StringBuilder buffer) {
    appendForeignKeyOnDelete(buffer, withDefault(request.onDelete()));
    appendForeignKeyOnUpdate(buffer, withDefault(request.onUpdate()));
  }

  protected ConstraintMode withDefault(ConstraintMode mode) {
    return (mode == null) ? ConstraintMode.RESTRICT : mode;
  }

  protected void appendForeignKeyOnDelete(StringBuilder buffer, ConstraintMode mode) {
    appendForeignKeyMode(buffer, foreignKeyOnDelete, mode);
  }

  protected void appendForeignKeyOnUpdate(StringBuilder buffer, ConstraintMode mode) {
    appendForeignKeyMode(buffer, foreignKeyOnUpdate, mode);
  }

  protected void appendForeignKeyMode(StringBuilder buffer, String onMode, ConstraintMode mode) {
    buffer.append(" ").append(onMode).append(" ").append(translate(mode));
  }

  protected String translate(ConstraintMode mode) {
    switch (mode) {
      case SET_NULL:
        return "set null";
      case SET_DEFAULT:
        return "set default";
      case RESTRICT:
        return "restrict";
      case CASCADE:
        return "cascade";
      default:
        throw new IllegalStateException("Unknown mode " + mode);
    }
  }

  /**
   * Drop a unique constraint from the table (Sometimes this is an index).
   */
  public String alterTableDropUniqueConstraint(String tableName, String 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 " + quote(tableName) + " " + dropConstraintIfExists + " " + maxConstraintName(constraintName);
  }

  /**
   * Add a unique constraint to the table.
   * 

* Overridden by MsSqlServer for specific null handling on unique constraints. */ public String alterTableAddUniqueConstraint(String tableName, String uqName, String[] columns, String[] nullableColumns) { StringBuilder buffer = new StringBuilder(90); buffer.append("alter table ").append(quote(tableName)).append(" add constraint ").append(maxConstraintName(uqName)).append(" unique "); appendColumns(columns, buffer); return buffer.toString(); } public void alterTableAddColumn(DdlWrite writer, String tableName, Column column, boolean onHistoryTable, String defaultValue) { String convertedType = convert(column.getType()); DdlBuffer buffer = alterTable(writer, tableName).append(addColumn, column.getName()); buffer.append(convertedType); // Add default value also to history table if it is not excluded if (defaultValue != null) { if (!onHistoryTable || !isTrue(column.isHistoryExclude())) { buffer.append(" default "); buffer.append(defaultValue); } } if (!onHistoryTable) { if (isTrue(column.isNotnull())) { buffer.appendWithSpace(columnNotNull); } // check constraints cannot be added in one statement for h2 if (!StringHelper.isNull(column.getCheckConstraint())) { String ddl = alterTableAddCheckConstraint(tableName, column.getCheckConstraintName(), column.getCheckConstraint()); writer.applyPostAlter().appendStatement(ddl); } } } /** * This method is used from DbTriggerBasedHistoryDdl to add the sysPeriodColumns. */ public void alterTableAddColumn(DdlWrite writer, String tableName, String columnName, String columnType, String defaultValue) { String convertedType = convert(columnType); DdlBuffer buffer = alterTable(writer, tableName).append(addColumn, columnName); buffer.append(convertedType); if (defaultValue != null) { buffer.append(" default "); buffer.append(defaultValue); } } public void alterTableDropColumn(DdlWrite writer, String tableName, String columnName) { alterTable(writer, tableName).append(dropColumn, columnName); } /** * Return true if unique constraints for nullable columns can be inlined as normal. * Returns false for MsSqlServer and DB2 due to it's not possible to to put a constraint * on a nullable column */ public boolean isInlineUniqueWhenNullable() { return inlineUniqueWhenNullable; } /** * Alter a column type. *

* Note that that MySql, SQL Server, and HANA instead use alterColumn() *

*/ protected void alterColumnType(DdlWrite writer, AlterColumn alter) { alterTable(writer, alter.getTableName()).append(alterColumn, alter.getColumnName()) .append(columnSetType).append(convert(alter.getType())); } /** * Alter a column adding or removing the not null constraint. *

* Note that that MySql, SQL Server, and HANA instead use alterColumn() *

*/ protected void alterColumnNotnull(DdlWrite writer, AlterColumn alter) { DdlBuffer buffer = alterTable(writer, alter.getTableName()).append(alterColumn, alter.getColumnName()); if (Boolean.TRUE.equals(alter.isNotnull())) { buffer.append(columnSetNotnull); } else { buffer.append(columnSetNull); } } /** * Alter table adding the check constraint. */ public String alterTableAddCheckConstraint(String tableName, String checkConstraintName, String checkConstraint) { return "alter table " + quote(tableName) + " " + addConstraint + " " + maxConstraintName(checkConstraintName) + " " + quoteCheckConstraint(checkConstraint); } /** * Alter column setting the default value. *

* Note that that MySql, SQL Server, and HANA instead use alterColumn() *

*/ protected void alterColumnDefault(DdlWrite writer, AlterColumn alter) { DdlBuffer buffer = alterTable(writer, alter.getTableName()).append(alterColumn, alter.getColumnName()); if (DdlHelp.isDropDefault(alter.getDefaultValue())) { buffer.append(columnDropDefault); } else { buffer.append(columnSetDefault).appendWithSpace(convertDefaultValue(alter.getDefaultValue())); } } /** * Alter column setting (type, default value and not null constraint). *

* Used by MySql, SQL Server, and HANA as these require all column attributes to * be set together. */ public void alterColumn(DdlWrite writer, AlterColumn alter) { if (hasValue(alter.getType())) { alterColumnType(writer, alter); } if (hasValue(alter.getDefaultValue())) { alterColumnDefault(writer, alter); } if (alter.isNotnull() != null) { alterColumnNotnull(writer, alter); } } /** * Creates or replace a new DdlAlterTable for given tableName. */ protected DdlAlterTable alterTable(DdlWrite writer, String tableName) { return writer.applyAlterTable(tableName, k -> new BaseAlterTableWrite(k, this)); } protected void appendColumns(String[] columns, StringBuilder buffer) { buffer.append(" ("); for (int i = 0; i < columns.length; i++) { if (i > 0) { buffer.append(","); } buffer.append(quote(columns[i].trim())); } buffer.append(")"); } public DatabasePlatform getPlatform() { return platform; } public String getUpdateNullWithDefault() { return updateNullWithDefault; } /** * Return true if null or trimmed string is empty. */ protected boolean hasValue(String value) { return value != null && !value.trim().isEmpty(); } /** * Null safe Boolean true test. */ protected boolean isTrue(Boolean value) { return Boolean.TRUE.equals(value); } /** * Add an inline table comment to the create table statement. */ public void inlineTableComment(DdlBuffer apply, String tableComment) { // do nothing by default (MySql only) } /** * Add an table storage engine to the create table statement. */ public void tableStorageEngine(DdlBuffer apply, String storageEngine) { // do nothing by default } /** * Add table comment as a separate statement (from the create table statement). */ public void addTableComment(DdlBuffer apply, String tableName, String tableComment) { if (DdlHelp.isDropComment(tableComment)) { tableComment = ""; } apply.append(String.format("comment on table %s is '%s'", quote(tableName), tableComment)).endOfStatement(); } /** * Add column comment as a separate statement. */ public void addColumnComment(DdlBuffer apply, String table, String column, String comment) { if (DdlHelp.isDropComment(comment)) { comment = ""; } apply.append(String.format("comment on column %s.%s is '%s'", quote(table), quote(column), comment)).endOfStatement(); } /** * Use this to generate a prolog for each script (stored procedures) */ public void generateProlog(DdlWrite writer) { // do nothing by default } /** * Use this to generate an epilog. Will be added at the end of script */ public void generateEpilog(DdlWrite writer) { // do nothing by default } /** * Shortens the given name to the maximum constraint name length of the platform in a deterministic way. *

* First, all vowels are removed, If the string is still to long, 31 bits are taken from the hash code * of the string and base36 encoded (10 digits and 26 chars) string. *

* As 36^6 > 31^2, the resulting string is never longer as 6 chars. */ protected String maxConstraintName(String name) { if (name.length() > platform.maxConstraintNameLength()) { int hash = name.hashCode() & 0x7FFFFFFF; name = VowelRemover.trim(name, 4); if (name.length() > platform.maxConstraintNameLength()) { return name.substring(0, platform.maxConstraintNameLength() - 7) + "_" + Integer.toString(hash, 36); } } return name; } /** * Returns the database-specific "create table" command prefix. For HANA this is * either "create column table" or "create row table", for all other databases * it is "create table". * * @return The "create table" command prefix */ public String getCreateTableCommandPrefix() { return createTable; } public void addTablePartition(DdlBuffer apply, String partitionMode, String partitionColumn) { // only supported by postgres and yugabyte } public void addDefaultTablePartition(DdlBuffer apply, String tableName) { // only supported by postgres and yugabyte } /** * Adds tablespace declaration. Now only supported for db2. */ public void addTablespace(DdlBuffer apply, String tablespaceName, String indexTablespace, String lobTablespace) { throw new UnsupportedOperationException("Tablespaces are not supported for this platform"); } /** * Moves the table to an other tablespace. */ public String alterTableTablespace(String tablename, String tableSpace, String indexSpace, String lobSpace) { if (tableSpace != null || indexSpace != null || lobSpace != null) { throw new UnsupportedOperationException("Tablespaces are not supported for this platform"); } return null; } protected String quote(String dbName) { return platform.convertQuotedIdentifiers(dbName); } protected String quoteCheckConstraint(String checkConstraint) { Matcher matcher = CHECK_PATTERN.matcher(checkConstraint); if (matcher.matches()) { return matcher.replaceFirst("$1" + quote(matcher.group(2)) + "$3"); } return checkConstraint; } public void createSchema(DdlWrite writer, CreateSchema request) { DdlBuffer apply = writer.apply(); if (!createSchemaSupport) { apply.append("-- "); } apply.append(createSchema).append(" ").append(quote(request.getName())).endOfStatement(); } /** * Override to return true for Postgres / platforms that want the partition column to be * part of the primary key when using table partitioning. */ public boolean addPartitionColumnToPrimaryKey() { return false; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy