001package io.ebeaninternal.dbmigration.ddlgeneration.platform; 002 003import io.ebean.config.DatabaseConfig; 004import io.ebeaninternal.dbmigration.ddlgeneration.DdlAlterTable; 005import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer; 006import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite; 007import io.ebeaninternal.dbmigration.migration.AddHistoryTable; 008import io.ebeaninternal.dbmigration.migration.DropHistoryTable; 009import io.ebeaninternal.dbmigration.model.MColumn; 010import io.ebeaninternal.dbmigration.model.MTable; 011 012import java.util.Collection; 013 014public class HanaHistoryDdl extends DbTableBasedHistoryDdl implements PlatformHistoryDdl { 015 016 private String systemPeriodStart; 017 private String systemPeriodEnd; 018 019 @Override 020 public void configure(DatabaseConfig config, PlatformDdl platformDdl) { 021 super.configure(config, platformDdl); 022 this.systemPeriodStart = config.getAsOfSysPeriod() + "_start"; 023 this.systemPeriodEnd = config.getAsOfSysPeriod() + "_end"; 024 } 025 026 @Override 027 public void createWithHistory(DdlWrite writer, MTable table) { 028 String tableName = table.getName(); 029 String historyTableName = historyTableName(tableName); 030 DdlBuffer apply = writer.applyPostAlter(); 031 032 apply.append(platformDdl.getCreateTableCommandPrefix()).append(" ").append(historyTableName).append(" (").newLine(); 033 034 // create history table 035 Collection<MColumn> cols = table.allColumns(); 036 for (MColumn column : cols) { 037 if (!column.isDraftOnly()) { 038 writeColumnDefinition(apply, column.getName(), column.getType(), column.getDefaultValue(), column.isNotnull(), 039 column.isIdentity() ? platformDdl.identitySuffix : null); 040 apply.append(",").newLine(); 041 } 042 } 043 writeColumnDefinition(apply, systemPeriodStart, "TIMESTAMP", null, false, null); 044 apply.append(",").newLine(); 045 writeColumnDefinition(apply, systemPeriodEnd, "TIMESTAMP", null, false, null); 046 apply.newLine().append(")").endOfStatement(); 047 048 // enable system versioning 049 apply.append("alter table ").append(tableName).append(" add (").newLine(); 050 apply.append(" ").append(systemPeriodStart).append(" TIMESTAMP NOT NULL GENERATED ALWAYS AS ROW START, ").newLine(); 051 apply.append(" ").append(systemPeriodEnd).append(" TIMESTAMP NOT NULL GENERATED ALWAYS AS ROW END").newLine(); 052 apply.append(")").endOfStatement(); 053 054 apply.append("alter table ").append(tableName).append(" add period for system_time(").append(systemPeriodStart) 055 .append(",").append(systemPeriodEnd).append(")").endOfStatement(); 056 057 enableSystemVersioning(apply, tableName, true); 058 platformDdl.alterTable(writer, tableName).setHistoryHandled(); 059 060 dropHistoryTable(writer.dropAll(), tableName, historyTableName); 061 } 062 063 @Override 064 public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) { 065 dropHistoryTable(writer.applyDropDependencies(), dropHistoryTable.getBaseTable(), 066 historyTableName(dropHistoryTable.getBaseTable())); 067 } 068 069 protected void dropHistoryTable(DdlBuffer apply, String baseTable, String historyTable) { 070 // disable system versioning 071 disableSystemVersioning(apply, baseTable); 072 073 apply.append("alter table ").append(baseTable).append(" drop period for system_time").endOfStatement(); 074 075 // drop the period columns 076 apply.append("alter table ").append(baseTable).append(" drop (").append(systemPeriodStart).append(",") 077 .append(systemPeriodEnd).append(")").endOfStatement(); 078 079 // drop the history table 080 apply.append("drop table ").append(historyTable).append(" cascade").endOfStatement(); 081 } 082 083 @Override 084 public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) { 085 MTable table = writer.getTable(addHistoryTable.getBaseTable()); 086 if (table == null) { 087 throw new IllegalStateException("MTable " + addHistoryTable.getBaseTable() + " not found in writer? (required for history DDL)"); 088 } 089 createWithHistory(writer, table); 090 } 091 092 @Override 093 public void updateTriggers(DdlWrite writer, String tableName) { 094 DdlAlterTable alter = platformDdl.alterTable(writer, tableName); 095 MTable table = writer.getTable(tableName); 096 if (table.isWithHistory() && !alter.isHistoryHandled()) { 097 disableSystemVersioning(writer.apply(), tableName); 098 enableSystemVersioning(writer.applyPostAlter(), tableName, false); 099 alter.setHistoryHandled(); 100 } 101 } 102 103 protected void writeColumnDefinition(DdlBuffer buffer, String columnName, String type, String defaultValue, 104 boolean isNotNull, String generated) { 105 106 String platformType = platformDdl.convert(type); 107 buffer.append(" ").append(columnName); 108 buffer.append(" ").append(platformType); 109 if (defaultValue != null) { 110 buffer.append(" default ").append(defaultValue); 111 } 112 if (isNotNull) { 113 buffer.append(" not null"); 114 } 115 if (generated != null) { 116 buffer.append(" ").append(generated); 117 } 118 } 119 120 public void disableSystemVersioning(DdlBuffer apply, String tableName) { 121 apply.append("alter table ").append(tableName).append(" drop system versioning").endOfStatement(); 122 } 123 124 public void enableSystemVersioning(DdlBuffer apply, String tableName, boolean validated) { 125 apply.append("alter table ").append(tableName).append(" add system versioning history table ").append(historyTableName(tableName)); 126 if (!validated) { 127 apply.append(" not validated"); 128 } 129 apply.endOfStatement(); 130 } 131 132 133}