/** * Licensed to the Austrian Association for Software Tool Integration (AASTI) * under one or more contributor license agreements. See the NOTICE file * distributed with this work for additional information regarding copyright * ownership. The AASTI licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.openengsb.core.edbi.jdbc; import static org.openengsb.core.edbi.jdbc.sql.Column.Option.AUTO_INCREMENT; import java.sql.Types; import java.util.Date; import java.util.UUID; import javax.sql.DataSource; import org.openengsb.core.edbi.api.Index; import org.openengsb.core.edbi.api.IndexCommit; import org.openengsb.core.edbi.api.IndexField; import org.openengsb.core.edbi.api.NameTranslator; import org.openengsb.core.edbi.jdbc.api.TableFactory; import org.openengsb.core.edbi.jdbc.api.TypeMap; import org.openengsb.core.edbi.jdbc.names.PrependingNameTranslator; import org.openengsb.core.edbi.jdbc.names.SQLIndexFieldNameTranslator; import org.openengsb.core.edbi.jdbc.names.SQLIndexNameTranslator; import org.openengsb.core.edbi.jdbc.operation.DeleteOperation; import org.openengsb.core.edbi.jdbc.operation.InsertOperation; import org.openengsb.core.edbi.jdbc.operation.UpdateOperation; import org.openengsb.core.edbi.jdbc.sql.Column; import org.openengsb.core.edbi.jdbc.sql.PrimaryKeyConstraint; import org.openengsb.core.edbi.jdbc.sql.Table; /** * Implementation of a TableEngine, that manages the 'history' table of models. It contains a factory for creating those * tables. */ public class HistoryTableEngine extends AbstractTableEngine { public static final String TABLE_PREFIX = "HISTORY_"; private HistoryTableFactory tableFactory; public HistoryTableEngine(DataSource dataSource, TypeMap typeMap) { this(dataSource, typeMap, new PrependingNameTranslator<>(new SQLIndexNameTranslator(), TABLE_PREFIX)); } public HistoryTableEngine(DataSource dataSource, TypeMap typeMap, NameTranslator<Index<?>> indexNameTranslator) { this(dataSource, typeMap, indexNameTranslator, new SQLIndexFieldNameTranslator()); } public HistoryTableEngine(DataSource dataSource, TypeMap typeMap, NameTranslator<Index<?>> indexNameTranslator, NameTranslator<IndexField<?>> indexFieldNameTranslator) { this(dataSource, typeMap, indexNameTranslator, indexFieldNameTranslator, new HistoryTableFactory(typeMap, indexNameTranslator, indexFieldNameTranslator)); } protected HistoryTableEngine(DataSource dataSource, TypeMap typeMap, NameTranslator<Index<?>> indexNameTranslator, NameTranslator<IndexField<?>> indexFieldNameTranslator, HistoryTableFactory tableFactory) { super(dataSource, typeMap, indexNameTranslator, indexFieldNameTranslator); this.tableFactory = tableFactory; } @Override public void execute(final InsertOperation operation) { execute(operation, new CommitIndexRecordCallback(operation.getCommit(), "INSERT")); } @Override public void execute(UpdateOperation operation) { final InsertOperation insert = new InsertOperation(operation); execute(insert, new CommitIndexRecordCallback(insert.getCommit(), "UPDATE")); } @Override public void execute(DeleteOperation operation) { final InsertOperation insert = new InsertOperation(operation); execute(insert, new CommitIndexRecordCallback(insert.getCommit(), "DELETE")); } @Override protected TableFactory getTableFactory() { return tableFactory; } protected static class CommitIndexRecordCallback implements IndexRecordCallback { private final String operation; private final IndexCommit commit; public CommitIndexRecordCallback(IndexCommit commit, String operation) { this.commit = commit; this.operation = operation; } @Override public void call(IndexRecord record) { record.addValue("REV_OPERATION", operation, Types.VARCHAR); record.addValue("REV_COMMIT", commit.getCommitId(), Types.VARCHAR); record.addValue("REV_TIMESTAMP", commit.getTimestamp(), Types.TIMESTAMP); record.addValue("REV_USER", commit.getUser(), Types.VARCHAR); record.addValue("REV_CONTEXTID", commit.getContextId(), Types.VARCHAR); record.addValue("REV_DOMAINID", commit.getDomainId(), Types.VARCHAR); record.addValue("REV_CONNECTORID", commit.getConnectorId(), Types.VARCHAR); record.addValue("REV_INSTANCEID", commit.getInstanceId(), Types.VARCHAR); } } /** * A TableFactory that creates 'history' tables for models. */ public static class HistoryTableFactory extends AbstractTableFactory { public HistoryTableFactory(TypeMap typeMap, NameTranslator<Index<?>> tableNameTranslator, NameTranslator<IndexField<?>> columnNameTranslator) { super(typeMap, tableNameTranslator, columnNameTranslator); } @Override protected void onBeforeCreate(Table table, JdbcIndex<?> index) { super.onBeforeCreate(table, index); table.addElement(new Column("REV_ID", getTypeMap().getType(Long.class), AUTO_INCREMENT)); table.addElement(new Column("REV_COMMIT", getTypeMap().getType(UUID.class))); table.addElement(new Column("REV_TIMESTAMP", getTypeMap().getType(Date.class))); table.addElement(new Column("REV_OPERATION", getTypeMap().getType(String.class))); table.addElement(new Column("REV_USER", getTypeMap().getType(String.class))); table.addElement(new Column("REV_CONTEXTID", getTypeMap().getType(String.class))); table.addElement(new Column("REV_DOMAINID", getTypeMap().getType(String.class))); table.addElement(new Column("REV_CONNECTORID", getTypeMap().getType(String.class))); table.addElement(new Column("REV_INSTANCEID", getTypeMap().getType(String.class))); } @Override protected void onAfterCreate(Table table, JdbcIndex<?> index) { super.onAfterCreate(table, index); table.addElement(new PrimaryKeyConstraint("REV_ID")); index.setHistoryTableName(table.getName()); } } }