Skip to content

Commit

Permalink
[SAFRAN-1037] Database - validate view query - Fix unqualified column…
Browse files Browse the repository at this point in the history
… should be looked up into all the view tables
  • Loading branch information
vrichard12 committed Nov 23, 2022
1 parent 51dd06c commit 36767f4
Showing 1 changed file with 68 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;

Expand Down Expand Up @@ -371,6 +372,8 @@ public static View updateViewContent(View view) {
ViewColumn viewColumn = DatabaseFactory.eINSTANCE.createViewColumn();
viewColumn.setName(parsedColumn.getName());
viewColumn.setAlias(parsedColumn.getAlias());
view.getColumns().add(viewColumn);

if(!StringUtils.isNullOrWhite(parsedColumn.getTable())) {
Optional<ViewTable> fromTableOpt = view.getTables().stream()
.filter(t -> parsedColumn.getTable().equals(t.getName()) ||
Expand All @@ -379,8 +382,12 @@ public static View updateViewContent(View view) {
if(fromTableOpt.isPresent()) {
viewColumn.setFrom(fromTableOpt.get());
}
} else {
ViewTable viewTable = computeViewTableFromViewColumn(viewColumn);
if(viewTable != null) {
viewColumn.setFrom(viewTable);
}
}
view.getColumns().add(viewColumn);
}
}

Expand All @@ -389,6 +396,39 @@ public static View updateViewContent(View view) {
return view;
}

private static ViewTable computeViewTableFromViewColumn(ViewColumn viewColumn) {

View view = EObjectUtils.getContainer(viewColumn, View.class);

// First collect the view tables to look the column in
List<ViewTable> viewTables = new ArrayList<>();

if(viewColumn.getFrom() != null) {
// The "from" table is specified then we must find the column in it
viewTables.add(viewColumn.getFrom());
} else {
// The "from" table is not specified then we must find the column in one of the ViewTables
viewTables.addAll(view.getTables());
}

// Now that we know the tables where to look the column in, look for it
Column column = viewTables.stream()
.map(DatabaseServices::findTable)
.filter(Objects::nonNull)
.flatMap(t -> t.getColumns().stream())
.filter(c -> viewColumn.getName().equals(c.getName()))
.findFirst().orElse(null);

// And finally crawl to the View Table
if(column != null) {
Table table = column.getOwner();
return view.getTables().stream()
.filter(vt -> vt.getName().equals(table.getName())).findFirst().orElse(null);
}

return null;
}

private static void validateViewQuery(View view) {
List<DDiagramEditor> openDDiagramEditorsShowingView = EclipseUtils.getOpenDDiagramEditors().stream()
.filter(dde -> dde.getRepresentation().getOwnedRepresentationElements()
Expand Down Expand Up @@ -426,34 +466,27 @@ public List<ViewElement> getViewElementsOrderedForDatabaseDiagram(View view) {
return viewElements;
}

private Table findTable(ViewTable viewTable) {
private static Table findTable(ViewTable viewTable) {
TableContainer tableContainer = EObjectUtils.getContainer(viewTable, TableContainer.class);
return tableContainer.getTables().stream()
.filter(Table.class::isInstance).map(Table.class::cast)
.filter(t -> viewTable.getName().equals(t.getName()))
.findFirst().orElse(null);
}

private Object findColumn(ViewColumn viewColumn) {

// First collect the view tables to look the column in
List<ViewTable> viewTables = new ArrayList<>();

if(viewColumn.getFrom() != null) {
// The "from" table is specified then we must find the column in it
viewTables.add(viewColumn.getFrom());
} else {
// The "from" table is not specified then we must find the column in one of the ViewTables
viewTables.addAll(EObjectUtils.getContainer(viewColumn, View.class).getTables());
private static Column findColumn(ViewColumn viewColumn) {
if(viewColumn.getFrom() == null) {
return null;
}

Table table = findTable(viewColumn.getFrom());
if(table == null) {
return null;
}

// Now that we know the tables where to look the column in, look for it
return viewTables.stream()
.map(this::findTable)
.flatMap(t -> t.getColumns().stream())
.filter(c -> viewColumn.getName().equals(c.getName()))
.findFirst().orElse(null);


return table.getColumns().stream()
.filter(c -> viewColumn.getName().equals(c.getName()))
.findFirst().orElse(null);
}

public boolean isQueryValid(View view) {
Expand All @@ -462,6 +495,10 @@ public boolean isQueryValid(View view) {
return false;
}

if(view.getColumns().stream().anyMatch(c -> !c.getName().equals("*") && c.getFrom() == null)) {
return false;
}

if(view.getColumns().stream().anyMatch(c -> !c.getName().equals("*") && findColumn(c) == null)) {
return false;
}
Expand All @@ -476,18 +513,19 @@ public String queryValidationMessage(View view) {
.filter(t -> findTable(t) == null)
.collect(toList());
tablesNotFound.forEach(t -> message.append(String.format("Table %s doesn't exist.\n", t.getName())));


List<ViewColumn> columnsFromNoTable = view.getColumns().stream()
.filter(c -> !c.getName().equals("*") && c.getFrom() == null)
.collect(toList());
columnsFromNoTable.forEach(c -> message.append(String.format("Column %s is from no existing table.\n", c.getName())));

view.getColumns().stream()
.filter(c -> !c.getName().equals("*")
.filter(c -> !c.getName().equals("*")
&& !columnsFromNoTable.contains(c)
&& !tablesNotFound.contains(c.getFrom())
&& findColumn(c) == null)
.forEach(c -> {
if(c.getFrom() != null)
message.append(String.format("Column %s of table %s doesn't exist.\n", c.getName(), c.getFrom().getName()));
else
message.append(String.format("Column %s doesn't exist in the 'from' tables.\n", c.getName()));
});

.forEach(c -> message.append(String.format("Column %s of table %s doesn't exist.\n", c.getName(), c.getFrom().getName())));

if(message.length() > 0) {
message.deleteCharAt(message.length() - 1);
}
Expand Down

0 comments on commit 36767f4

Please sign in to comment.