Skip to content

Commit 0777740

Browse files
azahnenulugbek
andauthored
Feature processing (#14)
* new schema version for feature provider data * license headers * Add additional provider schema information * Fix constraints field * upgrade immutables * Fixes to provider schema * migrate provider data from v1 to v2 * Implement migration to the new format * fix wrong path in test case * add special case with table name in square brackets to test case * Fix paths and property names * refactor provider migration * provider migration for deeply nested properties * add oneo test case * schemas, en/decoder, transactions * license headers * fix unit tests * version bump * reverse migration * nested schema integration * version bump Co-authored-by: ulugbek <[email protected]>
1 parent 85a3eee commit 0777740

File tree

122 files changed

+8682
-726
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

122 files changed

+8682
-726
lines changed

build.gradle

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ allprojects {
88
group = 'de.interactive_instruments'
99
}
1010

11-
version = '3.3.0'
11+
version = '3.3.1'
1212

1313
dependencies {
14-
feature group: 'de.interactive_instruments', name: 'xtraplatform-base', version: '2.2.+'
15-
feature group: 'de.interactive_instruments', name: 'xtraplatform-store', version: '2.2.+'
16-
feature group: 'de.interactive_instruments', name: 'xtraplatform-web', version: '2.2.+'
14+
feature group: 'de.interactive_instruments', name: 'xtraplatform-base', version: '2.2.3'
15+
feature group: 'de.interactive_instruments', name: 'xtraplatform-store', version: '2.2.9'
16+
feature group: 'de.interactive_instruments', name: 'xtraplatform-web', version: '2.2.3'
1717

1818
bundle subprojects
1919
}

license-headers.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ subprojects {
2121
"**/*.ico",
2222
"**/*.xcf",
2323
"**/*.txt",
24+
"**/*.yml",
2425
"**/*.json"])
2526
ext.year = Calendar.getInstance().get(Calendar.YEAR)
2627
ext.name = "interactive instruments GmbH"

unit-tests.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ subprojects {
1111
transitive = false // this avoids affecting your version of Groovy/Spock
1212
}
1313
testCompile group: 'org.mockito', name: 'mockito-core', version: '1.9.5'
14+
testCompile "net.bytebuddy:byte-buddy:1.10.9"
1415
}
1516

1617
test {

xtraplatform-feature-provider-api/src/main/java/de/ii/xtraplatform/feature/provider/api/ConnectorFactory.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@
99

1010
import de.ii.xtraplatform.features.domain.FeatureProviderConnector;
1111
import de.ii.xtraplatform.features.domain.FeatureProviderDataV1;
12+
import de.ii.xtraplatform.features.domain.FeatureProviderDataV2;
1213

1314
/**
1415
* @author zahnen
1516
*/
1617
public interface ConnectorFactory {
1718

18-
FeatureProviderConnector<?, ?, ?> createConnector(FeatureProviderDataV1 featureProviderData);
19+
FeatureProviderConnector<?, ?, ?> createConnector(FeatureProviderDataV2 featureProviderData);
1920

2021
void disposeConnector(FeatureProviderConnector<?, ?, ?> connector);
2122
}

xtraplatform-feature-provider-pgis/src/main/java/de/ii/xtraplatform/feature/provider/pgis/SqlFeatureCreator.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@ public CompletionStage<String> runQueries() {
121121
return previousId != null ? previousId : id;
122122
};
123123

124-
return SlickSql.source(session, queryFunctions, mapper, valueContainer, materializer.system())
125-
.runWith(Sink.fold("", (id1, id2) -> id1.isEmpty() ? id2 : id1), materializer);
124+
return null;//SlickSql.source(session, materializer.system().dispatcher(), queryFunctions, mapper, valueContainer)
125+
//.runWith(Sink.fold("", (id1, id2) -> id1.isEmpty() ? id2 : id1), materializer);
126126

127127
/*return Source.from(queries)
128128
.flatMapConcat(queryFunction -> {
@@ -223,8 +223,8 @@ public CompletionStage<String> runQueries(String id) {
223223
return previousId != null ? previousId : id2;
224224
};
225225

226-
return SlickSql.source(session, queryFunctions, mapper, valueContainer, materializer.system())
227-
.runWith(Sink.fold("", (id1, id2) -> id1.isEmpty() ? id2 : id1), materializer);
226+
return null;//SlickSql.source(session, materializer.system().dispatcher(), queryFunctions, mapper, valueContainer)
227+
// .runWith(Sink.fold("", (id1, id2) -> id1.isEmpty() ? id2 : id1), materializer);
228228

229229
/*return Source.from(queries)
230230
.flatMapConcat(queryFunction -> {

xtraplatform-feature-provider-pgis/src/test/java/de/ii/xtraplatform/feature/provider/pgis/SqlFeatureInsertsTest.java

Lines changed: 46 additions & 19 deletions
Large diffs are not rendered by default.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* Copyright 2020 interactive instruments GmbH
3+
*
4+
* This Source Code Form is subject to the terms of the Mozilla Public
5+
* License, v. 2.0. If a copy of the MPL was not distributed with this
6+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
7+
*/
8+
package de.ii.xtraplatform.feature.provider.sql;
9+
10+
import com.google.common.collect.ImmutableList;
11+
import de.ii.xtraplatform.features.domain.FeatureSchema;
12+
import de.ii.xtraplatform.features.domain.FeatureTypeV2;
13+
14+
import java.util.List;
15+
16+
public class SqlFeatureTypeParser2 {
17+
18+
private final SqlPathSyntax syntax;
19+
20+
public SqlFeatureTypeParser2(SqlPathSyntax syntax) {
21+
this.syntax = syntax;
22+
}
23+
24+
25+
public List<String> parse(FeatureTypeV2 featureType) {
26+
return featureType.getProperties()
27+
.values()
28+
.stream()
29+
.map(this::toPathWithFlags)
30+
.collect(ImmutableList.toImmutableList());
31+
}
32+
33+
private String toPathWithFlags(FeatureSchema property) {
34+
String path = property.getSourcePath().orElse("");
35+
36+
path = syntax.setQueryableFlag(path, property.getName());
37+
38+
boolean isOid = property.isId();
39+
40+
/*Optional<Integer> sortPriority = generalMapping.map(TargetMapping::getSortPriority);
41+
boolean isOid = generalMapping.flatMap(targetMapping -> Optional.ofNullable(targetMapping.getType()))
42+
.map(enumValue -> enumValue.toString()
43+
.equals("ID"))
44+
.orElse(false);
45+
Optional<String> queryableName = generalMapping.flatMap(targetMapping -> Optional.ofNullable(targetMapping.getName()));*/
46+
boolean isSpatial = property.getType() == FeatureSchema.Type.GEOMETRY;
47+
48+
if (isOid) {
49+
path = syntax.setOidFlag(path);
50+
}
51+
/*if (sortPriority.isPresent()) {
52+
path = syntax.setPriorityFlag(path, sortPriority.get());
53+
}
54+
if (queryableName.isPresent()) {
55+
path = syntax.setQueryableFlag(path, queryableName.get());
56+
}*/
57+
if (isSpatial) {
58+
path = syntax.setSpatialFlag(path);
59+
}
60+
61+
return path;
62+
}
63+
}

xtraplatform-feature-provider-sql/src/main/java/de/ii/xtraplatform/feature/provider/sql/SqlPathSyntax.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,11 +246,25 @@ default String getJoinConditionPattern() {
246246
Pattern.quote(getJoinConditionEnd());
247247
}
248248

249+
@Value.Derived
250+
default String getJoinConditionPlainPattern() {
251+
return Pattern.quote(getJoinConditionStart()) +
252+
"(?:" + getIdentifierPattern() + ")" +
253+
Pattern.quote(getJoinConditionSeparator()) +
254+
"(?:" + getIdentifierPattern() + ")" +
255+
Pattern.quote(getJoinConditionEnd());
256+
}
257+
249258
@Value.Derived
250259
default String getTablePatternString() {
251260
return "(?:" + getJoinConditionPattern() + ")?" + "(?<" + MatcherGroups.TABLE + ">" + getIdentifierPattern() + ")" + "(?<" + MatcherGroups.TABLE_FLAGS + ">" + getFlagsPattern() + ")?";
252261
}
253262

263+
@Value.Derived
264+
default String getTablePatternPlainString() {
265+
return "(?:" + getJoinConditionPlainPattern() + ")?" + "(?:" + getIdentifierPattern() + ")" + "(?:" + getFlagsPattern() + ")?";
266+
}
267+
254268
@Value.Derived
255269
default Pattern getTablePattern() {
256270
return Pattern.compile(getTablePatternString());
@@ -266,6 +280,21 @@ default Pattern getColumnPathPattern() {
266280
return Pattern.compile("^(?<" + MatcherGroups.PATH + ">" + "(?:" + getPathSeparator() + getTablePatternString() + ")+)" + getPathSeparator() + "(?<" + MatcherGroups.COLUMNS + ">" + getColumnPattern() + ")" + "(?<" + MatcherGroups.PATH_FLAGS + ">" + getFlagsPattern() + ")?$");
267281
}
268282

283+
@Value.Derived
284+
default Pattern getPartialColumnPathPattern() {
285+
return Pattern.compile(getPathPatternString() + "(?:" + getPathSeparator() + "(?<" + MatcherGroups.COLUMNS + ">" + getColumnPattern() + "))" + "(?<" + MatcherGroups.PATH_FLAGS + ">" + getFlagsPattern() + ")?$");
286+
}
287+
288+
@Value.Derived
289+
default Pattern getPathPattern() {
290+
return Pattern.compile(getPathPatternString());
291+
}
292+
293+
@Value.Derived
294+
default String getPathPatternString() {
295+
return "(?<" + MatcherGroups.PATH + ">" + getPathSeparator() + "?" + getTablePatternPlainString() + "(?:" + getPathSeparator() + getTablePatternPlainString() + ")*)";
296+
}
297+
269298
@Value.Default
270299
default Options getOptions() {
271300
return new ImmutableOptions.Builder()
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/**
2+
* Copyright 2020 interactive instruments GmbH
3+
*
4+
* This Source Code Form is subject to the terms of the Mozilla Public
5+
* License, v. 2.0. If a copy of the MPL was not distributed with this
6+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
7+
*/
8+
package de.ii.xtraplatform.feature.provider.sql.app;
9+
10+
import com.google.common.collect.ArrayListMultimap;
11+
import com.google.common.collect.ListMultimap;
12+
import de.ii.xtraplatform.features.domain.FeatureStoreRelation;
13+
14+
import java.util.LinkedHashMap;
15+
import java.util.List;
16+
import java.util.Map;
17+
import java.util.Optional;
18+
import java.util.stream.Collectors;
19+
import java.util.stream.IntStream;
20+
21+
/**
22+
* @author zahnen
23+
*/
24+
class FeatureCreatorValues {
25+
final List<FeatureStoreRelation> path;
26+
final ListMultimap<List<FeatureStoreRelation>, FeatureCreatorValues> relatedValues;
27+
final Map<List<FeatureStoreRelation>, List<Integer>> rowCounts;
28+
final Map<String, String> values;
29+
final Map<String, String> ids;
30+
31+
FeatureCreatorValues(List<FeatureStoreRelation> path) {
32+
this.path = path;
33+
this.relatedValues = ArrayListMultimap.create();
34+
this.rowCounts = new LinkedHashMap<>();
35+
this.values = new LinkedHashMap<>();
36+
this.ids = new LinkedHashMap<>();
37+
}
38+
39+
FeatureCreatorValues getRelatedValues(List<FeatureStoreRelation> path, List<Integer> parentRows) {
40+
int row = parentRows.size() < path.size() ? 0 : parentRows.get(path.size() - 1);
41+
42+
return getRelatedValues(path, row);
43+
}
44+
45+
FeatureCreatorValues getCurrentRelatedValues(List<FeatureStoreRelation> path) {
46+
if (path.equals(this.path)) {
47+
return this;
48+
}
49+
50+
int row = Optional.ofNullable(relatedValues.get(path))
51+
.map(List::size)
52+
.orElse(0);
53+
54+
return getRelatedValues(path, row);
55+
}
56+
57+
Map<List<FeatureStoreRelation>, List<Integer>> getRowCounts() {
58+
return rowCounts;
59+
}
60+
61+
private FeatureCreatorValues getRelatedValues(List<FeatureStoreRelation> path, int row) {
62+
if (!relatedValues.containsKey(path)) {
63+
throw new IllegalStateException(String.format("No values found for path %s", path));
64+
}
65+
66+
List<FeatureCreatorValues> values = relatedValues.get(path);
67+
68+
if (row > values.size() - 1) {
69+
throw new IllegalStateException(String.format("No values found for row %s of %s", row, path));
70+
}
71+
72+
return values.get(row);
73+
}
74+
75+
//TODO: value escaping to SqlSyntax
76+
void addValue(List<FeatureStoreRelation> path, String attribute, String value) {
77+
FeatureCreatorValues related = getCurrentRelatedValues(path);
78+
related.values.put(attribute, value != null ? "'" + value.replaceAll("'", "''") + "'" : null);
79+
}
80+
81+
void addRow(List<FeatureStoreRelation> path) {
82+
if (!relatedValues.containsKey(path)) {
83+
throw new IllegalStateException(String.format("No values found for path %s", path));
84+
}
85+
86+
relatedValues.put(path, new FeatureCreatorValues(path));
87+
88+
rowCounts.put(path, getIncrementedRowCounts(path));
89+
}
90+
91+
private List<Integer> getIncrementedRowCounts(List<FeatureStoreRelation> path) {
92+
List<Integer> currentRowCounts = rowCounts.getOrDefault(path, getDefaultRowCounts(path));
93+
int currentRowCount = currentRowCounts.get(currentRowCounts.size() - 1);
94+
95+
currentRowCounts.add(currentRowCounts.size() - 1, currentRowCount + 1);
96+
97+
return currentRowCounts;
98+
}
99+
100+
private List<Integer> getDefaultRowCounts(List<FeatureStoreRelation> path) {
101+
int currentParentRowCount = getCurrentParentRowCount(path);
102+
103+
return IntStream.range(0, currentParentRowCount)
104+
.mapToObj(i -> 0)
105+
.collect(Collectors.toList());
106+
}
107+
108+
private int getCurrentParentRowCount(List<FeatureStoreRelation> path) {
109+
for (int i = path.size() - 1; i > 0; i--) {
110+
if (rowCounts.containsKey(path.subList(0, i))) {
111+
List<Integer> parentRowCounts = rowCounts.get(path.subList(0, i));
112+
113+
return parentRowCounts.get(parentRowCounts.size() - 1);
114+
}
115+
}
116+
117+
return 1;
118+
}
119+
120+
}

0 commit comments

Comments
 (0)