
org.nuiton.topia.service.sql.TopiaEntitySqlModelResource Maven / Gradle / Ivy
The newest version!
package org.nuiton.topia.service.sql;
/*-
* #%L
* ToPIA Extension :: API
* %%
* Copyright (C) 2018 - 2022 Ultreia.io
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* .
* #L%
*/
import org.nuiton.topia.service.sql.blob.TopiaEntitySqlBlobModel;
import org.nuiton.topia.service.sql.internal.SqlRequestSet;
import org.nuiton.topia.service.sql.metadata.TopiaMetadataModel;
import org.nuiton.topia.service.sql.metadata.TopiaMetadataModelPaths;
import org.nuiton.topia.service.sql.model.TopiaEntitySqlModel;
import org.nuiton.topia.service.sql.model.TopiaEntitySqlSelectArgument;
import org.nuiton.topia.service.sql.plan.copy.TopiaEntitySqlCopyPlan;
import org.nuiton.topia.service.sql.plan.copy.TopiaEntitySqlCopyPlanModel;
import org.nuiton.topia.service.sql.plan.copy.TopiaEntitySqlCopyPlanTask;
import org.nuiton.topia.service.sql.plan.delete.TopiaEntitySqlDeletePlan;
import org.nuiton.topia.service.sql.plan.delete.TopiaEntitySqlDeletePlanModel;
import org.nuiton.topia.service.sql.plan.replicate.TopiaEntitySqlReplicatePartialPlan;
import org.nuiton.topia.service.sql.plan.replicate.TopiaEntitySqlReplicatePartialPlanTask;
import org.nuiton.topia.service.sql.plan.replicate.TopiaEntitySqlReplicatePlan;
import org.nuiton.topia.service.sql.plan.replicate.TopiaEntitySqlReplicatePlanModel;
import org.nuiton.topia.service.sql.plan.replicate.TopiaEntitySqlReplicatePlanTask;
import org.nuiton.topia.service.sql.request.CopyRequest;
import org.nuiton.topia.service.sql.request.CreateDatabaseRequest;
import org.nuiton.topia.service.sql.request.DeletePartialRequest;
import org.nuiton.topia.service.sql.request.DeleteRequest;
import org.nuiton.topia.service.sql.request.ReplicatePartialRequest;
import org.nuiton.topia.service.sql.request.ReplicatePartialRequestCallback;
import org.nuiton.topia.service.sql.request.ReplicateRequest;
import org.nuiton.topia.service.sql.request.ReplicateRequestCallback;
import org.nuiton.topia.service.sql.usage.TopiaEntitySqlUsageModel;
import java.nio.file.Path;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.stream.Collectors;
/**
* Created on 01/03/2022.
*
* @author Tony Chemit - [email protected]
* @since 1.67
*/
public interface TopiaEntitySqlModelResource {
TopiaEntitySqlModel getModel();
TopiaEntitySqlCopyPlanModel getCopyPlanModel();
TopiaEntitySqlReplicatePlanModel getReplicatePlanModel();
TopiaEntitySqlDeletePlanModel getDeletePlanModel();
TopiaEntitySqlUsageModel getUsageModel();
TopiaEntitySqlBlobModel getBlobModel();
TopiaMetadataModel getMetaModel();
TopiaMetadataModelPaths getMetaModelPaths();
Set getReplicatePartialRequestCallbacks();
Set getReplicateRequestCallbacks();
default Set createShell(ReplicatePartialRequest request) {
return createPartialShell(request.getDataType(), request.getLayoutTypes());
}
default Set createShell(DeletePartialRequest request) {
return createPartialShell(request.getDataType(), request.getLayoutTypes());
}
default SqlRequestSet buildSqlRequestSet(TopiaSqlServiceRequest request, Path targetPath) {
SqlRequestSet.Builder builder = createBuilder(request, targetPath);
if (request instanceof DeletePartialRequest) {
buildSqlRequestSet(builder, ((DeletePartialRequest) request));
} else if (request instanceof DeleteRequest) {
buildSqlRequestSet(builder, ((DeleteRequest) request));
} else if (request instanceof CopyRequest) {
buildSqlRequestSet(builder, ((CopyRequest) request));
} else if (request instanceof CreateDatabaseRequest) {
buildSqlRequestSet(builder, ((CreateDatabaseRequest) request));
} else if (request instanceof ReplicateRequest) {
buildSqlRequestSet(builder, ((ReplicateRequest) request));
} else if (request instanceof ReplicatePartialRequest) {
buildSqlRequestSet(builder, ((ReplicatePartialRequest) request));
} else {
throw new IllegalArgumentException("Can't manage request: " + request);
}
return builder.build(this);
}
private void buildSqlRequestSet(SqlRequestSet.Builder builder, DeletePartialRequest request) {
String dataType = request.getDataType();
Set layoutTypes = request.getLayoutTypes();
Set shell = createShell(request);
// keys are existing shell on which perform detach (value entry key is table, value is column name)
Map>> toDetach = new TreeMap<>();
TopiaEntitySqlReplicatePlanModel replicatePlanModel = getReplicatePlanModel();
for (TopiaEntitySqlReplicatePlan plan : replicatePlanModel.getPlans().values()) {
for (TopiaEntitySqlReplicatePlanTask task : plan.getTasks()) {
if (task.isEntryPoint() && !task.getColumnsToDetachSimple().isEmpty() && !shell.contains(task.getSchemaAndTableName())) {
for (Map.Entry entry : task.getColumnsToDetachSimple()) {
String requiredTable = entry.getValue();
if (shell.contains(requiredTable)) {
// need to detach this one
toDetach.computeIfAbsent(requiredTable, e -> new LinkedList<>()).add(Map.entry(task.getSchemaAndTableName(), entry.getKey()));
}
}
}
}
}
Map>> detachTasksMapping = new LinkedHashMap<>();
for (String entityTypeName : layoutTypes) {
TopiaEntitySqlReplicatePlan replicatePlan = replicatePlanModel.getPlan(entityTypeName);
for (TopiaEntitySqlReplicatePlanTask replicateTask : replicatePlan) {
boolean canExecute = replicateTask.accept(shell);
if (canExecute) {
String name = replicateTask.getSchemaAndTableName();
List> detachTasks = toDetach.get(name);
if (detachTasks != null) {
Map> cleanDetachTasks = new TreeMap<>();
for (Map.Entry detachTask : detachTasks) {
String table = detachTask.getKey();
cleanDetachTasks.computeIfAbsent(table, e -> new TreeSet<>()).add(detachTask.getValue());
}
detachTasksMapping.put(name, cleanDetachTasks);
}
}
}
}
TopiaEntitySqlDeletePlan plan = getDeletePlanModel().getPlan(dataType);
TopiaEntitySqlSelectArgument selectArgument = TopiaEntitySqlSelectArgument.of(request.getDataIds());
builder.addDeletePartialTableRequest(plan, selectArgument, shell, detachTasksMapping);
}
private void buildSqlRequestSet(SqlRequestSet.Builder builder, DeleteRequest request) {
TopiaEntitySqlDeletePlan plan = getDeletePlanModel().getPlan(request.getDataType());
TopiaEntitySqlSelectArgument selectArgument = TopiaEntitySqlSelectArgument.of(request.getDataIds());
builder.addDeleteTableRequest(plan, selectArgument);
}
private void buildSqlRequestSet(SqlRequestSet.Builder builder, CopyRequest request) {
TopiaEntitySqlCopyPlan plan = getCopyPlanModel().getEntryPointPlan(request.getDataType());
TopiaEntitySqlSelectArgument selectArgument = request.getDataIds().isEmpty() ? null : TopiaEntitySqlSelectArgument.of(request.getDataIds());
builder.addCopyTableRequest(plan, selectArgument);
}
private void buildSqlRequestSet(SqlRequestSet.Builder builder, ReplicateRequest request) {
TopiaEntitySqlReplicatePlan plan = getReplicatePlanModel().getPlan(request.getDataType());
TopiaEntitySqlSelectArgument selectArgument = TopiaEntitySqlSelectArgument.of(request.getDataIds());
Set callbacks = getReplicateRequestCallbacks().stream().filter(e -> e.accept(request)).collect(Collectors.toSet());
builder.addReplicateTableRequest(plan, request, callbacks);
}
private void buildSqlRequestSet(SqlRequestSet.Builder builder, ReplicatePartialRequest request) {
String dataType = request.getDataType();
Set layoutTypes = request.getLayoutTypes();
Set shell = createShell(request);
TopiaEntitySqlCopyPlan copyPlan = getCopyPlanModel().getEntryPointPlan(dataType);
Map copyTaskByTable = Objects.requireNonNull(copyPlan).tasksByTable();
TopiaEntitySqlReplicatePlanModel replicatePlanModel = getReplicatePlanModel();
Map taskMapping = new TreeMap<>();
for (String entityTypeName : layoutTypes) {
TopiaEntitySqlReplicatePlan replicatePlan = replicatePlanModel.getPlan(entityTypeName);
for (TopiaEntitySqlReplicatePlanTask replicateTask : replicatePlan) {
boolean canExecute = replicateTask.accept(shell);
if (canExecute) {
String name = replicateTask.getSchemaAndTableName();
TopiaEntitySqlCopyPlanTask copyTask = copyTaskByTable.get(name);
taskMapping.put(name, new TopiaEntitySqlReplicatePartialPlanTask(copyTask, replicateTask));
}
}
}
Set callbacks = getReplicatePartialRequestCallbacks().stream().filter(e -> e.accept(request)).collect(Collectors.toSet());
Set tasks = shell.stream().map(taskMapping::get).collect(Collectors.toCollection(LinkedHashSet::new));
TopiaEntitySqlReplicatePartialPlan plan = new TopiaEntitySqlReplicatePartialPlan(tasks);
builder.addReplicatePartialTableRequest(plan, request, callbacks);
}
private void buildSqlRequestSet(SqlRequestSet.Builder builder, CreateDatabaseRequest request) {
if (request.isAddSchema()) {
builder.addCreateSchemaRequest(true, true);
}
if (request.isAddGeneratedSchema()) {
builder.addGeneratedSchemaRequest(request.getDbVersion());
}
if (request.isAddVersionTable()) {
builder.addVersionTableRequest(request.getDbVersion());
}
TopiaEntitySqlCopyPlanModel copyPlan = getCopyPlanModel();
if (request.isAddStandaloneTables()) {
builder.addCopyTableRequest(copyPlan.getStandalonePlan(), null);
}
if (request.isAddData()) {
Map> allDataIds = request.getDataIds();
Map entryPoints = copyPlan.getEntryPointPlans();
boolean copyAll = allDataIds.isEmpty();
for (Map.Entry entry : entryPoints.entrySet()) {
String entryPoint = entry.getKey();
TopiaEntitySqlCopyPlan plan = entry.getValue();
if (copyAll) {
builder.addCopyTableRequest(plan, null);
} else {
Set dataIds = allDataIds.get(entryPoint);
if (dataIds != null && !dataIds.isEmpty()) {
TopiaEntitySqlSelectArgument selectArgument = TopiaEntitySqlSelectArgument.of(dataIds);
builder.addCopyTableRequest(plan, selectArgument);
}
}
}
}
}
private SqlRequestSet.Builder createBuilder(TopiaSqlServiceRequest request, Path targetPath) {
SqlRequestSet.Builder builder = SqlRequestSet.builder(targetPath);
if (request.isPostgres()) {
builder.forPostgresql();
} else {
builder.forH2();
}
return builder;
}
private Set createPartialShell(String entryPointType, Set layoutTypes) {
TopiaEntitySqlReplicatePlanModel replicatePlanModel = getReplicatePlanModel();
List unorderedShell = new LinkedList<>();
for (String entityTypeName : layoutTypes) {
TopiaEntitySqlReplicatePlan replicatePlan = replicatePlanModel.getPlan(entityTypeName);
Set shell = replicatePlan.getShell();
unorderedShell.addAll(shell);
}
TopiaEntitySqlCopyPlan copyPlan = getCopyPlanModel().getEntryPointPlan(entryPointType);
Set shell = copyPlan.getShell();
shell.retainAll(unorderedShell);
return shell;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy