001package io.ebeaninternal.dbmigration.ddlgeneration.platform;
002
003import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
004import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
005import io.ebeaninternal.dbmigration.model.MTable;
006
007import java.io.IOException;
008
009/**
010 * NuoDB history support using DB triggers to maintain a history table.
011 */
012public class NuoDbHistoryDdl extends DbTriggerBasedHistoryDdl {
013
014  NuoDbHistoryDdl() {
015    this.now = "now()";
016    this.sysPeriodEndValue = "NEW.sys_period_start";
017  }
018
019  @Override
020  protected void dropTriggers(DdlBuffer buffer, String baseTable) throws IOException {
021
022    buffer.append("drop trigger ").append(updateTriggerName(baseTable)).endOfStatement();
023    buffer.append("drop trigger ").append(deleteTriggerName(baseTable)).endOfStatement();
024  }
025
026  @Override
027  protected void createTriggers(DdlWrite writer, MTable table) throws IOException {
028
029    DbTriggerUpdate update = createDbTriggerUpdate(writer, table);
030
031    addBeforeUpdate(updateTriggerName(update.getBaseTable()), update);
032    addBeforeDelete(deleteTriggerName(update.getBaseTable()), update);
033  }
034
035  @Override
036  protected void updateHistoryTriggers(DbTriggerUpdate update) throws IOException {
037
038    recreateHistoryView(update);
039
040    DdlBuffer buffer = update.historyTriggerBuffer();
041    String baseTable = update.getBaseTable();
042
043    dropTriggers(buffer, baseTable);
044    addBeforeUpdate(updateTriggerName(baseTable), update);
045    addBeforeDelete(deleteTriggerName(baseTable), update);
046  }
047
048  private void addBeforeUpdate(String triggerName, DbTriggerUpdate update) throws IOException {
049
050    DdlBuffer apply = update.historyTriggerBuffer();
051    addTriggerStart(triggerName, update, apply, " before update for each row as ");
052    apply.append("    NEW.sys_period_start = greatest(current_timestamp, date_add(OLD.sys_period_start, interval 1 microsecond))").endOfStatement();
053    appendInsertIntoHistory(apply, update.getHistoryTable(), update.getColumns());
054    addEndTrigger(apply);
055  }
056
057  private void addBeforeDelete(String triggerName, DbTriggerUpdate update) throws IOException {
058
059    DdlBuffer apply = update.historyTriggerBuffer();
060    addTriggerStart(triggerName, update, apply, " before delete for each row as");
061    appendInsertIntoHistory(apply, update.getHistoryTable(), update.getColumns());
062    addEndTrigger(apply);
063  }
064
065  private void addTriggerStart(String triggerName, DbTriggerUpdate update, DdlBuffer apply, String s) throws IOException {
066    apply
067      .append("delimiter $$").newLine()
068      .append("create or replace trigger ").append(triggerName).append(" for ").append(update.getBaseTable())
069      .append(s).newLine();
070  }
071
072  private void addEndTrigger(DdlBuffer apply) throws IOException {
073    apply.append("end_trigger")
074      .endOfStatement()
075      .append("$$").newLine()
076      .newLine();
077  }
078
079}