org.teiid.spring.views.EntityBaseView Maven / Gradle / Ivy
/*
* Copyright 2012-2017 the original author or authors.
*
* Licensed 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.teiid.spring.views;
import javax.persistence.Entity;
import org.hibernate.boot.Metadata;
import org.springframework.context.ApplicationContext;
import org.teiid.adminapi.Model;
import org.teiid.adminapi.impl.VDBMetaData;
import org.teiid.metadata.Column;
import org.teiid.metadata.KeyRecord;
import org.teiid.metadata.MetadataFactory;
import org.teiid.metadata.Schema;
import org.teiid.metadata.Table;
import org.teiid.spring.autoconfigure.RedirectionSchemaBuilder;
import org.teiid.spring.autoconfigure.TeiidServer;
/**
* This view generates a base layer view for any source table.
*/
public class EntityBaseView extends ViewBuilder {
private VDBMetaData vdb;
private TeiidServer server;
public EntityBaseView(Metadata metadata, VDBMetaData vdb, TeiidServer server) {
super(metadata);
this.vdb = vdb;
this.server = server;
}
@Override
void onFinish(Table view, MetadataFactory mf, Class entityClazz, Entity annotation, ApplicationContext context) {
String sourceName = findSourceWhereEntityExists(view.getName());
if (sourceName == null) {
throw new IllegalStateException(
view.getName() + " not found in any datasource configured. " + "Failed to create view.");
}
view.setSelectTransformation(buildSelectPlan(view, sourceName));
// view.setInsertPlan(buildInsertPlan(view, sourceName));
// view.setUpdatePlan(buildUpdatePlan(view, sourceName));
// view.setDeletePlan(buildDeletePlan(view, sourceName));
}
public static String buildDeletePlan(Table view, String sourceName) {
StringBuilder sb = new StringBuilder();
sb.append("FOR EACH ROW\n");
sb.append("BEGIN ATOMIC\n");
sb.append("DELETE FROM ").append(sourceName).append(".").append(view.getName());
sb.append(" WHERE ");
KeyRecord pk = RedirectionSchemaBuilder.getPK(view);
for (int i = 0; i < pk.getColumns().size(); i++) {
Column c = pk.getColumns().get(i);
if (i > 0) {
sb.append(" AND ");
}
sb.append(c.getName()).append(" = ").append("OLD.").append(c.getName());
}
sb.append(";\n");
sb.append("END");
return sb.toString();
}
public static String buildUpdatePlan(Table view, String sourceName) {
StringBuilder sb = new StringBuilder();
sb.append("FOR EACH ROW\n");
sb.append("BEGIN ATOMIC\n");
sb.append("UPDATE ").append(sourceName).append(".").append(view.getName()).append(" SET ");
for (int i = 0; i < view.getColumns().size(); i++) {
Column c = view.getColumns().get(i);
if (i > 0) {
sb.append(", ");
}
sb.append(c.getName()).append(" = ").append("NEW.").append(c.getName());
}
KeyRecord pk = RedirectionSchemaBuilder.getPK(view);
sb.append(" WHERE ");
for (int i = 0; i < pk.getColumns().size(); i++) {
Column c = pk.getColumns().get(i);
if (i > 0) {
sb.append(" AND ");
}
sb.append(c.getName()).append(" = ").append("OLD.").append(c.getName());
}
sb.append(";\n");
sb.append("END");
return sb.toString();
}
public static String buildInsertPlan(Table view, String sourceName) {
StringBuilder sb = new StringBuilder();
sb.append("FOR EACH ROW\n");
sb.append("BEGIN ATOMIC\n");
sb.append("INSERT INTO ").append(sourceName).append(".").append(view.getName()).append("( ");
appendColumnNames(view, sb, null);
sb.append(") VALUES ( ");
appendColumnNames(view, sb, "NEW");
sb.append(");\n");
sb.append("END");
return sb.toString();
}
public static String buildSelectPlan(Table view, String sourceName) {
StringBuilder sb = new StringBuilder();
sb.append("SELECT ");
appendColumnNames(view, sb, null);
sb.append("FROM ").append(sourceName).append(".").append(view.getName());
return sb.toString();
}
private String findSourceWhereEntityExists(String tableName) {
String foundIn = null;
boolean found = false;
for (Model model : vdb.getModels()) {
Schema s = this.server.getSchema(vdb, model.getName());
Table table = s.getTable(tableName);
if (table != null) {
if (!found) {
foundIn = model.getName();
found = true;
} else {
throw new IllegalStateException(tableName + " table found in more than single data source, failed "
+ "to create view due to ambiguity. You can define @SelectQuery on the Entity class "
+ "with transformation to fix the issue.");
}
}
}
return foundIn;
}
private static void appendColumnNames(Table srcTable, StringBuilder sb, String alias) {
boolean first = true;
for (Column srcColumn : srcTable.getColumns()) {
if (!first) {
sb.append(", ");
} else {
first = false;
}
if (alias != null) {
sb.append(alias).append(".");
}
sb.append(srcColumn.getName());
}
sb.append(" ");
}
}